Question: 神秘的C语言问题，考考你们这些货们。

引用 89 楼 nadleeh123 的回复:[quote=引用 85 楼 gemo 的回复:] 对LZ这种人就应该狠狠地打击一下。  vs2008:   gcc4.6:  貌似lz歇菜了[/quote] 这几天到北京出差修摄像机去了，昨天才回来。

引用 114 楼 lovesmiles 的回复:虽然我不是高手，但这样理解这句话：  x++ + inc(); 1 先x++,再inc().那么结果是2 2先inc(),再x++,结果还是2.  难道不是2吗？这个结果根本就不用理会它的执行顺序吧。prinft语句和他们又不是在同一个序列点 你这样说，是我发现所有发言中比较靠谱的。函数比较特殊。a+b，a和b的求值可能交错。但a+f()就不同了。你能想像a的求值和f的执行是交错的吗？f()+g()，这两个函数可能会交错执行吗？标准中是有明确说法的。

引用 85 楼 gemo 的回复:对LZ这种人就应该狠狠地打击一下。  vs2008:   gcc4.6:  这也叫打击？ 我用的最新版的gcc，也是1呢。但是，扣标准的话，它就应该是2。 编译器说明不了什么问题，还谈何打击。

首先，认为这种题没有意义的可以不用费神了。  前面有人认为问题的焦点在于以下这个条款： The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified,but there is a sequence point before the actual call. 这句的意思是，对于表达式f(e)，f和e的求值顺序是未指定的，但它们前序于函数体的执行。  实际上，问题的焦点不在这里。考虑一个一般意义上的表达式Ｅ１+Ｅ２，假如Ｅ１和Ｅ２都不是函数调用表达式，根据本版那个没什么大用的置顶帖，Ｅ１和Ｅ２的求值是unsequenced（无序的）。也就是说，可能先求值Ｅ１再求值Ｅ２，也可能相反，也可能交叉求值，求值包括副作用的值的计算。  不过，标准显然考虑到了函数执行的特殊性。考虑一下表达式f(a)+g(b)，f、g、a和b的求值是unsequenced（无序的），但是，这两个函数的函数体执行不可能是无序的，因为，不可能对f和g的函数体反复交错执行。对吧？所以，可能是先执行f的函数体，再执行g的函数体，或者相反。但无论如何，唯一可以确定的是，a的求值前序于f函数体的执行，b的求值前序于g函数体的执行。  再来看表达式x++ +inc()。表面上看，x++和inc的求值是无序的。但是，我已经说过了，最重要的那一句是 N1570，6.5.2.2:  Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.  很明显，x++可以在inc()函数体执行之前，或者之后求值。inc的求值必然发生在inc函数体执行之前（前序于函数体执行），但不可能与x++交错执行，因为N1570，6.5.2.4： The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix++is a single evaluation.

引用 96 楼 supermegaboy 的回复:不过，对于楼主的结论，偶现在仍有保留意见。由于工作忙，偶现在还没时间详细看C11关于序列点的叙述，但把C11与C++11两者的相关内容粗略比较了一下，发现两者是基本一致的，问题是，g++4.8.1（已完全支持C++11）出来的结果是1，鉴于gcc一贯良好的编译器质量，所以这个问题现在还不能说就是2了。 C11跟C++11还是有些差别的。 比如int a = 42; a = ++a;在C++11里就不算UB但是C11还是。 然后是概念上的。C++11直接移除了sequence point的说法，用sequenced before代替。C11保留两者。 所以具体问题上这里没可比性。

引用 94 楼 nadleeh123 的回复:[quote=引用 93 楼 FrankHB1989 的回复:] [quote=引用 92 楼 nadleeh123 的回复:] [quote=引用 91 楼 FrankHB1989 的回复:] [quote=引用 89 楼 nadleeh123 的回复:] [quote=引用 85 楼 gemo 的回复:] 对LZ这种人就应该狠狠地打击一下。  vs2008:   gcc4.6:  貌似lz歇菜了[/quote] 艹gcc不开-std=c11 -pedantic么。 [/quote] 我会告诉你一大堆arm mips mipsel ppc powerpc等等一大堆16bit 32bit 64bit的编译器依然是默认89标准[/quote] LZ都明确说用什么了，你现在默认的有什么说服力。 而且gcc默认是gnu89，要是测VLA或者//什么的支持是不是还要怀疑撞鬼了？ （顺便，clang是gnu99。） [/quote] 有明确说用啥么，我咋只看见了一堆废代码？[/quote] LZ早就说了用N1570。 难道还要正版ISO/IEC 9899:2011？反正我敢确定这两个版本在这里的问题上没什么区别。

擦，+是左结合性，看编译器语法分析与优化！有毛线的研究意义？如果实际项目中有人给我写出这样代码来，我非要他给我重写去！可读性差，bug潜在强

引用 104 楼 supermegaboy 的回复:但实际上g++4.8.1的结果是1，这也是一个间接的证据。 咦。我找了个在线的4.8.1，结果也是2啊。

凡是人造的东西都有缺陷。 标准也是人造的。

凡是人造的东西都有缺陷。 编译器也是人造的。

引用 104 楼 supermegaboy 的回复:问题的焦点在于以下这个条款：  The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified,  but there is a sequence point before the actual call.  这里出现了两种理解（或许更多，但现在只发现两种）：  一是这里所说的序列点也是函数调用之前其它子表达式的序列点；  二是这里所说的序列点的作用范围只包括前半句所说的函数指示符、实参及其子表达式；  看完gcc的bug报告，我坚持第二种理解。因为：  1、标准条款前半句和后半句之间是一个逗号（我用红色标出来），这表示后半句承接的是前半句的意思，因而，那个序列点表达的意思是：在此序列点达到的时候，函数指示符、实参及子表达式的副作用被完全计算（不包括之前的子表达式）；  2、如果标准想表达这个序列点也作用于函数调用之前的子表达式的话，应该新起一个子条款，而不是跟在陈述函数指示符、实参及其子表达式这样一句范围受到限定的语句中。  所以，这个场景符合未定义的情景。但是，出于尊重你的观点的立场，我也接受以下说法：标准关于此处的描述比较模糊，没有表达精确的意思。  此外，BUG报告中版本范围限定在4.5、4.6、4.7，但实际上g++4.8.1的结果是1，这也是一个间接的证据。 这句话只说明了存在有一个sequence point，没有任何sequence point作用范围的描述。你那么大一段全是臆测。 C99的原文： At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. seq pt就是这么定义的。seq pt的存在性我们没有疑问，那么除非你能告诉我插在函数前后的那俩seq pt和这里定义的seq pt不是同一种seq pt，否则我不觉得这seq pt还有什么作用域的限制。  顺便，我手头4.8.2输出2。

引用 102 楼 FancyMouse 的回复:[quote=引用 101 楼 supermegaboy 的回复:] [quote=引用 44 楼 FancyMouse 的回复:] [quote=引用 30 楼 supermegaboy 的回复:] 你没想通的事情是，由于C/C++标准规定在两序列点之间发生的多于一次的副作用属于未定义行为，所以x++和inc中的x++的后缀增量在x++ + inc();语句的分号前何时发生是不确定的；x++的++有可能在+inc( )之前发生，当然也有可能在x+inc( )之后再发生两次++，这些行为取决于编译器设计者，因而造成可能的结果为0---4之间。 即使用旧标准你这句话也是不对的。函数调用前后都有sequence point，如果外面的x++在inc之前发生，那么在进入inc之前被进入函数的sequence point已经保证了副作用已经发生。如果外面的x++在inc之后发生，那么离开inc的seq point保证了外面的x++起始x值已经是被inc给++过的。 另外别用某些版本的gcc试。几个旧版本在这点上有bug的。[/quote]  请重新学习一下什么是undefined behaviour，如果标准规定这个行为是implmentation defined或者unspecified，那么你的想法就是有道理的。但作为未定义行为，作为错误的代码结构，其结果是不能以常理去推测的，你不能依然企盼编译器设计者还会为你做帕拉图式的收尾。一个常见的例子是超过提升后类型二进制宽度的移位，同一个编译器会出现不同的结果。[/quote] 我当然知道undefined behavior怎么回事。问题是那个代码符合标准，根本就不是什么undefined。  楼上几个测gcc的，bug在这里：http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814 注意直到4.7这bug还是有。  注意那个bug里的例子，你们如果把它和a[i]=++i认为是一回事的话那我只能摊手。[/quote]  问题的焦点在于以下这个条款：  The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified,  but there is a sequence point before the actual call.  这里出现了两种理解（或许更多，但现在只发现两种）：  一是这里所说的序列点也是函数调用之前其它子表达式的序列点；  二是这里所说的序列点的作用范围只包括前半句所说的函数指示符、实参及其子表达式；  看完gcc的bug报告，我坚持第二种理解。因为：  1、标准条款前半句和后半句之间是一个逗号（我用红色标出来），这表示后半句承接的是前半句的意思，因而，那个序列点表达的意思是：在此序列点达到的时候，函数指示符、实参及子表达式的副作用被完全计算（不包括之前的子表达式）；  2、如果标准想表达这个序列点也作用于函数调用之前的子表达式的话，应该新起一个子条款，而不是跟在陈述函数指示符、实参及其子表达式这样一句范围受到限定的语句中。  所以，这个场景符合未定义的情景。但是，出于尊重你的观点的立场，我也接受以下说法：标准关于此处的描述比较模糊，没有表达精确的意思。  此外，BUG报告中版本范围限定在4.5、4.6、4.7，但实际上g++4.8.1的结果是1，这也是一个间接的证据。

引用 114 楼 lovesmiles 的回复:虽然我不是高手，但这样理解这句话：  x++ + inc(); 1 先x++,再inc().那么结果是2 2先inc(),再x++,结果还是2.  难道不是2吗？这个结果根本就不用理会它的执行顺序吧。prinft语句和他们又不是在同一个序列点 前提是先考虑清楚没有未定义行为。 涉及后置++坑爹你应该懂的。

用编译软件试一下不就知道了吗

引用 101 楼 supermegaboy 的回复:[quote=引用 44 楼 FancyMouse 的回复:] [quote=引用 30 楼 supermegaboy 的回复:] 你没想通的事情是，由于C/C++标准规定在两序列点之间发生的多于一次的副作用属于未定义行为，所以x++和inc中的x++的后缀增量在x++ + inc();语句的分号前何时发生是不确定的；x++的++有可能在+inc( )之前发生，当然也有可能在x+inc( )之后再发生两次++，这些行为取决于编译器设计者，因而造成可能的结果为0---4之间。 即使用旧标准你这句话也是不对的。函数调用前后都有sequence point，如果外面的x++在inc之前发生，那么在进入inc之前被进入函数的sequence point已经保证了副作用已经发生。如果外面的x++在inc之后发生，那么离开inc的seq point保证了外面的x++起始x值已经是被inc给++过的。 另外别用某些版本的gcc试。几个旧版本在这点上有bug的。[/quote]  请重新学习一下什么是undefined behaviour，如果标准规定这个行为是implmentation defined或者unspecified，那么你的想法就是有道理的。但作为未定义行为，作为错误的代码结构，其结果是不能以常理去推测的，你不能依然企盼编译器设计者还会为你做帕拉图式的收尾。一个常见的例子是超过提升后类型二进制宽度的移位，同一个编译器会出现不同的结果。[/quote] 我当然知道undefined behavior怎么回事。问题是那个代码符合标准，根本就不是什么undefined。  楼上几个测gcc的，bug在这里：http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814 注意直到4.7这bug还是有。  注意那个bug里的例子，你们如果把它和a[i]=++i认为是一回事的话那我只能摊手。

引用 44 楼 FancyMouse 的回复:[quote=引用 30 楼 supermegaboy 的回复:] 你没想通的事情是，由于C/C++标准规定在两序列点之间发生的多于一次的副作用属于未定义行为，所以x++和inc中的x++的后缀增量在x++ + inc();语句的分号前何时发生是不确定的；x++的++有可能在+inc( )之前发生，当然也有可能在x+inc( )之后再发生两次++，这些行为取决于编译器设计者，因而造成可能的结果为0---4之间。 即使用旧标准你这句话也是不对的。函数调用前后都有sequence point，如果外面的x++在inc之前发生，那么在进入inc之前被进入函数的sequence point已经保证了副作用已经发生。如果外面的x++在inc之后发生，那么离开inc的seq point保证了外面的x++起始x值已经是被inc给++过的。 另外别用某些版本的gcc试。几个旧版本在这点上有bug的。[/quote]  请重新学习一下什么是undefined behaviour，如果标准规定这个行为是implmentation defined或者unspecified，那么你的想法就是有道理的。但作为未定义行为，作为错误的代码结构，其结果是不能以常理去推测的，你不能依然企盼编译器设计者还会为你做帕拉图式的收尾。一个常见的例子是超过提升后类型二进制宽度的移位，同一个编译器会出现不同的结果。

引用 108 楼 FancyMouse 的回复:[quote=引用 104 楼 supermegaboy 的回复:] 但实际上g++4.8.1的结果是1，这也是一个间接的证据。 咦。我找了个在线的4.8.1，结果也是2啊。[/quote]  中午在公司下载了个4.8.1，这回见鬼了，结果是2，但在家里明明是1的，可能在家编译时搞错了什么东西。不过无论如何，重新仔细思考了一下，我同意这个不是未定义行为，对104楼的条款理解有误。

引用 99 楼 jiandingzhe 的回复:去看置顶贴！！！！ 置顶早就不够用了。  引用 100 楼 lzhui1987 的回复:[quote=引用 49 楼 sholber 的回复:] [quote=引用 21 楼 lin5161678 的回复:] 这种事 可以让你去看置顶 到考虑到鼠侠你一直是专研标准  那就这样回答好了  i++ + f(i) 这里 的确存在序列点  问题是 这个序列点值确认了 f(i)的确会让 i+1  但没确认 i++ 的时候 已经调用了 f(i) 对于i++ 可以在 f(i) 之前求值 这时候 i++的值是0 也可以是在f(i)之后求值 这时候 i++的值是1  so 依然是一个未定义行为你们知道序列点就稍微好办一点。 你先弄懂 求值（evaluation） 前序（sequenced before） 后序（sequenced after） 无序（unsequenced） 不确定顺序（indetermined sequenced） 这些概念，然后再看看C11草案N1570，6.5.2.2:  Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.[/quote]   心算是1，但是用GCC编译执行打印1，用VS2010编译执行打印2，能打印出2实在不解，x++的后自增操作符优先级较低，不是在自增之前函数已经返回了吗？？？[/quote]  优先级这种纯语法上的东西跟这里说的有什么关系？ 副作用发生在文件作用域对象上，返回值又没用到，x在inc()求值以后存储了什么值跟inc的返回有什么关系？  顺便，我手头的mingw-w64-gcc-4.8.2和clang-3.5的结果都是2。


Question: 如何在c中获取bash的输出

有种东西叫管道 		dup2(sock, 0); 		dup2(sock, 1); 		execl(shell,"/bin/sh",(char *)0);

单就"如何在c中获取bash的输出 " man popen 你要的是这个?

为何要山寨，vim都有源码。


Question: c扫雷

真的有点儿长有点儿乱，倒杯水喝口茶，哈哈，来看一看代码


Question: 同一C语言程序在VC和codeblocks上运行结果不同，原因是什么？

求回文数这些写太复杂啦，把数字转字符串，倒序输出即可...

1-检查自己的程序的逻辑性 2.-采用GCC吧

双精度数转成整数时损失了精度，转换之前加个0.5就好了

从工具上找原因不如从程序上找。


Question: 这个两种写法有什么不同？把i--放在while循环体内和把i--放在条件判段中

while(i < j && a[j--] >= pivot) 主要是：第二中情况是a[j--] >= pivot条件不满组时，j还多自减了一次。

引用 9 楼 lm_whales 的回复:JiMoKuangXiangQu 的回复是正确的；  JiMoKuangXiangQu 好像是大神级别的。  shimachao 只有不会吧？三个字加一个问号，是错误的。 理解的是和JiMoKuangXiangQu一样的。 不过，不知道为什么会问出这个“不会吧？”。  [quote=引用 1 楼 JiMoKuangXiangQu 的回复:] j--和i++在前一种情况下，要同时满足 i < j && a[j] >= pivot 或 i < j && a[i] < pivot才会被执行； 后一种情况下，只要i < j，j--和i++都会被执行。 ++[/quote] 进入思维定式了

引用 5 楼 fuyongming 的回复:第二种写法不管后面的条件成不成立，i,j的值都会变。第一种写法只有整个条件成立才变化。  正解，本人也是小白，学习了。。。。

条件成为才执行

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

JiMoKuangXiangQu 的回复是正确的；  JiMoKuangXiangQu 好像是大神级别的。  shimachao 只有不会吧？三个字加一个问号，是错误的。 理解的是和JiMoKuangXiangQu一样的。 不过，不知道为什么会问出这个“不会吧？”。  引用 1 楼 JiMoKuangXiangQu 的回复:j--和i++在前一种情况下，要同时满足 i < j && a[j] >= pivot 或 i < j && a[i] < pivot才会被执行； 后一种情况下，只要i < j，j--和i++都会被执行。 ++

同意fuyongming的说法  第二种写法不管后面的条件成不成立，i,j的值都会变。第一种写法只有整个条件成立才变化。

引用 2 楼 shimachao 的回复:[quote=引用 1 楼 JiMoKuangXiangQu 的回复:] j--和i++在前一种情况下，要同时满足 i < j && a[j] >= pivot 或 i < j && a[i] < pivot才会被执行； 后一种情况下，只要i < j，j--和i++都会被执行。 不会吧？ while(i < j && a[j--] >= pivot)条件判断应该是i < j为假的话 后面的a[j--]>=pivot也不会执行了。 判断被短路了。  也就是说  A && B ，A为真的情况下才会去判断B。难道不是吗？ [/quote] 请仔细看回复：后一种情况下，只要i < j，j--和i++都会被执行。[/

这二种是j无条件减一，第一种是条件成立才减一，楼上说得对

引用 3 楼 user-10 的回复:while(i < j && a[j--] >= pivot)在跳出循环时后j = j - 1 而while(i < j && a[j] >= pivot)跳出循环后j不变 以前在写strcpy()、strcmp()时也碰到这种问题

引用 1 楼 JiMoKuangXiangQu 的回复:j--和i++在前一种情况下，要同时满足 i < j && a[j] >= pivot 或 i < j && a[i] < pivot才会被执行； 后一种情况下，只要i < j，j--和i++都会被执行。 不会吧？ while(i < j && a[j--] >= pivot)条件判断应该是i < j为假的话 后面的a[j--]>=pivot也不会执行了。 判断被短路了。  也就是说  A && B ，A为真的情况下才会去判断B。难道不是吗？


Question: 刚学数据结构，为何程序老是停止运行

typedef struct Node { unsigned char Element; struct Node * Next; } Node, *List;

Node *head;  Node *create()//建立链表，这是第一步； { 	Node *p,*q; 	head=NULL; 	int temp; 	cout<<"Now create the list,Input the data,end by -1:"<<endl; 	cin>>temp; 	while(temp!=-1) 	{ 		p=new Node; 		p->Element=temp; 		if(head==NULL) 			head=p; 		else 		{ 			q->Next=p; 		} 		q=p; 		cin>>temp; 	} 	if(head!=NULL) 		q->Next=NULL; 	return head; }  void PrintList(List L){  	int i = 0;  	Node *p = L; 	 	if (p == NULL){ 		printf("此表为空表\n"); 		return; 	} 	 	while (p!=NULL) 	{ 		printf("第%d个元素为%d\n", ++i, p->Element); 		p = p->Next; 	} }

引用 5 楼 wanren13 的回复:LZ把结构体也发一下吧，一般来说一个类或结构体就够了，你又有List 又有Node 头文件List.h #ifndef _List_H  struct Node; typedef struct Node *Node; typedef Node List;  List CreatList(int n); void Insert(int x, List L, int i); void PrintList(List L);  #endif

引用 5 楼 wanren13 的回复:LZ把结构体也发一下吧，一般来说一个类或结构体就够了，你又有List 又有Node 我发一下我的程序吧，麻烦您看看，谢谢了 主程序test.c #include "List.h" #include <stdio.h>  void main(){ 	List L = CreatList(5);         PrintList(L); }

引用 5 楼 wanren13 的回复:LZ把结构体也发一下吧，一般来说一个类或结构体就够了，你又有List 又有Node  我的node和list都是指向一个结构体的，我用的c，没有用c++的

我觉得你是不是应该检查下你定义的结构体，和你传到这里void PrintList(List L)的参数之类的有没有问题，   printf("第%个元素为%\n", ++i, p->Element); 这个printf 编译过了？

L和L->next是不一样的。 L如果为空，L->next就是非法操作，程序就会终止。

引用 1 楼 u012033027 的回复:你是不是应该先判一下L是否为空？ 我这里List L是指向的链表的头结点（我定义的链表有头结点的），在函数最开始我不是判定了L->next是否为空了么？

你是不是应该先判一下L是否为空？


Question: GDB如何调试带参数可执行文件？

gdb --args ./a.out ff 或者  gdb ./a.out r ff

你这样的不行的吧，不然我早弄出来了  引用 1 楼 Enter_ 的回复:gdb ./a.out ff

囧……哪里来的 ./

gdb ./a.out ff


Question: 求语音识别算法的理解！

你可以结合别人做的例子（最好是完整例子）看看。因为计算机里面的实现是离散的更容易理解。


Question: 问个将结构体写入文件然后读取的问题！

引用 8 楼 abcdql520 的回复:问题都解决了，原因是有几处地方写成了 w 模式  文件都呗清空了 恭喜

问题都解决了，原因是有几处地方写成了 w 模式  文件都呗清空了

引用 6 楼 lm_whales 的回复:1）用2进制编辑器，打开文件，看看写入的信息有没有问题. 2）有没有正确关闭文件. 3）文本方式（Text） 打开，要文本方式（Text） 读写 fscanf,fprintf，二进制（Binary） 打开要 二进制（Binary）  写 read,write.  目测，你用文本方式打开，用二进制在读写 文本方式 加"t",二进制方式加“b”,两者都不加，等同于加"t" "rt","r"文本方式 “rb” 二进制方式  PS: 读写方式，和打开方式不一致，不能保证结果正确。  我试试，谢谢回答

原谅我的代码都在Linux系统下面，win7下面没有，所以不能贴太多代码 注册：fread (  temp ,sizeof(user_t) ,1, fp);     //user_t是那个结构类型，temp是 user_t  类型的临时存放的变量

引用 2 楼 user-2 的回复:读写文件的过程不会有问题吧，你就调试看看，写入文件的和读出来的是否一样。  我运行程序，注册登录都没问题  但是一但我退出了程序，然后启动程序，这时候，就只有注册可以了，不能登录

读写文件的过程不会有问题吧，你就调试看看，写入文件的和读出来的是否一样。


Question: 求教！！！！C语言迷宫用图形界面显示出足迹

http://bbs.csdn.net/topics/390748108 如果觉得这不算图形界面。 参考下面：#include <windows.h> #include <gdiplus.h> using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib") VOID OnPaint(HDC hdc) {    Graphics     graphics(hdc);    Pen          pen(Color(255, 0, 0, 255));    FontFamily   fontFamily(L"宋体");    Font         font(&fontFamily, 12, FontStyleRegular, UnitPixel);    PointF       pointF1(30.0f, 60.0f),pointF2(230.0f, 60.0f);    SolidBrush   solidBrush(Color(255, 0, 0, 255));    StringFormat stringFormat;    WCHAR testString[] = L"Hello034∠你好";     stringFormat.SetFormatFlags(StringFormatFlagsDirectionVertical);     graphics.SetSmoothingMode(SmoothingModeDefault);    graphics.DrawLine(&pen, 0, 0, 200, 100);    graphics.DrawEllipse(&pen, 10, 10, 190, 90);    graphics.SetTextRenderingHint(TextRenderingHintSystemDefault);    graphics.DrawString(testString, -1, &font, pointF1, &stringFormat, &solidBrush);      graphics.SetSmoothingMode(SmoothingModeHighQuality);    graphics.DrawLine(&pen, 200, 0, 400, 100);    graphics.DrawEllipse(&pen, 210, 10, 190, 90);    graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);    graphics.DrawString(testString, -1, &font, pointF2, &stringFormat, &solidBrush); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {    HDC          hdc;    PAINTSTRUCT  ps;     switch(message) {    case WM_PAINT:       hdc = BeginPaint(hWnd, &ps);       OnPaint(hdc);       EndPaint(hWnd, &ps);       return 0;    case WM_DESTROY:       PostQuitMessage(0);       return 0;    default:       return DefWindowProc(hWnd, message, wParam, lParam);    } } INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {    HWND                hWnd;    MSG                 msg;    WNDCLASS            wndClass;    GdiplusStartupInput gdiplusStartupInput;    ULONG_PTR           gdiplusToken;     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);     wndClass.style          = CS_HREDRAW | CS_VREDRAW;    wndClass.lpfnWndProc    = WndProc;    wndClass.cbClsExtra     = 0;    wndClass.cbWndExtra     = 0;    wndClass.hInstance      = hInstance;    wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);    wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);    wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);    wndClass.lpszMenuName   = NULL;    wndClass.lpszClassName  = TEXT("GettingStarted");     RegisterClass(&wndClass);     hWnd = CreateWindow(       TEXT("GettingStarted"),   // window class name       TEXT("Getting Started"),  // window caption       WS_OVERLAPPEDWINDOW,      // window style       CW_USEDEFAULT,            // initial x position       CW_USEDEFAULT,            // initial y position       CW_USEDEFAULT,            // initial x size       CW_USEDEFAULT,            // initial y size       NULL,                     // parent window handle       NULL,                     // window menu handle       hInstance,                // program instance handle       NULL);                    // creation parameters     ShowWindow(hWnd, iCmdShow);    UpdateWindow(hWnd);     while(GetMessage(&msg, NULL, 0, 0)) {       TranslateMessage(&msg);       DispatchMessage(&msg);    }     GdiplusShutdown(gdiplusToken);     return 0; }

可以用opengl画界面

翻了些网页难道要用TC？

自己也看了些源程序代码，感觉还是有图形界面更过瘾，就是不知道怎么弄！！

还有就是昨晚已经安装好了easyx2014,现在用的是VC6.0


Question: 这么创建链表对不对，正规规吗？

//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

哇塞，不错！

好吧，我写错了，我理解错什么是头节点了

还有个问题，mallo后得记着free啊。。。

你这样在main里面创建链表那多蛋疼，定义一个函数创建，能成功那你对指针的理解会更深

可以   可以把结构体指针的声明直接放到node后面    这样比较简练一点

可以，没有问题


Question: 关于【更新保存在文件中的结构类型的数据】的问题，文件读写的一点问题，求教各位！！！！！！！

这个好像是需要fseek 这个函数的  但是不知道具体怎么操作  这些个东西也是周五从学的，这个是老师布置的作业

static?坐等大牛


Question: 问两个问题

还是没看懂。。为什么输出不是2.。。虽然平时不会这样做。。但是知道其中奥秘是 一件有意义的事

引用 7 楼 kzh125 的回复:[quote=引用 5 楼 PDD123 的回复:] int __cdecl printf( char * _Format, ...); 上面的是printf的申明，你看其形参，逗号后面是一段省略号，表示可以带一串实参。 这种类型的函数，前面的参数中要有指明后面参数格式的数据。在传递参数的时候，后面的参数并不会转化类型，而是直接入栈。  而普通的函数，比如四楼的函数： [quote=引用 4 楼 u012538549 的回复:] func(int a)；     int  main(void) {        float  a=2.5;          func(a)； }  func(a)；相当于是 func(int(a))；  所以：          float  a=2.5;                  printf("%d\n",a);  a是作为一个float传进去的，而没有经过类型转换[/quote]     那作为float入栈之后呢。。输出是怎么取的啊[/quote] 输出就是按照第一个参数"%d\n"，来输出的，%d表示按照整型数来输出，具体你看资料。

int __cdecl printf( char * _Format, ...); 上面的是printf的申明，你看其形参，逗号后面是一段省略号，表示可以带一串实参。 这种类型的函数，前面的参数中要有指明后面参数格式的数据。在传递参数的时候，后面的参数并不会转化类型，而是直接入栈。  而普通的函数，比如四楼的函数： 引用 4 楼 u012538549 的回复:func(int a)；     int  main(void) {        float  a=2.5;          func(a)； }  func(a)；相当于是 func(int(a))；  所以：          float  a=2.5;                  printf("%d\n",a);  a是作为一个float传进去的，而没有经过类型转换

引用 5 楼 PDD123 的回复:int __cdecl printf( char * _Format, ...); 上面的是printf的申明，你看其形参，逗号后面是一段省略号，表示可以带一串实参。 这种类型的函数，前面的参数中要有指明后面参数格式的数据。在传递参数的时候，后面的参数并不会转化类型，而是直接入栈。  而普通的函数，比如四楼的函数： [quote=引用 4 楼 u012538549 的回复:] func(int a)；     int  main(void) {        float  a=2.5;          func(a)； }  func(a)；相当于是 func(int(a))；  所以：          float  a=2.5;                  printf("%d\n",a);  a是作为一个float传进去的，而没有经过类型转换[/quote]     那作为float入栈之后呢。。输出是怎么取的啊

同样的二进制码用不同的指令去取就能得到不同的数据：定义float a=2.5  那么a中的数据就用浮点指令去取   得到2.5   输出的时候使用的是整数指令去取数据然后输出 func(int a)；     int  main(void) {        float  a=2.5;          func(a)； } 这个和传参不同    传参等同于赋值，是字面值的赋值      是把a的值取出来然后赋值给形参     像这样int a=2.5   截断后 a=2    不涉及从地址用指令取值       置于为什么是0    我也不清楚     我用int* pa=(int*)&a  然后*pa和1<<31与  来打印二进制码   得到0100 0000 0010  0000 0000 0000 0000 0000

float类型不能用%d输入，也不能用%d输出

第一个问题，我调试了一下，发现也是零。可能这与float和int转换有关系。

输入小数的时候循环直接跳过 是因为你残留在输入缓冲区里的小数部分不符合 scanf("%d",&a);的标准，实际上scanf函数是返回失败的，你可以查看下scanf的返回值

第一个问题我认为也是2    我这边不好测试     第二个问题：比如你输入3.1    缓冲区中就放入3.1   scanf第一次读取数据，是整数就读  不是就放回   所以第一次读取到3    遇到.就把.返回到缓冲区函数直接返回  实际a中第一次保存的是3  所以打印1    以后每次冲缓冲区读取数据都会读取到.  每次读取发现不在0-9之间  就把数据放回到缓冲区  函数直接返回


Question: 一个结构体问题

你把打印的改下吧 printf("address = %x\n",t [0].next);     printf("address = %x\n",t[1].next); 试试

问题发现了，我还定义了一个Lnode[B]，同样在for循环之后想给最后一个节点的next设置为NULL。但是实际代码却写的是：B[i].next = NULL; 然而B[i]对应的地址和A[0]的地址是一样的。我想这应该和程序运行时的堆栈有关吧，但是自己对其中的原理还是不太明白，是否有可以帮我解答的，谢谢！下面是我打印的数组各成员的地址：A数组有6个成员，B数组有4个成员，先定义了A然后定义B。 初始化：address = 22fde0 初始化：address = 22fdf0 初始化：address = 22fe00 初始化：address = 22fe10 初始化：address = 22fe20 初始化：address = 22fe30 add of B is 22fda0 add of B is 22fdb0 add of B is 22fdc0 add of B is 22fdd0

不好意思，粘贴的时候少了。 typedef struct node Lnode;

Lnode 是什么  你弄错了吧  我这里是正常的

结构体名字叫node，函数参数却是Lnode，LZ怎么编译过去的？ 改为Lnode后，我这运行正常，MinGW  初始化：address = 22ff18 初始化：address = 22ff20 初始化：address = 22ff28 初始化：address = 22ff30 初始化：address = 22ff38 初始化：address = 22ff40 address = 0  address = 22ff18 address = 22ff20 node 0 is 5     node 1 is 10    node 2 is 15    node 3 is 20    node 4 is 25 The last node is 30==0 请按任意键继续. . .


Question: n发子弹打靶打中的平均环数超过或等于九环则通过，求n发子弹打中环数的所有组合错在哪里，还有代码不太明白

引用 5 楼 u010107248 的回复:那个char **argv是二级指针吗？大神！！我刚入门啊。。。[quote=引用 4 楼 zhao4zhong1 的回复:] 仅供参考#include <stdio.h> #include <stdlib.h> #define MAX_NUM 26 int comb[MAX_NUM]; int c1,c2; void combination(int m,int n) {     int i,j;      for (i=m;i>=n;i--) {         comb[n]=i; /* 选择当前的“头”元素 */         if (n>1) {             combination(i-1,n-1); /* 进入下一次更小的组合问题 */         } else { /* 满了需要的组合数，输出 */             for (j=comb[0];j>0;j--) printf("%c",'A'+c1-comb[j]);             printf("\n");         }     }     return; } int main(int argc,char **argv) {     if (argc<3) {         printf("%s 组合下标 组合上标\n",argv[0]);         return 1;     }     c1=atoi(argv[1]);     if (c1<1 || MAX_NUM<c1) {         printf("1<=组合下标<=%d\n",MAX_NUM);         return 2;     }     c2=atoi(argv[2]);     if (c2<1 || c1<c2) {         printf("1<=组合上标<=组合下标\n");         return 3;     }     comb[0]=c2;     combination(c1,c2);     return 0; }  引用 4 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <stdlib.h> #define MAX_NUM 26 int comb[MAX_NUM]; int c1,c2; void combination(int m,int n) {     int i,j;      for (i=m;i>=n;i--) {         comb[n]=i; /* 选择当前的“头”元素 */         if (n>1) {             combination(i-1,n-1); /* 进入下一次更小的组合问题 */         } else { /* 满了需要的组合数，输出 */             for (j=comb[0];j>0;j--) printf("%c",'A'+c1-comb[j]);             printf("\n");         }     }     return; } int main(int argc,char **argv) {     if (argc<3) {         printf("%s 组合下标 组合上标\n",argv[0]);         return 1;     }     c1=atoi(argv[1]);     if (c1<1 || MAX_NUM<c1) {         printf("1<=组合下标<=%d\n",MAX_NUM);         return 2;     }     c2=atoi(argv[2]);     if (c2<1 || c1<c2) {         printf("1<=组合上标<=组合下标\n");         return 3;     }     comb[0]=c2;     combination(c1,c2);     return 0; } [/quote]  这是main函数的标准写法之一，刚入门就应该掌握。

那个char **argv是二级指针吗？大神！！我刚入门啊。。。引用 4 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <stdlib.h> #define MAX_NUM 26 int comb[MAX_NUM]; int c1,c2; void combination(int m,int n) {     int i,j;      for (i=m;i>=n;i--) {         comb[n]=i; /* 选择当前的“头”元素 */         if (n>1) {             combination(i-1,n-1); /* 进入下一次更小的组合问题 */         } else { /* 满了需要的组合数，输出 */             for (j=comb[0];j>0;j--) printf("%c",'A'+c1-comb[j]);             printf("\n");         }     }     return; } int main(int argc,char **argv) {     if (argc<3) {         printf("%s 组合下标 组合上标\n",argv[0]);         return 1;     }     c1=atoi(argv[1]);     if (c1<1 || MAX_NUM<c1) {         printf("1<=组合下标<=%d\n",MAX_NUM);         return 2;     }     c2=atoi(argv[2]);     if (c2<1 || c1<c2) {         printf("1<=组合上标<=组合下标\n");         return 3;     }     comb[0]=c2;     combination(c1,c2);     return 0; }  引用 4 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <stdlib.h> #define MAX_NUM 26 int comb[MAX_NUM]; int c1,c2; void combination(int m,int n) {     int i,j;      for (i=m;i>=n;i--) {         comb[n]=i; /* 选择当前的“头”元素 */         if (n>1) {             combination(i-1,n-1); /* 进入下一次更小的组合问题 */         } else { /* 满了需要的组合数，输出 */             for (j=comb[0];j>0;j--) printf("%c",'A'+c1-comb[j]);             printf("\n");         }     }     return; } int main(int argc,char **argv) {     if (argc<3) {         printf("%s 组合下标 组合上标\n",argv[0]);         return 1;     }     c1=atoi(argv[1]);     if (c1<1 || MAX_NUM<c1) {         printf("1<=组合下标<=%d\n",MAX_NUM);         return 2;     }     c2=atoi(argv[2]);     if (c2<1 || c1<c2) {         printf("1<=组合上标<=组合下标\n");         return 3;     }     comb[0]=c2;     combination(c1,c2);     return 0; }

求环数和 >= n* 9 的组合数 由于是组合数，所以可以不考虑顺序 1）所有都大于9环（m 10 ,n-m 9）若干 2）所有都等于9环只有一种情况 3）m 个10，K个9 混合 n -m-k 个9一下 >= 若干， 4）m个10 n -m 个9一下 >= 若干 5）m个10 n -m 个9一下 >= 若干  所有组合若干 如果求排列。方法一样

你的问题都说的不清楚，怎么解答啊，你的算法目的是什么，说清楚啊。


Question: 关于文件读写的一点问题，求高人解答！

上面那个结果图截的有问题，可能不能正确表示我的问题 充值前： qian  aaaaaa      0.00   0  充值后，比如我充值4： qian  aaaaaa      0.00   0 qian  aaaaaa      4.00   0  充值后并没有改变原来的数据，只是新加了个数据


Question: #define 公用引脚  应该写在哪里

感谢！ 原来globals.h里是这样的： #ifdef GLOBALS  #define EXT #else #define EXT extern  #endif ......//EXT  函数原型  然后我在下面写了这个就没问题了： #ifndef COMMON_DEFS_H #define COMMON_DEFS_H #define Pin_DianJi1             GPIO_Pin_3  //... #endif // COMMON_DEFS_H

如果把这句话写在app.c 或者 app.c 和A.c都包含的includes.h  你这个方法是错的， 宏应该放在includes.h中而不是app.c中。

写一个头文件CommonDefs.h：  #ifndef COMMON_DEFS_H #define COMMON_DEFS_H  #define Pin_DianJi1	    	 GPIO_Pin_3  //...  #endif // COMMON_DEFS_H  然后 app.c 和A.c都： #include "CommonDefs.h"


Question: Oj上的一道题。为什么错了。。测试数据正常呀。。。

5) 班级贡献奖，每人850元，班级评议成绩高于80分（>80）的学生干部均可获得； if((head->averScore >80) && (head->stuCadre=='Y'))


Question: C 讀入txt

fgetc()

用文件操作函数 fopen(filename, "r"); //打开文件 fgetc() //读取一个字节

查看编译器词法分析以及有限自动机相关知识！

C:\>findstr /? 在文件中寻找字符串。  FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/F:file]         [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]         strings [[drive:][path]filename[ ...]]    /B         在一行的开始配对模式。   /E         在一行的结尾配对模式。   /L         按字使用搜索字符串。   /R         将搜索字符串作为一般表达式使用。   /S         在当前目录和所有子目录中搜索匹配文件。   /I         指定搜索不分大小写。   /X         打印完全匹配的行。   /V         只打印不包含匹配的行。   /N         在匹配的每行前打印行数。   /M         如果文件含有匹配项，只打印其文件名。   /O         在每个匹配行前打印字符偏移量。   /P         忽略有不可打印字符的文件。   /OFF[LINE] 不跳过带有脱机属性集的文件。   /A:attr    指定有十六进位数字的颜色属性。请见 "color /?"   /F:file    从指定文件读文件列表 (/ 代表控制台)。   /C:string  使用指定字符串作为文字搜索字符串。   /G:file    从指定的文件获得搜索字符串。 (/ 代表控制台)。   /D:dir     查找以分号为分隔符的目录列表   strings    要查找的文字。   [drive:][path]filename              指定要查找的文件。  除非参数有 /C 前缀，请使用空格隔开搜索字符串。 例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或 "there"。'FINDSTR /C:"hello there" x.y' 文件 x.y  寻找 "hello there"。  一般表达式的快速参考:   .        通配符: 任何字符   *        重复: 以前字符或类别出现零或零以上次数   ^        行位置: 行的开始   $        行位置: 行的终点   [class]  字符类别: 任何在字符集中的字符   [^class] 补字符类别: 任何不在字符集中的字符   [x-y]    范围: 在指定范围内的任何字符   \x       Escape: 元字符 x 的文字用法   \<xyz    字位置: 字的开始   xyz\>    字位置: 字的结束  有关 FINDSTR 常见表达法的详细情况，请见联机命令参考。

引用 楼主 hydra0305 的回复:大一下學期要我們寫一個PROJECT 讀入一個input.txt 並判斷內容的字元 Identifier 字串 符號 並記錄他的[X,Y]位置  想請問要如何讀入那個TXT並一個一個讀入字元? 並跳過'   ', '\n' 这是要写词法分析器的节奏啊，呵呵。 果真如此，网络上有太多资源。


Question: 链表插入后输出问题。。。

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

好吧，因为你态度很好，朕看了一下程序，原因找到了： LNode head;  create_list(&head); 以上，你传了head的地址给create_list的实参。 但是你忘了，create_list的实参也是一个对象（变量），虽然名字都是head。因此， int create_list(link_list head)  {  int NodeNum;  link_list PNode;  head=(link_list)malloc(sizeof(LNode));  //本来在进入当前函数前，head就指向一个有效的LNode，现在可好，你毁了这个指针,令它指向一个新的LNode.当前函数返回后,你创建的所有LNode,以及整个华丽的LNode链,都再也找不到了.  /* …… */ } 当前函数返回时，你等于啥也没做，head还是原来的head。特别是head.next仍是无效值。

引用 1 楼 sholber 的回复:1，程序太长； 2，C++版块就在隔壁。  呃 这才多少行啊！！！

1，程序太长； 2，C++版块就在隔壁。


Question: 数组引用出问题了，晕了

c语言里局部变量定义必须在函数的头部

引用如果把*p=str[index];改成*p=str[1];就正常了  问题应该在其他地方。

str越界，导致栈内存中的数据被破坏，index的值应该不是1，不仅index, 连p的指针变量都危险。

*p=str[index];需要访问栈; *p=str[1];不需要访问栈. 说不定是栈的问题. 谁知道在进入当前函数之前,你的各个段寄存器和程序布局是咋弄的.单凭这一个函数,搞不清楚滴.

怀疑index != 1，改改代码试一下就知道了

这个应该没有问题吧？？另外这个str是越界了，加上最后面的0，一共要4个的。但是为什么会造成这种现象，实在不得而知。。。待大牛解释。

int index=1; if(index == 1) ...  试试，肯定是str[3]越界了

在使用Turbo Debuger在DosBox中运行和调试。

char str[3]="Int"; 越界了, 字符串算上结尾的'\0'有4个字符

引用 2 楼 truelance 的回复:c语言里局部变量定义必须在函数的头部 你说的是哪年月的事情啊？快睡醒吧，这都C11啦！


Question: 绝对地址赋值问题

指针的实质是地址，表示这个指针变量是存放的是变量地址，但是你要搞清楚为什么会有不同类型的指针，不同类型指针的差异就在于你如何去解释你所指向的这段内存地址的含义。单纯一个地址没有任何意义，需要转换这是语法的规定，不是你想象的那样

要是不加强制转换的话  0x67a9就是一个整数，可以赋值给int，但是不能赋值给指针 所以要用int*把它转为指针

OK, 我了解了,谢谢各位. 4楼的,你让我下午又看了一下午资料....

*(int *)0x67A9 = 0xaa55; 强制转换,是必要的。其他都不是必要的。  ptr这个指针变量，没有必要存在。有他也不为错。

问题是 （int *） 这东西就瞬间变地址了呢, int后面跟一个* 是什么意思?

ptr本身是一个指针，给他赋值应该是地址，而0x67A9只是一个普通的16进制数，（int *）是强制类型转换，不 用这个编译都过不了


Question: 【求助】关于程序跳过语句的问题啊！！！！

fflush(stdin);

在第二个scanf之前加上getchar()来接收第一个scanf的回车字符 for(i=0;i<100;i++)     {             printf(">>>请输入第%3d个数：",i+1);             scanf("%d",&num[i]);             if(0 == num[i])             {                 printf(">>>您输入了数字0，是否将其作为结束标志？(Y/N)\n"); 				getchar();//接收第一个scanf的回车字符                 scanf("%c",&end);                 if('Y'==end || 'y'==end)                 {                     i = 100;                     break;                 }             }             n = i+1;     }     putchar('\n');

printf(">>>您输入了数字0，是否将其作为结束标志？(Y/N)\n"); 因为这句printf输出了一个换行符，换行被后面的scanf语句当做输入了 在第二句scanf语句前面加一句getchar();


3.0库已经弱化这个函数，为了保持向后兼容，它会给出警告！取而代之将是gtk_grid_new()。你在编译时候指定2.0库就不会有这个警告了！

好久没用gtk，不甚了解，可能3.0的库有什么不同吧。这个应该没有多大问题，你想用垂直的就用垂直的，想用水平的就用水平的。


Question: 再问个scanf的问题

引用 2 楼 jhams 的回复:这是我项目代码里的一句，是回到打印行的左上角啊，结果确实是这样 啊，为什么我试验的时候不行啊？ 能否给一下，上下文的代码？ 楼上的兄弟NB。 我的试验代码如下。  int main() { 	puts("sdfsafsdfsdf"); 	puts("sdfsafsdfsdf"); 	printf("\033[2J");	// clear and goto 0, 0 	return 0; }  输出结果是： sdfsafsdfsdf sdfsafsdfsdf [2JPress any key to continue

\033[2J 相当于 ESC[2J  http://www.termsys.demon.co.uk/vtansi.htm

这是我项目代码里的一句，是回到打印行的左上角啊，结果确实是这样

这个不行啊。 我试验了一下的。 不过移动光标到原点这个有办法的。 printf("\r"); 即可。

#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }

搜“ANSI.SYS”  ANSI escape sequences for cursor movement, graphics, and keyboard settings  In the following list of ANSI escape sequences, the abbreviation ESC represents the ASCII escape character 27 (1Bh), which appears at the beginning of each escape sequence.  ESC[PL;PcH     Cursor Position: Moves the cursor to the specified position     (coordinates). If you do not specify a position, the cursor moves to the     home position--the upper-left corner of the screen (line 0, column     0). This escape sequence works the same way as the following Cursor     Position escape sequence.  ESC[PL;Pcf     Cursor Position: Works the same way as the preceding Cursor Position     escape sequence.  ESC[PnA     Cursor Up: Moves the cursor up by the specified number of lines without     changing columns. If the cursor is already on the top line, ANSI.SYS     ignores this sequence.  ESC[PnB     Cursor Down: Moves the cursor down by the specified number of lines     without changing columns. If the cursor is already on the bottom line,     ANSI.SYS ignores this sequence.  ESC[PnC     Cursor Forward: Moves the cursor forward by the specified number of     columns without changing lines. If the cursor is already in the     rightmost column, ANSI.SYS ignores this sequence.  ESC[PnD     Cursor Backward: Moves the cursor back by the specified number of     columns without changing lines. If the cursor is already in the leftmost     column, ANSI.SYS ignores this sequence.  ESC[s     Save Cursor Position: Saves the current cursor position. You can move     the cursor to the saved cursor position by using the Restore Cursor     Position sequence.  ESC[u     Restore Cursor Position: Returns the cursor to the position stored     by the Save Cursor Position sequence.  ESC[2J     Erase Display: Clears the screen and moves the cursor to the home     position (line 0, column 0).  ESC[K     Erase Line: Clears all characters from the cursor position to the     end of the line (including the character at the cursor position). ……


Question: 对本版置顶贴的几点质疑

不要从中文抠词了，要从c标准的英文版中去理解。 从英文到中文的过程，就有含义的弱变！ 你有时间瞅它这文章，还不如有那时间好好读读原本标准怎么说的呢

>程序设计中应该贯彻的规则是：如果在任何“完整表达式”（形成一段由顺序点结束的计算）里存在对同一“变量”的多个引用，那么表达式里就不应该出现对这一“变量”的副作用，否则就不能保证得到预期结果。 >这么说来，i = i + 1也不能得到预期的结果了。因为这里对i多次引用，而且出现了副作用 除了这点以外，其他的几个吐槽我就觉得lz在抠词，没啥建设性意见。

引用 2 楼 sholber 的回复:[quote=引用 1 楼 user-4 的回复:] C和C++标准在csdn都可以下载到。楼主为何不引用标准来给出你所谓的答案呢。 这还用得着下载，电脑里有现成的。 朕不想长篇大论，忙里偷闲，捣乱一下，好玩而已。 [/quote]捣乱也不多给点分

引用 1 楼 user-4 的回复:C和C++标准在csdn都可以下载到。楼主为何不引用标准来给出你所谓的答案呢。 这还用得着下载，电脑里有现成的。 朕不想长篇大论，忙里偷闲，捣乱一下，好玩而已。

C和C++标准在csdn都可以下载到。楼主为何不引用标准来给出你所谓的答案呢。


Question: scanf问题

引用 3 楼 jhams 的回复:。。。没查到 N1570  Committee Draft — April 12, 2011 ISO/IEC 9899:201x 7.21.6.4 The scanf function Synopsis 1 #include <stdio.h> int scanf(const char * restrict format, ...); Description 2 The scanf function is equivalent to fscanfwith the argument stdin interposed before the arguments toscanf. Returns 3 The scanf function returns the value of the macroEOFif an input failure occurs before the first conversion (if any) has completed. Otherwise, the scanf function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

试了一下，是输入字符串的限制长度，超过就截断

唉，不明白就动手练。 下面的代码，%9s，当输入的字符超过9个时，只接受前9个输入。 这样意思就明白了。  #include<stdio.h> int main() { 	char pcRead[10]; 	scanf("%9s", pcRead); 	puts(pcRead);  	return 0; }

http://www.cplusplus.com/reference/cstdio/scanf/:  width	Specifies the maximum number of characters to be read in the current reading operation (optional).

应该是长度吧

。。。没查到

查书去````

查书去


Question: 求大神解决

你自己先弄，弄完再说。退朝！！！

引用 3 楼 sholber 的回复:[quote=引用 2 楼 zjq9931 的回复:] 以前不知道有这个格里拉公式，学习了，作为回报，附上程序和注释。 希望楼主提供一下自己学习所用的书本。  int main() { 	double dQuarterPi=1.0;	//初始值 	double dx;				//1/3,1/5,1/7…… 	int ix=0; 	char pcPi1[100];		//结果存储 	char pcPi2[100];		//结果存储 	for(dx = 3; ; dx+=2) 	{ 		if(ix%2)				//计数，一次加，一次减 		{ 			dQuarterPi += 1/dx; 		} 		else 		{ 			dQuarterPi -= 1/dx; 		} 		sprintf(pcPi2, "%f", dQuarterPi*4);//数值转换成字符型 		if( 0!=memcmp(pcPi1, pcPi2, 5) )	//比较前5个字节，3.+小数点后三位 		{ 			strcpy(pcPi1, pcPi2);			//不同，则保存上一次的结果 		} 		else 		{ 			printf("%s\n", pcPi1);			//5个字节相同则输出。 			break; 		} 		ix++; 	} 	return 0; }  程序写得很工整，但是很要命。[/quote] 为什么恨要命？

引用 2 楼 zjq9931 的回复:以前不知道有这个格里拉公式，学习了，作为回报，附上程序和注释。 希望楼主提供一下自己学习所用的书本。  int main() { 	double dQuarterPi=1.0;	//初始值 	double dx;				//1/3,1/5,1/7…… 	int ix=0; 	char pcPi1[100];		//结果存储 	char pcPi2[100];		//结果存储 	for(dx = 3; ; dx+=2) 	{ 		if(ix%2)				//计数，一次加，一次减 		{ 			dQuarterPi += 1/dx; 		} 		else 		{ 			dQuarterPi -= 1/dx; 		} 		sprintf(pcPi2, "%f", dQuarterPi*4);//数值转换成字符型 		if( 0!=memcmp(pcPi1, pcPi2, 5) )	//比较前5个字节，3.+小数点后三位 		{ 			strcpy(pcPi1, pcPi2);			//不同，则保存上一次的结果 		} 		else 		{ 			printf("%s\n", pcPi1);			//5个字节相同则输出。 			break; 		} 		ix++; 	} 	return 0; }  程序写得很工整，但是很要命。


Question: 请大神告知，为什么我的程序陷入死循环

谢谢各位了！

引用 7 楼 u012421456 的回复:[quote=引用 6 楼 sholber 的回复:] [quote=引用 5 楼 u012421456 的回复:] 你循环里的代码就无法结束循环啊！比如说你输入一个7，则执行完 n=n/3; 语句后，n = 2,然后s=s+n; s = 2，接着j=n%3; j = 0， n还是2不变，继续循环，n变成了0，然后不再改变，根本无法结束啊！lz代码哪来的？还是自己写的？ 这样的代码正表明的确是他自己写的。抄袭可耻，原创光荣！[/quote] 如果是自己写的，建议lz好好看看循环方面的内容，这个代码只要往下推一下就可以找到问题啊！学习方法很重要，对于学习，我个人的建议是遇到不会的就仔细想想，想不出来就看书，看不出来就谷歌百度，再不行了来论坛，这样的流程下来，许多问题就被解决了，而且自己也能体会到学习的快乐，何乐而不为呢？ [/quote] 可不是咋的。有道理！顶！！

引用 6 楼 sholber 的回复:[quote=引用 5 楼 u012421456 的回复:] 你循环里的代码就无法结束循环啊！比如说你输入一个7，则执行完 n=n/3; 语句后，n = 2,然后s=s+n; s = 2，接着j=n%3; j = 0， n还是2不变，继续循环，n变成了0，然后不再改变，根本无法结束啊！lz代码哪来的？还是自己写的？ 这样的代码正表明的确是他自己写的。抄袭可耻，原创光荣！[/quote] 如果是自己写的，建议lz好好看看循环方面的内容，这个代码只要往下推一下就可以找到问题啊！学习方法很重要，对于学习，我个人的建议是遇到不会的就仔细想想，想不出来就看书，看不出来就谷歌百度，再不行了来论坛，这样的流程下来，许多问题就被解决了，而且自己也能体会到学习的快乐，何乐而不为呢？

引用 5 楼 u012421456 的回复:你循环里的代码就无法结束循环啊！比如说你输入一个7，则执行完 n=n/3; 语句后，n = 2,然后s=s+n; s = 2，接着j=n%3; j = 0， n还是2不变，继续循环，n变成了0，然后不再改变，根本无法结束啊！lz代码哪来的？还是自己写的？ 这样的代码正表明的确是他自己写的。抄袭可耻，原创光荣！

那就说明while条件始终为真，即n！=1

首先我不知道你到底要干嘛， 说说程序的问题吧， n = n / 3不能保证n最后为1，因此会出现死循环的情况，比如n = 7; 在使用while()时，里面的条件一定要保证在某种情况时结束

n最后的值是稳定到0。。。0不等于1

while(n!=1)  {  n=n/3;


Question: 数据结构里单链表读取里第14行的j>i条件的作用是什么？

引用 2 楼 my_live_123 的回复:非法值的处理：当i<=0都是非法的，函数进来没有立即处理。转移到你问的哪里处理的。因为当i非法时候，while循环是不执行的，p这个时候是非空，！p为假，继续执行||后的j>i此时就处理这种i非法的情况！ 当p为空的时候，！p为真，此时是不考虑j>i的 非常感谢 回答的很清晰  另外谢谢一楼的提醒

看起来应该是这样。不过也许i传入了一个非法值，如0，这时候就可能出现j > i了。 不过对参数的检查应该是刚进入函数就检查了。 贴代码最好格式化一下，否则别人没什么耐心去看。  /* 初始条件：顺序线性表L已存在，1≤i≤ListLength(L) */ /* 操作结果：用e返回L中第i个数据元素的值 */ Status GetElem(LinkList L, int i, ElemType *e) { 	int j; 	LinkList p;     /* 声明一结点p */ 	p = L->next;     /* 让p指向链表L的第一个结点 */ 	j = 1;      /*  j为计数器 */ 	while (p && j < i)  /* p不为空或者计数器j还没有等于i时，循环继续 */ 	{ 		p = p->next;  /* 让p指向下一个结点 */ 		++j; 	} 	if (!p || j>i)     //就是这里的j>i 按照前一个while循环，j最大只会到j=i啊 		return ERROR;  /*  第i个元素不存在 */ 	*e = p->data;   /*  取第i个元素的数据 */ 	return OK; }


Question: 进制转换

引用 15 楼 ak47_wz 的回复:[quote=引用 14 楼 sholber 的回复:] [quote=引用 11 楼 ak47_wz 的回复:] 题意有点没说清楚。 应该他想考的其中一个知识点是，补码和原码的转换。但是他没说清楚。或者他故意不说，这个我不懂。可能他认为，计算机中负整数是按照补码来存储的，所以自己来转换。答案应该是D。如果是无符号数的话，211，这个应该是没什么问题的。 如果是有符号，最高位是符号位1，表示负数，将补码转为原码，符号位不变，其余位取反，末位+1，即10101101，也就是-45. 就算按楼主的题意，在假定它是一个负数的情况下，你能确定它是按2的补码存储，还是按1的补码存储？[/quote] 你来给个答案吧。[/quote] C标准允许不同的实现可以选择1的补码或者2的补码方式。 按楼主的要求，如果10101101这个二进制序列是一个负数，那么，如果是按2的补码形式存储，则它对应的十进制数是-45；如果是按1的补码形式存储的，则它对应的十进制数是-82。

引用 14 楼 sholber 的回复:[quote=引用 11 楼 ak47_wz 的回复:] 题意有点没说清楚。 应该他想考的其中一个知识点是，补码和原码的转换。但是他没说清楚。或者他故意不说，这个我不懂。可能他认为，计算机中负整数是按照补码来存储的，所以自己来转换。答案应该是D。如果是无符号数的话，211，这个应该是没什么问题的。 如果是有符号，最高位是符号位1，表示负数，将补码转为原码，符号位不变，其余位取反，末位+1，即10101101，也就是-45. 就算按楼主的题意，在假定它是一个负数的情况下，你能确定它是按2的补码存储，还是按1的补码存储？[/quote] 你来给个答案吧。

引用 11 楼 ak47_wz 的回复:题意有点没说清楚。 应该他想考的其中一个知识点是，补码和原码的转换。但是他没说清楚。或者他故意不说，这个我不懂。可能他认为，计算机中负整数是按照补码来存储的，所以自己来转换。答案应该是D。如果是无符号数的话，211，这个应该是没什么问题的。 如果是有符号，最高位是符号位1，表示负数，将补码转为原码，符号位不变，其余位取反，末位+1，即10101101，也就是-45. 就算按楼主的题意，在假定它是一个负数的情况下，你能确定它是按2的补码存储，还是按1的补码存储？

引用 10 楼 u010328107 的回复:一个字节8位的 哪个告诉你的？建议你捶他一顿。

unsigned int atou(const char *s)  61 {  62         unsigned int i = 0;  63         while (isdigit(*s))  64                 i = i * 10 + (*s++ - '');  65         return i;  66 }

一个字节8位的

设某单字节整数的二进制形式为11010011，其分别作为有符号和无符号整数转换为十进制形式为？ A -211 211 B -83 83 C -44 211 D -45 211

忙得不沓糊涂，给弄错了。反正一个字节最少是8位，而你那又是8位，直接转换后赋给signed char即可。因为char 到底等效于signed char还是unsigned char是由实现定义的。 printf("%d\n", (signed char)strtol("11010011", 0, 2));

忙糊涂了，上面的答案不对。

一个字节多少位，哪种编码方式，可以由C的实现自由处理，只要程序中不做任何假定即可： unsigned char c = strtol("11010011", 0, 2);     printf("signed:%d, unsigned:%d\n", (signed char)c, c); 以上仅供参考。

引用 4 楼 sholber 的回复:[quote=引用 3 楼 u014044789 的回复:] int main(){ char *str="11010011"; printf("%ld",strtol(str,NULL,2));} 1，一个字节不一定非得是8位，有可能是9位、18位，等等。C语言只是规定1个字节至少8个比特。如果一个字节被定义成超过8位，正负值的十进制形式是一样的。你这么写就是错的。  2，你那个二进制比特串，到底是什么编码？是采用2的补码形式还是1的补码形式，没说清楚。如果一个字节8个比特，两种补码形式要分别判定处理，你这么写也是错的。[/quote] 能帮我看看这个题么，我不会写，谢谢 http://bbs.csdn.net/topics/390745070

引用 3 楼 u014044789 的回复:int main(){ char *str="11010011"; printf("%ld",strtol(str,NULL,2));} 1，一个字节不一定非得是8位，有可能是9位、18位，等等。C语言只是规定1个字节至少8个比特。如果一个字节被定义成超过8位，正负值的十进制形式是一样的。你这么写就是错的。  2，你那个二进制比特串，到底是什么编码？是采用2的补码形式还是1的补码形式，没说清楚。如果一个字节8个比特，两种补码形式要分别判定处理，你这么写也是错的。

有一个是211吧，哪一个就不知道了

这题出得没头没脑。 1，一个字节不一定非得是8位，有可能是9位、18位，等等。C语言只是规定1个字节至少8个比特； 2，你那个二进制比特串，到底是什么编码？是采用2的补码形式还是1的补码形式，没说清楚。


Question: 这两种循环选择有何区别，对于我的程序第一种循环选择可以，而第二种不可以，这是为啥？求求高手指教

多谢

第一种循环提取两次字符，第二种循环只提取一个字符 其实第一种循环，第一个字符是输入的Y,为真，继续||后的第二个getchar不执行；如果输入的非Y，第二个getchar得到的是“回车”。 我觉得你输入Y能成功，输入y就应该退出循环了

while( getchar() == 'Y' || getchar() == 'y' ); 这里获取了两次字符，你说呢，

区别在于，第一种循环，其实也有错误。他调用了两次getchar（），第二个getchar（）其实是把回车给吃掉了。第二种循环，他没有吃掉回车，导致下次循环的时候，读取到的字符将是回车，也就是‘\n'。 解决的方法可以刷新一下缓冲区。或者多吃掉那个回车符就行了。

我测试了一下，第一种循环有问题吧，getchar()应该是运行了两次，如下代码输入'y'时，就结束循环了， 输出：1，空格 显然不是你要的功能# include <stdio.h>  int main() { 	int i = 0; 	char ch; 	do 	{ 		i++; 	}while((ch = getchar()) == 'Y' || (ch = getchar()) == 'y');  	printf("%d,%c\n", i, ch); 	return 0; }

你需要的是fflush(stdin) scanf路遇回车，请看楼下分解

新手，说一下我的意见 为什么我的感觉是第一种不可以，第二种可以呢？ 第一种while语句里的getchar到底执行几次呢？ 这个貌似不太对


Question: C程序运行崩溃

引用 3 楼 majia2011 的回复:void *pt=p1  不要说咱眼力好，一看断言，我就知道那错了  厉害！！ok了，3Q~

引用 4 楼 u010875363 的回复:[quote=引用 2 楼 sholber 的回复:] bool str_in(char **); ？？？？？？？？？？？？？？？ bool str_in(char *);  在CSDN呆了好几天，没意思。  char **貌似没问题啊，指向char指针的指针。变元&pS[i]为pS[i]的地址，即指向pS[i]的指针。而pS[i]是一个指向char的指针。所以类型就申明为char **[/quote]  好吧，u r right.

引用 2 楼 sholber 的回复:bool str_in(char **); ？？？？？？？？？？？？？？？ bool str_in(char *);  在CSDN呆了好几天，没意思。  char **貌似没问题啊，指向char指针的指针。变元&pS[i]为pS[i]的地址，即指向pS[i]的指针。而pS[i]是一个指向char的指针。所以类型就申明为char **

void *pt=p1  不要说咱眼力好，一看断言，我就知道那错了

点击重试看看什么地方出错了


Question: 有关磁盘驱动进行加解密的问题

问题是挂到了系统盘上，已修改。


Question: 实参中含有return语句

好吧。我结贴。    每次 看到不懂的英文，我就感觉  好 屌丝

这个要看return 100是不是表达式了

标准多少年才更新一回……

引用 4 楼 sholber 的回复:你上网搜索n1570 pdf 最新的C语言标准。2011年 N1570  Committee Draft — April 12, 2011 ISO/IEC 9899:201x 记得给分啊。C11标准，为什么叫n1570，从哪可以获取啊，如果以后标准跟新了

引用 2 楼 sholber 的回复:N1570，6.5.2.2： A postfix expression followed by parentheses() containing a possibly empty, comma separated list of expressions is a function call. The postfix expression denotes the called function.  The list of expressions specifies the arguments to the function. 函数调用中的表达式列表指定了函数的实参。 return语句不是表达式。上面的英文是什么标准啊，从哪里获取

不符合编译器的语法规则就报错。


Question: 返回在两字符串中第一个相同的子串(大于1个字符),并将子串输出

引用 4 楼 my_live_123 的回复:这第一个也不行，要s1--,s2--。直到遇到相同的，然后比较下一个，一直比较，直到没有相同，如果相同字符大于2就输出啊，你这个无法实现啊！求助，谢谢，分已给。 神linus写的代码  /** 129  * strstr - Find the first substring in a %NUL terminated string 130  * @s1: The string to be searched 131  * @s2: The string to search for 132  */ 133 char *strstr(const char *s1, const char *s2) 134 { 135         size_t l1, l2; 136  137         l2 = strlen(s2); 138         if (!l2) 139                 return (char *)s1; 140         l1 = strlen(s1); 141         while (l1 >= l2) { 142                 l1--; 143                 if (!memcmp(s1, s2, l2)) 144                         return (char *)s1; 145                 s1++; 146         } 147         return NULL; 148 }

引用 6 楼 u014044789 的回复:你这么求不行啊，要是相同的是错位的，你就不能求出来了。。。。。 [quote=引用 5 楼 my_live_123 的回复:]这个高效的我看不懂。怎么这代码不能求出两个字符串的公共子串啊？ memcmp 高效的：   3 int memcmp(const void *s1, const void *s2, size_t len)   4 {   5         u8 diff;   6         asm("repe; cmpsb; setnz %0"   7             : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));   8         return diff;   9 }   用户的：  651 int memcmp(const void *cs, const void *ct, size_t count) 652 { 653         const unsigned char *su1, *su2; 654         int res = 0; 655  656         for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 657                 if ((res = *su1 - *su2) != 0) 658                         break; 659         return res; 660 }   这就是神写的代码[/quote]

引用 5 楼 my_live_123 的回复:这个高效的我看不懂。怎么这代码不能求出两个字符串的公共子串啊？ memcmp 高效的：   3 int memcmp(const void *s1, const void *s2, size_t len)   4 {   5         u8 diff;   6         asm("repe; cmpsb; setnz %0"   7             : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));   8         return diff;   9 }   用户的：  651 int memcmp(const void *cs, const void *ct, size_t count) 652 { 653         const unsigned char *su1, *su2; 654         int res = 0; 655  656         for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 657                 if ((res = *su1 - *su2) != 0) 658                         break; 659         return res; 660 }   这就是神写的代码

求大大来解答啊

5，输入两个数，第一个数决定一个nXn的矩阵，第二个数决定从1开始赋值，赋值的上限   比如：  输入:5 18   输出：  1  2  3  4  5  16 17 18 0  6   15 0  0  0  7  14 0  0  0  8  13 12 11 10 9    输入: 4 12   输出:  1 2 3 4  12 0 0 5  11 0 0 6  10 9 8 7

4，输入一个IP地址，判断时候ip地址合法    ip地址由4位0-255组成 中间使用 . 隔开  合法的ip地址是:    21.45.34.112   是合法的    第一位不能为全0  0.45.34.112   是不合法的    每一位不能超过255 Input 21.45.34.222 Output YES


Question: 计算机储存模式——大端模式和小端模式

引用 2 楼 sholber 的回复:楼主一派胡言。 “在共用体中，所有数据成员公用一个空间，同一时间内只能储存其中一个数据成员，它所占空间等于其最大成员所占的空间” 评：你不知道为了对齐的需要，联合（也就是你所说的共用体）是可以有填充字节的吗？建议你试试这个：printf ("%d\n", sizeof (union check {int i; char ch[5];}));  “union check  {   int i; char ch; }; 我们定义了一个union check的类型，占4个字节。” 评：难道int类型的长度一定要是4吗？  “对于上面定义的union check类型，假设int变量被初始化为1，则1在内存中存储为……” 评：你是说“假设”。别的数也可以用来测试。但是，如果用负数来测试，你的例子还能用吗（PS：这个世界除了2的补码外，还有1的补码），还有，有符号整数（除了char和signed char）可以有填充比特，考虑了吗？  int * p=( int * )( ( int )array+1 ); printf(" %x\n ",*p); 评：如果硬件架构要求int[color=#FF00FF]必须对齐，你这样做安全不？[/color] 老手何必为难我们新手

unsigned char c  = "B??L"[*(unsigned char *)&0x1020304 -1];       B →Big_endianess  ,  ？ → Unknown   ,L → Little_endianess 这个能测出么？？

我记着是，Intel和Motorola 两种模式 未知的否 似乎大小端是一笔糊涂账，有人称Intel为大端，有人称Intel为小端 两种方式的不同，就在字节顺序 一个低字节在低地址，另一个正好相反。 intel 的低字节在低地址（右），正好和16进制的书写顺序相反。  比如 0x 77 FF, 77 高字节在高地址。FF低字节在低地址， 按照字符串，从低地址数起的习惯，顺序正好是反的。 对于 整数 0x77FF，16进制字符串表示 是 77FF  二进制自低向高的顺序是 FF,77  符合低地址（位）在右，高地址（位）在左的习惯----计算机内，不管是位串，还是字符串，一般都是这样的。 但是，从字符表示看 0x77FF，则符合先读在左，后读在右的英文习惯。 ----传统汉语的习惯正好相反，水平排列的文字，从右向左读。竖直排列的文字，先读右边那一列。  如果自右向左读，刚好是低字节在前， 不过恰恰相反，人们习惯从高位读起，所以按照读的习惯 自然就写成高位（字节）在前，低位（字节）在后了。 这就是Intel格式数据的字节顺序。 Motorola和Intel恰好相反。

LZ是来散分的。


Question: 菜鸟求助，谁能帮忙看下

引用 楼主 u014412098 的回复:// 帮忙分析一下 #include<iostream.h> #include <string.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <memory.h> typedef struct  AA {         int b1:5;         int b2:2; }AA; void main() {         AA aa;         char cc[100];          strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");        memcpy(&aa,cc,sizeof(AA));         cout << aa.b1 <<endl;         cout << aa.b2 <<endl; } 答案是 -16和１ 首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit. 经过strcpy和memcpy后,aa的4个字节所存放的值是: 0,1,2,3的ASC码，即00110000,00110001,00110010,00110011 所以，最后一步：显示的是这４个字节的前５位，和之后的２位 分别为：10000,和01 因为int是有正负之分　　所以：答案是-16和１ 10000为什么是-16啊？ 01为什么就是1？ 你没学过补码吧，10000就是-16的二进制编码，5位有符号数表示范围-16~15 01自然是1喽。


Question: 这两种for循环不同在哪里？

j每次循环完，没有被重新赋值，

刚刚好像打错了，是j=10

当然会不一样了啊，   for(; i < 2; i++)         for(; j < 10; j++)             printf("%d\t", ar[i][j]); 这个循环在i= 1的时候进入二层循环的时候j= 11了，就不会在执行第二个循环了，条件不满足就跳出来了，只会打印一行

嗯，j 的问题，lz仔细想想，for循环的用法，能看出来的

J的值不一样


Question: 小程序fgetpos（）段错误

fpos_t *pos; pos又没分配内存，野指针


Question: 求解啊   哪里错了问题？？

Finding prime numbers - Kenneth Haugland Different schemas for finding prime numbers explained with code http://www.codeproject.com/Article.aspx?tag=198374988322054872& 我就是有点崇洋媚外。

引用 11 楼 u012421456 的回复:关于求素数的放方法，lz可以看看这个——http://blog.csdn.net/u012421456/article/details/19074525 方法

# include <stdio.h>         int main(void)   {         int i, n;        printf("100以内的所有数的质数为:");     for (i=2; i<=100; ++i)       {            for (n=2; n<i; ++n)           {               if (0 == i%n)                   break;           }           if (n == i)               printf("%3d ", i);       }          return 0;   }

mian??main??打几个字，顺便得几分，何乐不为。

error LNK2001: unresolved external symbol _main 把这句放到百度里，百度，然后解决办法一堆，一个环境量需要设置，按百度出的解决办法做就OK

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

引用 5 楼 u014403258 的回复:#include<stdio.h> int main() { 	int i,n,p=1; 	for(i=2;i<=100;i++) 	{ 		for(n=1;n<=100;n++) 		{ 			if(i%n==0) 				p=0; 		} 		if(p==1 && i!=1) 			printf("%d",i); 	} 		printf("100以内的所有数的质数为:%d",i); 		return 0; }    Linking...  22.exe - 0 error(s), 0 warning(s)    还是不能编译  这已经通过编译了啊

引用 3 楼 u014403258 的回复:改了之后，为什么还是用不了？？？  用不了...

改了之后，为什么还是用不了？？？

楼主要学会看懂英文的错误提示。error LNK2001:  是提示连接错误  unresolved external symbol _main  这句话的意思是没有找到main函数。也就是你把main     写成了 mian

mian --> main


Question: DES加密不一致问题,求大神解决

using  System; using  System.Security.Cryptography; using  System.IO; using  System.Text;  private	 byte[]	 Keys  =  {	 0xEF,	0xAB,  0x56,  0x78,	 0x90,	0x34,  0xCD,  0x12	};//默认密钥向量 ///	 <summary> ///	 DES加密字符串 ///	 </summary> ///	 <param	 name="encryptString">待加密的字符串</param> ///	 <param	 name="encryptKey">加密密钥,要求为8位</param> ///	 <returns>加密成功返回加密后的字符串，失败返回源串</returns> public	string	EncryptDES(string  encryptString,  string  encryptKey) { 		try 		{ 				byte[]	rgbKey	=  Encoding.UTF8.GetBytes(encryptKey.Substring(0,  8)); 				byte[]	rgbIV  =  Keys; 				byte[]	inputByteArray	=  Encoding.UTF8.GetBytes(encryptString); 				DESCryptoServiceProvider  dCSP	=  new	DESCryptoServiceProvider(); 				MemoryStream  mStream  =  new  MemoryStream(); 				CryptoStream  cStream  =  new  CryptoStream(mStream,  dCSP.CreateEncryptor(rgbKey,	rgbIV),	 CryptoStreamMode.Write); 				cStream.Write(inputByteArray,  0,  inputByteArray.Length); 				cStream.FlushFinalBlock(); 				return	Convert.ToBase64String(mStream.ToArray()); 		} 		catch 		{ 				return	encryptString; 		} }  ///	 <summary> ///	 DES解密字符串 ///	 </summary> ///	 <param	 name="decryptString">待解密的字符串</param> ///	 <param	 name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param> ///	 <returns>解密成功返回解密后的字符串，失败返源串</returns> public	string	DecryptDES(string  decryptString,  string  decryptKey) { 		try 		{ 				byte[]	rgbKey	=  Encoding.UTF8.GetBytes(decryptKey.Substring(0,  8)); 				byte[]	rgbIV  =  Keys; 				byte[]	inputByteArray	=  Convert.FromBase64String(decryptString); 				DESCryptoServiceProvider  DCSP	=  new	DESCryptoServiceProvider(); 				MemoryStream  mStream  =  new  MemoryStream(); 				CryptoStream  cStream  =  new  CryptoStream(mStream,  DCSP.CreateDecryptor(rgbKey,	rgbIV),	 CryptoStreamMode.Write); 				cStream.Write(inputByteArray,  0,  inputByteArray.Length); 				cStream.FlushFinalBlock(); 				return	Encoding.UTF8.GetString(mStream.ToArray()); 		} 		catch 		{ 				return	decryptString; 		} } ///	 <summary> ///	 use  sha1	to	encrypt	 string ///	 </summary> public	string	SHA1_Encrypt(string	 Source_String) { 		byte[]	StrRes	=  Encoding.Default.GetBytes(Source_String); 		HashAlgorithm  iSHA	 =	new	 SHA1CryptoServiceProvider(); 		StrRes	=  iSHA.ComputeHash(StrRes); 		StringBuilder  EnText  =  new  StringBuilder(); 		foreach	 (byte	iByte  in  StrRes) 		{ 				EnText.AppendFormat("{0:x2}",  iByte); 		} 		return	EnText.ToString(); }  namespace  Microsoft.Samples.Security.PublicKey { 	class  App 	{ 		//	Main  entry	 point 		static	void  Main(string[]	 args) 		{ 			//	Instantiate	 3	People	for	 example.  See	the	 Person	 class	below 			Person	alice  =  new  Person("Alice"); 			Person	bob	 =	new	 Person("Bob"); 			Person	steve  =  new  Person("Steve");  			//	Messages  that	will  exchanged.  See  CipherMessage  class	 below 			CipherMessage  aliceMessage; 			CipherMessage  bobMessage; 			CipherMessage  steveMessage;  			//	Example	 of	 encrypting/decrypting	your  own  message 			Console.WriteLine("Encrypting/Decrypting  Your  Own  Message"); 			Console.WriteLine("-----------------------------------------");  			//	Alice  encrypts	 a	message	 using	her	 own  public  key 			aliceMessage  =	 alice.EncryptMessage("Alice  wrote  this  message"); 			//	then  using	 her  private  key	can	 decrypt  the  message 			alice.DecryptMessage(aliceMessage); 			//	Example	 of	 Exchanging	 Keys  and	Messages 			Console.WriteLine(); 			Console.WriteLine("Exchanging  Keys  and  Messages"); 			Console.WriteLine("-----------------------------------------");  			//	Alice  Sends  a	 copy  of  her	public	key	 to	 Bob  and  Steve 			bob.GetPublicKey(alice); 			steve.GetPublicKey(alice);  			//	Bob	 and  Steve	 both  encrypt	messages  to  send	to	Alice 			bobMessage	=  bob.EncryptMessage("Hi  Alice!  -  Bob."); 			steveMessage  =	 steve.EncryptMessage("How  are  you?  -  Steve");  			//	Alice  can	decrypt	 and  read	both  messages 			alice.DecryptMessage(bobMessage); 			alice.DecryptMessage(steveMessage);  			Console.WriteLine(); 			Console.WriteLine("Private  Key  required  to  read  the  messages"); 			Console.WriteLine("-----------------------------------------");  			//	Steve  cannot  read	 the  message  that	 Bob  encrypted 			steve.DecryptMessage(bobMessage); 			//	Not	 even  Bob	can	 use  the  Message	he	encrypted  for	Alice. 			//	The	 RSA  private  key	is	required  to  decrypt  the	RS2	 key  used 			//	in	the	 decryption. 			bob.DecryptMessage(bobMessage);  		}  //  method  Main 	}  //  class  App  	class  CipherMessage 	{ 		public	byte[]	cipherBytes;	//	RC2	 encrypted	message	 text 		public	byte[]	rc2Key;				 //	 RSA  encrypted	 rc2  key 		public	byte[]	rc2IV;				  //  RC2  initialization  vector 	}  	class  Person 	{ 		private	 RSACryptoServiceProvider  rsa; 		private	 RC2CryptoServiceProvider  rc2; 		private	 string	 name;  		//	Maximum	 key  size	for	 the  RC2  algorithm 		const  int	keySize	 =	128;  		//	Person	constructor 		public	Person(string  p_Name) 		{ 			rsa	 =	new	 RSACryptoServiceProvider(); 			rc2	 =	new	 RC2CryptoServiceProvider(); 			rc2.KeySize	 =	keySize; 			name  =	 p_Name; 		}  		//	Used  to  send	the	 rsa  public  key  parameters 		public	RSAParameters  SendPublicKey() 		{ 			RSAParameters  result  =  new  RSAParameters(); 			try 			{ 				result	=  rsa.ExportParameters(false); 			} 			catch  (CryptographicException	e) 			{ 				Console.WriteLine(e.Message); 			} 			return	result; 		}  		//	Used  to  import  the  rsa	public	key	 parameters 		public	void  GetPublicKey(Person  receiver) 		{ 			try 			{ 				rsa.ImportParameters(receiver.SendPublicKey()); 			} 			catch  (CryptographicException	e) 			{ 				Console.WriteLine(e.Message); 			} 		}  		public	CipherMessage  EncryptMessage(string  text) 		{ 			//	Convert	 string	 to	 a	byte  array 			CipherMessage  message	=  new	CipherMessage(); 			byte[]	plainBytes	=  Encoding.Unicode.GetBytes(text.ToCharArray());  			//	A  new	key	 and  iv  are  generated  for  every  message 			rc2.GenerateKey(); 			rc2.GenerateIV();  			//	The	 rc2  initialization  doesnt  need	to	be	encrypted,	but	 will 			//	be	used  in  conjunction  with	 the  key  to  decrypt	the	 message. 			message.rc2IV  =  rc2.IV; 			try 			{ 				//	Encrypt	 the  RC2  key	using  RSA	encryption 				message.rc2Key	=  rsa.Encrypt(rc2.Key,	 false); 			} 			catch  (CryptographicException	e) 			{ 				//	The	 High  Encryption  Pack	 is	 required  to  run	this	sample 				//	because	 we	 are  using	 a	128-bit	 key.  See	the	 readme	 for 				//	additional	information. 				Console.WriteLine("Encryption  Failed.  Ensure  that  the"  + 					"  High  Encryption  Pack  is  installed."); 				Console.WriteLine("Error  Message:  "  +  e.Message); 				Environment.Exit(0); 			} 			//	Encrypt	 the  Text	Message	 using	RC2	 (Symmetric	 algorithm) 			ICryptoTransform  sse  =  rc2.CreateEncryptor(); 			MemoryStream  ms  =	 new  MemoryStream(); 			CryptoStream  cs  =	 new  CryptoStream(ms,	sse,  CryptoStreamMode.Write); 			try 			{ 					cs.Write(plainBytes,  0,  plainBytes.Length); 					cs.FlushFinalBlock(); 					message.cipherBytes	 =	ms.ToArray(); 			} 			catch  (Exception  e) 			{ 					Console.WriteLine(e.Message); 			} 			finally 			{ 				ms.Close(); 				cs.Close(); 			} 			return	message; 		}  //  method  EncryptMessage   		public	void  DecryptMessage(CipherMessage	message) 		{ 			//	Get	 the  RC2  Key	and	 Initialization	 Vector 			rc2.IV	=  message.rc2IV; 			try 			{ 				//	Try	 decrypting	 the  rc2  key 				rc2.Key	 =	rsa.Decrypt(message.rc2Key,	 false); 			} 			catch  (CryptographicException	e) 			{ 				Console.WriteLine("Decryption  Failed:  "  +  e.Message); 				return; 			}  			ICryptoTransform  ssd  =  rc2.CreateDecryptor(); 			//	Put	 the  encrypted	 message  in  a	 memorystream 			MemoryStream  ms  =	 new  MemoryStream(message.cipherBytes); 			//	the	 CryptoStream  will	 read  cipher  text	 from  the	MemoryStream 			CryptoStream  cs  =	 new  CryptoStream(ms,	ssd,  CryptoStreamMode.Read); 			byte[]	initialText	 =	new	 Byte[message.cipherBytes.Length];  			try 			{ 					//	Decrypt	 the  message  and	store  in  byte	 array 					cs.Read(initialText,  0,  initialText.Length); 			} 			catch  (Exception  e) 			{ 					Console.WriteLine(e.Message); 			} 			finally 			{ 				ms.Close(); 				cs.Close(); 			}  			//	Display	 the  message  received 			Console.WriteLine(name	+  "  received  the  following  message:"); 			Console.WriteLine("    "  +  Encoding.Unicode.GetString(initialText)); 		}  //  method  DecryptMessage 	}  //  class  Person }  //  namespace  PublicKey

参考《算法精解C语言实现》例子代码\examples_pc\source\des.c ？

引用 楼主 qiaomu22 的回复:各位大神  小弟在做一个文件传输项目   对方系统用的是c#写的des加解密算法  密钥：Bank2014 加密偏移量：Bank2014 加密模式:CipherMode.CBC、PaddingMode.PKCS5 块长度:64 文件编码：GBK  小弟这边用的是c写的加解密算法我就只设置了密钥:Bank2014 代码是参照大赛写的 位置在:http://www.iteye.com/topic/478024 目前的问题就是对方公司加密出来的文件跟我加密出来的文件不一样  我的代码是否需要设置加密偏移量呢 还是代码本身就有问题   求大神指点 先跪谢了  没接触过相关知识， 仅有的记忆是大学的网络安全课上 老师讲过的RSA加密算法，而且 也已经忘记了，爱莫能助

引用 4 楼 ak47_wz 的回复:[quote=引用 3 楼 qiaomu22 的回复:] [quote=引用 2 楼 ak47_wz 的回复:] C#有这种内置加解密算法。 不过C语言没做过。不知道这种问题是不是因为字符编码的问题，中文有好多种编码，也是烦的不行。帮你顶顶～～ 哎 不懂这原理就是悲催啊 谢谢哈[/quote] 毕竟不是信息安全专业～～可以理解。  不过我记得密码学上面有介绍这种算法，是经过什么什么列变化，什么什么做的。可以找个学安全的人问问就懂了～。[/quote] 行 我再去找找他们看有没懂的

引用 3 楼 qiaomu22 的回复:[quote=引用 2 楼 ak47_wz 的回复:] C#有这种内置加解密算法。 不过C语言没做过。不知道这种问题是不是因为字符编码的问题，中文有好多种编码，也是烦的不行。帮你顶顶～～ 哎 不懂这原理就是悲催啊 谢谢哈[/quote] 毕竟不是信息安全专业～～可以理解。  不过我记得密码学上面有介绍这种算法，是经过什么什么列变化，什么什么做的。可以找个学安全的人问问就懂了～。

引用 2 楼 ak47_wz 的回复:C#有这种内置加解密算法。 不过C语言没做过。不知道这种问题是不是因为字符编码的问题，中文有好多种编码，也是烦的不行。帮你顶顶～～ 哎 不懂这原理就是悲催啊 谢谢哈

DES_Encrypt("1.txt","Bank2014","2.txt"); 小弟是这样调用的


Question: 用16进制表示文件内容

引用 11 楼 u014320490 的回复:[quote=引用 8 楼 zjq9931 的回复:] [quote=引用 5 楼 u014320490 的回复:] 怎么没人了？？？？？？？？ 这个：(input=fopen(argv[1],"r")) 改成：(input=fopen(argv[1],"rb"))[/quote] 嗯，但是没什么用[/quote] 不行？ 我在VC6上试验过的啊，结果正确。

引用 8 楼 zjq9931 的回复:[quote=引用 5 楼 u014320490 的回复:] 怎么没人了？？？？？？？？ 这个：(input=fopen(argv[1],"r")) 改成：(input=fopen(argv[1],"rb"))[/quote] 嗯，但是没什么用

引用 9 楼 u014320490 的回复:可是程序是我自己编的，我并没有把什么0d去掉啊 这个：(input=fopen(argv[1],"r")) 改成：(input=fopen(argv[1],"rb"))  验证过了，这样就好了。

可是程序是我自己编的，我并没有把什么0d去掉啊

引用 5 楼 u014320490 的回复:怎么没人了？？？？？？？？ 这个：(input=fopen(argv[1],"r")) 改成：(input=fopen(argv[1],"rb"))

还有，我执行程序的时候输入的是./a.out file，那么用gdb怎么调试呢?

有些文本编辑器会吧0d去掉。 你用正规的16进制编辑器打开看一下有没有0d 引用 4 楼 u014320490 的回复:以下是完整代码： #include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(int argc,char **argv) {     if(argc>2)     {         fprintf(stderr,"Invalid input!\n");         exit(1);     }     FILE *input;     if(argc==2)         if(NULL==(input=fopen(argv[1],"r")))         {             perror(argv[1]);             exit(1);         } //  else     fpos_t pos;     char s[17]={0};     char ss[17]={0};     char *sp=s;     long offset=ftell(input);     int n=0,i;     while(NULL!=fgets(s,17,input))     {         sp=s;         for(i=0;i<17;i++)             ss[i]=s[i];         printf("%06X ",offset);         while(*sp!=EOF)         {             if(n!=15)             {                 if(n%4!=0)                     printf("%02X",*sp++);                 else                     printf(" %02X",*sp++);                 n++;             }             else             {                 printf("%X  *",*sp);                 for(i=0;i<16;i++)                     if(ss[i]=='\n')                         break;                     else                         if(isspace(ss[i]) || !isprint(ss[i]))                             putchar('.');                         else                             putchar(ss[i]);                 printf("*\n");                 n=0;                 break;             }         }         fgetpos(input,&pos);         fsetpos(input,&pos);         offset=ftell(input);         for(i=0;i<17;i++)             s[i]=0;     } }

怎么没人了？？？？？？？？

代码不全，恰恰是没有爆出来的那部分代码，让回车丢失了 爆出来的部分，没有问题

引用 1 楼 ak47_wz 的回复:其实没有太看懂你要做什么和你要问什么^_^～。 大体意思就是模拟16进制查看器

其实没有太看懂你要做什么和你要问什么^_^～。


Question: fgetpos（）段错误

fpos_t *pos,*pos2; --> fpos_t pos, pos2; fgetpos(fi,pos); --> fgetpos(fi, &pos); fgetpos(fi2, pos2); --> fgetpos(fi2, &pos2); fsetpos(fi2,pos2); --> fsetpos(fi2, &pos2); fsetpos(fi,pos); --> fsetpos(fi, &pos);


Question: 求助：怎么用c语言找图中最黑的点？？

很好奇找到这个最黑的点有算法吗 感觉图像没有什么规律，难道要遍历？

引用 4 楼 lin5161678 的回复:看了三楼的回复才想明白 这个不就只是读取文件数据嘛 连api都省了  你好！  谢谢你的回复！ 请问在C语音里怎么“读取文件数据”？ 可以提示写代码吗？  谢谢！

先转灰度，然后找即可。

引用 楼主 ampYou 的回复:求助啊！  请问怎么用C语言来找下面这张图中最黑的点？ 这个编程要怎么编啊？？  用的是一个 PPM image file  n44f.ppm    怎么用RGB 和 0-255（0 表示黑色，255表示白色）来编程这个C语言找图中最黑的点？？ 先得搞清楚ppm的存储格式，不然就算找到了你也不知道坐标

搜“RGB转HSL”和“RGB转HSB”

看了三楼的回复才想明白 这个不就只是读取文件数据嘛 连api都省了

我说的不是很有帮助啊，只是想起来一些相关的内容。  记得没在C里边写过，在用MATLAB的时候，可以把图片很轻松的提取出R、G、B分量，也可以将彩色图转换成灰度图，然后就可以很轻松的进行判断了。  在用OpenGL的时候看过 PPM 图像的一点东西，只知道能够读取头文件，PPM可以将图像以数值的形式显示出来，个人猜测可以通过这种方式来判断。但是对于API却真的是不知道了。

引用 1 楼 lin5161678 的回复:获取点的颜色就靠各种api了 获取颜色之后你的问题也只是 二维数组求最大值 二维数组求最小值这种水平的问题   你好！ 请问可以说具体些嘛？ 可以给些编程/代码建议嘛？  谢谢！


Question: C语言函数传参问题，传地址？

1.Tree  t ；  t是一个野指针(必须初始化，在我用的Centos，Ubuntu下   野指针不是能作为参数传递的)    2.所有的参数传递本质上都是值传递，只是一个数值，你传递了一个野指针的拷贝，再又把这个野指针的值赋值给一个局部变量  然后丢弃这个局部变量中的值(野指针原来的值，你可以%p打印他们三的值  都是一样的值)  让这个局部变量指向malloc分配的堆内存区域    其实你思路对了  但是你的指针用错了   你这个思路需要用二级指针   稍微改改就可以

楼上注意，楼主用的就是二级指针

前面几楼都被楼主恶劣的编程风格骗了，Tree是指针啊！声明成pTree就没歧义了 问题很明显， pTree ptre=*t； ptre=...malloc...； ptre此时就跟*t毫无关系了 所以最后要加上 *t=ptre

无论是传递什么，本质都是个值：也就是都是传值！只是这个“值”是什么性质的，决定你在函数体内能不能操作函数外的变量！ 所谓传指针，也是传递地址的这类值，是说明能够操作函数外变量区别于一般传递变量的值的一种简化称呼，不要被教科书迷惑！  举个范例吧，更好理解   void fun1（char *ptr和void fun2（char noptr）  现在有变量 char ch, *chp = &ch; fun1(chp);//传递值，这个值是指针chp，即ptr = chp fun2(ch);//传递值，这个值是变量ch，noptr=ch 都是传值，赋值！这是本质 那么在fun1内修改prt，chp不会变的。操作的临时变量ptr 同理在fun2内修改noptr，ch也不会变的，操作的临时变量noptr 但是在fun1内，操作*ptr，就不在是操作临时变量ptr了，而是操作ch 因为多了一层映射*作用。  就说这么多吧，自己慢慢理解！实在不行自己反汇编，这个更容易理解这些细节区别

引用 5 楼 u013867292 的回复:[quote=引用 4 楼 sholber 的回复:] void PreOrder( Tree t ) {     if (t) { /* …… */ }  }  不能这么干。t是结构类型的对象，而if语句的控制表达式只能是标量类型（指针类型和算术类型合称标量类型）。 那你能给我讲讲指针的间接引用这个问题吗[/quote] 函数CreateTree定义了，却没有使用，不知道你啥意思。 其次，void PreOrder( Tree t )本身没有问题，函数可以授受结构类型的参数，这没有问题。当然，通过传递指针也没有问题： void PreOrder(Tree * pt) {/* …… */} 你自己决定一下，写出来我看看再说。

问题出在main函数里面， int main() {        Tree T;        PreOrder(T);         }  这里本来就是传个空指针T给PreOrder,  没看到函数CreateTree在哪里使用啊？

搞这么多干嘛 统一一种方式就行

引用 4 楼 sholber 的回复:void PreOrder( Tree t ) {     if (t) { /* …… */ }  }  不能这么干。t是结构类型的对象，而if语句的控制表达式只能是标量类型（指针类型和算术类型合称标量类型）。 那你能给我讲讲指针的间接引用这个问题吗

传引用更方便。

嗯最后在函数中加上*t = tre;即可，间接引用？但是前面tre = *t;不已经让它们指向的同一块地址吗？ void CreateTree( Tree* t ) { char ch;   Tree tre = *t; //tre = *t; scanf("%c",&ch);   if ( ch == '#' )   tre = NULL;   else   {   tre = (Tree)malloc(sizeof(TreeNode));   if ( !tre )   {   printf("分配内存出错") ; return ;   }   tre->data = ch;   CreateTree(&(tre->lchild));   CreateTree(&(tre->rchild));   }   *t = tre; }

虽然我知道用returen的方法可以实现，但是我想知道为什么这样子传地址不可以，应该怎么传才能实现不通过返回将正确的值传入PreOrder()中乃?


Question: 照书写了个贪吃蛇，可一按方向键就退出，求助！

我照做了，是可以接受按键了，但是按一下走一步，我把跳出循环的break改成return就好了，不管怎么说，还是谢谢你看完了这么长的代码！

216行的的那个语句应该放在内循环里面的吧？              if(snake.life == 1)             {                 break;                } 这句应该是在里面的那个while的结尾处，而不是在外面的do...while()


Question: 集合并运算

回楼上，我用了typedef啊！指针传进去了的！  具体的见第一次贴的代码的前几行！！！   #define Element int   struct node; typedef struct node *list;

链表头要返回或者传递指针过去，不然你只是在操作野指针... void initlist(list *L);  void creatlist(list *L,int n);

楼上啊，我不是不调试，是有些接口问题不对劲，，这两个函数不能配对使用，但是我感觉是对的啊，  另外上面的代码缺陷在少了个i++计数器忘弄了→_→，  请看接下来这两个  建表和输出表：  不带头结点的表   void creatlist(list L,int n) { 	initlist(L); 	list p,r; 	int i=0; 	scanf("%d",&L->D); 	r=L; 	while(i<n-1) 	{ 		p=(list)malloc(sizeof(struct node)); 		scanf("%d",&p->D); 		r->next=p; 		r=r->next; 		i++; 	} 	r->next=NULL; }  void printlist(list L) { 	list p; 	p=L; 	while(p!=NULL) 	{ 		printf("%d",p->D); 		p=p->next; 	} 	printf("\n"); }

这个问题最高效的做法是直接遍历两个表建BST，最后输出一次即可。

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


Question: linux下的c程序，编程时函数参数到什么地方去查

引用 7 楼 ak47_wz 的回复:引用 4 楼 u013666035 的回复:[quote=引用 2 楼 turingo 的回复:] 很方便的，例如你要查printf的话，直接敲入命令即可：  man 3 printf   [quote=引用 楼主 u013666035 的回复:] 现在就是找了电子版的tlpi，感觉这书比apue好，然后搜索，不过挺麻烦的  这个可以，不过3是什么意思啊[/quote]  man 手册，   2 表示系统调用，3表示库函数。[/quote]  1和3有什么区别啊

引用 6 楼 ak47_wz 的回复:[quote=引用 5 楼 u013666035 的回复:] [quote=引用 3 楼 ak47_wz 的回复:] 我个人看法而已。。我感觉APUE已经非常非常好了，他的六本书，每本都是著作。我个人也只看APUE，感觉弄懂就够了。  apue的风格太像Windows System Programming，很多都没讲清楚，不喜欢[/quote] 如果有机会实际用到了，就清楚了。任何书光看，肯定也不会清楚的。[/quote]  随便翻翻就知道了，tlpi比apue好多了

引用 4 楼 u013666035 的回复:引用 2 楼 turingo 的回复:很方便的，例如你要查printf的话，直接敲入命令即可：  man 3 printf   [quote=引用 楼主 u013666035 的回复:] 现在就是找了电子版的tlpi，感觉这书比apue好，然后搜索，不过挺麻烦的  这个可以，不过3是什么意思啊[/quote]  man 手册，   2 表示系统调用，3表示库函数。

引用 5 楼 u013666035 的回复:[quote=引用 3 楼 ak47_wz 的回复:] 我个人看法而已。。我感觉APUE已经非常非常好了，他的六本书，每本都是著作。我个人也只看APUE，感觉弄懂就够了。  apue的风格太像Windows System Programming，很多都没讲清楚，不喜欢[/quote] 如果有机会实际用到了，就清楚了。任何书光看，肯定也不会清楚的。

引用 3 楼 ak47_wz 的回复:我个人看法而已。。我感觉APUE已经非常非常好了，他的六本书，每本都是著作。我个人也只看APUE，感觉弄懂就够了。  apue的风格太像Windows System Programming，很多都没讲清楚，不喜欢

引用 2 楼 turingo 的回复:很方便的，例如你要查printf的话，直接敲入命令即可：  man 3 printf  引用 楼主 u013666035 的回复:现在就是找了电子版的tlpi，感觉这书比apue好，然后搜索，不过挺麻烦的  这个可以，不过3是什么意思啊

函数参数问谷歌，百度啊


Question: C语言求助

引用 11 楼 u012421456 的回复:关于这个，可以看看置顶帖——裘老的表达式 是 C,C++表达式求值顺序 裘老的解释。

关于这个，可以看看置顶帖——裘老的表达式

引用 7 楼 ak47_wz 的回复:尽量不用这种类型的代码，一来是可读性不好，二来是不健壮。  仅仅是做的练习题而已  谢谢提醒

引用 5 楼 wufeng2014 的回复:这种东西，自己手动指行一遍就会明白的，关于这个前增后增的问题，你可以参考下http://bbs.csdn.net/topics/370153775  谢谢你

引用 楼主 ParadiseOK 的回复:#include <stdio.h> int main() { 	int x = 0 , y = 5 , z = 3; 	while(z-->=0 && ++x < 6)  y = y-1; 	printf("%d,%d%d\n",x,y,z); 	return 0; }    结果中的z=-2  不理解  求大神解释下  谢谢z--，表示 先用z的值，再做--运算。++x，表示先做++运算，再用x。也就是说在条件判断里面，先判断z, 再做--运算，先做x的++运算，再判断x的值。模拟结果如下： 第一遍，z=3, x=x+1=1, 符合z>=0&&x<6的条件，y=y-1=4，之后z=z-1=2，x=1 第二遍，z=2, x=x+1=2, 符合z>=0&&x<6的条件，y=y-1=3，之后z=z-1=1，x=2 第三遍，z=1, x=x+1=3, 符合z>=0&&x<6的条件，y=y-1=2，之后z=z-1=0，x=3 第四遍，z=0, x=x+1=4, 符合z>=0&&x<6的条件，y=y-1=1，之后z=z-1=-1，x=4 第五遍，z=-1, x=x+1=5, 不符合z>=0的条件，y仍然等于1，之后z=z-1=-2，x=5 这时候条件不成立，退出循环，x, y, z 的值为5, 1, -2，所以z=-2

在z=-1的时候去while里边进行比较，无论条件对不对都要进行--操作

尽量不用这种类型的代码，一来是可读性不好，二来是不健壮。

(z--)的值等于z的值， (--z)的值等于z-1,

引用 2 楼 truelance 的回复:不加括号的结果 while((z-->=0) && (++x < 6))  谢谢您

引用 1 楼 user-8 的回复:z-->=0 这个总是先判断z>=0然后执行z--。只要执行到这句，z--都会执行。 z等于0的时候，满足条件，然后z--，然后执行循环体，此时z等于-1，然后再到z-->=0，于是z等于-2了，并且条件不满足，跳出循环  谢谢您

不加括号的结果 while((z-->=0) && (++x < 6))


Question: 单链表插入元素的疑问

引用 12 楼 my_live_123 的回复:"顺序线性表"你怎么搞成链表了？  顺序表是在计算机内存中以数组的形式保存的线性表，是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。 不好意思，注释错了，应该是链表

PS：链表应当非空。

j好像是多余的。     //i不能为0。     while (--i && (p=p->next)) ;     //i==0说明已找到。

引用 9 楼 u010176717 的回复:p = *L;     /* 声明一个结点 p，指向头结点 */ 假设链表有两个结点，若 i=3  while循环两次，p指向第二个结点，即p非空，而p->next==Null 之后的if语句就无效了,不会执行 之后 s->next = p->next;      /* 将p的后继结点赋值给s的后继  */ p->next = s;          /* 将s赋值给p的后继 */ 会在链表的第三个位置补上一个元素  若输入i>=4 while循环执行3次，p指向第三个结点即空结点，p==null ，条件不满足后退出循环 if语句成立 执行return退出  假设链表有两个结点，若i=3， 则不会执行if语句，就不会报ERROR 但按设计规范，i=3时要报错的

如果按照程序的理解的话 i的范围应该是 1≤i≤ListLength(L)+1 这段程序在严蔚敏那本书里，while语句的判断条件是 (  p && j<i-1 ) 仅供参考

"while (p && j < i)    是不是要改为 while ((p->next) && j < i)" 为什么要改？应该是判断P非空而不是p->next非空，如果p为空，则p不在链表上， 如果p->next为空，则是最后一个节点，在最后一个节点前面还是可以插入节点啊。 欢迎讨论。

引用 2 楼 wufeng2014 的回复:你这错误以及漏洞挺多的啊，感觉没啥修改的价值，尤其是针对那些特殊情况都没有做出容错处理，比如i=1的时候，你插入的位置在原先的第一个结点之前，这样的话，你传入的链表参数是个一重指针，而且你链表又是个单链表，出了函数之后你怎么才能找到这个新插入的结点呢？另外你定义的p是个结构体变量而不是指针，看你的意思是想定义指针的。是应该改成你说的那样，要不然你这不是前插而是后插，链表有好几种：有头/无头，单向/双向，循环/不循环，你可以去多了解一下  不好意思，没声明 typedef struct Node {     ElemType data;     struct Node *next; }Node; typedef struct Node *LinkList; /* 定义LinkList */

楼上很卖力的样子，但是看了头大。

仅供参考：//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //


Question: c语言求助

引用 7 楼 lnetant 的回复:别用图片,要不没几个人愿意给你弄  #include <stdio.h>  int d=1; void fun(int d)   //此处传入的值,函数里边的赋值操作不会带回 {       int d=5;//局部变量,此处会导致此函数内不会使用全局变量       p=d;      printf("%d",p);  //输出5 }  int main() {     int a=3;     fun(a); //这里a的值不会被改变,想改变需修改函数的参数为地址传入方式     d=a;//改了全局的值了     printf("%d\n",d); //输出3 } C语言认真学，没那么难

局部变量修改了全局变量

引用 7 楼 lnetant 的回复:别用图片,要不没几个人愿意给你弄  #include <stdio.h>  int d=1; void fun(int d)   //此处传入的值,函数里边的赋值操作不会带回 {       int d=5;//局部变量,此处会导致此函数内不会使用全局变量       p=d;      printf("%d",p);  //输出5 }  int main() {     int a=3;     fun(a); //这里a的值不会被改变,想改变需修改函数的参数为地址传入方式     d=a;//改了全局的值了     printf("%d\n",d); //输出3 } 引用 7 楼 lnetant 的回复:别用图片,要不没几个人愿意给你弄  #include <stdio.h>  int d=1; void fun(int d)   //此处传入的值,函数里边的赋值操作不会带回 {       int d=5;//局部变量,此处会导致此函数内不会使用全局变量       p=d;      printf("%d",p);  //输出5 }  int main() {     int a=3;     fun(a); //这里a的值不会被改变,想改变需修改函数的参数为地址传入方式     d=a;//改了全局的值了     printf("%d\n",d); //输出3 }   看懂了 谢谢你

引用 8 楼 derekrose 的回复:结果不应该是53吗  p=5 a=3呀  是53 我先慢慢看 上面的那个兄弟给我的解释 谢谢你

引用 7 楼 lnetant 的回复:别用图片,要不没几个人愿意给你弄  #include <stdio.h>  int d=1; void fun(int d)   //此处传入的值,函数里边的赋值操作不会带回 {       int d=5;//局部变量,此处会导致此函数内不会使用全局变量       p=d;      printf("%d",p);  //输出5 }  int main() {     int a=3;     fun(a); //这里a的值不会被改变,想改变需修改函数的参数为地址传入方式     d=a;//改了全局的值了     printf("%d\n",d); //输出3 }  谢谢你的提醒 下次不会了

结果不应该是53吗  p=5 a=3呀

引用 3 楼 derekrose 的回复:哪里不懂  全局变量真坑爹对于他的结果我不懂  可以帮我解释下？？

引用 2 楼 Anti_Bird 的回复:请 Google “变量作用域”  你可以直接帮我解释??

你可以直接帮我解释下？？

哪里不懂  全局变量真坑爹

请 Google “变量作用域”

自己先定下  求大神解答


Question: C语言数据结构编写的航空客运订票系统


Question: 求帮忙

Google/百度.


Question: 这句代码是什么意思

谢谢楼主各位，这下明白了，这帖子可以结了 这种用法初次看到：）

引用 3 楼 romabdwy 的回复:[quote=引用 2 楼 a515360208 的回复:]  unsigned long p; p=1L;  你的p定义的是long型，所以将long型的1赋值给p  我就是想问后面那个L是什么意思，后面的L是指long型吗？[/quote] 是的.最好使用: p = 1UL; // UL: unsigned long 因为p是unsigned long.

L是long

引用 2 楼 a515360208 的回复: unsigned long p; p=1L;  你的p定义的是long型，所以将long型的1赋值给p  我就是想问后面那个L是什么意思，后面的L是指long型吗？

我记得这种情况是long，记不太清了，看楼下

数字也是有类型的

引用 5 楼 JiMoKuangXiangQu 的回复:[quote=引用 3 楼 romabdwy 的回复:] [quote=引用 2 楼 a515360208 的回复:]  unsigned long p; p=1L;  你的p定义的是long型，所以将long型的1赋值给p  我就是想问后面那个L是什么意思，后面的L是指long型吗？[/quote] 是的.最好使用: p = 1UL; // UL: unsigned long 因为p是unsigned long.[/quote]是的，使用p = 1UL;更好


Question: C语言弹窗程序源代码

MassageBox()?

不明觉厉

引用 2 楼 zyaiwx 的回复:MassageBox()?  msgbox.c: #pragma comment(lib,"user32") #include <windows.h> #include <conio.h> void main() {     int r;      cprintf("press any key...");     getch();     r=MessageBox(NULL,"Hello!","MsgBox",MB_OKCANCEL|MB_SETFOREGROUND);     cprintf("\r\nr=%d",r); }


Question: 《c和指针》I/O篇3个问题每个20分

上帖第26行 sprintf(st.s,"%*s",10-1,"abcdefghijk"); 可能应改为 sprintf(st.s,"%.*s",10-1,"abcdefghijk");

引用 1 楼 sholber 的回复:坐等zhao4zhong1大神出现  没实际编译链接调试，不保证对。仅供参考：  test.cpp: #include <stdio.h> #include <string.h> #pragma pack(push,1) struct ST {     char s[10];     char t[10]; } st; #pragma pack(pop) int v,n; float f; double d; char ss[100]; int main() { //1） //sprintf是一个潜在的错误根源，因为可能导致缓冲区溢出，     strcpy(st.s,"123456789");     strcpy(st.t,"ABCDEFGHI");     printf("%s,%s\n",st.s,st.t);     sprintf(st.s,"%s","abcdefghijk");     printf("%s,%s\n",st.s,st.t);  //解决方法是：字符串长度并没有限制，但函数所生成的字符串的字符数目可以用格式代码中一个可选的字段来限制。比如%*     strcpy(st.s,"123456789");     strcpy(st.t,"ABCDEFGHI");     printf("%s,%s\n",st.s,st.t);     sprintf(st.s,"%*s",10-1,"abcdefghijk");     printf("%s,%s\n",st.s,st.t);  //2) //printf函数家族的格式代码和scanf函数家族的格式代码用法不同。书后的总结中也提示到避免混淆printf和scanf格式代码，我就看不出哪里会混淆了？     sscanf("12  34","%d%n",&v,&n);printf("v,n=%d,%d\n",v,n);     sprintf(ss     ,"%d%n", v,&n);printf("v,n=%d,%d\n",v,n);     sscanf("1.0,34","%f,%lf" ,&f,&d);     printf("f,d="   "%f,%f\n", f, d);  //3） //为流缓冲区使用一个自动数组是很危险的。如果在流关闭之前，程序的执行流离开了数组声明所在的代码块，流就会继续使用这块内存，但此时它可能已经分配给了其它函数另作他用。     {         char buf[256];         setvbuf(stdout,buf,_IOFBF,256);         fprintf(stdout,"123\n");     }     {         char buf1[256];         strcpy(buf1,"ABC");         fprintf(stdout,"123\n");//buf这块内存此时可能已经分配给了buf1另作他用。     }     return 0; }

谁叫你整天说废话的，所以使这招。 朕这两天闲得无聊，所以来些逛逛。好吧，朕继续忙自己的……

引用 1 楼 sholber 的回复:坐等zhao4zhong1大神出现 抛砖引玉这招阁下用得炉火纯青啊。