Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 之前看到的一个递归，不太懂，望大神不吝赐教~！！！

回复:
user: user-1
content: 引用 9 楼 Oringe_new 的回复:0 == n 不怎么喜欢这种写法 Yoda condition

user: user-2
content: 举个例子：爬楼梯 任务要求：帮我到十楼去拿一个苹果 开始：你爬 啊 爬 爬啊爬，貌似每层都一样，其实层数变了 最后爬上10楼，拿到苹果----高兴过头了，任务还没完 你得一层一层走下来。把苹果交给我  f(0==n) ,如果误写成 if(0=n) 编译出错 而 if(n==0) 误写成 if(n=0) 的话，这就能编译通过

user: user-3
content: 递归：递进与回归

user: user-3
content: （1）两层循环就可以写完了，只有在迫不得已的情况下才选择递归 （2）mtable(n-1);每次这个函数返回的时候都会调用一次的。不是在递的过程，而是在归的过程调用！

user: user-4
content: if(0==n) ,如果误写成 if(0=n) 就是个语法错误，不能编译，能够让你立马知道这里有错误 而 if(n==0) 误写成 if(n=0) 的话，这就能编译通过，这个只是逻辑错误，后期排错不易被发现

user: user-5
content: 0 == n 不怎么喜欢这种写法

user: user-6
content: 你把他当成正常的程序,解读一下试试,语义一样很流畅呀

user: user-1
content: “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

user: user-7
content: 在纸上自己画吧，这个别人说是不好教会你的。 每一步每个变量会变成什么样子，注意终止条件。

user: user-0
content: 谢谢你们的回答，尽管我还不太明白

user: user-8
content: 理解递归我感觉有一个好办法就是 自己拿个笔画递归树

user: user-9
content: 1、0==n和n==0是没区别的，但0==n能防止写错，写成0=n 2、先执行mtable一直到n为0结束，然后再执行mtable_helper。前者只是为了调整n是从小到大执行的，其实完全没什么必要，换成循环可能更好理解些。 3、同上，直接换成while循环一样的。  void mtable(int const n) {   int i=1;   for(;i<=n;i++)      mtable_helper(i,1); }

user: user-10
content: 当n=1时，调用mtable(n-1）会直接返回，返回之后，就会接着执行下一条语句mtable_heler(n,1)。结束之后，回导致上一层的mtable返回，也就是n=2时的mtable返回，依此类推。

user: user-11
content: 调用函数时mtable(n-1); 会保存mtable_helper(n,1)指针;到栈里, 函数返回会继续往下执行.  最后一次是mtable(1-1);mtable_helper(1,1);后面函数返回就只调用mtable_helper(2,1);......
user-0 提问: 深入学习c语言，是否一定要装linux系统？

回复:
user: user-1
content: 依赖于IDE的话，Windows和Linux没什么区别，甚至可以说，Windows更好，比较Windows有很多成熟的IDE,比如MS的VS系列，如果你达到了一定的高度，并且尝试了解更深层次的系统内核信息，自己开发程序，编译使用，这样来说，基于Linux的开源，可扩展性，它无疑是一个更好的平台

user: user-2
content: 引用 楼主 u013545836 的回复:我想仔细研究一下c语言，到底应不应该装linux系统呢？我现在是win8系统，要装的话是直接装双系统，还是装虚拟机好呢？要是装虚拟机的话哪个版本的比较好？问题有点多哈 装个双系统吧，省的学着学着又点开 英雄联盟.exe了

user: user-3
content: 想深入学习C？跟装不装Linux没什么关系。有兴趣的话可以去看赵炯博士的《linux内核完全解析》v0.11的内核，代码量也少，又可以学习C的深入用法以及数据结构

user: user-4
content: 这样说来，应该安装的是Unix系统吧。。

user: user-5
content: 最好装，Linux下有大部分的C 函数源码

user: user-6
content: 双系统和虚拟机都装上，岂不是更好？

user: user-7
content: 虚拟机方便。。

user: user-8
content: 感觉还是装个双系统的方便

user: user-9
content: 哪有什么一定不一定

user: user-10
content: 建议装双系统，编译器的有些标准库函数效果可能不一样。。。 尽量让自己的代码能在编译，且没有警告

user: user-11
content: 有个编译器就可以了 vs够用呀  如果要用gcc 则可以装 cygwin  如果想学习linux，可以先从装虚拟机入门，当然虚拟机运行要看你机子的配置了，不然跑起来很费劲  如果喜欢折腾，或者已经入门linux建议装双系统。

user: user-12
content: 不需要，如果你对linux感兴趣的话，可以安装~

user: user-13
content: LINUX上用GCC

user: user-14
content: 学标准C， 到哪都一样。 要深入Linux系统编程的话，得装一个

user: user-15
content: 安装双系统，网上有很多教程的呀，一步一步去做就可以了。 不过，我觉得还是在虚拟机下学习比较方便。考虑轻巧的话，可以选择VBOX，初学的话，这个就很不错了；如果喜欢功能强大的话，就选VM吧。我现在使用的VM8，挺稳定的。如果你的电脑配置高的话，可以选择更高的版本。都是免费的，顶多注册个账户。

user: user-16
content: 引用 楼主 u013545836 的回复:我想仔细研究一下c语言，到底应不应该装linux系统呢？我现在是win8系统，要装的话是直接装双系统，还是装虚拟机好呢？要是装虚拟机的话哪个版本的比较好？问题有点多哈  个人觉得需要，我现在是win8，本来想再装一个Ubuntu，可惜不会装，教程看过几个，可惜不知啥原因不管用，在家目前也找不到人帮忙装，只能开学再找人装了，个人感觉不能在windows这一棵树上吊死，可以尝试着在Linux下也学学

user: user-17
content: 深入学习C语言与装不装linux是完全没前后关系的

user: user-18
content: 那要看你是否在linux做工作了

user: user-2
content: 引用 楼主 u013545836 的回复:我想仔细研究一下c语言，到底应不应该装linux系统呢？我现在是win8系统，要装的话是直接装双系统，还是装虚拟机好呢？要是装虚拟机的话哪个版本的比较好？问题有点多哈 装个双系统了事

user: user-19
content: 用windows也是可以的
user-0 提问: C++语法书籍(外国)？

回复:
user: user-1
content: 漏了个r C++ primer。有一点点基础后看这个还是挺不错的。 我当初就是先看的谭浩强的，看了前几章，懂了个大概，然后开始看C++ primer

user: user-2
content: mk:@MSITStore:C:\MSDN98\98VS\2052\vclang.chm::/html/_pluslang_grammar_summary.htm Grammar Summary This appendix describes the formal grammar of the C++ language, as implemented in the Microsoft C++ compiler. It is loosely organized around the chapter organization of this book as follows:   The Keywords section describes keywords, covered in Chapter 1, Lexical Conventions.    The Expressions section describes the syntax of expressions, described in Chapter 4, Expressions.    The Declarations section describes the syntax of declarations, described in Chapter 6, Declarations.    The Declarators section describes the syntax of declarators, covered in Chapter 7, Declarators.    The Classes section covers the syntax used in declaring classes, as covered in Chapter 8, Classes.    The Statements section covers the syntax used in writing statements, as covered in Chapter 5, Statements.    The Microsoft Extensions section covers the syntax of features unique to Microsoft C++. Many of these features are covered in Appendix B, Microsoft-Specific Modifiers.

user: user-3
content: effective c++  深入探讨c++d对象模型  了解c++背后的机制

user: user-4
content: C++ prime?
user-0 提问: 新版的visual studio express不能用.令人崩溃.

回复:
user: user-1
content: 你直接运行生成的exe行不行 建议使用codelite 或者 codeblocks,

user: user-2
content: 写小程序安装一个DevC++，又小又好用。

user: user-3
content: 程序怎么退出的？
user-0 提问: 常量指针和指针常量求解释~~~T_T

回复:
user: user-1
content: typedef  定义一个完整的类型，不可以拆分;  typedef char *ptr;/* ptr ==> char * ；指针类型 ptr 不能拆成 ，char 和 * 用  */ typedef const char *cptr;/* ptr ==> char * ；常量指针类型 cptr 不能拆成 ，const和 char 和 * 用  */  cptr p;        /* 常量指针，类型ptr 不能定义出，这种一级常量指针 */ const char *p; /* 常量指针，类型ptr 不能定义出，这种一级常量指针 */ char const *p; /* 常量指针，类型ptr 不能定义出，这种一级常量指针 */   ptr  const  q;/* ===> char * const q;  指针常量 */ const ptr   q;/* ===> char * const q;  指针常量 */  直接定义，不用typedef 定义的类型，每个符号，按照语言规则，结合成一个声明语句。 按照每个符号的位置解析类型。  用了typedef 定义的类型名后，因为typedef 不同于宏定义， 该类型名是一个类型整体，不在分割。 不再还原成，单个的类型。  里面的每个符号，都不单独参与解析类型， 而是固定算作一个解析过的类型，参与后续解析。

user: user-2
content: typedef产生新的类型

user: user-3
content: 4: 	typedef char* p;      5: 	const p p_1 = "test"; 00F65488  mov         dword ptr [p_1],0F6CD80h        6: 	const p *p_2 = &p_1; 00F6548F  lea         eax,[p_1]   00F65492  mov         dword ptr [p_2],eax    汇编拯救世界

user: user-4
content: lz没仔细啃过C++ primer吧 上面有一模一样的解释，

user: user-5
content: 引用 楼主 u012433862 的回复:常量指针：指向常量的指针，const int *p;//内容不能变 指针常量：指针是一个常量，int * const p;//地址不能变  我一直里这样理解的，但是： typedef char *ptr; const ptr p1=0;//p1是一个指向char的常量指针 const ptr *p2;//p2时一个指针，他的对象是指向char的常量指针--怎么理解 还有指向char的常量指针与指向char常量的指针有区别吗？？？为啥这两个不一样啊 typedef貌似你理解错了，他不像define，不是简单的文本替换 所以， const ptr p1=0;  不等于 const char * p1 =0; 它的意思应该是 p1是一个字符指针， 也是常量  用你的话说是 指针常量（这个翻译很暧昧）
user-0 提问: 问一个模糊控制的实现问题

回复:
user: user-1
content: 引用 3 楼 baichi4141 的回复:if(a>10&&a<=100) flagx=1; if(a>80&&a<=800) flagy=1;  然后给个算法，输入flagx，flagy，输出一个值

user: user-2
content: if(a>10&&a<=100) flagx=1; if(a>80&&a<=800) flagy=1;

user: user-0
content: 引用 1 楼 user-3 的回复:这个需要啥经验？ 简单的判断条件就可以解决的 - -额，属于两部分的内容怎么做？还是没懂。。。

user: user-3
content: 这个需要啥经验？ 简单的判断条件就可以解决的
user-0 提问: 求助-关于字符输入

回复:
user: user-0
content: 引用 1 楼 derekrose 的回复:debug过了吗，还有为什么要局部声明定义extern变量  Debug刚会，不太会看。刚刚试了下，发现是可以自己发现问题的。我分别在for loop和 if语句的段落设置了断点。然后运行输入 1234，发现if语句的断点会显示loop语句的执行情况，发现到了 i = 4时候 出现了name[i] = ' '. 因此可以发现程序出错。  非常谢谢提醒！

user: user-1
content: debug过了吗，还有为什么要局部声明定义extern变量

user: user-0
content: 引用 2 楼 l786112323 的回复:是这样的，你的i会一直加一直加，你用的不是字符指针，所以最后一个字符不是'\n'而是空字符，你的判断机制有问题，另外，虽然不知道你想干什么，可能是身份证号检测？如果20个字符不全是数字的话显然就算你的i没有加到头也会显示wrong的 谢谢各位帮忙！ 如麦丽素所说，问题解决。  #include <stdio.h> char name[20];  int main () {   int i = 0;   extern char name[20];   gets(name);    for (i = 0; name[i] != '\0'; i++)   { 	      if ((name[i]<'0')||(name[i]>'9'))        {            printf("That' wrong\n"); 	  break;        }   }   return 0; } 惭愧，一开始一直以为我敲的那个回车换行键，会被当作'\n'吃进去。

user: user-2
content: for (i = 0; name[i] != '\n'; i++) -> for (i = 0; name[i] != '\n' && i < 20; i++)  gets is dangerous是说，gets这个函数有风险（google 缓冲区溢出攻击），建议你不要用。只是警告。

user: user-3
content: 是这样的，你的i会一直加一直加，你用的不是字符指针，所以最后一个字符不是'\n'而是空字符，你的判断机制有问题，另外，虽然不知道你想干什么，可能是身份证号检测？如果20个字符不全是数字的话显然就算你的i没有加到头也会显示wrong的
user-0 提问: C语言编程声明数组的问题

回复:
user: user-1
content: in windows, use GetTickCount to get the time

user: user-2
content: void foo() { static int a[1000]; }  void bar() { int a[1000]; }  void foobar() { int * a = (int *)malloc(sizeof(int) * 1000); }

user: user-3
content: 你哪里不会？ 这是最基本的概念，如果都不会的话，最好再看看书，找人当面问问。
user-0 提问: 迷茫不知所措，求方向指引！

回复:
user: user-0
content: 引用 2 楼 ALNG 的回复:学指针结合链表，二叉树等来学习。堆栈的话，好像没多少可说的，作为一种抽象数据结构，就是后进先出。这个特性特别适合函数调用的关系，后调用的函数先返回。一般性地了解C函数调用的参数和函数地址压栈的顺序，了解局部变量(多数)是在堆栈上分配空间，并随着调用函数退出而不再有效(有助于理解局部变量的生存期)。然后学习树的时候有n多递归，这个也有助于以及有求于你对堆栈工作机制的了解。都是很简单的东西，去做，就会点滴理解以致融汇贯通。没有什么大虾能几句话放进你的脑袋里面吧？  子曰，学而不思则罔，思而不学则殆。你是未学先思，殆矣乎，殆矣乎！ 谢谢指导，我会注意你说的哪些问题的，谢谢

user: user-1
content: 指针是C语言的精华，也是C语言学习的难点。  不会用指针，意味着你还没有掌握C语言。  我的经验，花点时间学一下汇编语言，再来学指针就很轻松了。不需要把汇编学得很深入，重点是了解CPU的工作原理。  另外，学语言的目的不是做习题或考试，而是要应用，提高应用水平的方法，就是阅读一些典范的源代码，然后自己动手模仿、练习。例如： A）UNIX/LINUX 环境中的命令和实用程序。如：date, bc, wc, common, bash, grep, awk ... B) LINUX 内核源代码。这个比较庞大。但如果你准备从事嵌入式系统开发，这是必要的功课。 C）还有一些优秀的开源软件也是用C开发的。如：Nginx。如果把这个东东搞清楚，你在就业市场上就很有竞争力。  建议从A入手。首先加强两方面的技能：一是对复杂的任务进行分析，分解成若干个简单的子任务；二是如何利用现成的模块构造功能较为复杂的大模块。 这两方面的能力是程序员的基本功，不管你从事那个领域的开发都能用上。  推荐你看一本书：《深入理解计算机系​统》。

user: user-0
content: 引用 6 楼 KenZhang1031 的回复:C是工具，学C是了解不了系统底层的东西的。不知道你要学习底层的什么？ 看你举了单片机的例子，如果想要学单片机，就直接看单片机的书，从单片机的芯片架构、汇编指令，c编程顺序学就可以了，单片机方面书籍有很多，入门可以看北航的书籍和单片机的datasheet，其中intel的51系列的手册比较完整；如果对ARM感兴趣，就看ARM的官方资料。 如果是要了解计算机系统，那么就学计算机系统的原理（比如深入理解计算机系统这样的书），要了解计算机系统，操作系统原理也是必须要理解的，可以学习linux内核，因为开源，结合内核源码，可以知道计算机是怎么管理整个系统的，包括怎么驱动底层的硬件的。 如果是要理解一门语言是怎么工作的，比如C语言，那要学编译原理。 如果只是想深入学习C语言，那就好好的学C语言，不过光学C是深入理解不了底层的东西的。 很全面的分析，谢谢，我知道怎么做了

user: user-0
content: 引用 5 楼 u013584315 的回复:C语言的精华是指针。好好学，我只能这么说 嗯，为了更加深刻的学习C，我现在在看汇编，了解以后再学习指针我觉得会比较好理解内存

user: user-0
content: 引用 4 楼 caozhy 的回复:C神奇在哪里？你应该明白，任何通用编程语言都是图灵等价的，即不存在一种语言可以解决，但是另一种语言无法解决的问题。 我说的神奇是因为C能直接操作机器，很早以前以为能控制机器就是牛B的东西，所以在小时候几年级的时候就印象到心里了

user: user-2
content: 赵老师上！！

user: user-0
content: 引用 3 楼 ForestDB 的回复:如果只是堆栈和指针，倒不用特别深入到非常底层，因为它们已经是在某一抽象层次之上了； 学会用debugger，然后看看基本理论，够用。 嗯，我现在找到重点了，去汇编了

user: user-3
content: C语言视频教程: http://www.tudou.com/plcover/z5u9lwXuPKU/  按顺序看。

user: user-4
content: C是工具，学C是了解不了系统底层的东西的。不知道你要学习底层的什么？ 看你举了单片机的例子，如果想要学单片机，就直接看单片机的书，从单片机的芯片架构、汇编指令，c编程顺序学就可以了，单片机方面书籍有很多，入门可以看北航的书籍和单片机的datasheet，其中intel的51系列的手册比较完整；如果对ARM感兴趣，就看ARM的官方资料。 如果是要了解计算机系统，那么就学计算机系统的原理（比如深入理解计算机系统这样的书），要了解计算机系统，操作系统原理也是必须要理解的，可以学习linux内核，因为开源，结合内核源码，可以知道计算机是怎么管理整个系统的，包括怎么驱动底层的硬件的。 如果是要理解一门语言是怎么工作的，比如C语言，那要学编译原理。 如果只是想深入学习C语言，那就好好的学C语言，不过光学C是深入理解不了底层的东西的。

user: user-5
content: C语言的精华是指针。好好学，我只能这么说

user: user-6
content: C神奇在哪里？你应该明白，任何通用编程语言都是图灵等价的，即不存在一种语言可以解决，但是另一种语言无法解决的问题。

user: user-7
content: 如果只是堆栈和指针，倒不用特别深入到非常底层，因为它们已经是在某一抽象层次之上了； 学会用debugger，然后看看基本理论，够用。

user: user-8
content: 学指针结合链表，二叉树等来学习。堆栈的话，好像没多少可说的，作为一种抽象数据结构，就是后进先出。这个特性特别适合函数调用的关系，后调用的函数先返回。一般性地了解C函数调用的参数和函数地址压栈的顺序，了解局部变量(多数)是在堆栈上分配空间，并随着调用函数退出而不再有效(有助于理解局部变量的生存期)。然后学习树的时候有n多递归，这个也有助于以及有求于你对堆栈工作机制的了解。都是很简单的东西，去做，就会点滴理解以致融汇贯通。没有什么大虾能几句话放进你的脑袋里面吧？  子曰，学而不思则罔，思而不学则殆。你是未学先思，殆矣乎，殆矣乎！

user: user-0
content: 这里补充一下，我是希望第一步先把C学会，为了更好的了解堆栈和指针，我应该怎么学习？
user-0 提问: 回溯法与剪枝

回复:
user: user-1
content: 回溯法就是一个系统的状态空间搜索方法，特别适用于状态空间是树型或者可以转化成树型的问题。剪枝是状态空间搜索的通用技巧，分支限界法等也用到剪枝的技巧。具体的剪枝可以进一步区分为合法性和最优性剪枝两种。
user-0 提问: C语言题目   代码写出来了  也能按样例输出  为什么是WA？求大神解释！！！！

回复:
user: user-1
content: 7 1->2->5->7->8->10->17->end  2*5+3*1=13，你13呢

user: user-0
content: 小B一到市场,傻眼了,卖物资的老板告诉小B这些货是不能拆开卖,要买就只能全部都买了,小B回去和后勤的boss报告,后勤的boss也很尴尬,只能说,钱就那么多,尽量多买点吧. 小B这回就真不知道该咋办了,但是呢,小B还有绝招---求助,女孩子到哪都不缺人帮助滴~. Input  小B拿到钱n(1~1000). 物资总类数m(1~16). 接下来m行,每行两个正整数,该类物资单价a和总数b. Output  能购买的最多物资. Sample Input  100 5 1 10 2 10 3 10 4 10 5 10  Sample Output  40 能帮我看看这道题目该怎么判断么 我写的是按物资的重量优先来的  但是是错的 #include<stdio.h> #include<stdlib.h> struct GOOD { 	int pi,mi; }gd[16]; int cmp(const void *a,const void *b) { 	struct GOOD *p=(struct GOOD *)a; 	struct GOOD *q=(struct GOOD *)b; 	if(p->mi!=q->mi)return q->mi-p->mi; 	else 	return p->pi-q->pi; } int main() { 	int n,m,sum,weight; 	struct GOOD *p; 	while(scanf("%d%d",&n,&m)!=EOF) 	{ 		sum=0;weight=0; 		for(p=gd;p<gd+m;p++) 			scanf("%d%d",&p->pi,&p->mi); 		qsort(gd,m,sizeof(gd[0]),cmp); 		for(p=gd;p<gd+m;p++) 		{ 			sum+=p->mi*p->pi; 			if(sum<=n){weight+=p->mi;} 			else sum-=p->mi*p->pi; 		} 		printf("%d\n",weight); 	} 	return 0; }

user: user-0
content: 恩恩 对的 我遗漏了  谢谢你
user-0 提问: PAT BASIC 1013 一个测试点段错误百思不得其解

回复:
user: user-1
content: 我也是测试点四段错误，不解，楼主最近在刷PAT吗？求加好友，一起讨论讨论，我的扣扣是624956561

user: user-2
content: 搜索104，替换为10000， 就可以了。到10000，楼主的方法可能会稍显慢了。

user: user-3
content: 拜托……题目是10^4不是104……10^4是10000

user: user-2
content: 应该没有问题。最后结束的时候是不是可以加个换行符？  问题很小，看不出差别，但具体实现可以改进。可先生成这个素数数组。另外测试素数时，只需要用已经生成了的小于其平方根(你用另一个的平方，更好)的素数测试就好。   #include<stdio.h>   int primes[104];  void gen_prime();  int main(void) {     int begin,end;     scanf("%d%d",&begin,&end);     count=0;     gen_prime();     --begin;     for(int i=begin; i<end; ++i)         printf("%d%c", primes[i],(i-begin)%10==9?'\n':' ');     putchar('\n');     return 0; }   void gen_prime() {      primes[0]=2;      primes[1]=3;      for(int i=5,j=2; j<104; i+=2)      {          // test if i is prime.          bool prime=true;          for(int k=1;primes[k]*primes[k]<=i;++k)          {             if(i%primes[k]==0)             {                 prime=false;                 break;             }          }          if(prime)              primes[j++]=i;      } }
user-0 提问: c语言   返回上一级目录

回复:
user: user-1
content: case 4:return; // "void one()" return. case 5:break;  // "switch" break.

user: user-1
content: switch会有break的, case:没有break会往下执行的. 所以case 4: break;有没有break都一样.  return就是函数返回.

user: user-0
content: 好吧，我想通了,case 5中的break只是终止了one1函数,返回到被调用处后又遇到continue，故继续执行我想到利用返回值来操作。不过还是谢谢您…………#include<stdio.h> int one() { 	for(;;) 	{ 		int q; 		scanf("%d",&q); 		switch(q) 		{ 		case 1:printf("1_1的内容\n");continue; 		case 2:printf("1_2的内容\n");continue; 		case 3:printf("1_3的内容\n");continue; 		case 4:return(0);//结束函数 		case 5:return(1);//返回上一级 		} 		//break; 		//printf("haha\n"); 	} 	//break; }      #include <stdio.h> void main() { 	while(1) 	{ 		int i,q; 		scanf("%d",&i); 		switch(i) 		{ 		case 1:q=one(); 			if(q==1) 				continue; 			else 				break; 	//	case 2:two();continue; 	//	case 3:three();continue; 		case 4:break; 		} 		break; 	} }

user: user-0
content: 上楼的大哥，小弟听不懂啊？
user-0 提问: 问一下这个队列哪里出现了问题

回复:
user: user-1
content: void in_queue(struct queue *q,char a){     struct node *n=new node;     if(n==NULL){          return;     }     n->data=a;     n->next=NULL;     if(q->rear)     {         q->rear->next=n;     }else{        q->front=n;     }     q->rear=n; // 我刚才漏了这个。 }

user: user-1
content: void in_queue(struct queue *q,char a){     struct node *n=new node;     if(n==NULL){          return;     }     n->data=a;     n->next=NULL;     if(q->rear)     {         q->rear->next=n;     }else{        q->front=q->rear=n;     } }  void out_queue(struct queue *q){    struct node * tmp;     if(q->front==NULL)       return;    if(q->front==q->rear)    {       delete q->front;       q->front=q->rear=NULL;       return;    }     tmp=q->front;    q->front=temp->next;    delete tmp; }  void print(struct queue *q){     struct node *n=q->front;     while(n){        std::cout<< n->data << ' ';        n=n->next;     } }   粗看了下，你再试试？
user-0 提问: 下列不符合C语言规定赋值的是

回复:
user: user-1
content: 引用 6 楼 KenZhang1031 的回复:这种题，舍本逐末，对学习C没作用，不用理会。 赞一个，%只能是整数操作，c选项有问题， 这种题不要看了  而A选项等号右边是逗号表达式，但=优先级比，高 引用 5 楼 ForestDB 的回复:BCD都是赋值语句，而A是逗号表达式语句。 因为=的优先级比,高

user: user-2
content: 这种题，舍本逐末，对学习C没作用，不用理会。

user: user-3
content: 是的 A本质上来说似乎并不叫赋值语句 因为=操作符优先级高，A算作是赋值语句+一个额外语句的组合语句

user: user-4
content: 答案是 C。  #include <stdio.h> int main(void) { 	double a=22; 	int i; 	i=a%11;  }  编译提示左值类型非法。  选项 A  是正确的。

user: user-5
content: 本来有答案，看了大家的回答，我也拿不准了

user: user-6
content: BCD都是赋值语句，而A是逗号表达式语句。 因为=的优先级比,高

user: user-3
content: c  double无法进行%操作吧

user: user-7
content: 好象答案是A吧。

user: user-8
content: 异样->一样

user: user-8
content: C语言不了解，但是应该和C++异样。 答案是C。double不能应用%，只有char long int之类整形才可以。 A可以，没有问题。
user-0 提问: C和INI文件如何连接

回复:
user: user-0
content: 引用 11 楼 baichi4141 的回复:[quote=引用 10 楼 u011497426 的回复:] 英语好孬的  不懂 你觉得你在笑给谁看？谁会为了你听不懂英语而高兴或伤心？ 我无意找茬，让你不爽我也得不到任何好处。我只想劝你一句，只有在学校才有人逼着你学习什么，进入社会之后你能力不足就被淘汰，除了你的家人没人会在乎你。所以别再“没学过”“看不懂”了，真的，没人逼着你学，也没人在乎你学得会学不会。大家提一些意见解答一些疑点，帮自强努力的人一把没什么，要让别人QQ一步一步像带小孩一样指导你？你觉得大家很闲么？[/quote]我曾经这么给自己说过，如果一个和你不相关的人都会来说教，那你肯定做得太过分了，所以我很感谢你对我说这些，我一定会努力改变的，非常感谢

user: user-1
content: windows有读写INI文件函数

user: user-2
content: 引用 10 楼 u011497426 的回复:英语好孬的  不懂 你觉得你在笑给谁看？谁会为了你听不懂英语而高兴或伤心？ 我无意找茬，让你不爽我也得不到任何好处。我只想劝你一句，只有在学校才有人逼着你学习什么，进入社会之后你能力不足就被淘汰，除了你的家人没人会在乎你。所以别再“没学过”“看不懂”了，真的，没人逼着你学，也没人在乎你学得会学不会。大家提一些意见解答一些疑点，帮自强努力的人一把没什么，要让别人QQ一步一步像带小孩一样指导你？你觉得大家很闲么？

user: user-2
content: 听说一个没学过的东西，百度该用什么教材，下载电子书学习 如果非要别人手把手教会你——转行吧，技术行业不适合你

user: user-0
content: 没有  我是个新手   你说的这个API是什么我都不知道

user: user-0
content: 英语好孬的  不懂

user: user-3
content: find some source code

user: user-0
content: 好吧   我知错了   我也在想办法充实自己  提升自己的

user: user-4
content: LZ确定学会了文件操作的API？

user: user-0
content: 没学过

user: user-5
content: 为什么不试下xml呢？

user: user-0
content: 说实话，你说得高深了，你说的有的知识点我还没学，可不可以把你QQ给我，在论坛上聊太慢了，你加我也行，我QQ是：295812562

user: user-6
content: 如果只是学习文件操作，可以。INI不过就一文本文件。就用fopen, fgets一类的函数就剋搞定。就一文本格式文件的读取和写入的问题。也别INI了，你可以定义一非常简单的文件格式。比如每行一个记录，每个记录由 ID 名字 地址 电话 email QQ 等字段组成，字段间用'\t'分隔。你先试着往这个方向写一下，有具体问题再问。  如果要真正做个有点意思的东西，建议用数据库，比如sqlite, 这样你需要的技能编程: 1. 掌握如何把外部库(dll及 lib)加入你的工程； 2. 基本的SQL知识。  这个可以先放一放，你就用你最初的想法， 练习一下文本文件的读写吧。
user-0 提问: 关于rand()%X实现等概率随机的问题

回复:
user: user-1
content: 其实这个是伪随机的。

user: user-2
content: #include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79

user: user-3
content: 在使用rand()%x进行模拟随机是，如果x的值不是rand()最大范围的倍数应该就没有办法实现等概率随机了吧?  如果你需要rand超过最大范围的数, 可以使用多次rand来组合.

user: user-4
content: 建议使用如下真正获取随机数的函数：   #include <stdio.h> #include <stdlib.h>  //获得CPU自上电以来的时钟周期数 __declspec (naked) unsigned __int64 GetCpuCycle() { 	_asm 	{ 		rdtsc 		ret 	} }  #define RAND() (srand((unsigned int)GetCpuCycle()), rand())  void main() { 	for (int i = 0; i < 10; i++) 	{ 		int x = RAND() % 9 + 1;	//获取1-9之间的一个随机数 		int y = RAND() % 9 + 1;	//获取1-9之间的一个随机数 		printf("%d %d\n", x, y); 	} }

user: user-5
content: 不应该那么写，应该这么写： int rnd0to100() {     int x = 101;     while (x > 100)     {         x = rand0to150();     }     return x; }

user: user-6
content: rand() * MAX / RAND_MAX 再注意一下溢出、舍入什么的

user: user-7
content: 严格来说，你是对的，但这样的影响维乎其微，可以忽略。  真的要较真，也是可以调整的。  比如你想要的是0-99 (即%100)这100个整数完全等概，因为机器的限制，RAND_MAX不是正好是100的整数倍，这昂就会导致有那么一些数字(0 到 RAND_MAX%100)比其余的数字有多一次的出现机会，当范围较大的时候，这个影响有时甚至不能忽略，怎么办才能然他们严格等概呢？  最简单的办法是抛弃掉机会不均等的区间的那些值，我们看看是哪些值破坏了严格均等。是大于等于(RAND_MAX-RAND_MAX%范围)的数。 关于边界，我们可以用一组小的数字来考察，比如RAND_MAX是10， 范围是9，那么0-8是等概的，9，10应该被抛弃，所以你可以定义一个自己version的rand()   int myrand(int max) {      int v;      do{        v=rand();      }while(v>=RAND_MAX-RAND_MAX%max);      return v%max;      }   这样就可以保证严格等概了。
user-0 提问: c语言中如何在debug下查看stdin所指向的内容呢

回复:
user: user-1
content: #include <stdio.h> FILE *f; int main() {     f=(FILE *)stdin;     printf("stdin->_ptr     ==0x%p\n",f->_ptr     );     printf("stdin->_cnt     ==%d  \n",f->_cnt     );     printf("stdin->_base    ==0x%p\n",f->_base    );     printf("stdin->_flag    ==%d  \n",f->_flag    );     printf("stdin->_file    ==%d  \n",f->_file    );     printf("stdin->_charbuf ==%d  \n",f->_charbuf );     printf("stdin->_bufsiz  ==%d  \n",f->_bufsiz  );     printf("stdin->_tmpfname==0x%p\n",f->_tmpfname);     return 1; } //stdin->_ptr     ==0x10259860 //stdin->_cnt     ==0 //stdin->_base    ==0x10259860 //stdin->_flag    ==257 //stdin->_file    ==0 //stdin->_charbuf ==0 //stdin->_bufsiz  ==4096 //stdin->_tmpfname==0x00000000 //

user: user-2
content: stdin是一个系统预先定义好的FILE *类型的变量，不用程序员定义，程序员可以直接使用。  如下片段是从stdio.h文件中抽出来的：  _CRTIMP extern FILE _iob[]; #define stdin  (&_iob[0])  在debug模式下，不能直接从变量观察窗口查看其值，用如下代码可以打印出其地址： 	printf("%x08\n", stdin); 在VC6.0下，其值为 0x424A3008 这个地址，该地址是受系统保护的，查看不了其中的值。
user-0 提问: 用了动态链表输出文件内容，但是运行到最后总是出现debug assertion failed failed fscanf.c line 54

回复:
user: user-1
content: 错误或者可改进的地方还真不少   #include<stdio.h> #include<stdlib.h> #include<malloc.h> #define len sizeof(struct student)  struct student {     int number;     char name[20];     struct student *next; };  // 原型声明调出去，这样main更简练 struct student *creat(void); void print(struct student *p4);   int main() {     print(creat()); }  struct student * new_node() { 	struct student* p=(struct student*)malloc(sizeof(struct student)); 	if(!p) 	{     	printf("不能成功分配存储空间。");      	exit(1); 	} 	// 建议把next指针初始化为NULL, 不要节省这点cpu 	// next=NULL; 	return p;	 }  // return NULL if fail to read... struct student* read_a_student(FILE* fp, struct student * s) { 	 //    if(2!=fscanf(fp,"%d%s\n",&s->number,&s->name)) //    { //        printf("读取学生信息失败。文件格式错误或未预期的文件结束！"); //        exit(1); //    }     return 2!=fscanf(fp,"%d%s\n",&s->number,&s->name) ? NULL : s; }  struct student* read_student_ex(FILE*fp) { 	return read_a_student(fp, new_node()); }  struct student *creat(void) {     struct student *p1,*p, *p2;     // 用p指向表头，p1指向表尾，或者用head, tail更容易理解     // 你最后返回的p什么地方初始化的，好像没有？也许我看错了。     //     FILE *fp;        // 下面的错误最恐怖最致命，遗憾的是c编译器发现不了，     // 我还真没注意，把文件名改成cpp, 编译器一下帮我发现了。     // 所以...     if((fp=fopen("name2.txt","r"))==NULL)     {         printf("cannot open");         exit(0);     }          //p1=(struct student *)malloc(len); //    if((p=(struct student *)malloc(len)) == NULL) //    { //    } //    else       printf("hello");          p=p1=read_student_ex(fp);          while(p1->number!=2012210420 && NULL!=(p2=read_student_ex(fp)))     { //      没必要，一个指表头，一个指表尾，总是加在表尾         //        if(i>1) //        { //            p2->next=p1; //            p2=p1; //        } //        else //        	p=p1; //        i++;  		// 链入新增节点，然后更新表尾指针以备下一次append 		p1->next=p2; 		p1=p2; 		 //        p1=(struct student *)malloc(len); //        if((p1=(struct student *)malloc(len)) == NULL) //        { //         printf("不能成功分配存储空间。"); //         exit(1); //        } //        fscanf(fp,"%d%s\n",&p1->number,&p1->name);     }     p1->next=NULL;      //free(fp);     fclose(fp);     return(p); } void print(struct student *p4) {        struct student *p;     p=p4;     do     {         printf("%d %s\n",p->number,p->name);         p=p->next;     }while(p!=NULL); }

user: user-1
content: p1=(struct student *)malloc(len);         if((p1=(struct student *)malloc(len)) == NULL) 为什么分配两次  fp并不是动态分配的，为什么要free?  fscanf真没看出问题，可能是其他地方的问题. 上面两个肯定是问题，但未必是导致你观测到的错误的问题。程序写得是有点乱的，完成主功能的create函数做太多事了，要分派一些出去，让它精简一些，更容易阅读和维护
user-0 提问: 本人刚自学，有些疑问，可以用C语言编写游戏吗

回复:
user: user-1
content: 完全可以！还是c++、c# 做界面方便

user: user-2
content: 书 名: Windows程序设计（第五版 珍藏版） 作　者：佩措尔德(CharlesPetzold) 可以让你用纯C写界面程序。 如果你懂点C++，懂点MFC，尝试自己用C++的思想把书中的东西封装成自己的类库。 然后在去学下C#,你会发现。。。。。。。

user: user-3
content: C语言是绝对可以的，写出的游戏效率还要高呢

user: user-4
content: 引用 25 楼 AGong1990 的回复:以上有几楼说的不太准确，我也来说说我的看法 C语言当然可以写出有界面的程序，当然这得依赖操作系统提供的API或GUI包装库之类的，在windows上最典型的就是GDI相关的API函数，这些函数都是C语言写的，但是界面程序的入口是变成WinMain了，里面还涉及到消息循环，窗口，窗口消息之类的东西，至于楼上有同学说用C#来做界面，至于桌面开发的天堂我就不同意了 桌面软件开发的主流还是C/C++，用C#的话运行效率肯定没有C/C++好，兼容性问题是硬伤，依赖于.net framework，像QQ,360等等软件基本都是C/C++开发的，当然都是用界面库了，或自己做的，或买的了。如开发的界面库duilib，也有很多软件产品使用了，QT的话YY语音在用，WPS好像也是  游戏的话C/C++也是主流，小游戏用GDI即可，大型的一般都会用游戏引擎了，不会直接用DirectX

user: user-4
content: 以上有几楼说的不太准确，我也来说说我的看法 C语言当然可以写出有界面的程序，当然这得依赖操作系统提供的API或GUI包装库之类的，在windows上最典型的就是GDI相关的API函数，这些函数都是C语言写的，但是界面程序的入口是变成WinMain了，里面还涉及到消息循环，窗口，窗口消息之类的东西，至于楼上有同学说用C#来做界面，至于桌面开发的天堂我就不同意了 桌面软件开发的主流还是C/C++，用C#的话运行效率肯定没有C/C++好，兼容性问题是硬伤，依赖于.net framework，像QQ,360等等软件基本都是C/C++开发的，当然都是用界面库了，或自己做的，或买的了。如开发的界面库duilib，也有很多软件产品使用了，QT的话YY语音在用，WPS好像也是

user: user-5
content: 可以依托库和游戏引擎  C+WinAPI，你可以写出任何windows程序

user: user-6
content: 可以写游戏。  界面与C无关，需要界面相应的API。  学C推荐看TCPL。

user: user-7
content: C+WinAPI，你可以写出任何windows程序

user: user-8
content: 请教qt是什么

user: user-9
content: 很多优秀的游戏都是用C语言写的、

user: user-10
content: 可以学mfc和qt，mfc就是用vc++6.0编写可视化界面的，如果单纯靠c只能写出类似dos环境下的黑白界面!

user: user-11
content: c语言很强大的，其实不同语言还是相通的，你熟练其中之一，在熟悉其他的也不会吃力的

user: user-0
content: 谢谢你的经验分享！其实我觉得c入门可能简单点，但想要精通得费不少功夫

user: user-12
content: 有些头目了0 0  新手还是要有毅力啊 。。。。。

user: user-13
content: 受教了，我也是新手

user: user-14
content: c++作为起点、、转向C#、、、那才是桌面开发的天堂

user: user-15
content: 我也是学习C的新手，之前自学了其他语言，略懂一些，这里和你分享一下我的看法： 要快速的写windows上的软件，那就去学习C#，开发速度很快，界面也还可以，看你自己的美工！ java我不知道了，但看过相关的文章，现在手机上的游戏基本都是这个平台开发 C这个是很强大的，可以开发任何东西，看个人能力，你可以用它来写底层，如开发系统，驱动编写等等，当然，你也可以用它写软件，不是很复杂的完全可以用C写，要是复杂一点就要用C++来写了，C不是面向对象的语言，写大东西会有气无力的~ 汇编就不说了，精通汇编的人基本是开挂投胎的，我们不讨论  最后，要是我早点知道C不难学，我就不会走那么多弯路了。但想想，走过弯路才知道更多的经验

user: user-16
content: 1.c和指针 2.c缺陷与陷阱 3.c专家编程 4.编程珠玑 自己可以在csdn上搜索，我说不全

user: user-17
content: 引用 10 楼 u010913001 的回复:[quote=引用 9 楼 caozhy 的回复:] 谭浩强之流学得如同皮毛的皮毛。  好比你说学好数学可以预测天气预报么？很遗憾，学会小学一年级的算术估计不能。  用程序设计语言编写程序究竟能写出什么不在于语言，而在于人。所有的通用编程语言都是图灵完备的，或者说是等价的，这意味着没有任何一种语言有超越计算机本身或者另一种语言的特异功能。 最后一句读的好不通顺啊[/quote] Google 图灵完备 图灵等价。

user: user-18
content: 引用 9 楼 caozhy 的回复:谭浩强之流学得如同皮毛的皮毛。  好比你说学好数学可以预测天气预报么？很遗憾，学会小学一年级的算术估计不能。  用程序设计语言编写程序究竟能写出什么不在于语言，而在于人。所有的通用编程语言都是图灵完备的，或者说是等价的，这意味着没有任何一种语言有超越计算机本身或者另一种语言的特异功能。 最后一句读的好不通顺啊
user-0 提问: 函数指针的声明

回复:
user: user-1
content: 没问题。

user: user-2

user: user-3
content: typedef int (*cmpfunction)(point_t*, point_t *); cmpfunction pf; pf=myfun1; int result=pf(&p1,&p2);

user: user-4
content: 没问题，亲！

user: user-5
content: 没问题

user: user-6
user-0 提问:  getchar读取缓冲区字符问题

回复:
user: user-1
content: getchar()只接受一个，你的循环结束不了，吃回车的

user: user-2
content: 肯定的啊，回车也算是一个字符了。输入e回车，这是两个字符，进入循环两次。  ead回车，除了a不满足条件，其余都满足，会循环三次。

user: user-3
content: getchar每收到一个值的时候就返回,键入回车也同样返回。

user: user-4
content: 引用 11 楼 robert_chen1988 的回复:[quote=引用 10 楼 a345485527 的回复:] [quote=引用 9 楼 robert_chen1988 的回复:] [quote=引用 4 楼 a345485527 的回复:] lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出  我想问一下，e进入循环两次后，为啥getchar没有字符读了呢，它为什么不一直读换行符呢？ [/quote] 为什么要一直读换行符呢？ 和读完e之后要读取下一个字符一个道理呀 因为按照输入，缓冲区中目前只有两个字符，<e，回车> 读完e之后，可以理解为把e踢出去了，下一个再读回车，然后再读，发现缓冲区没数据了，所以就等待用户输入了 照您这种想法来说，为什么不一直读e呢？ 这里有个博客，刚刚查的，它用开闸放水做了类比，可以参考下[/quote]  非常感谢，我目前c语言只看了谭浩强的两本书，还没有缓存区的概念，谢谢了，看来需要学的还有不少[/quote] 看完谭浩强的就看国外的书，虽然我没看过老谭的，不过口碑很不好，误人子弟

user: user-5
content: 引用 10 楼 a345485527 的回复:[quote=引用 9 楼 robert_chen1988 的回复:] [quote=引用 4 楼 a345485527 的回复:] lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出  我想问一下，e进入循环两次后，为啥getchar没有字符读了呢，它为什么不一直读换行符呢？ [/quote] 为什么要一直读换行符呢？ 和读完e之后要读取下一个字符一个道理呀 因为按照输入，缓冲区中目前只有两个字符，<e，回车> 读完e之后，可以理解为把e踢出去了，下一个再读回车，然后再读，发现缓冲区没数据了，所以就等待用户输入了 照您这种想法来说，为什么不一直读e呢？ 这里有个博客，刚刚查的，它用开闸放水做了类比，可以参考下[/quote]  非常感谢，我目前c语言只看了谭浩强的两本书，还没有缓存区的概念，谢谢了，看来需要学的还有不少

user: user-4
content: 引用 9 楼 robert_chen1988 的回复:[quote=引用 4 楼 a345485527 的回复:] lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出  我想问一下，e进入循环两次后，为啥getchar没有字符读了呢，它为什么不一直读换行符呢？ [/quote] 为什么要一直读换行符呢？ 和读完e之后要读取下一个字符一个道理呀 因为按照输入，缓冲区中目前只有两个字符，<e，回车> 读完e之后，可以理解为把e踢出去了，下一个再读回车，然后再读，发现缓冲区没数据了，所以就等待用户输入了 照您这种想法来说，为什么不一直读e呢？ 这里有个博客，刚刚查的，它用开闸放水做了类比，可以参考下

user: user-5
content: 引用 4 楼 a345485527 的回复:lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出  我想问一下，e进入循环两次后，为啥getchar没有字符读了呢，它为什么不一直读换行符呢？

user: user-0
content: 引用 7 楼 a345485527 的回复:[quote=引用 6 楼 u012757050 的回复:] [quote=引用 4 楼 a345485527 的回复:] lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出回车也符合循环条件？不懂。[/quote] ASCII码 十进制 回车13，a是97，满足条件[/quote]了解

user: user-4
content: 引用 6 楼 u012757050 的回复:[quote=引用 4 楼 a345485527 的回复:] lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出回车也符合循环条件？不懂。[/quote] ASCII码 十进制 回车13，a是97，满足条件

user: user-0
content: 引用 4 楼 a345485527 的回复:lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出回车也符合循环条件？不懂。

user: user-5
content: 我想问一下，e进入循环两次后，为啥getchar没有字符读了呢，它为什么不一直读换行符呢？

user: user-4
content: lz我记得你.... getchar吃回车 输入  e 回车，进入循环两次 由于没有字符读了，所以阻塞在while循环中的getchar函数处 输入ead,a不满足循环条件，所以循环退出
user-0 提问: C语言怎样写代理服务器，能实现GET请求和CONNECT请求

回复:
user: user-1
content: 说白了，就是映射一下当前连接，数据转发而已

user: user-2
content: 搜一下socket编程, 一般都有示范代码, 没有特殊要求的话, 代码很简单.
user-0 提问: 【求助帖】循环产生随机数的问题

回复:
user: user-1
content: 应用程序初始化的时候调用即可，比如main函数进入后，即可执行随机种子初始化。

user: user-0
content: 引用 1 楼 user-3 的回复:随机数的种子没有变化， 在主函数里面 加 srand (time (NULL)); 要注意这个函数，放的位置，   函数应该放在哪个位置呢？

user: user-2
content: LS正解，srand(time(NULL));

user: user-3
content: 随机数的种子没有变化， 在主函数里面 加 srand (time (NULL)); 要注意这个函数，放的位置，
user-0 提问: 看看这句话是什么意思

回复:
user: user-0
content: 引用 10 楼 richyhuang 的回复:把ulong型的数据赋给float型的变量,我认为结果没有任何意义。那应该怎么做

user: user-1
content: 把ulong型的数据赋给float型的变量,我认为结果没有任何意义。

user: user-2
content: 这样赋值是不对的吧，没有什么实质作用吧

user: user-2
content: 感觉意义不大啊，语句的作用好像是把long型的值的二进制形式解释成了float值

user: user-0
content: 引用 6 楼 user-3 的回复:你从哪里挖的代码？这段代码是不是用于学习和理解浮点数用的？嘿嘿，在做一个测试，搞不懂，这是别人的程序。

user: user-3
content: 你从哪里挖的代码？这段代码是不是用于学习和理解浮点数用的？

user: user-3
content: 我不十分确定你的目的，很难描述。  可以试试：  unlong1 = strtoul(buf2,NULL,16); f5 = (float)unlong1;

user: user-0
content: 引用 3 楼 user-3 的回复:直接赋值可能得到一个为止的结果。  这句说错了，太绕了。  其实是想说，如果没有经过整型到浮点变化的赋值，会得到一个未知结果。  就说你运行你写那段代码，可能得到未知结果。这句代码应该怎么改，程序原来的语句是这样的：        unlong1 = strtoul(buf2,NULL,16);         *((unsigned long *)&f5)=unlong1; buf2是char类型，长度为 256。如果直接赋值，unlong1和f5就是一样的。这块应该是将unlong1转换成float 类型.谢谢！！

user: user-3
content: 直接赋值可能得到一个为止的结果。  这句说错了，太绕了。  其实是想说，如果没有经过整型到浮点变化的赋值，会得到一个未知结果。  就说你运行你写那段代码，可能得到未知结果。

user: user-0
content: 引用 1 楼 user-3 的回复:有区别，直接赋值，是将一个整型进行浮点变化后，赋值给一个浮点数。  用指针赋值是将浮点数的内存区域直接用整型替换掉，不涉及整形到浮点的变换。  直接赋值可能得到一个为止的结果。  另外这段代码在64位的linux上会有问题。还好，我的是32位系统，我打印输出之后，发现f5是-NAN

user: user-3
content: 有区别，直接赋值，是将一个整型进行浮点变化后，赋值给一个浮点数。  用指针赋值是将浮点数的内存区域直接用整型替换掉，不涉及整形到浮点的变换。  直接赋值可能得到一个为止的结果。  另外这段代码在64位的linux上会有问题。
user-0 提问: 为什么我写的快排比堆排序要慢得多？

回复:
user: user-1
content: for那里。。。是从left到right遍历一次，相当于每次递归，你都要遍历一次，当然你这个有点像动态规划，交换次数可能比插入要少一点  要是序列稍微特殊一点，你这个算法就直接是O(N^2)了

user: user-2
content: 应该是数据分布不佳所致，一般数组小到一个程度转成插入排序，递归过深转为堆排，不要全程都是快排...

user: user-3
content: 先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c

user: user-4
content: 都是用release版本测试的吗？

user: user-5
content: 没看出来这个是快排,感觉你这个复杂度为O(n^2) 因为你一个for,再加了一个递归  感觉像是变形的冒泡~~~~  堆排序复杂度是lgn*n     你这个方法说的不好听的  比2个for还烂  如果设计到数据查找的话,  最好还是用红黑树  每次插入最多做3次旋转即可,当然你这种已经存在大批量的数据的画,最快的还是快排 但是如果是频繁性的插入和查找的话还是应该用rbtree

user: user-6
content: 交换太多  字数补丁
user-0 提问: 求c语言大学课程视频

回复:
user: user-1
content: C语言视频教程:  http://www.tudou.com/plcover/z5u9lwXuPKU/

user: user-2
content: 鱼C论坛上有个C入门视频  既然是大二看起来肯定很轻松

user: user-3
content: “C Primer Plus” 大神书籍，还需要看视频？

user: user-4
content: 百度网盘上有赫斌老师的c语言视频

user: user-5
content: 建议看郝斌的C语言视频，讲的不错，适合入门

user: user-6
content: 建议看国外的~
user-0 提问: ACM A == B ? 问题

回复:
user: user-1
content: 如下修改可AC: #include<stdio.h> #include<string.h>  int main() {      int num,i,j;   static char a[100000],b[100000];//改  char a[100],b[100];   while(scanf("%s%s",a,b)!=EOF)   {     //加 判断正负号     if((a[0]=='-' && b[0]!='-' ) || (a[0]!='-' && b[0]=='-'))     {       printf("NO\n");       continue;     }     if(a[0]=='+' || a[0]=='-')         a[0]='0';       if(b[0]=='+' || b[0]=='-')         b[0]='0';        num=strlen(a);      for(i=0;i<num-1;i++)//改  for(i=0;i<num;i++) 处理前置的0，如果a[0]=0,就把a[1]的值及后面的值向前挪一位      {       if(a[i]=='0')        {//加         for(j=0;j<num;j++)         {           a[j]=a[j+1];           //删 i--;         }         i--;//加        }//加       else break;     }      num=strlen(a);     for(i=0;i<num;i++)//处理后置的0 ，检测到小数点就从最后一位开始检测是否为0，如果是就把0用\0代替        if(a[i]=='.')       {         for(i=num-1;i>0;i--)         {           //printf("ai=%c\n",a[i]);           if(a[i]=='0')             a[i]='\0';           else break;         }       }      if (a[strlen(a)-1]=='.') a[strlen(a)-1]='\0'; //加      //printf("%s\n",a);	      num=strlen(b);     for(i=0;i<num-1;i++)//改 for(i=0;i<num;i++)     {       if(b[i]=='0') //改 if(b[0]=='0')        {//加         for(j=0;j<num;j++)         {           b[j]=b[j+1];           //删 i--;         }         i--;//加        }//加       else break;     }     num=strlen(b);     for(i=0;i<num;i++)       if(b[i]=='.')       {         for(i=num-1;i>0;i--)         {           if(b[i]=='0')             b[i]='\0';           else break;         }       }        //printf("%s\n",b);	     if (b[strlen(b)-1]=='.') b[strlen(b)-1]='\0'; //加      if(strcmp(a,b)==0)       printf("YES\n");     else printf("NO\n");   }   return 0; }

user: user-0
content: 引用 2 楼 ALNG 的回复:如果输入限制在整数，你不用这么辛苦。  如果输入有可能是浮点数，你的程序貌似处理不了1.5e10一类的输入。  建议，先用int试，不行再用double试。用double的话，记得比较相等不要直接用==，看他们的差的绝对值是否小于 epsilon.这个题的坑爹之处就是题目要求太少，可能性太大，我在网上找了AC的代码，思路应该是这样的没错，可是就是不知道哪里有问题   #include <stdio.h> #include <string.h>  void A(char *s) {     int len = strlen(s);     char *p = s + len - 1;     if (strchr(s, '.'))     while (*p == '0') *p-- = 0;     if (*p == '.') *p = 0; }  int main(void) {     char *pa, *pb;     char a[100024], b[100024];      while (scanf("%s%s", &a, &b) != EOF)     {         pa = a; pb = b;         while (*pa == '0') pa++;         while (*pb == '0') pb++;         A(pa); A(pb);         puts(strcmp(pa, pb) ? "NO" : "YES");     }      return 0; }

user: user-2
content: 如果输入限制在整数，你不用这么辛苦。  如果输入有可能是浮点数，你的程序貌似处理不了1.5e10一类的输入。  建议，先用int试，不行再用double试。用double的话，记得比较相等不要直接用==，看他们的差的绝对值是否小于 epsilon.
user-0 提问: 求更好的方法，谭浩强习题讨论

回复:
user: user-1
content: 引用 3 楼 lpcads 的回复:void divproc(int a) //递归函数 { 	if(a!=0) 	{ 		divproc(a/10); 		cout<<a%10<<endl; //显示余数 	} 	return; } int main( )  { 	//若n为0，则需打印出‘0’ 	//if(n==0)  		//cout<<'0'<<endl; 	divproc(n); 	system("pause"); 	return 0; } 这是以前学汇编时的legacy了，功能是顺序输出每一位数字，现在看看写得真烂。 特别改了下： #include <iostream> using namespace std;  void each_digit_recursion(int a) //递归函数 { 	if (a == 0) 		return ;  	each_digit_recursion(a / 10); 	cout << a % 10 << ' '; //显示余数 	 }  void output_each_digit(int a) { 	cout << "each digit: "; 	if (a == 0) 		cout << '0'; 	else 		each_digit_recursion(a);  }   void reverse(int a) { 	cout << "reverse: "; 	while (true) 	{ 		cout << a % 10; 		a /= 10; 		if (a == 0) 			break; 	} 	 }  int main() { 	int n = 1234567; 	cout << "num: " << n << endl; 	output_each_digit(n); 	cout << endl; 	reverse(n);  	cout << endl; 	cout << endl;  	n = 0; 	cout << "num: " << n << endl; 	output_each_digit(n); 	cout << endl; 	reverse(n);  	cout << endl;  	system("pause"); 	return 0; }

user: user-2
content: 首先要明确给出的数字的数据类型  计算机不是人

user: user-1
content: void divproc(int a) //递归函数 { 	if(a!=0) 	{ 		divproc(a/10); 		cout<<a%10<<endl; //显示余数 	} 	return; } int main( )  { 	//若n为0，则需打印出‘0’ 	//if(n==0)  		//cout<<'0'<<endl; 	divproc(n); 	system("pause"); 	return 0; }

user: user-1
content: 使用递归啊。

user: user-3
content: 写的太复杂了，这个会不会简单点？ #include <stdio.h>  int main(void) { 	int a, b = 0, dig, count = 0;  	printf("Please input a integer: "); 	scanf("%d", &a); 	 	while(a) 	{ 		dig = a % 10; 		printf("%d\n", dig);  // 输出每个数字 		b = b * 10 + dig; 		a /= 10; 		count++; 	} 	printf("Digit number is %d\n", count); // 输出位数 	printf("Reverse order is %d\n", b);    // 输出反序 	getchar(); 	getchar(); 	return 0; }
user-0 提问: C控制结构与链表的插入操作问题

回复:
user: user-0
content: 谢谢啦……。

user: user-1
content: 这些地方有错误: 1. print_matrix里面的if(p || p->j==b)应该是if(p && p->==b) 2. create_matrix里面的 	    r=k/M->m; 	    c=k%M->m; 应该改成 	    r=k/M->n; 	    c=k%M->n; 3. Matrix插入节点的函数整个混乱，改无可改，两个链表应该分别插入。    #include "stdio.h" #include "stdlib.h" #include "stdbool.h"  typedef struct node { 	int i,j,val; 	struct node *row,*col; }Node;  typedef struct matrix { 	int m,n; 	struct node *rhead[10],*chead[10]; }Matrix;  Matrix* insert_matrix(Matrix* M,Node* N) { 	/* 分别插入行列链表不就容易了？ 	 */ 	Node *p; 	//插入行链表 	if(!(p=M->rhead[N->i])) 		M->rhead[N->i]=N; 	else{ 		while(p->row && p->j<N->j) 			p=p->row; 		if(p->j<N->j) // append as the last node 			p->row=N; 		else if(p->j==N->j) // update data 		{ 			p->val=N->val; 			free(N); 			// no need to worry about chead list as it's correct already! 			return M; 		}else{ // link in as p's next node 			N->row=p->row; 			p->row=N; 		} 	} 	//插入列链表 	if(!(p=M->chead[N->j])) 		M->chead[N->j]=N; 	else{ 		while(p->col && p->i<N->i) 			p=p->col; 		if(p->i<N->i) // append as the last node 			p->col=N; 		else { // link in as p's next node 			N->col=p->col; 			p->col=N; 		} 	} 	return M; }  Matrix* creat_matrix() { 	Matrix *M; 	Node *N; 	int k,v,r,c; 	M=(Matrix*)malloc(sizeof(Matrix)); 	for(k=0;k<10;k++) 		M->rhead[k]=NULL; 	for(k=0;k<10;k++) 		M->chead[k]=NULL; 	printf("请输入矩阵的行,列数:"); 	scanf("%d%d",&M->m,&M->n); 	printf("请输入矩阵元素:"); 	for(k=0;k<M->m*M->n;k++) 	{ 	 	scanf("%d",&v); 	    r=k/M->n; 	    c=k%M->n; 		if(v!=0) 		{ 		   N=(Node*)malloc(sizeof(Node)); 		   N->i=r;N->j=c; 		   N->val=v; 		   N->row=N->col=NULL; 		   M=insert_matrix(M,N); 	   } 	 }	 	 return M; }  void printf_matrix(Matrix *M) { 	int a,b; 	Node *p; 	for(a=0;a<M->m;a++) 	{ 		p=M->rhead[a]; 		for(b=0;b<M->n;b++) 		{ 			if(p && p->j==b) 			{ 				printf("%d ",p->val); 				p=p->row; 			} 			else 				printf("0 "); 		} 		printf("\n"); 	} }  main ( ) {  Matrix *M;  M=creat_matrix();  printf_matrix(M);  return 0;	 }
user-0 提问:  getchar函数与purchar函数到底是怎样啊？

回复:
user: user-1
content: http://ideone.com/6lWyQm

user: user-2
content: getchar一次读一个字符 putchar一次输出一个字符  BUT  问题的关键在于，你是在一个循环中使用putchar和getchar。

user: user-0
content: 引用 4 楼 a345485527 的回复:[quote=引用 2 楼 u012757050 的回复:] [quote=引用 1 楼 a345485527 的回复:] 输出什么lz跑一次就知道了 getchar一次是只读一个字符，但是是从缓冲区中读取， 输入she walks in beauty会存至缓冲区中，每次取出一个字符，然后Putchar ctrl+z结束  另外，求助she walks in beauty怎么翻译我是新手，未在电脑操作过，请问我输入句子后回车，打印出s吗？ 然后其他字符怎么取出来。[/quote] 会打印整句话 输入句子后，she walks in beauty会存储在缓冲区中 getchar从该缓冲区中一个一个读取字符， 首先读取's'，然后putchar 由于处于while循环中，所以继续调用getchar，这次调用从缓冲区中取出第二个字符'h'，然后putchar 以此类推，一直循环取出每个字符，然后putchar这个字符，所以你会看到输出了完整的一句话 当遇到EOF时结束[/quote]明白 谢谢

user: user-3
content: 引用 2 楼 u012757050 的回复:[quote=引用 1 楼 a345485527 的回复:] 输出什么lz跑一次就知道了 getchar一次是只读一个字符，但是是从缓冲区中读取， 输入she walks in beauty会存至缓冲区中，每次取出一个字符，然后Putchar ctrl+z结束  另外，求助she walks in beauty怎么翻译我是新手，未在电脑操作过，请问我输入句子后回车，打印出s吗？ 然后其他字符怎么取出来。[/quote] 会打印整句话 输入句子后，she walks in beauty会存储在缓冲区中 getchar从该缓冲区中一个一个读取字符， 首先读取's'，然后putchar 由于处于while循环中，所以继续调用getchar，这次调用从缓冲区中取出第二个字符'h'，然后putchar 以此类推，一直循环取出每个字符，然后putchar这个字符，所以你会看到输出了完整的一句话 当遇到EOF时结束

user: user-4
content: getchar只要你输入马上就退出了。

user: user-0
content: 引用 1 楼 a345485527 的回复:输出什么lz跑一次就知道了 getchar一次是只读一个字符，但是是从缓冲区中读取， 输入she walks in beauty会存至缓冲区中，每次取出一个字符，然后Putchar ctrl+z结束  另外，求助she walks in beauty怎么翻译我是新手，未在电脑操作过，请问我输入句子后回车，打印出s吗？ 然后其他字符怎么取出来。

user: user-3
content: 输出什么lz跑一次就知道了 getchar一次是只读一个字符，但是是从缓冲区中读取， 输入she walks in beauty会存至缓冲区中，每次取出一个字符，然后Putchar ctrl+z结束  另外，求助she walks in beauty怎么翻译
user-0 提问: 怎样让程序往txt文件里的字符，在txt里实时显示，最好是往txt里写一个字符，txt文件就显示一个字符

回复:
user: user-1
content: fflush(你打开的文件的指针)

user: user-2
content: FILE *fp; //... fprintf(fp,...); fflush(fp); 不过看需求好像是要实时显示？

user: user-3
content: fflush意味着缓冲区内容写入文件指针（如果参数是一个文件指针的话） 然后 清空缓冲区，是我没有表述明白？

user: user-0
content: 你的意思是写一个字符就flush一次啊 能不能flush函数的语句的给我写一下 我是用fprintf往txt文件写数据的哦

user: user-3
content: 写好数据调用下这个 fflush
user-0 提问: while (getchar () !=‘\n’） continue求解

回复:
user: user-1
content: 如果代码是这样的话： char ch; while ((ch = getchar ()) != ‘#’） { .....若干语句 while (getchar () !=‘\n’） continue; }  那么意味着： 1、某行以#开头的话，结束处理。 2、ch在你所谓的“.....若干语句”中应该有进一步的操作；或者说，以非#字符开头的行的处理被你用“.....若干语句”省略掉了。 3、由于你的while(getchar()!='\n')continue;并没有将取得字符显示保存下来，所以表示在“……若干语句”中的处理之后，跳过了到行末尾的所有输入字符的处理。 4、如果你输入了dev后又敲了回车，并且在此程序内没有其他地方出现getchar()之类的函数的话，那么，显然，程序会对d进行“……若干语句）的处理，然后，跳过ev和回车键的输入，最后，接着等待您进行新的字符的输入，直到输入了#字符。

user: user-0
content: 输入dev后回车，然后呢？

user: user-2
content: 主要的目的是，用户输入dev三个字符的时候，操作系统并不会吧输入立刻传送给程序，一定要遇到回车才会发送字符串，也就是说没有回车，你的程序，两个while都接受不到字符，但是呢\n回车并不是输入想要的，是辅助的，所以就特别处理 \n

user: user-3
content: 改用getch函数会比较符号你的要求。  引用 楼主 u012757050 的回复:char ch while ((ch = getchar ()) != ‘#’） { .....若干语句 while (getchar () !=‘\n’） continue;  假如我输入dev，是不是只有d读入到ch? 第二个while语句是什么意思？是指getchar读取我之前输入的dev，然后全部舍弃吗？  问题补充：如果没有第二个while语句，当第一次输入dev,第二次输入a时，ch会赋予a吗？

user: user-4
content: 第一个是 以# 为结束符，跳出循环  第二个是以\n 回车为结束符,跳出循环  看这写的就取了第一个字符，后面的不要了，若换行（\n）就再取一个，若第一个是#就退出吧
user-0 提问: 請教一支程式的執行流程

回复:
user: user-0
content: 感謝回覆 我是想知道每個程序的步驟 可否幫忙說明一下  感謝您

user: user-1
content: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

user: user-2
content: 他就是这么一步一步的跑下来的啊~~~
user-0 提问: 请教几个服务器端 SOCKET 的问题

回复:
user: user-1
content: 1 上libuv，用过的都说好 2 除了加机器没有什么好办法了 可以参考C10K 3 这个不懂不敢乱说

user: user-2
content: 带宽总要够用吧。

user: user-3
content: 2、大并发，增加服务器，有共享软件可以处理负载平衡 3、如有大数据请求，另开socket通道，参考telnet  1、如果要跨平台，考虑e-poll或其它的共享软件
user-0 提问: C 检测安全密码

回复:
user: user-1
content: #include <stdio.h> #include <string.h> int main() {     int a,i,j,L;     char s[51],c;     int f[4]={0,0,0,0};      scanf("%d",&a);     getchar();     for (i=0;i<a;i++) {         fgets(s,51,stdin);         L=strlen(s);         if ('\n'==s[L-1]) {s[L-1]=0;L--;}         if (8<=L && L<=16) {             for (j=0;j<L;j++) {                 c=s[j];                      if ('a'<=c && c<='z'   ) f[0]=1;                 else if ('A'<=c && c<='Z'   ) f[1]=1;                 else if ('0'<=c && c<='9'   ) f[2]=1;                 else if (strchr("~!@#$%^",c)) f[3]=1;             }             if (f[0]+f[1]+f[2]+f[3]>=3)                 printf("YES\n");             else                 printf("NO\n");         } else  printf("NO\n");     }     return 0; }

user: user-2
content: switch(1) 这种用法是比较少见。

user: user-0
content: 引用 2 楼 FancyMouse 的回复:switch(1) case 1: 给跪怎么了

user: user-0
content: 引用 1 楼 user-6 的回复:LZ程序中switch的用法比较特别。 如下修改可ac: #include<stdio.h> #include<string.h> int main() {   int a,i,j;   char s[51];   scanf("%d",&a);   getchar();//加   for(i=0;i<a;i++)   {     //删 getchar();     gets(s);     if(strlen(s)>=8&&strlen(s)<=16)     {     	int flag[4]={0,0,0,0};       for(j=0;j<strlen(s);j++)       {         switch(1)         {         case 1:if(s[j]>='a'&&s[j]<='z')  flag[0]=1;         case 2:if(s[j]>='A'&&s[j]<='Z')  flag[1]=1;         case 3:if(s[j]>='0'&&s[j]<='9')  flag[2]=1;         case 4:if(s[j]=='~'||s[j]=='!'||s[j]=='@'||s[j]=='#'||s[j]=='$'||s[j]=='%'||s[j]=='^') flag[3]=1;	         }       }       if(flag[0]+flag[1]+flag[3]+flag[2]>=3)         printf("YES\n");       else         printf("NO\n");     }     else printf("NO\n");   }   return 0;//加 }可能就是gets那里的问题，因为我换成scanf就AC了，最后的return 0；我经常不加，有关系吗

user: user-0
content: 引用 3 楼 buyong 的回复:why switch(1)?懒的写if else，用switch比较方便

user: user-3
content: 你的switch case语句块有误，switch(1)就只会执行case :1的语句。既然你的switch中有if分支，那又何必多此一举加switch，直接2层for循环，内部四个分支就够了

user: user-4
content: why switch(1)?

user: user-5
content: switch(1) case 1: 给跪

user: user-0
content: 引用 4 楼 ZXvivian 的回复:你的switch case语句块有误，switch(1)就只会执行case :1的语句。既然你的switch中有if分支，那又何必多此一举加switch，直接2层for循环，内部四个分支就够了因为switch结构后不加break就会按case顺序执行下去,所以我就用这种1方法了

user: user-6
content: LZ程序中switch的用法比较特别。 如下修改可ac: #include<stdio.h> #include<string.h> int main() {   int a,i,j;   char s[51];   scanf("%d",&a);   getchar();//加   for(i=0;i<a;i++)   {     //删 getchar();     gets(s);     if(strlen(s)>=8&&strlen(s)<=16)     {     	int flag[4]={0,0,0,0};       for(j=0;j<strlen(s);j++)       {         switch(1)         {         case 1:if(s[j]>='a'&&s[j]<='z')  flag[0]=1;         case 2:if(s[j]>='A'&&s[j]<='Z')  flag[1]=1;         case 3:if(s[j]>='0'&&s[j]<='9')  flag[2]=1;         case 4:if(s[j]=='~'||s[j]=='!'||s[j]=='@'||s[j]=='#'||s[j]=='$'||s[j]=='%'||s[j]=='^') flag[3]=1;	         }       }       if(flag[0]+flag[1]+flag[3]+flag[2]>=3)         printf("YES\n");       else         printf("NO\n");     }     else printf("NO\n");   }   return 0;//加 }
user-0 提问: 请用C实现过电信短信网关SMGP3.0协议的大侠进来看下

回复:
user: user-0
content: 现在有logresp是有了 问题每次都返回21  卡在这了 你Q多少 讨论讨论

user: user-1
content: 同样的 问题 不知道 楼主找到答案了吗？

user: user-0
content: 这是我抓到tcp包  前8字节是账号 接着16字节是md5密码 1字节 登录模式  1字节版本  4字节 时间戳   做过的大侠帮忙看看是不是这样的

user: user-2
content: 遇到这种问题，可以抓下tcp包。按照SMGP3.0协议，看下报文是否正确。

user: user-0
content: MSG_Login log;     log.nLoginMode = 0x0;     log.nVersion = 0x30;     time_t a = time(NULL);     struct tm *time  = gmtime(&a);     log.nTimeStamp = (time->tm_mon+1)*100000000+time->tm_mday*1000000+time->tm_hour*10000+time->tm_min*100+time->tm_sec;     strcpy(log.sUser, "xxxxxxxx");     MD5_CTX md5;     MD5Init(&md5);     UCHAR md5res[16];     MD5Update(&md5, (unsigned char*)"xxxxxxxx", strlen("xxxxxxxx"));     MD5Final(&md5,md5res);     int i;     for(i=4;i<12;i++)     {         sprintf(log.sAuthenMD5+(i-4)*2, "%02x",md5res[i]);     }    以上是本人LOGIN包的内容  麻烦各位大侠看看有没什么问题     发过去之后连接直接被网关给断开了
user-0 提问: 关于大端模式读数的问题

回复:
user: user-1
content: 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-1
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

user: user-1
content: 0000:0000 68 10 a7 00 8b 01 70 00-16 00 a9 03 8b 01 70 00 ..... 表示从内存地址0000:0000处开始有16个字节68 10 a7 00 8b 01 70 00 16 00 a9 03 8b 01 70 00  因为是以小端模式保存，所以 0000:0000处开始的两个字节68 10可以看作是一个4位十六进制数0x1068，其中0x10为高字节，0x68为低字节， 0000:0000处开始的四个字节68 10 a7 00可以看作是一个8位十六进制数0x00a71068，其中0x00a7为高字，0x1068为低字。  如果是以大端模式保存，那么 0000:0000处开始的两个字节68 10可以看作是一个4位十六进制数0x6810，其中0x68为高字节，0x10为低字节， 0000:0000处开始的四个字节68 10 a7 00可以看作是一个8位十六进制数0x6810a700，其中0x6810为高字，0xa700为低字。  2位十六进制，即 8位二进制为一个字节。 4位十六进制，即16位二进制为一个字。 8位十六进制，即32位二进制为一个双字。

user: user-2
content: 是6810h，小端模式才是1068h。  引用 楼主 mounty_fsc 的回复:对于这么一串数0000:0000 68 10 a7 00 8b 01 70 00-16 00 a9 03 8b 01 70 00 有数0x1068    MS-DOS大端模式，10h为高位 68h为低位，所以  0000:0000 68 10 a7 00 8b 01 70 00-16 00 a9 03 8b 01 70 00.....  左边是地址高位，右边是地址低位? 要如何理解？ 为什么 68 10 读出来是1068h?
user-0 提问: 有序二叉树的递归

回复:
user: user-0
content: 引用 3 楼 ALNG 的回复:OK 根节点问左右子树，你们各有多少节点。  左右子树又分别问他们的左右子树....  一直到页节点。叶节点忘了算自己，说是0. 收到这个消息的上级节点，很遗憾，它的左右子树基于同样的原因都报自己高度为0，而它也不知道算上自己，还是向上级报0. 就这样一层骗一层，一直骗到档中央---根节点发现左右子树都是0个子树，忘了算自己它就把0报告给外部世界了。   高度计算的理由同此。  你用颗简单的树模拟一下就知道了。一直走到叶节点，啥都明白了。可以看出递归的总数是从一个一个1累加来的，如果把这个1换0了，多少个0相加也走不出0的黑洞。赞～！例子生动活泼引人入胜绕梁三日不知肉味

user: user-1
content: 递归函数的运行有两种了解方法，一种是抽象层次上，就像数学公式一样理解。    二叉树的节点数=1. 树是空树时，为0， 否则             2. 1+左（子)数的节点数+右（子树)的节点数  你看这个公式本身就是递归的，读懂这个公式，就读懂了抽象意义上的递归。  另外一种是从特定的实现细节上理解。有点简单的汇编常识更容易明白上面的抽象的公式形成的递归函数在具体的硬件上是怎样执行的。这个你可以用一个相对简单的二叉树，单步执行跟踪一下，最好把堆栈的情形看清楚。

user: user-1
content: OK 根节点问左右子树，你们各有多少节点。  左右子树又分别问他们的左右子树....  一直到页节点。叶节点忘了算自己，说是0. 收到这个消息的上级节点，很遗憾，它的左右子树基于同样的原因都报自己高度为0，而它也不知道算上自己，还是向上级报0. 就这样一层骗一层，一直骗到档中央---根节点发现左右子树都是0个子树，忘了算自己它就把0报告给外部世界了。   高度计算的理由同此。  你用颗简单的树模拟一下就知道了。一直走到叶节点，啥都明白了。可以看出递归的总数是从一个一个1累加来的，如果把这个1换0了，多少个0相加也走不出0的黑洞。

user: user-0
content: 引用 1 楼 ALNG 的回复:1是节点自身啊。比如根节点左子树有10个节点，右子树犹20个节点，那总结点数是不是10+20+1（自己)? 所以  int tjjd(node * n) {     int count;           if(!n)         return 0;     count=1;     if(n->left)         count+=tjjd(n->left);     if(n->right)         count+=tjjd(n->right); }  或者 int tjjd(node * n) {     return n==NULL?0:1+tjjd(n->left)+tjjd(n->right);  }   高度也一样，一颗树的高度为max(左子树高度，右子树高度)+1（这个1也是根节点自身)   typedef struct node node; #define max(a,b)  ((a)<(b)?(b):(a))  int height(node *n) {      return n==NULL?0:1+max(height(n->left),height(n->right)); } 这个我知道阿，为就想问为什么不加一就会输出0，不是应该就少1个节点吗

user: user-1
content: 1是节点自身啊。比如根节点左子树有10个节点，右子树犹20个节点，那总结点数是不是10+20+1（自己)? 所以  int tjjd(node * n) {     int count;           if(!n)         return 0;     count=1;     if(n->left)         count+=tjjd(n->left);     if(n->right)         count+=tjjd(n->right); }  或者 int tjjd(node * n) {     return n==NULL?0:1+tjjd(n->left)+tjjd(n->right);  }   高度也一样，一颗树的高度为max(左子树高度，右子树高度)+1（这个1也是根节点自身)   typedef struct node node; #define max(a,b)  ((a)<(b)?(b):(a))  int height(node *n) {      return n==NULL?0:1+max(height(n->left),height(n->right)); }