Question: 求大神解答一道C/C++问题

引用 10 楼 qq_34528718 的回复:还是不能通过测试 那几个用例过不了？ 在求平均数和距离最近的值时，不要用整型变量，会有误差的，修改完再测测，算法是可以推导出来的。

引用 7 楼 face_t0_sea 的回复:[quote=引用 6 楼 qq_34528718 的回复:] 新数组中离平均数最近的数加上原数组最小数是将来的相等的目的数，这里的平均数是原数组还是新数组的 新数组[/quote]  答案错误50%  #include<stdio.h> #include<math.h> int num[1001]; int newnum[1001]; int N; void quiksort(int a[],int low,int high) { 	int i=low; 	int j=high; 	int temp=a[i]; 	if(low<high) 	{ 		while(i<j) 		{ 			while((a[j]<=temp)&&(j>i)) 			{ 				j--; 			} 			a[i]=a[j]; 			while((a[i]>=temp)&&(j>i)) 			{ 				i++; 			} 			a[j]=a[i]; 		} 		a[i]=temp; 		quiksort(a,low,i-1); 		quiksort(a,j+1,high); 	} 	else 	{ 		return; 	} } int maxu(int a, int b) { 	int s=0; 	for(s=a;s>=1;s--) 	{ 		if(a%s==0&&b%s==0) 		{ 			break; 		} 	} 	return s; }  int MAXX() { 	    int i,X; 		X=maxu(newnum[1],newnum[2]); 		for(i=3;i<=N;i++) 		{ 			if(newnum[i]!=0) 			{ 			if(X<newnum[i]) 			X=maxu(X,newnum[i]); 			else 			X=maxu(newnum[i],X); 		    } 		} 		return X; }  int simT(int av) { 	    int i,j; 	    int T,min=10000000,mid; 	    for(i=1;i<=N;i++) 		{ 			mid=abs(newnum[i]-av); 			if(mid<min) 			{ 				j=i; 				min=mid; 			} 		} 		T=newnum[j]+num[N]; 		return T; }  int STEP(int T,int X) { 	int i; 	int step=0; 	for(i=1;i<=N;i++) 		{ 			step+=abs(num[i]-T)/X; 		} 		return step; }  int main() { 	int i; 	int X,step; 	int T,sum,av,mid; 	while(scanf("%d",&N)!=EOF) 	{ 		step=sum=0; 		for(i=1;i<=N;i++) 		{ 			scanf("%d",&num[i]); 		} 		quiksort(num,1,N); 		for(i=1;i<=N;i++)  		{ 			newnum[i]=num[i]-num[N]; 			sum+=newnum[i]; 		} 		av=sum/N; 		X=MAXX(); 		T=simT(av); 		mid=STEP(T,X); 		T=simT(av+1); 		step=STEP(T,X); 		if(step>mid) step=mid; 		printf("%d %d\n",X,step);	 	} 	return 0; }

还是不能通过测试

修改了两处bug, 重贴一下：    #include <stdio.h> #include <stdlib.h> #include <math.h> #include <limits.h>  #define swap(m, n) do {int r = m; m = n; n = r;} while(0)   int gcd(int m, int n) { 	int r; 	if(m < n) swap(m, n); 	if(n == 0) return m;  	 	while((r = (m % n))) 	{ 		m = n; 		n = r; 	} 	return n; }  #define MAX_ITEMS (1000) int a[] =  {4, 8, 12, 14, 16, 20, 30, 32, 34, 35, 36};  static inline int calc_min_steps(int dst, int N, int * min_steps, int * X) { 	if(N < 1) exit(1); // invalid parameter 	 	// 计算数组个元素与目标值的偏差 	int i;  	int steps; 	int diffs[MAX_ITEMS]; 	int x = 0; 	 	for(i = 0; i < N; ++i) 	{ 		diffs[i] = abs(a[i] - dst); 		if(x == 0 && diffs[i]) x = diffs[i]; 	} 	// 计算偏差值的最大公约数 x 	//~ x = diffs[0];	 	for(i = 1; i < N; ++i) 	{ 		if(diffs[i]) // 仅计算偏差值不为0的情况 		{ 			x = gcd(x, diffs[i]); 		} 	} 	 	// 计算步数 	if(x == 0) // 只有一个元素的情况，或所有元素均为0的情况，此时不需要执行任何步骤 	{ 		* min_steps = 0; 		* X = x; 		return 0; 	} 	 	steps = 0; 	for(i = 0; i < N; ++i) 	{ 		steps += diffs[i] / x; 	} 	 	* min_steps = steps; 	*X = x; 	return 0; }   void exhaustive_method() { 	int N = (int)(sizeof(a) / sizeof(a[0])); 	 	int dst; 	int steps; 	int x; 	int min = INT_MAX; 	int min_dst = INT_MAX; 	int min_x = INT_MAX; 	printf(" N = %d\n", N); 	//~ return 0; 	for(dst = a[0]; dst <= a[N - 1]; ++dst) 	{ 		steps = 0; 		calc_min_steps(dst, N, &steps, &x); 		 		printf("dst = %d, ", dst); 		if(steps < min)  		{ 			min = steps; 			min_dst = dst; 			min_x = x; 		} 		printf("x = %d: steps = %d\n", x, steps); 	} 	printf("min steps = %d, min_dst = %d, min_x = %d\n", min, min_dst, min_x); 	 }  void fast_method() { 	int N = (int)(sizeof(a) / sizeof(a[0])); 	int mid_pos = (N + 1) / 2 - 1; 	int min_steps = 0; 	int X = 0; 	 	int min_dst = a[mid_pos]; 	 	calc_min_steps(min_dst, N,  &min_steps, &X); 	//~ printf("min steps = %d, min_dst = %d, min_x = %d\n", min_steps, min_dst, X); 	 	if((N & 0x01) == 0) // N 为偶数时有两个中位数，需要多检查一个中位数 	{ 		int steps = INT_MAX; 		int x = INT_MAX; 		int dst = a[mid_pos + 1]; 		calc_min_steps(dst, N,  &steps, &x); 		if(steps < min_steps) 		{ 			min_dst = dst; 			min_steps = steps; 			X = x; 		}		 	} 	printf("N = %d, min_steps = %d, min_dst = %d, min_x = %d\n", N, min_steps, min_dst, X); }   int main(int argc, char **argv) { 	exhaustive_method(); 	 	printf("====  fast_methos ====\n"); 	fast_method(); 	return 0; }

第一次贴的取平均数这一步是错的，应该先对数组排序并取中间那个数。 至于为什么是中间那个数，我是在用穷举法计算时发现的，但不知道该怎么证明。  以下是测试代码： 其中，exhausitive_method是用穷举法，遍历数组最小值和最大值之间的所有数作为目标值（dst)，并获取其中的最小步数； fast_method是直接取中间位置的那个数为目标值（dst），然后计算步数。（如果数组元素个数为偶数，将有两个中间位置，需要计算两次）； 注： 代码中省略了排序算法，假设数组已经排好了序。     #include <stdio.h> #include <stdlib.h> #include <math.h> #include <limits.h>  static inline void swap(int m, int n) { 	int r = m; 	m = n; 	n = r; }  int gcd(int m, int n) { 	int r; 	if(m < n) swap(m, n); 	 	while((r = (m % n))) 	{ 		m = n; 		n = r; 	} 	return n; }  #define MAX_ITEMS (1000) int a[] = {4, 8, 12, 13, 15, 16, 18, 20, 30, 32};  static inline int calc_min_steps(int dst, int N, int * min_steps, int * X) { 	if(N < 1) exit(1); // invalid parameter 	 	// 计算数组个元素与目标值的偏差 	int i;  	int steps; 	int diffs[MAX_ITEMS]; 	int x = 0; 	 	for(i = 0; i < N; ++i) 	{ 		diffs[i] = abs(a[i] - dst); 	} 	// 计算偏差值的最大公约数 x 	x = diffs[0]; 	for(i = 1; i < N; ++i) 	{ 		if(diffs[i]) // 仅计算偏差值不为0的情况 		{ 			x = gcd(x, diffs[i]); 		} 	} 	 	// 计算步数 	if(x == 0) // 只有一个元素的情况，或所有元素均为0的情况，此时不需要执行任何步骤 	{ 		* min_steps = 0; 		* X = x; 		return 0; 	} 	 	steps = 0; 	for(i = 0; i < N; ++i) 	{ 		steps += diffs[i] / x; 	} 	 	* min_steps = steps; 	*X = x; 	return 0; }   void exhaustive_method() { 	int N = (int)(sizeof(a) / sizeof(a[0])); 	 	int dst; 	int steps; 	int x; 	int min = INT_MAX; 	int min_dst = INT_MAX; 	int min_x = INT_MAX; 	printf(" N = %d\n", N); 	//~ return 0; 	for(dst = a[0]; dst <= a[N - 1]; ++dst) 	{ 		steps = 0; 		calc_min_steps(dst, N, &steps, &x); 		 		printf("dst = %d, ", dst); 		if(steps < min)  		{ 			min = steps; 			min_dst = dst; 			min_x = x; 		} 		printf("x = %d: steps = %d\n", x, steps); 	} 	printf("min steps = %d, min_dst = %d, min_x = %d\n", min, min_dst, min_x); 	 }  void fast_method() { 	int N = (int)(sizeof(a) / sizeof(a[0])); 	int mid_pos = (N + 1) / 2 - 1; 	int min_steps = 0; 	int X = 0; 	 	int min_dst = a[mid_pos]; 	 	calc_min_steps(min_dst, N,  &min_steps, &X); 	//~ printf("min steps = %d, min_dst = %d, min_x = %d\n", min_steps, min_dst, X); 	 	if((N & 0x01) == 0) // N 为偶数时有两个中位数，需要多检查一个中位数 	{ 		int steps = INT_MAX; 		int x = INT_MAX; 		int dst = a[mid_pos + 1]; 		calc_min_steps(dst, N,  &steps, &x); 		if(steps < min_steps) 		{ 			min_dst = dst; 			min_steps = steps; 			X = x; 		}		 	} 	printf("N = %d, min_steps = %d, min_dst = %d, min_x = %d\n", N, min_steps, min_dst, X); }   int main(int argc, char **argv) { 	exhaustive_method(); 	 	printf("====  fast_methos ====\n"); 	fast_method(); 	return 0; }

引用 6 楼 qq_34528718 的回复:新数组中离平均数最近的数加上原数组最小数是将来的相等的目的数，这里的平均数是原数组还是新数组的 新数组

引用 2 楼 face_t0_sea 的回复:[quote=引用 1 楼 chehw_1 的回复:] 一种简单的解法（可能不是最优的算法）：  （1）计算所有数的平均数ave; （2）建立一个临时数组，存储每个数与平均数的差值diffs[N]； （3）计算diffs[N]中所有数的最大公约数X； int X = diffs[0]; int i = 1; while(i < N) {     X = gcd(X, diffs[i++]); } （4）计算所需的步数： steps = 0; for(i = 0; i < N; ++i) {     steps += abs(diffs[i]) / X; } 最大 公约数的思想是对的，但是不是和平均数的差；把原数组排序，然后所有数减去最小数之后得到新数组，再求最大公约数即为X，新数组中离平均数最近的数加上原数组最小数是将来的相等的目的数。然后步数遍历一遍就可以计算了。[/quote] 受教了

引用 3 楼 qq_29120981 的回复:我觉得这题和平均数没有关系,比如三个数据1 6 6,很明显X=5只需要1步即可,和平均数无关,和众数有关.  初步思路如下: 找出输入数据的最大值maxn,最小值minn,和众数. 取lim=max{abs(众数-maxn),abs(众数-minn)} (如果众数有多个取最大值) 则X的范围应该在(0,lim],对其中每个值枚举计算所需步数即可.  1  6  6   第一步减去最小数： 0   5    5 最大公约数，除去0是5； 一步到位

引用 1 楼 chehw_1 的回复:一种简单的解法（可能不是最优的算法）：  （1）计算所有数的平均数ave; （2）建立一个临时数组，存储每个数与平均数的差值diffs[N]； （3）计算diffs[N]中所有数的最大公约数X； int X = diffs[0]; int i = 1; while(i < N) {     X = gcd(X, diffs[i++]); } （4）计算所需的步数： steps = 0; for(i = 0; i < N; ++i) {     steps += abs(diffs[i]) / X; } 最大 公约数的思想是对的，但是不是和平均数的差；把原数组排序，然后所有数减去最小数之后得到新数组，再求最大公约数即为X，新数组中离平均数最近的数加上原数组最小数是将来的相等的目的数。然后步数遍历一遍就可以计算了。


Question: C语言链表问题

#include<stdio.h> #include<malloc.h> #define NULL 0  struct name  { 	int num; 	struct name *next; };  int FindNode(struct name *head, int x) { 	int i = 1; 	struct name *p=head->next; 	while(p) 	{ 		if(p->num == x) 			break; 		p=p->next; 		i++; 	} 	return p == NULL ? 0 : i; }  void main() {	 	int x; 	struct name a; 	struct name b; 	struct name c; 	struct name d; 	struct name *p; 	struct name *head; 	head=(struct name*)malloc(sizeof(struct name)); 	a.num=1; 	b.num=2; 	c.num=3; 	head->next=&a; 	a.next=&b; 	b.next=&c; 	c.next=NULL; 	printf("请输入要查找的元素:"); 	scanf("%d", &x); 	int res = FindNode(head, x); 	if(res == 0) 		printf("没有找到元素!\n"); 	else 		printf("节点序号为:%d\n", res); }

引用 1 楼 旧剑鞘的回复:struct name { int num; struct name *next; }; 节点里面只有num和next指针，序号是num? 寻找的的x是个什么鬼？ 序号是节点的序号

引用 1 楼 旧剑鞘的回复:struct name { int num; struct name *next; }; 节点里面只有num和next指针，序号是num? 寻找的的x是个什么鬼？ x是num中的数据


Question: 用C语言进行十进制和八进制的转换怎么做？

仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

谢谢你了!!!

#include <stdio.h> #include <math.h> #include <string.h> int main() { 	int a,b,c,d,e=0; 	int j=0; 	printf("请输入一个十进制整数："); 	scanf("%d",&a); 	if(a<8){b=a;} 	else{c=a; 	do{  		d=c%8; 		e+=d*pow(10.0,j); 		c/=8; 		j++; 	}while(c>=8); 	} 	b=c*pow(10.0,j)+e; 	printf("转换成八进制数是:%d\n\n",b);  	printf("请输入一个八进制整数："); 	char x[100]={0}; 	scanf("%s", x); 	int i,flag=1; 	int k=0,w=0; 	j=strlen(x);//j用来判断用这个八进制数有多少位 	for(i=0;i<strlen(x);i++) 	{ 		if(x[i]<'0'||x[i]>'8')flag=0; 		k=(x[i]-48)*(pow(8.0,--j)); 		w+=k; 	} 	if(flag) 		printf("转换成十进制数是:%d\n",w);//显示十进制数 	else 		printf("八进制输入错误！\n");  }

输出标识符改成八进制的就行了！


Question: C 语音如何获取Windows的显示内存

搜“DirectX Surface” ？

图像显示的数据应该也存再内存中吧，能不能通过存在内存中的数据获取呢？我猜的哈

谢谢， 我再看看opengl

抓图 录屏的软件看看源码？windows现在应该是不可以直接访问显存的

引用 4 楼 ynsenyu 的回复:抓图 录屏的软件看看源码？windows现在应该是不可以直接访问显存的 恩，哪里会有这种开源的代码？

引用 2 楼 yueyuezai 的回复:不好意思，比较菜，不过这个好像只是获取当前内存的状态，我是想获取显示屏显示的图像的内存数据，这个接口也可以？ 看样子我理解错了。你如果想读显存的数据，替你查了下百度，DirectX和OpenGL可能会提供类似接口，但是这里面有硬件加解码的部分，这个我不懂，自己找吧

引用 1 楼 face_t0_sea 的回复:GlobalMemoryStatusEx http://blog.csdn.net/caimouse/article/details/1904782 完全可以自己百度的 不好意思，比较菜，不过这个好像只是获取当前内存的状态，我是想获取显示屏显示的图像的内存数据，这个接口也可以？


Question: 程序运行到while((p!=NULL)&&(strcmp(p->name,name)!=0))停止运行

感觉是链表中某个节点p!=NULL，但p->name变量是个空指针。

不要使用 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;  //... } 类似的例子还可以举很多。

GoodsLink 和CreatGoodsLink()具体是什么？ GoodsLink 里的name是指针么？

出错时断下来检测p的值是什么

死循环了？while换成if看能不能跳出来继续运行

这部分代码感觉没啥问题，建议楼主再贴一下CreatGoodsLink函数的 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

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


Question: ipv6开发需要注意什么？

理想很丰满， 现实很骨感。

引用 2 楼 qq423399099 的回复:技术上的困难是如何让IPv4与IPv6网络互联互通。 如果一夜之间，所有的路由器、主机、应用程序都能支持IPv6，那明天就可以抛弃IPv4了。现实中不可能这么做，IPv6的部署肯定是循序渐进的过程，这就要求技术上处理好旧的IPv4网络与新的IPv6网络的兼容性。以我们最熟悉的QQ为例，如果IPv4和IPv6用户不能互相通信将是非常糟糕的情况。 IPv6的过渡方案主要有双栈、隧道、地址转换3种。 双栈技术本身不解决网络互联互通，只是要求所有主机都支持两种IP协议，这样对用户而言就是互通了。显然这种方案很难调动运营商和用户的积极性：别人都有双栈，我有IPv4就够了。 隧道技术可以解决双向互通，但需要强大的隧道服务器，可能会成为瓶颈。 地址转换技术方面曾经有一个标准草案NAT－PT，但已被IETF放弃了。 现在有一些更具体的新方案被提出来，如法国运营商Comcast提出的DS-Lite，国内CERNET2团队提出的IVI。新方案一般都将隧道和地址转换结合起来，可能更适合实现过渡的目的。   你的意思是说，只要所有路由器，计算机支持ipv6， 就可以了？

IPv6协议对IPv4的改进表现在：  （1）扩展地址空间。IP地址长度由32位增加到128位。  （2）简化的首部格式，优化路由选择。IPv4首部的某些字段被取消或改为选项，以减少报文分组处理过程中常用情况的处理开销，并使得IPv6首部的带宽开销尽可能低。  （3）支持扩展首部和选项。IPv6的选项放在单独的扩展首部中，位于报文分组中IPv6基本首部和传送层首部之间。因为大多数IPv6选项首部不会被报文分组投递路径上的任何路由器检查和处理，直至其到达最终目的地，这种组织方式有利于改进路由器在处理包含选项的报文分组时的性能。IPv6的另一改进，是其选项与IPv4不同，可具有任意长度，不限于40字节。  （4）支持认证和加密机制。IPv6定义了一种扩展，可支持权限验证和数据完整性并支持保密性要求。  （5）支持自动配置。IPv6支持多种形式的自动配置，从孤立网络结点地址的“即插即用”自动配置，到DHCP提供的全功能的设施。  （6）服务质量能力。IPv6增加了一种新的能力，如果某些报文分组属于特定的工作流，发送者要求对其给予特殊处理，则可对这些报文分组加标号，例如非缺省服务质量通信业务或“实时”服务。


Question: socket套接字传输问题

server  #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <sys/stat.h> #include <errno.h>  // Need to link with Ws2_32.lib #pragma comment(lib, "ws2_32.lib")   #define PORT 6500  typedef struct file_trans_header { 	unsigned short status;// 1:OK, 0:NG 	unsigned long filesize; 	char filename[256];//file name 	char errinfo[256]; }file_trans_header_t;  int main(void) {  	//---------------------- 	// Initialize Winsock 	WSADATA wsaData; 	int iResult = 0;  	SOCKET ListenSocket = INVALID_SOCKET; 	SOCKET AcceptSocket = INVALID_SOCKET; 	sockaddr_in service, client; 	file_trans_header_t fheader;  	struct _stat info; 	 	FILE* fp = NULL; 	int len = 0;  	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 	if (iResult != NO_ERROR) { 		printf("WSAStartup() failed with error: %d\n", iResult); 		return 1; 	} 	//---------------------- 	// Create a SOCKET for listening for incoming connection requests. 	ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 	if (ListenSocket == INVALID_SOCKET) { 		printf("socket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// The sockaddr_in structure specifies the address family, 	// IP address, and port for the socket that is being bound. 	service.sin_family = AF_INET; 	service.sin_addr.s_addr = inet_addr("127.0.0.1"); 	service.sin_port = htons(PORT);  	iResult = bind(ListenSocket, (SOCKADDR *)& service, sizeof (service)); 	if (iResult == SOCKET_ERROR) { 		printf("bind function failed with error %d\n", WSAGetLastError()); 		closesocket(ListenSocket); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// Listen for incoming connection requests  	// on the created socket 	if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) { 		printf("listen function failed with error: %d\n", WSAGetLastError()); 		closesocket(ListenSocket); 		WSACleanup(); 	}  	//---------------------- 	while (1) { 		printf("\n\n*** waiting for client to connect...\n"); 		// Accept the connection. 		len = sizeof(sockaddr_in); 		AcceptSocket = accept(ListenSocket, (sockaddr*)&client, &len); 		if (AcceptSocket == INVALID_SOCKET) { 			printf("accept failed with error: %ld\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		} 		else 			printf("=== client [%s] connected.\n", inet_ntoa(client.sin_addr));  		//  Recive the Reuquest File Name 		memset(&fheader, 0x00, sizeof(fheader)); 		iResult = recv(AcceptSocket, fheader.filename, 255, 0); 		if (iResult > 0) 			printf("=== client want to download file [%s]\n", fheader.filename); 		else if (iResult == 0) { 			printf("=== clinet connection closed\n"); 			continue; 		} 		else { 			printf("recv failed: %d\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		}   		// parse the request file info 		iResult = _stat(fheader.filename, &info); 		// Check if statistics are valid:  		if (iResult != 0) 		{ 			fheader.status = htons(0); //NG 			switch (errno) 			{ 			case ENOENT: 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "File not found."); 				break; 			case EINVAL: 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Invalid parameter to _stat."); 				break; 			default: 				/* Should never be reached. */ 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Unexpected error %d in _stat.", errno); 				break; 			} 			printf("=== %s\n", fheader.errinfo); 		} 		else { 			fp = fopen(fheader.filename, "rb"); 			if (NULL == fp) { 				fheader.status = htons(0); //NG 				_snprintf(fheader.errinfo, sizeof(fheader.errinfo) - 1, "Open File Failed."); 				printf("=== %s\n", fheader.errinfo); 			} 			else { 				fheader.status = htons(1);//OK 				fheader.filesize = htonl(info.st_size); 			} 		}  		//send protocol header 		iResult = send(AcceptSocket, (char*)&fheader, sizeof(fheader), 0); 		if (SOCKET_ERROR == iResult) { 			printf("send failed, errno = %d\n", WSAGetLastError()); 			closesocket(ListenSocket); 			WSACleanup(); 			return 1; 		}  		// send file 		if (fheader.status != 0) { 			char buff[2048]; 			printf("=== send file to client ..."); 			while (!feof(fp)) { 				iResult = fread(buff, 1, 2048, fp); 				send(AcceptSocket, buff, iResult, 0); 			} 			fclose(fp); 			printf("[done]\n"); 			shutdown(AcceptSocket, SD_SEND); 			closesocket(AcceptSocket); 		} 	}  	// No longer need server socket 	closesocket(ListenSocket); 	WSACleanup(); 	return 0; }     client  #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h>  // Need to link with Ws2_32.lib #pragma comment(lib, "ws2_32.lib")  #define SERVER_IP "127.0.0.1" #define PORT 6500  typedef struct file_trans_header { 	unsigned short status;// 1:OK, 0:NG 	unsigned long filesize; 	char filename[256];//file name 	char errinfo[256]; }file_trans_header_t;   int main(void) { 	//---------------------- 	// Initialize Winsock 	WSADATA wsaData; 	file_trans_header_t fheader;  	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 	if (iResult != NO_ERROR) { 		printf("WSAStartup function failed with error: %d\n", iResult); 		return 1; 	} 	//---------------------- 	// Create a SOCKET for connecting to server 	SOCKET ConnectSocket; 	ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 	if (ConnectSocket == INVALID_SOCKET) { 		wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	} 	//---------------------- 	// The sockaddr_in structure specifies the address family, 	// IP address, and port of the server to be connected to. 	sockaddr_in clientService; 	clientService.sin_family = AF_INET; 	clientService.sin_addr.s_addr = inet_addr(SERVER_IP); 	clientService.sin_port = htons(PORT);  	//---------------------- 	// Connect to server. 	iResult = connect(ConnectSocket, (SOCKADDR *)& clientService, sizeof (clientService)); 	if (iResult == SOCKET_ERROR) { 		printf("connect function failed with error: %ld\n", WSAGetLastError()); 		iResult = closesocket(ConnectSocket); 		if (iResult == SOCKET_ERROR) 			printf("closesocket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	}  	printf("=== connected to server.\n");  		char filename[512] = { 0 }; 		printf("\n\n*** please input the filename(with path) you want to download:\n"); 		scanf("%s", filename); 		//send file name to server 		iResult = send(ConnectSocket, filename, (int)strlen(filename), 0); 		if (iResult == SOCKET_ERROR) { 			printf("send failed: %d\n", WSAGetLastError()); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		// shutdown the connection since no more data will be sent 		iResult = shutdown(ConnectSocket, SD_SEND); 		if (iResult == SOCKET_ERROR) { 			printf("shutdown failed: %d\n", WSAGetLastError()); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		// Receive the header 		int recvbuflen = sizeof(fheader); 		memset(&fheader, 0x00, recvbuflen);  		iResult = recv(ConnectSocket, (char*)&fheader, recvbuflen, 0); 		if (ntohs(fheader.status) == 0) { 			printf("%s\n", fheader.errinfo); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		char* name = strrchr(fheader.filename, '\\'); 		if (NULL == name) { 			name = fheader.filename; 		} 		else { 			name++; 		}  		FILE* fp = fopen(name, "wb"); 		if (NULL == fp) { 			printf("fopen failed\n"); 			closesocket(ConnectSocket); 			WSACleanup(); 			return 1; 		}  		char recvbuf[2048]; 		unsigned long filesize = 0; 		recvbuflen = 2048; 		do { 			iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 			if (iResult > 0) { 				filesize += iResult; 				fwrite(recvbuf, 1, iResult, fp); 			} 			else if (iResult == 0)  				printf("=== download is done\n"); 			else 				printf("recv failed: %d\n", WSAGetLastError());  		} while (iResult > 0); 		fclose(fp);  		if (filesize != ntohl(fheader.filesize)) 		{ 			printf("=== file download error, mismatch filesize\n"); 		}   	iResult = closesocket(ConnectSocket); 	if (iResult == SOCKET_ERROR) { 		wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError()); 		WSACleanup(); 		return 1; 	}  	WSACleanup(); 	return 0; }

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

引用 4 楼 qq423399099 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  不如打log来的实际，   我们以前测试代码（是测试人员， 通过抓包或者查看日志，来验证 协议设计、实现的正确性）   调试这种玩意， 取决于程序员，测试人员搞不了，

不知道是不是因为你的服务端程序默认使用的是Nagle算法。在服务端程序加入下面代码试下 const char chOpt=1;        int   nErr=setsockopt(   m_socket,   IPPROTO_TCP,   TCP_NODELAY,   &chOpt,   sizeof(char));

跟题有关？？希望讲详细一点，谢了

楼主，学会打印日志，   recv 打印接受的数据，


Question: 数据结构书中说    线索二叉树一般不设置fwd和bkwd指针，会浪费存储，为什么这么说

我也觉得是一样的啊，楼主想明白这个问题了吗？

一个 char 四个字节， 两个也是， 如果位数比较少， 例如1Bit,32个标志占四个字节 大约如此，另外16Bits程序，int只有2个字节

引用 3 楼 galiniur0u 的回复:fwd和bkwd是否浪费空间只是相对于不加这两个字段而言，因为使用书上说的方式，不加这两个字段也可以实现线索二叉树。 也就是说结构体正常来说包括，left、right、fwd、bkwd、data。如果不加fwd、bkwd也可以实现。 不加fwd  bkwd 的话，只有left和right以及data，结点不是应该再加上ltag和rtag么

没人吗。。。


Question: C语言让主程序每运行一次变量永久自加1

引用 14 楼 lm_whales 的回复:过去有些程序，会把数据写入可执行文件自身内部 现在似乎有点玄，可能需要一点手段 比如：http://bbs.csdn.net/topics/390968755

引用 14 楼 lm_whales 的回复:过去有些程序，会把数据写入可执行文件自身内部 现在似乎有点玄，可能需要一点手段  用读取文件已解决 谢谢

引用 12 楼 zhao4zhong1 的回复:读写文件 读写注册表 读写数据库 读写云存储 读写FLASH ROM ……  谢谢 ，虽然只明白第一个，但是已经能用来解决问题了

过去有些程序，会把数据写入可执行文件自身内部 现在似乎有点玄，可能需要一点手段

引用 10 楼 h370981805 的回复:[quote=引用 9 楼 qq_29007291 的回复:] [quote=引用 8 楼 lgbxyz 的回复:] static 和 全局 变量  static int number=0; int main() {  printf("%d",number); return 0; } 这样能达到想要的效果吗？（number在头文件所声明的函数里自动加  1    了） [/quote]  这么说吧，main 当做一个主程序，运行的时候载入内存的，你退出了，存变量的内存这块就清空了（这么说不严谨，你先这样理解），所以你每次起一次main 这个变量又重新初始化，除非你把这个变量以文件写入硬盘。硬盘是除非别人复写了这块文件，要不然它存的这个变量文件是都存在的[/quote]   也就是说 也只有读写文件了对吧。OK，我正在试，谢谢！

读写文件 读写注册表 读写数据库 读写云存储 读写FLASH ROM ……

引用 9 楼 qq_29007291 的回复:[quote=引用 8 楼 lgbxyz 的回复:] static 和 全局 变量  static int number=0; int main() {  printf("%d",number); return 0; } 这样能达到想要的效果吗？（number在头文件所声明的函数里自动加  1    了） [/quote]  这么说吧，main 当做一个主程序，运行的时候载入内存的，你退出了，存变量的内存这块就清空了（这么说不严谨，你先这样理解），所以你每次起一次main 这个变量又重新初始化，除非你把这个变量以文件写入硬盘。硬盘是除非别人复写了这块文件，要不然它存的这个变量文件是都存在的

引用 8 楼 lgbxyz 的回复:static 和 全局 变量  static int number=0; int main() {  printf("%d",number); return 0; } 这样能达到想要的效果吗？（number在头文件所声明的函数里自动加  1    了）

static 和 全局 变量

引用 5 楼 u014444402 的回复:[quote=引用 2 楼 qq_29007291的回复:][quote=引用 1 楼 u014444402 的回复:] 文件被你忽略了？ ...不知道什么意思..C语言掌握的非常浅[/quote] 每次程序开始从文件里读，后面加了之后在写回文件。[/quote]  懂了懂了..这部分内容掌握的不是很熟，但是知道了有这个方法，谢谢哈

引用 3 楼 yuelengdihai 的回复:在主程序main函数中肯定不可以的，mian函数结束整个程序的资源都被回收了 在其它函数中可以，下面test运行一次 a就加1  #include<stdio.h> void test() {    static int a=0;     a++;   printf("%d",a); } int main() {     test();    return 0; }  好像看到了希望，再进一步要求 如果这个变量还想在其他文件使用呢，也就是说我这个变量还得是全局变量

引用 2 楼 qq_29007291的回复:[quote=引用 1 楼 u014444402 的回复:] 文件被你忽略了？ ...不知道什么意思..C语言掌握的非常浅[/quote] 每次程序开始从文件里读，后面加了之后在写回文件。

引用 2 楼 qq_29007291 的回复:[quote=引用 1 楼 u014444402 的回复:] 文件被你忽略了？ ...不知道什么意思..C语言掌握的非常浅[/quote] 楼上意思是你运行一次，在程序中把变量写入文件一次

引用 1 楼 u014444402 的回复:文件被你忽略了？ ...不知道什么意思..C语言掌握的非常浅

文件被你忽略了？


Question: C语言怎么把一个链表的3个表元加互斥量

引用 13 楼 u012324313 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 11 楼 u012324313 的回复:] [quote=引用 10 楼 zhao4zhong1 的回复:] 搞一个互斥量数组不就得了。 但是怎么把3个表元这种数据结构放到锁里面？[/quote] 使用第几个表元，就锁第几个锁。[/quote] 我懂了，谢谢了！[/quote] 心有灵犀一点通。

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 u012324313 的回复:] [quote=引用 10 楼 zhao4zhong1 的回复:] 搞一个互斥量数组不就得了。 但是怎么把3个表元这种数据结构放到锁里面？[/quote] 使用第几个表元，就锁第几个锁。[/quote] 我懂了，谢谢了！

引用 11 楼 u012324313 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] 搞一个互斥量数组不就得了。 但是怎么把3个表元这种数据结构放到锁里面？[/quote] 使用第几个表元，就锁第几个锁。

引用 10 楼 zhao4zhong1 的回复:搞一个互斥量数组不就得了。 但是怎么把3个表元这种数据结构放到锁里面？

搞一个互斥量数组不就得了。

对整条链表进行加锁，我已经做好了，但是我觉得如果访问的2个表元距离较远，没必要等前几个解锁后再进行访问，可以同时进行，只有在2次修改同时在相邻表元进行操作时才加锁比较好，但是我不知道该怎么实现。

引用 7 楼 galiniur0u 的回复:不知道楼主的插入表元和添加表元有什么区别，如果仅仅是插入和查询操作，没有多线程操作同一链表，也不需要加锁的。 不好意思，我写错了，是插入和删除

引用 5 楼 chehw_1 的回复:[quote=引用 4 楼 u012324313 的回复:] [quote=引用 3 楼 chehw_1 的回复:] 建议准确描述一下你是在什么情况下需要这种加锁操作，看看是否有必要加这么多锁。  我感觉一般用一个锁就可以了。当你还不太清楚该如何实现时，如果对这种链表内部的某一个操作同时加三个锁，估计你有99.9%以上的概率会出现deaklock。 我做操作系统的课程设计[/quote]  与你做什么设计没什么关系，我指的是你打算对链表进行什么具体操作时必须要加3个锁？[/quote] 插入表元，添加表元和查询

引用 4 楼 u012324313 的回复:[quote=引用 3 楼 chehw_1 的回复:] 建议准确描述一下你是在什么情况下需要这种加锁操作，看看是否有必要加这么多锁。  我感觉一般用一个锁就可以了。当你还不太清楚该如何实现时，如果对这种链表内部的某一个操作同时加三个锁，估计你有99.9%以上的概率会出现deaklock。 我做操作系统的课程设计[/quote]  与你做什么设计没什么关系，我指的是你打算对链表进行什么具体操作时必须要加3个锁？

引用 3 楼 chehw_1 的回复:建议准确描述一下你是在什么情况下需要这种加锁操作，看看是否有必要加这么多锁。  我感觉一般用一个锁就可以了。当你还不太清楚该如何实现时，如果对这种链表内部的某一个操作同时加三个锁，估计你有99.9%以上的概率会出现deaklock。 我做操作系统的课程设计

引用 1 楼 lgbxyz 的回复:访问加锁呗   LOCK(); //链表增删查排  UNLOCK();  能不能说详细一点？谢谢了

访问加锁呗   LOCK(); //链表增删查排  UNLOCK();


Question: 一个栈的问题

for reference only package main import (     "fmt"     "errors"     "strconv" ) type stack struct{      data []int  } func (s *stack)push(n int) {     s.data = append(s.data , n) }  func (s *stack)pop() (int , error){     a := *s     lenStack := len(s.data)     if lenStack < 1{         return 0, errors.New("error , can not pop a empty stask")     }     tmp := a.data[lenStack-1]     s.data =  a.data[0 : (lenStack-1)]     return tmp , nil }  func (s *stack)find(n int) int{     for i, v := range s.data{         if v == n{             return i         }     }     return -1 }  func (s *stack)string()string{     str := ""     if len(s.data) == 0{         return "栈空"     }     for _, v := range s.data{         str += strconv.Itoa(v) + " "     }    return str } func main(){     var data int     s := &stack{}      for{           fmt.Scanf("%d\n",&data)           pos := s.find(data)           if pos != -1{               for {                   popValue , _ := s.pop()                   if popValue == data {                       break;                   }               }               fmt.Println("当前栈:" + s.string())               continue           }           s.push(data)           fmt.Println("当前栈:" + s.string())     } }

楼主既然不要求以什么方式实现，那我就用数组当做栈，不知道满不满足要求。 #include <stdlib.h> #include <stdio.h>  #define MAX 100  int isEmpty(int stack[]) { 	if(0 == stack[0]) 		return 0; 	return 1; } //入栈 void push(int stack[], int top, int num) { 	int i = 0; 	printf("栈中内容为:"); 	stack[top] = num; 	for(i = 0; i <= top; i ++) 	{ 		printf("%d ", stack[i]); 	} 	printf("\n"); } //出栈 int pop(int stack[], int top) { 	int tmp = stack[top]; 	stack[top] = 0; 	return tmp; }  int main(int argc, char *argv[]) { 	int stack[100] = {0};//栈 	int top = -1;//当前栈头位置 	int num = 0;//输入的元素值 	int i = 0; 	int j = 0; 	int k = 0; 	for(i = 0; i < 60; i ++) 	{ 		printf("输入元素值:"); 		scanf("%d", &num); 		for(j = top; j >= 0; j --)//扫描是否有以入栈的元素与之前元素相同 		{ 			if(stack[j] == num) 			{ 				break; 			} 		} 		if(0 < j || (j == 0 && stack[0] == num && top >= 0))//如果当前栈中有与输入元素相同的值，出栈 		{ 			printf("弹出内容为:"); 			for(k = top; k >= j; k --) 			{ 				printf("%d ", pop(stack, top)); 				top --; 			} 			printf("\n"); 		} 		else//否则入栈 		{ 			top ++; 			push(stack, top, num); 		} 	} }

二叉树，做这个比较好

弄得是一个单纯的.c文件。虽然感谢4楼的大哥打了一堆码，但是连表头我都不认识........

这东西我怎么回复单独的人呀........其实我想说的不是局限于只是用栈来实现，是有这么一个命题，用什么实现都行

二叉堆结合链式栈。

#include "stdafx.h" #include<iostream>   #include<stack>   using namespace std; void show_stack(stack<int> stl_stack) { 	cout << "current stack value:"; 	while (!stl_stack.empty()) { 		cout << stl_stack.top() << " "; 		stl_stack.pop(); 	} 	cout << endl; }  bool find_value_in_stack(int value ,stack<int> stl_stack, stack<int> &stl_stack_dest) { 	bool bfind = false; 	while (!stl_stack.empty()) { 		if(value == stl_stack.top()) 		{ 			stl_stack.pop(); 			bfind = true; 			break; 		} 		stl_stack.pop(); 	} 	if(bfind == true) 	{ 		stl_stack_dest = stl_stack; 	} 	return bfind; }  int main() { 	int ivalue; 	stack<int>stl_stack; 	while (true) 	{ 		cout << "input: "; 		if(stl_stack.empty()) 		{ 			cin >> ivalue; 			stl_stack.push(ivalue); 			show_stack(stl_stack); 			continue; 		} 		cin >> ivalue; 		stack<int>t_stl_stack; 		if(find_value_in_stack(ivalue, stl_stack, t_stl_stack) == true) 		{ 			stl_stack = t_stl_stack; 		} 		else 		{ 			stl_stack.push(ivalue); 		} 		show_stack(stl_stack); 	} }  栈的C实现 首先你可以自己实现  如果栈很大 建议转换成循环队列 这样直接以最底下的元素向上查找 效率会高些 且C实现采取链式存储。

你可以设置一个标记数组bool[]表示该数是否已经入栈，数组下标就是该数，所以数组可能会比较大。如果很大，确实，参考楼上的解答，换一种方法，不一定非得是栈。

和之前栈内所有元素比较的话，建议不要用栈了。要使用方便查找和删除的数据结构。


Question: 哪位大神能帮我写个程序，用遗传算法求解投资组合的最优比例。

再牛×的老师也无法代替学生自己领悟和上厕所！ 百度也无法代替楼主自己把这个代码的适应度函数改一下！

我是想把这个代码的适应度函数改一下


Question: 指针传递

如果允许Add函数改变nTmp，就写成 Add ((uint *) & nTmp); 否则就应该用 Add(& (uint) {nTmp});

uchar     gucEtherNetSocketID;   int           iRet; gucEtherNetSocketID = (uchar)iRet;   与  gucEtherNetSocketID = (uchar *)iRet; 上面两句赋值哪句是对的？能说说过程嘛？ int GetNetCSQ(struct CommStru *pCommInfo,uchar *pucRetVal) { //DEBUG_STACK if (pCommInfo==NULL || pucRetVal==NULL) { return EXCEPTION; }  return PubNetTestCSQ(pucRetVal);   //warning（int PubNetTestCSQ(int *piRetVal)） } 将上面的 return PubNetTestCSQ(pucRetVal); 直接改为 return PubNetTestCSQ((int *)pucRetVal); 这样的转变可以吗？       现在讨论这个！！！

Add((uint *)&nTmp);

可以的，楼主在转换的过程中注意变量的位数就可以了，不要在转换中被截断。例如int 转 char时由于位数不同就会被截断，导致数据错误。

第二种，  &就是取这个变量的地址

引用 楼主 afdlig 的回复:定义一个int nTmp; 现要调用一个函数void Add(uint *p); 是写成Add((uint)&nTmp);还是Add((uint *)&nTmp);这样的形式? 求解~能具体说点的  uchar     gucEtherNetSocketID;   int           iRet; gucEtherNetSocketID = (uchar)iRet;   与  gucEtherNetSocketID = (uchar *)iRet; 上面两句赋值哪句是对的？

引用 1 楼 Rewen 的回复:Add((uint *)&nTmp); 传递进去的是指针。 那么也应该是指针的格式转换。 uchar     gucEtherNetSocketID;   int           iRet; gucEtherNetSocketID = (uchar)iRet;   与  gucEtherNetSocketID = (uchar *)iRet; 上面两句赋值哪句是对的？能说说过程嘛？

你的nTmp是int类型的 那么取地址以后&nTmp就是int *类型的 要满足形参是uint *类型的，那么此时再强制转换成(uint *) 所以是Add((uint *)&nTmp);


Question: while和i++

先执行i，然后在i--

while(--i) --i     i--

i=0是跳出了循环的，但是还是要执行--


Question: 大家有没有使用过 return main();

本来就有语法错，编译通不过的。

自己也可以去掉用main函数，如果你觉得有必要的话

你倒不如问有什么好处，我可以明确的告诉你：没有

那会有什么不好的影响

这是递归 它不会像你想象那样回到最初调用它的 main 函数中，而是在当前栈上再执行一个“新的” main

堆栈剩余空间会越来越小。


Question: 关于在函数中返回一个指向数组的指针

//.1 void  function(int a[], int nCount) {     //对a[]进行操作 } //.2 int*  function(int a[], int nCount) {    int *temp = (int)malloc(sizeof(a)*nCount);    ....    return temp; }  主要是有两种情况，一是如果你是直接对传进来的数组进行操作，那么就不需要返回。 二是如果你是要返回在函数里面新建的一个数组，那么就需要用malloc去申请内存。 否则随便定义的数组出来这个函数就没有意义了。还有，记得用完malloc申请的数组记得释放内存

恩恩额，可以

请问楼主怎么解决的这个问题，我也遇到了同样的问题

为什么总有人把C++与C混为一谈，这是C语言版块，讨论什么引用啊？

函数参数本身就是数组指针，所以根本不需要返回了，因为修改后的数组，直接用传递的实参就可以。

数组引用通常需要定义函数模板 不然只能传递固定长度数组

golang can do it betterpackage main import (     "fmt"     "strconv" )  type  slice []int  func (s slice)string()string{     str := ""     for _ , v := range s{         str += strconv.Itoa(v) + " "      }     return str    }  func fucn(s slice)slice{     for k , v := range s{         s[k] = v + 1     }     return s } func main(){     data  := slice{12,45,778,6}     fmt.Println(data.string())     s := fucn(data)     fmt.Println(s.string())     fmt.Println(data.string()) }

#include <stdlib.h> #include <stdio.h>  int* arr(int a[], int count) {         a[3] = 100;         return a; }  int main(int argc, char *argv[]) {         int a[] = {2, 3, 5, 6, 20};         arr(a, 5);         printf("%d\n", a[3]); }  不知道楼主的详细意图，如果以数组为参数传入，实际上传入的就是数组指针，可以随意操作数组。

如果不想让数组退化，可以考虑传入数组的引用，在函数中进行的修改的其实就是main中的数组

如果楼主仅仅只是想改变数组中元素的值，那么在函数里直接操作修改就行了（实参和形参指向的是同一块内存区域）不需要返回数组 如果该数组是函数内创建出来的，并且想返回，那么要用malloc（不能返回生命周期结束的变量） 如果想让传递进来的数组指向一块新的内存区域，那么要传引用或者二级指针才行

int (* f ( int a []) ) [] {     return a; }

请那些喜欢将数组作为函数参数传来传去或函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或函数返回值呢？

我记得在C中不能返回一个数组，即使是用指针返回也不行，你传递进来的是数组，其实也就相当于传进来的是数组首地址，也就是一个指针，而按指针传递的变量在函数内的变化在外部也是变化的所以不用返回值，调用函数后的数组就是你操作后的数组

void array_trans(typename array[]);  直接把数组首地址传入，随意修改

数组做函数参数时，自动退化为相应的指针，函数返回数组时也是返回相应指针


Question: 《标准C语言指南》一书的问题，到底有几个对象？

李忠老师写的书,我等小辈能去评价啥?这本书刚 开始就说了,本书中的对象即变量,至于为什么这么叫自己买本看一看就知道了

3楼：

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

//extern1.c #include <stdlib.h> #include <stdio.h> int y; int others() { 	printf("extern y = %p\n", &y); }   //extern2.c #include <stdlib.h> #include <stdio.h> extern int others(); int main(int argc, char *argv[]) { 	others(); 	int x = 2;  //    D1 	printf("D1 = %p\n", &x); 	int y;  //    D2 	printf("D2 = %p\n", &y); 	{ 		int x = 2;  // D3 		printf("D3 = %p\n", &x); 		extern int y;   //D4 		printf("D4 = %p\n", &y); 		{ 			int x = 2;    //D5 			printf("D5 = %p\n", &x); 			extern int y;  //D6 			printf("D6 = %p\n", &y); 		} 	} 	return 0; }  直接上代码： 这个是说明变量作用域以及extern关键字的例子 楼主可以看到，对于x，我们每次进行了声明，最终打印出x的地址是不一样的。也就是说大括号标示了不同的作用域。 而extern关键字是告诉程序去其他模块里找extern之后的变量，使用其他模块里的那个变量。通过打印我们也可以看出，extern声明的y的地址都是另一个程序中的变量地址。因此说y的地址都一样。 建议楼主遇到问题时多敲敲代码，就容易理解了。

工作中要是这样写，肯定被领导骂死了！

这书里有好几处错误，楼上指出的是其中一处。应该是排版的问题，改成这样就好了： int x;  //    D1 int y;  //    D2 void f (void) {     int x;  // D3     extern int y;   //D4     {         int x;    //D5         extern int y;  //D6     } }


Question: 关于二叉搜索树插入算法的困惑

不要依赖调试器输出复杂数据结构！而要将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”  仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //   再供参考： 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

求大神帮忙


Question: 在WIN32控制台下，读取一张位图，并将其中的每个像素的值保存到一个矩阵中（二维数组）

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

仅供参考：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }   电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 1 楼 face_t0_sea 的回复:像素点的值只代表颜色在计算机里的对应数值表示，不是可打印字符，乱码是正常的。 那我想把那个值保存进int数组该怎么转换呢？

像素点的值只代表颜色在计算机里的对应数值表示，不是可打印字符，乱码是正常的。


Question: 求c语言高手看看，我实在不知道为什么？

node* add(int data, node* head) { node* temp = head; for(; temp->next != NULL; temp = temp->next);  // 要记录最后一个节点，不然没地方加了 temp-next = (node*)malloc(sizeof(node)); temp->next->data = data; temp->next->next = NULL; return head; }  你add函数的temp并没和原来链表连接起来

问题出在add函数里，for(; temp != NULL; temp = temp->next);这个for循环之后，temp已经是NULL了 之后再为它malloc以及赋值都是没用的，根本没有连到原来的链表上 当temp->next是NULL的时候，也就是说到了最后一个节点的时候就应该跳出for循环了 然后temp->next = (node*)malloc(sizeof(node));连上要添加的节点，然后temp后移一个节点，然后赋值  node* add(int data, node* head) { 	node* temp = head->next; 	for(; temp->next != NULL; temp = temp->next); 	temp->next = (node*)malloc(sizeof(node)); 	temp = temp->next; 	temp->data = data; 	temp->next = NULL; 	return head; }


Question: 大一新生对十字链表有些疑惑，希望大伙能帮帮我

仅供参考： 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

入门级别的，数据结构与算法分析C语言描述，但是没有完整程序，里面基本是C风格伪代码有完整程序的，C语言接口与实现，但是不是入门级别 《大话数据结构》讲得通俗易懂，且例程比较规范

引用 4 楼 SHANXI_ns 的回复:[quote=引用 3 楼 qq423399099 的回复:] [quote=引用 2 楼 SHANXI_ns 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢。数据结构学起来感觉真吃力，老师上课说的感觉和到课后做题感觉很不同，有时候一道题卡好久，有的题是真不会，一点思路没有，我就上网看别人的代码，照葫芦画瓢写个差不多，但是感觉自己能力并没有得到什么提升，，不知道这样做对不。最近感觉很迷茫，不知道自己是否选错了专业。。。[/quote] 迷茫很正常，做题觉得有点难没思路就更正常了，大部分人都经历过这个过程，从一开始学指针到数据结构里的指针指来指去 楼主你才大一。。。。如果很讨厌编程的话可以乘早找找自己的兴趣在哪方面，早点转型，如果还是对编程有兴趣的话不妨多坚持一下。 找一些编程实例的书籍，挑选一些感兴趣的例子，照着做出来并自行添加一些功能。 自己对自己提需求，然后编程实现一些小软件，比如想实现一个小软件，在开机的时候运行，从网上获取数据，显示今天的天气，显示一条笑话，显示本期双色球的中奖号码等等。然后上网查阅资料，如何实现这么一个软件，再编程实现它。 入门书:首先是两本如同《辞海》般详细的神书:The C++ Programming Language & C++ Primer,这是两本几乎完全涵盖了C++所有特性的书籍，就不做过多介绍了；另外一本同样超赞的Essensial C++,可以看做是一本C++的《新华字典》，也就是上述两本的的简化版；以上3本适合所有同学看，不管是有还是没有C基础的同学，尤其是Primer第五版，随着Moo大神的加入，将Accelerate C++的写作风格带入，呈现出了一种跟第四版完全不同的风格，另外就是C++11标准在第五版被涵盖并放在了醒目的位置，也是超赞的(>_ 进阶书:那就不得不提主席大人和他的好基友Meyers的两个著名系列:Excptional 和 Effective系列了，前者包含3本:Excptional C++, More Excptional C++和Excptional C++ Style(中文版叫C++编程剖析)，难度逐渐加深。主要是谈工程方面的细节和经验；在这个开始读这个系列之前，有必要将Effective 系列中的两本Effective C++和More Effective C++读一下，尤其是前者，可谓"C++ 程序员必读的第二本书"，这个系列是讲述编程风格的。这两个系列读完后可以看看(也可以不用看)《C++编程规范》，这可以说是上面两个系列书的总结。[/quote]不能说没兴趣，但是要实现您所说的编个小程序什么的对于现在的我来说几乎不可能，学校布置的oj都够我做好久，有时候一个晚上就只能做一道题，我想问问，对于不会的题目，看别人的代码模仿者写可行吗。。。感觉和抄袭没什么两样。。。有时候其他人的代码看懂都要好久，不过您说的是，会调试确实很重要，十分感谢。最后再问问有什么好的关于数据结构的书吗？学校的教材好简练，希望像C primer那种说的很清晰的，thx。[/quote]不好意思，能推荐本C的吗？我们上学期只学了C，寒假回家也没看C++,有点惭愧。。。麻烦了

引用 4 楼 SHANXI_ns 的回复:[quote=引用 3 楼 qq423399099 的回复:] [quote=引用 2 楼 SHANXI_ns 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢。数据结构学起来感觉真吃力，老师上课说的感觉和到课后做题感觉很不同，有时候一道题卡好久，有的题是真不会，一点思路没有，我就上网看别人的代码，照葫芦画瓢写个差不多，但是感觉自己能力并没有得到什么提升，，不知道这样做对不。最近感觉很迷茫，不知道自己是否选错了专业。。。[/quote] 迷茫很正常，做题觉得有点难没思路就更正常了，大部分人都经历过这个过程，从一开始学指针到数据结构里的指针指来指去 楼主你才大一。。。。如果很讨厌编程的话可以乘早找找自己的兴趣在哪方面，早点转型，如果还是对编程有兴趣的话不妨多坚持一下。 找一些编程实例的书籍，挑选一些感兴趣的例子，照着做出来并自行添加一些功能。 自己对自己提需求，然后编程实现一些小软件，比如想实现一个小软件，在开机的时候运行，从网上获取数据，显示今天的天气，显示一条笑话，显示本期双色球的中奖号码等等。然后上网查阅资料，如何实现这么一个软件，再编程实现它。 入门书:首先是两本如同《辞海》般详细的神书:The C++ Programming Language & C++ Primer,这是两本几乎完全涵盖了C++所有特性的书籍，就不做过多介绍了；另外一本同样超赞的Essensial C++,可以看做是一本C++的《新华字典》，也就是上述两本的的简化版；以上3本适合所有同学看，不管是有还是没有C基础的同学，尤其是Primer第五版，随着Moo大神的加入，将Accelerate C++的写作风格带入，呈现出了一种跟第四版完全不同的风格，另外就是C++11标准在第五版被涵盖并放在了醒目的位置，也是超赞的(>_ 进阶书:那就不得不提主席大人和他的好基友Meyers的两个著名系列:Excptional 和 Effective系列了，前者包含3本:Excptional C++, More Excptional C++和Excptional C++ Style(中文版叫C++编程剖析)，难度逐渐加深。主要是谈工程方面的细节和经验；在这个开始读这个系列之前，有必要将Effective 系列中的两本Effective C++和More Effective C++读一下，尤其是前者，可谓"C++ 程序员必读的第二本书"，这个系列是讲述编程风格的。这两个系列读完后可以看看(也可以不用看)《C++编程规范》，这可以说是上面两个系列书的总结。[/quote]不能说没兴趣，但是要实现您所说的编个小程序什么的对于现在的我来说几乎不可能，学校布置的oj都够我做好久，有时候一个晚上就只能做一道题，我想问问，对于不会的题目，看别人的代码模仿者写可行吗。。。感觉和抄袭没什么两样。。。有时候其他人的代码看懂都要好久，不过您说的是，会调试确实很重要，十分感谢。最后再问问有什么好的关于数据结构的书吗？学校的教材好简练，希望像C primer那种说的很清晰的，thx。[/quote] 刚学是这样的，刷OJ巩固基础还是蛮好的 很多大学都是大一下才开始学C或者C++的，毕竟学的时间短，慢慢来，多练练就好了 Adam Drozdek的c++数据结构与算法

引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 SHANXI_ns 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢。数据结构学起来感觉真吃力，老师上课说的感觉和到课后做题感觉很不同，有时候一道题卡好久，有的题是真不会，一点思路没有，我就上网看别人的代码，照葫芦画瓢写个差不多，但是感觉自己能力并没有得到什么提升，，不知道这样做对不。最近感觉很迷茫，不知道自己是否选错了专业。。。[/quote] 迷茫很正常，做题觉得有点难没思路就更正常了，大部分人都经历过这个过程，从一开始学指针到数据结构里的指针指来指去 楼主你才大一。。。。如果很讨厌编程的话可以乘早找找自己的兴趣在哪方面，早点转型，如果还是对编程有兴趣的话不妨多坚持一下。 找一些编程实例的书籍，挑选一些感兴趣的例子，照着做出来并自行添加一些功能。 自己对自己提需求，然后编程实现一些小软件，比如想实现一个小软件，在开机的时候运行，从网上获取数据，显示今天的天气，显示一条笑话，显示本期双色球的中奖号码等等。然后上网查阅资料，如何实现这么一个软件，再编程实现它。 入门书:首先是两本如同《辞海》般详细的神书:The C++ Programming Language & C++ Primer,这是两本几乎完全涵盖了C++所有特性的书籍，就不做过多介绍了；另外一本同样超赞的Essensial C++,可以看做是一本C++的《新华字典》，也就是上述两本的的简化版；以上3本适合所有同学看，不管是有还是没有C基础的同学，尤其是Primer第五版，随着Moo大神的加入，将Accelerate C++的写作风格带入，呈现出了一种跟第四版完全不同的风格，另外就是C++11标准在第五版被涵盖并放在了醒目的位置，也是超赞的(>_ 进阶书:那就不得不提主席大人和他的好基友Meyers的两个著名系列:Excptional 和 Effective系列了，前者包含3本:Excptional C++, More Excptional C++和Excptional C++ Style(中文版叫C++编程剖析)，难度逐渐加深。主要是谈工程方面的细节和经验；在这个开始读这个系列之前，有必要将Effective 系列中的两本Effective C++和More Effective C++读一下，尤其是前者，可谓"C++ 程序员必读的第二本书"，这个系列是讲述编程风格的。这两个系列读完后可以看看(也可以不用看)《C++编程规范》，这可以说是上面两个系列书的总结。[/quote]不能说没兴趣，但是要实现您所说的编个小程序什么的对于现在的我来说几乎不可能，学校布置的oj都够我做好久，有时候一个晚上就只能做一道题，我想问问，对于不会的题目，看别人的代码模仿者写可行吗。。。感觉和抄袭没什么两样。。。有时候其他人的代码看懂都要好久，不过您说的是，会调试确实很重要，十分感谢。最后再问问有什么好的关于数据结构的书吗？学校的教材好简练，希望像C primer那种说的很清晰的，thx。

引用 2 楼 SHANXI_ns 的回复:[quote=引用 1 楼 qq423399099 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢。数据结构学起来感觉真吃力，老师上课说的感觉和到课后做题感觉很不同，有时候一道题卡好久，有的题是真不会，一点思路没有，我就上网看别人的代码，照葫芦画瓢写个差不多，但是感觉自己能力并没有得到什么提升，，不知道这样做对不。最近感觉很迷茫，不知道自己是否选错了专业。。。[/quote] 迷茫很正常，做题觉得有点难没思路就更正常了，大部分人都经历过这个过程，从一开始学指针到数据结构里的指针指来指去 楼主你才大一。。。。如果很讨厌编程的话可以乘早找找自己的兴趣在哪方面，早点转型，如果还是对编程有兴趣的话不妨多坚持一下。 找一些编程实例的书籍，挑选一些感兴趣的例子，照着做出来并自行添加一些功能。 自己对自己提需求，然后编程实现一些小软件，比如想实现一个小软件，在开机的时候运行，从网上获取数据，显示今天的天气，显示一条笑话，显示本期双色球的中奖号码等等。然后上网查阅资料，如何实现这么一个软件，再编程实现它。 入门书:首先是两本如同《辞海》般详细的神书:The C++ Programming Language & C++ Primer,这是两本几乎完全涵盖了C++所有特性的书籍，就不做过多介绍了；另外一本同样超赞的Essensial C++,可以看做是一本C++的《新华字典》，也就是上述两本的的简化版；以上3本适合所有同学看，不管是有还是没有C基础的同学，尤其是Primer第五版，随着Moo大神的加入，将Accelerate C++的写作风格带入，呈现出了一种跟第四版完全不同的风格，另外就是C++11标准在第五版被涵盖并放在了醒目的位置，也是超赞的(>_ 进阶书:那就不得不提主席大人和他的好基友Meyers的两个著名系列:Excptional 和 Effective系列了，前者包含3本:Excptional C++, More Excptional C++和Excptional C++ Style(中文版叫C++编程剖析)，难度逐渐加深。主要是谈工程方面的细节和经验；在这个开始读这个系列之前，有必要将Effective 系列中的两本Effective C++和More Effective C++读一下，尤其是前者，可谓"C++ 程序员必读的第二本书"，这个系列是讲述编程风格的。这两个系列读完后可以看看(也可以不用看)《C++编程规范》，这可以说是上面两个系列书的总结。

引用 1 楼 qq423399099 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢。数据结构学起来感觉真吃力，老师上课说的感觉和到课后做题感觉很不同，有时候一道题卡好久，有的题是真不会，一点思路没有，我就上网看别人的代码，照葫芦画瓢写个差不多，但是感觉自己能力并没有得到什么提升，，不知道这样做对不。最近感觉很迷茫，不知道自己是否选错了专业。。。


Question: 请问29a是什么

世界上第一个近十年不用找总在CSDN C/C++论坛屠屏和卖萌的ID（zhao4zhong1）,他不是一个人在战斗！

我是来找赵老师身影的

two nine a

早期非常有名的研究编写病毒的组织，现在貌似不存在了。

从前的 Dos/Win16 病毒编写者，几个病毒家族的作者包括Ginger和Rainbow,世界上第一个使用循环分区技巧的联合病毒作者（Orsam），世界上第一个XMS(扩展内存）交换病毒的发明者（John Galt），世界上第一个使用线程局部存储用作复制的病毒作者（Shrug），世界上第一个使用Visual Bisic 5/6 语言扩展用作复制的病毒的作者（OU812),世界上第一个本地可执行的病毒的作者（Chthon)，世界上第一个使用进程相互协作防止被中止的病毒的作者（Gemini），世界上第一个使用多态SMTP报头的病毒的作者（JunkMail），世界上第一个能转换任何数据文件到感染对象的病毒的作者（Pretext)，世界上第一个32/64位寄生EPO .NET病毒的作者（Croissant），世界上第一个使用自身执行的HTML病毒的作者（JunktmaiL），世界上第一个能吹的病毒制造者(zhangyu),他们组成了29A这个世界知名的病毒制造机构。 编写了世界首例手机之间传播的病毒“卡比尔”。

引用 4 楼 zhao4zhong1 的回复:[quote=引用 3 楼 zhulei1978 的回复:] [quote=引用 1 楼 Intel0011 的回复:] 早期非常有名的研究编写病毒的组织，现在貌似不存在了。  你有他们的资料吗[/quote] 试试去掘他们的墓。[/quote]

“卡比尔”制造者

引用 3 楼 zhulei1978 的回复:[quote=引用 1 楼 Intel0011 的回复:] 早期非常有名的研究编写病毒的组织，现在貌似不存在了。  你有他们的资料吗[/quote] 试试去掘他们的墓。

引用 1 楼 Intel0011 的回复:早期非常有名的研究编写病毒的组织，现在貌似不存在了。  你有他们的资料吗


Question: 新人学习C，求教一下这个小题

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

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

#include<stdio.h> int main() {         int a,b;         float c,d,e;         printf("input a,b:\n");         scanf("%d %d", &a, &b);         c = a * b;         d = c * 0.08;         e = c - d;         printf("c = %.2f, d = %.2f, e = %.2f\n", c, d, e);         return 0; }  楼主有几个地方错了， 1、main函数的小括号和中括号之间是不能有printf的。 2、scanf两个变量之间要用逗号分隔，并且传入的参数为引用。 3、return 0;中间要有空格。 4、计算浮点数不要用int，要用float。

#include<stdio.h> int main() {     int a,b;     double c,d,e;     printf("please input a b:");     scanf("%d %d",&a,&b);     c=a*b;     d=c*0.08;     e=c-d;    printf("c d e,%f,%f,%f\n",c,d,e);    return 0; }

还有删除第三行的printf return0;之间要有个空格return 0;

scanf("%d %d",&a,&b);


Question: c语言   停车场   求大神改一下

#include<iostream> using namespace std;   typedef struct time {     int hour;     int min; }Time;  typedef struct CarNode {     char CarNumber[10];     Time reach;     Time leave; }StackElementType, QueueElementType;   typedef struct Node {     struct CarNode *data;     struct Node *next; }LinkQueueNode;   class Queue { private:     LinkQueueNode *front;     LinkQueueNode *rear; public:     Queue() 	{ 		front = new LinkQueueNode ;         if (front != NULL) 		{ 			rear = front;             front->next = NULL; 		} 	} 	struct CarNode *getdata() 	{ 		return front->next->data; 	} 	LinkQueueNode *getfront() 	{ 		return front; 	} 	LinkQueueNode *getrear() 	{ 		return rear; 	} 	       void EnterQueue(QueueElementType *x) 	{ 		LinkQueueNode * NewNode;         NewNode = new LinkQueueNode ;         if (NewNode != NULL) 		{ 			NewNode->data = x;             NewNode->next = NULL;             rear->next = NewNode;             rear=NewNode; 		} 	}       void DeleteQueue(QueueElementType *x) 	{ 		LinkQueueNode *p;         p= front->next;         front->next = p->next;         if (rear == p)            rear =front;         x = p->data;         delete p; 	}     void Printf() 	{ 		LinkQueueNode *q;         q=front->next;         if (front !=rear) 		{ 			while (q != NULL) 			{ 				cout<<q->data->CarNumber;                 q=q->next; 			} 		} 	} };  class Stack { private:     StackElementType car[2];     int top; public:     Stack() 	{ 		top = -1; 	} 	int gettop() 	{ 		return top; 	}       void Push(StackElementType *x)       	{ 		top++;         car[top] = *x; 	}       void Pop(StackElementType *x)   	{ 		*x=car[top];         top--; 	}     void Printf() 	{          for (int i=0; i<=top; i++) 		 { 			 cout<<i+1;              cout<<car[i].CarNumber<<"\t\t\t\t"<<car[i].reach.hour<<":"<<car[i].reach.min; 		 } 	} };  void PRINT(struct CarNode *p) {   int A1, A2, B1, B2,f;     cout<<"\n请输入离开时间:/**:**/";     cin>>p->leave.hour>>p->leave.min;     cout<<"\n离开车辆:";     cout<<p->CarNumber<<"\n";     cout<<p->reach.hour<<":"<<p->reach.min<<endl;     cout<<p->leave.hour<<":"<<p->leave.min<<endl;     A1 = p->reach.hour;     A2 = p->reach.min;     B1 = p->leave.hour;     B2 = p->leave.min;     f=((B1 - A1) + (B2 - A2)/60)*5; 	cout<<"费用:"<<f<<endl; }        int main(void) {     int ch;     Stack enter;      Stack temp;      Queue wait;      while (1)     {         cout<<" 1. 车辆到达\n";         cout<<" 2. 车辆离开\n";         cout<<" 3. 列表显示\n";         cout<<" 4. 退出系统\n";           while (1)         {             cin>>ch;             if (ch >= 1 && ch <= 4)             {                 break;             }             else                  cout<<"\n please choose a number";         }         switch (ch)         {         case 1:            {     if (enter.gettop()!=1)     {         cout<<"请输入车辆牌照和进入时间:\n";         struct CarNode *p;         p = new CarNode;         cin>>p->CarNumber>>p->reach.hour>>p->reach.min;         enter.Push(p);         cout<<"车已入停车场\n";     }     else     {         cout<<"停车场已满,请入便道";         cout<<"请输入车辆牌照\n";         QueueElementType *a;         a =new QueueElementType;         cin>>a->CarNumber;         wait. EnterQueue(a);         cout<<"车已入便道\n";     }             } 		   break;          case 2: 			{  StackElementType z;  int room;     if (enter.gettop()>=0)     { 		cout<<"请输入车在车场的位置/1--";         cout<<enter.gettop()+1<<"/:";         cin>>room;         room--;         while (1)         {             if (enter.gettop()>room)             {                 enter.Pop( &z);                 temp.Push( &z);             }             else                 break;         }         enter.Pop(&z);         PRINT(&z);         while (1)         {             if (temp.gettop ()!= -1)             {                 temp.Pop( &z);                 enter.Push(&z);             }             else                 break;         }         if ((wait.getfront ()!= wait.getrear()) && enter.gettop() <=1)          {             struct CarNode *b;             b =new struct CarNode;             b = wait.getdata();             cout<<"\n请输入现在的时间/**:**/:";             cin>>b->reach.hour>>b->reach.min;             wait.DeleteQueue( b);            enter. Push(b);              cout<<"便道的第";             cout<<b->CarNumber<<"号车进入车场第"<<enter.gettop ()+ 1<<"位置.\n";         }         else             cout<<"\n便道里没有车\n";     }     else         cout<<"停车场里没车\n"; 			}  			break;          case 3: 			{ 				enter.Printf(); 				wait.Printf(); 			}             break;          case 4: break;          default: break;         }     }     return 0; }

#include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <time.h>   #define FALSE -1 #define TRUE 1 #define Money 5 #define PARK 4 #define SHORCUT 5         typedef struct time {     int hour;     int min; }Time;   typedef struct CarNode {     char CarNumber[10];     Time reach;     Time leave; }StackElementType, QueueElementType;     typedef struct ZHAN {     StackElementType CarNode[2];     int top; }SeqStack;   typedef struct Node {     struct CarNode *data;     struct Node *next; }LinkQueueNode;   typedef struct ZIZE {     LinkQueueNode *front;     LinkQueueNode *rear; }LinkQueue;   void Pop(SeqStack *S, StackElementType *x); void Push(SeqStack *S,struct CarNode *x); void EnterQueue(LinkQueue *Q, QueueElementType *x); void DeleteQueue(LinkQueue * Q, QueueElementType *x); void PRINT(struct CarNode *p);   void InitStack(SeqStack *S) {     S->top = -1; }   int InitQueue(LinkQueue *Q) {     Q->front = (LinkQueueNode *)malloc(sizeof (LinkQueueNode));     if (Q->front != NULL)     {         Q->rear = Q->front;         Q->front->next = NULL;         return(TRUE);     }     else         return(FALSE); }     int getInTo(SeqStack *S, LinkQueue *Q) {     if (S->top !=1)     {         struct CarNode *p;  		printf("请输入车辆牌照和进入时间\n");         p = (struct CarNode *)malloc(sizeof(struct CarNode));         scanf("%s %d:%d", p->CarNumber, &p->reach.hour, &p->reach.min);getchar();         Push(S, p);         return PARK;     }     else     {  		QueueElementType *a;         printf("停车场已满,请入便道");         printf("请输入车辆牌照\n");         a = (QueueElementType *)malloc(sizeof(QueueElementType));         scanf("%s", a->CarNumber);getchar();         EnterQueue(Q, a);         return SHORCUT;     } }   void EnterQueue(LinkQueue *Q, QueueElementType *x) {     LinkQueueNode * NewNode;     NewNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));     if (NewNode != NULL)     {         NewNode->data = x;         NewNode->next = NULL;         Q->rear->next = NewNode;         Q->rear = NewNode;     } }   void DeleteQueue(LinkQueue * Q, QueueElementType *x) {     LinkQueueNode *p;     p = Q->front->next;     Q->front->next = p->next;     if (Q->rear == p)         Q->rear = Q->front;     x = p->data;     free(p); }   void Push(SeqStack *S, struct CarNode *x)       {     S->top++;     S->CarNode[S->top] = *x; }   void Pop(SeqStack *S, StackElementType *x)    {     *x = S->CarNode[S->top];     S->top--; }       void Printf(LinkQueue *Q, SeqStack *S) { 	int i; 	LinkQueueNode *q;     printf("首先输出停车场信息:n");     printf("位置\t\t车牌号\t\t\t\t进入时间\n");     for (i=0; i<=S->top; i++)     {         printf("%d\t\t", i+1);         printf("%s", S->CarNode[i].CarNumber);         printf("\t\t\t\t");         printf("%d:%d\n", S->CarNode[i].reach.hour, S->CarNode[i].reach.min);     }     q = Q->front->next;     if (Q->front != Q->rear) //判断通道上是否有车     {         printf("\n等待车辆的号码为:\n");         printf("输出便道信息:\n");         while (q != NULL)         {             puts(q->data->CarNumber);             q = q->next;         }     }     else printf("\n便道里没有车\n"); }       void Leave(LinkQueue *Q, SeqStack *Enter, SeqStack *Temp) {     StackElementType z;     if (Enter->top>=0)     {  		int room;         printf("请输入车在车场的位置/1--%d/:", Enter->top+1);         scanf("%d", &room);getchar();         room--;         printf("Enter->top:%d\n",Enter->top);         while (1)         {             if (Enter->top>room)             {                 Pop(Enter, &z);//2号车离开Enter                 Push(Temp, &z);//2号车进入Temp             }             else                 break;         }         Pop(Enter,&z);//1号车离开Enter         PRINT(&z);         while (1)         {             if (Temp->top != -1)//进入Temp的车重新进入Enter             {                 Pop(Temp, &z);                 Push(Enter, &z);             }             else                 break;         }         /*判断通道上是否有车及车站是否已满*/         if ((Q->front != Q->rear) && Enter->top <=1) /*便道的车辆进入车场*/         {             struct CarNode *b;             b = (struct CarNode *)malloc(sizeof(struct CarNode));             b = Q->front->next->data;             printf("\n请输入现在的时间/**:**/:");             scanf("%d:%d", &b->reach.hour, &b->reach.min);getchar();             DeleteQueue(Q, b);             Push(Enter, b);                           printf("\n便道的第%s号车进入车场第%d位置.\n",b->CarNumber, Enter->top + 1);         }         else             printf("\n便道里没有车.\n");     }     else         printf("车站里没车\n"); }     void PRINT(struct CarNode *p) /*打印出站车的信息*/ {     int A1, A2, B1, B2;     printf("\n请输入离开的时间:/**:**/");     scanf("%d:%d", &(p->leave.hour), &(p->leave.min));getchar();     printf("\n离开车辆的车牌号为:");     puts(p->CarNumber);     printf("\n其到达时间为: %d:%d\n", p->reach.hour, p->reach.min);     printf("离开时间为:%d:%d\n", p->leave.hour, p->leave.min);     A1 = p->reach.hour;     A2 = p->reach.min;     B1 = p->leave.hour;     B2 = p->leave.min;     printf("\n应交费用为: %2d元\n", ((B1 - A1) + (B2 - A2)/60)*Money); }   int main(void) {     SeqStack Enter, Temp;     LinkQueue Wait;     int ch;     InitStack(&Enter); /*初始化车站*/     InitStack(&Temp); /*初始化让路的临时栈*/     InitQueue(&Wait); /*初始化通道*/     while (1)     {         printf(" 1. 车辆到达\n");         printf(" 2. 车辆离开\n");         printf(" 3. 列表显示\n");         printf(" 4. 退出系统\n");           while (1)         {             scanf("%d", &ch);getchar();             if (ch >= 1 && ch <= 4)             {                 break;             }             else                  printf("\n please choose a number");         }         switch (ch)         {         case 1:            {             int a = getInTo(&Enter, &Wait);             if (a == PARK)                 printf("车已存入停车场\n");             else                 printf("车已入便道\n");            }break; /*车辆到达*/         case 2:Leave(&Wait, &Enter, &Temp); break; /*车辆离开*/         case 3:Printf(&Wait, &Enter); break; /*列表打印信息*/         case 4:exit(0); break; /*退出主程序*/         default: break;         }     }     return 0; }

这么热闹？希望有一天我也能和大家一起参与讨论。。。

引用 13 楼 kingofblack 的回复:小灸舞    赵4老师     感谢两位   调试时出现一些问题 ：  如  1. 在离开函数调用完后，vs提示遇到一个断点，但我并没有设置断点  2. 还有单句调试时 遇到printf这类的函数 会跳入头文件中 这个要怎么解决 1.这个问题，根据经验，一般都是空指针野指针的问题，或者是有线程在程序退出的时候没有结束掉引起的 2.用F10应该不会出现这个问题吧？F11会跳入函数

谢谢各位帮助   问题已经解决  这是改完的代码 #include <stdio.h> #include <tchar.h> #include <stdlib.h> #include <time.h>  #define FALSE -1 #define TRUE 1 #define Stack_Size 2  #define Money 5 #define PARK 4 #define SHORCUT 5     typedef struct time { 	int hour; 	int min; }Time;  typedef struct CarNode { 	char CarNumber[10]; 	Time reach; 	Time leave; }StackElementType, QueueElementType;   typedef struct ZHAN { 	StackElementType CarNode[Stack_Size]; 	int top; }SeqStack;  typedef struct Node { 	CarNode *data; 	struct Node *next; }LinkQueueNode;  typedef struct ZIZE { 	LinkQueueNode *front; 	LinkQueueNode *rear; }LinkQueue;  void Pop(SeqStack *S, StackElementType *x); void Push(SeqStack *S, CarNode *x); void EnterQueue(LinkQueue *Q, QueueElementType *x); void DeleteQueue(LinkQueue * Q, QueueElementType *x); void PRINT(CarNode *p);  void InitStack(SeqStack *S) { 	S->top = -1; }  int InitQueue(LinkQueue *Q) { 	Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if (Q->front != NULL) 	{ 		Q->rear = Q->front; 		Q->front->next = NULL; 		return(TRUE); 	} 	else 		return(FALSE); }   int getInTo(SeqStack *S, LinkQueue *Q) { 	if (S->top != Stack_Size - 1) 	{ 		printf("请输入车辆牌照和进入时间\n"); 		CarNode *p; 		p = (CarNode *)malloc(sizeof(CarNode)); 		scanf("%s %d:%d", p->CarNumber, &p->reach.hour, &p->reach.min); 		Push(S, p); 		return PARK; 	} 	else 	{ 		printf("停车场已满，请入便道\n"); 		printf("请输入车辆牌照\n"); 		QueueElementType *a; 		a = (QueueElementType *)malloc(sizeof(QueueElementType)); 		scanf("%s", a->CarNumber); 		EnterQueue(Q, a); 		return SHORCUT; 	} }  void EnterQueue(LinkQueue *Q, QueueElementType *x) { 	LinkQueueNode * NewNode; 	NewNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if (NewNode != NULL) 	{ 		NewNode->data = x; 		NewNode->next = NULL; 		Q->rear->next = NewNode; 		Q->rear = NewNode; 	} }  void GetHead(LinkQueue *Q, QueueElementType *x) { 	LinkQueueNode *p; 	p = Q->front->next; 	x = p->data; }  void DeleteQueue(LinkQueue * Q, QueueElementType *x) { 	LinkQueueNode *p; 	p = Q->front->next; 	Q->front->next = p->next; 	if (Q->rear == p) 		Q->rear = Q->front; 	x = p->data; 	free(p); }  void Push(SeqStack *S, CarNode *x)      //入栈  { 	S->top++; 	S->CarNode[S->top] = *x; }  void Pop(SeqStack *S, StackElementType *x)   //出栈 { 	*x = S->CarNode[S->top]; 	S->top--; }    void Printf(LinkQueue *Q, SeqStack *S) { 	printf("首先输出停车场信息:\n"); 	printf("位置\t\t车牌号\t\t\t\t进入时间\n"); 	for (int i=0; i<=S->top; i++) 	{ 		printf("%d\t\t", i+1); 		printf("%s", S->CarNode[i].CarNumber); 		printf("\t\t\t\t"); 		printf("%d:%d\n", S->CarNode[i].reach.hour, S->CarNode[i].reach.min); 	} 	LinkQueueNode *q; 	q = Q->front->next; 	if (Q->front != Q->rear) //判断通道上是否有车 	{ 		printf("\n等待车辆的号码为:\n"); 		printf("输出便道信息:\n"); 		while (q != NULL) 		{ 			puts(q->data->CarNumber); 			q = q->next; 		} 	} 	else printf("\n便道里没有车.\n"); }    void Leave(LinkQueue *Q, SeqStack *Enter, SeqStack *Temp) { 	StackElementType z; 	if (Enter->top>=0) 	{ 		printf("请输入车在车场的位置/1--%d/：", Enter->top+1); 		int room; 		scanf("%d", &room); 		room--; 		while (1) 		{ 			if (Enter->top>room) 			{ 				Pop(Enter, &z); 				Push(Temp, &z); 			} 			else 				break; 		} 		Pop(Enter,&z); 		PRINT(&z); 		while (1) 		{ 			if (Temp->top != -1) 			{ 				Pop(Temp, &z); 				Push(Enter, &z); 			} 			else 				break; 		} 		/*判断通道上是否有车及车站是否已满*/ 		if ((Q->front != Q->rear) && Enter->top <= Stack_Size - 1) /*便道的车辆进入车场*/ 		{ 			CarNode *b; 			b = (CarNode *)malloc(sizeof(CarNode)); 			b = Q->front->next->data; 			printf("\n请输入现在的时间/**:**/:"); 			scanf("%d:%d", &b->reach.hour, &b->reach.min); 			DeleteQueue(Q, b); 			Push(Enter, b); 			 			printf("\n便道的第%s号车进入车场第%d位置.\n",b->CarNumber, Enter->top + 1); 		} 		else 			printf("\n便道里没有车.\n"); 	} 	else 		printf("车站里没车\n"); }   void PRINT(CarNode *p) /*打印出站车的信息*/ { 	int A1, A2, B1, B2; 	printf("\n请输入离开的时间:/**:**/"); 	scanf("%d:%d", &(p->leave.hour), &(p->leave.min)); 	printf("\n离开车辆的车牌号为:"); 	puts(p->CarNumber); 	printf("\n其到达时间为: %d:%d\n", p->reach.hour, p->reach.min); 	printf("离开时间为: %d:%d\n", p->leave.hour, p->leave.min); 	A1 = p->reach.hour; 	A2 = p->reach.min; 	B1 = p->leave.hour; 	B2 = p->leave.min; 	printf("\n应交费用为: %2d元\n", ((B1 - A1) + (B2 - A2)/60)*Money); }  int main(void) { 	SeqStack Enter, Temp; 	LinkQueue Wait; 	int ch; 	InitStack(&Enter); /*初始化车站*/ 	InitStack(&Temp); /*初始化让路的临时栈*/ 	InitQueue(&Wait); /*初始化通道*/ 	while (1) 	{ 		printf(" 1. 车辆到达\n"); 		printf(" 2. 车辆离开\n"); 		printf(" 3. 列表显示\n"); 		printf(" 4. 退出系统\n");  		while (1) 		{ 			scanf("%d", &ch); 			if (ch >= 1 && ch <= 4) 			{ 				break; 			} 			else  				printf("\n please choose a number"); 		} 		switch (ch) 		{ 		case 1: 		   { 			int a = getInTo(&Enter, &Wait); 			if (a == PARK) 				printf("车已存入停车场\n"); 			else 				printf("车已入便道\n"); 		   }break; /*车辆到达*/ 		case 2:Leave(&Wait, &Enter, &Temp); break; /*车辆离开*/ 		case 3:Printf(&Wait, &Enter); break; /*列表打印信息*/ 		case 4:exit(0); break; /*退出主程序*/ 		default: break; 		} 	} 	return 0; }

帮楼主又调试了下发现Pop函数有问题，这样是拿不到值的 改成如下才行：  void Pop(SeqStack *S, StackElementType *x)   //出栈 {     *x = *(S->CarNode[S->top]);     S->top--; }  PS：这个问题解决了还有之后的问题，楼主自己再调试下哈，用单步看每个变量的值然后就知道问题在哪了

引用 9 楼 qq423399099 的回复:[quote=引用 8 楼 kingofblack 的回复:] [quote=引用 7 楼 qq423399099 的回复:] [quote=引用 6 楼 kingofblack 的回复:] 最关键的是 主函数while没有循环    帮楼主稍微调试了下发现 getInTo函数里scanf_s("%s %d:%d", &p->CarNumber, &p->reach.hour, &p->reach.min);有问题 首先scanf_s如果要读入字符串的话，要多传一个值比较接收字符串的长度，不传这个值的话会出问题 其次p->CarNumber也用不着取地址 改为如下就好了： scanf_s("%s %d:%d", p->CarNumber, 10, &p->reach.hour, &p->reach.min);[/quote] 又出现新的问题了 调试时 出现 0x01201DC4 处(位于 park.exe 中)引发的异常: 0xC0000005: 读取位置 0xCCCCCCDC 时发生访问冲突。 这些问题具体是什么意思呢？[/quote] 都是指针的不规范操作造成，比如越界，未初始化，对NULL指针操作等等[/quote]   谢谢答疑  typedef struct time { 	int hour; 	int min; }Time;  typedef struct CarNode { 	char CarNumber[10]; 	Time reach; 	Time leave; }StackElementType, QueueElementType;   typedef struct ZHAN { 	StackElementType *CarNode[Stack_Size]; 	int top; }SeqStack;  typedef struct Node { 	CarNode *data; 	struct Node *next; }LinkQueueNode;  typedef struct ZIZE { 	LinkQueueNode *front; 	LinkQueueNode *rear; }LinkQueue;  void Pop(SeqStack *S, StackElementType *x); void Push(SeqStack *S, CarNode *x); void EnterQueue(LinkQueue *Q, QueueElementType *x); void DeleteQueue(LinkQueue * Q, QueueElementType *x); void PRINT(CarNode *p);  void InitStack(SeqStack *S) { 	S->top = -1; }  int InitQueue(LinkQueue *Q) { 	Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if (Q->front != NULL) 	{ 		Q->rear = Q->front; 		Q->front->next = NULL; 		return(TRUE); 	} 	else 		return(FALSE); }   int getInTo(SeqStack *S, LinkQueue *Q) { 	if (S->top != Stack_Size - 1) 	{ 		printf("请输入车辆牌照和进入时间\n"); 		CarNode *p; 		p = (CarNode *)malloc(sizeof(CarNode)); 		scanf_s("%s %d:%d", p->CarNumber, 10, &p->reach.hour, &p->reach.min); 		Push(S, p); 		return PARK; 	} 	else 	{ 		printf("停车场已满，请入便道\n"); 		printf("请输入车辆牌照\n"); 		QueueElementType t; 		scanf_s("%s", t.CarNumber, 10); 		EnterQueue(Q, &t); 		return SHORCUT; 	} }  void EnterQueue(LinkQueue *Q, QueueElementType *x) { 	LinkQueueNode * NewNode; 	NewNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if (NewNode != NULL) 	{ 		NewNode->data = x; 		NewNode->next = NULL; 		Q->rear->next = NewNode; 		Q->rear = NewNode; 	} }  void DeleteQueue(LinkQueue * Q, QueueElementType *x) { 	LinkQueueNode *p; 	p = Q->front->next; 	Q->front->next = p->next; 	if (Q->rear == p) 		Q->rear = Q->front; 	x = p->data; 	free(p); }  void Push(SeqStack *S, CarNode *x)      //入栈  { 	S->top++; 	S->CarNode[S->top] = x; }  void Pop(SeqStack *S, StackElementType *x)   //出栈 { 	x = S->CarNode[S->top]; 	S->top--;  }    void Printf(LinkQueue *Q, SeqStack *S) { 	printf("首先输出停车场信息:\n"); 	printf("位置\t\t车牌号\t\t\t\t进入时间\n"); 	for (int i=0; i<=S->top; i++) 	{ 		printf("%d\t\t", i+1); 		printf("%s", S->CarNode[i]->CarNumber); 		printf("\t\t\t\t"); 		printf("%d:%d\n", S->CarNode[i]->reach.hour, S->CarNode[i]->reach.min); 	} 	LinkQueueNode *q; 	q = Q->front->next; 	if (Q->front != Q->rear) //判断通道上是否有车 	{ 		printf("\n等待车辆的号码为:\n"); 		printf("输出便道信息:\n"); 		while (q != NULL) 		{ 			puts(q->data->CarNumber); 			q = q->next; 		} 	} 	else printf("\n便道里没有车.\n"); }  void Leave(LinkQueue *Q, SeqStack *Enter, SeqStack *Temp) { 	CarNode *t; 	if (Enter->top>=0) 	{ 		printf("请输入车在车场的位置/1--%d/：", Enter->top+1); 		int room; 		StackElementType x; 		scanf_s("%d", &room); 		while (1) 		{ 			if (Enter->top>room) 			{ 				Pop(Enter, &x); 				Push(Temp, &x); 			} 			else 				break; 		} 		Pop(Enter, &x); 		PRINT(&x); 		while (1) 		{ 			if (Temp->top != -1) 			{ 				Pop(Temp, &x); 				Push(Enter, &x); 			} 			else 				break; 		} 		/*判断通道上是否有车及车站是否已满*/ 		if ((Q->front != Q->rear) && Enter->top <= Stack_Size - 1) /*便道的车辆进入车场*/ 		{ 			t = Q->front->data; 			printf("\n便道的%s号车进入车场第%d位置.", t->CarNumber, Enter->top + 1); 			printf("\n请输入现在的时间/**:**/:"); 			scanf_s("%d:%d", &(t->reach.hour), &(t->reach.min)); 			EnterQueue(Q, t); 		} 		else 			printf("\n便道里没有车.\n"); 	} 	else 		printf("车站里没车\n"); }   void PRINT(CarNode *p) /*打印出站车的信息*/ { 	int A1, A2, B1, B2; 	printf("\n请输入离开的时间:/**:**/"); 	scanf_s("%d:%d", &(p->leave.hour), &(p->leave.min)); 	printf("\n离开车辆的车牌号为:"); 	puts(p->CarNumber); 	printf("\n其到达时间为: %d:%d\n", p->reach.hour, p->reach.min); 	printf("离开时间为: %d:%d\n", p->leave.hour, p->leave.min); 	A1 = p->reach.hour; 	A2 = p->reach.min; 	B1 = p->leave.hour; 	B2 = p->leave.min; 	printf("\n应交费用为: %2d元\n", ((B1 - A1) * 60 + (B2 - A2))*Money); 	free(p); }  int main(void) { 	SeqStack Enter, Temp; 	LinkQueue Wait; 	int ch; 	InitStack(&Enter); /*初始化车站*/ 	InitStack(&Temp); /*初始化让路的临时栈*/ 	InitQueue(&Wait); /*初始化通道*/ 	while (1) 	{ 		printf(" 1. 车辆到达\n"); 		printf(" 2. 车辆离开\n"); 		printf(" 3. 列表显示\n"); 		printf(" 4. 退出系统\n");  		while (1) 		{ 			scanf_s("%d", &ch); 			if (ch >= 1 && ch <= 4) 			{ 				break; 			} 			else  				printf("\n please choose a number"); 		} 		switch (ch) 		{ 		case 1: 		   { 			int a = getInTo(&Enter, &Wait); 			if (a == PARK) 				printf("车已存入停车场\n"); 			else 				printf("车已入便道\n"); 		   }break; /*车辆到达*/ 		case 2:Leave(&Wait, &Enter, &Temp); break; /*车辆离开*/ 		case 3:Printf(&Wait, &Enter); break; /*列表打印信息*/ 		case 4:exit(0); break; /*退出主程序*/ 		default: break; 		} 	} 	return 0; }  又出现问题  调试也搞不清楚，只要一输出就会变，完全不知道原因啊

引用 8 楼 kingofblack 的回复:[quote=引用 7 楼 qq423399099 的回复:] [quote=引用 6 楼 kingofblack 的回复:] 最关键的是 主函数while没有循环    帮楼主稍微调试了下发现 getInTo函数里scanf_s("%s %d:%d", &p->CarNumber, &p->reach.hour, &p->reach.min);有问题 首先scanf_s如果要读入字符串的话，要多传一个值比较接收字符串的长度，不传这个值的话会出问题 其次p->CarNumber也用不着取地址 改为如下就好了： scanf_s("%s %d:%d", p->CarNumber, 10, &p->reach.hour, &p->reach.min);[/quote] 又出现新的问题了 调试时 出现 0x01201DC4 处(位于 park.exe 中)引发的异常: 0xC0000005: 读取位置 0xCCCCCCDC 时发生访问冲突。 这些问题具体是什么意思呢？[/quote] 都是指针的不规范操作造成，比如越界，未初始化，对NULL指针操作等等

1.这个叫异常断点，和你设置的断点不是一回事。 2.我当此时就按Shift+F11键。

引用 12 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 被幽默会死人吗？  “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\advapi32.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\msvcrt.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\sechost.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\rpcrt4.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\sspicli.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\cryptbase.dll”。无法查找或打开 PDB 文件。 “park.exe”(Win32): 已加载“C:\Windows\SysWOW64\bcryptprimitives.dll”。无法查找或打开 PDB 文件。 HEAP[park.exe]: Invalid address specified to RtlValidateHeap( 00B90000, 0018F7DC ) park.exe 已触发了一个断点。    用vs2015调试时遇到的问题  ，但我并未设置断点

引用 7 楼 qq423399099 的回复:[quote=引用 6 楼 kingofblack 的回复:] 最关键的是 主函数while没有循环    帮楼主稍微调试了下发现 getInTo函数里scanf_s("%s %d:%d", &p->CarNumber, &p->reach.hour, &p->reach.min);有问题 首先scanf_s如果要读入字符串的话，要多传一个值比较接收字符串的长度，不传这个值的话会出问题 其次p->CarNumber也用不着取地址 改为如下就好了： scanf_s("%s %d:%d", p->CarNumber, 10, &p->reach.hour, &p->reach.min);[/quote] 又出现新的问题了 调试时 出现 0x01201DC4 处(位于 park.exe 中)引发的异常: 0xC0000005: 读取位置 0xCCCCCCDC 时发生访问冲突。 这些问题具体是什么意思呢？

引用 6 楼 kingofblack 的回复:最关键的是 主函数while没有循环    帮楼主稍微调试了下发现 getInTo函数里scanf_s("%s %d:%d", &p->CarNumber, &p->reach.hour, &p->reach.min);有问题 首先scanf_s如果要读入字符串的话，要多传一个值比较接收字符串的长度，不传这个值的话会出问题 其次p->CarNumber也用不着取地址 改为如下就好了： scanf_s("%s %d:%d", p->CarNumber, 10, &p->reach.hour, &p->reach.min);

最关键的是 主函数while没有循环

引用 2 楼 qq423399099 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 0x53B3E224 (ucrtbased.dll)处(位于 park.exe 中)引发的异常: 0xC0000005: 写入位置 0x007F3000 时发生访问冲突  调试尽是这些错误，这是输入进入车辆信息时的错误       我新手啊 搞不懂这些

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

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

设停车场是一个可停放n辆汽车的狭长通道,且只有有个大门可供汽车进出.  汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列  (大门在最南端,最先到达的第一辆车停放在车场的最北端),  若车场内一停满n辆汽车,则后来的汽车只能在门外的便道上等候,  一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,  在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,  其他车辆再按原次序进入车场,每辆停放在车场内的车在它离开时必须按它停留时间长短交纳费用.  试为停车场编制按上述要求进行管理的模拟程序.  基本要求:  以堆栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理.  每一组输入数据包括三个数据项:汽车"到达"或"离开"信息,汽车牌照号码以及汽车在停车场内或便道上的停车位置;  若是车辆离去,则输出汽车在停车场内停留时间和应交纳的费用(在便道上停留的时间不收费).  堆栈一顺序结构实现,队列以链表结构实现.   这是原问题


Question: 请教一下VS提示已触发一个断点是什么意思

我在调试的时候是因为给队列足够的空间，使用在调试完之后出现“以出发一个断点错误“，你可以看一下你的是不是这样的

// //  Dijkstra.c //  suanfa // //  Created by 12306wifi on 2017/12/20. //  Copyright © 2017年 12306wifi. All rights reserved. //  #include "Dijkstra.h" void Dijkstra(int linkMatrix[][MaxV], int lowLR[MaxV], int numV, int beginV){     int i,j,newcost,min,selectV;     int pre[MaxV],visited[MaxV];     visited[beginV]=1;     for(i=0;i<numV;i++){         lowLR[i]=linkMatrix[beginV][i];         pre[i]=beginV;     }     lowLR[beginV]=0;     pre[beginV]=-1;     selectV=beginV;     for(i=0;i<numV;i++){         for(j=0;j<numV;j++){             newcost=lowLR[selectV]+linkMatrix[selectV][j];             if(newcost<lowLR[j]&&visited[j]==0){                 lowLR[j]=newcost;                 pre[j]=selectV;             }         }         min=INF;         for(j=0;j<numV;j++){             if(visited[j]==0&&lowLR[j]<INF){                 min=lowLR[j];                 selectV=j;             }         }         visited[selectV]=1;a      }

引用 7 楼 qq_33660269 的回复: 你的h指针是NULL吧？

因为你的creat函数最后忘了返回一个值了  另外，add函数里return 0;改成return 因为函数返回类型是void

帮我找一下哪里出错了谢谢我真的找不到了

能不能帮我看看代码 哪里出错了

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

那你看断点处提示的是什么错误啊，比如越界比如不能为空等等。  你断点处的哪个函数是从哪个函数里面调用（包括间接调用） 就是你代码里面那个函数的某个参数对于它来说不合法。  还有一种方法就是注释掉某段代码某行代码来定位错误点。


Question: 萌新求问生成BMP图像的程序问题。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  仅供参考：#include <math.h> #include <string.h> #include <stdio.h> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; wchar_t formats[5][11]={     L"image/bmp",     L"image/jpeg",     L"image/gif",     L"image/tiff",     L"image/png", }; wchar_t exts[5][5]={     L".bmp",     L".jpg",     L".gif",     L".tif",     L".png", }; int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {    UINT  num = 0;          // number of image encoders    UINT  size = 0;         // size of the image encoder array in bytes    ImageCodecInfo* pImageCodecInfo = NULL;    GetImageEncodersSize(&num, &size);    if(size == 0) return -1;  // Failure    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));    if(pImageCodecInfo == NULL) return -1;  // Failure    GetImageEncoders(num, size, pImageCodecInfo);    for (UINT j = 0; j < num; ++j) {       if ( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) {          *pClsid = pImageCodecInfo[j].Clsid;          free(pImageCodecInfo);          return j;  // Success       }    }    free(pImageCodecInfo);    return -1;  // Failure } int wmain(int argc,wchar_t *argv[]) {     int r=1;     if (argc<4) {     USAGE:         wprintf(L"%s srcimg.{bmp|jpg|gif|tif|png|wmf|emf|ico}  desimg.{bmp|jpg|gif|tif|png}  angle\n",argv[0]);         return r;     }     int i;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[1]+wcslen(argv[1])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[2]+wcslen(argv[2])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);     {         Image img(argv[1]);         if (Ok==img.GetLastStatus()) {             UINT height = img.GetHeight();             UINT width  = img.GetWidth();             REAL angle;             if (1==swscanf_s(argv[3],L"%f",&angle)) {                 REAL size;                 size=(REAL)sqrt(1.0*width*width+1.0*height*height);                 Matrix mat;                 mat.Translate(size / -2.0f, size / -2.0f);                 mat.Rotate(-angle, MatrixOrderAppend);                 mat.Translate(size / 2.0f, size / 2.0f, MatrixOrderAppend);                 PointF pfTL((size-width)/2.0f      ,(size-height)/2.0f       );                 PointF pfTR((size-width)/2.0f+width,(size-height)/2.0f       );                 PointF pfBL((size-width)/2.0f      ,(size-height)/2.0f+height);                 PointF pfBR((size-width)/2.0f+width,(size-height)/2.0f+height);                 Graphics tgp(&img);                 Bitmap bmp((UINT)size,(UINT)size,&tgp);//Let bmp Resolution equal to img Resolution                 Graphics gp(&bmp);                 gp.SetTransform(&mat);                 gp.DrawImage(&img,pfTL);                 REAL xmin,ymin,xmax,ymax,x,y,rw,rh;                 mat.TransformPoints(&pfTL);                 xmin=xmax=pfTL.X;                 ymin=ymax=pfTL.Y;                 mat.TransformPoints(&pfTR);                 if (xmin>pfTR.X) xmin=pfTR.X;                 if (xmax<pfTR.X) xmax=pfTR.X;                 if (ymin>pfTR.Y) ymin=pfTR.Y;                 if (ymax<pfTR.Y) ymax=pfTR.Y;                 mat.TransformPoints(&pfBL);                 if (xmin>pfBL.X) xmin=pfBL.X;                 if (xmax<pfBL.X) xmax=pfBL.X;                 if (ymin>pfBL.Y) ymin=pfBL.Y;                 if (ymax<pfBL.Y) ymax=pfBL.Y;                 mat.TransformPoints(&pfBR);                 if (xmin>pfBR.X) xmin=pfBR.X;                 if (xmax<pfBR.X) xmax=pfBR.X;                 if (ymin>pfBR.Y) ymin=pfBR.Y;                 if (ymax<pfBR.Y) ymax=pfBR.Y;                 x=xmin;                 y=ymin;                 rw=xmax-x;                 rh=ymax-y;                 Bitmap* clone;                 clone = bmp.Clone(x,y,rw,rh,PixelFormat24bppRGB);//bmp.GetPixelFormat()                 CLSID encoderClsid;                 if (0<=GetEncoderClsid(formats[i],&encoderClsid)) {                     if (Ok==clone->Save(argv[2],&encoderClsid)) {                         wprintf(L"OK to %s  %s  %s  %s\n",argv[0],argv[1],argv[2],argv[3]);                         r=0;                     } else {                         wprintf(L"Error to save %s\n",argv[2]);                         r=4;                     }                 } else {                     wprintf(L"Error to GetEncoderClsid(%s,...)\n",formats[i]);                     r=3;                 }                 delete clone;             } else {                 wprintf(L"Error to get angle %s\n",argv[3]);                 r=2;             }         } else {             wprintf(L"Error to load %s\n",argv[1]);             r=5;         }     }     GdiplusShutdown(gdiplustoken);     return r; }


Question: 【请教】关于Linux C程序调用shell的问题

仅供参考：#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> pid_t rw_popen(char* cmd, FILE **rfile, FILE **wfile) {     int pipefd[2],pipefd2[2]; //管道描述符     pid_t pid; //进程描述符      if (pipe(pipefd) < 0) //建立管道     {         printf("rw_popen() pipe create error/n");         return 0;     }     if (pipe(pipefd2) < 0) //建立管道     {         printf("rw_popen() pipe create error/n");         return 0;     }      pid = fork(); //建立子进程      if (pid < 0)     return 0;      if (0 == pid) //子进程中     {         close(pipefd[0]);         dup2(pipefd[1], 1);         close(pipefd[1]);         dup2(pipefd2[0], 0);         close(pipefd2[0]);         close(pipefd[1]);         char *argv[] = { "/bin/sh", "-c", cmd, NULL };         if (execvp("/bin/sh", argv) < 0) //用exec族函数执行命令         exit(1);     }      close(pipefd[1]);     *rfile = fdopen(pipefd[0], "r");     close(pipefd2[0]);     *wfile = fdopen(pipefd2[1], "w");     return pid; } void rw_pclose(pid_t pid, FILE *rfile, FILE *wfile) {     int status;     waitpid(pid, &status, 0);     fclose(rfile);     fclose(wfile); } int main() {     char buf1[1024];     FILE *file1, *file2;     pid_t pid;     pid = rw_popen("sh", &file1, &file2);     if (pid) {         fputs("pwd;exit;\n",file2);         fflush(file2);         if (fgets(buf1, 1400, file1)) {             puts(buf1);         }         rw_pclose(pid, file1, file2);     }     return 1; }

哦哦！奏效！多谢这位英雄！