Question: 菜鸟大无畏，多个问题求解

引用 1 楼 truelance 的回复:数据存到文件里，用归并排序 可以用数据库软件吗 我知道access的容量好像才最大2G肯定不够…… 其他的呢？

数据存到文件里，用归并排序

取TOP1000,可以用最小二叉树来实现，可以把数据保存到硬盘中，保存成比如TXT的格式，然后就是读数据、建二叉树，有1000个数据的最小二叉树，等数据全部遍历一次后，就可以得到TOP1000了。  是50G 的数据？如果要全排序，可以借助哈希表，或外排序

用文件读写模拟内存读写，参考_lseeki64函数。 排序算法参考C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\QSORT.C


引用 4 楼 cypress2012 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] #include <stdio.h> #include <string.h> char s[80]; int i; char c; int main() {     while (1) {         printf("Input a integer:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (strlen(s)>10) {             printf("Input too long(>9)!\n");             continue;         }         if (2==sscanf(s,"%d%c",&i,&c)) {             if ('\n'==c) {                 printf("%d is a integer.\n",i);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a integer!\n",s);     }     return 0; }  四哥，我就想简单的实现个scanf的功能，你应该不用帮我写一个类似的吧，帮忙看看我那个问题出哪里好么[/quote] 你以后类似我这段代码使用scanf，就不会出也不会问类似问题了。 scanf功能是IT界最简单也最复杂的功能。

引用 3 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> char s[80]; int i; char c; int main() {     while (1) {         printf("Input a integer:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (strlen(s)>10) {             printf("Input too long(>9)!\n");             continue;         }         if (2==sscanf(s,"%d%c",&i,&c)) {             if ('\n'==c) {                 printf("%d is a integer.\n",i);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a integer!\n",s);     }     return 0; }  四哥，我就想简单的实现个scanf的功能，你应该不用帮我写一个类似的吧，帮忙看看我那个问题出哪里好么

引用 1 楼 ZHANGJIXIN 的回复:没发现代码错误我把scanf那里注释掉，然后i初始化的时候就赋值，这样是可以执行ok的。用scanf键盘输入就报错了

没发现代码错误


Question: c语言如何实现定点运算，用定点模拟浮点

请看11楼链接的帖子。

那个double类型在c语言中是不是在不同型号的机子上的长度不一样啊，如何保证不同平台上的运行结果一致，是不是只能用定点型啊

引用 8 楼 a707497224 的回复:我现在想显示定点数，整数部分好显示，那小数部分怎么办，好麻烦啊，谁能教我一下，谢谢了 __int64 v=1234567890123456789i64; printf("%I64.%I64\n",v/1000000000i64,v%1000000000i64);//1234567890.123456789

不是说定点数比浮点数，精度高吗，怎么我在使用乘法时，浮点数的值更接近真实值呢，它用了什么优化吗，怎么才能让定点数精度更高

看了一下那个 decimal128也是浮点型的，老师让我们用定点型来做，不过还是谢谢了

你要的不是定点运算，你要的是高精度小数，比如用在银行之类的。 到网上搜索 decimal128 之类的。 有一个库叫做 libdecnumber 好像就是解决这个的。

太感谢了，给了我很大帮助，不过还有个问题我用的int 分解为1位符号位，3位数字位和28位小数位，但是在计算乘法是如何存储中间临时结果因为乘法会扩大，例如我定义的数据类型类型不能存储中间结果，我要怎么做才能让精度更大一些，我想先两个数左移16再乘这样可以吗，还是有更好的算法

主要看你的小数部分有多长,,,或者说整个数有多长,如果不是很长的话,直接把小数点舍弃就是了,然后通过计算得出结果,再通过另一个计算得出小数点的位置就行了,,,,比如,12.345*67.89 直接用12345*6789然后小数点标到12*67的位数后面就是了,而12.345/67.89同样,用12345/6789,然后把小数眯标到12/67的整数位后面就是了,难道你计算的数长度已经超过long long所能表达的极限长度了?那结合整数数组来做就是了,,,,并不会损失多少效率的 切记一点,别走弯路,你要的是小数长,而不是大数运算,别被带到套数运算的沟里,那样,你就真损失效率了

主要是运算尤其是除法与乘法，还有就是输入时把浮点转化为定点

可以用结构体呀。字符串也是可以的哦

参考 http://en.wikipedia.org/wiki/Libfixmath


Question: 一个搞怪的问题

不是没有初始化的问题，在字符串初始化中，未初始化的空间不是自动初始化为NULL即‘\0',可我的电脑自动初始化的是a

初始化变量。。。

未初始化的局部变量

你是想看c语言里面,未初始 的变量 吗?


Question: MSP430F169  定时器中断问题

你在if语句里面设断点，看看究竟是那句话出的错


Question: c学习困惑

我的经验就是 数据结构的题  还有算法导论的题  这2本教材提供了很多的思考和练习的题   多做会增加内功哦~~~~~~~~~~~

引用 31 楼 sholber 的回复:[quote=引用 30 楼 misskissC 的回复:] [quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。[/quote] 能够通过《计算机组成原理》而明白计算机的也算有些文化。系统学C还得搞点哲学....

引用 34 楼 misskissC 的回复:[quote=引用 33 楼 sholber 的回复:] [quote=引用 32 楼 misskissC 的回复:] [quote=引用 31 楼 sholber 的回复:] [quote=引用 30 楼 misskissC 的回复:] [quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。[/quote] 求 系统版本的C...不然都跟赵老湿系统C了[/quote] 下载个N1570.PDF看懂了就是第一步。第二步是要加强实践。[/quote] 您说的系统C就是 C标准 + 实践么，也有十分儿的道理。赵老湿说过，任何不按照他路线走的IT人，都易发生断章取义的现象.....[/quote]  招虱老湿再不系统学习，就是下一个谭浩强。哈哈。找虱老湿只信编译器……

引用 33 楼 sholber 的回复:[quote=引用 32 楼 misskissC 的回复:] [quote=引用 31 楼 sholber 的回复:] [quote=引用 30 楼 misskissC 的回复:] [quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。[/quote] 求 系统版本的C...不然都跟赵老湿系统C了[/quote] 下载个N1570.PDF看懂了就是第一步。第二步是要加强实践。[/quote] 您说的系统C就是 C标准 + 实践么，也有十分儿的道理。赵老湿说过，任何不按照他路线走的IT人，都易发生断章取义的现象.....

引用 32 楼 misskissC 的回复:[quote=引用 31 楼 sholber 的回复:] [quote=引用 30 楼 misskissC 的回复:] [quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。[/quote] 求 系统版本的C...不然都跟赵老湿系统C了[/quote] 下载个N1570.PDF看懂了就是第一步。第二步是要加强实践。

引用 31 楼 sholber 的回复:[quote=引用 30 楼 misskissC 的回复:] [quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。[/quote] 求 系统版本的C...不然都跟赵老湿系统C了

引用 30 楼 misskissC 的回复:[quote=引用 29 楼 sholber 的回复:] 学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工 [/quote] 计算机原理谁都学过。这不算有文化。 据我的观察，赵老湿的C语言的确是不系统。

引用 29 楼 sholber 的回复:学C的有三类人： 第一类，不探求细节，只靠点滴积累获得知识。这就像一个没文化的钳工，刚进厂时啥也不懂，但好学，喜欢观察和思考，虽然没有经过正规学校教育，也能在几十年后成为工厂里的技术尖子。这类人的典型代表就是赵老湿和论坛版主。不过问题是这类人缺乏正规的理论素养，基础不足，如果一个问题他从来没遇到过，他会不知所措。 第二类，学过C或者没学过，但都一样。觉得C就那些东西，很简单。但用的时候也会茫然。这种人实践经验都没有，更遑论理论知识。 第三类，理论和实践都扎实。这才是我们要达到的目标。可惜都走光了，本论坛现在没有这样的人了。 赵老师从 《计算机原理》 -->省略号，怎么是没文化的钳工

引用 27 楼 gzazty 的回复:你们这些老人就不能好好的带带新人……

编程能力至少由三部分组成：一部分是写代码的能力；另一部分是理解编译器报错的能力；更重要的部分是使用调试器提供的各种调试功能调试各种运行时错误的能力。

说实话，我觉得这句话有点误导人的感觉  其实学编程并不需要刻意保证敲代码的数量  提升编程能力最快的方法是用你学的语言实现算法  比如dijkstra算法 这算简单的  最好是你懂比较深一点的算法  比如遗传算法    你随便找个遗传算法的题目   做一遍 我保证你的编程能力提升超级快  我本人其实刚学编程的时候入门并不顺利，走了很多弯路，不过庆幸的是我学了算法，而老师要求必须用语言去实现这些算法，我做了这些后编程能力瞬间提高很多  另外，编程能力由两部分组成：一部分是写代码的能力；另一部分是理解编译器报错的能力 所以在这里提醒楼主，对于第二部分的能力，只能靠花半天一天的时间去找你自己写的代码里那些非常sb的错误来培养

你们这些老人就不能好好的带带新人……

既要抄，又要自己写。

引用 22 楼 ForestDB 的回复:既要抄，又要自己写。 +1 与“天下文章一大抄”有异曲同工之妙

引用 22 楼 ForestDB 的回复:既要抄，又要自己写。 同意！ 比如我在CSDN论坛的回复说实话就是：90%拷贝粘贴，5%搜索引擎搜，5%自己写。

我也很困惑啊

自己写一些简单的小程序，然后用学到的知识不断完善他，同时不断为这个程序增加一些新的功能，比如可以写个记事本、扫雷等小程序，实现起来也挺容易

引用 15 楼 zhao4zhong1 的回复:[quote=引用 14 楼 cxs812747475 的回复:] 没事的时候就来csdn看帖  别人不会的你也不一定会 没事的时候就来csdn回帖 前人不会的后人也一定不会，拷贝粘贴点前人问题的答案，还能赚点后人问题的积分！[/quote]   找死老师在哪都恩能够看到你的身影啊

第一步、多做一些语法题，了解每个语法的规则和另类用法 。 第二步、多做一些算法题，了解每个算法中所使用到的语法，巩固语法的同时提高算法编写能力。 第三步、多做一些小项目，了解每个项目中可以用到哪些算法，巩固算法的实用性。


Question: 有关数据结构的几个小问题  求救各位高手

引用 10 楼 qq_23908539 的回复:[quote=引用 3 楼 Evankaka 的回复:] 第二个可以在最后加一句while(1); 这样不管是什么编译器都不会退出啦～，当然 。2楼的方法也行，只不过只能用在C++里头，C不行  我刚试过加个while（1）确实好用   但这样的话怎么什么都输不进去了， 这个while（1）的含义我还不是太理解，麻烦再解释一些，非常感谢！！[/quote]  while(1);//这是一个死循环，1表示为真，要注意后面的分号，表示什么都不做～。我平时写控制台程序最后喜欢加这个

引用 3 楼 Evankaka 的回复:第二个可以在最后加一句while(1); 这样不管是什么编译器都不会退出啦～，当然 。2楼的方法也行，只不过只能用在C++里头，C不行  我刚试过加个while（1）确实好用   但这样的话怎么什么都输不进去了， 这个while（1）的含义我还不是太理解，麻烦再解释一些，非常感谢！！

非常感谢每一个替我解答疑问的人！

引用 1 楼 C0909 的回复:第一个  0在C语言里就是NULL   第二个 你可以使用systme("pause");//这个是等待用户按下任意键 第三个 等下 第四个 是  三木运算符  如果p1==1 把p1赋值給 p3->next 否则 把p2赋值給 p3->next  p3->next=p1?p1:p2;这句的意思是如果p1指针不为空，则将p1赋给p3->next，否则将p2赋给p3->next

第一个为强制转换

引用 4 楼 Evankaka 的回复:第四个 <表达式1>?<表达式2>:<表达式3>; "?"运算符的含义是: 先求表达式1的值, 如果为真, 则执行表达式2，并返回表达式2的结果 ; 如果表达式1的值为假, 则执行表达式3 ，并返回表达式3的结果。 可以理解为条件 ? 结果1 : 结果2 里面的？号是格式要求。也可以理解为是不是条件成立，条件成立为结果1否则为结果2。  我怎么感觉楼上的说错了  p3->next=p1?p1:p2;    这个语句不知道啥意思。。 p3->next=p1是赋值啊，不是判断。所以它无论怎么样返回都是真的。所以返回p1  如果p1  为NULL，则将p3的next指向p2,否则，指向p1

/*  #define NULL 0  int main() { 	... 	getchar(); 	return 0; }  //exit(1)表示异常退出.这个1是返回给操作系统的。 //exit(x)（x不为0）都表示异常退出 //exit(0)表示正常退出 //exit()的参数会被传递给一些操作系统，包括UNIX,Linux,和MS DOS，以供其他程序使用。 //stdlib.h: void exit(int status);  p3->next=p1?p1:p2;   if(p1!=NULL)p3->next=p1; else p3->next=p2;  */

第三个：调用exit()函数会正常结束程序,该函数需要一个Int类型的参数,它表示程序结束时的状态,该参数可以是0或者表示成功数字。一般使用return 就可以了 除非在特别的情况才使用


Question: 求大神告诉我原因，为什么输出的结果会是这样呢 ？按道理x[8]='\0',输出结果应该是1 9 9 4才对啊，哪里出问题了，请详细说下，谢谢！！

#include <stdio.h> #include <string.h> void aaa(char x[10]) { 	int i; 	for(i=strlen(x)-1;i>=0;i--) 	{ 		x[2*i]=x[i]; 		x[2*i+1]=' '; 	} 	printf("%s\n",x); } void main() { 	char a[10]; 	gets(a); 	aaa(a); } /* 1.i=strlen(x)不对,比如楼主输入1994,strlen(x)=4,而对应的是x[0],x[1],x[2],x[3] 2.按楼主意思格式应该是          0 1 2 3 4 5 6 7 8    input:1 9 9 4   output:1   9   9   4   所以是x[2*i]=x[i] x[2*i+1]=' ' */

#include <stdio.h> #include <string.h> void aaa(char x[10]) { 	int i; 	int len = strlen(x); 	for(i=len - 1;i>=0;i--) 	{ 		x[2*i+1]=x[i];  		x[2*i]=' '; 		 	} 	x[2 * len] = 0; 	printf("%s\n",x);} void main() { 	char a[10];  	gets(a);  	aaa(a); }  你那个写法x[0]取不出来的 另外数组小了，很容易越界 注意数组下标从0开始

x[10]的下标序号是从0开始的

把printf放到循环里看结果


Question: 自定义的http协议，怎样读取body?

引用 20 楼 zhuyf87 的回复:[quote=引用 19 楼 baidu_24733621 的回复:] [quote=引用 17 楼 zhuyf87 的回复:] [quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗[/quote]  既然不固定，。那么只有一个办法读取头， 一个个字节recv。  但是这样效率很低。 [/quote]  呃，为什么要一个一个字节的recv呢？一个线程负责将协议数据读取到一个缓冲队列中，另一个线程将缓冲队列中的数据copy出来，遍历解析，正确解析一包之后，就从缓冲队列中删除一包数据。[/quote]  以前说了， 头的大小不固定，你怎么知道， 几个字节是一个完整的头呢？   请认真看问题。  我不知道其他开源库是怎么处理的？   标准http 的头，确实是不固定的， [/quote]  不是头有多大，就必须一次recv多大。而是只要有数据就读到buffer里，然后处理线程从buffer中取数据解析。 读到特殊标记，比如\r\n\r\n时，则读完了一个完整的Head。 我认真看问题了，其实我和7楼的想法是一样的，我觉得你认为的： “既然不固定。那么只有一个办法读取头， 一个个字节recv。” 是不对的。 [/quote]  赞同  接受线程，每次接受几k大小的包，然后放到buffer中，接受线程只管接受，不关协议内容。  处理线程去处理包里的东西。 谢谢

引用 17 楼 zhuyf87 的回复:[quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗[/quote]  既然不固定，。那么只有一个办法读取头， 一个个字节recv。  但是这样效率很低。 [/quote]  呃，为什么要一个一个字节的recv呢？一个线程负责将协议数据读取到一个缓冲队列中，另一个线程将缓冲队列中的数据copy出来，遍历解析，正确解析一包之后，就从缓冲队列中删除一包数据。[/quote]  以前说了， 头的大小不固定，你怎么知道， 几个字节是一个完整的头呢？   请认真看问题。  我不知道其他开源库是怎么处理的？   标准http 的头，确实是不固定的，

根据自己项目需求，采用相应的方法，没有那种方法绝对的适合所有应用

引用 14 楼 baidu_24733621 的回复:[quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗[/quote]  既然不固定，。那么只有一个办法读取头， 一个个字节recv。  但是这样效率很低。 [/quote]  呃，为什么要一个一个字节的recv呢？一个线程负责将协议数据读取到一个缓冲队列中，另一个线程将缓冲队列中的数据copy出来，遍历解析，正确解析一包之后，就从缓冲队列中删除一包数据。

引用 19 楼 baidu_24733621 的回复:[quote=引用 17 楼 zhuyf87 的回复:] [quote=引用 14 楼 baidu_24733621 的回复:] [quote=引用 13 楼 zhuyf87 的回复:] [quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗[/quote]  既然不固定，。那么只有一个办法读取头， 一个个字节recv。  但是这样效率很低。 [/quote]  呃，为什么要一个一个字节的recv呢？一个线程负责将协议数据读取到一个缓冲队列中，另一个线程将缓冲队列中的数据copy出来，遍历解析，正确解析一包之后，就从缓冲队列中删除一包数据。[/quote]  以前说了， 头的大小不固定，你怎么知道， 几个字节是一个完整的头呢？   请认真看问题。  我不知道其他开源库是怎么处理的？   标准http 的头，确实是不固定的， [/quote]  不是头有多大，就必须一次recv多大。而是只要有数据就读到buffer里，然后处理线程从buffer中取数据解析。 读到特殊标记，比如\r\n\r\n时，则读完了一个完整的Head。 我认真看问题了，其实我和7楼的想法是一样的，我觉得你认为的： “既然不固定。那么只有一个办法读取头， 一个个字节recv。” 是不对的。

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

引用 13 楼 zhuyf87 的回复:[quote=引用 11 楼 baidu_24733621 的回复:] [quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗[/quote]  既然不固定，。那么只有一个办法读取头， 一个个字节recv。  但是这样效率很低。

加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。

引用 2 楼 u012879787 的回复:[quote=引用 1 楼 starytx 的回复:] 固定长度不行吗？或者说协议设置成前四个字节保存head的长度，先读取到这个信息，然后根据这个读取对应长度的信息  开源库是如何处理的？  自定义http协议，感觉头+体里的东西都是按照标准http协议走的，  标准 http的头里没有头大小这个东西。  你的方法不对吧 [/quote]我没研究过http协议，只是针对lz说的“自定义”来说可以这样，如果要和标准依附那就要遵循标准，而不是自定义了

要么加len字段，要么加标记。

引用 6 楼 bsnry 的回复:[quote=引用 5 楼 luciferisnotsatan 的回复:] [quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 starytx 的回复:] 固定长度不行吗？或者说协议设置成前四个字节保存head的长度，先读取到这个信息，然后根据这个读取对应长度的信息  开源库是如何处理的？  自定义http协议，感觉头+体里的东西都是按照标准http协议走的，  标准 http的头里没有头大小这个东西。  你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准，要自己定义一套，那么就要你自己想怎么算结束了[/quote]  两个\r\n， 那么如何读取head, 每次读取一个字符来判断头是否结束，不觉得效率太低了吗  [/quote] 你不会socket一次接收一大段数据到内存buffer里，然后再去判断这段buffer里有没有连续的\r\n。干嘛要一个字节一个字节recv  同时，CPU解析这么段http文本的所需时间相对于网络传输的时间来说可以忽略不计的。

引用 5 楼 luciferisnotsatan 的回复:[quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 starytx 的回复:] 固定长度不行吗？或者说协议设置成前四个字节保存head的长度，先读取到这个信息，然后根据这个读取对应长度的信息  开源库是如何处理的？  自定义http协议，感觉头+体里的东西都是按照标准http协议走的，  标准 http的头里没有头大小这个东西。  你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准，要自己定义一套，那么就要你自己想怎么算结束了[/quote]  两个\r\n， 那么如何读取head, 每次读取一个字符来判断头是否结束，不觉得效率太低了吗

引用 2 楼 u012879787 的回复:[quote=引用 1 楼 starytx 的回复:] 固定长度不行吗？或者说协议设置成前四个字节保存head的长度，先读取到这个信息，然后根据这个读取对应长度的信息  开源库是如何处理的？  自定义http协议，感觉头+体里的东西都是按照标准http协议走的，  标准 http的头里没有头大小这个东西。  你的方法不对吧 [/quote] 标准http头是以两个连续的“\r\n”结尾的。 如果你不按标准，要自己定义一套，那么就要你自己想怎么算结束了

引用 11 楼 baidu_24733621 的回复:[quote=引用 10 楼 zhuyf87 的回复:] 加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。 [/quote]  当然是不固定的，这有什么关系吗

协议栈一般是这么实现（大概思路）： 1. 查找两个 "\r\n" 以确定头结束 2. 因为是 TCP，没找到则需要缓存数据等待后续数据到达（新数据到达开始 1） 3. 找到了就知道 Header 在哪里结束，对 Header 部分查找 "\r\n"（处理每一行） 4. 对每一行数据查找 ":" 分割，前面的部分匹配头域关键字，按照不同的头来处理 ":"  之后的内容 5. 获得 Content-Length 头，检查 Body 的数据是否已收全（Header 结束的位置至数据的尾部） 6. 如果没有收全，需要等待 Body 的后续数据，因此缓存已处理内容（新数据到达开始 5） 7. 按照 Body 的类型，解析 Body 8. 仍有剩余数据（已收取数据减去 Header 和 Body 的长度）需要开始下一个报文的解析（因为是 TCP），继续 1

引用 10 楼 zhuyf87 的回复:加标记不会降低效率，本来http头里面的各个字段也需要遍历一遍才能解析出来。  标准http的头的大小不固定。

请参考nginx的HTTP协议解码部分。

加一个 字段标注   head多大

引用 1 楼 starytx 的回复:固定长度不行吗？或者说协议设置成前四个字节保存head的长度，先读取到这个信息，然后根据这个读取对应长度的信息  开源库是如何处理的？  自定义http协议，感觉头+体里的东西都是按照标准http协议走的，  标准 http的头里没有头大小这个东西。  你的方法不对吧


Question: 编译不通过，不知道为什么

void fnchange(struct test sthuman);//要求输入不是数组  fnchange(ststaff);//你这输入是个数组啊。。

引用 5 楼 C0909 的回复: struct test{     int iage;     char sex; }ststaff[2]={18,'M'};  难道不是应该写成  struct test{     int iage;     char sex; }ststaff[2]={{18,'M'},{19,'c'}};  还有一个错误就是你的  ststaff 是数组   而你的 函数里的形参不是数组,是一个普通变量, 数组不可以传递給 普通变量    要么你把形参写成  指针 要么就 把  形参写成数组(其实编译以后都是指针)！

引用 3 楼 user-3 的回复:[quote=引用 2 楼 tenmenglin 的回复:] [quote=引用 1 楼 user-3 的回复:] fnchange(ststaff); 里边的参数传的不对 函数需要一个结构体对象，你传的是个数组，改成fnchange(ststaff[0]);还是不对啊[/quote]printf("%d,%c\n",ststaff[0].iage,ststaff[0].sex); [/quote] 那个不应该是这个吗？ststaff[1].sex，0不是被占用了么  而且  fnchange 在函数里不是又被赋值了么

引用 2 楼 tenmenglin 的回复:[quote=引用 1 楼 user-3 的回复:] fnchange(ststaff); 里边的参数传的不对 函数需要一个结构体对象，你传的是个数组，改成fnchange(ststaff[0]);还是不对啊[/quote]printf("%d,%c\n",ststaff[0].iage,ststaff[0].sex);

引用 1 楼 user-3 的回复:fnchange(ststaff); 里边的参数传的不对 函数需要一个结构体对象，你传的是个数组，改成fnchange(ststaff[0]);还是不对啊


Question: x262 64bit crash

引用 1 楼 user-1 的回复:以前搞过。。现在忘完了。 帮忙回忆一下吧，谢谢了！你那时候64位的x262可以用吗？

是common/quant.c中的x264_quant_8x8_avx2出错，没找到这个函数定义，好像是在common/x86/quant-a.asm中，我对汇编语言不熟没看出来。只要把这个函数所在的两行注释起来，不用这个汇编优化，默认使用static int quant_8x8函数就不会有问题。

以前搞过。。现在忘完了。


Question: 问下windows7下的JMP ESP 指令的地址是多少？

哦哦 ，是变动的了啊

换个系统试一下，稍微看了一下， 是想修改main的返回地址，12个字节后就是你注释jmp的地方，看起来不是jmp指令？

《The Intel 64 and IA-32 Architectures Software Developer's Manual》

WIN7以后, 几个核心dll都是浮动地址加载的, 没有统一的JMP ESP地址. 你到你要溢出的程序里找个合适的地址呗...


Question: 触屏点餐系统，用什么语言开发？

系统的开发随意了，C++的qt开发界面也行，MFC开发界面也行，但是触屏应该是硬件问题了，那就不是单纯的软件解决了！

java最简单了

最简单的：android平板，再找人给你开发个点餐应用。

c++吧，不错呦！

我觉得c语言应该比较适合

u011337306：  为什么，要调试底层驱动？

组装台收银机，必须具备以下两方面。 1.支持触摸屏的系统。 2.电脑有触摸屏功能。 对么？

在网络看到，有种触摸屏收银一体机。 这东西，怎么安装软件？

1.如果是android系统，Java开发APP，C/C++开发底层；如果是Windows，可以C++开发App，C/C++开发底层； 2.比如触摸屏的话，一般是电容屏，一般都是IIC接口，需要调试底层驱动；


Question: 我想把一个字节拆开来用

引用 5 楼 adlay 的回复:现在系统都是 64 位的了，一次就取 8 个字节，就算是 32 位的系统，一次读也可以同时取四个字节，不存在说 2 个字节要分开取。 位运算在 CPU 内部进行，不访问任何外部设备，当然快了 如果不这么做，我就要把数据写进硬盘，然后读文件  如果数据能缩水一半，就不用硬盘操作了，我觉得有这个必要

2方法比1写程序要麻烦点，占用的内存要少点，其他的区别其实不大，效率其实差不多

先做出来再谈效率，啥都没有等于白说！没有一步到位的事

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

如果内存少,可以用位运算.c语言够灵活,自己想咋搞咋搞. 给你个结构供参考.  typdef union{     char a;     struct byte2bit {         char top       : 4;         char bottom : 4;     } bit_u; } bit_op;

你老师告诉你一个字节存两个值快了?还是你老师告诉你一个字节存两个值是位运算了?,,,如果你老师真的这么说了,要么,你老师口误,没说明确,要么,他忽悠你. 位运算的效率与你怎么存储有毛关系?,你一个字节存一个有效数据和丰8个,与是不是位运算什么关系?,,,位运算指的是运算过程,不是存储方式..你取一个字节C(假设字符型)的四位 C&0xF,这叫位运算,C%16这不叫位运算, 切记,位运算是运算,不是存储

再快的运算也比不运算要慢 你一个字节的两个有效数据要做什么处理呢？加减乘除？

如果你真的只要使用一个字节的一部分，那你可以考虑使用位域啊

because  x86 registers  ?   AL/AH/AX/EAX/RAX: Accumulator        ??  modern computer has  rich resource   SIMD  XMM0–XMM15   128-bit    SIMD YMM0–YMM15    256-bit    SIMD  ZMM0–ZMM31      512-bit

具体问题具体分析。老师的话也可以质疑啊

没必要这么省内存吧？

取即赋值 ，当然还有计算   而位可以用移位  位域等实现 蛮方便  效率也高

效率这东西，等你确定是因为把一个字节拆开导致慢的时候再说。没必要在这问题上纠结，基本上不会是因为这种东西导致速度慢的。


Question: 形参不可以是void类型吗

void*可以吧

sizeof是关键字

你先想想要写什么东西，用void干什么

C 基本上不支持泛型 不过有几种方式，可以大约实现泛型  一种是 函数指针，  一种是宏 void *则 可以储存任何类型的地址 其实，C标准库的 qsort 就是 C泛型的一个例子 另外 如果想实现，一个标准的泛型，可以自己写个泛型的预处理器， 就像 C++的早期实现那样， 写个 CFront 就可以了 不过这个必要性不大

可以的，可以是void

引用 18 楼 zouyuncheng 的回复:你需要定义的是多个函数,传递数据类型以判断调用哪个函数, 顺便说一句,之所以不能用void做参数的原因是,C函数的参数类型作用是确定数据长度,说白了,你提供给它一个明确的存储数据所需的空间大小就可以了,,,可VOID是多大?,,,,,所以,不能用void做参数,而上面人说的void*,这个是明确的指针,而在一个系统中,指针大小是确定的.所以可以做参数. 而sizeof是运算符,它被规到运算符中,完全是因为它的作用和使用方法,而它的级别甚至和宏相当,一般是在编译前就处理完了,所以无法在运行时用它去确定任何类型的大小  而想像C++那样去直接实现用参数类型来确定调用哪个函数,,,估计用复杂的宏也许能实现,但像你这样调用,是肯定不行的, 可行的方法是 void * max(char *, void *, void *);  int main(void) { 	int a=10, b=50; 	double c=15.47, d=17.92; 	 	printf ("%d\t%g\n", *(int *)max("int", &a, &b), *(double*) max("double", &c, &d)); 	 	return 0; }  double * dmax(double * c, double * d) { 	return *c > *d ? c : d; }  int * imax(int * a, int * b) { 	return *a > *b ? a : b; }  void * max ( char * st, void * x, void * y) { 	if (strcmp(st, "double") == 0) 		return dmax(x,y); 	if (strcmp(st, "int") == 0) 		return imax(x,y); } 当然你在同一个函数中实现也没事,不过是把一个函数的代码更复杂一些而已,

sizeof（void *），在32位机器上的结果是4，因为指针占用4个字节，得到的结果跟你想要的可能会不一致  引用 3 楼 robertbo 的回复:可以是void *

/* Copyright (C) 1991-2014 Free Software Foundation, Inc.    This file is part of the GNU C Library.    Written by Douglas C. Schmidt (schmidt@ics.uci.edu).     The GNU C Library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.     The GNU C Library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.     You should have received a copy of the GNU Lesser General Public    License along with the GNU C Library; if not, see    <http://www.gnu.org/licenses/>.  */  /* If you consider tuning this algorithm, you should consult first:    Engineering a sort function; Jon Bentley and M. Douglas McIlroy;    Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993.  */  #include <alloca.h> #include <limits.h> #include <stdlib.h> #include <string.h>  /* Byte-wise swap two items of size SIZE. */ #define SWAP(a, b, size)						      \   do									      \     {									      \       size_t __size = (size);						      \       char *__a = (a), *__b = (b);					      \       do								      \ 	{								      \ 	  char __tmp = *__a;						      \ 	  *__a++ = *__b;						      \ 	  *__b++ = __tmp;						      \ 	} while (--__size > 0);						      \     } while (0)  /* Discontinue quicksort algorithm when partition gets below this size.    This particular magic number was chosen to work best on a Sun 4/260. */ #define MAX_THRESH 4  /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct   {     char *lo;     char *hi;   } stack_node;  /* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The stack needs log (total_elements) entries (we could even subtract    log(MAX_THRESH)).  Since total_elements has type size_t, we get as    upper bound for log (total_elements):    bits per byte (CHAR_BIT) * sizeof(size_t).  */ #define STACK_SIZE	(CHAR_BIT * sizeof(size_t)) #define PUSH(low, high)	((void) ((top->lo = (low)), (top->hi = (high)), ++top)) #define	POP(low, high)	((void) (--top, (low = top->lo), (high = top->hi))) #define	STACK_NOT_EMPTY	(stack < top)   /* Order size using quicksort.  This implementation incorporates    four optimizations discussed in Sedgewick:     1. Non-recursive, using an explicit stack of pointer that store the       next array partition to sort.  To save time, this maximum amount       of space required to store an array of SIZE_MAX is allocated on the       stack.  Assuming a 32-bit (64 bit) integer for size_t, this needs       only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).       Pretty cheap, actually.     2. Chose the pivot element using a median-of-three decision tree.       This reduces the probability of selecting a bad pivot value and       eliminates certain extraneous comparisons.     3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving       insertion sort to order the MAX_THRESH items within each partition.       This is a big win, since insertion sort is faster for small, mostly       sorted array segments.     4. The larger of the two sub-partitions is always pushed onto the       stack first, with the algorithm then concentrating on the       smaller partition.  This *guarantees* no more than log (total_elems)       stack size is needed (actually O(1) in this case)!  */  void _quicksort (void *const pbase, size_t total_elems, size_t size, 	    __compar_d_fn_t cmp, void *arg) {   char *base_ptr = (char *) pbase;    const size_t max_thresh = MAX_THRESH * size;    if (total_elems == 0)     /* Avoid lossage with unsigned arithmetic below.  */     return;    if (total_elems > MAX_THRESH)     {       char *lo = base_ptr;       char *hi = &lo[size * (total_elems - 1)];       stack_node stack[STACK_SIZE];       stack_node *top = stack;        PUSH (NULL, NULL);        while (STACK_NOT_EMPTY)         {           char *left_ptr;           char *right_ptr;  	  /* Select median value from among LO, MID, and HI. Rearrange 	     LO and HI so the three values are sorted. This lowers the 	     probability of picking a pathological pivot value and 	     skips a comparison for both the LEFT_PTR and RIGHT_PTR in 	     the while loops. */  	  char *mid = lo + size * ((hi - lo) / size >> 1);  	  if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) 	    SWAP (mid, lo, size); 	  if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) 	    SWAP (mid, hi, size); 	  else 	    goto jump_over; 	  if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) 	    SWAP (mid, lo, size); 	jump_over:;  	  left_ptr  = lo + size; 	  right_ptr = hi - size;  	  /* Here's the famous ``collapse the walls'' section of quicksort. 	     Gotta like those tight inner loops!  They are the main reason 	     that this algorithm runs much faster than others. */ 	  do 	    { 	      while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) 		left_ptr += size;  	      while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) 		right_ptr -= size;  	      if (left_ptr < right_ptr) 		{ 		  SWAP (left_ptr, right_ptr, size); 		  if (mid == left_ptr) 		    mid = right_ptr; 		  else if (mid == right_ptr) 		    mid = left_ptr; 		  left_ptr += size; 		  right_ptr -= size; 		} 	      else if (left_ptr == right_ptr) 		{ 		  left_ptr += size; 		  right_ptr -= size; 		  break; 		} 	    } 	  while (left_ptr <= right_ptr);            /* Set up pointers for next iteration.  First determine whether              left and right partitions are below the threshold size.  If so,              ignore one or both.  Otherwise, push the larger partition's              bounds on the stack and continue sorting the smaller one. */            if ((size_t) (right_ptr - lo) <= max_thresh)             {               if ((size_t) (hi - left_ptr) <= max_thresh) 		/* Ignore both small partitions. */                 POP (lo, hi);               else 		/* Ignore small left partition. */                 lo = left_ptr;             }           else if ((size_t) (hi - left_ptr) <= max_thresh) 	    /* Ignore small right partition. */             hi = right_ptr;           else if ((right_ptr - lo) > (hi - left_ptr))             { 	      /* Push larger left partition indices. */               PUSH (lo, right_ptr);               lo = left_ptr;             }           else             { 	      /* Push larger right partition indices. */               PUSH (left_ptr, hi);               hi = right_ptr;             }         }     }    /* Once the BASE_PTR array is partially sorted by quicksort the rest      is completely sorted using insertion sort, since this is efficient      for partitions below MAX_THRESH size. BASE_PTR points to the beginning      of the array to sort, and END_PTR points at the very last element in      the array (*not* one beyond it!). */  #define min(x, y) ((x) < (y) ? (x) : (y))    {     char *const end_ptr = &base_ptr[size * (total_elems - 1)];     char *tmp_ptr = base_ptr;     char *thresh = min(end_ptr, base_ptr + max_thresh);     char *run_ptr;      /* Find smallest element in first threshold and place it at the        array's beginning.  This is the smallest array element,        and the operation speeds up insertion sort's inner loop. */      for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)       if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0)         tmp_ptr = run_ptr;      if (tmp_ptr != base_ptr)       SWAP (tmp_ptr, base_ptr, size);      /* Insertion sort, running from left-hand-side up to right-hand-side.  */      run_ptr = base_ptr + size;     while ((run_ptr += size) <= end_ptr)       { 	tmp_ptr = run_ptr - size; 	while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) 	  tmp_ptr -= size;  	tmp_ptr += size;         if (tmp_ptr != run_ptr)           {             char *trav;  	    trav = run_ptr + size; 	    while (--trav >= run_ptr)               {                 char c = *trav;                 char *hi, *lo;                  for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)                   *hi = *lo;                 *hi = c;               }           }       }   } }

你要写的这个不是模版函数吗。。。用c好像很为难啊。。。

我觉得应该是可以，只不过你在函数里面还要把它转成你要的类型。。 要不你就用泛型。。

#define  add (a,b,c)   ( c) = (a)+(b)   int main {  int a =0,b=1,c=2; double r=3,s=4,t=5; add(a,b,c); add(r,s,t); printf("%d %lf\n",c,t); return 0; }

不可以，但可以是void*

引用 6 楼 fuqingyun 的回复:[quote=引用 3 楼 robertbo 的回复:] 可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加  [/quote] 你需要的是C++的泛型，C不能很方便的解决这个问题。

不可以 sizeof是运算符

LZ貌似要C++泛型  可以用void*  你代码相加 也是 z= *((int*)x)+*((int*)y);

引用 6 楼 fuqingyun 的回复:[quote=引用 3 楼 robertbo 的回复:] 可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加  [/quote]谁说可以直接这样相加了，只是说可以用void*作为形参，你可以通过再加一个参数来表示某种类型，然后在函数内部根据第三个参数将对应的形参指针强制转化为对应的类型，从而取得正确的数值。比如第三个定义成枚举类型

引用 3 楼 robertbo 的回复:可以是void * 哥，还是不行  #include<stdio.h> add(void *x, void *y); void main() { 	int a=1; 	int b=2; 	printf("%d\n",add(&a,&b)); } int add(void *x, void *y) { 	int z; 	//printf("%d",sizeof(x)); 	z=x+y; 	return z; } //error C2110: cannot add two pointers加了*号了，还说指针不能相加

sizeof 是运算符

引用 3 楼 robertbo 的回复:可以是void * 谢谢，太有用了 那sizeof可以那么用吗？


Question: 【C语言】求帮助看个程序 能运行但是输入数据不弹出结果

好长的程序。。

a:  printf("\n回到原火车票管理系统:"); 	printf("\n请输入你的选择:"); 	scanf("%d",&x); 	switch(x){ 	   case 1:printf("\n******************************************"); 	          printf("\n*查询功能界面:                           *");               printf("\n*1.按火车出发日期查询*");               printf("\n*2.按车的班次查询*"); 			  printf("\n*3.返回到原火车票系统                    *"); 	          printf("\n******************************************");           b:  printf("\n请输入你的选择:"); 			  scanf("%d",&y); 			  switch(y){ 			    case 1: printf("\n请输入你要查询的售票日期:"); 					    scanf("%s",e); 						searchlist_traindate(myl,e); 						break; 				case 2: printf("\n请输入你要查找的车的班次:"); 					    scanf("%s",d); 						searchlist_trainnum(myl,d); 						break; 				case3: goto a; 					    break; 				default:printf("\n输入错误");} 			  goto b; 			  break; 		case 2:printf("\n请输入你要买的火车票的起点站和终点站:"); 			   scanf("%s%s",f1,f2); 			   if(deletelist_l(myl,f1,f2)){ 				   printf("\n请输出售出一张火车票后的剩余火车票为:"); 			       dataout_l(myl); 			   } 			   break; 		case 3:printf("\n请输入退的这张票的内容\n票号\t班次\t起始站\t终点站\t票价\t出发时间:\n");	   scanf("%d%s%s%s%f%s",&k.ticketnumber,k.trainnum,k.startstation,k.destination,&k.ticketprice,k.traindate); 			   insertlist_l(myl,k); 			   printf("\n请输出退票以后的票的情况:");                dataout_l(myl); 		       break;         case 4:dataout_l(myl); 		       break; 		case 5:w=listcountnum_l(myl); 			   printf("\n******************************************"); 	           printf("\n*排票功能界面:                           *"); 	           printf("\n*1.按票价排票;     *");                printf("\n*2.按车的班次排票;     *"); 			   printf("\n*3.返回到原火车票系统                    *"); 	           printf("\n******************************************"); c:		       printf("\n请输入你的选择:"); 			   scanf("%d",&z); 			   switch(z) 			   	{ 			   case 1:listticketprice_l(myl,w); 				      printf("\n经按票价排票后为:"); 					  dataout_l(myl); 					  break;                case 2:listtrainnum_l(myl,w); 				      printf("\n经按车的班次排票后为:"); 					  dataout_l(myl); 					  break; 			   case 3:goto a;                       default:printf("\n输入错误");} 			          goto c; 			          break;                case 6:printf("\n现有票%d张,且这些票分别为:",listcountnum_l(myl)); 			          dataout_l(myl);                       break; 		       case 7: 		             goto a;                      default:printf("\n输入错误");}                       printf("\n退出程序");                      exit (0); 			    }

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h> #define OK      1 #define ERROR   0 #define MAX_NUM 10 #define MAX     20 #define MAX1    5  typedef int     status; struct ticket {   long int ticketnumber;            //票号采用长整型     char     trainnum[MAX_NUM];       //车的班次     char     startstation[MAX];       //起始站     char     destination[MAX];        //终点站     float    ticketprice;             //票价     char     traindate[MAX];          //火车出发日期 }ticket[MAX1]; typedef  struct ticket elemtype; typedef struct lnode                 //管理类型重定义 {   elemtype data; 	struct lnode *next; }*linklist,lnode; void save(){FILE *fp; 	int i;     fp=fopen("C:\\ticketrecord.txt","w"); 	if(fp==NULL){printf("\ncannot open file"); 		exit(0); 	}     for(i=0;i<=MAX1-1;i++){ 		if(fwrite(&ticket[i],sizeof(elemtype),1,fp)!=1) 		       printf("\nfile write error"); 	}	 	fclose(fp); } status createlist_l(linklist &L) //生成链表的定义 { int i;   linklist p;   FILE *fp;   fp=fopen("C:\\ticketrecord.txt","r");   if(fp==NULL){printf("\ncannot open file"); 		exit(0);   }   L=(linklist)malloc(sizeof(lnode)); //向内存申请一块占sizeof(lnode)字节的空间，并将这块空间的首地址交给L管理   L->next=NULL;   for(i=MAX1;i>0;i--){p=(linklist)malloc(sizeof(lnode));       if(fread(&p->data,sizeof(elemtype),1,fp)!=1) 	  printf("\nfile read error"); 	  p->next=L->next; 	  L->next=p;   }   fclose(fp);   return OK; } void dataout_l(linklist &L)     //打印火车票 {linklist p; 	p=L->next; 	printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期:"); 	while(p){ 	printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.trainnum,p->data.startstation,p->data.destination,p->data.ticketprice,p->data.traindate); 	    printf("\n"); 		p=p->next; 	} } void searchlist_traindate(linklist &L,char e1[])  //按火车出发日期查询 {linklist p; 	int count=0; 	p=L->next; 	while(p){if(strcmp(p->data.traindate,e1)==0){             count++; 			if(count==1) 				printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:");		printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.trainnum,p->data.startstation,p->data.destination,p->data.ticketprice,p->data.traindate); 		} 		p=p->next; 	}         if(count==0) 			printf("\n没有找到"); } void searchlist_trainnum(linklist &L,char e3[])  //按班次查询 {linklist p; 	int count=0; 	p=L->next; 	while(p){ 		if(strcmp(p->data.trainnum,e3)==0){ count++; 			if(count==1) 				printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:"); 	printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.trainnum,p->data.startstation,p->data.destination,p->data.ticketprice,p->data.traindate); 		}p=p->next;}         if(count==0) 			printf("\n没有找到");} status deletelist_l(linklist L,char k1[],char k2[])  //售票功能 {linklist p,q,r,t,b,c,d; 	char a1[MAX],a2[MAX],a3[MAX_NUM]; 	int count=0,i; 	long int j; 	p=L->next; 	while(p){ 	if(strcmp(p->data.startstation,k1)==0&&strcmp(p->data.destination,k2)==0){ 			count++; 			if(count==1){ 				printf("\n根据你要查找的起点站和终点站有以下这些票:");                 printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期\n:"); 			} 	printf("\n%ld\t%s\t%s\t%s\t%f\t%s",p->data.ticketnumber,p->data.trainnum,p->data.startstation,p->data.destination,p->data.ticketprice,p->data.traindate); 		}p=p->next; 	}if(count==0){printf("\n没有找到你所要查找的票:"); 		return ERROR; 	} 	else{printf("\n根据上述找到的票,请输入你想在找到的这些票中再根据哪种方式那你所需要的票:"); 		printf("\n**********************************");         printf("\n1.按上车时间;     2.按票号;      *"); 	    printf("\n3.按车的班次;                    *");         printf("\n**********************************"); d:		printf("\n请输入你的选择:"); 		scanf("%d",&i); 		switch(i){ 		  case 1:printf("\n请输入你想买火车票的时间范围即时间的下限和上限:"); 			     scanf("%s%s",a1,a2); 			     c=L->next; 				 q=L; while(c){if(strcmp(a1,c->data.traindate)<=0&&strcmp(a2,c->data.traindate)>=0&&strcmp(c->data.startstation,k1)==0&&strcmp(c->data.destination,k2)==0){printf("\n你要买的火车票为:");  printf("\n%ld\t%s\t%s\t%s\t%f\t%s",c->data.ticketnumber,c->data.trainnum,c->data.startstation,c->data.destination,c->data.ticketprice,c->data.traindate); 					   q->next=c->next; 					   free(c);                        return OK;    }    else { q=c; 			c=c->next;}} 				 if(c==NULL) { 					   printf("\n没有你要的票");                        return ERROR; 				 } 			   break; 		case 2:printf("\n请输入你想买的票号:"); 			   scanf("%ld",&j); 			   t=L->next; 			   b=L; while(t){   if(t->data.ticketnumber==j&&strcmp(t->data.startstation,k1)==0&&strcmp(t->data.destination,k2)==0){printf("\n你要买的火车票为:");	  printf("\n%ld\t%s\t%s\t%s\t%f\t%s",t->data.ticketnumber,t->data.trainnum,t->data.startstation,t->data.destination,t->data.ticketprice,t->data.traindate); 					   b->next=t->next; 					   free(t); 					   return OK; 				   }  else { 					   b=t; 					   t=t->next; 				   }} 			   if(t==NULL){printf("\n没有你要的票"); 				       return ERROR; 				} 			   break; 		case 3:printf("\n请输入你要买的火车班次:"); 			   scanf("%s",a3); 			   r=L->next; 			   d=L; 			   while(r){ if(strcmp(r->data.trainnum,a3)==0&&strcmp(r->data.startstation,k1)==0&&strcmp(r->data.destination,k2)==0){printf("\n你要买的火车票为:"); printf("\n%ld\t%s\t%s\t%s\t%f\t%s",r->data.ticketnumber,r->data.trainnum,r->data.startstation,r->data.destination,r->data.ticketprice,r->data.traindate); 					   d->next=r->next; 					   free(r); 					   return OK;                    } 				   else { 					   b=r; 					   r=r->next; 				   } 			   } 			  if(r==NULL) {printf("\n没有你要的票"); 			           return ERROR; 			  } 			 break; 		default:printf("\n输入错误"); 		} 		goto d; 	} }		 status listcountnum_l(linklist &L)   //票数功能 {linklist p; 	int count=0; 	p=L->next; 	while(p){count++; 		p=p->next; 	} 	return count; } status listticketprice_l(linklist &L,int count)  //按票价排票 {int i,j; 	i=count; 	linklist p,t,h,s; 	for(;i>=1;i--){ 		p=L->next; 		t=L; 		h=L; 		if(i==1) continue; 		if(p->data.ticketprice<p->next->data.ticketprice&&i==2) continue;         if(p->data.ticketprice>p->next->data.ticketprice&&i==2){             s=p->next; 			L->next=s;             p->next=s->next; 			s->next=p; 			continue; 		}         p=L->next;         if(p->data.ticketprice>p->next->data.ticketprice) 			s=p; 		else s=p->next; 		p=p->next; 		j=i-1; 		while(p&&j>=1){ 			if(s->data.ticketprice<p->data.ticketprice) 			s=p; 			t=p; 			p=p->next; 			j--; 		} 		if(s==t) continue; 		while(h->next){if(h->next==s){h->next=s->next; 				s->next=t->next; 				t->next=s; 				break; 			} 			else h=h->next; 		} 	} 	return OK; }		 status listtrainnum_l(linklist &L,int count)   //按班次排票 {int i,j; 	i=count; 	linklist p,t,h,s; 	for(;i>=1;i--){p=L->next; 		t=L; 		h=L;         if(i==1) continue; 		if(strcmp(p->data.trainnum,p->next->data.trainnum)<0&&i==2) continue;         if(strcmp(p->data.trainnum,p->next->data.trainnum)>0&&i==2){             s=p->next; 			L->next=s;             p->next=s->next; 			s->next=p; 			continue; 		}         p=L->next;         if(strcmp(p->data.trainnum,p->next->data.trainnum)>0) 			s=p; 		else s=p->next; 		p=p->next; 		j=i-1; 		while(p&&j>=1){if(strcmp(s->data.trainnum,p->data.trainnum)<0) 			s=p; 			t=p; 			p=p->next; 			j--; 		} 		if(s==t) continue; 		while(h->next){ 			if(h->next==s){ 				h->next=s->next; 				s->next=t->next;                 t->next=s; 				break; 			} 			else h=h->next; 		} 	} 	return OK; }		 status insertlist_l(linklist &L,elemtype e)   //退票功能{linklist s,p {     linklist p,t,h,s; 	s=(linklist)malloc(sizeof(lnode)); 	s->data=e; 	p=L->next; 	while(p->next){p=p->next; 	} 	s->next=p->next; 	p->next=s; 	return OK; } void main(){int x,y,w,z,h; 	elemtype k; 	long int j; 	float a; 	char e[MAX],b[MAX],c[MAX],d[MAX_NUM],f1[MAX],f2[MAX]; 	linklist myl;     printf("\n请输入车票数据:"); 	printf("\n票号\t班次\t起始站\t终点站\t票价\t火车出发日期:\n");     for(h=0;h<=MAX1-1;h++){ 	scanf("%d%s%s%s%f%s",&ticket[h].ticketnumber,ticket[h].trainnum,ticket[h].startstation,ticket[h].destination,&ticket[h].ticketprice,ticket[h].traindate); 	} 	save(); 	createlist_l(myl);     printf("\n*************************************"); 	printf("\n*火车票管理系统:                    *");     printf("\n*1.查询功能;     2.售出功能;        *"); 	printf("\n*3.退票功能;     4.打印表功能;      *");     printf("\n*5.排票功能;     6.票数功能         *"); 	printf("\n*7.退出                             *"); 	printf("\n*************************************");


Question: (void *)p 与 *(void **)p区别

*p = a 就是  5566 至于地址格式输入， 只是输出用地址输入方式表示数据，通常不过是，输出整型数据的 十六进制表示而已 。 其实  printf("%p\n",a) ;也是没有问题的， 因为  printf 通常，并不检测参数是个正确， 而是依照 %格式 输出对应的数据   你只要保证数据格式（主要是长度）是对的就没有问题。 至于参数错误，输出结果，是否正确，  这是你自己编程的时候的逻辑问题。 printf 这种函数，并不考虑  注意，。这里有这么几个问题 1） 参数传递 2）参数也是表达式，所以参数在表达式解析的时候，会做一些改变 3）printf 函数，对应参数的获取方式， 其中 float ,会当作double 处理。 4）printf 只是按照 第一个参数提供的格式， 逐一匹配传入的参数，                        不足者，继续读取堆栈上的数据，不管是否传入的参数，有余者自动丢弃 因为这是 C调用约定，所以每个书写正确的 printf  都是没有问题的 而且，参数错误，通常不会影响后面的程序正确运行， C语言可以正确的清理堆栈。


Question: 不会做。。


Question: C语言编程， 急~~求大神帮忙分析下问题，本人新手，谢谢啦~~

你这段代码的问题太多了！！

引用 2 楼 yDevilz 的回复:D:\DEVc++\新建文件夹\zuoye.c: In function 'main':  D:\DEVc++\新建文件夹\zuoye.c:19:17: error: expected identifier or '(' before '[' token       struct stu([10];                  ^ D:\DEVc++\新建文件夹\zuoye.c:60:2: error: expected declaration or statement at end of input   }  编译错误神马的自己可以解决的。看下编译器的报错就行啦

引用 3 楼 q3733353520 的回复:struct stu([10];  多了个(  sruct stu  stu[10];

struct stu([10];  多了个(

程序看不清，什么错误？


Question: 没有头结点的单链表的冒泡排序，大神看看怎么错了

楼主试试 把p1=head;放在 循环外面试试

把结果输出，看看到底变成啥样了，在调试

把p1->name  什么的打印出来就知道了了


Question: 【求助】TrieTree的问题。

引用 4 楼 user-2 的回复:TrieNode *a;       InitTrieRoot(&a); 这里为什么这么用？你 想把让a=null?何必这么复杂， for ( i = 0; i < n; i++)             InsertTrie(&a); 上面a是空的啊？？你还插入？ 我把Init都注释了，提交依旧是RE错误。

init这个函数没用，等于不要，你的所有节点必须通过create。

引用 2 楼 fly_dragon_fly 的回复:init这个函数没用，等于不要，你的所有节点必须通过create。 可是create没有出错啊~

输入 输入的第一行为一个正整数n，表示词典的大小，其后n行，每一行一个单词（不保证是英文单词，也有可能是火星文单词哦），单词由不超过10个的小写英文字母组成，可能存在相同的单词，此时应将其视作不同的单词。接下来的一行为一个正整数m，表示小Hi询问的次数，其后m行，每一行一个字符串，该字符串由不超过10个的小写英文字母组成，表示小Hi的一个询问。  在20%的数据中n, m<=10，词典的字母表大小<=2.  在60%的数据中n, m<=1000，词典的字母表大小<=5.  在100%的数据中n, m<=100000，词典的字母表大小<=26.   输出 对于小Hi的每一个询问，输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。  样例输入 5 babaab babbbaaaa abba aaaaabaa babaababb 5 babb baabaaa bab bb bbabbaab 样例输出 1 0 3 0 0


Question: 关于循环语句里的问题，对大神来说很简单的

主程序循环写错了  应该在输入后， 立即判断数据的合法性， 然后再执行操作  如果希望，从输入到操作的全部代码 都在循环里面  用 for 循环比较合适 输入语句 放在 第一个和第三个表达式中

引用 1 楼 user-4 的回复:int main(int argc, char* argv[]) { 	int i1=0; 	int i2=0; 	int i3=i1%i2; 	cout<<i3<<endl; 	return 0; } 楼主，我只是执行这个操作，也崩溃，所以可能是int i3=i1%i2;问题，也就是你进行了这个操作，除数为０ 谢谢,我用2#的思维,一步一步测试了,之后发现了这个问题了!谢谢哈

后两个按楼主的输入是不会调用到aliqout函数的，前三个都会调用到aliqout函数，qliqoout函数有除数为0情况，所以会错……

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  不要使用 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;  //... } 类似的例子还可以举很多。


Question: 新手！求解为什么会出现这问题？

引用 2 楼 qq532400624 的回复:[quote=引用 1 楼 windzhu0514 的回复:] int fac(int n) { int f; if(n==1) f=1; else f=fac(n-1)*n; return(f); }  这个函数如果n传入了0  程序就会错误  递归没有了接受条件  万分感谢！！你怎么看出来的？但是，不是当n=1时，fac返回1，他就不是不再减下去了？[/quote]  递归最怕的就是起始条件不对 和 没有结束条件   多练习下

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

引用 1 楼 windzhu0514 的回复:int fac(int n) { int f; if(n==1) f=1; else f=fac(n-1)*n; return(f); }  这个函数如果n传入了0  程序就会错误  递归没有了接受条件  万分感谢！！你怎么看出来的？但是，不是当n=1时，fac返回1，他就不是不再减下去了？


Question: 大家帮帮忙  急急急

找到原因了。这个不是我编的，是剽窃别人的。所以印象不深。

嫌4楼复杂，可直接使用GDI+，参考下面：（我怎么才想起我以前编过这个例子代码！？唉！老了，岁月不绕人啊。） #include <iostream> #include <fstream> #include <string> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib")  using namespace std; using namespace Gdiplus;  int main() {     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);      wstring infilename(L"1.jpg");     string outfilename("color.txt");      Bitmap* bmp = new Bitmap(infilename.c_str());     UINT height = bmp->GetHeight();     UINT width  = bmp->GetWidth();     cout << "width " << width << ", height " << height << endl;      Color color;     ofstream fout(outfilename.c_str());      for (UINT y = 0; y < height; y++)     for (UINT x = 0; x < width ; x++) {             bmp->GetPixel(x, y, &color);             fout << x << "," << y << ";"                  << (int)color.GetRed()   << ","                  << (int)color.GetGreen() << ","                  << (int)color.GetBlue()  << endl;     }      fout.close();      delete bmp;     GdiplusShutdown(gdiplustoken);     return 0; }

引用 6 楼 yunyunjianjian 的回复:4楼，我看不懂，不是网站么？ C语言开源图象处理项目。

每一行都得到了，你还要得到什么数据？

4楼，我看不懂，不是网站么？

但是我要c需要的，我现在知道matlab，就是改不成c

最简单就用opencv，你直接读入图片，有函数可以得到三通道的数据。 还有一法子就是用GDI或才GDI+，可以百度看看

如果是在mfc的话用 clr=::GetPixel(pDC->m_hDC,250,250); R=GetRValue(clr); G=GetGValue(clr); B=GetBValue(clr);

我翻了好多书，都不懂

我开始想先把他每一行都弄成一个数组 然后再把每一行拆开存入这7个数组中 但是不知道该如何拆。。。


Question: c语言如何实现实时按某个键退出或者放回主界面

win32程序那就可以用捕获鼠标按键的办法

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309

如果这样的话，用户输入的时候需要一个字符回车一次，体验就不好了

scanf( "%c", &char ); 一个一个字符读入，并判断

我做的是win32程序，之前用getchar没起作用

引用 2 楼 clearnerpro 的回复:这样就可以在用户输入的时候即正在执行scanf语句时，实现按键退出吗？   你是win32还是控制台的程序？

你写的是控制台程序吧？ 如果是这样的话，用户输入密码的时候，如果已经进入scanf函数，用户不按回车的话，程序会一直停在那里等待的。。  按照你的需求，用户输入一半，不按回车，按下ESC，然后你响应，这是可以的，不过用scanf估计实现不了，你应该用 getchar 试一试，用户只要敲键盘了，你都会收到信息，这样你自己再判断有没有ESC，然后就可以处理了

这样就可以在用户输入的时候即正在执行scanf语句时，实现按键退出吗？

这样就可以在用户输入的时候即正在执行scanf语句时，实现按键退出吗？

捕获鼠标按键，你可以网上搜，很多解决方案的


Question: 求助啊！！。。。关于txt中的文件导入到数组中的问题

是啊、、、怒谢！！

自己定义一个结构体，然后从文件读取数据，更新到结构体中

22行%d,改为%d;: //in.txt: //07/12/2006;1.25;1.28;1.23;1.24;11362204;111085760.000 //07/13/2006;1.22;1.22;1.07;1.10;18304398;171802096.000 //07/14/2006;1.09;1.19;1.07;1.12;12187752;114498688.000 //07/17/2006;1.10;1.14;1.08;1.12;5623536;52357016.000 //07/18/2006;1.12;1.13;1.09;1.12;4215610;39236372.000 //07/19/2006;1.12;1.12;1.07;1.08;5370469;49774080.000 //07/20/2006;1.09;1.11;1.08;1.09;4441253;41202572.000 //07/21/2006;1.10;1.18;1.09;1.13;7977284;74979888.000 //07/24/2006;1.07;1.19;1.04;1.15;6312648;59374432.000 //07/25/2006;1.15;1.17;1.10;1.11;8795141;82844016.000 //07/26/2006;1.12;1.14;1.08;1.11;7207959;67096544.000 //07/27/2006;1.09;1.15;1.05;1.07;7212810;66774156.000 //07/28/2006;1.07;1.08;1.00;1.03;9094381;82472512.000 //07/31/2006;1.01;1.01;0.93;0.94;9749117;86585360.000 //08/01/2006;0.94;0.97;0.92;0.93;7003191;61438528.000 // #include <stdio.h> #define MAXN 10000 char dt[MAXN][11]; float f1[MAXN]; float f2[MAXN]; float f3[MAXN]; float f4[MAXN]; int d[MAXN]; double lf[MAXN]; FILE *f; char ln[100]; int i,n; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     i=0;     n=0;     while (1) {         if (NULL==fgets(ln,100,f)) break;         n++;         if (7==sscanf(ln,"%10s;%f;%f;%f;%f;%d;%lf",dt[i],&f1[i],&f2[i],&f3[i],&f4[i],&d[i],&lf[i])) {             i++;             if (i>=MAXN) break;         } else {             printf("Line %3d Format error:%s",n,ln);         }     }     fclose(f);     n=i;     for (i=0;i<n;i++) printf("line %3d:%s;%4.2f;%4.2f;%4.2f;%4.2f;%8d;%13.3lf\n",i+1,dt[i], f1[i], f2[i], f3[i], f4[i], d[i], lf[i]);     return 0; } //line   1:07/12/2006;1.25;1.28;1.23;1.24;11362204;111085760.000 //line   2:07/13/2006;1.22;1.22;1.07;1.10;18304398;171802096.000 //line   3:07/14/2006;1.09;1.19;1.07;1.12;12187752;114498688.000 //line   4:07/17/2006;1.10;1.14;1.08;1.12; 5623536; 52357016.000 //line   5:07/18/2006;1.12;1.13;1.09;1.12; 4215610; 39236372.000 //line   6:07/19/2006;1.12;1.12;1.07;1.08; 5370469; 49774080.000 //line   7:07/20/2006;1.09;1.11;1.08;1.09; 4441253; 41202572.000 //line   8:07/21/2006;1.10;1.18;1.09;1.13; 7977284; 74979888.000 //line   9:07/24/2006;1.07;1.19;1.04;1.15; 6312648; 59374432.000 //line  10:07/25/2006;1.15;1.17;1.10;1.11; 8795141; 82844016.000 //line  11:07/26/2006;1.12;1.14;1.08;1.11; 7207959; 67096544.000 //line  12:07/27/2006;1.09;1.15;1.05;1.07; 7212810; 66774156.000 //line  13:07/28/2006;1.07;1.08;1.00;1.03; 9094381; 82472512.000 //line  14:07/31/2006;1.01;1.01;0.93;0.94; 9749117; 86585360.000 //line  15:08/01/2006;0.94;0.97;0.92;0.93; 7003191; 61438528.000 //

28行n=i可以么？...我运行的时候只有press any key to .continue..

我开始想先把他每一行都弄成一个数组 然后再把每一行拆开存入这7个数组中 但是不知道该如何拆。。

最后运行不出来。。。这里不用管分隔符 分号 么？

#include <stdio.h> #define MAXN 10000 char dt[MAXN][11]; float f1[MAXN]; float f2[MAXN]; float f3[MAXN]; float f4[MAXN]; int d[MAXN]; double lf[MAXN]; FILE *f; char ln[100]; int i,n; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     i=0;     while (1) {         if (NULL==fgets(ln,100,f)) break;         if (7==sscanf(ln,"%10s;%f;%f;%f;%f;%d,%lf",dt[i],&f1[i],&f2[i],&f3[i],&f4[i],&d[i],&lf[i]) {             i++;             if (i>=MAXN) break;         }     }     fclose(f);     n=i;     for (i=0;i<n;i++) printf("%s;%4.2f;%4.2f;%4.2f;%4.2f;%8d;%12.3lf\n",dt[i], f1[i], f2[i], f3[i], f4[i], d[i], lf[i]);     return 0; }

自顶……求助啊


Question: C或C++外部调用函数

max.cpp是外部调用的函数，不能编译，只能生成目标文件后，再由主程序调用。max.h是要写的

gcc编译的时候写清楚文件依赖关系就可以的，比如 gcc -o main main.o max.o

文件 1#include<stdio.h> void myprint() { 	printf("this is my lib!\n"); } 文件 2 /*************************************************************************     > File Name: main.c     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月23日 星期二 20时02分14秒  ************************************************************************/  #include<stdio.h> #include"mylib.h" int main() { 	myprint();  	return 0; } sudo gcc main.c  jukay@jukay-desktop:/pragram/p8$ ./a.out this is my lib!jukay @jukay-desktop:/pragrame/p8$

你需要区别编译和链接，这是两个过程。 建议看看《程序员的自我修养 链接 装载与库》

1. 创建一个max.h文件 2. #include <stdio.h> 3. int max( int x, int y); 保存。 max.c和main.c中增加#include"max.h"

就写一个int max (int ,int );作为声明，建议你在linux下开发的时候使用Qt Creator作为开发工具进行开发，这个在linux 下开发属于标准开发，使用命令行开发比较慢

max.h怎么写啊

mian中找不到max函数，max函数声明一个放到max.h，main文件包含max.h

是不是要要写一个max.h，创建DLL？


Question: 大神求助，请问问什么会出现这种情况的？？？、、详细告诉我原因，谢谢！！

第二个for的i++改为j++

2个 i++?

#include <stdio.h> int max(int x[][4]) { 	int i,m,j; 	m=x[0][0]; 	for(i=0;i<3;i++) 	 	for(j=0;j<4;j++) 	   		if(m<x[i][j]) 				m=x[i][j]; 	return m; } void main() { 	static int a[3][4]={{1,8,15,54},{64,24,3,47},{47,122,34,469}}; 	printf("%d",max(a)); }


Question: setvbuf函数的作用

setvbuf Controls stream buffering and buffer size.  int setvbuf( FILE *stream, char *buffer, int mode, size_t size );  Routine Required Header Compatibility  setvbuf <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  setvbuf returns 0 if successful, or a nonzero value if an illegal type or buffer size is specified.  Parameters  stream  Pointer to FILE structure  buffer  User-allocated buffer  mode  Mode of buffering  size  Buffer size in bytes. Allowable range: 2 < size < 32768. Internally, the value supplied for size is rounded down to the nearest multiple of 2.  Remarks  The setvbuf function allows the program to control both buffering and buffer size for stream. stream must refer to an open file that has not undergone an I/O operation since it was opened. The array pointed to by buffer is used as the buffer, unless it is NULL, in which case setvbuf uses an automatically allocated buffer of length size/2 * 2 bytes.  The mode must be _IOFBF, _IOLBF, or _IONBF. If mode is _IOFBF or _IOLBF, then size is used as the size of the buffer. If mode is _IONBF, the stream is unbuffered and size and buffer are ignored. Values for mode and their meanings are:  _IOFBF  Full buffering; that is, buffer is used as the buffer and size is used as the size of the buffer. If buffer is NULL, an automatically allocated buffer size bytes long is used.  _IOLBF  With MS-DOS, the same as _IOFBF.  _IONBF  No buffer is used, regardless of buffer or size.  Example  /* SETVBUF.C: This program opens two streams: stream1  * and stream2. It then uses setvbuf to give stream1 a  * user-defined buffer of 1024 bytes and stream2 no buffer.  */  #include <stdio.h>  void main( void ) {    char buf[1024];    FILE *stream1, *stream2;     if( ((stream1 = fopen( "data1", "a" )) != NULL) &&        ((stream2 = fopen( "data2", "w" )) != NULL) )    {       if( setvbuf( stream1, buf, _IOFBF, sizeof( buf ) ) != 0 )          printf( "Incorrect type or size of buffer for stream1\n" );       else          printf( "'stream1' now has a buffer of 1024 bytes\n" );       if( setvbuf( stream2, NULL, _IONBF, 0 ) != 0 )          printf( "Incorrect type or size of buffer for stream2\n" );       else          printf( "'stream2' now has no buffer\n" );       _fcloseall();    } }   Output  'stream1' now has a buffer of 1024 bytes 'stream2' now has no buffer   Stream I/O Routines  See Also   fclose, fflush, fopen, setbuf

针作为它们的第一个参数),而且也应在对该流执行任何一个其他操作之前调用。 可以使用s e t b u f函数打开或关闭缓存机制。为了带缓存进行 I / O,参数buf 必须指向一个长 度为B U F S I Z的缓存(该常数定义在 < s t d i o . h >中)。通常在此之后该流就是全缓存的,但是如果 该流与一个终端设备相关,那么某些系统也可将其设置为行缓存的。为了关闭缓存,将 b u f设 置为N U L L。 使用s e t v b u f,我们可以精确地说明所需的缓存类型。这是依靠 m o d e参数实现的: _IOFBF 全缓存 _IOLBF 行缓存 _ I O N B F 不带缓存 如果指定一个不带缓存的流,则忽略 buf 和size 参数。如果指定全缓存或行缓存,则 buf 和s i z e 可以可选择地指定一个缓存及其长度。如果该流是带缓存的,而 buf 是N U L L,则标准I / O库将 自动地为该流分配适当长度的缓存。适当长度指的是由 s t r u c t结构中的成员 s t _ b l k s i z e所指定的 值(见 4 . 2节)。如果系统不能为该流决定此值(例如若此流涉及一个设备或一个管道),则分 配长度为B U F S I Z的缓存。  出处：  UNIX环境高级编程  第五章第四节

这些函数一定要在流已被打开后调用(这是十分明显的,因为每个函数都要求一个有效的文件第 5章 标 准 I/O 库 下载 9 3 指针作为它们的第一个参数),而且也应在对该流执行任何一个其他操作之前调用。 可以使用s e t b u f函数打开或关闭缓存机制。为了带缓存进行 I / O,参数buf 必须指向一个长 度为B U F S I Z的缓存(该常数定义在 < s t d i o . h >中)。通常在此之后该流就是全缓存的,但是如果 该流与一个终端设备相关,那么某些系统也可将其设置为行缓存的。为了关闭缓存,将 b u f设 置为N U L L。 使用s e t v b u f,我们可以精确地说明所需的缓存类型。这是依靠 m o d e参数实现的: _IOFBF 全缓存 _IOLBF 行缓存 _ I O N B F 不带缓存 如果指定一个不带缓存的流,则忽略 buf 和size 参数。如果指定全缓存或行缓存,则 buf 和s i z e 可以可选择地指定一个缓存及其长度。如果该流是带缓存的,而 buf 是N U L L,则标准I / O库将 自动地为该流分配适当长度的缓存。适当长度指的是由 s t r u c t结构中的成员 s t _ b l k s i z e所指定的 值(见 4 . 2节)。如果系统不能为该流决定此值(例如若此流涉及一个设备或一个管道),则分 配长度为B U F S I Z的缓存。 伯克利系统首先使用 s t _ b l k s i z e表示缓存长度。较早的系统 V版本使用标准 I / O 常数B U F S I Z(其典型值是 1 0 2 4)。即使4 . 3 + B S D使用s t _ b l k s i z e决定最佳的I / O缓存 长度,它仍将B U F S I Z设置为1 0 2 4。 表5 - 1列出了这两个函数的动作,以及它们的各个选择项。 表5-1 setbuf 和setvbuf 函数 函 数 m o d e b u f 缓存及长度 缓存的类型 n o n n u l l 长度为B U F S I Z的用户缓存 全缓存或行缓存 s e t b u f N U L L (无缓存) 不带缓存 n o n n u l l 长度为s i z e的用户缓存 N U L L 合适长度的系统缓存 n o n n u l l 长度为s i z e的用户缓存 N U L L 合适长度的系统缓存 忽略 无缓存 _ I O F B F s e t v b u f _ I O L B F _ I O N B F 全缓存 行缓存 不带缓存


Question: 新人大数加法求解

仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

引用 4 楼 a138762698828 的回复:scanf("%d%*c",&n);     while(n-->0)     {         scanf("%s%s",&a,&b); 两个scanf 就有问题了  第一个scanf  有两个输出  只有一个参数 n， 第二个scanf ， a b都是数组， 输入就不需要取地址了 他们本来就指向数组的首地址！  感谢！其实第一个%*c没问题，只是用来过滤换行符，问题出在第二个scanf，去掉&后终于Presentation Error了，再结合3楼答案就AC了！

引用 3 楼 niechangxu 的回复:你的 # 位置错了吧 应该是 Case #1:   ，还有就是这句话Output a blank line between two test cases.  两组测试数据之间有空行，你这个空行太多了吧。。  感谢！那个#是多余的，还有空行问题，格式感觉真心难玩，老是Presentation Error！

引用 1 楼 user-4 的回复:先说一下那里错了  OJ那里错误信息是Wrong Answer

先说一下那里错了


Question: 帮忙看看这个程序哪里错了（新手）

字符串中找字符串用的是，strstr() 字符串中找字符用的是，strchr(), 这时候楼主的‘b[10]’就不对了，该是吧b[10]

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

都说清楚了.

l自己可以动手调 F9下断点，F10单步调试，F4定位有问题的地方

引用 3 楼 zero_bug 的回复:[quote=引用 1 楼 hnwyllmm 的回复:] while(1) { int n=strlen(a[20]);    // a是字符串，a[20]是字符，不能用strlen，还有，a[20]已经越界了，楼主很多这种越界的访问 c[10]=strchr(a,'b[10]'); // b[10]也越界了，c[10]也是；b[10]已经是字符了，不需要加单引号 int m=strlen(c[10]); p=n-m; printf("%d",p); exit(0); } print("%d",-1);那什么又是越界呢[/quote] ------------------------------------------------------------------------------------------------------------- 数组a[20]应该是从a[0] 到a[19]，a[20]这个字符已经超出了定义的范围之外。。。所以就叫越界。

引用 1 楼 hnwyllmm 的回复:while(1) { int n=strlen(a[20]);    // a是字符串，a[20]是字符，不能用strlen，还有，a[20]已经越界了，楼主很多这种越界的访问 c[10]=strchr(a,'b[10]'); // b[10]也越界了，c[10]也是；b[10]已经是字符了，不需要加单引号 int m=strlen(c[10]); p=n-m; printf("%d",p); exit(0); } print("%d",-1);那什么又是越界呢


Question: 编译器怎么能够输出结构体成员的符号信息和地址

是想知道结构内成员的偏移吗？ 直接在VC里面看不就可以了

换GCC试试

SymGetTypeInfo

引用 2 楼 wangbinyantai 的回复:[quote=引用 1 楼 q3733353520 的回复:] VS 没用过， 不过 你可以根据首地址和内存来计算，比如int 占4个字节  您好，谢谢您的回复，地址好办，主要是结构体内部变量的符号表示怎么获取？例如怎么获取Tmy.a，Tmy.b等字符串信息[/quote] 值就存在地址。。。，而且 一般 你printf的是不会骗你的

编译器编译的时候， 会储存符号和地址的对应关系， 包括结构体信息，这一类的东西。  调试版，可以把一部分信息储存在 .exe,.dll 内部 VC 可以储存在vc90.pdb 等 *.pdb内部 调试的时候，就可以查看这些信息了 当然，也可以完全不储存，任何这一类的信息 所以这一功能， 只能是编译器厂家，做到编译器内 编译器外部，实现这个功能， 难度要大得多， 甚至几乎是不可能的  换句话说，你要实现一个调试器类似的东西，最好有编译器配合 要不然，你就要去了解编译器，具体的实现方案，了解每个细节  脱离编译器，直接实现是很有挑战性的。

引用 1 楼 q3733353520 的回复:VS 没用过， 不过 你可以根据首地址和内存来计算，比如int 占4个字节  您好，谢谢您的回复，地址好办，主要是结构体内部变量的符号表示怎么获取？例如怎么获取Tmy.a，Tmy.b等字符串信息

VS 没用过， 不过 你可以根据首地址和内存来计算，比如int 占4个字节


Question: c语言的一道题目~求大神解答

别沉  没有大神吗？


Question: 本人小菜，请问怎么能使程序在不满足输入时提示用户，并重新等待用户输入

再供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

if (2==sscanf(s,"%lf%c",&d,&c)) {             if ('\n'==c) {                 printf("%lg is a double.\n",d);                 break;             }  这段比较巧，学习了了！非常感谢。。。嘻嘻

引用 4 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> char s[80]; double d; char c; int main() {     while (1) {         printf("Input a double:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (strlen(s)>20) {             printf("Input too long(>20)!\n");             continue;         }         if (2==sscanf(s,"%lf%c",&d,&c)) {             if ('\n'==c) {                 printf("%lg is a double.\n",d);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a double!\n",s);     }     return 0; }   非常感谢赵老师的指导，小菜有点函数还没学过，慢慢地研究下！非常感谢！多多指教哟。

自己搞定了，作为一个刚学C4个月的小菜，把代码贴出来，请高人指正，同时也想吸取点他人思路。 这是一个C99的二维VLA，的练习题，只是本菜想拓展下，按实用要求来写。最后就不多余地free()了。   #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> int main(void) {      int n,m;    char ar[30];      int (*ptr)[m]; printf("pls enter 2 number n & m. \n");      while(gets(ar)&&ar[0]!='\0')   {       if(isalpha(ar[0]))      { 	 puts("pls number"); 	 continue; 	 }        n=atoi(ar);        puts("pls 2 nums");        gets(ar);        m=atoi(ar);         	   ptr=(int(*)[m])malloc(n*m*sizeof(int));        for(int i=0;i<n;i++)         for(int j=0;j<m;j++)          { 	      scanf("%d",&ptr[i][j]);           printf("%-2d",*(*(ptr+i)+j)); 	     }              }       return 0;   }

引用 1 楼 hnwyllmm 的回复:while(scanf("%d%d",&n,&m)==2)   {        if (n <= 0 || m <= 0 )        {             printf("invalid arguments\n") ;             continue ;       }        ptr=(int(*)[m])malloc(n*m*sizeof(int));        for(int i=0;i<n;i++)         for(int j=0;j<m;j++)          {       scanf("%d",&ptr[i][j]);           printf("%-2d",*(*(ptr+i)+j));       }                } 这么修改似乎对负数有用，但你想比较容易出现的错误应该是误输入字母，比如n=2, m=a;这种类型的错误！


Question: 为什么把浮点数用整形格式输出会变成0？

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

《计算机组成原理》 《CSAPP》信息的表示和处理

去看下 int float 这些类型的存储方式

printf("--%d\n",(int)k); 这样输出试试

自己调试看看呗，我用手机没法调试 估计是输出的数小于0.5

2.0显示0对的，它刚好尾数为0，可变参数不指定时float将转成double，低4字就是0，要么改为%f,要么强转为int


Question: 请大家帮我解决一下这个问题，谢谢了

你讲的都是什么

参考c语言的隐式转换

c语言中，发生double到int的隐式转换，主要原因可能是由于double的精度问题没能达到1.7这个具体值，乘法完成后发生转换的时候小数点后面向0舍入。  1.7d = 1.10[1100]....b * 2^0

y 要改成 double


Question: C,C++中用栈实现算术表达式求值

引用 1 楼 user-1 的回复:那就用scanf 求教

那就用scanf


Question: 程序问题

ld是链接器

不懂可以百度谷歌一下，楼主有吗

链接时报错 楼主贴出更详细的信息大家才能帮你分析，看看是不是少了链接库，或者有些源文件没有添加到工程中


Question: C新手求助

单步跟一下就知道

程序都是通过card_name[0]来判断，所以没必要定义一个char数组……  一闪而过可能是因为设置问题……


Question: 求个函数

#include <iostream.h>  void main() { 	int m; 	int n; 	cin>>m>>n;  	long cm = 1; 	long cn = 1;  	for (int i = 1;i < n;i ++) 	{ 		cm *= (m - i + 1) * (m - i); 		cn *= (n - i + 1) * (n - i); 	} 	cout<<cm / cn<<endl; }

写过非递归的树遍历嘛？这个和那个差不多！写过八皇后问题嘛？还是差不多！先尝试写个递归的，然后自己管理栈，改写成非递归即可！

楼上的，我只会c不好意思啊，有c 的吗

http://blog.csdn.net/zhouqinghe24/article/details/8140046  我这里有个C# 版的  你可以参考一下


Question: 彻底蒙圈了，求助，如何定义指向数组的指针变量

谢谢，原来这样表达啊

问题1：typedef  int(*DP) [100]; 问题2：申请空间后，data的空间也会被申请，即100个int类型的数据空间。 问题3：数据赋值，建议使用memcpy；data是一个数组，数组名不能做作左值；


Question: 数据结构中伸展树的节点展开应该怎么理解

这个看着不就是访问哪个节点就把哪个节点转换成根节点吗？ 以9为例，他变为根节点，找到左边的子树，放左边，右边的子树放右边 问题就是怎么找左子树和右子树 以左子树为例，比9小的是1-8,1-8组成的子树，找到它的根节点就好了，从图形上看，明显是3 右子树类似，找右边的根节点

首先实现一次旋转的操作，然后再考虑实现伸展操作。


Question: 工资管理程序

。。。。。。先学会问问题吧。。。


Question: 工资管理程序

大神 你代码呢


Question: 停止运行——超级简单，求指导

int *get_place(int n) { return (int *)get_place(n); }

看懂了！！！！！

啥意思 复制粘贴？


Question: C实现魔方阵问题


Question: 一个简单的函数，但我看不懂，求帮助

明白了，谢谢大家

楼主了解这几个位运算符的用法吗 在循环最后输出三个变量的值，看能想明白不 one=2,two=0,three=-1 one=6,two=0,three=-1 one=2,two=4,three=-1 one=1,two=2,three=-5 one=0,two=1,three=-3 one=2,two=0,three=-2 one=1,two=2,three=-1 one=5,two=2,three=-1 one=5,two=0,three=-3 one=7,two=0,three=-1 7

两个for循环也行

大概远离就是 3个相同的元素 两个做与运算再做异火运算那么就为0，最终的结果就是只有一个的那个元素

arr[1] = {1} arr[2] = {1, 1}; arr[3] = {1, 1, 1}; 这三个数组逐次代入函数中思考一下 one 记录只出现 过1次的数字； two 记录数组中出现过2次的数字； three 用来记录出现1次 和 2次数字的反码集；

不错的想法， one异或同一个数三次还是one，而two的值也是one，这样three只是用来清除，题目已经规定了只有一个数不同，最后就只剩下one。

考验你数学功底的时间到了

这思想真是奇妙，逻辑运算用的出神入化，没有很深的功力怕是写不出来

代码效率确实很高，一次循环o(N)，变量存储空间也很节省。 a[i]&one,如果两个值相同，这个结果是1； 后面几个也是同样的原理，了解几个运算符的结果就会好了。。。

求帮忙。。。


Question: 关于一个组合排序的算法,想找出一个比较高效的......求指点.

有人知道吗?


#include "stdio.h" #include "string.h" #include "stdlib.h"  int strCmp(const void *str1, const void *str2)//排序 { 	return strcmp((char *)str1, (char *)str2); } void main() {  	FILE *fpInFile, *fpOutFile; 	char str[10000][16]={'\0'}; 	int i = 0, iStrLen = 0; 	fpInFile = fopen("case1.in","r+"); 	if(fpInFile == NULL) 	{ 		printf("Error: Open file failed!\n"); 		return; 	} 	 	printf("Open file succeed!\n");  	while(!feof(fpInFile)) 	{ 		if(fgets(str[i],16,fpInFile)!= NULL)		 			printf("%s",str[i]); 		i++; 		iStrLen++; 	} 	fclose(fpInFile); 	printf("iStrLen:%d\n",iStrLen);  	qsort(str, iStrLen -1, sizeof(char)*16, strCmp); 	 	fpOutFile = fopen("answer.txt","w+");  	for(i=0; i<iStrLen-1; i++) 	{ 		printf("sort:%s",str[i]); 		fputs(str[i],fpOutFile); 	} 	fclose(fpOutFile);   }  VC测试通过

#include <stdio.h> #include <string.h>  static int  count; static char words[10000][10 + 1];  int wordcmp(const void *v1, const void *v2) {     const char *p1;     const char *p2;      p1 = (const char *)v1;     p2 = (const char *)v2;      return strcmp(p1, p2); }  int main(int argc, char *argv[]) {     int    i;     FILE  *fp;     size_t len;     char   buf[80 + 1];      fp = fopen("case1.in", "rb");     count = 0;     while (fgets(buf, sizeof(buf) , fp)) {         len = strlen(buf);         if (len > 0) {             buf[len - 1] = '\0';         }         strcpy(words[count], buf);         count++;     }     fclose(fp);      qsort(words, count, sizeof(words[0]), &wordcmp);      for (i = 0; i < count; i++) {         printf("%s\n", words[i]);     }      return 0; }

愿意使用脚本嘛？AWK+sort就搞定喽

加个  # include <iostream>  using namespace std;  主函数 排序就写个 sort(s,s+n); 其中s是存单词的二维数组 n为单词的个数。

读取文件 排序 输出文件


Question: 计算字符串长度？

size_t strlen(const char *s) {         const char *sc;           for (sc = s; *sc != '\0'; ++sc)                /* nothing */;        return sc - s;  }

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

这么简单的问题，单步跟一下就啥都知道了，不会调试程序不是一个合格的程序员

你让p指向一个毫无关系的字符串常量"a",最后再让s的末尾位置减这个p，怎么能对呢？让p先指向s，保存住首地址才对

<c程序设计语言>上是这么写的 int strlen(char *s) {   char *p = s;   while(*p != '\0')   p++;    return p - s; }

while(*s++)  ; 改成 for( ;*s;++s); 或者s-p-1

计算字符串长度也可以这样：  int strlen( const char *str ) //输入参数const { 	assert( str != NULL ); //断言字符串地址非0 	int len; 	while( (*str++) != '\0' )  	{  		len++;  	}  	return len; }

可以改成这样： #include <stdio.h> size_t my_strlen(const char *s) { 	const char *p=s; 	while(*s!='\0') 	{ 		s++; 	} 	return s-p; }  int main() { 	const char *q="a"; 	printf("%d\n",my_strlen(q)); }

while(*s++) 执行完后s的值已指导'\0'

更改：  size_t my_strlen(const char *s)   {     const char *p=s;     while(*s++)        ;     return s-p;   }  int main()   {     const char *q="a";     printf("%d\n",my_strlen(q));  //输出是：2。是错！   }  问题： 1.函数是计算字符串长度。 函数是用字符串最后字符的下一个字符，也就是空字符('\0')的地址，减去字符串的首地址。 其结果，就是字符串长度。 为什么，函数是错呢？


Question: 新人求大神来看看

这是我前段时间在网上找的程序，对LZ有用，仅供参考： /*     2、将一句话里的单词进行倒置，标点符号不倒置。 	比如一句话：i come from beijing.倒置后变成：beijing. from come i。      	解析：解决该问题可以分为两步： 	第一步全盘置换该语句成：.gnijieb morf emoc i。 	第二步进行部分翻转，如果不是空格，则开始翻转单词。*/ #include <iostream> using namespace std; void main ()  {       	int  i=0, j=0, begin, end; 	char str[] = "hello world"; 	char temp; 	j = strlen(str) - 1; 	//第一步是进行全盘翻转 	while(j>i) 	{ 		temp = str[i]; 		str[i++] = str[j]; 		str[j--]=temp; 	} 	cout<<"第一步全盘翻转："<<str<<endl;//.gnijieb morf emoc i  	//第二步进行部分翻转 	i=0; 	while(str[i])  	{ 		if(str[i] != ' ') 		{   			begin = i; 			while(str[i] && str[i] != ' ') 				i++;                 //找到str[i]为空格符  			i = i - 1;               //空格符回退一个    			end = i;          		}           		while(end > begin) //部分翻转          		{               			temp = str[begin]; 			str[begin++] = str[end]; 			str[end--] = temp; 		}          		i++; 		//cout<<str[i]<<endl; 	}       	cout << "第二步进行部分翻转：" << str << endl;  }

你自己先写。哪里不会再来提问


Question: 急用一份学生管理系统c语言程序

楼主说的一堆里,其实除了界面制作的时候比较蛋疼,在没什么难度

引用 1 楼 user-4 的回复:还不如给你同学些钱，让他帮你做。

http://yunpan.cn/cfGsTtizjekvI  提取码 4a32 挺不错的 ，可以借鉴一下

还不如给你同学些钱，让他帮你做。


已经解决，应当用pthread_cond_broadcast()，而不是pthread_cond_signal()，后者如果没有叫醒正确的线程，会出现所有线程都在wait的情况。


Question: 将手动输入数据改为在程序中已经写好数据！问题比较急~

将scanf改为直接初始化。 比如 sampleNode z[2]={ {{1.,2.,3.,4.,5.,6.,7.,8.,9.,10.},1},//z[0] {{1.,2.,3.,4.,5.,6.,7.,8.,9.,10.},2},//z[1] };


Question: 分享奇异BUG一枚

楼主很牛逼！

引用 50 楼 bug1190 的回复:一个SB在这B叫而己 Remarks The GetThreadContext function is used to retrieve the context of the specified thread. The function allows a selective context to be retrieved based on the value of the ContextFlags member of the CONTEXT structure. The thread handle identified by the hThread parameter is typically being debugged, but the function can also operate when it is not being debugged.  You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.  If you call GetThreadContext for the current thread, the function returns successfully; however, the context returned is not valid.  像你这种没教养的东西，我不愿意理你，自己滚蛋。

引用 45 楼 fly_dragon_fly 的回复:int  getcontext( ucontext_t *a ) {       int ret;       a->thread_context.ContextFlags = CONTEXT_FULL;       ret = GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1;       return ret; }  这个ret会导致占用栈空间4字节，而set的时候没有这个消耗，当切换回来a时，两边栈就不平衡，导致返回地址无效了。  这是正确答案。  这位兄弟肯定搞过类似的工作吧？

楼上的分析很精辟。

难道是  多进程？无限刷内存？。。

You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.  If you call GetThreadContext for the current thread, the function returns successfully; however, the context returned is not valid. 是你说可以不停就可以切换是吧，MSDN上的这段话怎么跟你说的完全相反呢

只看看状况和分析

#include <windows.h>   typedef struct ucontext {        CONTEXT  thread_context; } ucontext_t;   int  getcontext( ucontext_t *a ) {       int ret;       a->thread_context.ContextFlags = CONTEXT_FULL;               ret = GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1; //GetThreadContext 获取的是此处的上下文，不是调用 getcontext 的调用点的上下文，切换回来以后，这部分//GetThreadContext有可能重新执行，或者在  //GetThreadContext 函数内部某点执行。        return ret; }   int setcontext( ucontext_t *a ) {       return SetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1; }   int swapcontext( ucontext_t *a, ucontext_t *b ) {       int ret;       if((ret = getcontext(a)) == 0)             ret = setcontext(b);       return ret; }  int  swapcontext( ucontext_t *a, ucontext_t *b ) {     int ret;     a->thread_context.ContextFlags = CONTEXT_FULL;     if( (ret = (GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1) == 0 )           ret = SetThreadContext(GetCurrentThread(), &b->thread_context) ? 0 : -1;  //切换点在这个函数内部执行     return ret; }

看 了半天回复，也不懂。。。

我猜GetCurrentThread()的值有问题

来围观，只做过多线程的初级应用。。。。

围观的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

你对当前线程SetThreadContext，那么可能会影响到当前线程的执行栈，下一条语句都不知道去哪了，因此可能出现各种奇异情况：  if （ＳｅｔＴｈｒｅａｄＣｏｎｔｅｘｔ（当前线程）） ｛ 　　　在这里写代码很可能是没有任何意义的 ｝  －－－ ＳｅｔＴｈｒｅａｄＣｏｎｔｅｘｔ一般都是用来搞其他线程的，搞自己的时候真不多

引用 30 楼 sinservice 的回复:[quote=引用 28 楼 zhao4zhong1 的回复:] 《30天自制操作系统》  在linus之前，全世界只有5个人独自设计并实现了操作系统，linus是第6个。  我根本不相信这种自制操作系统的说法。  我用8051汇编写个电子秤的程序，那的确是运行在纯粹硬件上的直接接触硬件的软件，但我不认为那就是操作系统。  [/quote] 你的成见阻挡了你学习提高的前路。 搜“空杯心态”

引用 38 楼 luciferisnotsatan 的回复:windows不有个协程么？CreateFiberEx  不能满足lz需求？  windows fiber限制很大，最多只能建立2000多个，太少了，不够用的。

windows不有个协程么？CreateFiberEx  不能满足lz需求？

引用 36 楼 fly_dragon_fly 的回复:ret = setcontext(b);  在切换线程后，这个context是否把当前的esp也换掉了，导致ret的地址无效了，  有门了，但不对。  你看29L，那样写就可以。

getcontext setcontext 用这两个函数都是从主线程的栈中调用GetThreadContext、SetThreadContext。返回的时候作为协程会不会。。。不知道！~~~


Question: AOE网关键路径算法问题，c语言

引用 1 楼 user-1 的回复:这里肯定是指针方面除了问题。  要快速掌握数据结构不现实，只有踏实多做总结、多思考以及多看看其他经典的源码我也大概知道应该指针出错，继续努力中


Question: 本人现在正在阿里巴巴面试，急求如何写一个函数生成25个随机数，数字在0到50之间。谢谢，最好贴代码

#include <stdio.h> #include<time.h> #include <stdlib.h> #define RADIX 100 int main ( int argc, char *argv[] ) {     int a[25], tmp[32767];     unsigned idum;     idum = (unsigned)time (NULL);     srand (idum);     int i, j;      for ( i = 0; i < 32767; i++ ) tmp[i] = -1;      i = 0;     j = 0;      while ( i < 25 )     {         if ( tmp[j] == -1 )         {             tmp[rand()/RADIX] = 0;             i++;         }         j++;     }      i = 0;     j = 0;      while ( i < 32767 )     {         if ( tmp[i] != -1 )         {             a[j] = i;             printf ( "%d, ", a[j] );             j++;         }         i++;     }      getchar();     return 0; }

引用 6 楼 jyzdtn 的回复:[quote=引用 2 楼 ri_aje 的回复:] 创建一个50个元素的数组，存 [0,50] 中的数字，然后  random shuffle 一下，第一次取的时候给前半个区间，第二次的时候后半个区间。 引用 2 楼 ri_aje 的回复:创建一个50个元素的数组，存 [0,50] 中的数字，然后  random shuffle 一下，第一次取的时候给前半个区间，第二次的时候后半个区间。  如何编码  random shuffle 是什么意思 ，[/quote] http://en.cppreference.com/w/cpp/algorithm/random_shuffle

引用 2 楼 ri_aje 的回复:创建一个50个元素的数组，存 [0,50] 中的数字，然后  random shuffle 一下，第一次取的时候给前半个区间，第二次的时候后半个区间。 引用 2 楼 ri_aje 的回复:创建一个50个元素的数组，存 [0,50] 中的数字，然后  random shuffle 一下，第一次取的时候给前半个区间，第二次的时候后半个区间。  如何编码  random shuffle 是什么意思 ，

随机必然有重复，所谓“不重复的随机”实际上是洗牌。 洗牌算法参考下面： #include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } }

引用 3 楼 u010794470 的回复:#include <stdio.h> #include<time.h>  int main(int argc, char *argv[]) { 	int a[25]; 	srand((int)time(NULL)); 	int i=0; 	for(i=0;i<25;i++) 	{ 		a[i]=rand()%50; 		printf("%d ",a[i]); 	}		 	return 0; } 头文件包括下面这个才对  #include <stdlib.h>

什么叫2次生成25个随机数？


Question: 帮忙看下贪心算法的题目，为何wa了，测试结果好像挺对的

引用 3 楼 whm546877424 的回复:为何呢？？ 不太明白你的意思。不就是让你解决问题么？而且也只是个人建议，你可以不用采纳。

引用 2 楼 panasonic0804 的回复:个人觉得你应该定义一个struct，该结构中可包含一个link来记录以该点为起点，有效项任务(或者是总数)。然后，你只需要访问这个link或者是总数就可以了吧。为何呢？？

通向金牌之路 《全国青少年信息学竞赛培训教材——复赛》陈合力 游光辉 编著 浙江大学出版社 定价：39.00元（含光盘）


Question: 算不出平均分求助【c语言】

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

引用 1 楼 xionggch 的回复:a是学生数？b是每个学生的科目数？  double Aver( Student stu[], int a, int b ) {     int i, j;     double n=0;     for( i=0; i<a; i++ )     {         for( j=0; j<b; j++ )         {             printf( "%f", stu[i].score[j] );             n += stu[i].score[j];         }         printf( "\n" );     }     printf( "%f", n );     printf( "%f", n/(i*j) );     return n/(i*j); }  我直接把你的代码换掉我的，然后结果就变成下图这样了

你先scanf("%d",&a)然后才n=n/a，只有在输入的值与原值一样时才正确。 此外，图二的结果我没看出哪点儿不正确： ( 59 + 70 + 64 + 64 ) / 4 = 64.25 ≈ 64 ( 69 + 80 + 74 + 74 ) / 4 = 74.25 ≈ 74 让我惊奇的是你居然能用printf("%d",n)输出double类型，难道你的程序前面有#define double int？


引用 5 楼 wanguser-3 的回复:[quote=引用 3 楼 fdsafwagdagadg6576 的回复:] 第4个参数是timeout，为0则epoll_wait立即返回，不阻塞，CPU当然高了。-1则阻塞等到相应事件的发生才返回。 你看你添加的fd可读可写了没有。[/quote]  fd可读写是什么意思？ 我只用了ecp_ctrl(epfd,EPOLL_CTL_ADD,fd,*ev)。 没有用EPOLL_CTL_MOD 同一个socket应该即可以读又可以写啊。 select，poll也不需要切换fd状态，同一个socket既可以读也可以写啊？[/quote] 还有你添加的ev是什么事件，如果是EPOLLIN，那这个fd如果没有数据到达那epoll_wait就一直阻塞啊[/quote]  ev,events 没有问题是epollin|epollout

搜“select、poll、epoll之间的区别总结”

引用 楼主 fdsafwagdagadg6576 的回复:用epoll做服务器。阻塞在epoll_wait. 通过gdb，问题是epoll_wait_nocancel。 	nfds=epoll_wait(epfd,events,1024,-1); 参数4开始是0，cpu达到100%，后来改成-1，cpu正常. 但是epoll_wait_nocancel。 第4个参数是timeout，为0则epoll_wait立即返回，不阻塞，CPU当然高了。-1则阻塞等到相应事件的发生才返回。 你看你添加的fd可读可写了没有。

引用 3 楼 fdsafwagdagadg6576 的回复: 第4个参数是timeout，为0则epoll_wait立即返回，不阻塞，CPU当然高了。-1则阻塞等到相应事件的发生才返回。 你看你添加的fd可读可写了没有。[/quote]  fd可读写是什么意思？ 我只用了ecp_ctrl(epfd,EPOLL_CTL_ADD,fd,*ev)。 没有用EPOLL_CTL_MOD 同一个socket应该即可以读又可以写啊。 select，poll也不需要切换fd状态，同一个socket既可以读也可以写啊？[/quote] 还有你添加的ev是什么事件，如果是EPOLLIN，那这个fd如果没有数据到达那epoll_wait就一直阻塞啊

引用 2 楼 sinservice 的回复:问题是什么？  第4个参数是超时，0，当然只是尝试一下，线程不阻塞，当然CPU100% （不断尝试中。。。。）  问题是block 在ecp_wait 不动

[/quote] 第4个参数是timeout，为0则epoll_wait立即返回，不阻塞，CPU当然高了。-1则阻塞等到相应事件的发生才返回。 你看你添加的fd可读可写了没有。[/quote]  fd可读写是什么意思？ 我只用了ecp_ctrl(epfd,EPOLL_CTL_ADD,fd,*ev)。 没有用EPOLL_CTL_MOD 同一个socket应该即可以读又可以写啊。 select，poll也不需要切换fd状态，同一个socket既可以读也可以写啊？


Question: 关于存钱的的C语言问题

活期利率这么高，就存活期好了

我想说，呵呵


Question: 数组名完全等价于首元素地址？

请参考K&R 《C程序设计语言》第二版附录A.7.1  A.7.1  指针生成      对于某类型T，如果某表达式或子表达式的类型为“T类型的数组”，则此表达式的值是指向数组中第一个对象的指针，并且此表达式的类型将被转换为“指向T类型的指针”。如果此表达式是一元运算符&或sizeof，则不会进行转换。

这是因为，函数调用是表达式 函数调用的实参也是表达式  数组名，在解析表达式的时候，a,*a 这些表达式中，解析为指针

当然不会 只是有时候数组名会隐式转换为指向数组第一个元素的指针[非左值]

慢慢的体会吧

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

《C和指针》

三楼已经让你清楚了吧

说是一物即不中。搜“盲人摸太阳”。

既然楼主都发现两者的sizeof不一样了  肯定“数组名和元素首地址完全等价”这句话就不对了～～  当我们想把数组做实参的时候，通常会把形参设定为指针  但其实呢，这里涉及到一个隐形的“降阶”过程，即从数组类型降为指针 为什么说是降而不是升呢？ 因为数组类型包含两个信息：地址和长度 而指针只包含地址，少了长度 所以在传递参数的时候，实际上是丢掉了长度信息  对于编译器而言，任何数据的类型，都是把该数据挖去后剩下的东西即为它的类型  比如，int i  i的类型为int int *p  p的类型为int * 那么，int a[3] a的类型是什么呢？是 int [3]类型 int b[4] b的类型就是 int [4]类型 int[3]和int[4]是两种完全不同的、毫不相关的类型 用人类的语言可以说他们都是int型数组  但在编译器看来 这就是两种完全不同的类型  所以 指针的类型是指针 数组的类型是数组  它们是不相关的 只不过，你可以用数组名初始化一个指针  但这并不意味着他俩就是一回事 最直接的证据就是sizeof

用多了，就懂了。  也就不再执着于“完全等价”的问题了。

第一个是整个数组 第二个是个地址

去认真啃《C和指针》


Question: C语言中的函数运用

printf( "%x", 1234 );

scanf函数

用移位来做吧，简单快捷

参考 http://wenku.baidu.com/link?url=KQ4k-MBtnd9kUtyMJpDxjm-f1aoaFj4Ux0z7DiUjmMgllniNhnBpejBeVaCsSVWvIs9LoKTfzRqIqmC06aPJKmTPT1BIewDkNZ9n3VGXoS_

了解16进制的来源即可，逢16进一，貌似可以用枚举依次表示字母的10进制值，把它当作字符串处理，对每个字符，进行处理，因子累乘16就行

先 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\xtoa.c 和 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\strtol.c /*** *strtol.c - Contains C runtimes strtol and strtoul * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       strtol - convert ascii string to long signed integer *       strtoul - convert ascii string to long unsigned integer * *******************************************************************************/  #include <cruntime.h> #include <stdlib.h> #include <limits.h> #include <errno.h> #include <ctype.h> #include <internal.h> #include <locale.h> #include <mtdll.h> #include <setlocal.h>  /*** *strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed *       int. * *Purpose: *       Convert an ascii string to a long 32-bit value.  The base *       used for the caculations is supplied by the caller.  The base *       must be in the range 0, 2-36.  If a base of 0 is supplied, the *       ascii string must be examined to determine the base of the *       number: *               (a) First char = '0', second char = 'x' or 'X', *                   use base 16. *               (b) First char = '0', use base 8 *               (c) First char in range '1' - '9', use base 10. * *       If the 'endptr' value is non-NULL, then strtol/strtoul places *       a pointer to the terminating character in this value. *       See ANSI standard for details * *Entry: *       nptr == NEAR/FAR pointer to the start of string. *       endptr == NEAR/FAR pointer to the end of the string. *       ibase == integer base to use for the calculations. * *       string format: [whitespace] [sign] [0] [x] [digits/letters] * *Exit: *       Good return: *               result * *       Overflow return: *               strtol -- LONG_MAX or LONG_MIN *               strtoul -- ULONG_MAX *               strtol/strtoul -- errno == ERANGE * *       No digits or bad base return: *               0 *               endptr = nptr* * *Exceptions: *       Input parameters are validated. Refer to the validation section of the function. * *******************************************************************************/  /* flag values */ #define FL_UNSIGNED   1       /* strtoul called */ #define FL_NEG        2       /* negative sign found */ #define FL_OVERFLOW   4       /* overflow occured */ #define FL_READDIGIT  8       /* we've read at least one correct digit */   static unsigned long __cdecl strtoxl (         _locale_t plocinfo,         const char *nptr,         const char **endptr,         int ibase,         int flags         ) {         const char *p;         char c;         unsigned long number;         unsigned digval;         unsigned long maxval;         _LocaleUpdate _loc_update(plocinfo);          /* validation section */         if (endptr != NULL)         {             /* store beginning of string in endptr */             *endptr = (char *)nptr;         }         _VALIDATE_RETURN(nptr != NULL, EINVAL, 0L);         _VALIDATE_RETURN(ibase == 0 || (2 <= ibase && ibase <= 36), EINVAL, 0L);          p = nptr;                       /* p is our scanning pointer */         number = 0;                     /* start with zero */          c = *p++;                       /* read char */         while ( _isspace_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )             c = *p++;               /* skip whitespace */          if (c == '-') {             flags |= FL_NEG;        /* remember minus sign */             c = *p++;         }         else if (c == '+')             c = *p++;               /* skip sign */          if (ibase < 0 || ibase == 1 || ibase > 36) {             /* bad base! */             if (endptr)                 /* store beginning of string in endptr */                 *endptr = nptr;             return 0L;              /* return 0 */         }         else if (ibase == 0) {             /* determine base free-lance, based on first two chars of                string */             if (c != '0')                 ibase = 10;             else if (*p == 'x' || *p == 'X')                 ibase = 16;             else                 ibase = 8;         }          if (ibase == 0) {             /* determine base free-lance, based on first two chars of                string */             if (c != '0')                 ibase = 10;             else if (*p == 'x' || *p == 'X')                 ibase = 16;             else                 ibase = 8;         }          if (ibase == 16) {             /* we might have 0x in front of number; remove if there */             if (c == '0' && (*p == 'x' || *p == 'X')) {                 ++p;                 c = *p++;       /* advance past prefix */             }         }          /* if our number exceeds this, we will overflow on multiply */         maxval = ULONG_MAX / ibase;           for (;;) {      /* exit in middle of loop */             /* convert c to value */             if ( __ascii_isdigit_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )                 digval = c - '0';             else if ( __ascii_isalpha_l((int)(unsigned char)c, _loc_update.GetLocaleT()) )                 digval = __ascii_toupper(c) - 'A' + 10;             else                 break;             if (digval >= (unsigned)ibase)                 break;          /* exit loop if bad digit found */              /* record the fact we have read one digit */             flags |= FL_READDIGIT;              /* we now need to compute number = number * base + digval,                but we need to know if overflow occured.  This requires                a tricky pre-check. */              if (number < maxval || (number == maxval &&                         (unsigned long)digval <= ULONG_MAX % ibase)) {                 /* we won't overflow, go ahead and multiply */                 number = number * ibase + digval;             }             else {                 /* we would have overflowed -- set the overflow flag */                 flags |= FL_OVERFLOW;                 if (endptr == NULL) {                     /* no need to keep on parsing if we                        don't have to return the endptr. */                     break;                 }             }              c = *p++;               /* read next digit */         }          --p;                            /* point to place that stopped scan */          if (!(flags & FL_READDIGIT)) {             /* no number there; return 0 and point to beginning of                string */             if (endptr)                 /* store beginning of string in endptr later on */                 p = nptr;             number = 0L;            /* return 0 */         }         else if ( (flags & FL_OVERFLOW) ||                 ( !(flags & FL_UNSIGNED) &&                   ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) ||                     ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) )         {             /* overflow or signed overflow occurred */             errno = ERANGE;             if ( flags & FL_UNSIGNED )                 number = ULONG_MAX;             else if ( flags & FL_NEG )                 number = (unsigned long)(-LONG_MIN);             else                 number = LONG_MAX;         }          if (endptr != NULL)             /* store pointer to char that stopped the scan */             *endptr = p;          if (flags & FL_NEG)             /* negate result if there was a neg sign */             number = (unsigned long)(-(long)number);          return number;                  /* done. */ }  extern "C" long __cdecl strtol (         const char *nptr,         char **endptr,         int ibase         ) {     if (__locale_changed == 0)     {         return (long) strtoxl(&__initiallocalestructinfo, nptr, (const char **)endptr, ibase, 0);     }     else     {         return (long) strtoxl(NULL, nptr, (const char **)endptr, ibase, 0);     } }  extern "C" long __cdecl _strtol_l (         const char *nptr,         char **endptr,         int ibase,         _locale_t plocinfo         ) {     return (long) strtoxl(plocinfo, nptr, (const char **)endptr, ibase, 0); }  extern "C" unsigned long __cdecl strtoul (         const char *nptr,         char **endptr,         int ibase         ) {     if (__locale_changed == 0)     {         return strtoxl(&__initiallocalestructinfo, nptr, (const char **)endptr, ibase, FL_UNSIGNED);     }     else     {         return strtoxl(NULL, nptr, (const char **)endptr, ibase, FL_UNSIGNED);     } }  extern "C" unsigned long __cdecl _strtoul_l (         const char *nptr,         char **endptr,         int ibase,         _locale_t plocinfo         ) {     return strtoxl(plocinfo, nptr, (const char **)endptr, ibase, FL_UNSIGNED); }


Question: 表达式求值，出现not all control paths return a value，并且求不出值，出现栈为空

十分感谢，以经很不错

出现栈为空的原因是没有正确地从数组exp取值。如下修改5行可计算无括号的表达式。有括号时仍有错，请LZ自己继续调试。 #include<stdio.h> #include<conio.h>  #include<stdlib.h> #define SIZE 50 typedef int DATA; typedef struct stack {   DATA data[SIZE+1];   int top; }seqstack; seqstack *seqstackInit() {   seqstack *p;   if(p=(seqstack *)malloc(sizeof(seqstack)))   {     p->top=0;     return p;   }   return NULL; } void seqstackFree(seqstack *s) {   if(s)     free(s); } int seqstackIsEmpty(seqstack *s) {   return (s->top==0); } void  seqstackClear(seqstack *s) {   s->top=0; } int seqstackIsFull(seqstack *s) {   return(s->top==SIZE); } int seqstackPush(seqstack *s,DATA data) {   if((s->top+1)>SIZE)   {     printf("栈溢出!\n");     return 0;   }   s->data[++s->top]=data;   return 1; } DATA seqstackPop(seqstack *s) {   if(s->top==0)   {     printf("栈为空 ");     exit(0);   }   return (s->data[s->top--]); } DATA seqstackPeek(seqstack *s) {   if(s->top==0)   {     printf("栈为空 ");     exit(0);   }   return (s->data[s->top]); } int IsOperator(char c) {   switch(c)   {   case'+':   case'-':   case'*':   case'/':   case'(':   case')':   case'=':     return 1;     break;   default:return 0;     break;   } } int PRI(char oper1,char oper2) {   int pri;   switch(oper2)   {   case'+':   case'-':     if(oper1=='('||oper1=='=')       pri=-1;     else       pri=1;break;   case'*':   case'/':     if(oper1=='*'||oper1=='/'||oper1==')')        pri=1;     else       pri=-1;     break;   case '(':     if(oper1==')')     {       printf("语法错误");       exit(0);     }     else       pri=-1;     break;   case')':     if(oper1=='(')       pri=0;     else if(oper1=='=')     {       printf("括号不匹配");       exit(0);     }     else       pri=1;     break;   case '=':     if(oper1=='(')     {       printf("括号不匹配!\n");       exit(0);     }     //改? else if(oper2=='=')     //改?   pri=0;     else       pri=1;     break;   }   return pri; } int Calc(int a,int oper,int b) {   switch(oper)   {   case'+':return a+b;   case'-':return a-b;   case'*':return a*b;   case'/':     if(b!=0)       return a/b;     else     {       printf("除0溢出\n");       exit(0);     }   }   printf("无效操作符: %c\n", oper);//加   exit(0); } int CalcExp(char exp[]) {   seqstack *stackOper,*stackData;   int i=0,flag=0;   DATA a,b,c,q,x,t,oper;   stackOper=seqstackInit();   stackData=seqstackInit();   q=0;   x='=';   seqstackPush(stackOper,x);   c=exp[i++];//改 c=exp[i+1];   while(c!='='||x!='=')   {     if(IsOperator(c))     {       if(flag){         seqstackPush(stackData,q);         q=0;         flag=0;       }       switch(PRI(x,c))       {       case -1:         seqstackPush(stackOper,c);         c=exp[i++];//改 c=exp[i+1];         break;       case 0:         c=seqstackPop(stackOper);         //改 c=exp[i++];         break;       case 1:         oper=seqstackPop(stackOper);         b=seqstackPop(stackData);         a=seqstackPop(stackData);         t=Calc(a,oper,b);         seqstackPush(stackData,t);         break;       }     }     else if(c>='0'&&c<='9')     {       c-='0';       q=q*10+c;       flag=1;       c=exp[i++];     }     else     {       printf("输入错误!\n");       getch();       exit(0);     }     x=seqstackPeek(stackOper);   }   q=seqstackPop(stackData);   seqstackFree(stackOper);   seqstackFree(stackData);   return q; } int main() {   //int c;   char exp[80];   printf("请输入表达式(以=结束):");   scanf("%s",&exp);   printf("%s%d\n",exp,CalcExp(exp));    getch();   return 0; }

我的哪里错了啊。大神啊

还是出现栈为空，怎么办？

int Calc(int a,int oper,int b) { 	switch(oper) 	{ 	case'+':return a+b; 	case'-':return a-b; 	case'*':return a*b; 	case'/': 		if(b!=0) 			return a/b; 		else 		{ 			printf("除0溢出\n"); 			exit(0); 		} 	} 	return -1;/*如果oper不是加减乘除之间的任意一个，也得有个默认的返回值*/}

没人吗吗?

仅供参考/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }


Question: 【求助】关于C语言编写登陆器

引用 1 楼 jiezai69 的回复:就没人会吗？ 这东西，就算是程序，也没人会免费给你的。更别说源代码了。

C++、CHttpConnection、CHttpFile、ASP、存储过程、T-SQL、SQL Server

就没人会吗？


Question: 链表文件写入和输出  急急急~~~

fwrite(list,sizeof(list),1,fp); fread(list,sizeof(list),1,fp); 写入和读出的数据块应该是struct lnode_t，不是list

fread配合fwrite更好用

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

没有报错， 能写入关闭再打开后不能读取！

报错信息是什么?


Question: C语言与链表

楼主这个系统不打算用数据库? 这些信息必然是全部存数据库的，不然你的程序一重启所有东西全都没了

和链表基本没关系。 楼主学习使用SQL Server和ADO正当时。

百度+Google，很多关于C链表的


Question: 关于devc++生成dll时的问题