Question: 一个奇怪的C语言问题

scanf("%c",&op);  如果要用字符串，你应该申请一个char [2] 否则结尾的\0会越界

引用 5 楼 qq423399099 的回复:用getchar和%c就行了 楼主用%p打印下三个变量的地址，用%s写入的话，因为有2个字节，可能破坏了别的变量的存储空间 我看了下地址，char一个字节，然后跟的是left，用%s的话是会覆盖掉left的内存空间。谢谢

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 Ysniper 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 不知道楼主想验证什么？ scanf("%s",&op);应该是scanf("%c",&op); 栈是向下生长的，在Windows下,栈是向低地址扩展的数据结构，是一块连续的内存的区域。 楼主不妨打印printf("%p %p %p", &left, &right, &op); 就算输入一个字符串给op,应该也不会造成left和right的值被清零 我试过%c，程序不会等你输出就直接执行完毕了，所以采用%s。我调试时发现被清零的，你可以自己编译试试看，我也觉得很奇怪[/quote] %c来不及看到输出就结束了，是因为之前输入缓冲区有遗留的回车符，所以%c会直接读掉回车符 在第一个scanf后面加上getchar();或者fflush(stdin);来清除掉遗留的回车符  我这里就算用%s也不会被清零，用%s由于会越界写入，程序结束的时候会报错 [/quote] ubuntu，使用getchar()和%c没有问题，但是fflush不行，如果用getchar和%s还是会清零，但不会报错。这个真是奇怪

引用 1 楼 qq423399099 的回复:不知道楼主想验证什么？ scanf("%s",&op);应该是scanf("%c",&op); 栈是向下生长的，在Windows下,栈是向低地址扩展的数据结构，是一块连续的内存的区域。 楼主不妨打印printf("%p %p %p", &left, &right, &op); 就算输入一个字符串给op,应该也不会造成left和right的值被清零 我试过%c，程序不会等你输出就直接执行完毕了，所以采用%s。我调试时发现被清零的，你可以自己编译试试看，我也觉得很奇怪

引用 2 楼 Ysniper 的回复:[quote=引用 1 楼 qq423399099 的回复:] 不知道楼主想验证什么？ scanf("%s",&op);应该是scanf("%c",&op); 栈是向下生长的，在Windows下,栈是向低地址扩展的数据结构，是一块连续的内存的区域。 楼主不妨打印printf("%p %p %p", &left, &right, &op); 就算输入一个字符串给op,应该也不会造成left和right的值被清零 我试过%c，程序不会等你输出就直接执行完毕了，所以采用%s。我调试时发现被清零的，你可以自己编译试试看，我也觉得很奇怪[/quote] %c来不及看到输出就结束了，是因为之前输入缓冲区有遗留的回车符，所以%c会直接读掉回车符 在第一个scanf后面加上getchar();或者fflush(stdin);来清除掉遗留的回车符  我这里就算用%s也不会被清零，用%s由于会越界写入，程序结束的时候会报错


Question: C:求同构数

引用 3 楼 qq423399099 的回复:主要是值每次循环前没有把count和k的值重新置为0和1 while循环用一个新的变量t来保存i的值，不要直接改变i的值，这样会导致最外层的for循环出错  #include<stdio.h> int main() { 	 	int count=0; 	int i,j,k=1;  	for(i=0; i<=10000; i++) 	{ 		count = 0; 		int t = i; 		while(t != 0) 		{ 			count++; 			t /= 10; 		} 		k=1; 		for(j=0; j<count; j++) 			k *= 10;  		if( i*i%k == i) 			printf("%d\n",i); 	} }  太感谢了，自己经常因为一些小问题停在那儿，思维还是没能跳出来。

感谢1楼指导 ~~~~ #include<stdio.h> int countBits(int x) { 	int counter=0; 	while(x) 	{ 		counter++; 		x /= 10; 	} 	return counter; }  int Pow10(int n) { 	int p =1,i; 	for(i=0; i<n;i++) 	{ 		p *= 10; 	} 	return p; }   int main(void) { 	int i,j,p=1; 	int count=0; 	for(i=0; i<=10000; i++) 	{ 		if( i*i % Pow10(countBits(i)) == i) 		{ 			printf("%d\n",i); 		} 	} 	return 0; }

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


Question: Makefile怎么排除某两三个文件不编译

SRC := $(filter-out a.cpp b.cpp, $(SRC))


Question: 关于二维数组的乘法请教

各位帮忙看一下哪里出问题了，数组要先改小了才能在编译器的运行，但是oj中没这种限制

什么问题，栈溢出？ 光这3个数组所占用的栈空间就有301*301*3*8/1024/1024=2.08M左右 一般栈的默认大小是1M到几M

Description 天才少女Alice，哦，不，应该叫天才幼儿才对，她才1岁7个月，就开始学习线性代数了。她很快就掌握了矩阵加法、减法，马上又学乘法。  矩阵乘法是这样定义的： 一个m行n列的矩阵A 与 一个n行p列的矩阵B 的乘积，是一个m行p列的矩阵C。  C的第i行第j个元素是这样算出来的： C(i,j) = A(i,1)*B(1,j) + A(i,2)*B(2,j) + ... + A(i,k)*B(k,j) + ... + A(i,n)*B(n,j) 即，C的第i行第j个元素，是由A的第i行与B的第j列的元素相应做乘法，最后求和所得。  矩阵A与矩阵B可以做乘法的前提是：A的列数等于B的行数。  对于m、n、p比较小的情况，Alice很快就能计算完毕。算出来的结果如果没有错，那么就会嚷嚷着要奖励吃蛋糕。并且常常以做矩阵乘法为理由，向爸爸索要蛋糕吃。坏坏的爸爸于是出了一些矩阵让Alice做，但m、n、p的值可能很大（ 1 ≤ m、n、p ≤ 300 ），那么Alice就没有那么快计算完了。  Alice一看那么大的矩阵，立刻傻眼了，心想：算一个礼拜也算不完啊。。。。于是，狡猾的Alice又用水汪汪的大眼睛向你发出哀求的目光。请大哥哥/大姐姐快点编个程序帮Alice算出来吧。  Input 输入的第一行是三个数m、n、p （ 1 ≤ m、n、p ≤ 300 ），接下来的m行每行是n个用空格分隔的整数，组成一个m*n的矩阵A。  接下来是n行，每行是p个用空格分隔的整数，组成一个n*p的矩阵B。  Output 输出 A*B的积矩阵C  ：m行，每行p个整数（空格分隔）。C的元素不超unsigned long的表示范围。  Sample Input 3 3 2 7 5 0 0 2 1 1 3 0 1 1 0 1 19 23  Sample Output 7 12 19 25 1 4  这是题目

解决了，中间一个循环错了

引用 4 楼 zhao4zhong1 的回复:在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 我把数组定义换到全局变量还是Wrong Answer #include<stdio.h> double a[301][301],b[301][301],c[301][301]; int main() {  	double sum; 	int m,n,p; 	int i,j,k; 	while(scanf("%d%d%d",&m,&n,&p)!=EOF) 	{ 		for(i = 1;i <= m;i++) 		for(j = 1;j <= n;j++) 		scanf("%lf",&a[i][j]); 		 		for(i = 1;i <= n;i++) 		for(j = 1;j <= p;j++) 		scanf("%lf",&b[i][j]); 		 		for(i = 1;i <= m;i++) 		{ 		   for(j = 1;j <= p;j++) 		  { 		  	sum = 0; 			for(k = 1;k <= m;k++) 			sum += a[i][k] * b[k][j]; 			c[i][j] = sum; 		  } 	    } 		for(i = 1;i <= m;i++) 		{ 		    for(j = 1;j <= p;j++) 		    { 		      if(j != p) 			  printf("%.0f ",c[i][j]); 			  else 		      printf("%.0f",c[i][j]); 		    } 		    printf("\n"); 	    } 	} 	return 0; }


Question: 新人问一个c语言问题，大家帮忙看一下

选择排序法的的降序排列没有实现是因为内层循环有个地方写错了 for(j=n+1;j<n;j++)应该改为for(j=i+1;j<n;j++) 折半查找法这里不是用不了，是你的scanf里面多写了\n scanf("%ld\n",&x1);应该是scanf("%ld",&x1);  #include <stdio.h> #include <stdlib.h> #define N 5 int Readscore(int  score[],long id[]); int Linsearch(long id[],long m,int n); void Linsort(int score[],long id[],int n); void Selectsort(int score[],long id[],int n); int Binsearch(long id[],long m,int n); void Printf(int score[],long id[],int n);  int main() { 	int score[N];//记录学生成绩 	long id[N];//记录学生学号 	int num;//接收 READscore的返还值，即学生人数 	long x,x1; 	int a,a1;//接收返回学号的值  	//记录学生成绩 	num=Readscore(score,id);  	//输出成绩和学号 	Printf(score,id,num);   	// 顺序查找法 	printf("输入你要查找的学生的学号："); 	scanf("%ld",&x); 	a=Linsearch(id,x,num); 	printf("%d %ld\n",score[a],id[a]);  	//线性排序法 	Linsort(score,id,num);  	//输出成绩和学号 	Printf(score,id,num);  	//选择排序法 	Selectsort(score,id,num);  	//输出成绩和学号 	Printf(score,id,num);  	//折半查找法 	printf("输入你要查找的学生的学号："); 	scanf("%ld",&x1); 	a1=Binsearch(id,x1,num); 	if(a1 != -1) 	{ 		printf("%d %ld\n",score[a1],id[a1]); 	} 	else 	{ 		printf("大兄弟，没这个人啊!"); 	}   	//输出成绩和学号 	Printf(score,id,num);   	return 0; }  //录入学生成绩 和学号 int Readscore(int score[],long id[]) { 	int i=-1; 	do 	{ 		i++; 		printf("input score and id:"); 		scanf("%d %ld",&score[i],&id[i]); 	}while((score[i] >= 0)&&(id[i] >=0)); 	return i; } //顺序查找 int Linsearch(long id[],long m,int n) { 	int i;  	for(i=0;i<n;i++) 	{ 		if(m == id[i]) 		{ 			return i; 		} 	} 	return -1; } //线性排序,升序排 void Linsort(int score[],long id[],int n) { 	int i,j; 	int temp1,temp2;  	for(i=0;i<n-1;i++) 	{  		for(j=i+1;j<n;j++) 		{ 			if(score[i]>score[j]) 			{ 				//交换成绩 				temp1=score[j]; 				score[j]=score[i]; 				score[i]=temp1; 				//交换学号 				temp2=id[j]; 				id[j]=id[i]; 				id[i]=temp2; 			} 		} 	} } //选择排序法,降序排 void Selectsort(int score[],long id[],int n) { 	int i,j,k; 	int temp1; 	long temp2;  	for(i=0;i<n-1;i++) 	{ 		k=i; 		for(j=i+1;j<n;j++) 		{ 			if(score[j] > score[k]) 			{ 				k=j; 			} 		} 		if(k != i) 		{ 			//交换成绩 			temp1 = score[k]; 			score[k] = score[i]; 			score[i] = temp1;  			//交换学号 			temp2 = id[k]; 			id [k] =id[i]; 			id[i] = temp2; 		} 	} }  //折半查找法 int Binsearch(long id[],long m,int n) { 	int high = n-1; 	int low = 0; 	int mid;  	while(low <= high) 	{ 		mid = (high+low)/2; 		if(m < id[mid]) 		{ 			high = mid-1; 		} 		else if(m > id[mid]) 		{ 			low = mid+1; 		} 		else 		{ 			return mid; 		} 	} 	return -1; } //输出函数 void Printf(int score[],long id[],int n) { 	int i; 	printf("=============================\n"); 	for(i=0;i < n;i++) 	{  		printf("%d %ld\n",score[i],id[i]);  	} }

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

你的降序中第二个循环根本不会执行。初始条件不对。 你说的不继续执行是什么意思

有个工具叫调试器，还有个工具叫日志。


引用 1 楼 user-1 的回复:如果 输入的数据满足   n%m ==0 循环一次也没有执行 tmp 中就是错误的值，而不是m谢谢，漏掉了，问题解决


Question: 怎么用setTimeout（）设置页面为指定时间刷新

var timmer = setInterval(function () {             var curDate = new Date();             if (curDate.getHours() == 0) {                 clearInterval(timmer);                 location.href = 'Index.aspx';             }         }, 1000)  设置一个间隔1秒的计时器，每隔一秒检查一下当前时间，如果发现到0点了，执行刷新操作


Question: Cmake3.4 + opencv3.0 + Qt5.2

研读CMake在线相关文档或在CMake官方论坛发帖求助。

引用 1 楼 zhao4zhong1 的回复:在CMake里你选的什么编译器？ 试了三个 1：VS2013  生成完了以后有VS的工程文件，可以用VS2013编译，不过有一个工程失败，highgui那个工程 2.VS2008 生成VS工程文件，但是基本上没有一个工程编译通过 3.：GCC + G++ 仍然没有Makefile文件

在CMake里你选的什么编译器？


Question: [C语言求救贴] C语言里的一个细节问题，求大神指教

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

引用 10 楼 dalemwi 的回复:[quote=引用 7 楼 ForestDB 的回复:] 没有用return，就表示你只是调用函数，并不要函数的返回值。  所以我在函数里直接打印出正确的x可以，因为函数有分配临时的空间给那个正确的多次递归后的x，但是就不能返回给main了，请问是这样吗？[/quote] 虽然不准确，差不多就这个意思。 每次函数调用都有其自己的frame，每个frame中的‘同名’变量‘，其实是没有任何关系的。

楼主可以自己单步一步步看 如果没有加return,那么一层层递归进去，到最里面那层了（即进入else分支了）打印出2.00000，然后return x了 但由于之前的没有return,你用什么接收返回值呢？ 最后在主函数打印出来的也就是寄存器里的值

引用 7 楼 ForestDB 的回复:没有用return，就表示你只是调用函数，并不要函数的返回值。  所以我在函数里直接打印出正确的x可以，因为函数有分配临时的空间给那个正确的多次递归后的x，但是就不能返回给main了，请问是这样吗？

引用 6 楼 user-5 的回复:longjmp 或者异常  好的，谢谢您！

楼主sb昂。。

没有用return，就表示你只是调用函数，并不要函数的返回值。

要不用长跳转 或者 异常试试看

递归 必须逐层返回，没有捷径 想要捷径，用循环

longjmp 或者异常

引用 1 楼 user-5 的回复:funct(x);---> tmp = funct(x); 递归调用结束，继续执行后续代码  return funct(x); 递归调用结束执行 函数调用funct(x); 的返回值作为 返回值象上一层调用返回   您好！我还想问一下， funct(x);---> tmp = funct(x) 这样的话，为什么多次这样调用后，在函数里  printf("%.5lf!!\n\n",x);  这一句中，我还是可以得到一我想要的递归结果（x）呢？  而且为什么这样不能把那个正确的递归结果（x）返回给main函数为它所用呢？  谢谢您！

引用 楼主 dalemwi 的回复:新手初学C，有一个细节问题一直想不懂，求教各位大神  在一个需要返回值得函数里，函数调用自己这两种形式： .. function(..) { 	..         function(..)	 }   和这样调用自己：   .. function(..) { 	.. 	return function(..)	 }  有什么区别呢？。。。   问题来源于一段简单的递归代码：  #include<stdio.h>  int main() {     double funct(double x);      printf("%.5lf",funct(10.0));     return 0; }   double funct(double x) {    if(x!=2.0)    {         x--;         funct(x);    }    else   {        printf("%.5lf!!\n\n",x);         return x;   } }   里面递归的一句：         funct(x);  没有写成： return funct(x);[/code]  会造成返回给main的参数出错。。。。但是一直想不懂为什么。。。  所以求教各位大神了，帮帮初学者吧！   您好，我还想问一下， funct(x);---> tmp = funct(x) 这样的话，为什么多次这样调用后，在函数里  printf("%.5lf!!\n\n",x); 这一句中，我还是可以得到一我想要的递归结果（x）呢？  而且为什么这样不能把那个正确的递归结果（x）返回给main函数为它所用呢？  谢谢您！


Question: C语言写“用最小面积的圆覆盖平面上的点集”应该怎么写？

我找了一个，求大神看看对不对? #include <stdio.h> #include <math.h> // 输入最多的点数目  #define MAX_POINTS_AMOUNT 100  struct Point {     double x,y; }; // 求点 p1, p2 的距离  double distance(struct Point p1, struct Point p2) {     return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));     } // 求 a, b, c  中的最大值  double max(double a, double b, double c) {     return a>=b && a>=c              ?    a             :    b>=a && b>=c                  ?    b                 :    c;  }  // 判断长度为 a, b, c 的 3条线段能否组成三角形  // 判断依据为：至少有一条边的长度，大于另两条边的长度差（绝对值），小于另两条边的长度和  int canMakeTriangle(double a, double b, double c) {     return     a>fabs(b-c) && a<(b+c) ||             b>fabs(a-c) && b<(a+c) ||             c>fabs(a-b) && c<(a+b); }   // 判断长度为 a, b, c 的 3条线段能否组成锐角三角形  // 判断依据：根据余弦定理，求出 3 个角的余弦值  int canMakeAcuteTriangle(double a, double b, double c) {     unsigned int i;     double cos_a, cos_b ,cos_c;     if(canMakeTriangle(a, b, c))     {         cos_a = (b*b + c*c - a*a)/(2*b*c);         cos_b = (a*a + c*c - b*b)/(2*a*c);         cos_c = (a*a + b*b - c*c)/(2*a*b);          return cos_a>0 && cos_b>0 && cos_c>0;     }     return 0; }  /* 求覆盖 n 个点 points 的最小圆的半径     算法：     只要分别求出所有3点组合覆盖的最小圆，取其中半径最大者即为所求。      确定覆盖3点的最小圆的步骤可以如下：     (1) 若3点组成直角或钝角三角形，或3点共线，此时，最小圆的半径为三边中最长边的一半。     (2) 否则，3点组成锐角三角形，最小圆为3点的外接圆。     (3) 外接圆半径计算方法：          (a) 若3点构成一个三角形(即3点不共线)，              并设3点的坐标为 (x1,y1)，(x2,y2)，(x3,y3)，求出两点(x1,y1)和(x2,y2)之间的距离              L1=sqrt((x1-x2)^2+(y1-y2)^2), 同样求出(x1,y1)和(x3,y3)之间的距离L2，              以及(x2,y2)和(x3,y3)之间的距离L3。          (b) 求出三角形半周长L=(L1+L2+L3)/2以及面积S=sqrt(L*(L-L1)*(L-L2)*(L-L3))。          (c) 根据公式4SR=L1*L2*L3，求外接圆半径R=L1*L2*L3/(4*S)。      参数：         n                    ：    点数目          points                ：    n 个点的坐标          start                ：    递归参数。表示当前从在 n 个点的第 start 个开始选取。初始值为 0。          selectPointsAmount    ：     递归参数。表示当前已经选好了的点数。最多为 3 个。初始值为 0。          selectPoints        :    递归参数。表示当前已经选好了的点的坐标数组。初始值为 NULL。      返回：         覆盖 n 个点 points 的最小圆的半径。            */ double minCircleRadius(unsigned int n, struct Point points[],      unsigned int start, unsigned int selectPointsAmount, struct Point selectPoints[]) {     if(n <= 1)         return 0.0;     if(n == 2)         return distance(points[0], points[1])/2.0;     else     {         if(selectPointsAmount == 3)         {// 已经选好了 3 个点，求能覆盖它们的最小圆的半径                        double L1 = distance(selectPoints[0], selectPoints[1]);             double L2 = distance(selectPoints[0], selectPoints[2]);             double L3 = distance(selectPoints[1], selectPoints[2]);             double L  = (L1 + L2 + L3)/2.0;             double S  = sqrt(L*(L-L1)*(L-L2)*(L-L3));             if(canMakeAcuteTriangle(L1, L2, L3))             {// 能组成锐角三角形                  return L1*L2*L3/(4.0*S);             }             else             {// 其他情况：三点共线，组成直角三角形，或锐角三角形                  return max(L1, L2,L3)/2.0;             }         }         else         {// 任选 3 个点             double r, minR = 0.0;             unsigned int i;                          struct Point temp[3];             if(selectPoints == NULL)                 selectPoints = temp;                              for(i=start;(n-i)>=(3-selectPointsAmount);i++)             {                 selectPoints[selectPointsAmount] = points[i];                 r = minCircleRadius(n, points, i+1, selectPointsAmount+1, selectPoints);                 if(minR < r)                     minR = r;                             }             return minR;         }     }  } int main(int argc, char *argv[]) {     struct Point points[MAX_POINTS_AMOUNT];     unsigned int i,n;     while(scanf("%d",&n)!=EOF)     {         for(i=0; i<n; i++)             scanf("%lf,%lf",&points[i].x, &points[i].y);         printf("%.4lf\n",minCircleRadius(n, points, 0, 0, NULL));      }     return 0; } /* 4 4.2,5.6 78.3,3.8 35.4,15.9 29.88,42.56 */

用上面的那种方法的话，我怎么确定圆的圆心呢？

计算任两点最大距离作为直径？暴力了一点


Question: 从串口接收一段十六进制数据中提取特定数据

引用 1 楼 zhao4zhong1 的回复:#pragma warning(disable:4305 4309) #include <stdio.h> #include <string.h> char b[]={ 0x2D,0x30,0x30,0x30,0x35,0x2E,0x30,0xB7, 0x8D,0x0A,0x53,0xD4,0xAC,0x4E,0xD4,0xAC, 0x2D,0x30,0x30,0x30,0x35,0x2E,0x30,0xB7, 0x8D,0x0A,0x53,0xD4,0xAC,0x4E,0xD4,0xAC, }; char s[8]; int main() {     s[7]=0;     memcpy(s,&b[ 0],7);     printf("%s\n",s);     memcpy(s,&b[16],7);     printf("%s\n",s);     return 0; } //-0005.0 //-0005.0 // 谢谢。


Question: 数据结构栈的问题

我靠，忘记了一个重点，因为原始栈有一个字节，所以上面的函数中的栈大小等处代码都要相应+1

char gettop (SqStack *s)//取栈顶的元素  {   if(s->base==s->top||s->base==NULL)      return ERROR;   return *(s->top); }  int stacklength (SqStack *s)//返回栈的长度  {     //返回S的元素个数，即栈的长度     return (s->base - s->top); }  SElemType pop (SqStack *s)//弹出一个，删除  {     //若栈不空，则删除S的栈顶元素     if (s->top==s->base) return ERROR;      return (*s->top);//带回了被删除的值       --s->top; }  Status visit(SqStack *s) { while(s->base!=s->top)   printf("%c\n",*s->top);   --s->top; return ok; } #endif  #include<stdio.h> #include<stdlib.h> #include<malloc.h> #include"stack.h" int main()  {  char c; SqStack *s; s=(SqStack*)malloc(sizeof(SElemType)); ; while(scanf("%c",&c)!=EOF) push(s,c);     return 0;  另外，楼主你的栈还不完美，只能处理CHA类型的数据，那要是INT或float的你怎么办

Status push(SqStack *s, char c)//在栈顶插入新元素 {    if((s->base)-(s->top)>=(s->stacksize))//通常栈是向低端地址增长的，你用top-base是个负数一定会大于                                                                                stacksize     {  s->base=(char *)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElemType));          s->stacksize += STACKINCREMENT;         s->top=s->base + s->stacksize;、\\这里前后顺序错了         } s->top=s->top-STACKINCREMENT; \\栈顶指针减少了10个cha *(s->top)=c;  return ok; }

SqStack *s改成SqStack s你栈没分配空间，sigsegv 段访问违例，一般由于没有分配空间的指针被访问

稍微看了下发现了两个问题： 1.SqStack *s这个指针需要分配空间，因为楼主initstack函数传的是一级指针，所以建议直接在主函数里malloc 2.while(scanf("%c",&c)!=EOF);后面多了分号吧？ PS:不过另外还有错误，楼主会单步调试的，自己先调试下，还有问题再发上来  int main()  { 	char c; 	SqStack *s = (SqStack *)malloc(sizeof(SqStack)); 	initstack(s); 	while(scanf("%c",&c)!=EOF) 		push(s,c); 	return 0; }


Question: c预定义

楼上该说的都说了。我就不废话了。

VMX_API_PRINTF(...)	do{}while(0)好处： 1、辅助定义复杂的宏，避免引用的时候出错： 2、避免空宏引起的warning

把宏展开了理解。 cpp, gcc -E, cl.exe /E可以帮你展开。

VMX_API_PRINTF("%s-Line-%d\n",__FUNCTION__,__LINE__);	  ---->lib_print("%s-Line-%d\n",__FUNCTION__,__LINE__);	  VMX_API_PRINTF(...)---->	do{}while(0)  在不同条件下，VMX_API_PRINTF 定义成不同 形式 前一种形式，VMX_API_PRINTF 直接替换成 lib_print 后一种形式，不定参数宏调用 替换成 空循环 这样 两种宏，定义形式虽然不统一 用起来却是一致的  前一种，定义不带参数宏 直接替换，省得处理不定参数 让 lib_print 这个函数来处理 不定参数  后一种，处理就是不处理  所以 定义带不定参数的宏 ，使之武功尽废，什么也不做。

就是打印当前函数名以及行号。


Question: 数据机构的顺序表实现不了？

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

问题超级多，有几个scanf里面有\n,还有各种小问题，帮楼主调了一部分 InitList，创建学生信息表，DisplayList这3处帮楼主改正确了 之后的函数楼主可以结合DisplayList自己写，比如插入函数，在插入之前和之后都调用DisplayList，来看看自己插入正确了没  #include<stdio.h> #include<stdlib.h> #define ERROR 0 #define OK 1 #define OVERFLOW -1 #define Status int #define MAXSIZE 100 typedef struct { 	char no[4]; 	char name[8]; 	int price; }Student; typedef struct { 	Student *elem; 	int length; }SqList; int i,j; Status InitList(SqList &L)//初始化顺序表 { 	L.elem=new Student[MAXSIZE]; 	if(L.elem==0) exit(OVERFLOW); 	L.length=0; 	return OK; } void DisplayList(SqList L)//显示学生信息 { 	for(j=0;j<L.length;j++) 	{ 		printf("%s %s %d\n",L.elem[j].no,L.elem[j].name,L.elem[j].price); 	} } Status Searchelem(SqList L,int i,Student &e)//3查找对应的数据元素 { 	if(i<1||i>L.length) return ERROR; 	if(L.length!=0) return ERROR; 	e=L.elem[i-1]; 	return OK; } Status SearchElemName(SqList L,char e[8])//根据姓名查找 { 	for(j=0;j<L.length;j++) 	{ 		if(L.elem[j].name[8]==e[8]) 			return OK; 	} } Status InsertList(SqList &L,int i,Student e)//4插入一个数据元素 { 	if(L.length!=MAXSIZE) return ERROR; 	if(i<1||i>L.length) return ERROR; 	for(j=L.length-1;j<L.length-i;j--) 		L.elem[j+1]=L.elem[j]; 	L.elem[j-1]=e; 	L.length++; 	return OK; } Status DeleteList(SqList &L,int i)//5删除一个数据元素 { 	if(i<1||i>L.length) exit(ERROR); 	for(j=i;j<L.length;j++) 		L.elem[j-1]=L.elem[j]; 	--L.length; 	return OK; } Status ClearList(SqList &L)//6清空顺序表 { 	L.length=0; 	return OK; } Status DestorySqList(SqList &L)//7销毁顺序表 { 	if(L.elem) delete[]L.elem; 	return OK; } int LengthList(SqList L)//10取表的长度 { 	return L.length; } int main() { 	SqList L; 	Student e; 	int number,N; 	char na[20]; 	printf("1-初始化顺序表\n"); 	printf("2-创建学生信息表\n"); 	printf("3-查找学生信息表\n"); 	printf("4-显示学生信息\n"); 	printf("5-删除信息表\n"); 	printf("6-插入学生信息\n"); 	printf("7-显示学生个数\n"); 	printf("8-根据姓名查找\n"); 	printf("0-退出程序\n"); 	number=-1; 	while(number!=0) 	{ 		printf("请选择1~8的序号: "); 		scanf("%d",&number); 		switch(number) 		{ 		case 1: 			if(InitList(L)) 				printf("初始化完成"); 			else 				printf("初始化失败"); 			break; 		case 2: 			printf("创建顺序表,请输入N个学生信息表"); 			scanf("%d",&N); 			for(j=0;j<N;j++) 			{ 				L.length++; 				scanf("%s%s%d",L.elem[j].no,L.elem[j].name,&L.elem[j].price); 			} 			break; 		case 3: 			printf("请输入第i个元素的序号: "); 			scanf("%d",&i); 			if(!Searchelem(L,i,e)) 				printf("查找失败\n"); 			else 				printf("%s%s%d",L.elem[i].no[8],L.elem[i].name[20],L.elem[i].price); 			break; 		case 4: 			DisplayList(L); 			break; 		case 5: 			printf("请输入第i个元素: "); 			scanf("%d",&i); 			if(DeleteList(L,i)) 				printf("删除成功\n"); 			else 				printf("删除失败\n"); 			break; 		case 6: 			printf("请输入第i个元素: "); 			scanf("%d",&i); 			printf("请输入要插入学生的信息:1511 支付宝 100,每个数据之间空格隔开\n"); 			scanf("%s%s%d",e.no,e.name,e.price); 			if(InsertList(L,i,e)) 				printf("插入成功"); 			else 				printf("插入失败"); 			break; 		case 7: 			printf("这个顺序表的长度为%d:LengthList(L)"); 			break; 		case 8: 			printf("请输入要查找的名字"); 			scanf("%s",na); 			if(SearchElemName(L,e.name)) 				printf("%s%d\n",L.elem[j].no,L.elem[j].price); 			else 				printf("查找失败\n"); 			break; 		case 0: 			number=0; 			break; 		} 	} 	return 0; }

可能是格式输入的问题，但是我又找不出问题？

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

哪位大神可以帮我看看


Question: 关于udp的问题

仅供参考：//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef _MSC_VER     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef _MSC_VER void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             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]:'.');             }             Log("%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]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef _MSC_VER     pthread_exit(NULL); #endif } int main() { #ifdef _MSC_VER     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef _MSC_VER     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef _MSC_VER     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

引用 4 楼 psv1988psv 的回复:双队列是挺好  但例子少了点 双队列比较简单，但是使用广泛

谢谢赵老师。。

双队列是挺好  但例子少了点

先谢谢楼上  我对这块也比较陌生   只能先找找看了

楼主看看双缓冲队列啥的，感觉是比较适合的

楼主其实就是想找一个缓冲区的例子 使用读写锁的缓冲区当然可以用于楼主的UDP，不过肯定不是最合适的 看楼主的描述，一秒钟5W个包，就是说这个缓冲区的修改还是很频繁的，而使用读写锁的缓冲区适用于读多写少的场景。


Question: c语言：带有参数的main（int argc，char *args[])中参数的含义

main函数的两个参数用于接收命令行的参数，第一个是命令行参数的个数，第二个一个字符串数组，用于访问命令行的参数。 假如你的程序最后生成的程序文件是p.exe，那么，当你双击程序运行它是，相当于在命令行输入以下内容并回车： p.exe 这时，你在程序中可以得到第一个参数是1,第二个参数是含有1个字符串的字符串数组，这1个字符串是"p.exe"  如果想带参数运行你的程序，应该使用Cmd窗口，在cmd窗口中输入你的程序，后面带上参数： p.exe c1 c2 c3 以上表示你的程序带了3个参数运行，3个参数分别是c1,c2和c3，在你的程序中，第一个参数的值将是4,第二个参数将是包含4个字符串的字符串数组，这4个字符串分别是：“p.exe"，"c1"，"c2"，"c3"。  下面是我曾经写过的一个命令行程序的代码片段，楼主可以参考一下这两个参数的用法：    int main(int argc, char* argv[]) {     bool bRemoveAsterisk=false;     bool bRemoveSlash=false;     bool bRemoveBlankLine=false;     bool bReplaceTab=false;     String str,file1,file2;     int n;     int iErrorCode=0;     for(int i=1;i<argc;i++)     {         str = argv[i];         if(str=="//") bRemoveSlash=true;         else if(str=="/*") bRemoveAsterisk=true;         else if(str=="/b") bRemoveBlankLine=true;         else if(str.SubString(1,2)=="/t")         {             if(str=="/t")             {                 cout<<"对C语言程序源文件进行处理"<<endl;                 cout<<endl;                 cout<<"CommRemove [/b] [/*] [//] [/t<n>] <file1> <file2>"<<endl;                 cout<<endl;                 cout<<" <file1> 需要处理的源文件"<<endl;                 cout<<" <file2> 处理后的结果文件"<<endl;                 cout<<endl;                 cout<<" [/t<n>] 将源文件中的TAB字符替换为空格,n为替换空格的个数"<<endl;                 cout<<"         其中的<n>必须指定一个数值"<<endl;                 iErrorCode = 3;             }             String ns = str.SubString(3,255);             bReplaceTab=true;             n = atoi(ns.c_str());         }         else if(file1.Length()==0) file1 = str;         else file2 = str;     }     if(iErrorCode!=0) return iErrorCode;

argc,argv 用命令行编译程序时有用。 主函数main中变量(int argc, char *argv[])的含义 有些编译器允许将main() 的返回类型声明为void，这已不再是合法的C++ main(int argc, char *argv[], char **env)才是UNIX和Linux中的标准写法。 argc: 整数,用来统计你运行程序时送给main函数的命令行参数的个数 * argv[]: 字符串数组，用来存放指向你的字符串参数的指针数组，每一个元素指向一个参数 argv[0] 指向程序运行的全路径名 argv[1] 指向在DOS命令行中执行程序名后的第一个字符串 argv[2] 指向执行程序名后的第二个字符串          argv[argc]为NULL。 **env:字符串数组。env[]的每一个元素都包含ENVVAR=value形式的字符串。其中ENVVAR为环境变量，value 为ENVVAR的对应值。 argc,argv,env是在main( )函数之前被赋值的，编译器生成的可执行文件，main()不是真正的入口点，而是一个标准的函数,这个函数名与具体的操作系统有关。

没用过对于没用过命令行的人的确很难说清楚, 去实地用一下就清楚了。 试想一下我想删除某个文件夹，但是没有GUI工具该怎么办.


Question: C中macro的Token Pasting的问题

cur_l3_ ## table ## _table_entries++;   \

#define CURL_I3_TABLE_ENTRIES(table, entries) curl_I3_##table##entries  #define TTP_ROUTE_TABLE_ENTRY(table, tag)    \ static inline void  \ ttp_route_##table##tag(void)   \ {   \   CURL_I3_TABLE_ENTRIES(table, _entries)++; \ }  #define TTP_ROUTE_TABLE_ENTRY_INC(table) TTP_ROUTE_TABLE_ENTRY(table, _inc)  TTP_ROUTE_TABLE_ENTRY_INC(ipv4_host)

#define TTP_ROUTE_TABLE_ENTRY_INC(table)    \ static inline void  \ ttp_route_##table(void)   \ {   \     cout<<#table<<endl;   \ }去掉_inc

仅供参考： #与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC


Question: error C2064: term does not evaluate to a function

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

关于这个错误我遇到了两种情况： 1.数组下标问题     char szBuffer[64];     int nTest = szBuffer(0); // 注意到了没有？[]写成了()  2.将类成员的后面加了()，被当做函数调用  反正总是跟()有关，仔细看看吧。

谢谢您，这个方法试过了，还是不行。还有其他办法吗？

将Hx替换为MyHx ？


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-> //

楼主你单步一下就知道了 第一个insert:  void insert(lnode* node){ 	lnode *p;   //定义一个指针 	p=head;    //指针指向头结点 	while(p != NULL){ //,头结点是NULL,所以p也是NULL，所以不会进入while循环 		p=p->next; 	} 	p=node; //p指向了传入的结点     //结束了，head根本没有变 }  要为head指针malloc一个空间，然后insert函数里应该是p->next=node 改为如下：  #include <iostream>  using namespace std;   #include <stdio.h>  typedef struct node{ 	char data; 	struct node *next; }lnode;  lnode* head = NULL;    //头指针   //插入链表尾 void insert(lnode* node){ 	lnode *p; 	p=head;  	while(p->next != NULL){ 		p=p->next; 	}  	p->next=node; 	node->next = NULL; }  //从链表中删除 void del(lnode* node){ 	lnode *p; 	p = head;  	while(p != NULL && p != node){ 		p=p->next; 	}  	if(p == NULL){ 		return; 	}  	p=p->next;    //从链表中删除 }   int main(void){ 	head = (lnode *)malloc(sizeof(lnode)); 	head->next = NULL; 	lnode a; 	lnode b; 	lnode c; 	lnode d;  	while(1){  		insert(&a); 		insert(&b); 		insert(&c); 		insert(&d);    		del(&a); 		del(&b); 		del(&c); 		del(&d); 	} 	return 0; }


Question: 求助，C语言编程结果不对

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

scanf("%f%f",&t[0][1],&t[0][2]); 改为scanf("%lf%lf",&t[0][1],&t[0][2]);  这处改了以后后面也有地方不对ax[k][i]=0.5*(a+b); 在调试的时候发现k会取到大于100的数，然后越界崩溃了  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 呜啦啦，我又不懂啦(ಥ _ ಥ)

你的insert函数有问题导致add函数的while(p2!=NULL)陷入死循环

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

1.好诡异的代码，为何不统一使用poly或Poly，混合起来好乱，不是好的代码风格，提醒一点 2，第40行代码，x=p->prer;，bug，导致插入失败补丁->p-prer=x;

引用 6 楼 haokeaiaheng 的回复:[quote=引用 4 楼 paschen 的回复:] 到那一步不对的原因我帮你测试了下，我到那一步h2是NULL，而你去取h2->next，故出错了 至于h2为什么是NULL，建议楼主自己单步跟踪程序运行以分析原因其实h1也不对，进入函数后的值与输入的值不符[/quote]  学会调试程序，在适当的位置添加段点，然后单步运行，观察分析原因

引用 4 楼 paschen 的回复:到那一步不对的原因我帮你测试了下，我到那一步h2是NULL，而你去取h2->next，故出错了 至于h2为什么是NULL，建议楼主自己单步跟踪程序运行以分析原因其实h1也不对，进入函数后的值与输入的值不符

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }


Question: 从键盘给指针赋值

怎么从键盘上给一个初始化为NULL的指针赋值

当然，范围是受限制的

如果是读取内存数据，还是可以的，如果写数据，是不能随意指定的

需要创建空间，不然往哪写数据就不知道了

需要创建空间，用scanf


Question: 为什么计算不了带括号的  用的是VC++

调试看下那块报错，再分析什么原因

仅供参考：/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console) 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数^     ⑿向上取整ceil     ⒀向下取整floor     ⒁四舍五入取整round 用法： 如果要求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 round(double dVal, short iPlaces) {//iPlaces>=0     char s[30];     double dRetval;      sprintf(s,"%.*lf",iPlaces,dVal);     sscanf(s,"%lf",&dRetval);     return (dRetval); } 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;         case 17: x=ceil(x);   (*iop)--;break;         case 18: x=floor(x);  (*iop)--;break;         case 19: x=round(x,0);(*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","ceil","floor","round",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=='%'||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] = fmod(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=='/'||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] = fmod(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] = fmod(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,ceil,floor,round"<<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,ceil,floor,round"<<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: strbprk

因为你的source 和chars指针是指向NULL的，NULL指针代表的地址为0x00000000，该地址代表的内存区域是不允许读写的 然后执行gets(source)试图写入的时候自然引发异常了 可以改为数组或者malloc出来的堆空间,而且在find_char里找到的话应该返回source字符串，同时还要遍历chars字符串才行  #include<stdio.h>  char *find_char( char *source, char *chars){ 	char *p; 	while(*source != NULL){ 		for(p = chars; *p != '\0'; p++) 		{ 			if(*source == *p){ 				return source; 			} 		} 		source++; 	} 	return NULL; }  int main(){ 	char *source = (char *)malloc(64 * sizeof(char)); 	char chars[64] = {0}; 	gets(source); 	gets(chars); 	printf("%s\n",find_char(source, chars)); }

source chars是指针，得分配空间，用char数组


Question: c语言 循环问题

引用 3 楼 qq423399099 的回复:放这里应该可以的啊，每次b[j]的各自取sgn的累乘之前初始化成1 楼主有什么问题么？可是我这样跑出来的结果不对因为我这地方是对b取sgn得连乘，就是每次当b数组里面的负数的个数是奇数个时，出来的结果就会在最后一个数出错。如果b数组里面的负数是偶数个时，出来的结果就全对。不知道为什么？？？求大神帮我看看 谢谢啦

double minof(double x[], int no) { int i; double min = x[0];  for (i = 1; i < no; i++) { if (x[i] < min) min = x[i]; }  return min; }  int pr(int a[],int no) { int i; int c = 1;  for (i = 0; i < no; i++) { c *= a[i]; } return c; }  int sgn(double x) { if (x > 0) return 1; else if (x < 0) return -1; else return 0; }  int main(void) { int c = 1; double a[] = { 1.2, 3.4, 5.6, 7.8 }; double b[] = { -1.1, 2.4, 4.8, -7.9 }; double e[] = { 0 }; int i, j; double d = 1.0;    for (i = 0; i < 4; i++) {  for (j = 0; j < 4; j++) { if (j != i) { d = minof(&a[j], 3); break; } }     for (j = 0; j < 4; j++) {  if (j != i) { c *= sgn(*(b + j)); } }  e[i] = c*d; printf("%f\t", e[i]); }   getchar(); return(0); } 这样就可以了，

在线等大神！！！！！！！！！

顶上去！！！！


Question: 数组指针的问题

引用 3 楼 TsingSoftware2014 的回复:[quote=引用 1 楼 paschen 的回复:] int (*p1)[3]; 改成 int (*p1)[4];  int (*p)[3]; 它表示，数组 *p 具有三个int类型元素，分别为 (*p)[0] , (*p)[1] , (*p)[2] ，即 p指向的是具有三个int类型的一维数组，也就是说，p为行指针么？那这里为什么要改成4啊？[/quote]   int (*p1)[3]; 这里的3表示的是列而不是行

引用 3 楼 TsingSoftware2014 的回复:[quote=引用 1 楼 paschen 的回复:] int (*p1)[3]; 改成 int (*p1)[4];  int (*p)[3]; 它表示，数组 *p 具有三个int类型元素，分别为 (*p)[0] , (*p)[1] , (*p)[2] ，即 p指向的是具有三个int类型的一维数组，也就是说，p为行指针么？那这里为什么要改成4啊？[/quote]首先*p不是一个标示符，而且这是一个定义语句。首先p1是一个指针，它指向的内容是一个维数为3的一维数组，这个数组中的类型是int类型，你将 数组名赋给这个指针：p1 = arr;而arr是一个二维数组，数组名是指向首个行数组的指针，arr的首个行数组是一个int类型的4维数组，因此需要将int (*p1)[3]; 改成int (*p1)[4];

引用 4楼我是你的主体 的回复:引用 2 楼 renwotao2009 的回复:int (*p)[3]改成int *p[3]我就是想用数组指针来实现看看的。那用1楼的方式

#include<stdio.h> int main() {     int arr[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};     int (*p1)[4];     int i,j;     p1 = arr;      fprintf(stdout,"使用数组指针的方式访问二维数组arr\n");     for(i = 0;i<3;i++)     {         for(j = 0;j<4;j++)         {             printf("arr[%d] [%d]= %d\t",i,j,*(*(p1+i)+j));         }         printf("\n");     }    getchar(); }   这样就对了，

不要急着运行。先编译一下，把所有的语法警告都消除了，再考虑结果为什么不对

引用 1 楼 paschen 的回复:int (*p1)[3]; 改成 int (*p1)[4];  int (*p)[3]; 它表示，数组 *p 具有三个int类型元素，分别为 (*p)[0] , (*p)[1] , (*p)[2] ，即 p指向的是具有三个int类型的一维数组，也就是说，p为行指针么？那这里为什么要改成4啊？

int (*p)[3]改成int *p[3]

int (*p1)[3]; 改成 int (*p1)[4];


Question: OpenGL编程读取txt文档数据，运行时不显示图像，只出现一个白色背景的窗口，怎么回事。本人刚开始学习编程，求各位大神指导，跪谢，急~~

while(!feof(fp))  {   fscanf(fp,"%4f",&data);   a[i]=data;   i++;  } 应改为 while(1)  {   if (1!=fscanf(fp,"%f",&data)) break;   a[i]=data;   i++;   if (i>=20) break;  }

多是viewport设置不正确看不到图 尝试在opengl api 每一步后调用 glGetError ，看看有没有 opengl抛出的渲染错误

谢谢楼上解答。楼上提示我都尝试了，还是不行……继续跪求解答


Question: 关于用C写简易用户级线程库的问题

/*  * types used by thread library  */ /*  * types used by thread library  */ #include <stdio.h> #include <stdlib.h> #include <ucontext.h> #include <sys/mman.h>  struct TCB {   int thread_id;   int thread_priority;   ucontext_t thread_context;   struct TCB *next; };  typedef struct TCB TCB;  struct Queue {   TCB *front;   TCB *rear; };  typedef struct Queue Queue;  //utility functions  // Create new TCB  TCB* createTCB(ucontext_t *context,int threadId, int threadPriority) {   TCB *newT = (TCB *)malloc(sizeof(TCB));   newT->thread_context = *context;   newT->thread_id = threadId;   newT->thread_priority = threadPriority;   return newT; }  // Initialize a queue void initQueue(Queue *cq) {   cq->front = cq->rear = NULL; }  // Insert a new TCB into a Queue void Enqueue(Queue *cq, TCB *newT) {   newT->next = NULL;   if(cq->front == NULL && cq->rear == NULL){ 	cq->front = cq->rear = newT; 	return;   }   cq->rear->next = newT;   cq->rear = newT; }  // Remove the front TCB from a Queue void Dequeue(Queue *cq) { 	TCB *tmp = cq->front;  	if (cq->front == NULL) { 		printf("Access Error: Queue is Empty...\n"); 		return; 	}  	if (cq->front == cq->rear) { 		cq->front = cq->rear = NULL; 	} 	else { 		cq->front = cq->front->next; 	} 	free(tmp); }    #include "t_lib.h"  Queue *runningQueue; Queue *readyQueue; ucontext_t *newT; ucontext_t *mainT; TCB *current;  void t_init() {   runningQueue = (Queue *)malloc(sizeof(Queue));   readyQueue = (Queue *)malloc(sizeof(Queue));      initQueue(runningQueue);   initQueue(readyQueue);   mainT = (ucontext_t *) malloc(sizeof(ucontext_t));    getcontext(mainT);    /* let mainT be the context of main thread */    Enqueue(runningQueue,createTCB(mainT,0,1)); }  void t_shutdown()  { 	free(runningQueue); 	free(readyQueue); 	free(mainT); 	free(newT); 	free(current); }  int t_create(void (*fct)(int), int id, int pri) { 	size_t size = 0x10000; 	newT = (ucontext_t *) malloc(sizeof(ucontext_t)); 	 	getcontext(newT);  /* let newT be the context of new thread */ 	newT->uc_stack.ss_sp = malloc(size);  /* new statement */   newT->uc_stack.ss_size = size;   newT->uc_stack.ss_flags = 0;   newT->uc_link = &runningQueue->front->thread_context;  	makecontext(newT, (void (*)(void)) fct, 1, id); 	 	Enqueue(readyQueue,createTCB(newT,id,pri)); //	setcontext(newT);  // switch to new one }  void t_terminate()  { 	setcontext(&readyQueue->front->thread_context); 	Dequeue(runningQueue); //	runningQueue->front = readyQueue->front; //	Dequeue(readyQueue); }  void t_yield()  {  		current = (TCB *)malloc(sizeof(TCB));     current = runningQueue->front;          Enqueue(readyQueue, current);          runningQueue->front = readyQueue->front;          Dequeue(readyQueue);     swapcontext(&readyQueue->rear->thread_context, &runningQueue->front->thread_context);  }

仅供参考：//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             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]:'.');             }             Log("%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]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

代码不全 另外代码要用格式插入

我第一次来这边问问题 还不会用

不是的，就只是简单的在linux上写一个等同于pthread库作用的用户级库

ucos吗?

This is main()#0 created single thread[1]... This is main()#0 created double thread[2]... This is main()#0 created triple thread[5]... This is main()#0 created quad thread[15]... This is main()[0]... this is thread #1 [0]... this is double thread #2, created single thread #3. this is double thread #2, created single thread #4. this is triple thread #5, created double thread #6. this is triple thread #5, created double thread #9. this is triple thread #5, created double thread #12. this is quad thread #15, created single thread #16. this is quad thread #15, created single thread #17. this is quad thread #15, created single thread #18. this is quad thread #15, created single thread #19. This is main()[1]... this is thread #1 [1]... this is thread #3 [0]... this is thread #4 [0]... this is 'double' thread 2 [0]... this is double thread #6, created single thread #7. this is double thread #6, created single thread #8. this is double thread #9, created single thread #10. this is double thread #9, created single thread #11. this is double thread #12, created single thread #13. this is double thread #12, created single thread #14. this is 'triple' thread 5 [0]... this is thread #16 [0]... this is thread #17 [0]... this is thread #18 [0]... this is thread #19 [0]... this is 'quad' thread #15 [0]... This is main()[2]... this is thread #1 [2]... this is thread #3 [1]... this is thread #4 [1]... this is 'double' thread 2 [1]... this is thread #7 [0]... this is thread #8 [0]... this is 'double' thread 6 [0]... this is thread #10 [0]... this is thread #11 [0]... this is 'double' thread 9 [0]... this is thread #13 [0]... this is thread #14 [0]... this is 'double' thread 12 [0]... this is 'triple' thread 5 [1]... this is thread #16 [1]... this is thread #17 [1]... this is thread #18 [1]... this is thread #19 [1]... this is 'quad' thread #15 [1]... This is main()[3]... this is thread #1 [3]... this is thread #3 [2]... this is thread #4 [2]... this is 'double' thread 2 [2]... this is thread #7 [1]... this is thread #8 [1]... this is 'double' thread 6 [1]... this is thread #10 [1]... this is thread #11 [1]... this is 'double' thread 9 [1]... this is thread #13 [1]... this is thread #14 [1]... this is 'double' thread 12 [1]... this is 'triple' thread 5 [2]... this is thread #16 [2]... this is thread #17 [2]... this is thread #18 [2]... this is thread #19 [2]... this is 'quad' thread #15 [2]... This is main()[4]... this is thread #1 [4]... this is thread #3 [3]... this is thread #4 [3]... this is 'double' thread 2 [3]... this is thread #7 [2]... this is thread #8 [2]... this is 'double' thread 6 [2]... this is thread #10 [2]... this is thread #11 [2]... this is 'double' thread 9 [2]... this is thread #13 [2]... this is thread #14 [2]... this is 'double' thread 12 [2]... this is 'triple' thread 5 [3]... this is thread #16 [3]... this is thread #17 [3]... this is thread #18 [3]... this is thread #19 [3]... this is 'quad' thread #15 [3]... This is main()[5]... this is thread #1 [5]... this is thread #3 [4]... this is thread #4 [4]... this is 'double' thread 2 [4]... this is thread #7 [3]... this is thread #8 [3]... this is 'double' thread 6 [3]... this is thread #10 [3]... this is thread #11 [3]... this is 'double' thread 9 [3]... this is thread #13 [3]... this is thread #14 [3]... this is 'double' thread 12 [3]... this is 'triple' thread 5 [4]... this is thread #16 [4]... this is thread #17 [4]... this is thread #18 [4]... this is thread #19 [4]... Thread 15 is done... This is main()[6]... this is thread #1 [6]... this is thread #3 [5]... this is thread #4 [5]... this is 'double' thread 2 [5]... this is thread #7 [4]... this is thread #8 [4]... this is 'double' thread 6 [4]... this is thread #10 [4]... this is thread #11 [4]... this is 'double' thread 9 [4]... this is thread #13 [4]... this is thread #14 [4]... this is 'double' thread 12 [4]... this is 'triple' thread 5 [5]... this is thread #16 [5]... this is thread #17 [5]... this is thread #18 [5]... this is thread #19 [5]... This is main()[7]... this is thread #1 [7]... this is thread #3 [6]... this is thread #4 [6]... this is 'double' thread 2 [6]... this is thread #7 [5]... this is thread #8 [5]... this is 'double' thread 6 [5]... this is thread #10 [5]... this is thread #11 [5]... this is 'double' thread 9 [5]... this is thread #13 [5]... this is thread #14 [5]... this is 'double' thread 12 [5]... Thread 5 is done... this is thread #16 [6]... this is thread #17 [6]... this is thread #18 [6]... this is thread #19 [6]... This is main()[8]... this is thread #1 [8]... this is thread #3 [7]... this is thread #4 [7]... this is 'double' thread 2 [7]... this is thread #7 [6]... this is thread #8 [6]... this is 'double' thread 6 [6]... this is thread #10 [6]... this is thread #11 [6]... this is 'double' thread 9 [6]... this is thread #13 [6]... this is thread #14 [6]... this is 'double' thread 12 [6]... this is thread #16 [7]... this is thread #17 [7]... this is thread #18 [7]... this is thread #19 [7]... This is main()[9]... this is thread #1 [9]... this is thread #3 [8]... this is thread #4 [8]... Thread 2 is done... this is thread #7 [7]... this is thread #8 [7]... this is 'double' thread 6 [7]... this is thread #10 [7]... this is thread #11 [7]... this is 'double' thread 9 [7]... this is thread #13 [7]... this is thread #14 [7]... this is 'double' thread 12 [7]... this is thread #16 [8]... this is thread #17 [8]... this is thread #18 [8]... this is thread #19 [8]... This is main()[10]... Thread 1 is done... this is thread #3 [9]... this is thread #4 [9]... this is thread #7 [8]... this is thread #8 [8]... Thread 6 is done... this is thread #10 [8]... this is thread #11 [8]... Thread 9 is done... this is thread #13 [8]... this is thread #14 [8]... Thread 12 is done... this is thread #16 [9]... this is thread #17 [9]... this is thread #18 [9]... this is thread #19 [9]... This is main()[11]... Thread 3 is done... Thread 4 is done... this is thread #7 [9]... this is thread #8 [9]... this is thread #10 [9]... this is thread #11 [9]... this is thread #13 [9]... this is thread #14 [9]... Thread 16 is done... Thread 17 is done... Thread 18 is done... Thread 19 is done... This is main()[12]... Thread 7 is done... Thread 8 is done... Thread 10 is done... Thread 11 is done... Thread 13 is done... Thread 14 is done... This is main()[13]... This is main()[14]... This is main()[15]... Begin shutdown... Done with shutdown...

第二个测试文件中run出来的结果是： This is main()#0 created single thread[1]... This is main()#0 created double thread[2]... This is main()#0 created triple thread[5]... This is main()#0 created quad thread[15]... This is main()[0]... this is thread #1 [0]... this is double thread #2, created single thread #3. this is double thread #2, created single thread #4. this is triple thread #5, created double thread #6. this is triple thread #5, created double thread #9. this is triple thread #5, created double thread #12. this is quad thread #15, created single thread #16. this is quad thread #15, created single thread #17. this is quad thread #15, created single thread #18. this is quad thread #15, created single thread #19. This is main()[1]... this is thread #1 [1]... this is thread #3 [0]... this is thread #4 [0]... this is 'double' thread 2 [0]... this is double thread #6, created single thread #7. this is double thread #6, created single thread #8. this is double thread #9, created single thread #10. this is double thread #9, created single thread #11. this is double thread #12, created single thread #13. this is double thread #12, created single thread #14. this is 'triple' thread 5 [0]... this is thread #16 [0]... this is thread #17 [0]... this is thread #18 [0]... this is thread #19 [0]... this is 'quad' thread #15 [0]... This is main()[2]... this is thread #1 [2]... this is thread #3 [1]... this is thread #4 [1]... this is 'double' thread 2 [1]... this is thread #7 [0]... this is thread #8 [0]... this is 'double' thread 6 [0]... this is thread #10 [0]... this is thread #11 [0]... this is 'double' thread 9 [0]... this is thread #13 [0]... this is thread #14 [0]... this is 'double' thread 12 [0]... this is 'triple' thread 5 [1]... this is thread #16 [1]... this is thread #17 [1]... this is thread #18 [1]... this is thread #19 [1]... this is 'quad' thread #15 [1]... This is main()[3]... this is thread #1 [3]... this is thread #3 [2]... this is thread #4 [2]... this is 'double' thread 2 [2]... this is thread #7 [1]... this is thread #8 [1]... this is 'double' thread 6 [1]... this is thread #10 [1]... this is thread #11 [1]... this is 'double' thread 9 [1]... this is thread #13 [1]... this is thread #14 [1]... this is 'double' thread 12 [1]... this is 'triple' thread 5 [2]... this is thread #16 [2]... this is thread #17 [2]... this is thread #18 [2]... this is thread #19 [2]... this is 'quad' thread #15 [2]... This is main()[4]... this is thread #1 [4]... this is thread #3 [3]... this is thread #4 [3]... this is 'double' thread 2 [3]... this is thread #7 [2]... this is thread #8 [2]... this is 'double' thread 6 [2]... this is thread #10 [2]... this is thread #11 [2]... this is 'double' thread 9 [2]... this is thread #13 [2]... this is thread #14 [2]... this is 'double' thread 12 [2]... this is 'triple' thread 5 [3]... this is thread #16 [3]... this is thread #17 [3]... this is thread #18 [3]... this is thread #19 [3]... this is 'quad' thread #15 [3]... This is main()[5]... this is thread #1 [5]... this is thread #3 [4]... this is thread #4 [4]... this is 'double' thread 2 [4]... this is thread #7 [3]... this is thread #8 [3]... this is 'double' thread 6 [3]... this is thread #10 [3]... this is thread #11 [3]... this is 'double' thread 9 [3]... this is thread #13 [3]... this is thread #14 [3]... this is 'double' thread 12 [3]... this is 'triple' thread 5 [4]... this is thread #16 [4]... this is thread #17 [4]... this is thread #18 [4]... this is thread #19 [4]... Thread 15 is done... This is main()[6]... This is main()[7]... this is thread #1 [6]... this is thread #3 [5]... this is thread #4 [5]... this is 'double' thread 2 [5]... this is thread #7 [4]... this is thread #8 [4]... this is 'double' thread 6 [4]... this is thread #10 [4]... this is thread #11 [4]... this is 'double' thread 9 [4]... this is thread #13 [4]... this is thread #14 [4]... this is 'double' thread 12 [4]... this is 'triple' thread 5 [5]... this is thread #16 [5]... this is thread #17 [5]... this is thread #18 [5]... this is thread #19 [5]... This is main()[8]... This is main()[9]... this is thread #1 [7]... this is thread #3 [6]... this is thread #4 [6]... this is 'double' thread 2 [6]... this is thread #7 [5]... this is thread #8 [5]... this is 'double' thread 6 [5]... this is thread #10 [5]... this is thread #11 [5]... this is 'double' thread 9 [5]... this is thread #13 [5]... this is thread #14 [5]... this is 'double' thread 12 [5]... Thread 5 is done... this is thread #16 [6]... this is thread #16 [7]... this is thread #17 [6]... this is thread #18 [6]... this is thread #19 [6]... This is main()[10]... This is main()[11]... this is thread #1 [8]... this is thread #3 [7]... this is thread #4 [7]... this is 'double' thread 2 [7]... this is thread #7 [6]... this is thread #8 [6]... this is 'double' thread 6 [6]... this is thread #10 [6]... this is thread #11 [6]... this is 'double' thread 9 [6]... this is thread #13 [6]... this is thread #14 [6]... this is 'double' thread 12 [6]... this is thread #16 [8]... this is thread #16 [9]... this is thread #17 [7]... this is thread #18 [7]... this is thread #19 [7]... This is main()[12]... This is main()[13]... this is thread #1 [9]... this is thread #3 [8]... this is thread #4 [8]... Thread 2 is done... this is thread #7 [7]... this is thread #7 [8]... this is thread #8 [7]... this is 'double' thread 6 [7]... this is thread #10 [7]... this is thread #11 [7]... this is 'double' thread 9 [7]... this is thread #13 [7]... this is thread #14 [7]... this is 'double' thread 12 [7]... Thread 16 is done... This is main()[14]... Segmentation fault 就会有分段错误，按道理应该输出

另外附上我写的功能方程： #include <stdio.h> #include <stdlib.h> #include <ucontext.h> #include <sys/mman.h>  struct TCB {   int thread_id;   int thread_priority;   ucontext_t thread_context;   struct TCB *next; };  typedef struct TCB TCB;  struct Queue {   TCB *front;   TCB *rear; };  typedef struct Queue Queue;  //utility functions  // Create new TCB  TCB* createTCB(ucontext_t *context,int threadId, int threadPriority) {   TCB *newT = (TCB *)malloc(sizeof(TCB));   newT->thread_context = *context;   newT->thread_id = threadId;   newT->thread_priority = threadPriority;   return newT; }  // Initialize a queue void initQueue(Queue *cq) {   cq->front = cq->rear = NULL; }  // Insert a new TCB into a Queue void Enqueue(Queue *cq, TCB *newT) {   newT->next = NULL;   if(cq->front == NULL && cq->rear == NULL){ 	cq->front = cq->rear = newT; 	return;   }   cq->rear->next = newT;   cq->rear = newT; }  // Remove the front TCB from a Queue void Dequeue(Queue *cq) { 	TCB *tmp = cq->front;  	if (cq->front == NULL) { 		printf("Access Error: Queue is Empty...\n"); 		return; 	}  	if (cq->front == cq->rear) { 		cq->front = cq->rear = NULL; 	} 	else { 		cq->front = cq->front->next; 	} 	free(tmp); }


Question: 段错误（核心转存）

你记载coredump文件了吗

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

在进入 gdb 输入where时，说no stack

已经生成了coredump，用gdb加载一下看一下死在哪里  coredump 位置：cat /proc/sys/kernel/core_pattern coredump大小设置：ulimit -c unlimited 编译时候需要加 -g -ggdb选项  gdb 你的程序 core的位置  bt命令

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  那什么操作会引起段错误呢？   粗略的分一下类：   1）往受到系统保护的内存地址写数据   有些内存是内核占用的或者是其他程序正在使用，为了保证系统正常工作，所以会受到系统的保护，而不能任意访问。   2）内存越界(数组越界，变量类型不一致等)   3）其他   例如：   <1>定义了指针后记得初始化，在使用的时候记得判断是否为NULL   <2>在使用数组的时候是否被初始化，数组下标是否越界，数组元素是否存在等   <3>在变量处理的时候变量的格式控制是否合理等    代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: c语言结构体指针问题

char *p; if(p!=NULL) { ... } 和这个同样的道理吧，肯定不能这样判断的，定义指针时，在用他前必须要赋值的，没有的话，那定义时就这样char *p= NULL。

内存没有初始化

没有分配的内存，全部是随机值。 不是一个指针是随机值。

那只要声明一个结构体指针，只要没有赋值，都会是有一个指针为随机值，其他为空？

在 Debug 模式下，VC 会把未初始化的栈内存上的指针全部填成 0xcccccccc ，会把未初始化的堆内存上的指针全部填成 0xcdcdcdcd 楼主可以用printf("%p\n", head->right);打印看看

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

malloc 出的内存中是随机值。


Question: C语言问题，关于getchar和switch问题

while((c = getchar()) != '0')这句也有问题 下面k = c%2;也不对，k是个int的，你case的情况是'0'和'1'是字符啊。。。。 所以一个case分支都不会进去，所以打印出来都是0 改为如下：  #include<stdio.h> int main() { 	char c = ' '; 	int oushu = 0,sum1=0,jishu = 0,sum2=0; 	int k; 	while(c != '\n') 	{ 		scanf("%d", &k); 		switch(k%2) 		{ 		case 0:oushu+=1;sum1 +=k;break; 		case 1:jishu+=1;sum2 +=k;break; 		} 		c = getchar(); 	}  	printf("oushu: %d,oushu of sum: %d\n",oushu,sum1); 	printf("jishu: %d,jishu of sum: %d\n",jishu,sum2); 	return 0; }

k = c%2+‘0';

c语言中 '0' == 0x30, '\0' == 0


Question: c语言的指向二维数组的相关问题

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

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  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 //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

一楼自顶~~~大 牛       求辅助

第一次发帖不会见谅

前面加static应该也行。 static int tMap...

引用 8 楼 fornetuse123的回复:#include<stdio.h> #define wall 0 #define road 1 int(*p)[9]; int tMap[8][9] = { { wall, wall, wall, wall, wall, wall, wall, road, wall }, { wall, road, wall, wall, wall, wall, wall, road, wall }, { wall, road, road, road, road, road, road, road, wall }, { wall, wall, road, wall, wall, wall, wall, road, wall }, { wall, wall, road, wall, wall, wall, wall, road, wall }, { wall, wall, road, wall, wall, wall, wall, road, wall }, { wall, road, road, wall, wall, wall, wall, road, wall }, { wall, road, wall, wall, wall, wall, wall, wall, wall }, }; void display() {  int i, j;  p = tMap; for (i = 0; i < 8; i++) { for (j = 0; j < 9; j++) { printf("%d",*(*(p + i) + j)); } printf("\n"); } printf("\n");  } void isplay() { int i, j; p = tMap; for (i = 0; i < 8; i++) { for (j = 0; j < 9; j++) { printf("%d",*(*(p + i) + j)); } printf("\n"); } } void main() { display(); isplay(); }  参考楼上的，你需要去看看变量的作用域、链接，内存存在时间相关内容。

把这段代码放在函数外面去吧：  int tMap[8][9] =  {  { wall, wall, wall, wall, wall, wall, wall, road, wall },  { wall, road, wall, wall, wall, wall, wall, road, wall },  { wall, road, road, road, road, road, road, road, wall },  { wall, wall, road, wall, wall, wall, wall, road, wall },  { wall, wall, road, wall, wall, wall, wall, road, wall },  { wall, wall, road, wall, wall, wall, wall, road, wall },  { wall, road, road, wall, wall, wall, wall, road, wall },  { wall, road, wall, wall, wall, wall, wall, wall, wall },  };

引用 5 楼 小灸舞的回复:你的p指向的是一个在栈上创建的局部变量的数组 display调用结束了以后该变量的存储空间就被系统回收了 你再在isplay函数里打印就打印出来一堆无法确定结果的内容了


Question: 一个关于溢出的问题

引用 3 楼 qq_33257674 的回复:引用 1 楼 u014444402 的回复:后面的strlen dest长度已经是不确定的了，因为结束值0已经被你覆盖了。请问可以怎么改？   #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include<stdio.h> #include<string.h> #define MAX 128  int substr( char dst[], char src[], int start, int len ) { int i; int previouslength = strlen(dst); for(i = 0;i < len; i++){ if ( (src[start  + i] != 0)  ) {     dst[previouslength + i] = src[start  + i]; }  } dst[previouslength+i] = '\0'; return strlen(dst); }  int main(){ char dst[MAX]; char src[MAX]; int start, len;  gets(dst); gets(src); scanf("%d%d",&start, &len); printf("%d\n",substr(dst, src, start, len)); printf("%s", dst); }  不过还有个bug就是start要是比src的长度大，会发生错误。

dst  src数组清零

请问可以怎么改？

后面的strlen dest长度已经是不确定的了，因为结束值0已经被你覆盖了。


Question: 一个问题！

while("getchar() == '\n'"); return num; 永不退出的死循环么?

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

楼上正解while("getchar() == '\n'");多了双引号,恒为真 应该是while(getchar() != '\n');  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

是不是get_float里面错了 改成getchar() == '\n'可不可以？ 应该是回车的时候返回吧？


Question: 请问关于指针内存分配问题？

给结构体malloc只能是申请了12个字节（32位系统），三个结构提元素都是指针（3×4）那么这三个都是野指针，即若不进行初始化或申请空间（malloc)很有可能会出现内存错误；建议在使用时初始化或为其分配空间；

有点复杂，倒没用过，内还有指针的，学习学习

一段没有使用的空间，malloc出来是全0，如果使用过的空间，那么其中可能保留有旧值，这些值对于用户来说是随机数据，会构成潜在的程序bug，C中指针避免操作NULL和野指针

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

mystruct* ms = malloc(sizeof(mystruct)); 此时结构体内的3个指针都是野指针，指着一个未知的区域 如果尝试访问这3个指针所指的区域或者尝试写入那么就会产生异常

都是野指针，

malloc申请到的内存，不会自动清零，很可能是一些垃圾数据。申请成功后应该给它们赋初值，如果不加处理而直接使用，那么里面的指针是野指针，数据是垃圾数据。 如果仅仅是为了将申请到地内存全部清零的话，也可以使用另一个申请内存的函数：calloc，它的原型如下： void * calloc(size_t n,size_t size); 这个函数会自动将申请到的内存清零，相信应该比我们先用malloc再用memset效率更好一些。

在解引这个指针之前，你肯定要malloc或者让这个指针去指向一个已有的对象  否则是个野指针，解引可能导致程序崩溃

不初始化或者不分配内存是允许的,但是一旦操作到结构体指针的时候一定要分配内存或指向操作,否则操作野指针结局等同于 int main(void) { char *p; *p='a'; return 0; }  https://www.zhihu.com/question/35470332


Question: 进制转换

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

#include <stdio.h> #include <stdlib.h>  typedef struct Node { 	int date; 	struct Node *next; } LinkNode, *LinkList;   void conversion(LinkList top , int n) { 	int x; 	LinkList NewNode, tmpNode; 	  	//find the link tail 	tmpNode = top; 	while(tmpNode->next != NULL) { 		tmpNode = tmpNode->next; 	} 	 	while (n != 0) { 		x = n % 2; 		n /= 2; 		NewNode = (LinkList)malloc(sizeof(LinkNode)); 		NewNode->date = x; 		NewNode->next = NULL; 		 		tmpNode->next = NewNode; 		tmpNode = NewNode; 	} 	//add "." 	NewNode = (LinkList)malloc(sizeof(LinkNode)); 	NewNode->date = -1; 	NewNode->next = NULL; 		 	tmpNode->next = NewNode; 	tmpNode = NewNode;	 }  void conversion1(LinkList top, float n) { 	float x, y; 	LinkList NewNode, tmpNode; 	 	//find the link tail 	tmpNode = top; 	while(tmpNode->next!=NULL) { 		tmpNode = tmpNode->next; 	} 	 	 	while(n) { 		n *= 2; 		y = n - 1; 		if(y > 0) { 			n -= 1;	 			x = 1; 		} else if (y < 0) { 			x = 0; 		} else { 			x = 1; 		} 		 		NewNode = (LinkList)malloc(sizeof(LinkNode)); 		NewNode->date = x; 		tmpNode->next = NewNode; 		tmpNode = NewNode; 		if(0 == y) 		{ 			break; 		} 	} }  	 void input(LinkList top) { 	LinkList tmpNode = NULL; 	 	tmpNode = top->next; 	while(tmpNode != NULL) { 		if (tmpNode->date >= 0){ 			printf("%d",tmpNode->date); 		}else { 			printf("."); 		} 		 		tmpNode = tmpNode->next; 	} 	printf("\n"); }   int main(void) { 	LinkList head, tmpNode; 	float nubmer,decimal; 	int integers; 	 	printf("Please input a float number: "); 	scanf("%f",&nubmer);  	integers = (int)nubmer;  	decimal = nubmer - integers;   	head = (LinkList)malloc(sizeof(LinkNode)); 	head->next = NULL; 	 	//conv float to binary 	conversion(head, integers); 	conversion1(head, decimal); 	 	//display 	input(head); 	 	//free the link table 	while (head) { 		tmpNode = head; 		head = head->next; 		free(tmpNode); 	} 	 	return 0; }

要求用到链表

单步调试，观察数据变化找问题

求大腿指点下

引用 楼主 baidu_33333408 的回复:#include "stdio.h" #include"stdlib.h" typedef struct Node { 	int date; 	struct Node *next; } *LinkList; void conversion( LinkList top , int n) { 	int x;int i=0; 	LinkList NewNode; 	while(n!=0) 	{ 		x=n%2; 		n/=2; 		NewNode=(LinkList)malloc(sizeof(LinkList)); 		NewNode->date=x; 		NewNode->next=NULL; 		top->next=NewNode; 		top=top->next; 	 	 	} } void conversion1(LinkList top,float n) { 	float x; 	LinkList NewNode; 	while(top->next!=NULL) 	{ 		top=top->next; 	} 	while(n) 	{ 		n*=2; 		if(n-1>0) 		{ 		n-=1;	x=1; 		} 		if(n-1<0) 		x=0; 		if(n-1==0) 		x=1; 		NewNode=(LinkList)malloc(sizeof(LinkList)); 		NewNode->date=x; 		top->next=NewNode; 		top=top->next; 		if(n-1==0) 		{ 			top->next=NULL; break; 		} 	}  }   void input(LinkList top) { 	top=top->next; 	while(top!=NULL) 	{	 		printf("%d\t",top->date); 		top=top->next; 	} } int main (void) { 	LinkList head; 	float nubmer,decimal; 	int integers; 	scanf("%f",&nubmer);  	integers=(int)nubmer;  	decimal=nubmer-integers;  	head=(LinkList)malloc(sizeof(LinkList)); 	head->next=NULL; 	conversion(head,integers); //	input(head); //	printf("\n"); 	conversion1(head,decimal); 	input(head); 	printf("\n");  } 我很奇怪，为什么数值进制转换要用到链表？

仅供参考：#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汉


Question: 关于最少费用购物问题，有几段程序看不懂，希望能给我解释一下红色代码的作用？

搜“动态规划”

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

建议不要光看代码，必要时单步跟踪程序运行，观察每步各变量的变化情况，这样会容易理解的多