Question: 求问computational function如何运行

引用 楼主 weixin_38194305 的回复:我用一个软件自动生成C程序 结果生成了一样computational function和一个standalone function。 Standalone的可以运行 但是computational function的没有main 函数。但是导师希望我让computational 的运行起来。 求大神指导 针对C/C++语言，不同的系统一定是有个主程序入口（main或WinMain），在程序完成初始化后，其会跳转到该入口：其表明主程序入口，所以没有main(或其他类似WinMain)的程序是一定不能不能直接运行的；我对您导师的用意理解是，因为考虑到代码可复用性，他希望您将"computational function"独立出来，即这个程序中是没有main的。因此，您为了他这个要求，可以在外部构造一个宿主程序，这个宿主程序仅仅提供运行“computational function”的外围条件。 当然如果您是在某个嵌入系统，情况会稍有不同。此时您可能需要将“computational function”生成为相对某个地址的二进制可执行代码，然后在另一个程序（也许是个Shell或类似的代码中），直接调用。当然此时又可能根据您的系统有一些不同的处理方式。

computational function程序是什么文件？如果只是C语言格式有几种方法：1）将该文件变成一个静态库（Windows和Linux会有差别）;2)编译成动态库。这样computational function仍是独立的 然后再写一个宿主程序，其中是包含main，在宿主程序中调用computational function的函数

百度搜相关关键字。


Question: 求大神帮忙看看这个编程应该怎么编写 求指点

你应该先想好一个小的框架来写这个代码，而不是一个while（1）。 再小的代码都需要设计。

#include"stdio.h"  int main() { int q,m,i,a,b,c,x,y,run1;  	while(run1) 	printf("请选择您所需要的商品类型序号：\n"); 	printf("1:日用品 2:零食类 3:饮品类\n");	 	scanf("%d,&q"); 	m=q; 	switch(m) 	printf("*******************************\n");  	printf("1:毛巾(20元/张) 2:牙刷(10元/支) 3:牙膏(15/支)\n");   	printf("*******************************\n");  	printf("从1~3中选择按键：\n");  	scanf("%d", &i);  	switch(i)  		{  			case 1:  			{ 				printf("你选择了毛巾，请输入您选择的商品数量\n"); 				scanf("%d", &a);  				x=20*a; 				printf("您所购买的商品总价为：%d\n",x); 				break;  				case 2:  				printf("你选择了牙刷，请输入您选择的商品数量\n"); 				scanf("%d", &b);  				x=10*b; 				printf("n您所购买的商品总价为：%d\n",x);  				break;  				case 3:  				printf("你选择了牙膏，请输入您选择的商品数量\n");  				scanf("%d", &c);  				x=15*c; 				printf("您所购买的商品总价为：%d\n",x); 				break;  				default: printf("选择错误\n"); 				break;  				case '0':   				{ 				 					{ 					run1=0; 					} 				}break; 						  			} 		}   	 	printf("继续购买请按 1 退出请按 2 \n",y); 	if (y==1)	 	return m; 	else 	scanf ("谢谢光临 \n"); 	 }


Question: 16行代码莫名奇妙多了输出

#include<stdio.h> int main() {     int n,i;     double x;     char sex;      scanf("%d",&n);     getchar();     for(i=0;i<n;i++)     {         scanf("%c %lf",&sex,&x);         if(sex=='M') 		{ 			printf("%.2lf\n",x/1.06); 		} 		else { 			printf("%.2lf\n",x*1.06); 		}     }     return 0; }


Question: GNU11无法给结构体整体赋值，编译语法出错

引用 2 楼 wang0635 的回复:A structA =(A) {1,2,3,4};  不错，这个正解！

不错，这个正解！

A structA =(A) {1,2,3,4};

百度搜相关关键字。


Question: 希望大神能用建立一个线程的方法解决我这个问题

楼主, 新线程里面是无法接收标准输入的, cin 或 scanf只能在main函数所在的主线程里面使用

瞧人家1楼就没问什么平台。

引用 2 楼 kacyquan的回复:什么平台，windows的还是linux的。 windows的，谢谢了！

什么平台，windows的还是linux的。

#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h>     #include <process.h>     #define  MYVOID             void #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf     #define  MYVOID             void * #endif int a=0; int No_Loop=0; void sleep_ms(int ms) { #ifdef WIN32     Sleep(ms); #else     usleep(ms*1000); #endif } MYVOID testThread(void *pcn) {     int n,i;      n=(int)pcn;     i=0;     while (1) {         scanf("%d",&a);         i++;         if (i>=5) {No_Loop=1;break;}     } } int main() {     int i; #ifndef WIN32     pthread_t threads[1];     int threadsN;     int rc; #endif #ifdef WIN32     _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1); #endif     i=0;     while (1) {         sleep_ms(1000);         printf("a=%d\n",a);         if (No_Loop==1) break;//     }     return 0; } //a=0 //a=0 //a=0 //a=0 //1 //a=1 //a=1 //a=1 //2 //a=2 //a=2 //a=2 //3a=2 // //a=3 //a=3 //a=3 //4 //a=4 //a=4 //a=4 //a=4 //5 //a=5 //


Question: NMAKE:fatal errror LNK1181:无法打开输入文件“fl1500s.lib"


Question: 初始化结构体成员时定义为全局变量报错，定义为局部两边是正常

谢谢各位的答复！马上给分；）

p.sem_num=0; p.sem_op=-1; p.sem_flg=0;   v.sem_num=0; v.sem_op=1; v.sem_flg=0;  这样的语句要写去函数内，不能在全局范围，你可以放在主函数里的开头位置  或者定义全局结构体对象的时候，用大括号初始里面的成员

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

可以给全局变量初始化，定义时后跟等号，等号后面是初始化的值。 其他的等号就是赋值了，是赋值运算，函数外是不允许的。

好像找到答案了，但还是不太理解。 http://bbs.bccn.net/thread-343840-1-1.html


Question: 多种方法求解0/1背包问题，程序运行出错，求解！！！

double *W = new double[]; double *V = new double[]; double *R = new double[];  没有指定申请的数组大小

仅供参考：//http://www.cnblogs.com/chinazhangjie/archive/2010/11/16/1878400.html //多边形游戏 //描述 //    一个多边形，开始有n个顶点。每个顶点被赋予一个正整数值，每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。 //    现在来玩一个游戏，该游戏共有n步： //    第1步，选择一条边，将其删除 //    随后n-1步，每一步都按以下方式操作： //    （1）选择一条边E以及由E连接着的2个顶点v1和v2； //    （2）用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2，将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。 //    最后，所有边都被删除，只剩一个顶点，游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少？ //输入 //    第一行为多边形的顶点数n（n ≤ 20），其后有n行，每行为一个整数和一个字符， //    整数为顶点上的正整数值，字符为该顶点到下一个顶点间连边上的运算符“+”或“*” //    （最后一个字符为最后一个顶点到第一个顶点间连边上的运算符）。 //输出 //    输出仅一个整数，即游戏所计算出的最大值。 //样例输入 //4 //4 * //5 + //5 + //3 + //样例输出 //70 // //分析： //最优子结构性质 //按照顺时针顺序，多边形和顶点的顺序可以写成： //  op[1], v[1], op[2], v[2], …, op[n], v[n] //在所给多边形中，从顶点i(1 <= i <= n)开始，长度为j(链中有j个顶点)的顺时针链p(i，j) 可表示为 //v[i], op[i+1], v[i+1],…, op[i+j-1], v[i+j-1] // //如果这条链在op[i + s]处进行最后一次合并运算(1 <= s <= j-1)，则可在op[i+s]处将链分割为2个子链： // //从i开始长度为s的链：  p(i，s) //从i + s开始，长度为j - s的链：p(i + s，j-s)。 //设: //m1是对子链p(i，s)的任意一种合并方式得到的值，而a和b分别是在所有可能的合并中得到的最小值和最大值。 // //m2是p(i+s，j-s)的任意一种合并方式得到的值，而c和d分别是在所有可能的合并中得到的最小值和最大值。 // //依此定义有a <= m1 <= b，c <= m2 <= d // //(1)当op[i+s] = ‘+’时，显然有a + c <= m <= b + d // //(2)当op[i+s] = ’*’时，有 // //min {ac，ad，bc，bd} <= m <= max {ac，ad，bc，bd} //换句话说，主链的最大值和最小值可由子链的最大值和最小值得到。 #include <windows.h> #include <stdio.h> #include <string.h> #include <conio.h> #include <locale.h> int n; char o[21];//op int  d[21];//vertex data int maxv; struct SEGINFO {//阶段信息     int maxv;     int minv; } sg[21][21],si; int X,Y; void getXY() {     CONSOLE_SCREEN_BUFFER_INFO csbi;     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbi);     X=csbi.dwCursorPosition.X;     Y=csbi.dwCursorPosition.Y; } void gotoXY(int x, int y) {     COORD coord = {x, y};     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void ConPrintAt(int x, int y, char *CharBuffer, int len) {     DWORD count;     COORD coord = {x, y};     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     SetConsoleCursorPosition(hStdOut, coord);     WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } void ClearCon() {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     COORD coord = {0, 0};     DWORD count;     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         SetConsoleCursorPosition(hStdOut, coord);     } } void show(char *p) {     int y,x;     static char ss[128];      for (y=1;y<n;y++) {         sprintf(ss,"%c",o[y]);         ConPrintAt(0,y,ss,1);         for (x=1;x<n;x++) {             sprintf(ss,"%2d ",sg[y][x].maxv);             ConPrintAt(x*3,y,ss,3);         }     }     sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void pmt(char *p) {     static char ss[128];      sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void getmaxmin(int i, int s, int j) {// 从i开始，长度为j，s为切分位置     int minL;     int maxL;     int minR;     int maxR;     int r;     int mm[4];     int vmin;     int vmax;     static char p[128];      minL=sg[i][s].minv;     maxL=sg[i][s].maxv;         sprintf(p,"总长j:%d 上开始i:%d,长度  s:%d,maxL:%d",j,i,s  ,maxL);pmt(p);getXY();gotoXY(s    *3,i);getch();gotoXY(X,Y);       r=(i+s-1)%(n-1)+1;     minR=sg[r][j - s].minv;     maxR=sg[r][j - s].maxv;     sprintf(p,"总长j:%d 下开始r:%d,长度j-s:%d,maxR:%d",j,r,j-s,maxR);pmt(p);getXY();gotoXY((j-s)*3,r);getch();gotoXY(X,Y);      if (o[r] == '+') {// 处理加法         si.minv=minL + minR;         si.maxv=maxL + maxR;    sprintf(p,"上下合并maxv:%d=maxL:%d + maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } else {// 处理乘法         mm[0]=minL * minR;         mm[1]=minL * maxR;         mm[2]=maxL * minR;         mm[3]=maxL * maxR;         vmin=mm[0];         vmax=mm[0];         for (i=1;i<4;i++) {             if (mm[i]<vmin) vmin=mm[i];             if (mm[i]>vmax) vmax=mm[i];         }         si.minv=vmin;         si.maxv=vmax;           sprintf(p,"上下合并maxv:%d=maxL:%d * maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } } void pg() {     int i,j,s;     static char p[128];      ClearCon();     for (i=1;i<n;i++) {         sg[i][1].maxv=d[i];         sg[i][1].minv=d[i];     }     show("init");getch();     for (j=2;j<n;j++) {//长度         for (i=1;i<n;i++) {//起点             for (s=1;s<j;s++) {//子切分位置                 getmaxmin(i,s,j);                 if (sg[i][j].minv > si.minv) sg[i][j].minv=si.minv;                  sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ?",i,j,sg[i][j].maxv,si.maxv);pmt(p);                 getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 if (sg[i][j].maxv < si.maxv) {                     sg[i][j].maxv=si.maxv;                     show("");                     sprintf(p,"Yes, sg[开始i:%d][长度j:%d].maxv:%d <-- maxv=%d",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 } else {                     sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ? No",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getch();                 }             }         }     }     sprintf(p,"规划完毕，下一步计算总maxv...");pmt(p);getch();     maxv=sg[1][n-1].maxv;     sprintf(p,"总maxv=sg[1][n-1].maxv:%d",maxv);pmt(p);     getXY();gotoXY((n-1)*3,1);getch();gotoXY(X,Y);     for (i=2;i<n;i++) {         sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ?",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);         getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         if (maxv < sg[i][n-1].maxv) {             maxv=sg[i][n-1].maxv;             sprintf(p,"Yes,总maxv:%d <-- sg[开始i:%d][长度n-1:%d].maxv:%d",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         } else {             sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ? No",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getch();         }     }     sprintf(p,"计算出总maxv:%d",maxv);pmt(p);getch();     gotoXY(0,n+1); }  int main() {     int i;     char b[2];      setlocale(LC_ALL,"chs");     scanf("%d",&n);     for (i=1;i<=n;i++) {         scanf("%d%1s",&d[i],b);o[(i%n)+1]=b[0];     }     n++;     pg();//PolyGame     printf("%d\n",maxv);     return 0; } //4 //1 + //2 + //4 + //8 +


Question: 写的代码通不过oj，望大佬帮忙看下问题出在哪

找到第三个删除第二个，然后迭代。

void do_it (char* str) { 	char* ptmp = NULL; 	char* ptmpNext = NULL;  	ptmp = strstr(str, "*"); 	if (!ptmp) 		return;  	ptmp = strstr(ptmp + 1, "*"); 	while (ptmp) { 		ptmpNext = strstr(ptmp+1, "*"); 		if (ptmpNext){ 			for (int i = 0; i <= strlen(ptmp+1); i++) { 				*(ptmp + i) = *(ptmp + (i + 1)); 			} 			ptmp = ptmpNext -1; 		} else { 			 ptmp = NULL; 		} 	} }

a*a 字数补丁

边界条件 输入输出格式 ……

1.确定下输入的字符串有多长char c[80];这个长度能不能存储题目要求的最长字符串 2.看下题目要求处理几组输入数据，你这只处理了一组输入数据，一般Oj都会要求处理多组输入数据


Question: 将if-else语句转为 ? : 三目条件表达式

奇技淫巧！

引用 18 楼 baijiaheizhiganmao 的回复:[quote=引用 17 楼 zenny_chen 的回复:] [quote=引用 16 楼 lgbxyz 的回复:] 你来试试用一条 return 语句？ void 函数 return 个毛线啊[/quote]  你不会写就别BB～[/quote] 代码始终还是要给人看的.过度优化未必就是"好"的代码[/quote] 楼上那句"你不会写就别BB～"不是写的,csdb的bug

引用 17 楼 zenny_chen 的回复:[quote=引用 16 楼 lgbxyz 的回复:] 你来试试用一条 return 语句？ void 函数 return 个毛线啊[/quote]  你不会写就别BB～[/quote] 代码始终还是要给人看的.过度优化未必就是"好"的代码

脑筋操

这种代码对工作有意义吗？

return  不是不行  但挺无聊的 return (void)printf(a>0?"Above zero! a + 1 = %d\n":"Below zero! a - 1 = -%d\n", abs(a)+1);

引用 16 楼 lgbxyz 的回复:你来试试用一条 return 语句？ void 函数 return 个毛线啊[/quote]  你不会写就别BB～

广告贴

引用 15 楼 zenny_chen 的回复:[quote=引用 13 楼 lgbxyz 的回复:] 广告贴  你来试试用一条 return 语句？[/quote] void 函数 return 个毛线啊

引用 13 楼 lgbxyz 的回复:广告贴  你来试试用一条 return 语句？

#define PRINT(a) ((a) > 0 ? printf("Above zero! a + 1 = %d\n", (a)+1) : printf"Below zero! a - 1 = %d\n", (a)-1))  void foo (int a) { 	PRINT(a); }

#define PRINT ((a) > 0 ? printf("Above zero! a + 1 = %d\n", (a)+1) : printf"Below zero! a - 1 = %d\n", (a)-1))  void foo (int a) { 	PRINT(a); }

qianlaicanguanxuexi

楼上几位答得都不错，谁来试试用一条 return 语句？

void foo(int a) { 	a > 0 ? printf("Above zero! a + 1 = %d\n", a + 1) : printf("Below zero! a - 1 = %d\n", a - 1); }


Question: 数组赋值问题（C语言）

引用 4 楼 starytx 的回复:仅供参考 	for (int m = 0; m != i; ++m) 	{ 		for (int n = 0; n != j; ++n) 		{ 			if (a[m][n] == 9) 			{                                 //自己在此记录m,n 				if (m > 0)		// 上 				{ 					a[m - 1][n] = 0; 				} 				if (m <i-1)		// 下 				{ 					a[m + 1][n] = 0; 				} 				if (n > 0)		// 左 				{ 					a[m][n - 1] = 0; 				} 				if (n < j-1)		// 右 				{ 					a[m][n + 1] = 0; 				} 			} 		} 	}感谢！

首先这个位置肯定不是边界值，因为边界没有左边或右边，或者上面和下面元素；因此循环的i,j下标需要去掉边界；  for (i = 1; i < MAX_ROW - 1; i++)     for (j = 1; j < MAX_COL-1; j++) {         if (arr[i][j] == 9) {             arr[i-1][j] = 0;             arr[i][j+1] = 0;             arr[i+1][j] = 0;          }     }

边界条件

这个还是比较容易的，for嵌套循环，加上条件判定

先记录9对应的所有下标，后加条件置0。防止把9置0

双重循环，遍历中判断如果a[ i ][ j ]  == 9，设置：  a[ i-1 ][ j ] = 0; a[ i+1 ][ j ] = 0; a[ i ][ j-1 ] = 0; a[ i ][ j+1 ] = 0;  执行上述每条赋值前，先检查i-1  i+1  等会不会越界，如果越界则不执行


Question: c语言和C++混合编程的问题

在类中加一个plulic的方法：Void SetNalArray(TNAL* pnal_array) {     m_pNalArray = pnal_array; }在外部通过类的对象或者指针调用这个方法设置就行了。

把这个成员设置成public的，就可以直接赋值了  aaa.bbb = ccc;  //aaa是类对象，,bbb是你要设置的成员变量，ccc是要赋的值

引用 2 楼 faihung 的回复:[quote=引用 1 楼 qq_36782456 的回复:] 使用构造函数对类成员初始化，在初始化列表时把ringbuf传给你想要初始化的变量 也就是说，我在这个派生类的构造函数定义的地方，将NULL换成ringbuf就可以了。  MyH264VideoStreamFramer::MyH264VideoStreamFramer(UsageEnvironment& env,      FramedSource* inputSource, H264EncWrapper* pH264Enc, H264DecWrapper* pH264Dec):       H264VideoStreamFramer(env, inputSource),        m_pNalArray(NULL/ringbuf), m_iCurNalNum(0), m_iCurNal(0), m_iCurFrame(0),       m_pH264Enc(pH264Enc), m_pH264Dec(pH264Dec) {  }[/quote]  嗯呢，就是这样

引用 1 楼 qq_36782456 的回复:使用构造函数对类成员初始化，在初始化列表时把ringbuf传给你想要初始化的变量 也就是说，我在这个派生类的构造函数定义的地方，将NULL换成ringbuf就可以了。  MyH264VideoStreamFramer::MyH264VideoStreamFramer(UsageEnvironment& env,      FramedSource* inputSource, H264EncWrapper* pH264Enc, H264DecWrapper* pH264Dec):       H264VideoStreamFramer(env, inputSource),        m_pNalArray(NULL/ringbuf), m_iCurNalNum(0), m_iCurNal(0), m_iCurFrame(0),       m_pH264Enc(pH264Enc), m_pH264Dec(pH264Dec) {  }


Question: C语言实现的万年历里面的逻辑是怎么推算的,看不懂,求指教

date[1][20]; 这个是什么意思?

年月日的轮换交替变化有一定规律，  比如month>12时，month=1； 线按照规律写一个，再把特殊的提取出来，比如2月的天数

/****************************************************************************/ /* Function Name    :    getWeekdayFromGrogoryDate                          */ /* Description      :    通过格里高利日期获取星期                               */ /*--------------------------------------------------------------------------*/ /* Parameter        :    1) year        :    年(阳历)                        */ /*                       2) month       :    月(阳历)                        */ /*                       3) day         :    日(阳历)                        */ /*--------------------------------------------------------------------------*/ /* Return            :    星期几(0~6)[0为星期天,1~6 为星期一至星期六]            */ /* Remark            :    使用 基姆拉尔森计算公式                               */ /*                        W = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) mod 7   */ /*                        把1月和2月看成是上一年的13月和14月                     */ /****************************************************************************/ int getWeekdayFromGrogoryDate(int year, int month, int day) {     if ((1 == month) || (2 == month))     {         month += 12;    /* 13/14月 */         year -= 1;        /* 上一年 */     }          return (day + 2 * month + 3 * (month + 1)/5 + year + year/4 - year/100 + year/400 + 1) % 7; }

char WEEK[9],date[1][20];     printf("请输入日期:");     scanf("%s",date[0]); 注意，date[1]二维数组的运用都越界了，date[0]才可以。因为数组的行数是1，那么下标是从0开始，所以date[1]都是越界操作。

四年一闰，百年不闰，四百年再闰

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


Question: 一个小小的问题『c语言』

是Windows还是Linux下得程序? Linux下会比较麻烦，Windows用_kbhit(), VC++6.0大致如下： while(1) { if(_kbhit())      {      // 有按键      ch = getchar()....      } // 其他移动程序 // 延时程序 }

引用 5 楼 AngryWang 的回复:@tomsoft  这个函数在哪个头文件里？  该函数在conio.h中，VS++可用，记得要有下划线 #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <conio.h>         // <<<====!!!!!  int main() { 	while(1) 		{  		char ch = 0; 		if(_kbhit()) 			{ 			ch = getchar();                         .... 			}                 .... 		} }

回复贴错了。。。

@tomsoft  这个函数在哪个头文件里？

注意fread返回值！

windows下使用winapi循环判断按键按下状态，而不是使用输入动作

得用定时器才行，如果是linux系统的话，用alarm定时发信号， 用signal指定alarm信号触发一个函数就行了


Question: 关于printf()函数运算问题

类似这样的运算，都是有副作用的，不建议这么写，或者不要去研究了。因为a++,a--是跟编译器有关系的。

编译器不同，结果也不通。++a, 在运算之前把a+1， a++, a先做运算，之后a+1

未定义行为，编译器爱怎么都行  关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

这说明你的编译器先编译了第二个a++，此时a=6，然后编译了第一个a++，a= 7，最后编译了第三个a++，最后a = 8. 楼主你把按顺序一个一个输出就不会错了。

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775


Question: 一个小问题

谢谢，现在明白了

for(i = 39; i == -1; --i)  i 的 初值为39，然后判断循环执行表达式是 : i == -1  显然表达式求值结果为false，所以循环体不执行。

是不会被执行 for( i = 39; i >= 0; i--) .....


Question: 求助，关于判断文件是否读取到文件结尾

语义的二义性有人还没理解。

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

试过不可以，读完最后一组，feof还是返回零认为没到文件尾，要再读一次才行，可那样就多malloc了一块空间。。 不过我想起来之前做过的一个作业，照着改了改，程序已经过了 但现在还是有点想知道那个fseek到底肿么肥四。。

文件本身不具有结束符标志，eof只是程序读取失败后向流里面添加的 所以，你这种方式用eof有些问题 1，你可以采取判断fread返回值于要读取的数据长度来判断

用feof(fp1)函数就可以判断文件尾了， 赶紧改改，还可以装

我是不是描述的不清楚啊 我的意思是如果我fread读到了最后一组数，那么我文件指针当前位置的后一位不就是结束标志嘛 那我fseek(fp1,2,SEEK_CUR)应该会出错返回非零吧(超出文件结束位置应该会非零吧?)那不就能进入if然后退出了吗 这么想有错没有呢 。。。我还说帮同学改代码呢，眼瞅着就要装逼失败了，早知道就不强行使用链表了，哭哭...


Question: error C2143: syntax error : missing ';' before 'type'

函数声明要放在函数外，另外，程序有问题，建议将代码都贴出来。

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

改之前和改之后完整代码太长上传不了

引用 2 楼 qingmuzhe 的回复:[quote=引用 1 楼 BadCat2000的回复:]int stu_num(FILE *fq);    放在menu2外边 我也这么改过然后出现好几个警告，直接运行不了了[/quote] 函数定义必须在函数体外，C不支持函数嵌套定义。因此，您之前写法本身就是错的 另外，请确认stu_num这个函数是否被实现 如果修改后仍有警告无法运行，请贴出新的警告错误，或给出完整的程序代码

引用 1 楼 BadCat2000的回复:int stu_num(FILE *fq);    放在menu2外边 我也这么改过然后出现好几个警告，直接运行不了了

int stu_num(FILE *fq);    放在menu2外边

未引用变量，是警告信息，不打紧； 只是说这些变量定义后没有被引用，通常不需要改，若一定要修改，根据警告行号找相应代码就可以了。 （我没有用过VC++6.0，我通常用clang，提示信息会清楚一些，但大同小异）  如果只是这类错误，造成结果不对，请仔细检查您程序的逻辑


Question: 求两链表交集.貌似进入死循环..

#include<stdio.h> #include <stdlib.h> #include<malloc.h>  typedef struct Node {     int data;     struct Node *next; }Node,*LinkList;  int CreatList(LinkList *L) {     int i;     Node *p, *last;      *L=(LinkList)malloc(sizeof(Node));     (*L)->data = 0;     (*L)->next = NULL;     last = *L;     while(scanf("%d", &i) && i != -1) {         p = (Node *)malloc(sizeof(Node));         p->data = i;         p->next = NULL;         last->next = p;         last = p;     }     return 0; } void fun(LinkList S1,LinkList S2,LinkList *S3) {     Node *p, *q, *r;     p = S1->next;     q = S2->next;     (*S3) = (LinkList)malloc(sizeof(struct Node));     (*S3)->next = NULL;     r = (*S3);     while(p && q)     {         if(p->data < q->data)             p = p->next;         else if(p->data>q->data)             q = q->next;         else         {             r->next = p;             r = p;             p = p->next;             q = q->next;         }     }     r->next = NULL; } void Print(LinkList L) {     Node *p;     p = L->next;     if(!p)         printf("NULL\n");     else     {         while(p->next)         {             printf("%d ",p->data);             p = p->next;         }         printf("%d\n", p->data);     } } int main() {     LinkList S1,S2,S3;     CreatList(&S1);     Print(S1);     getchar();     CreatList(&S2);     Print(S2);     fun(S1,S2, &S3);     Print(S3);     return 0; }  问题主要是以下几点： 1. while(scanf("%d",&i),i!=-1)，逗号运算符，对于scanf的返回不做判断，只是以i != 1作为while的判断，将逗号运算符改成 && 2. 输出时，if(p=NULL) 改成if (p == NULL)或者if (!p) 3. 以上两点是语法错误，fun是逻辑错误。 下面是我的修改，作为一个参考： #include<stdio.h> #include <stdlib.h> #include<malloc.h>  typedef struct Node {     int data;     struct Node *next; }Node,*LinkList;  int CreatList(LinkList *L) {     int i;     Node *p, *last;      *L=(LinkList)malloc(sizeof(Node));     (*L)->data = 0;     (*L)->next = NULL;     last = *L;     while(scanf("%d", &i) && i != -1) {         p = (Node *)malloc(sizeof(Node));         p->data = i;         p->next = NULL;         last->next = p;         last = p;     }     return 0; } void fun(LinkList S1,LinkList S2,LinkList *S3) {     Node *p, *q, *r;     p = S1->next;     q = S2->next;     (*S3) = (LinkList)malloc(sizeof(struct Node));     (*S3)->next = NULL;     r = (*S3);     while(p && q)     {         if(p->data < q->data)             p = p->next;         else if(p->data>q->data)             q = q->next;         else         {             r->next = p;             r = p;             p = p->next;             q = q->next;         }     }     r->next = NULL; } void Print(LinkList L) {     Node *p;     p = L->next;     if(!p)         printf("NULL\n");     else     {         while(p->next)         {             printf("%d ",p->data);             p = p->next;         }         printf("%d\n", p->data);     } } int main() {     LinkList S1,S2,S3;     CreatList(&S1);     Print(S1);     getchar();     CreatList(&S2);     Print(S2);     fun(S1,S2, &S3);     Print(S3);     return 0; }

在调试模式运行，出错时点中断，通过调用堆栈定位到相关位置观察分析原因

fun(S1, S2, S3); 这里的S3，还没有初始化，你就使用了

说什么非降序就是升序

引用 2 楼 paschen 的回复:if (p = NULL) printf("NULL");  改成：  if (p == NULL) printf("NULL");  奥这个后来我改了的 这里忘记说了。。S3初始化后也还是会程序停止运行


Question: 遇到了个从没遇到的问题

引用 1 楼 qq_20553613 的回复:[quote=引用 楼主 tc1hen 的回复:] 操作系统（AIX 64位），一个函数完成的功能是，发送和接收XML报文，存储这个XML报文的局部变量最大长度是1024 * 96，这个函数中还定义了其他局部变量，发送之前还有值，非常疑惑的一点是，当接收到报文时，大概40000多字节，那些其他这个函数中局部变量的内容都被冲成返回的XML报文字符串的内容了，这是我从来没遇到过的，谁能帮我解释下为何会出现这种情况，每个局部变量的名字都不一样，难道地址还会冲突吗？ 这么大的内存，要从堆上分配，手动malloc一段内存呗。[/quote] 之前也是想这样做来的，但是我这次对系统架构的改造，通讯这块能不动尽量不动，至于为什么不动，你懂得

引用 3 楼 tomsoft 的回复:Sorry，想了一下，不是堆栈溢出，刚在我系统中看了一下，我的64位系统的堆栈大小是8M，而从现象上看并不像堆栈溢出。您仍可以用ulimit -a确认一下，我相信栈大小应该足够了。通常32位系统可能会有栈的问题。如果是堆栈不够，则程序在返回时会崩溃，而非简单破坏临时变量。 因为临时变量和您定义的数组都是在堆栈中，因此，产生这个问题很显然是数组越界。结合您所说，数组大小96K，而大约读入40K个字符出错，那请您注意检查： 1）96K的数组是字节大小还是字大小。即是96KBytes还是96KWord 2）40K个字符串，请问字串是单字节的吗？如果是多字节的，如汉字或UTF等，40K就会造成读入96KBytes的字符出现数组越界的问题。 是一个宏的用法出现了问题，这个数组实际上定义的长度大小是10240，我改过之后好了，两个宏一个名字，那个发送XML报文的函数所包含的头文件里的宏定义是1024 * 96

引用 3 楼 tomsoft 的回复:Sorry，想了一下，不是堆栈溢出，刚在我系统中看了一下，我的64位系统的堆栈大小是8M，而从现象上看并不像堆栈溢出。您仍可以用ulimit -a确认一下，我相信栈大小应该足够了。通常32位系统可能会有栈的问题。如果是堆栈不够，则程序在返回时会崩溃，而非简单破坏临时变量。 因为临时变量和您定义的数组都是在堆栈中，因此，产生这个问题很显然是数组越界。结合您所说，数组大小96K，而大约读入40K个字符出错，那请您注意检查： 1）96K的数组是字节大小还是字大小。即是96KBytes还是96KWord 2）40K个字符串，请问字串是单字节的吗？如果是多字节的，如汉字或UTF等，40K就会造成读入96KBytes的字符出现数组越界的问题。 谢了兄弟问题找到了，就是数组越界了，把这个函数栈里的内容都覆盖了，

学会使用数据断点：#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; }

AIX的堆栈限制是32768，即实际在差不多这个数值后（比这个值略小），就会破坏堆栈 可以使用ulimit -a看以下您堆栈的设置 试一下ulimit -s unlimited

引用 楼主 tc1hen 的回复:操作系统（AIX 64位），一个函数完成的功能是，发送和接收XML报文，存储这个XML报文的局部变量最大长度是1024 * 96，这个函数中还定义了其他局部变量，发送之前还有值，非常疑惑的一点是，当接收到报文时，大概40000多字节，那些其他这个函数中局部变量的内容都被冲成返回的XML报文字符串的内容了，这是我从来没遇到过的，谁能帮我解释下为何会出现这种情况，每个局部变量的名字都不一样，难道地址还会冲突吗？ 这么大的内存，要从堆上分配，手动malloc一段内存呗。


Question: 关于数组求解

谢谢上面的两位

#include <stdio.h> #include <ctype.h>  #define MAX_STR_LEN     32  int get_digit(char (*digit)[4], char *str);  int main(void) {     char str[MAX_STR_LEN];     char digit[MAX_STR_LEN/3+1][4] = { { 0 } };     int i, cnt;          fgets(str, MAX_STR_LEN, stdin);               cnt = get_digit(digit, str);     printf("total digit number: %d\n", cnt);     for (i = 0; i < cnt; i++)         puts(digit[i]);     return 0; }  int get_digit(char (*digit)[4], char *str) {     int cnt = 0, idx = 0, i = 0;          puts(str);     while (str[i]) {         if (isdigit(str[i])) {             digit[cnt][idx] = str[i];             idx++;             if (idx == 3) {                 digit[cnt][idx] = 0;                 idx = 0;                 cnt++;             }         }         i++;     }     return cnt; } 作为一个参考吧

这题不难，分三个思路： 第一：提取数字 第二：将提取的数据分组 第三：输出 我有一个系列专栏，里面的上string里面涉及了很多这类的问题，我网址发你http://blog.csdn.net/redrnt/article/details/72761861 你这个问题我刚刚写完了 代码发你： #include <iostream> #include <string> #include <cctype> using namespace std; /*函数原型*/  string selectNumbers(string str); int main(){ 	string str,line; 	int j = 0; 	getline(cin,str); 	line = selectNumbers(str); 	const int LENGTH = line.length(); 	/*下面把line存进数组中，然后用substr方法截取长度为3的字符串 	 *然后存进数组a[j]中，每次循环，数组的下标加1*/  	string a[LENGTH]; 	for(int i = 0; i < LENGTH; i += 3){ 		a[j] = line.substr(i, i + 3); 		cout << a[j] << endl; 		j++; 	} 	cout << "共有" << j << "个这样的数";  	 } /*  *函数： selectNumbers  *用法： string line = selectNumbers(str);  *--------------------------------------  *作用: 提取字符串中的数字，并返回新的由数字组成的字符串  */  string selectNumbers(string str){ 	string line = ""; 	for(int i = 0; i < str.length(); i++){ 		if(isdigit(str[i])){ 			line += str[i]; 		} 	} 	return line; } 测试结果：


Question: 请问 k&r 定义的函数格式，有工具能自动转换为ansi 的吗？

如果这样子的很多而且很乱，可以自己写个小程序专门处理这个

如果这样的函数定义格式不多，建议手动改吧，暂没听说过有这样的软件。


Question: 数据结构链表出错，链表无限输出数据，求大神

InitList函数里面的  (*ll)->data = NULL; 改成  (*ll)->next = NULL;

void InitList(LinkList *ll,int n){     int i;     *ll = (LinkList)malloc(sizeof(LinkList));     (*ll)->data = 0;   /* 若将NULL赋值给data，我想编译器应该会提示警告吧 */     (*ll)->next = NULL;    /*我想你是初始化next的，但是却初始化了data */     for(i=1;i<10;i++){         LinkList p=(LinkList)malloc(sizeof(LinkList));         p->data = n*i;         p->next = (*ll)->next;         (*ll)->next = p;     }     LinkList p=(*ll)->next;     while(p){          printf("p: %d ,",p->data);         p=p->next;     }     printf("\n"); } 注意即使是编译程序时提示警告，也尽可能的去掉警告


Question: 求助：资源中的JPG图片为何不工作？

不懂，但是也想知道。


Question: 求助：用C实现汉信码的生成

百度搜相关官方说明文档或例子代码。


Question: 变参函数加打印

#define printf_func(a, ...)  (printf("the first parameter is %d\n",a), func(a, ##__VA_ARGS__))

试试  int printf_func(int a, ...) {     va_list args;     va_start(args, a);     func(a, args);     va_end(args); }

Calls with a Variable Number of Arguments A partial parameter list can be terminated by the ellipsis notation, a comma followed by three periods (, ...), to indicate that there may be more arguments passed to the function, but no more information is given about them. Type checking is not performed on such arguments. At least one parameter must precede the ellipsis notation and the ellipsis notation must be the last token in the parameter list. Without the ellipsis notation, the behavior of a function is undefined if it receives parameters in addition to those declared in the parameter list.   To call a function with a variable number of arguments, simply specify any number of arguments in the function call. An example is the printf function from the C run-time library. The function call must include one argument for each type name declared in the parameter list or the list of argument types.   All the arguments specified in the function call are placed on the stack unless the __fastcall calling convention is specified. The number of parameters declared for the function determines how many of the arguments are taken from the stack and assigned to the parameters. You are responsible for retrieving any additional arguments from the stack and for determining how many arguments are present. The STDARGS.H file contains ANSI-style macros for accessing arguments of functions which take a variable number of arguments. Also, the XENIX®- style macros in VARARGS.H are still supported.  This sample declaration is for a function that calls a variable number of arguments:    int average( int first, ...);  Microsoft Specific —>  To maintain compatibility with previous versions of Microsoft C, a Microsoft extension to the ANSI C standard allows a comma without trailing periods (,) at the end of the list of parameters to indicate a variable number of arguments. However, it is recommended that code be changed to incorporate the ellipsis notation.  END Microsoft Specific


Question: C语言创建链表问题

你要在函数中修改指针本身，那你需要传入一个二级指针

你的CreateList参数是按值传递的  函数中的headList只是一个复制品  LNode *headNode = new LNode; headList = headNode;  上面语句及之后的语句只是对一个复制品进行修改  主函数中的指针当然不会有变化

#include"Student.h" #include<iostream> using namespace std;  void CreateList(LNode **headList) {     //LNode *headList;     LNode *headNode=new LNode;     *headList=headNode;     LNode *stu1=new LNode;     LNode *nodeTemp=NULL;  //定义临时变量     stu1->ptrNext=NULL;     headNode->ptrNext=stu1;     cout<<"Please input Student Information (If finish,please input 0 on Student Number )"<<endl;     cout<<"Input form: Number Name birthYear birthMonth birthday gender(Male or Female)  "<<endl;     cin>>stu1->stuInfomation.nNumber;      //输入第一个学号     int ntmpNumber=stu1->stuInfomation.nNumber;     while(ntmpNumber!=0)     {         cin>>stu1->stuInfomation.strName;         cin>>stu1->stuInfomation.birthDate.nYear>>stu1->stuInfomation.birthDate.nMonth>>stu1->stuInfomation.birthDate.nDay;         cin>>stu1->stuInfomation.strGender;         nodeTemp=stu1;         stu1=new LNode;         nodeTemp->ptrNext=stu1;         cin>>stu1->stuInfomation.nNumber;         ntmpNumber=stu1->stuInfomation.nNumber;     }     delete stu1; //当用户输入0结束后,stu1没有任何信息，应先释放;     nodeTemp->ptrNext=NULL; //由于释放了stu1，所以nodeTemp是最后一个结点，给next指针赋NULL;  }  int main() {     LNode *L = NULL; //记得delete     CreateList(&L);     cout<<"Why"<<endl;     L=L->ptrNext;     cout<<L->stuInfomation.nNumber<<endl;     L=L->ptrNext;     cout<<L->stuInfomation.nNumber<<endl;     cin.get();     cin.get();     return 0;  } 试试传递二重指针，另外，main函数里的L指向NULL； 若函数在调用函数之前，就不用再声明了。

你在函数外面new了一个，到里面又new一个，你要么直接把外面new的那个当成头结点不存数据，把数据都挂在这个头结点的后面，要么就传指针的引用进去，全部在函数内部加数据。


Question: EMCV库编译问题

估计是CCS2.2不支持C++2011标准，long long是该标准才明确增加的类型


Question: 按值插入有序单链表，使之依旧有序

while(s->next->data<m) s=s->next; //这里s->next可能为空，s->next->data这样访问会崩溃的 s->next && s->next->data < m;//应该改成这样

#include <stdio.h> #include<malloc.h>   typedef struct Node {     int data;     struct Node *next; }Node,*LinkList;  void InsertList(LinkList *L,int m) {     Node *t,*s;     s = *L;       while (s->next && s->next->data < m) {         s = s->next;     }      //while(s->next->data < m)     //    s = s->next;     t = (Node *)malloc(sizeof(Node));     t->data = m;     t->next = s->next;     s->next = t; } void Print(LinkList L) {     Node *p;     p = L->next;     while(p->next)     {         printf("%d ",p->data);         p = p->next;     }     printf("%d\n", p->data); } int main() {     LinkList L;     int i,a,m,n;     Node *last,*p;     L=(LinkList)malloc(sizeof(Node));     L->data = 0;     L->next = NULL;     last = L;     //输入个数和待插入数     scanf("%d%d", &n, &m);     //输入序列     for(i=0;i<n;i++)     {         scanf("%d",&a);         p=(Node*)malloc(sizeof(Node));         p->data=a;         p->next=NULL;         last->next=p;         last=p;     }     InsertList(&L,m);     Print(L);      return 0; }   while (s->next && s->next->data < m) {         s = s->next;     } //对比一下     //while(s->next->data < m)     //    s = s->next; 若不判断s->next是否为NULL，那么s->next->data < m就可能导致段错误。因为s->next可能为NULL

这个程序不是可以实现么？


Question: 为什么下面这个数据结构里把结构体声明为Node，结构体中的指针域也是一个Node

你完全可以声明为 void * 每次再转一遍，只要你不嫌麻烦。

引用 3 楼 sleep_s 的回复:链表是有数据和指向下一个地址的指针组成的。无论结构体里多少个数据，必须要有一个地址指针 那为什么这个地址指针是用他本身声明的呢？→因为链表的节点都是同一种类型。

链表啊。Node类型指针next指向下一个节点，如此类推，形成链式结构

建议看一下链表的相关知识，看别人如何写链表的。

引用 4 楼 u011342403 的回复:[quote=引用 3 楼 sleep_s 的回复:] 链表是有数据和指向下一个地址的指针组成的。无论结构体里多少个数据，必须要有一个地址指针 那为什么这个地址指针是用他本身声明的呢？[/quote] 因为用本身结构体声明后，这个指针指向的地址也是一个具有数据和指针的结构体（也就是是本身结构体里面的内容）

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

int  *p = malloc(10); 分配了10个int的空间，没有说是10个char空间。 同样链表中一个节点可以看着|--data--|--next--|，这是一个空间，而next是一个point，是指向下一个节点的指针，下一个节点是什么， 是一个struct node结构体，所以这个node也要是对应的类型。

有什么问题吗  结构体中是一个Node*的指针，可以指向下一个对象，这样可以形成一个链

引用 1 楼 user-8 的回复:首先指针本身的大小是固定的，不是4字节就是8字节（编译器选x86就是4字节，选x64就是8字节），其次结构体本身中存放一个本身数据类型的指针，其目的显而易见，就是形成链表，可方便顺序访问查找。 为什么存放一个本身数据类型的指针就是为了形成链表，有什么原因吗。能详细说一下吗？


Question: 请教printf缓冲区。

你说的这种情况只是指逗留在缓冲区的数据  它不保证数据能立即输出，也不能保证全部的数据都能立即输出。 但是到遇到那几种情况下，缓冲区会被清空  C追求性能，所以输出时机由更系统自由地控制，遇到某些情形之下才进行干涉。 类似于医院的门诊和急症？

在每个最后不带\n的printf后面加fflush(stdout);

只是说 当缓冲区满、遇到换行字符或需要输入的时候 会清空缓冲区  但没说其他时候一定不会清空  编译器和系统可以进行优化  控制台的输出一般都会直接看得到，但对文件的输出可能就不会立即写入了，可能就会等到缓冲区满才写入

该程序只是打印test就执行结束了。既然程序执行结束了，那么系统就要回收它占用的内存。回收的过程中，将停留在内存的数据刷到文件中（标准输出也是文件），将输出缓冲区里的数据也一并清除，所以它肯定会输出的。

int main(void) {     printf("test");     sleep(5); } 这样要等5秒后才能看到test，5秒之前test一直是在系统的buffer里的，之于你的问题，这些都是由操作系统帮你处理的。因为return 0，这时你的main程序都结束了，这时操作系统自然会对Main程序占用的buffer要做flush处理。具体的可以看看linux系统编程相关的书。


Question: 在创建管道应用时，strcat函数时灵时不灵，大多数会报错？

好像不是这个原因，我刚改了result字符串的长度就行了，好像是result字符串长度不够，无法全部接受str的字符，导致溢出

strcat 的两个参数都要求是以\0结尾的字符串，你的第二个参数不一定满足  http://en.cppreference.com/w/c/string/byte/strcat


Question: Linux下socket编程问题

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

引用 9楼自信男孩 的回复:if((ret = read(sockfd, buffer, sizeof(buffer)-1) ) < 0) 问题主要出在这儿，仔细对比一下client程序里的这句。 写代码注意不要太随意哦，  以下是client的完整代码： #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <netdb.h>  #define RET_ERR    -1 #define RET_OK    0 #define BUFFERSIZE    1024 #define ECHO_PORT    2029  int main(int argc, char *argv[]) {     int sockfd;     struct sockaddr_in servaddr;     struct hostent *server;     char buffer[BUFFERSIZE];     int ret;      if(argc < 2)     {         fprintf(stderr, "Usage:%s hostname\n", argv[0]);         return RET_ERR;     }      if((server=gethostbyname(argv[1])) == NULL)     {         hstrerror(h_errno);         return RET_ERR;     }      if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) < 0)     {         perror("ERROR opening socket");         return RET_ERR;     }      memset(&servaddr, 0, sizeof(servaddr));     servaddr.sin_family = AF_INET;     servaddr.sin_addr.s_addr = *(uint32_t *)server->h_addr;     servaddr.sin_port = htons((uint16_t)ECHO_PORT);      if((ret=connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0)     {         perror("ERROR connecting");         close(sockfd);         return RET_ERR;     }       while(1)     {         if(fgets(buffer, sizeof(buffer)-1, stdin) == NULL)         {             break;         }          if((ret=write(sockfd, buffer, strlen(buffer)) < 0))         {             perror("ERROR writing from socket");             break;         }         printf("send buffer = %s", buffer);          if((ret = read(sockfd, buffer, sizeof(buffer)-1) ) < 0)         {             perror("ERROR reading from socket");             break;         }         if(ret == 0)         {             printf("server disconnect\n");             break;         }          buffer[ret] = '\0';         printf("receive message:%s\n", buffer);      }      close(sockfd);      return RET_OK; }好low的错误，最近自己想重新回顾一下socket的代码，一开始碰到错误就懵了，感觉不会玩了，谢谢

引用 7楼自信男孩 的回复:[quote=引用 5 楼 mark_qzh 的回复:] [quote=引用 2楼JXES 的回复:] if (ret == 0)  {      close(nsock);     break; }server端收到消息就返回了，但是好像cliemt端没收到[/quote] 你的client发完就关闭socket了，服务器即使收到了你发的，但服务器还没发呢，你已经关了socket了，那客户端还怎么接收（client已经关了）[/quote]client不是阻塞的吗？他不是应该等待server端发送信息过来吗……难道read是非阻塞的吗

引用 5 楼 mark_qzh 的回复:[quote=引用 2楼JXES 的回复:] if (ret == 0)  {      close(nsock);     break; }server端收到消息就返回了，但是好像cliemt端没收到[/quote] 你的client发完就关闭socket了，服务器即使收到了你发的，但服务器还没发呢，你已经关了socket了，那客户端还怎么接收（client已经关了）

引用 1楼JXES 的回复:while(1)         {             if((ret = read(nsock, buffer, sizeof(buffer)-1)) < 0)             {                 perror("Error on read");                 close(nsock);                 close(sockfd);                 return RET_ERR;             } if (ret == 0) break; //不判定=0情况就死循环了             buffer[ret] = '\0';             printf("Server:receive message buffer = %s", buffer);             if((ret = write(nsock, buffer, strlen(buffer))) < 0)             {                 perror("Error on write");                 close(nsock);                 close(sockfd);                 return RET_ERR;             }             printf("Server:send message buffer = %s ret = %d\n", buffer, ret);         }   这里面有问题，循环退不出了，当client没有发时，这里ret = 0,所以在里面要加一句如上。read函数不是阻塞的吗？没有数据它应该阻塞吧

引用 2楼JXES 的回复:if (ret == 0)  {      close(nsock);     break; }server端收到消息就返回了，但是好像cliemt端没收到

引用 2楼JXES 的回复:if (ret == 0)  {      close(nsock);     break; }我现在的问题是我client发了一个字符串过去，client断开连接，server端就进入死循环了

注意，你的判定只是限于发送和接收出错时，若client正常关闭，你没有处理。加上read返回0时，直接close(nsock);

if (ret == 0)  {      close(nsock);     break; }


Question: 关于 c  头文件枚举使用的问题

要编译得有一个完整的程序，你可以添加将你的头文件添加到工程，并写一个main函数，函数中可以什么都不写，如果你前面的定义没问题的话是可以通过编译的，有问题的话就会提示错误

只有实际编译一下，才会知道。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

// main.c int main() {     acctngInterfaceEntry_PARAM_S aps = { true };     return 0; }

做好的方法就是写个简单的小程序，然后通过输出测试一下；如下：  #include <stdio.h>  typedef enum {     true = 1,     false = 2 }TRUEORFALSE_E;  typedef struct acctngInterfaceEntry_Table_PARAM {     TRUEORFALSE_E  acctngInterfaceEnable; }acctngInterfaceEntry_PARAM_S;   int main(void) {     acctngInterfaceEntry_PARAM_S param;      param.acctngInterfaceEnable = true;      printf("param = %d\n", param.acctngInterfaceEnable);      return 0; }  另外，TRUEORFALSE_E是枚举类型的变量，不是类型。如果想做为类型，需要typedef一下： typedef enum  flag {     true = 1,     false = 2 }TRUEORFALSE_E;


Question: 一道线性表的oj题编译出错

应该是oj上的编译选项较高，也就是更为严格。普通编译器，void *转其他指针类型是不需要强转的。这也是为什么你用VC++可以编译通过的原因； l = (struct sheet *)malloc(sizeof(struct sheet)); 还有： p = (struct sheet *)malloc(sizeof(struct sheet)); 这个地方是错误的，应去掉前面的& scanf("%s", choice); 数组名本身就是数组的首地址，可以看成指针常量。

兄弟，行号不都给你了吗，13行和29行，malloc函数返回的是void*，你要显式地转成sheet*才行，有的编译器是会报这种错的。


Question: 编译原理-讨论

无源码，无技术含量。

引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 jiftlixu 的回复:] 因为开发的是脚本解释器，代码需要解释执行的。 参考Lua源代码？[/quote]  太无语了,这些代码都在研究... 只是探讨下理论,能不能回答问题有点技术含量.

计算表达式本身也是等价变换。常数折叠是一种常见的提早发生的表达式求值。 没什么应该不应该，就看语言是怎么设计的，需求是怎么样的。

引用 6 楼 jiftlixu 的回复:因为开发的是脚本解释器，代码需要解释执行的。 参考Lua源代码？

因为开发的是脚本解释器，代码需要解释执行的。

语义分析时太早了  词法分析 语义分析 词义分析与中间代码产生 优化 目标代码生成   在优化阶段再对表达式求值  http://blog.csdn.net/alextan_/article/details/51246794

参考Tiny C Compiler源代码。

一般简单的就求，  复杂点的还是到代码生成， 编译优化的时候求。

编译的时候，宏定义会被替换（但是仅是等价替换），也不会计算表达式的值。

编译阶段是不会对表达式求值的，因为计算（表达式）是需要在内存里，运行阶段才会做的事情。


Question: 右移和 &0xff

怎么赋值就反向提取  赋值是右移，提取时就左移  把各个位重新组合到相应位置就还原了  建议拿个纸在上面画一下容易明白

引用 2 楼 CKRGD 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 你的移位操作并没有将gx.latitude 和   gx.nshemi修改，它们还是原来的值。因为你的移位只是对变量值的读操作，并没有写（修改） 关键是我不知道它们原来的值，我是收到下位机数据 3D 17 A5 4E 00  知道他是这么操作，我需要计算gx.latitude gx.nshemi的值[/quote]  m_data.p_packet_data[strlen++]=gx.latitude>>24; // 最高字节 m_data.p_packet_data[strlen++]=(gx.latitude>>16)&0xFF;// 次高字节 m_data.p_packet_data[strlen++]=(gx.latitude>>8)&0xFF; //第三个字节 m_data.p_packet_data[strlen++]=(gx.latitude)&0xFF; // 最低字节；  每个字节都知道是什么值了，再去求gx.latitude，通过移位过去就好了。 gx.nshemi这个值不需要移位就可以。

unsigned char buf[1024]={0x3D, 0x17, 0xA5, 0x4E, 0x00}; 	long latitude=((long)buf[0])<<24 | ((long)buf[1])<<16 | ((long)buf[2])<<8 | ((long)buf[3]); 	unsigned char nshemi=buf[4]; 	printf("%ld \t", latitude); 	printf("%c \t", nshemi);  	//验证 	unsigned char data[1024]; 	data[0]=latitude>>24; // 18 	data[1]=(latitude>>16)&0xFF;// 19  	data[2]=(latitude>>8)&0xFF; // 20 	data[3]=(latitude)&0xFF; // 21 	data[4]=nshemi;  //22  	for(int i = 0; i < 5; i++) 	{ 		printf("%x   ", data[i]); 	} //结果  1024959822          3d  17  a5  4e  0     感谢6楼

unsigned char buf[1024]={0x3D,0x17,0xA5,0x4E,0x00}; long latitude=((long)buf[0])<<24|((long)buf[1])<<16|((long)buf[2])<<8|((long)buf[3]); unsigned char nshemi=buf[4];

LZ你代码没贴全吧？右移n位，可以看成是乘以2的n次方，&0xff是求某一位的值。另外printf("%x ",m_data.p_packet_data[xxx]);xxx具体指哪一位的值？你都没说清楚。3楼已经告诉你了正确答案，m_data.p_packet_data[i]中的i就是你的xxx

引用 3 楼 zhao4zhong1 的回复:m_data.p_packet_data[strlen++]=gx.latitude>>24; // 18 m_data.p_packet_data[strlen++]=(gx.latitude>>16)&0xFF;// 19  m_data.p_packet_data[strlen++]=(gx.latitude>>8)&0xFF; // 20 m_data.p_packet_data[strlen++]=(gx.latitude)&0xFF; // 21 m_data.p_packet_data[strlen++]=gx.nshemi;  3D       17       A5       4E       00 00111101 00010111 10100101 01001110 00000000 gx.latitude                         gx.nshemi 0x3D17A54E                          0x00  int i=strlen-5;//18 gx.latitude=*(long *)&m_data.p_packet_data[i]; gx.nshemi=*(unsigned char *)&m_data.p_packet_data[i+4];  没看懂，我没有那个变量m_data.p_packet_data[i]， 我是收到下位机数据3D       17       A5       4E       00  下位机是那样计算

引用 1 楼 cfjtaishan 的回复:你的移位操作并没有将gx.latitude 和   gx.nshemi修改，它们还是原来的值。因为你的移位只是对变量值的读操作，并没有写（修改） 关键是我不知道它们原来的值，我是收到下位机数据 3D 17 A5 4E 00  知道他是这么操作，我需要计算gx.latitude gx.nshemi的值

你下位机给你的是一个4字节的数据，所以按6楼的方法是对的


Question: 数据结构的实现里，SqList L和SqList *L有什么区别

第一种参数是传结构体变量，但是SeqlistInsert之后，不能将新的插入数据带回（或者说是更新）； 第二种参数是传结构体指针，调用SeqlistInsert之后，能将新的插入带回调用函数；因为它传递的是地址，在SeqlistInsert函数里对L的操作就是对调用函数里L的操作。  引用 7 楼 u011342403 的回复:[quote=引用 6 楼 paschen 的回复:] 第一种是传值，相当于函数中只能使用这个结构体的数据，但修改并不会生效，因为是复制传递的  第二种是传址，传的是地址，函数中可以使用结构体数据，也可以修改结构体数据 那为什么还会有人用第一种方式去做数据结构的实现呢?如果修改都实现不了，那不是没意义吗？[/quote] 主要是函数，根据函数功能来确定是否要传指针。比如你的这个函数是插入，那么就要修改L的内容，并要获得修改之后的数据，那就需要传指针。

引用 4 楼 cfjtaishan 的回复:第一种参数是传结构体变量，但是SeqlistInsert之后，不能将新的插入数据带回（或者说是更新）； 第二种参数是传结构体指针，调用SeqlistInsert之后，能将新的插入带回调用函数；因为它传递的是地址，在SeqlistInsert函数里对L的操作就是对调用函数里L的操作。  也就是说第一种方式对原来的数据结构没有改变。第二种才是真正的插入了数据？

引用 6 楼 paschen 的回复:第一种是传值，相当于函数中只能使用这个结构体的数据，但修改并不会生效，因为是复制传递的  第二种是传址，传的是地址，函数中可以使用结构体数据，也可以修改结构体数据 那为什么还会有人用第一种方式去做数据结构的实现呢?如果修改都实现不了，那不是没意义吗？

理解和讨论之前请先学会如何观察！  //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]

struct结构也是一种数据类型，所以这里你可以对照函数传参去理解，按值传参与按地址传参这两个能分清，这个问题也就理解了。

引用 1 楼 user-5 的回复:一种是传值，一种是传指针，后者在函数里改变结构体的数据后上级函数里也能得到修改后的数据 引用 1 楼 user-5 的回复:一种是传值，一种是传指针，后者在函数里改变结构体的数据后上级函数里也能得到修改后的数据  我看了别人的实现方式，用*L声明的在用的时候还是对L进行的操作，那么这个时候的*L代表什么，L又代表什么。 nt InsertSeqList(SeqList* L,int i,DataType x) //对顺序表进行插入操作，插入格式如(1,a) { int j; if (L->length==L->listsize)     {       cout<<"\t\t\t顺序表已满";       return 0;     } else {    if (i<1||i>L->length+1) {        cout<<"\t\t\t位置不合法";        return 0;     }     else       {         for(j=L->length;j>=i;j--)           {             L->elem[j+1]=L->elem[j];           }    L->elem[i]=x;    L->length++;         return 1;       } } }

引用 8 楼 u011342403 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 第一种参数是传结构体变量，但是SeqlistInsert之后，不能将新的插入数据带回（或者说是更新）； 第二种参数是传结构体指针，调用SeqlistInsert之后，能将新的插入带回调用函数；因为它传递的是地址，在SeqlistInsert函数里对L的操作就是对调用函数里L的操作。  也就是说第一种方式对原来的数据结构没有改变。第二种才是真正的插入了数据？[/quote]  是的，第一种只是复制了一个一样的结构体到函数中，函数中使用的参数只是一个复制品，修改并不会反映到原结构体对象上


Question: 求助！引发了异常: 读取访问权限冲突。s 是 0xCCCCCCCC。

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

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             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=v;                 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-> //

cc 分配了但是未被初始化的内存区域

引用 楼主 qq_38870629 的回复:#include "stdio.h"   #include "math.h" #include "stdlib.h" //exit()   typedef int DataType; #include "malloc.h" //malloc()      typedef struct Node { 	DataType data; 	struct Node *next; } SLNode;  void ListInitiate(SLNode **head) { 	if ((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1); 	(*head)->next = NULL; }  //在带头节点的单链表head的第i（0<=i<=size）个结点前插入   int ListInsert(SLNode * head, int i, DataType x) { 	SLNode *p, *q; 	int j;  	p = head; 	j = -1; 	//其实就是i-1-(-1)=i次，把p指针移到第i-1个结点上,因为结点从0开始   	while (p->next != NULL && j < i - 1) 	{ 		p = p->next; 		j++; 	}  	if (j != i - 1) 	{ 		printf("insert error !/n"); 		return 0; 	}  	if ((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1); 	q->data = x;  	q->next = p->next; 	p->next = q; 	return 1;  }  //释放动态申请的内存空间   void Destroy(SLNode * *head) { 	SLNode *p, *p1; 	p = *head; 	while (p != NULL) 	{ 		p1 = p; 		p = p->next; 		free(p1); 	} 	*head = NULL; } void  Buildloop(SLNode *head, SLNode *head2, DataType m, DataType n) { 	int flag1 = 0, flag2 = 0; 	SLNode *p, *q, *r, *s; 	p = head->next; 	q = head2; 	 	while (p != NULL) 	{ 		if (p->data ==m ) { 			flag1++; 			if (flag1 == 1) { 				r = (SLNode *)malloc(sizeof(SLNode)); 				r->data = m; 				r->next = p->next; 			  			} 		} 		if (p->data == n) { 			flag2++; 			if (flag2 == 1) { 				s = (SLNode *)malloc(sizeof(SLNode)); 				s->data = n; 				s->next = p->next; 				//s = p; 			} 			if (flag1 == 1 && flag2 == 1)  				break; 			 		} 		/*if (s->next = NULL) { 			s->next = r; 		}*/  		head2->next = s->next; 		s->next = r;  		while (q->next != NULL) { 			q = q->next; 		} 		q->next = r;    	} } int FindLoopNode(SLNode *head, int j) { 	int i = j, begin = 1; 	SLNode *fast = head, *slow = head; 	for (i; i > 0; i--) { 		fast = fast->next; 	} 	slow = head; 	while (slow != fast) { 		begin++; 		slow = slow->next; 		fast = fast->next; 	} 	return begin; }   int IsExitsloop(SLNode *head) { 	SLNode *slow = head; 	SLNode *fast = head; 	int i, j = 1;  	while (fast&&fast->next) 	{ 		slow = slow->next; 		fast = fast->next->next; 		if (slow == fast)break; 	} 	if (fast == NULL || fast->next == NULL) { 		printf("该链表不存在环！\n"); 	} 	else { 		printf("该链表存在环！\n"); 		while (fast&&fast->next) { 			slow = slow->next;//fast与slow相遇后，slow并没有遍历完链表，继续遍历 			j++; 			if (slow->next == fast)break; 		} 	} 	i = FindLoopNode(head, j); 	printf("环的起始位置为:%d\n", i); 	printf("环的结束位置为:%d\n", j + i - 1); 	return 0; } int ListLength(SLNode *head) { 	SLNode *slow = head->next, *fast = head->next; 	int length = 1; 	while (fast&&fast->next) { 		slow = slow->next; 		fast = fast->next->next; 		if (slow == fast) 		{ 			while (fast&&fast->next) 			{ 				slow = slow->next; 				length++; 				if (slow->next == fast)break; 			} 			break; 		} 	} 	return length; } void ReList(SLNode *head) { 	SLNode *p = head, *q = head; 	int length = ListLength(head); 	for (; length > 0; length--)p = p->next; 	while (p != q) 	{ 		q = q->next; 		if (p->next == q) 		{ 			p->next = NULL; 			break; 		} 		p = p->next; 	} } void IsIntersect(SLNode *head, SLNode *head2) { 	SLNode *p, *q; 	p = head; 	q = head2; 	int i = 0, flag = 0; 	while (p->next != NULL) 	{ 		i++; 		p = p->next; 		while (q->next != NULL) 		{ 			q = q->next; 			if (p == q) { 				flag = 1; 				printf("链表存在相交位置，位置为%d\n",i); 				break; 			} 		} 		if (flag == 1)break; 	} 	if (flag != 1) 		printf("链表不相交！"); } #pragma once s->next = r;这里的s指针可能还是NULL，赋值前最后判定下，因前面s = (SLNode *)malloc(sizeof(SLNode));这句不一定执行到。

head2->next = s->next;         s->next = r;  这里，如果if (p->data == n)条件不满足，那么s->next肯定是有问题的，所以这儿有潜在的bug. 做如下修改，试试： void  Buildloop(SLNode *head, SLNode *head2, DataType m, DataType n) {     int flag1 = 0, flag2 = 0;     SLNode *p, *q, *r = NULL, *s = NULL;     p = head->next;     q = head2;      while (p != NULL)     {         if (p->data ==m ) {             flag1++;             if (flag1 == 1) {                 r = (SLNode *)malloc(sizeof(SLNode));                 r->data = m;                 r->next = p->next;               }         }         if (p->data == n) {             flag2++;             if (flag2 == 1) {                 s = (SLNode *)malloc(sizeof(SLNode));                 s->data = n;                 s->next = p->next;                 //s = p;             }             if (flag1 == 1 && flag2 == 1)                 break;          }         /*if (s->next = NULL) {           s->next = r;           }*/         if (s) {    /*判断一下s*/             head2->next = s->next;             s->next = r;         }           while (q->next != NULL) {             q = q->next;         }         q->next = r;     } }

#include "stdio.h"   #include "stdlib.h" //exit()   #include "malloc.h" //malloc()     typedef int DataType; #include "NLinlist.h"    int main() {  	char a = 'Y'; 	SLNode *head, *head2, *p,*q; 	int i,j, number, ii, m, n; 	//int ninsertx, ninserty, ndeletex, npreviousx, ninsertm, ninsertn; 	//初始化链表 	ListInitiate(&head); 	ListInitiate(&head2);  	printf("请输入链表的数据元素个数:\n"); 	scanf("%d", &number); 	printf("\n请一个一个的输入元素值:\n"); 	for (i = 0; i < number; i++) 	{ 		scanf("%d", &ii); 		ListInsert(head, i, ii); 	} 	printf("你输入的链表是:\n"); 	p = head->next; 	while (p != NULL) 	{ 		printf("%d  ", p->data); 		p = p->next; 	} 	printf("\n请输入要成环的两个元素的值:\n"); 	scanf("%d%d", &m,&n); 	//printf("%d%d", m, n); 	//scanf("%d", &n); 	Buildloop(head, head2, m, n); 	/*p = head->next; 	q = head2->next; 	while (q != NULL) 	{ 		printf("%d  ", p->data); 		p = p->next; 		printf("%d  ", q->data); 		q = q->next;   	}*/ 	FindLoopNode(head,j); 	IsExitsloop(head); 	ListLength(head); 	ReList(head); 	IsIntersect(head, head2); } 	 这里

你的main函数呢？


Question: 单个宽字符输出问题？

fflush(stdout);

wprintf(L"%lc", wch);


Question: 数据结构与算法分析

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组 http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组

《数据结构（C语言描述）》 《算法精解（C语言描述）》 为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

适合初学数据结构的计算机学生吗？

《数据结构与算法》、《C和指针》

代码少的，理论性比较强，建议理论多联系实践，这样更有利于提高对理论的理解。

能给自己带来技能的书都是好书


Question: 新手学C语言有道题目不会

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

谢谢，最下面那个for是什么用，没看懂

#include<stdio.h> #include<string.h>  #define N 80  int main(void) {     char s[N];     int i, j;     int len, pos;      printf("Enter a sentence:");     for(i = 0; i < N; i++) {         s[i] = getchar();         if ((s[i] == '.') || (s[i] == '!') || (s[i] == '?'))             break;     }      len = strlen(s);     pos = len - 1;     for (i = strlen(s) - 1; i >= 0; i--) {         if (s[i] == ' ') {             for(j = i + 1; j < pos; j++)                 printf("%c", s[j]);             printf(" ");             pos = i;         }      }     for(j = i + 1; j < pos; j++)         printf("%c", s[j]);      printf("%c", s[len - 1]);     printf("\n");     return 0; }


Question: 从文件中读取数据到数组中

fscanf 将3个数先读到3个临时变量中，然后进行赋值

fscanf/fprintf，  int i, j, val; fscanf(fp, "%d %d %d\n", i, j, val);  array[i][j] = val;


Question: mktime函数如何实现

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\mktime.c /*** *mktime.c - Convert struct tm value to __time32_t value. * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       Defines _mktime32() and _mkgmtime32(), routines to converts a time value *       in a tm structure (possibly incomplete) into a __time32_t value, then *       update (all) the structure fields with "normalized" values. * *******************************************************************************/  #include <cruntime.h> #include <stddef.h> #include <ctime.h> #include <time.h> #include <internal.h>  /*  * ChkAdd evaluates to TRUE if dest = src1 + src2 has overflowed  */ #define ChkAdd(dest, src1, src2)   ( ((src1 >= 0L) && (src2 >= 0L) \     && (dest < 0L)) || ((src1 < 0L) && (src2 < 0L) && (dest >= 0L)) )  /*  * ChkMul evaluates to TRUE if dest = src1 * src2 has overflowed  */ #define ChkMul(dest, src1, src2)   ( src1 ? (dest/src1 != src2) : 0 )   /*  * Core function for both _mktime32() and _mkgmtime32()  */ static __time32_t __cdecl _make__time32_t( struct tm *, int);   /*** *__time32_t _mktime32(tb) - Normalize user time block structure * *Purpose: *       _mktime32 converts a time structure, passed in as an argument, into a *       calendar time value in internal format (__time32_t). It also completes *       and updates the fields the of the passed in structure with 'normalized' *       values. There are three practical uses for this routine: * *       (1) Convert broken-down time to internal time format (__time32_t). *       (2) To have _mktime32 fill in the tm_wday, tm_yday, or tm_isdst fields. *       (3) To pass in a time structure with 'out of range' values for some *           fields and have _mktime32 "normalize" them (e.g., pass in 1/35/87 and *           get back 2/4/87). *Entry: *       struct tm *tb - pointer to a tm time structure to convert and *                       normalize * *Exit: *       If successful, _mktime32 returns the specified calender time encoded as *       a __time32_t value. Otherwise, (__time32_t)(-1) is returned to indicate an *       error. * *Exceptions: *       None. * *******************************************************************************/  _CRTIMP __time32_t __cdecl _mktime32 (         struct tm *tb         ) {         return( _make__time32_t(tb, 1) ); }   /*** *__time32_t _mkgmtime32(tb) - Convert broken down UTC time to __time32_t * *Purpose: *       Convert a tm structure, passed in as an argument, containing a UTC *       time value to internal format (__time32_t). It also completes and updates *       the fields the of the passed in structure with 'normalized' values.  *Entry: *       struct tm *tb - pointer to a tm time structure to convert and *                       normalize * *Exit: *       If successful, _mkgmtime returns the calender time encoded as __time32_t *       Otherwise, (__time32_t)(-1) is returned to indicate an error. * *Exceptions: *       None. * *******************************************************************************/  _CRTIMP __time32_t __cdecl _mkgmtime32 (         struct tm *tb         ) {         return( _make__time32_t(tb, 0) ); }   /*** *static __time32_t _make__time32_t(tb, ultflag) - * *Purpose: *       Converts a struct tm value to a __time32_t value, then updates the struct *       tm value. Either local time or UTC is supported, based on ultflag. *       This is the routine that actually does the work for both _mktime32() and *       _mkgmtime32(). * *Entry: *       struct tm *tb - pointer to a tm time structure to convert and *                       normalize *       int ultflag   - use local time flag. the tb structure is assumed *                       to represent a local date/time if ultflag > 0. *                       otherwise, UTC is assumed. * *Exit: *       If successful, _mktime32 returns the specified calender time encoded as *       a __time32_t value. Otherwise, (__time32_t)(-1) is returned to *       indicate an error. * *Exceptions: *       None. * *******************************************************************************/  static __time32_t __cdecl _make__time32_t (         struct tm *tb,         int ultflag         ) {         __time32_t tmptm1, tmptm2, tmptm3;         struct tm tbtemp;         long dstbias = 0;         long timezone = 0;          _VALIDATE_RETURN( ( tb != NULL ), EINVAL, ( ( __time32_t )( -1 ) ) )          /*          * First, make sure tm_year is reasonably close to being in range.          */         if ( ((tmptm1 = tb->tm_year) < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR           + 1) )             goto err_mktime;           /*          * Adjust month value so it is in the range 0 - 11.  This is because          * we don't know how many days are in months 12, 13, 14, etc.          */          if ( (tb->tm_mon < 0) || (tb->tm_mon > 11) ) {              /*              * no danger of overflow because the range check above.              */             tmptm1 += (tb->tm_mon / 12);              if ( (tb->tm_mon %= 12) < 0 ) {                 tb->tm_mon += 12;                 tmptm1--;             }              /*              * Make sure year count is still in range.              */             if ( (tmptm1 < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR + 1) )                 goto err_mktime;         }          /***** HERE: tmptm1 holds number of elapsed years *****/          /*          * Calculate days elapsed minus one, in the given year, to the given          * month. Check for leap year and adjust if necessary.          */         tmptm2 = _days[tb->tm_mon];         if ( !(tmptm1 & 3) && (tb->tm_mon > 1) )                 tmptm2++;          /*          * Calculate elapsed days since base date (midnight, 1/1/70, UTC)          *          *          * 365 days for each elapsed year since 1970, plus one more day for          * each elapsed leap year. no danger of overflow because of the range          * check (above) on tmptm1.          */         tmptm3 = (tmptm1 - _BASE_YEAR) * 365L + ((tmptm1 - 1L) >> 2)           - _LEAP_YEAR_ADJUST;          /*          * elapsed days to current month (still no possible overflow)          */         tmptm3 += tmptm2;          /*          * elapsed days to current date. overflow is now possible.          */         tmptm1 = tmptm3 + (tmptm2 = (__time32_t)(tb->tm_mday));         if ( ChkAdd(tmptm1, tmptm3, tmptm2) )             goto err_mktime;          /***** HERE: tmptm1 holds number of elapsed days *****/          /*          * Calculate elapsed hours since base date          */         tmptm2 = tmptm1 * 24L;         if ( ChkMul(tmptm2, tmptm1, 24L) )             goto err_mktime;          tmptm1 = tmptm2 + (tmptm3 = (__time32_t)tb->tm_hour);         if ( ChkAdd(tmptm1, tmptm2, tmptm3) )             goto err_mktime;          /***** HERE: tmptm1 holds number of elapsed hours *****/          /*          * Calculate elapsed minutes since base date          */          tmptm2 = tmptm1 * 60L;         if ( ChkMul(tmptm2, tmptm1, 60L) )             goto err_mktime;          tmptm1 = tmptm2 + (tmptm3 = (__time32_t)tb->tm_min);         if ( ChkAdd(tmptm1, tmptm2, tmptm3) )             goto err_mktime;          /***** HERE: tmptm1 holds number of elapsed minutes *****/          /*          * Calculate elapsed seconds since base date          */          tmptm2 = tmptm1 * 60L;         if ( ChkMul(tmptm2, tmptm1, 60L) )             goto err_mktime;          tmptm1 = tmptm2 + (tmptm3 = (__time32_t)tb->tm_sec);         if ( ChkAdd(tmptm1, tmptm2, tmptm3) )             goto err_mktime;          /***** HERE: tmptm1 holds number of elapsed seconds *****/          if  ( ultflag ) {              /*              * Adjust for timezone. No need to check for overflow since              * localtime() will check its arg value              */              __tzset();              _ERRCHECK(_get_dstbias(&dstbias));             _ERRCHECK(_get_timezone(&timezone));              tmptm1 += timezone;              /*              * Convert this second count back into a time block structure.              * If localtime returns NULL, return an error.              */             if ( _localtime32_s(&tbtemp, &tmptm1) != 0 )                 goto err_mktime;              /*              * Now must compensate for DST. The ANSI rules are to use the              * passed-in tm_isdst flag if it is non-negative. Otherwise,              * compute if DST applies. Recall that tbtemp has the time without              * DST compensation, but has set tm_isdst correctly.              */             if ( (tb->tm_isdst > 0) || ((tb->tm_isdst < 0) &&               (tbtemp.tm_isdst > 0)) ) {                 tmptm1 += dstbias;                 if ( _localtime32_s(&tbtemp, &tmptm1) != 0 )                     goto err_mktime;             }          }         else {             if ( _gmtime32_s(&tbtemp, &tmptm1) != 0 )                 goto err_mktime;         }          /***** HERE: tmptm1 holds number of elapsed seconds, adjusted *****/         /*****       for local time if requested                      *****/          *tb = tbtemp;         return (__time32_t)tmptm1;  err_mktime:         /*          * All errors come to here          */          errno = EINVAL;         return (__time32_t)(-1); }

谢谢，问题已经解决了

引用 3 楼 XiaRiKuHan 的回复:所以想求一个具体实现，在网上找的都不能使用 因为目前不知道你的环境里，那些函数是可以使用的（与时间相关的）;  同时，要实现这个mktime，你能提供什么参数，或者什么数据；

用 UTC的话， 这样一句就可以了， 要处理时区就麻烦大了。  long j__mktime(int year, int month, int mday, int hour, int minute, int second) {	 	return (((year*365L+year/4-year/100+year/400+30*month+((signed char*)"\0\0\1\xff\0\0\1\1\2\3\3\4\4\5")[month]+mday- 		((month<=2&&((year&3)==0)&&((year%100)!=0||year%400==0)))-719558)*24+hour)*60+minute)*60+second; }

所以想求一个具体实现，在网上找的都不能使用

这个我知道，但是在公司的api里连time.h都不能使用，跟别说mktime了

mktime是C标准库的函数，本来就可以直接用！


Question: c  两个不同的枚举类型里的成员不能重名么

引用 8 楼 LM165678 的回复:楼主,枚举是一种类,可以看成是常量表的类,在外部中无法定义两个拥有同样成员的枚举类,在函数中也无法定义两个拥有相同成员的枚举类,但是可以在外部和内部定义拥有同样成员的枚举类,如下: enum cheks{A = 0};//在全局中定义一个外部枚举类,成员有A /*enum cheks1{A = 1};//那么无法在全局中再定义一个外部枚举类,成员也有A的枚举类*/ /*enum cheks1{A = 0};*/ void test2() { 	enum chek {A = 0, MyName, Hellow};//但是可以在内部函数中定义一个枚举类,成员为A 	enum testEnum {A = 0, A1 = 1, MyName1, Hellow1};//如果testEnum中有一个A值,那么无法编译通过  	enum chek chek1; 	enum testEnum testEnum1;  	chek1 = A;//因为局域变量里面有一个chek的枚举值为A,所以会引用chek的A值,而不会引用外部的cheks的A值 	printf("chek1 = %d", chek1); 	 	testEnum1 = A1; 	printf("testEnum1 = %d", testEnum1); } 楼主,请忽略我说的"类",因为我习惯用java的术语来描述,类就是一种数据结构,请这么理解

http://en.cppreference.com/w/cpp/language/enum  Each enumerator becomes a named constant of the enumeration's type (that is, name), visible in the enclosing scope, and can be used whenever constants are required.

是的，不能，除非写在两个不同的名字空间中

枚举，你可以认为是宏，宏定义是不允许重名的，那么枚举也是一样的。

那我又多个枚举，可能里面的成员会有相同的，难道每个都设置namespace  ？？

对于不同枚举值，取不同名称，例如加前缀  typedef enum {     cact_active = 1, }CREATEORACTIVE_E;  typedef enum {     act_notActive = 1,     act_active = 2 }ACTIVENO_E;

这么写是不行的，一般用不同的namespace包起来


Question: 在windows窗体程序中用opengl画三维图，把代码蓝色部分注释掉就是动图，不然就是一个静态的图，问题出在哪了啊！！求路过的大神救助！！！

windows下程序的绘制使用到DC（设备上下文），opengl也是使用该HDC进行绘制的 而且PAINT重绘消息里总是（或者说几乎）有如下形式  hDC =BeginPaint(hWnd,&ps); //绘制代码 EndPaint (hWnd,&ps);


Question: linux sem_inti,wait,post 未定义的引用

编译的时候加-pthread试试，没有前面的l -pthread

#include <semaphore.h>

试过加 -lpthread 不管用啊


Question: C语言读取txt文件中的数据，printf显示读取的数与txt中存的数不一致，怎么回事

1L已经指明了，就是颠倒使用  dst = (double**)malloc(sizeof(double*)*col); //row? dst[0] = (double*)malloc(sizeof(double)*row*col); for (i = 1; i<col; i++) dst[i] = dst[i - 1] + row; //col？

引用 5 楼 cfjtaishan 的回复:double **array2DI(int col, int row) {     double **dst;     int i;     dst = (double**)malloc(sizeof(double*) * row);      for (i = 0; i < col; i++)         dst[i] = (double*)malloc(sizeof(double) * col);      /*     for (i = 1; i<col; i++)         dst[i] = dst[i - 1] + row;     */     return dst; } 改一下函数array2DI的实现试试； 另外， main函数里return 0（打开文件失败时）和其类型void不匹配。 我用了你修改的，结果还是一样的，还有别的修改方法吗？

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

使用数据断点功能Debug  参考下面：#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; }

因为你读取的时候行列颠倒了

在两次输出中间没有其他操作，理论上是不改输出结果不一致的。所以，很有可能是申请（malloc)内存时出了问题。所以，仔细看一下array2DI的实现吧

你用到了二维数组，我看循环次数不是太多，你可以在出问错的那次循环那里设置断点 （条件断点），然后看是谁改了那里的数值。

我首先定义了一个二维的动态数组，然后用动态数组去读取txt文件中的数字，一共是30*20个，读取的时候，我用了printf，显示的数字是对的，全部读取完毕后，我又用printf显示了某一行，发现和txt中数字有出入


Question: if()的问题

引用f(a.y==4||a.y==6||a.y==9||a.y==11) a.r=30;   //这个可以写成if(a.y==(4,6,9,11))吗  不可以，那样就是逗号表达式了，实际比较的只是11这个数

引用这个(a.y>=1&&a.y<=12)能用，这个(a.r>=1&&a.r<=31)怎么没用  || 运算符在第一个表达式为真的情况下不会再判断第二个

if(a.y==(4,6,9,11)) 写成这样，这里就是要注意一个逗号表达式的问题，逗号表达式即做后一个逗号后面的表达式是最终表达式。即写成这样，就是下面的意思： if (a.y == 11)

因为你用的是||，若||前面的表达式为真，则||后面的表达式则不会计算和判断，因为前面的表达式为真，则真个||表达式为真，除非||前面的表达式为假，才会继续判断||后面的表达式。因此，若要想两个表达式都为真则执行if语句，建议改成&&

2.a.y==（4，6，9，11）；不能这样写，没有这样的语句，如果去掉一个等号变成赋值语句倒是可以，这样右边是逗号表达式。

if((a.y>=1&&a.y<=12) && (a.r>=1&&a.r<=31))   逻辑与&&：前后都为真才为真，否则为假，如果前一个表达式为假，则后一个表达式不再执行与判断。 逻辑或||：前后都为假才为假，否则为真，如果前一个表达式为真，则后一个表达式不再执行与判断。

1. if（xxx || yyy）为什么yyy不起作用，这是||这个逻辑符的陷阱，如果xxx是真的话，编译器就不会计算yyy，只有当xxx为假时，才会计算yyy。


Question: 才学C语言，找不到自己的错误，请教一下，谢谢

先看一下C语言变量定义的要求吧，带括号的都是函数吧。

f（n-1），f（n-2）这不是变量名，变量是以数字、字母或下划线命名。如果要这样用，只能定义一个函数名为f的函数。

f应该是函数，不能定义成变量； #include<stdio.h>  unsigned int f(int n);  int main() {     int n;      printf("Please input a number: ");     scanf("%d", &n);      printf("%u\n", f(n));   return 0; }  unsigned int f(int n) {     unsigned int fn;      if (n == 1 || n == 2)         return 1;     else         fn = f(n-1) + f(n-2);      return fn; }

感谢感谢

f定义成数组或者函数吧 ，用变量肯定不行啊

首先你要实现什么功能？我就从代码规范上说说吧。f一般是float类型变量，fn,fun一般是函数名。 printf("f1=%d,f2=%d,f=%d\n",f1,f2,fn);


Question: 为什么写进去输出不了，就是检验不了是不是乱输入的，求解救

if(strcmp(p->data.sex,"男")!=0 && strcmp(p->data.sex,"女")!=0)

scanf("%s",p->data.sex); 			if(strcmp(p->data.sex,"男")!=0 || strcmp(p->data.sex,"女")!=0) 			{ 				printf("性别只有男和女，请重新输入！\n");                    //显示也是错误的啊这是为啥 				goto lab2; 			}

scanf 的返回值不表示你输入的数，而是成功接收参数的个数  http://en.cppreference.com/w/c/io/fscanf

仅供参考：#include <stdio.h> int main() {     int IP[4];     int i;     char c;      printf("请输入一个ip地址:");fflush(stdout);     while (1) {         rewind(stdin);         if (5==scanf("%d.%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&IP[3],&c)) {             if (0<=IP[0] && IP[0]<=255              && 0<=IP[1] && IP[1]<=255              && 0<=IP[2] && IP[2]<=255              && 0<=IP[3] && IP[3]<=255              && '\n'==c) {                 break;             } else printf("输入的ip地址格式不对!\n请重新输入:\n");         } else printf("输入的ip地址格式不对!\n请重新输入:\n");     }     for (i=0;i<4;i++) {         printf("IP[%d]=%d\n",i,IP[i]);     }     return 0; }

性别若是字符串，去掉scanf时的&, 另外，strcmp的返回值，若是相等则返回0；

ret1=scanf("%s",&p->data.age);   //scanf返回值是成功读取的个数，并不是读取到的数值 // age是int类型用 %d，而不是%s //if(ret1<=0) if(p->data.age <= 0)  scanf("%s",&p->data.sex);  //看下面的语句，那么sex应该是一个char*，那么p->data.sex就不需要使用& if(strcmp(p->data.sex,"男")!=1 || strcmp(p->data.sex,"女")!=1) //strcmp的返回值0表示相等，所以这里判断应该是 != 0

scanf, wscanf Read formatted data from the standard input stream.  int scanf( const char *format [,argument]... );  int wscanf( const wchar_t *format [,argument]... );  Routine Required Header Compatibility  scanf <stdio.h> ANSI, Win 95, Win NT  wscanf <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Both scanf and wscanf return the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character.  Parameters  format  Format control string  argument  Optional arguments  Remarks  The scanf function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined.  wscanf is a wide-character version of scanf; the format argument to wscanf is a wide-character string. wscanf and scanf behave identically otherwise.   Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tscanf scanf scanf wscanf    For more information, see Format Specification Fields — scanf functions and wscanf Functions.   Example   /* SCANF.C: This program uses the scanf and wscanf functions   * to read formatted input.   */  #include <stdio.h>  void main( void ) {    int   i, result;    float fp;    char  c, s[81];    wchar_t wc, ws[81];     printf( "\n\nEnter an int, a float, two chars and two strings\n");     result = scanf( "%d %f %c %C %s %S", &i, &fp, &c, &wc, s, ws );    printf( "\nThe number of fields input is %d\n", result );    printf( "The contents are: %d %f %c %C %s %S\n", i, fp, c, wc, s, ws);     wprintf( L"\n\nEnter an int, a float, two chars and two strings\n");     result = wscanf( L"%d %f %hc %lc %S %ls", &i, &fp, &c, &wc, s, ws );    wprintf( L"\nThe number of fields input is %d\n", result );    wprintf( L"The contents are: %d %f %C %c %hs %s\n", i, fp, c, wc, s, ws); }   Output  Enter an int, a float, two chars and two strings 71 98.6 h z Byte characters  The number of fields input is 6 The contents are: 71 98.599998 h z Byte characters  Enter an int, a float, two chars and two strings 36 92.3 y n Wide characters  The number of fields input is 6 The contents are: 456 92.300003 y n Wide characters   Floating-Point Support Routines, Stream I/O Routines, Locale Routines  See Also   fscanf, printf, sprintf, sscanf


Question: 使用perl截取文本中特定的内容

请楼主移驾 CSDN论坛 > 其他开发语言 > 脚本语言(Perl/Python)论坛。 http://bbs.csdn.net/forums/OL_Script


Question: assert的应用

assert是在debug模式下才起作用，在release下不会被编译的。至于i++，这完全是自增的语法，加加在前是先加后运用，如果在后就先运用后加加。

assert内是要避免修改数据的 release下assert的代码是不编译进去的

引用 2 楼 wanggui2015 的回复:assert只做判断，不做处理，这代码在debug下没啥问题，但是到release下，assert语句不执行，i++也不会执行了，逻辑就会有问题了 不过，可能跟这个release版本时，assert不执行有关

引用 2 楼 wanggui2015 的回复:assert只做判断，不做处理，这代码在debug下没啥问题，但是到release下，assert语句不执行，i++也不会执行了，逻辑就会有问题了 release版本里，assert是仍然有效的吧，除非把debug在编译的时候关了，这样才会不执行assert语句 http://blog.csdn.net/yeyuboy/article/details/593736

但从你的这些描述看不出是assert应用本身问题，而倒是++（后增）和<优先级的问题。是否要将i++放到assert外面还要看环境和逻辑。因此，可以贴出更多一些的代码。


Question: c语言，数组作为自定义函数参数，如果要实现原数组内部数据的改变

引用 4 楼 weixin_37923716 的回复:引用 3楼weixin_37923716 的回复:数组作为函数的实参传递，传递的数组的首地址，所以自定义函数操作形参就是在操作实参数了，数组的传递一般都是值传递，除非操作单个数组元素，只传一个值(例如传递a[0])，就是值传递，传递数组名称a就是地址传递，数组名称本来就是一个指针常量，所以你要传递数组时声明自定义函数时声明形参时数组的那个形式参数是声明为指针的，就是这么一回事了不好意思，打错一个地方了，第三行那里应该是“数组的传递一般是地址传递”，手机打字不方便…… 地址值也是值，一次参数传递可以统一归结为值传递。只不过这个值是地址值。

形参其实就是一个指针，即使你定义的形参是int array[]，编译器也是将其看成指针。 如果将数组作为实参传给自定义函数，那么自定义形参（指针）就指向了数组的首地址（因为传递的时候是数组名），那么在自定义函数里所有的修改，都是修改原数组的内容。所以，自定义函数处理结束后，原数组的数据也就变化了。

如果传入的是数组指针，在函数里修改之后原始的数组也会被修改


Question: 请教问题

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

引用 3 楼 cfjtaishan 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h> #include <string.h>  int main() {     char a[80];     int i;      for(i=1;i<=3;i++)     {         gets(a);         if(strcmp(a,"628628")==0)         {             printf("输入正确请稍后......\n");             break;         }         else         {             printf("输入错误按任意键继续\n");             getch();         }         if(i == 3)         {             printf("您的卡已冻结\n");         }     }     return 0; } 两处拼写错误，分别是main，printf； 若输入匹配应break处循环，不然逻辑说不通。 #include<stdio.h> #include <string.h>   int main() {     char a[80];     int i;       for(i=1;i<=3;i++)     {         gets(a);         if(strcmp(a,"628628")==0)         {             printf("输入正确请稍后......\n");             break;         }         else         {             printf("输入错误按任意键继续\n");             getch();         }     }     if(i == 3)     {         printf("您的卡已冻结\n");     }      return 0; } if判断是否为3，应放在循环外。[/quote] 如果放在外面，if (i == 4)才可以。上面回复我太过草率

引用 1 楼 cfjtaishan 的回复:#include<stdio.h> #include <string.h>  int main() {     char a[80];     int i;      for(i=1;i<=3;i++)     {         gets(a);         if(strcmp(a,"628628")==0)         {             printf("输入正确请稍后......\n");             break;         }         else         {             printf("输入错误按任意键继续\n");             getch();         }         if(i == 3)         {             printf("您的卡已冻结\n");         }     }     return 0; } 两处拼写错误，分别是main，printf； 若输入匹配应break处循环，不然逻辑说不通。 #include<stdio.h> #include <string.h>   int main() {     char a[80];     int i;       for(i=1;i<=3;i++)     {         gets(a);         if(strcmp(a,"628628")==0)         {             printf("输入正确请稍后......\n");             break;         }         else         {             printf("输入错误按任意键继续\n");             getch();         }     }     if(i == 3)     {         printf("您的卡已冻结\n");     }      return 0; } if判断是否为3，应放在循环外。


Question: memcmp判断空字符串

引用 6 楼 cfjtaishan 的回复:对于空串，只有一个'\0'，没有两个字节失误失误，脑子一直想的是只有一个字符的字符串。

引用 5 楼 SXJIAKE 的回复:引用 3 楼 github_27546213 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 因为你比较了8个字符，已经越界了。它会判断a字符串的8个字节与""比较，第三个参数建议用strlen你好，谢谢，明白了。不过我自己试验了一下应该是前一个字节是一样的，不是前2个字节。 第二个字节是 0，这个也是一样的……[/quote] 对于空串，只有一个'\0'，没有两个字节

引用 3 楼 github_27546213 的回复:引用 1 楼 cfjtaishan 的回复:因为你比较了8个字符，已经越界了。它会判断a字符串的8个字节与""比较，第三个参数建议用strlen你好，谢谢，明白了。不过我自己试验了一下应该是前一个字节是一样的，不是前2个字节。 第二个字节是 0，这个也是一样的……

引用 2 楼 SXJIAKE 的回复:memcmp 是比较指定字节的内容是否完全相同。所以你这是比较 a 和 "" 的 8个字节的二进制是否相同。其前两个字节是相同的，后面的话就不知道了。作为字符串，a 的后面 6 字节可以是任意内容，而 "" 只有 2 字节是你可以访问的，之后的内容你可能不一定有写权限，甚至没有读权限。strcmp 是比较字符串，只要其中一个字符串结束 (遇到 0 字符为止)，比较就结束。这个例子中，实际上只比较了 2 字节。 memcmp是不会判断字符串的'\0'的，所以，它是要比较8个字节， 对于第二个字符串，8个字节很明显是越界了吗？ 注意:memcmp和strncmp是不一样的


Question: 使用C语言的强制类型转换将基类指针转换成子类指针如何判断是否合法？

已经写代码验证，基类如果没有虚函数，确实不可使用dynamic_cast，而且delete这样的基类的指针也不会判断指针的实际对象类型而是忠实地调用基类的析构。

如果有个基类Base和派生类Derived,然后有一个Base *arr[4] 里面放了4个Base类型对象指针，实际上都是指向Derived类型的实例的。 假设我的Base和Derived都没声明任何虚函数。 不考虑编译环境不支持dynamic_cast的问题，我使用这些指针时不可以使用dynamic_cast吗？ 这时基类的析构相当于没有virtual的是吗？使用完了这个数组，我要delete[] arr，是不是会析构不完整呢？

dynamic_cast 是基于虚函数表的，即使在c++中，没有虚函数的类或结构对象也是不能用dynamic_cast的

好奇怪的C，居然有继承关系

C语言有基类子类的概念？？？

AIX的机器，gcc编译器，由于版本有一点旧，要支持dynamic_cast需要在编译选项中注明。 编译选项的配置是另一个产品组的，我们项目组不能修改。 C里面看来没有考虑过这种继承关系的问题，没办法解决就算了，只能写的时候时刻记住指针的类型了。

引用 1 楼 jianwen0529 的回复:指针这东西没办法，完全靠写作者本身的细心 能想到的就是实现运行时类型机制  类你都用了，为什么不能使用dynamic_cast？难道你的代码的编译器是古董级别？

指针这东西没办法，完全靠写作者本身的细心


Question: Dev c++中第二次运行程序提示“Program received signal SIGSEGV，Segmentation fault.”是什么原因，求指导。

引用 5 楼 cfjtaishan 的回复:可以这样理解，但是，struct tm成员都得是int类型（占四个字节）才可以。这样做有一个缺点，就是如果struct tm添加或者减少一个成员或者某个成员的类型变了，比如编程char，或者double，那么还是有问题。 所以，建议写成这样形式： fwrite(local,sizeof(struct tm),1,fp); fread(&date,sizeof(struct tm),1,fp); 除了安全以外，也能提高程序的可移植性。  明白了，谢谢！

引用 4 楼 longquan0315 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] fwrite(local,sizeof(struct tm),1,fp); 不清楚楼主为什么要传fwrite第三个参数为9，根据你的需要，一个就可以了。 i = fread(&date,sizeof(struct tm),1,fp); 感谢楼上两位的回答，我像下面这样理解对吗？ struct tm中有9个int型数据，在fread和fwrite两个函数的参数中，如果第二个参数是sizeof（int）的话，第三个参数就应该是9。 fwrite(local,sizeof(int),1,fp); fread(&date,sizeof(int),1,fp); 如果第二个参数是sizeof（struct tm）的话，第三个参数就应该是1 fwrite(local,sizeof(struct tm),1,fp); fread(&date,sizeof(struct tm),1,fp); 这样对吗？[/quote] 可以这样理解，但是，struct tm成员都得是int类型（占四个字节）才可以。这样做有一个缺点，就是如果struct tm添加或者减少一个成员或者某个成员的类型变了，比如编程char，或者double，那么还是有问题。 所以，建议写成这样形式： fwrite(local,sizeof(struct tm),1,fp); fread(&date,sizeof(struct tm),1,fp); 除了安全以外，也能提高程序的可移植性。

引用 2 楼 cfjtaishan 的回复:fwrite(local,sizeof(struct tm),1,fp); 不清楚楼主为什么要传fwrite第三个参数为9，根据你的需要，一个就可以了。 i = fread(&date,sizeof(struct tm),1,fp); 感谢楼上两位的回答，我像下面这样理解对吗？ struct tm中有9个int型数据，在fread和fwrite两个函数的参数中，如果第二个参数是sizeof（int）的话，第三个参数就应该是9。 fwrite(local,sizeof(int),1,fp); fread(&date,sizeof(int),1,fp); 如果第二个参数是sizeof（struct tm）的话，第三个参数就应该是1 fwrite(local,sizeof(struct tm),1,fp); fread(&date,sizeof(struct tm),1,fp); 这样对吗？

引用 1 楼 ckc 的回复:fread(&date,sizeof(struct tm),9,fp); 这一句读了9个tm出来，而date只能保存1份数据， 所以把后面的变量都搞乱了，fp数据被改写，所以fclose的时候就出错了 感谢楼上两位的回答，我像下面这样理解对吗？ struct tm中有9个int型数据，在fread和fwrite两个函数的参数中，如果第二个参数是sizeof（int）的话，第三个参数就应该是9。 fwrite(local,sizeof(int),1,fp); fread(&date,sizeof(int),1,fp); 如果第二个参数是sizeof（struct tm）的话，第三个参数就应该是1 fwrite(local,sizeof(struct tm),1,fp); fread(&date,sizeof(struct tm),1,fp); 这样对吗？


Question: 可以运行  到了第二步就不崩溃了【C语言】

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

#include<stdio.h> #include<stdlib.h> #include<string.h> struct worker {     char No[20];  //职工号     char name[20];  //姓名     char sex;       //性别     int age;        //年龄     char xueli[10];  //学历     float gongzi;    //工资     char addr[32];     //地址     char tel[11];    //电话 };   //职工信息结构体 void face(); void input(); void save(struct worker wo[]); void chaxun(); void ghcx(); void xmcx(); void shanchu(); void ghsc(); void xmsc(); struct worker wo[100];  //职工的信息 int Number=0;  //记录职工人数 void face()   //操作面板 {     printf("\t\t\t\t=========湖北工程学院========\n\n");     printf("\t\t\t\t=====计算机信息与科学学院====\n\n");     printf("\t\t\t\t=======职工信息管理系统======\n\n");     printf("\t\t\t\t      1  输入职工信息        \n\n");     printf("\t\t\t\t      2  浏览职工信息        \n\n");     printf("\t\t\t\t      3  查询职工信息        \n\n");     printf("\t\t\t\t      4  删除职工信息        \n\n");     printf("\t\t\t\t      0      退出            \n\n"); }; void input()   //录入函数 {     int numberTemp=0;     int i = 0;     struct worker temp;     printf("请您输入要添加职工个数：");     scanf("%d",&numberTemp);     for (i = 0; i < numberTemp; i++)     {         printf("请输入工号:  ");         scanf("%s", temp.No);         printf("请输入姓名:  ");         scanf("%s", temp.name);         printf("请输入性别:  ");         scanf("%s",&temp.sex);         printf("请输入年龄:  ");         scanf("%d",&temp.age);         printf("请输入学历:  ");         scanf("%s", temp.xueli);         printf("请输入工资:  ");         scanf("%f",&temp.gongzi);         printf("请输入住址:  ");         scanf("%s", temp.addr);         printf("请输入电话:  ");         scanf("%s", temp.tel);         wo[Number++] = temp; //写入到数组         save(&temp); //写入到文件     }     printf("添加成功\n"); } void show()  //浏览职工信息 {     int i=0;     printf("\t工号\t姓名\t性别\t年龄\t学历\t工资\t地址\t电话\n");     while(i<Number)     {         printf("\t%s\t%s\t%c\t%d\t%s\t%f\t%s\t%s\n",wo[i].No,wo[i].name,wo[i].sex,wo[i].age,wo[i].xueli,wo[i].gongzi,wo[i].addr,wo[i].tel);         i++;     }  }  void ghcx()  //工号查询 {     int i;     char No[20];     printf("请输入要查询的工号\n");     scanf("%s", No);     for(i=0;i<Number;i++)     {         if (strcmp(No, wo[i].No) == 0)         {             printf("\t工号\t姓名\t性别\t年龄\t学历\t工资\t地址\t电话\n");             printf("\t%s\t%s\t%c\t%d\t%s\t%f\t%s\t%s\n",wo[i].No,wo[i].name,wo[i].sex,wo[i].age,wo[i].xueli,wo[i].gongzi,wo[i].addr,wo[i].tel);         }     } } void xmcx() //姓名查询 {     char name[20];     int i;     printf("请输入要查询的姓名\n");     scanf("%s", name);     for(i=0;i<Number;i++)     {         if(strcmp(name,wo[i].name)==0)         {             printf("\t工号\t姓名\t性别\t年龄\t学历\t工资\t地址\t电话\n");             printf("\t%s\t%s\t%c\t%d\t%s\t%f\t%s\t%s",wo[i].No,wo[i].name,wo[i].sex,wo[i].age,wo[i].xueli,wo[i].gongzi,wo[i].addr,wo[i].tel);         }     } } void chaxun() //查询职工信息 {     int x;     printf("1 按工号查询\t 2 按姓名查询\n");     scanf("%d", &x);     switch (x)     {         case 1:             ghcx();break;         case 2:             xmcx();break;         default:printf("输入错误!\n");chaxun();                 break;     } }  void ghsc()  //工号删除 { FILE *fp=NULL;     char No[20];     int i=0;     int j=0;     printf("请输入要删除的职工工号\n");     scanf("%s",No);     for (i=0; i<Number; i++)     {         if (strcmp(No, wo[i].No)==0)         {             for (j=i; j<Number-1; j++)             {                 wo[j] = wo[j+1];             }             Number--;         }     }     //将剩余数据写入文件擦除以前的数据     fp=fopen("C://worker.dat", "wb");     for (i = 0; i < Number; i++)     {         fwrite(&wo[i], sizeof(struct worker), 1, fp);     }     fclose(fp);     printf("删除成功！\n"); } void xmsc()  //姓名删除 {     FILE *fp = NULL;     char name[20];     int i = 0;     int j = 0;     printf("请输入要删除的职工姓名\n");     scanf("%s",name);     for (i=0; i<Number; i++)     {         if (strcmp(name, wo[i].name) == 0)         {             for (j=i; j <Number-1; j++)             {                 wo[j] = wo[j+1];             }             Number--;         }     }     //将剩余数据写入文件擦除以前的数据     fp = fopen("C://worker.dat", "wb");     for (i = 0; i < Number; i++)     {         fwrite(&wo[i], sizeof(struct worker), 1, fp);     }     fclose(fp);     printf("删除成功;\n"); } void shanchu()  //删除职工信息 {     int x;     printf("1 按工号删除\t 2 按姓名删除\n");     scanf("%d",&x);     switch (x)     {         case 1:             ghsc();break;         case 2:             xmsc();break;         default:printf("输入错误!\n");shanchu();                 break;     } } void main() {     int c = 0;     while (1)     {         face();         printf("\t\t请选择：");         scanf("%d", &c);         system("cls");         switch (c)         {             case 1:                 input();                 break;             case 2:                 show();                 break;             case 3:                 chaxun();                 break;             case 4:                 shanchu();                 break;             case 0:                 exit(0);                 break;             default:printf("输入错误！\n");main();         }     } } void save(struct worker *wo) {     FILE *fp=NULL;     fp=fopen("C://worker.dat","ab+");     fwrite(wo, sizeof(struct worker),1,fp);     fclose(fp); }

引用 1 楼 自信男孩的回复:printf("请输入工号:  ");         scanf("%s", temp.No);         printf("请输入姓名:  ");         scanf("%s", temp.name);         printf("请输入性别:  ");         scanf("%s",&temp.sex);         printf("请输入年龄:  ");         scanf("%d",&temp.age);         printf("请输入学历:  ");         scanf("%s", temp.xueli);         printf("请输入工资:  ");         scanf("%f",&temp.gongzi);         printf("请输入住址:  ");         scanf("%s", temp.addr);         printf("请输入电话:  ");         scanf("%s", temp.tel); 输入有误，学号和姓名都是字符串，字符数组名本身就是地址。  struct worker {     char No[20];  //职工号     char name[20];  //姓名     char sex;       //性别     int age;        //年龄     char xueli[10];  //学历     float gongzi;    //工资     char addr[32];     //地址     char tel[12];    //电话 };   //职工信息结构体 结构体也做了修改；  其他问题，主要是对于字符串要用%s个数输入，对于char要用%c或者%d格式输出。对于int，要用%d格式输入； 问题，不一一给你罗列了。对于稍微复杂的程序，建议每写完一个功能都进行编译和测试。 我一直以为是储存的原因。非常感谢。


Question: [资源优选]第十九期：20个热门的C语言源码

我是进来学习的🙄

谢谢分享

好贵啊，买不起，

需要的积分有点多啊

收了 这么好的资源

谢谢楼主分享。

谢谢分享6666

不知道为什么打开后404

谢谢分享sdadsf

666  很喜欢  正在学

下载要积分 全部差评

C-FREE不错，小巧实用，功能不失强大

C语言怪异代码大赛历届作品大全 1984～1996，1998，2000，2001，2004～2006，2011，2012http://download.csdn.net/detail/zhao4zhong1/5538847

赞一个，收藏了。

分享是美


Question: 结构题数组问题求助

引用 3 楼 sunglina 的回复:[quote=引用 2 楼 starytx 的回复:] 没有初始化，你想获得什么值？你想让编译器给你初始化吗？结构体也可以弄个默认构造函数嘛，相当于自动初始化了   我是想直接给结构体赋值，如果没有初始化，那么是不是不能直接这样用 b[1].p = "hello"[/quote]  可以直接：b[1].p = "hello"

引用可以直接b[1].i,b[1].p这样使用吗  可以

引用请问第二个元素是怎么处理初始化的  第二个元素用0填充

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

引用 3 楼 sunglina 的回复:[quote=引用 2 楼 starytx 的回复:] 没有初始化，你想获得什么值？你想让编译器给你初始化吗？结构体也可以弄个默认构造函数嘛，相当于自动初始化了   我是想直接给结构体赋值，如果没有初始化，那么是不是不能直接这样用 b[1].p = "hello"[/quote]可以啊，我只是说不能引用，赋值当然是可以的

引用 2 楼 starytx 的回复:没有初始化，你想获得什么值？你想让编译器给你初始化吗？结构体也可以弄个默认构造函数嘛，相当于自动初始化了   我是想直接给结构体赋值，如果没有初始化，那么是不是不能直接这样用 b[1].p = "hello"

当我们定义一个结构体后,没有初始化就使用,就会访问到内存的垃圾数据,而且这种错误很难发现。 对于定义的任何变量,在使用之前都先初始化是个良好的习惯。

#include <stdio.h>  struct a {     int i;     char *p; };  //struct a b[2] = { {1,"we"}}; int main() {     struct a b[2] = { {1,"we"}};          printf("%d\n", b[1].i);     if (b[1].p == NULL)     printf("p == NULL\n");      return 0; } 可以通过这个小程序验证自己的猜测； 若struct a b[2]如此初始化，那么b[1].i为0，b[1].p= NULL；即第一个结构体成员初始化，第二个默认是都为0；类似 int array[10] = { 1, 2, 3 };  后面array[3], .... array[9]都为0


Question: printf函数中没有修改变量的值，却会影响相关变量的值吗？

VS和GDB都有数据断点功能专门用来解决此类问题。 关键是看楼主学不学得会了。

深究这个问题还是挺有意思的。不要只抓着那些编程的原则不放。看看编译器，看看进程运行的内存状态，再来研究这个有趣的问题，蛮好玩的。

感谢各位大神回复。 主要是想弄清楚，有printf与没有printf，为什么造成后面的输出不一致。当然，++p确实不应该这样使用，但这个不是本问题的重点。 经过提示，再进行跟踪调试发现，VS在有无printf编译后，变量位置没有发生变化，所以有没有printf没有影响输出。而gcc在有无printf的编译结果，变量的位置是不一样的，所以造成两次输出不一致。

变量怎么排是未定义的，VS调试时，各变量地址之间有12字节的间隔，所以++p 这种写法没什么意义

#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; }

以上正解，而且编译器可以自由实现这些细节，没必要关心。

同意2楼，*(++p)会随机对应到内存中的某块数据 这是非安全的操作

不用试图找什么原因。 代码中使用 *(++p) 就是错的，除非p是数组，否则任何可能的后果都要自负。 不要对编译器做什么假设，因为编译器实现的只是语言的标准，标准不会规定一些细节的，原因在于C语言的设计原则，追求效率，相信程序员。即使是同一编译器，在不同的OS上，实现细节也有不同；即使是同一OS上，同一编译器的不同版本，实现细节也可能有不同。 一句话，不要做无意义的讨论。

#include <stdio.h> int main() {     int *p, z = 43, a=100, b=1767, c=15164;     p = &a;     //printf(" %p,%p,%p,%p,%p\n", &p,&z,&a,&b,&c);//本行注释与否对结果有影响？     printf("%p, %p\n", &b, &c);     printf("%d\n",*p);     printf("%p\n", p);     printf("%d\n",*(++p));      printf("%d\n",a);     printf("%p, %p\n", &b, &c);      return 0; } 打印地址，建议使用%p或%P; 加上printf行应该是改变了函数栈上变量的位置。


Question: 新手问题，求解决

vc6.0是比较早的产物了。建议采用vs2008建一个空项目，把代码贴进去编译。不是你代码的问题

在VC6中新建一个Win32 Console空项目，将你的代码添加到Source Files中，……

应该是函数库的问题吧


Question: 如何交换函数指针数组里的元素呢？

引用 4 楼 qq_34287840 的回复:[quote=引用 3 楼 paschen 的回复:] 和交换普通常量一样的原理呗   	void(*TMP)(PSchedule) = XXX[0]; 	XXX[0] = XXX[1]; 	XXX[1] = TMP;  那个，我的意思是用一个swap函数来交换，但是我搞不懂swap的参数到底应该怎么来表示，感觉有点复杂，请大大赐教！[/quote]  void Swap(void(**A)(PSchedule), void(**B)(PSchedule))

引用 1 楼 cfjtaishan 的回复:函数指针数组，那么每个函数指针就是存放一个地址，即函数的首地址。 如果交换，应该就是交换里面的地址值， 类似这样： 交换第一和第二个的地址值   void (*pfunc) (PSchedule);  pfunc = XXX[0]; XXX[0] = XXX[1]; XXX[1] = pfunc;  我的想法是用一个swap函数来交换，但是我搞不懂swap的参数到底应该怎么来表示，麻烦大神赐教！

引用 3 楼 paschen 的回复:和交换普通常量一样的原理呗   	void(*TMP)(PSchedule) = XXX[0]; 	XXX[0] = XXX[1]; 	XXX[1] = TMP;  那个，我的意思是用一个swap函数来交换，但是我搞不懂swap的参数到底应该怎么来表示，感觉有点复杂，请大大赐教！

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

引用 5 楼 qq_34287840 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 函数指针数组，那么每个函数指针就是存放一个地址，即函数的首地址。 如果交换，应该就是交换里面的地址值， 类似这样： 交换第一和第二个的地址值   void (*pfunc) (PSchedule);  pfunc = XXX[0]; XXX[0] = XXX[1]; XXX[1] = pfunc;  我的想法是用一个swap函数来交换，但是我搞不懂swap的参数到底应该怎么来表示，麻烦大神赐教！[/quote]   typedef void (*pfunc)(PSchedule); void swap(pfunc *a, pfunc *b) {     pfunc c;     c = *a;     *a = *b;     *b = c; } //调用： swap(&XXX[0], &XXX[1]);