Question: 请问这个四则运算 错在哪

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

引用 3 楼 ACMtop 的回复:好烦老师说的对

引用 6 楼 ni_mamagea 的回复:很遗憾跟你说，代码太长了，没全看完，感觉看不大懂。。。

很遗憾跟你说，代码太长了，没全看完，感觉看不大懂。。。

/*上面赵老师说的甚是*/ 楼主主要问题在于传值和传址不清楚，算法是对的，没细看，调式几次没啥问题，代码修改如下：  #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h>    #define OK 1 #define ERROR 0  // type of number operator typedef struct LinkNodeOVS{ 	int data; 	struct LinkNodeOVS *next; } LinkSackNodeNum, *LinkStackNum;  void Init_Stack1(LinkStackNum *top) {      *top = NULL; }  int Push1(LinkStackNum *top,int e) { 	LinkStackNum p; 	p=(LinkSackNodeNum*)malloc(sizeof(LinkSackNodeNum)); 	p->data=e; 	p->next=*top; 	*top=p; 	return  OK; }  int Pop1(LinkStackNum *top,int *e) { 	LinkStackNum temp; 	if(!*top) 		return ERROR;    	*e=(*top)->data; 	temp=*top; 	*top=temp->next; 	free(temp); 	return OK; }  int GetTop1(LinkStackNum top) { 	return(top->data);     }    // type of char operation typedef struct LinkNodeOP{ 	char data; 	struct LinkNodeOP *next; } LinkSackNodeOP, *LinkStackOP;  void Init_Stack(LinkStackOP *top) { 	*top = NULL; }  int Push(LinkStackOP *top,char e) { 	LinkStackOP p; 	p=(LinkSackNodeOP*)malloc(sizeof(LinkSackNodeOP)); 	p->data=e; 	p->next=*top; 	*top=p; 	return OK;     }  int Pop(LinkStackOP *top,char *e) { 	LinkStackOP temp; 	if(!*top) 		return ERROR;    	temp = *top; 	*e=temp->data; 	*top = temp->next; 	free(temp); 	return OK; }  char GetTop(LinkStackOP top) { 	return top->data;     }       int cmp[7][7]={{2,2,1,1,1,2,2},    /*operator PRI,3:'=',2:'>',1:'<',0 no compare*/                 {2,2,1,1,1,2,2},                 {2,2,2,2,1,2,2},                 {2,2,2,2,1,2,2},                 {1,1,1,1,1,3,0},                 {2,2,2,2,0,2,2},                 {1,1,1,1,1,0,3}}; char ops[7]={'+','-','*','/','(',')','#'};   int Isoperator(char ch)      /*if ch is operator, return TRUE or return FALSE*/ { 	char ops[7]={'+','-','*','/','(',')','#'}; 	int i; 	for (i=0;i<7;i++) 	{ 		if(ch==ops[i]) 			return 1; 	} 	return 0; }   char Compare(char ch1, char ch2)   /*compare operator PRI*/ { 	int i,m,n; 	char pri; 	int priority; 	for(i=0;i<7;i++)              /*find the relative position of operator */ 	{ 		if(ch1==ops[i]) 			m=i; 		if (ch2==ops[i]) 			n=i; 	}  	priority = cmp[m][n]; 	switch(priority) 	{ 	case 1: 		pri='<'; 		break; 	case 2: 		pri='>'; 		break; 	case 3: 		pri='='; 		break; 	case 0: 		pri='$'; 		printf("error !\n"); 		break; 	} 	return pri; }  int Compute(int a,char op,int b) { 	int ret = 0; 	switch (op) 	{ 	case '+': ret = a+b; break; 	case '-': ret = a-b; break; 	case '*': ret = a*b; break; 	case '/': ret = a/b; break;                        	} 	return ret; }  int ExpEvaluation() { 	char ch,op; 	int v,a,b,temp,i=0; 	char *str;  	LinkStackOP OPTR; 	LinkStackNum OVS;  	Init_Stack(&OPTR); 	Init_Stack1(&OVS);  	Push(&OPTR,'#'); 	printf("\nPlease input one expression which of the last character is '#':\n") ; 	str =(char *)malloc(50*sizeof(char)); 	fgets(str, 50, stdin);  	ch=str[i]; 	i++;  	while(ch!='#' || GetTop(OPTR)!='#') 	{ 		if(!Isoperator(ch)) 		{ 			// num=GetNum(ch); 			//Push1(OVS,num);  			temp=ch-'0';    /*put char to dec*/ 			ch=str[i]; 			i++;   			while(!Isoperator(ch)) 			{ 				temp=temp*10 + ch-'0'; 				ch=str[i]; 				i++; 			} 			Push1(&OVS,temp); 		} 		else 		{ 			switch (Compare(GetTop(OPTR),ch)) 			{ 			case'<': Push(&OPTR,ch); 				ch=str[i]; 				i++; 				break; 			case'>': Pop(&OPTR,&op); 				Pop1(&OVS,&b); 				Pop1(&OVS,&a);     				v=Compute(a,op,b);                        				Push1(&OVS,v); 				break; 			case'=': Pop(&OPTR,&op); 				ch=str[i]; 				i++; 				break; 			}  		} 	}      	v=GetTop1(OVS); 	return v; }  int main() { 	int result; 	result=ExpEvaluation(); 	printf("\nexpression result:%d\n",result); 	return 0; }

好烦

道友速来就我


Question: ACM编程题

又见约瑟夫问题！！！！！！！！其实我做过的最难的也是约瑟夫环问题而已！！！！！！！！！！！

第二个就类似于约瑟夫环，模拟一下就完事了，数学NB的话也可以用同余的代数方法解决 第三题更简单。。。把第二位第一位读法分别写出特别注意10，20之类的，别读第一位 再判断一下最高位超了就报错 真太水了，懒得写了楼主加油写写试一下吧1

问题1代码   int num[500000], size; void ShellSort(int array[],int length) { 	 	int d = length/2;   //设置希尔排序的增量 	int i ; 	int j; 	int temp; 	while(d>=1)         { 		for(i=d;i<length;i++)     		{     			temp=array[i]; 			j=i-d; 			while(j>=0 && array[j]<temp)     			{     				array[j+d]=array[j];     				j=j-d;     			}     			array[j+d] = temp;     		} 		 		d= d/2;    //缩小增量     	} }  int main {     int sum1 = 0, sum2 = 0;     scanf("%d", &size);     for(int i = 0; i < size; i++)         scanf("%d", &num[i]);     Shell(num, size);     for(i=0;i<size;i++)    {         if(i % 2 == 0)            sum1 += num[i];         else            sum2 += num[i];    }    if(sum1 > sum2)       cout << sum1 - sum2 << endl;    else       cout << sum2 - sum1 << endl; }

第一个就是按升序排序，然后求和 第二个类似于耶稣的叛徒 第三个（怎么是拼音呢）我直接用字符数组的 代码只有自己写才能明白为什么


Question: 关于汇编和c，程序语言

我反正是学不会。

难 汇编的指令还会影响状态寄存器各种跳来跳去 脑子要是不注意的话根本看不下去

看来汇编比c要难或者说不太一样

引用 19 楼 dsyayo 的回复:<<计算机组成原理>>,学习中!加油我们一起努力

引用 18 楼 zhang5476499 的回复:都学了快半年了，王爽的书还没有看完，还是学校的课程，老师完全照着书念，好不好？  我无法了。 加油我们一起努力

<<计算机组成原理>>,学习中!

编写相同规模的程序，当然汇编比C语言难。但是不要忘了，我们用不同语言编写的程序的规模是不同的。  用汇编可能也就是显示几个字符，读取下串口这样简单的功能，实现极其简单的数据处理，但是用C语言，你可能就要面对诸如编写用户界面，设计比较复杂的算法，同时访问很多硬件这样的任务了。而如果你使用Java，你甚至可能要写一个服务器/客户端架构多层的应用程序……  从这个意义上说，没有什么语言是简单的，要不然编程语言进步了那么多，程序员的工资早就一钱不值了。  你特别需要注意的是，不同的语言，解决问题的尺度不同，比如用C语言，你可能习惯于结构化编程，你的脑子中不太注意变量怎么分配，循环的跳转怎么安排，甚至操作一个加法运算，是否考虑进位、溢出之类的事情，但是用汇编这些都需要考虑。你思考的问题的层次完全不同。

引用 4 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

面向对象只是一种编程思想。 再抽象的编程语言，最后不都变成汇编代码了吗？我们完全可以说汇编语言是面向对象、脚本化、动态化、泛函化、并行化、分布化的语言。

越自由的语言越难。

linux启动代码里一会x86汇编，一会at&t汇编，不懂

术业有专攻，你学汇编也只会学一两种，常见的有x86, arm，C却是通用的 学汇编要学会把汇编指令分类，运算指令，加载存储指令等等

汇编语言非常接近硬件，所以在学习之前得系统的了解计算机硬件的相关知识，否则学习起来当然觉得难。 正如4楼所说，如果能先看完《计算机组成原理》再来学汇编的话，就会轻松多了，因为汇编语言的书中提到的各种硬件的概念，都在《计算机组成原理》中有详细介绍。

汇编不可能完成大型软件，没有任何一个大项目是完全用汇编写的，但是很多大型项目都可能在某个点上用汇编进行优化， 所以，任何语言都有其应用的场合，如果一个人只会汇编而不会其他任何编程语言，他可能连个码农都不如。更莫说高手了， 很多新人都有这个误区，认为只要学会最难的就能成为高手，当然这是错误的。

汇编重要吗？

引用 3 楼 user-14 的回复:汇编 还是先看看视屏在看书，比较好，网上有中山大学的汇编视屏51节课 还是比较清晰的 有空再网上下了看看

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》


Question: [求助]win7的nslookup与linux下c语言写的一个DNS服务器端交互的问题(TCP)

引用 1 楼 user-1 的回复:TCP没有保证发10字节一定能一次recv到10字节，建议了解一下TCP的特性。 额。。可是在linux下每次recv都是正常的，windows下每次都只能recv到2字节


Question: 这是一个直接对中缀表达式求值的程序，可运行，初学数据结构，请各位大侠帮忙看看有没有哪些地方可以改进？小弟感激不尽！！

看错了。。。两个结构体名字太相似了。。

引用 1 楼 zxhuser-1 的回复:那两个结构体不是一样的吗?为什么要重复定义呢？   一个是存储int型数字的，一个是存储运算符的

那两个结构体不是一样的吗?为什么要重复定义呢？


Question: 学生管理系统，文件读取写入链表的问题

用函数fscanf试试

f9加断点调试下看看是哪句的问题啊

加了，一共有近600行代码，这就一小段

加头文件了吗?


Question: 线程的问题，我的输出线程执行不了我在编一个电梯，前面有个输入线程，接着一个输出线程，但是输出线程好像没有工作

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

我需要大神帮助，如果看不清，我的QQ896776703 这是电梯，我线程不能用


Question: 使用数组进行计数！新手求教！

运行了一遍，没有问题啊

你应该自己调试一下，看看各个变量是否符合你你要求！！

a应该是char类型

哪错了？


Question: 简单的方法把二进制数据写入文件

引用 5 楼 zhao4zhong1 的回复:还可以用bitset我知道bitset，但现在课程实验在用C。。。貌似没有更好的办法了，结贴。

还可以用bitset

哈夫曼哈夫曼码最长如果为16个， 可以考虑用32位编码缓存数据。 编码的时候直接把编码缓存数据移位， 把生成的哈夫曼码放到数据中。 当缓存数据超过16位的时候， 把整Byte数据保存， 编码缓存数据移位。 编码结束时， 把剩余的数据保存。

引用 2 楼 user-3 的回复:最简单的： 每个编码写一行不清楚你的每个编码写一行是什么意思？每个编码长度不同，你要写进文件，每1个字节可能包含的字符也是不一样的。可能包含两个字符，可能包含一个半，可能是半个，也可能是几分之一个。

最简单的： 每个编码写一行

仅供参考//有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }


Question: 越写越乱，请求牛人们帮我分析分析，要怎么改才好？？？

引用 2 楼 shimachao 的回复:描叙清楚你要做什么，你遇到的问题是什么？ 再把代码贴好！ 看别人的代码需要比你本人更大的耐心。 谢谢！！！ 我想用opengl做一个海浪仿真，在xoz面上作网格，y方向上作为海浪高度，海浪的模型是 在xoz面上作网格，y方向上作为海浪高度。我不知道怎么把x,z,t的值传入到函数height，还有我不知道关于使用opengl的函数是否正确？

搜网络教程“学OpenGL编3D游戏”。


Question: 每个线程传递一个局部变量会影响到其他线程的变量值？百思不得其解

这样的话传递给线程的最好是全局变量或者动态分配的，已经结贴了。谢谢！

犯了这么傻的错误，谢谢各位了

引用 5 楼 TheNewIpad 的回复:RMSG rmsg; 是一个局部变量。 由于在启动函数中，所以地址是不变的。 会被最后接收的变量覆盖。  第一块代码的第18行。 改为在堆上分配RMSG吧。

rmsg是一个局部变量 你的循环执行一次完成之后 对象笑话内存释放 &rmsg变成野指针  传入线程的指针是野指针  于是 出现这些问题

引用 2 楼 user-3 的回复:理论上是一个rmsg对应一个线程的。 你说下怎么对应的  补充一下啊，每个客户端发送了不同数目的唯一消息，线程一开是都能接收到的，但有线程退出以后似乎就“影响”了其他的线程！

引用 2 楼 user-3 的回复:理论上是一个rmsg对应一个线程的。 你说下怎么对应的                   RMSG rmsg;                 memset(&rmsg, 0, sizeof (rmsg));                 rmsg.cli_sockd = client_sockd;                 memcpy(&(rmsg.cli_addr), &client_addr, sizeof (client_addr));                  pthread_create(&tid, NULL, server_handle, (void *) &rmsg);  应该是对应的吧。。想不通怎么搞串了。

理论上是一个rmsg对应一个线程的。 你说下怎么对应的

希望有人能够帮助我一下！


Question: 求助，dereferencing pointer to incomplete type

Function: xmlStrdup  xmlChar *	xmlStrdup		(const xmlChar * cur)  a strdup for array of xmlChar's. Since they are supposed to be encoded in UTF-8 or an encoding with 8bit based chars, we assume a termination mark of '0'.  cur:	the input xmlChar * Returns:	a new xmlChar * or NULL

我在网上查了，知道是这个问题，但是具体的缺什么或者哪里有错还是找不出来，按说这是在网上下载的现成的代码应该不会有什么问题啊。。。。这是libxslt文件夹下的xsltutils.c文件，一部分代码：  #define IN_LIBXSLT #include "xsltutils.h" #include "libxslt.h" #include <stdio.h> #include <string.h> #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #include <stdarg.h>  #include <libxml/xmlmemory.h> #include <libxml/tree.h> #include <libxml/HTMLtree.h> #include <libxml/xmlerror.h> #include <libxml/xmlIO.h>  #include "templates.h" #include "xsltInternals.h" #include "imports.h" #include "transform.h" 。 。 。  int xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,  		       xmlDocPtr result, xsltStylesheetPtr style) {     xmlOutputBufferPtr buf;     const xmlChar *encoding;      *doc_txt_ptr = NULL;     *doc_txt_len = 0;     if (result->children == NULL) 	return(0);      XSLT_GET_IMPORT_PTR(encoding, style, encoding)     if (encoding != NULL) { 	xmlCharEncodingHandlerPtr encoder;  	encoder = xmlFindCharEncodingHandler((char *)encoding); 	if ((encoder != NULL) && 	    (xmlStrEqual((const xmlChar *)encoder->name, 			 (const xmlChar *) "UTF-8"))) 	    encoder = NULL; 	buf = xmlAllocOutputBuffer(encoder);     } else { 	buf = xmlAllocOutputBuffer(NULL);     }     if (buf == NULL) 	return(-1);     xsltSaveResultTo(buf, result, style);     if (buf->conv != NULL) { 	*doc_txt_len = buf->conv->use; 	*doc_txt_ptr = xmlStrndup(buf->conv->content, *doc_txt_len);     } else { 	*doc_txt_len = buf->buffer->use; 	*doc_txt_ptr = xmlStrndup(buf->buffer->content, *doc_txt_len);     }     (void)xmlOutputBufferClose(buf);     return 0; } 。 。 。

你的指针类型是不完全类型吧。。。只有声明没定义，看看是不是头文件什么的没包含。


Question: 急求各位前辈一个数据处理问题！！！

1楼给出了在“组合下标”中取“组合上标”种组合的算法。 楼主不是想“n行取其中的每两行，三行，四行，...,n行(不能遗漏或是重复)”吗？参考一下。 如果行顺序相关的话，那就不是组合而是排列了。排列参考下面： //qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

仅供参考#include <stdio.h> #include <stdlib.h> #define MAX_NUM 26 int comb[MAX_NUM]; int c1,c2; void combination(int m,int n) {     int i,j;      for (i=m;i>=n;i--) {         comb[n]=i; /* 选择当前的“头”元素 */         if (n>1) {             combination(i-1,n-1); /* 进入下一次更小的组合问题 */         } else { /* 满了需要的组合数，输出 */             for (j=comb[0];j>0;j--) printf("%c",'A'+c1-comb[j]);             printf("\n");         }     }     return; } int main(int argc,char **argv) {     if (argc<3) {         printf("%s 组合下标 组合上标\n",argv[0]);         return 1;     }     c1=atoi(argv[1]);     if (c1<1 || MAX_NUM<c1) {         printf("1<=组合下标<=%d\n",MAX_NUM);         return 2;     }     c2=atoi(argv[2]);     if (c2<1 || c1<c2) {         printf("1<=组合上标<=组合下标\n");         return 3;     }     comb[0]=c2;     combination(c1,c2);     return 0; }


Question: 依旧是我！依旧是白痴题！但真的不懂啊！

如果输入1 2 3 4就会在执行if（a<b)a=b后跳过后面的语句，直接执行a的输出

引用 9 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我是自学的！有很多不懂！那请问要学单步调试和设断点调试看那些书？？ 或者书应该怎么学？？ 谢谢！

把else去掉

看书吧。。多多的看。自己学会调试设断点

我想楼主的代码不正确，1 2 3 4输出2

引用 1 楼 user-9 的回复:你把else全去了  ++++++++++++

引用 1 楼 user-9 的回复:你把else全去了正解。

引用 10 楼 u014497083 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我是自学的！有很多不懂！那请问要学单步调试和设断点调试看那些书？？ 或者书应该怎么学？？ 谢谢！[/quote] VS IDE中，编译链接通过之后，按F11、F10、Shift+F11或F9、F5键。 凡是可以不通过看书而通过实际操作学习的技能，都尽量通过实际操作学习。 比如开车、比如游泳、比如骑车、……看遍所有开车、游泳、骑车、……的书的人就一定会开车、游泳、骑车、……吗？

if else if这种结构的语句 若是遇到了其中一个满足条件的就会跳出整个if else if语句，不会执行其他分支的语句了；     if (a<b)         a=b;     else if (a<c)         a=c;     else if (a<d)         a=d; 比如你写的这个，若是满足a<b，则a=b；之后下一条执行的语句是printf ("%d\n", a);后面的else if条件不会去判断的； 我帮你改写了一下 # include <stdio.h> #include<stdlib.h> main () {     int a, b, c, d;     printf ("请输入四个数（用空格隔开）：");     scanf ("%d %d %d %d", &a, &b, &c, &d);     a=_max(a,b);     a=_max(a,c);     a=_max(a,d);     printf ("%d\n", a); } 分给我吧

你把else全去了


Question: 大神帮忙看看，这是错在哪？（编译可过~）

引用 1 楼 user-3 的回复:uid = string_id(string_adjust("Hello")); 这句话你确定不能改成 char s[100]="Hello"; uid = string_id(string_adjust(s));  说到这的话  先要知道char *p; 你是把指针p指向了字符串常量了 也就是p是字符串常量指针 是说明了他们的内容是不能改变的  是的，谢谢！

引用 3 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   好的，感谢！

修改一个常量当然报错了 "Hello"


Question: 求教一个编译错误！

错误表明缺少声明。

看起来可能是这里的问题‘GHmac’ undeclared

不是缺少头文件

你是用啥编译的？

在你的代码里面应该是有中文字母或者中文标点符号，中文空格。

符号未定义。你检查一下那几个符号


Question: printf（）；

楼主为什么不自己试试呢，运行了就知道了

printf Width Specification The second optional field of the format specification is the width specification. The width argument is a nonnegative decimal integer controlling the minimum number of characters printed. If the number of characters in the output value is less than the specified width, blanks are added to the left or the right of the values — depending on whether the – flag (for left alignment) is specified — until the minimum width is reached. If width is prefixed with 0, zeros are added until the minimum width is reached (not useful for left-aligned numbers).  The width specification never causes a value to be truncated. If the number of characters in the output value is greater than the specified width, or if width is not given, all characters of the value are printed (subject to the precision specification).  If the width specification is an asterisk (*), an int argument from the argument list supplies the value. The width argument must precede the value being formatted in the argument list. A nonexistent or small field width does not cause the truncation of a field; if the result of a conversion is wider than the field width, the field expands to contain the conversion result. Precision Specification The third optional field of the format specification is the precision specification. It specifies a nonnegative decimal integer, preceded by a period (.), which specifies the number of characters to be printed, the number of decimal places, or the number of significant digits (see Table R.5). Unlike the width specification, the precision specification can cause either truncation of the output value or rounding of a floating-point value. If precision is specified as 0 and the value to be converted is 0, the result is no characters output, as shown below:  printf( "%.0d", 0 );      /* No characters output */  If the precision specification is an asterisk (*), an int argument from the argument list supplies the value. The precision argument must precede the value being formatted in the argument list.  The type determines the interpretation of precision and the default when precision is omitted, as shown in Table R.5.  Table R.5   How Precision Values Affect Type  Type Meaning Default  c, C The precision has no effect. Character is printed.  d, i, u, o, x, X The precision specifies the minimum number of digits to be printed. If the number of digits in the argument is less than precision, the output value is padded on the left with zeros. The value is not truncated when the number of digits exceeds precision. Default precision is 1.  e, E The precision specifies the number of digits to be printed after the decimal point. The last printed digit is rounded. Default precision is 6; if precision is 0 or the period (.) appears without a number following it, no decimal point is printed.   f  The precision value specifies the number of digits after the decimal point. If a decimal point appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.  Default precision is 6; if precision is 0, or if the period (.) appears without a number following it, no decimal point is printed.  g, G The precision specifies the maximum number of significant digits printed. Six significant digits are printed, with any trailing zeros truncated.  s, S The precision specifies the maximum number of characters to be printed. Characters in excess of precision are not printed. Characters are printed until a null character is encountered.    If the argument corresponding to a floating-point specifier is infinite, indefinite, or NaN, printf gives the following output.  Value Output  + infinity 1.#INFrandom-digits  – infinity –1.#INFrandom-digits  Indefinite (same as quiet NaN) digit.#INDrandom-digits  NAN  digit.#NANrandom-digits

引用 1 楼 user-9 的回复:%m.nf格式中m和n的关系应该是m>n+2,即没有整数部分的位置，也要考虑一个符号位和一个小数点位。你的%2.5f对编译器而言本来就是不合理要求，它只能按它能满足的某个功能：如保证值的正确性、保证值的有效宽度等----这些称作编译器的行为（实现的行为这个编译器的作者在满足ANSI C的大前提下，个别ANSI C没有严格限定的就按作者自己的意愿做了） 	y=333.1234567; 	printf("%8.5f\n",y); 这样的话  8>5+2 但结果显示为 333.12346 加上小说点是9位了。 这个也是属于相同意思的编译器行为吗？

引用 1 楼 user-9 的回复:%m.nf格式中m和n的关系应该是m>n+2,即没有整数部分的位置，也要考虑一个符号位和一个小数点位。你的%2.5f对编译器而言本来就是不合理要求，它只能按它能满足的某个功能：如保证值的正确性、保证值的有效宽度等----这些称作编译器的行为（实现的行为这个编译器的作者在满足ANSI C的大前提下，个别ANSI C没有严格限定的就按作者自己的意愿做了） ++

实际数值大于给定宽度，按实际输出！

引用 3 楼 zxh707wk 的回复:引用 2 楼 turingo 的回复:++  [quote=引用 1 楼 user-9 的回复:] %m.nf格式中m和n的关系应该是m>n+2,即没有整数部分的位置，也要考虑一个符号位和一个小数点位。你的%2.5f对编译器而言本来就是不合理要求，它只能按它能满足的某个功能：如保证值的正确性、保证值的有效宽度等----这些称作编译器的行为（实现的行为这个编译器的作者在满足ANSI C的大前提下，个别ANSI C没有严格限定的就按作者自己的意愿做了） +1[/quote]  ++

引用 2 楼 turingo 的回复:++  引用 1 楼 user-9 的回复:%m.nf格式中m和n的关系应该是m>n+2,即没有整数部分的位置，也要考虑一个符号位和一个小数点位。你的%2.5f对编译器而言本来就是不合理要求，它只能按它能满足的某个功能：如保证值的正确性、保证值的有效宽度等----这些称作编译器的行为（实现的行为这个编译器的作者在满足ANSI C的大前提下，个别ANSI C没有严格限定的就按作者自己的意愿做了） +1


Question: 很好的一个循序渐进的C语言教材，很适合新手学习，内容非常详细。

很适合基础阶段的学习。

老谭的书还是挺不详细的，感觉很模糊；

好像没太必要。。。 现在在看《代码之美》和》编程之美》 上周刚看完《编程珠玑》

引用 4 楼 zxh707wk 的回复:看老谭书的路过。。。 赶紧下了，重新学一遍

看老谭书的路过。。。

路过支持一下

○ 同意

c程序设计语言，最经典的c语言书籍，作者为c语言设计者


Question: 用SYSTEM（“notepad a.txt”）在程序中打开a.txt 文件后，程序就停在当前，不会往下执行除非关闭txt文件 程序才会继续往下执行

学到东西了！

阻塞函数呗，等待返回

引用 3 楼 zhao4zhong1 的回复:system(“start notepad.exe a.txt”); 或 system(“cmd.exe /c start notepad.exe a.txt”);  如果是linux下就system("notepad.exe a.txt &");

winexec，这个函数也是可以的，用法比上面的还简单些。

CreateProcess 或者ShellExecute，这里推荐用ShellExecute，直接open a.txt。当然可能txt关联破坏就不能用notepad打开了


Question: 求解决void   interrupt  (*oldhandler)();  函数指针定义出错，谢谢。

再顶一下，有人知道intterupt的用法吗？在哪个头文件里面定义的？只能在dos系统下才能用吗？

引用 1 楼 u010039337 的回复:你这太复杂了，你想使用什么功能？联系函数指针的用法吗？ 中断处理函数

引用 5 楼 FightForProgrammer 的回复:错误信息说的很明白呀  interrupt未定义的标识符,你需要知道interrupt是个什么类型撒 想用的是中断处理函数，这不是吗？

#define interrupt __stdcall

去掉所有的interrupt

interrupt没有定义，你看下原来的代码是什么类型的

你这太复杂了，你想使用什么功能？联系函数指针的用法吗？


Question: the c programming language这本书现在还有必要看吗？

C语言这本书包含了很多C++的基础，对于初学者来说是很不错的，如果觉得自己C++已经掌握不错了就没必要看了

引用 1 楼 shisi 的回复:你都觉得没必要，还问啥~ 毕竟没看过

你都觉得没必要，还问啥~


Question: fwrite写400M数据，在win7上秒杀，在xp上居然要10多秒！！！！

win7确实比xp快十倍的速度，只能承认win7的缓存系统比较强了，结贴

引用 3 楼 baichi4141 的回复:磁盘IO是瓶颈，这是硬件决定的，和操作系统关系不大，所以400M的数据不太可能瞬间完成 大概win7的缓存比较强，你认为写入的数据实际上都放在了缓存里，等你程序关闭后缓存慢慢往硬盘上写，如果你程序关闭后立刻断电，估计你会发现开机后磁盘上并没有完整的400M数据。而winxp的缓存比较老实，一点一点往磁盘上写数据  以上纯属猜测，我没做过大数据读写的任务 建议重新考虑功能需求  win7读取文件也快，读取是确实得到数据了啊

本人在做数据库系统，按块读取文件分析数据，本来130M的数据可以0.1秒完成，结果程序拿到学校机器上要1秒多。 我试了自己本子装上xp运行也一样。

这就是win7的优势啊,要不ms怎么放弃xp

引用 楼主 new_liang 的回复:代码如下  #include <stdio.h> #include <time.h>  void main() { 	clock_t t=clock(); 	FILE *fp=fopen("1.txt","wb"); 	char buff[400*1024]; 	for(int i=0;i<1024;i++) 		fwrite(buff,400*1024,1,fp); 	fclose(fp); 	printf("%d\n",clock()-t); }   有人知道为什么么， 有解决方法不？？？？ 你确定win7 真的写下去了？

急求大神解答，程序放到学校的机器运行上超慢，又不想背本子去


Question: 多线程条件变量无法唤醒

void run(){ while(true){ pthread_mutex_lock(&lock); while(queue_.empty()) pthread_cond_wait(&cv, &lock); SliceArg* arg = queue_.front(); queue_.pop_front(); doTask(arg); pthread_mutex_unlock(&lock); }  你这用条件变量有啥用，在锁里面doTask怎么并发。  void run(){ while(true){ pthread_mutex_lock(&lock); while(queue_.empty()) pthread_cond_wait(&cv, &lock); SliceArg* arg = queue_.front(); queue_.pop_front(); pthread_mutex_unlock(&lock); doTask(arg); // 这样就行了 }

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

嗯，这个测试过了，lock和cv的地址是同一个！

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

十分感谢5楼的代码！不过我有点问题，5楼里面写的应该是使用sleep代替wait，不知道这样改会不会有性能或者其他方面的影响！

你要保证pushData中的 threadpool[0]->lock threadpool[0]->cv 和run中的 lock cv 是同一个,如果是不同的你怎么唤醒对方.

我看网上是这么写的，说的是wait的时候会释放锁

先lock再wait，主线程先lock再signal。不会死锁么？


Question: OpenSSL求助  有关pair BIO的

求帮忙啊

求帮忙啊

求大神回答一下


Question: FindFirstFile 为什么总是出错？

转义字符的问题

引用 1 楼 tujiaw 的回复:改为:"d:\\cgi"主要不是这，FindFirstFile 因为这个函数的第一个参数是TCHAR型，如果只是传一个字符串常量就不行。可以用_T（）。

引用 3 楼 zhao4zhong1 的回复:system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。嗯，可以考虑。

\转义字符 会和后一个字母c组成一个字符 应该添加一个\哈

改为:"d:\\cgi"


Question: 又是我！又是新手问题！

switch 里面只能是整数。 还有第九行，比较运算符的两边，类型最好是相同的，所以你最好改成(int)score>100这样，或者 score>100.0f 这样。

引用 6 楼 u013697891 的回复:[quote=引用 2 楼 u012421456 的回复:] 找不到错误，你的学会看编译器的报错啊！score是浮点数，score/10以后还是个浮点数，switch中不能是浮点数 这个知识书上没有吧[/quote] 整数与浮点数经运算后结果为浮点数，这个是有的，switch中不能是浮点数，我记不清了，记得是有来

引用 2 楼 u012421456 的回复:找不到错误，你的学会看编译器的报错啊！score是浮点数，score/10以后还是个浮点数，switch中不能是浮点数 这个知识书上没有吧

也可以使用一个函数# include <stdio.h>  char panbie(float score, int e);  int main (void) { 	int e = 0; 	float score;// score:得分，得分记录 	char grade;//grade:阶段，阶级；等级，级别；标准；班级 	 	printf ("Input score:");//input:输入 	scanf ("%f",&score); 	grade = panbie(score, 0);     if (e == 0) 		printf ("成绩是%6.2f, 相应的等级是%c\n", score, grade);  	return 0; }  char panbie(float score, int e) { 	char grade; 	if (score>100 || score<0)//验证数据的正确 	{ 		printf ("\n数据有误！无法判别！"); 		e=1; 	} 	switch ((int)score/10) 	{ 	   case 10: 	   case 9: grade='A'; break; 	   case 8: grade='B'; break; 	   case 7: grade='C'; break; 	   case 6: grade='D'; break; 	   case 5: 	   case 4: 	   case 3: 	   case 2: 	   case 1: 	   case 0: grade='E'; 	} 	 	return grade; }

还有就是29行   相应的等级   ，输出应该是%c，毕竟输出的是个字符

可将switch(score)改成switch((int)score)即可

系统规定，switch后的表达式的类型只能是int,enum,char等离散的数据类型，而不能是float,double等连续的数据类型。


Question: 有关sizeof的用法

引用 14 楼 u014711608 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] #include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // // 老师，能解释一下这句吗#define field_offset(s,f) (int)(&(((struct s *)(0))->f))[/quote] 将0强制类型转换为指向结构s的指针，然后取这个指针指向的结构s的分量f的地址，最后将这个地址强制类型转换为int类型。

google或者百度    结构体对齐和补齐

LZ可能是学谭浩强的c。 谭将结构体的尺寸算成全部成员之和。 事实上即使在Borland公司的编译器（TC\BC）中就有一编译开关，选择存储优化或运行优化，选用存储优化时，结构体的尺寸小一些，成员间的间隙处要被压缩一些（但也不一定压缩为0）；选用运行优化时，就采用字节对齐方法，成员间存在较多的间隙。

楼主搜一下字节对齐，大把文章介绍。

首先是结构体这个概念，然后是结构体在内存中怎么分布，是否需要内存对齐，对齐的好处是什么，是不是CPU 读取更快，里面的成员怎么计算，顺便和联合体比较一下就很清楚了！

引用 7 楼 zhao4zhong1 的回复:#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // // 老师，能解释一下这句吗#define field_offset(s,f) (int)(&(((struct s *)(0))->f))

C/C++数据内存对齐，可以参考这篇文章：C++ sizeof的内存计算（1）

好吧。。。 gcc也是这样

按4字节（32位）对齐的

结构体用sizeof计算大小有内存对齐

google字节对齐

内存要对齐，对齐的内存必须是最大数据类型的整数倍，本来是9 但是要是4的倍数，就必须是12了

数据对齐 http://www.cnblogs.com/bakari/archive/2012/08/27/2658956.html

引用 4 楼 focuslight 的回复:char和其他结构体成员内存分配大小对齐， 变成4  举个其他例子   sizeof(strcut B)=8不是要按顺序

引用 2 楼 u014161864 的回复:http://blog.csdn.net/jiejiaozhufu/article/details/8180249  整个结构体大小考虑数据对齐！但是在turbo c编译器下却没有这个对齐

结构体成员对齐


Question: 词法分析（C语言），求代码！

编译原理?

开源中国或者github上搜，很多啊

参考TinyC ？

使用lex。

没有讲清楚？？

词法分析？什么意思啊

课堂内容，已解决，谢谢各位大神！


Question: 字符串排序，实在找不到哪错了，大神帮忙看看

void sortstr(TCHAR *v[],int n) { 	int i = 0; 	int j = 0; 	TCHAR *temp; 	for(i = 0; i < n;i++) 	{ 		for(j = i; j < n;j++) 		{ 			if(0 < _tcscmp(v[i],v[j])) 			{ 				temp = v[i]; 				v[i] = v[j]; 				v[j] = temp; 			} 		} 	}

第二种改法，直接传数组  #include <stdio.h> #include <string.h> #define N 10 int swap(char p[],char q[])//此函数用于交换两个字符串 {     char s[N]; 	strcpy(s,p); 	strcpy(p,q); 	strcpy(q,s); 	return 0; } void sort(char p[N][N]) { 	int i,j;     for(i=0;i<N-1;i++) 	{ 		for(j=0;j<N-i-1;j++) 		{ 			if(strcmp(p[j],p[j+1])>0)  			{ 				swap(p[j],p[j+1]); 			} 		} 	} 			 }  int main() { 	char str[N][N]; 	int i; 	//str = (char **)malloc(sizeof(char*)*N);  	for(i=0;i<N;i++) 	{	 		scanf("%s",str[i]); 	} 	sort(str); 	for(i=0;i<N;i++) 	{ 		printf("%s ",str[i]); 	} 	return 0; }

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

第一种改法，动态分配内存。  #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 10 int swap(char *p,char *q)//此函数用于交换两个字符串 {     char s[N]; 	strcpy(s,p); 	strcpy(p,q); 	strcpy(q,s); 	return 0; } void sort(char **p) { 	int i,j;     for(i=0;i<N-1;i++) 	{ 		for(j=0;j<N-i-1;j++) 		{ 			if(strcmp(p[j],p[j+1])>0)  			{ 				swap(p[j],p[j+1]); 			} 		} 	} 			 }  int main() { 	char **str; 	int i; 	str = (char **)malloc(sizeof(char*)*N);  	for(i=0;i<N;i++) 	{	 		str[i] = (char *)malloc(N); 		scanf("%s",str[i]); 	} 	sort(&str[0]); 	for(i=0;i<N;i++) 	{ 		printf("%s ",str[i]); 	} 	return 0; }

设断点，单步跟踪吧

你的问题是什么呢？ 是运行时崩溃 还是得不到正确的结果？


Question: 求大神帮助。。。本人菜鸟加新手。

用Visual Studio 2013，和Windows 8.1完美兼容。  也可以使用Codeblock、DevC++。

请问VC++是不是与WIN8系统不兼容?那我是不是还要下个虚拟机再搞..

在VC++中新建一个Win32应用程序，选择带窗口的。一路点下去就成了。  进一步学习请google Windows编程 chm


Question: 急救！！！！希望各位大神指点！！！！

"....salary=%f",  应改为...salary=%d",

此外，这个结构体中只定义了指针name，没有姓名的存放空间，程序不能正确运行的

scanf("%d%s",&a[i].num,&a[i].name); getchar(); scanf("%c%d%d%d%d",&a[i].sex,&a[i].year,&a[i].month,&a[i].day,&a[i].salary);

char *name; 怎么用？

#include <stdio.h> struct employee { 	int num; 	char *name; 	char sex; 	int year; 	int month; 	int day; 	int salary; }a[3];  int main(void) { 	int i; 	for(i = 0; i < 3; i++) 	{ 		printf("输入第%d名员工的信息：\n", i+1); 		scanf("%d%s", &a[i].num, &a[i].name); 		getchar();    //接收'\n' 		scanf("%c%d%d%d%d", &a[i].sex, &a[i].year, &a[i].month, &a[i].day, &a[i].salary); 	} 	for(i = 0; i < 3; i++) 	{ 		printf("num=%d, name=%s, sex=%c, year=%d, month=%d, day=%d, salary=%f", 			a[i].num, a[i].name, a[i].sex, a[i].year, a[i].month, a[i].day, a[i].salary); 		printf("\n"); 	} 	return 0; }


Question: 想用c语言并加上SDL库写个小游戏如何开始

lazyfoo的教程不错 http://www.lazyfoo.net/ 上面有SDL教程，1.2的已经完了，2.0的还在更新。英文版的，不懂英文的话会比较吃力 挺不错的，你可以去看看


Question: 我写的数据压缩软件 wzip

引用 16 楼 goldbeef 的回复:引用 14 楼 Symfund 的回复:真的没必要实现压缩算法的软件，只要将算法原理发布出来就可以了，看看arxiv上的大牛都是这样的！我要发论文的，你得和已有的压缩软件比较啊，才能得出数据 无profiler不要谈效率！！ 尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

好家伙  顶个贴

建议将”你的“新的压缩算法发布在arxiv.org上哈！

这么牛X  PS: 听说一天回个贴可以得10分

引用 8 楼 zhao4zhong1 的回复:引用 6 楼 goldbeef 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 支持一下校友！多谢赵老师，您也是计算机学院的？ 提醒：一个新的压缩解压软件首先要兼容解压流行的压缩文件格式如.rar,.7z,.zip,.iso,.cab,……，然后能压缩为自己独特的压缩格式，且压缩比大于流行的压缩文件格式。还要支持超大文件压缩解压，支持跨流行的几种操作系统、文件系统的压缩解压。[/quote] 恩，赵老师说的很全面，thanks。目前的压缩上限应该是4G，32位下写的。 目前忙着写论文，9月份要投。等空闲了，在好好整一整。

引用 6 楼 goldbeef 的回复:引用 5 楼 zhao4zhong1 的回复:支持一下校友！多谢赵老师，您也是计算机学院的？ 提醒：一个新的压缩解压软件首先要兼容解压流行的压缩文件格式如.rar,.7z,.zip,.iso,.cab,……，然后能压缩为自己独特的压缩格式，且压缩比大于流行的压缩文件格式。还要支持超大文件压缩解压，支持跨流行的几种操作系统、文件系统的压缩解压。

支持一下校友！

学习了，

接分要六个字

再供参考（支持大于4GB的文件） #include <sys\stat.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <string.h> #define MAX_CLU_BYTES 65536 FILE *fo; int fh; __int64 offs,offs1; __int64 rvi64; int rv,wrv; unsigned char buf[MAX_CLU_BYTES]; char ofn[_MAX_PATH]; char offstr[80]; void strcpybutcomma(char *t,char *s) {     char c;      while (1) {         c = *s++;         if (','!=c) *t++ = c;         if (0==c) break;     } } void main(int argc,char **argv) {     if (argc<3) {         printf("Copy File Tail.\n");         printf("Usage:\n");         printf("    cft filename.ext offset_begin[-offset_end]\n");         printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n");         printf("Note: Byte at offset_end is NOT included.\n");         printf("Example:\n");         printf("    cft abc.rar 12345\n");         printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");         printf("    cft abc.rar 123-12345\n");         printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");         printf("    cft abc.rar 0xAB-0xCD\n");         printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");         return;     }     strcpybutcomma(offstr,argv[2]);     rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);     if (rv==0) {         printf("offset %s is not number\n",argv[2]);         return;     }     fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYNO);     if (fh==-1) {         printf("_sopen %s errno=%d\n",argv[1],errno);         return;     }     if (rv==1) {         offs1=_filelengthi64(fh);         if (offs1==-1i64) {             printf("%I64=_filelengthi64 errno=%d\n",offs1,errno);             _close(fh);             return;         }     } else {//rv==2         if (offs1<offs) {             printf("%s offset_begin>offset_end error\n",argv[2]);             _close(fh);             return;         }     }     rvi64=_lseeki64(fh,offs,SEEK_SET);     if (rvi64!=offs) {         printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno);         _close(fh);         return;     }     sprintf(ofn,"%s-",offstr);     strcat(ofn,argv[1]);     fo=fopen(ofn,"wb");     if (fo==NULL) {         _close(fh);         printf("fopen %s error\n",ofn);         return;     }     cprintf("\n%I64u\r",offs);     while (1) {         rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));         if (rv==0) break;//         if (rv<0) {             fclose(fo);             _close(fh);             printf("_read %s offset %I64u error\n",argv[1],offs);             return;         }         wrv=fwrite(buf,1,rv,fo);         if (wrv!=rv) {             fclose(fo);             _close(fh);             printf("fwrite %s error\n",ofn);             return;         } else {             offs+=rv;             cprintf("%I64u\r",offs);             if (offs>=offs1) break;//         }     }     fclose(fo);     _close(fh);     printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn); }


Question: 二位数组查找问题.

引用 8 楼 zhao4zhong1 的回复:[quote=引用 6 楼 cao_julians 的回复:] 二维数组的遍历与计算机的体系结构（CPU与主存间有一块称为cache的高速缓存）有关。提供两个线索 1.《深入理解计算机系统》 2.前几年计算机考研的专业课考试题，结合了软硬件知识的一道题  结论性的是按行效率高 无profiler不要谈效率！！ 尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！[/quote] 这个版块是C吧，本帖帖主问的是二维数组吧，你给出那么一大堆的与C中数组有直接关系吧？ 另一点，对你老ZHAO说，学C在学汇编之前，你动不动让初学者去汇编级看问题合适吧？

作为一个应用软件的设计者，没必要这么细究其差别

从连续排布的那个维度扫描。  最好的办法是不要用a[m][n]这种东西，而是自定义数组，用a(m,n)的形式来调用。

前几天看到一个题，行递增，列也是递增，然后查看这个数组中是否有某一个数， 这样你就没必要一直行列的去找了，根据结果选择行列， 行列的遍历，关键要看具体情况，

应该没什么区别吧！

有区别，一般来说在不同语言中，数据排列方式不同。 C,C++和 fortran 有所不同。 如果希望C，C++和 fortran协调工作，必须正确处理这个问题。 两外C，C++ 每行数据，连续存储在一起，这样分行处理比较简单。 C,C++读取一列数据比较麻烦，因为不是连续存放的。   fortran  每列数据，连续存储在一起，这样分列处理比较简单。 读取一行数据比较麻烦，因为不是连续存放的。  另外，即使fortran  ,C,C++分别读写同一批数据； 由于数据排列方式不同，所以对行和列解释也不同。 不过形式却差不多 C，C++ int a[10][20]; fortran ： integer a(1:10,1:20) 同样10行20列数据，行和列正好相反 fortran 要定义排列相同的数据，定义成20行10列即可。 改成 integer  a(1:20,1:10) 即下标次序相反。  结果是赵老师的，那个读写文件的法子，也不是一定行得通的。 因为C，C++和Fortran 对航和列的解释不一样，所以输出数据的排列，也不一定一样。  这里，主要问题各个语言的是习惯，而不是效率。

引用 6 楼 cao_julians 的回复:二维数组的遍历与计算机的体系结构（CPU与主存间有一块称为cache的高速缓存）有关。提供两个线索 1.《深入理解计算机系统》 2.前几年计算机考研的专业课考试题，结合了软硬件知识的一道题  结论性的是按行效率高 无profiler不要谈效率！！ 尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

引用 5 楼 q5390498 的回复:二维数组其实就是个一维数组，都是连续内存，行列和列行 都可以遍历，对于没什么特殊的遍历一般选择行列，但在需要的时候，再选择列行，其实也没什么。。 谁说的? //在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19

仅供参考//有两个每一项都是0或1组成的二维数组：A[50][50]和B[2][2] //找出在A里包含有多少与B相同的项，并标出坐标 #include <stdio.h> #include <stdlib.h> #include <time.h> int A[50][50]; int B[2][2]; int y,x; int j,i; int n; int main() {     srand(time(NULL));     for (y=0;y<50;y++) {         for (x=0;x<50;x++) {             A[y][x]=rand()%2;         }     }     for (y=0;y<2;y++) {         for (x=0;x<2;x++) {             B[y][x]=rand()%2;         }     }     n=0;     for (y=0;y<50-2+1;y++) {         for (x=0;x<50-2+1;x++) {             for (j=0;j<2;j++) {                 for (i=0;i<2;i++) {                     if (A[y+j][x+i]!=B[j][i]) goto NE;                 }             }             n++;             printf("n    y,x=%4d %2d,%2d\n",n,y,x);             NE:;         }     }     return 0; } //n    y,x=   1  0, 1 //n    y,x=   2  0, 3 //n    y,x=   3  0,17 //n    y,x=   4  1,12 //n    y,x=   5  1,20 //n    y,x=   6  1,33 //n    y,x=   7  2, 4 //n    y,x=   8  2,32 //n    y,x=   9  3,13 //n    y,x=  10  3,31 //n    y,x=  11  3,48 //n    y,x=  12  4, 0 //n    y,x=  13  5,14 //n    y,x=  14  5,32 //n    y,x=  15  5,36 //n    y,x=  16  5,47 //n    y,x=  17  6, 7 //n    y,x=  18  6,17 //n    y,x=  19  6,45 //n    y,x=  20  7, 1 //n    y,x=  21  7,31 //n    y,x=  22  8, 0 //n    y,x=  23  8,16 //n    y,x=  24  8,18 //n    y,x=  25  8,25 //n    y,x=  26  9, 9 //n    y,x=  27  9,27 //n    y,x=  28 10,12 //n    y,x=  29 10,26 //n    y,x=  30 12,12 //n    y,x=  31 12,20 //n    y,x=  32 13,36 //n    y,x=  33 13,45 //n    y,x=  34 13,48 //n    y,x=  35 14, 5 //n    y,x=  36 14, 7 //n    y,x=  37 14, 9 //n    y,x=  38 14,21 //n    y,x=  39 15, 4 //n    y,x=  40 15,20 //n    y,x=  41 16,10 //n    y,x=  42 16,23 //n    y,x=  43 16,45 //n    y,x=  44 17,16 //n    y,x=  45 17,22 //n    y,x=  46 17,40 //n    y,x=  47 18, 1 //n    y,x=  48 18, 5 //n    y,x=  49 18,26 //n    y,x=  50 18,43 //n    y,x=  51 19,40 //n    y,x=  52 19,46 //n    y,x=  53 20,31 //n    y,x=  54 20,38 //n    y,x=  55 21,27 //n    y,x=  56 21,41 //n    y,x=  57 21,48 //n    y,x=  58 22,10 //n    y,x=  59 22,15 //n    y,x=  60 22,20 //n    y,x=  61 22,24 //n    y,x=  62 23, 0 //n    y,x=  63 23, 3 //n    y,x=  64 23,40 //n    y,x=  65 24,11 //n    y,x=  66 24,14 //n    y,x=  67 24,29 //n    y,x=  68 24,34 //n    y,x=  69 24,43 //n    y,x=  70 25,16 //n    y,x=  71 25,19 //n    y,x=  72 25,25 //n    y,x=  73 26,18 //n    y,x=  74 26,23 //n    y,x=  75 27, 9 //n    y,x=  76 27,44 //n    y,x=  77 28, 7 //n    y,x=  78 28,22 //n    y,x=  79 28,24 //n    y,x=  80 28,33 //n    y,x=  81 28,48 //n    y,x=  82 29, 0 //n    y,x=  83 29,35 //n    y,x=  84 29,41 //n    y,x=  85 29,44 //n    y,x=  86 30, 7 //n    y,x=  87 30,23 //n    y,x=  88 31,35 //n    y,x=  89 31,41 //n    y,x=  90 31,45 //n    y,x=  91 33,21 //n    y,x=  92 33,27 //n    y,x=  93 34, 2 //n    y,x=  94 34,19 //n    y,x=  95 34,25 //n    y,x=  96 34,47 //n    y,x=  97 35,14 //n    y,x=  98 36, 6 //n    y,x=  99 36,13 //n    y,x= 100 36,25 //n    y,x= 101 36,31 //n    y,x= 102 36,41 //n    y,x= 103 36,47 //n    y,x= 104 37,11 //n    y,x= 105 37,16 //n    y,x= 106 37,24 //n    y,x= 107 37,30 //n    y,x= 108 38,18 //n    y,x= 109 38,20 //n    y,x= 110 38,28 //n    y,x= 111 38,38 //n    y,x= 112 39,32 //n    y,x= 113 39,43 //n    y,x= 114 39,45 //n    y,x= 115 39,48 //n    y,x= 116 40,35 //n    y,x= 117 40,38 //n    y,x= 118 41,33 //n    y,x= 119 42, 9 //n    y,x= 120 42,13 //n    y,x= 121 42,22 //n    y,x= 122 42,25 //n    y,x= 123 43,21 //n    y,x= 124 44,25 //n    y,x= 125 45,15 //n    y,x= 126 45,20 //n    y,x= 127 45,42 //n    y,x= 128 46, 4 //n    y,x= 129 47, 3 //n    y,x= 130 47,22 //n    y,x= 131 47,33 //n    y,x= 132 47,43 //n    y,x= 133 47,45 //n    y,x= 134 47,48 //n    y,x= 135 48, 0 //

最主要的是寻址方式不同，都能遍历的

有区别，从内存排列上是这样的 假设 a[3][6] 的字符： a[0][0] a[0][1] a[0][2] a[0][3] a[0][4] a[0][5]  a[1][0] a[1][1] a[1][2] a[1][3] a[1][4] a[1][5]  a[2][0] a[2][1] a[2][2] a[2][3] a[2][4] a[2][5] ;  可以看到，如果逐行遍历的话，是顺序的访问数据，对于CPU优化而言会非常好，如果列行遍历的话，每次都寻址，所以效率上有较大的差异，特别是当数组维数巨大的时候，每次太多寻址带来非常巨大的开销。


Question: 程序输入数据时停止运行，下面是代码，求大神指教

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

引用 1 楼 user-3 的回复:代码都不能给完整的 让人怎么找错误？ 最明显的错误就是 scanf("%s",p->name);  printf("sex:")  scanf("%c",p->sex); 这个p->会得到输入上面一句时的回车符！ 在scanf("%c",p->sex);前面加上一句getchar()吧 还有这个student*creat_dorm()这样写 不知道多一个空格会要花几万块么 嗷嗷 ，本人学生，刚学这些东西，编程风格实在烂，谢谢指教 还有就只有这些代码

引用 2 楼 vcgaoshou 的回复:这个程序中没有使用free释放malloc申请的堆空间，造成内存的泄露。应增加一个函数void delmem(struct student * head) void delmem(struct student * head){    struct student * p1,*p2; p1=p2= head; while(p1){   p2=p1->next; free(p1); p1=p2; } }   你调试过，可以运行？


Question: 生成，编译都过了，但是调试的时候出问题了，求大神指教啊

引用 5 楼 padechwu 的回复:我错了，我也不知道什么问题，我再输了一遍奇迹般的好啦 唉，有时候编译器就是有这样的问题，建议以后再遇到类似情况，即检查不出错误，而编译器报的错也看不出来，就新建一个文档，重新输入试试

我错了，我也不知道什么问题，我再输了一遍奇迹般的好啦

哥们，我编译没错呀！！！

我怎么看着没问题啊——

引用 1 楼 user-3 的回复:int i;      struct student * high=s;      for(i = 1; i < n; i++)   {             if(s[i])->total > s->total)              high = s;      }      return high;  前提是，你计算了total。 而且，实用double值做比较。存在精确度问题。 自己解决吧。   if(s[i])->total > high->total)


Question: C语言的篱笆加密是什么 求代码

引用 1 楼 zhang5476499 的回复:就是栅栏密码的意思，，，，，，，，，，，，，   我是一个男人   爱去嫖娼   你去不去  明文是：我爱你，貌似这个思想来着的，暂时忘记了。这个得好好翻书看看！ 爬到一边玩去。。。。。。我又不是水贴

引用 1 楼 zhang5476499 的回复:就是栅栏密码的意思，，，，，，，，，，，，，   我是一个男人   爱去嫖娼   你去不去  明文是：我爱你，貌似这个思想来着的，暂时忘记了。这个得好好翻书看看！ 屌


Question: 求大神帮忙看看，急啊！！！

LZ下一步操作逻辑错了，所以我觉得应该把， 把这里的for(k = 0; k < data_length; k++){ for(j = 0; j < 3; j++) { s[i] = z[j][k]; i++; }}应该是这样的

你这代码能编译成功？太神奇了 还能进行输入输出！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！ int s[3*data_length] 第一次看到这样定义数组还能编译成功 还可以输入？  跪求楼主的强大编译器啊

哈哈  我知道LZ的想法  所以答案是

要代码啊。。。

用代码格式贴出代码啊

把代码上传、、

正确的输出应该是什么？你的输出又是什么？ 何为“三分加密”？ 贴图方便了你自己，却失去了别人帮你调试的机会。


Question: ACM新手入门

问你老师。。。

http://acm.nyist.net/JudgeOnline/problemset.php 你来试试看

先去poj或者杭电oj上刷题，可以先从水体开始，逐步加强难度

刘汝佳的白色封面书《算法竞赛入门经典》，对我还说，看这本书很难！如果你看完这本书，并且把题目都做了，那挑战黑书吧，黑书没有看过，听别人说，黑书很杀死人脑细胞！只是听说！

去杭电OJ上step by step

在当当上搜“ACM参考书”


Question: 求一个平衡分组算法

楼上可能没理解我的意思啊，现在是背景类似这样 有12个实力权重值分别为1-12的选手，分成3组，要求各组选手的权重之和要相等或接近，求一个算法。

仅供参考//给出12个随机数,分成三组求和,每组的个数不定,要求求出来的三个数之间相差最小,最完美的情况是三个数相等. #include <stdlib.h> #include <stdio.h> #include <time.h> #include <math.h> #include <limits.h> int i,j,k; int g[12][3]={//可能的分组大小     { 1, 1,10},     { 1, 2, 9},     { 1, 3, 8},     { 1, 4, 7},     { 1, 5, 6},     { 2, 2, 8},     { 2, 3, 7},     { 2, 4, 6},     { 2, 5, 5},     { 3, 3, 6},     { 3, 4, 5},     { 4, 4, 4}, }; int n[12]; int m[12]; int f[12];//当前最小时各数 int g1,g2,g3;//1,2,3组可分配的个数 int n1,n2,n3;//1,2,3组已分配的个数 int f1,f2;//当前最小时1,2组的个数 int s1,s2,s3;//123组的和 int d;//1-2,2-3,3-1组中各数和之间差的绝对值之和 int dmin=INT_MAX;//保存当前d的最小值 void swap(int *pi1,int *pi2) {     int t;     t=*pi1;*pi1=*pi2;*pi2=t; } void test() {     s1=0;     for (i=0;i<g1;i++) s1=s1+n[i];     s2=0;     for (i=g1;i<g1+g2;i++) s2=s2+n[i];     s3=0;     for (i=g1+g2;i<12;i++) s3=s3+n[i];     d=abs(s1-s2)+abs(s2-s3)+abs(s3-s1);     if (d<dmin) {         dmin=d;         f1=g1;         f2=g2;         for (i=0;i<12;i++) f[i]=n[i];         printf("(");         for (i=0;i<g1;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);         printf(") %4d\n",dmin);     } else {         printf("(");         for (i=0;i<g1;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);         printf(")  (");         for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);         printf(") %4d\n",d);     } } void main() {     srand(time(NULL));     for (i=0;i<12;i++) m[i]=rand()%100;     for (i=0;i<12;i++) printf("%2d,",m[i]);     printf("\n");     for (i=1;i<12;i++) {         for (j=0;j<i;j++) {             if (m[i]>m[j]) swap(&m[i],&m[j]);//冒泡排序从大到小         }     }     for (i=0;i<12;i++) printf("%2d,",m[i]);     printf("\n");     for (k=0;k<12;k++) {//在12种分组方法中         //取第i种分组方法         g1=g[k][0];         g2=g[k][1];         g3=g[k][2];         printf("%2d-%2d,%2d,%2d\n",k,g1,g2,g3);         //将从大到小12个数双向轮流分配到三个组中         n1=0;         n2=0;         n3=0;         for (j=0;j<12;j++) {             switch (j%6) {             case 0:         redo:                 if (n1<g1) {                     n[n1]=m[j];                     n1++;                     break;                 }             case 1:                 if (n2<g2) {                     n[g1+n2]=m[j];                     n2++;                     break;                 }             case 2:                 if (n3<g3) {                     n[g1+g2+n3]=m[j];                     n3++;                     break;                 }             case 3:                 if (n3<g3) {                     n[g1+g2+n3]=m[j];                     n3++;                     break;                 }             case 4:                 if (n2<g2) {                     n[g1+n2]=m[j];                     n2++;                     break;                 }             case 5:                 if (n1<g1) {                     n[n1]=m[j];                     n1++;                     break;                 }             default:goto redo;             }         }         test();     }     printf("---------------------------------------------------\n");     g1=f1;     g2=f2;     for (i=0;i<12;i++) n[i]=f[i];     printf("(");     for (i=0;i<g1;i++) printf("%2d,",n[i]);     printf(")  (");     for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);     printf(")  (");     for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);     printf(") %4d\n",dmin); }


Question: c89三目运算符可以简写吗？

所谓的副作用，见5L的例子。

引用 5 楼 mujiok2003 的回复:[quote=引用 4 楼 suseyaoyao 的回复:] [quote=引用 3 楼 ForestDB 的回复:] https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html 这样做的话，如果x有副作用，可以避免副作用。  在上述页面中up的话，是 https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions  可以看到这不是标准C语法，是gcc的扩展。  看了你发的网址，非常感谢哦。顺便再问下，x有副作用该如何理解呢[/quote]   #define INC ++x int x = 0; .... int b = INC ? : 1; //和int b = INC ?  INC: 1;后者x自增了两次， 而前者只自增一次 [/quote]  可能。

引用 4 楼 suseyaoyao 的回复:[quote=引用 3 楼 ForestDB 的回复:] https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html 这样做的话，如果x有副作用，可以避免副作用。  在上述页面中up的话，是 https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions  可以看到这不是标准C语法，是gcc的扩展。  看了你发的网址，非常感谢哦。顺便再问下，x有副作用该如何理解呢[/quote]   #define INC ++x int x = 0; .... int b = INC ? : 1; //和int b = INC ?  INC: 1;后者x自增了两次， 而前者只自增一次

引用 3 楼 ForestDB 的回复:https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html 这样做的话，如果x有副作用，可以避免副作用。  在上述页面中up的话，是 https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions  可以看到这不是标准C语法，是gcc的扩展。  看了你发的网址，非常感谢哦。顺便再问下，x有副作用该如何理解呢

a = b怎么能和a==b混为一谈呢？！

编译器扩展  标准没这做法


Question: 粒子群算法测试函数问题

这个测试用例是很简单的，主要问题应该是你程序在演化的过程中出现了问题。


Question: 新人求大神帮忙，n个球放入m个箱子问题，要列举所有情况

有个算法，效率很高的，如果求多于盒子，就是先给每个盒子放一个，等等，这是有名的放苹果，具体看链接 http://www.cnblogs.com/dongsheng/archive/2012/08/15/2640468.html

仅供参考//qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

引用 4 楼 lovebeyondcxd 的回复:[quote=引用 3 楼 user-3 的回复:] [quote=引用 2 楼 user-3 的回复:] [quote=引用 1 楼 user-3 的回复:] 递归来做。  putKthBall(int m[] , n , k) {     if(k == n)               return;     for(int i = 0 ; i < m ; i++ )     {               putKthBall(int m[] , n , k+1);     } }    可能有些错误，每当 k == n 的时候，可以退出循环，此时应该把所有的球放完了，这个时候打印当前放的情况就可以了。[/quote]  我这里所说的错误是 m 不是数组，而是 数字，多少个箱子。[/quote]  非常感谢！！我还是不太理解，输入变量中的数组m[ ]的含义是？还有递归过程中球的数量如何增加？[/quote] 说错了，是怎么增加某个箱子中的球，每次完整递归完输出一种情况？

引用 3 楼 user-3 的回复:[quote=引用 2 楼 user-3 的回复:] [quote=引用 1 楼 user-3 的回复:] 递归来做。  putKthBall(int m[] , n , k) {     if(k == n)               return;     for(int i = 0 ; i < m ; i++ )     {               putKthBall(int m[] , n , k+1);     } }    可能有些错误，每当 k == n 的时候，可以退出循环，此时应该把所有的球放完了，这个时候打印当前放的情况就可以了。[/quote]  我这里所说的错误是 m 不是数组，而是 数字，多少个箱子。[/quote]  非常感谢！！我还是不太理解，输入变量中的数组m[ ]的含义是？还有递归过程中球的数量如何增加？

引用 2 楼 user-3 的回复:[quote=引用 1 楼 user-3 的回复:] 递归来做。  putKthBall(int m[] , n , k) {     if(k == n)               return;     for(int i = 0 ; i < m ; i++ )     {               putKthBall(int m[] , n , k+1);     } }    可能有些错误，每当 k == n 的时候，可以退出循环，此时应该把所有的球放完了，这个时候打印当前放的情况就可以了。[/quote]  我这里所说的错误是 m 不是数组，而是 数字，多少个箱子。

引用 1 楼 user-3 的回复:递归来做。  putKthBall(int m[] , n , k) {     if(k == n)               return;     for(int i = 0 ; i < m ; i++ )     {               putKthBall(int m[] , n , k+1);     } }    可能有些错误，每当 k == n 的时候，可以退出循环，此时应该把所有的球放完了，这个时候打印当前放的情况就可以了。


Question: 求助：关于code block中如何自订资源

.rc资源文件为纯文本的，随便用个编辑器就可以了，完了用rc.exe编译一下。  引用 楼主 c_hard 的回复:一直在用该软件学习编程 目前学习windows api中的图标，光标等资源的自订 但书中所举 引用： 将资源添加到程式中需要 Visual C++ Developer Studio 的一些附加功能。 对於图示来说，可以使用「Image Editor」（也称为「Graphics Editor」）来 绘制图示的图像。该图像被储存在副档名为.ICO 的图示档案中。Developer Studio 还产生一个资源描述档（副档名为.RC 的档案，有时也称作资源定义档 案），它列出了程式的所有资源和一个让程式引用资源的表头档案 （RESOURCE.H）。   问题：在code block中如何新建.RC的资源文件？             如何自订其他资源？ 注：本人濒临崩溃，求指教，或相关详细教程；谢谢，谢谢

MSDN上面有RC.exe 以及RC文件的编译使用了


Question: 怎么编程实现排列组合？

引用 33 楼 yeyu333 的回复:[quote=引用 32 楼 sadadi 的回复:] [quote=引用 28 楼 sadadi 的回复:]  srand((unsigned int)time(NULL)); 	int a[5]={3,67,9,2,5}; 	int i=0,j=0,k=0; 	i=rand()%5; 	j=rand()%5; 	k=rand()%5; 	if(i==j) 	{ 		i=abs(i-rand()%5); 	} 	if(j==k) 	{ 		k=abs(k-rand()%5); 	} 	if(i==k) 	{ 		while(j==i||k==i) 			i=rand()%5; 	} 	cout<<a[i]<<" "<<a[j]<<" "<<a[k];   失误。。。  srand((unsigned int)time(NULL));     int a[5]={3,67,9,2,5};     int i=0,j=0,k=0;     while(i==k||i==j||j==k) 	{ 		i=rand()%5; 		j=rand()%5; 		k=rand()%5; 	}          cout<<a[i]<<" "<<a[j]<<" "<<a[k]; [/quote] 可是我现在不会用RAND()啊，这个是不是产生一个随机的数 还有time(null)是怎么回事啊?[/quote] time的定义： time_t time( time_t *timer ); 用法是你先自己定义一个time_t变量，让后把变量的地址传给它。函数会返回自1970年1月1日0点走过的秒数，同时把这个返回值保存在你传进来的那个time_t*指向的变量里面。如果你传进来NULL的话，就不保存。  srand()函数是用来重置随机数的种子。参数为一个unsigned int time()取当前时间。 整个语句就是将随机数的种子设为当前时间。经常会在随机数使用前用到，可以保证每次生成的随机数不一样。

引用 8 楼 zhao4zhong1 的回复:凡是不超过10000行代码能实现的算法都称不上复杂。赵老师啊 求交往 求联系啊  我要为你生孩子啊

量变很可能会引起质变。

引用 28 楼 sadadi 的回复: srand((unsigned int)time(NULL)); 	int a[5]={3,67,9,2,5}; 	int i=0,j=0,k=0; 	i=rand()%5; 	j=rand()%5; 	k=rand()%5; 	if(i==j) 	{ 		i=abs(i-rand()%5); 	} 	if(j==k) 	{ 		k=abs(k-rand()%5); 	} 	if(i==k) 	{ 		while(j==i||k==i) 			i=rand()%5; 	} 	cout<<a[i]<<" "<<a[j]<<" "<<a[k];   失误。。。  srand((unsigned int)time(NULL));     int a[5]={3,67,9,2,5};     int i=0,j=0,k=0;     while(i==k||i==j||j==k) 	{ 		i=rand()%5; 		j=rand()%5; 		k=rand()%5; 	}          cout<<a[i]<<" "<<a[j]<<" "<<a[k];

引用 29 楼 yeyu333 的回复:[quote=引用 24 楼 my_live_123 的回复:] 如果简单来论的话，套用公式直接计算即可！C（5，3）这是库内MATH.H里面的吗 那里面又发生饿了什么状况了呢？[/quote] 不是库，我写的是数学公式！查看排列组合相关知识

引用 32 楼 sadadi 的回复:[quote=引用 28 楼 sadadi 的回复:]  srand((unsigned int)time(NULL)); 	int a[5]={3,67,9,2,5}; 	int i=0,j=0,k=0; 	i=rand()%5; 	j=rand()%5; 	k=rand()%5; 	if(i==j) 	{ 		i=abs(i-rand()%5); 	} 	if(j==k) 	{ 		k=abs(k-rand()%5); 	} 	if(i==k) 	{ 		while(j==i||k==i) 			i=rand()%5; 	} 	cout<<a[i]<<" "<<a[j]<<" "<<a[k];   失误。。。  srand((unsigned int)time(NULL));     int a[5]={3,67,9,2,5};     int i=0,j=0,k=0;     while(i==k||i==j||j==k) 	{ 		i=rand()%5; 		j=rand()%5; 		k=rand()%5; 	}          cout<<a[i]<<" "<<a[j]<<" "<<a[k]; [/quote] 可是我现在不会用RAND()啊，这个是不是产生一个随机的数 还有time(null)是怎么回事啊?

引用 21 楼 yeyu333 的回复:[quote=引用 20 楼 a1385341 的回复:] [quote=引用 7 楼 HiSoldier__ 的回复:] [quote=引用 5 楼 yeyu333 的回复:] [ [quote=引用 1 楼 HiSoldier__ 的回复:]  #include <stdio.h>  int main() {     int i, j, k;      for (i = 1; i <= 5; i++) {         for (j = 1; j <= 5; j++) {             if (j == i) continue;             for (k = 1; k <= 5; k++) {                 if (k == i || k == j) continue;                 printf("i = %d, j = %d, k = %d\n", i, j, k);              }            }        }        return 0; } 只要选3个就可以了，比如125和152是同一种类型[/quote] 那只要吧continue换成break就行了[/quote]  厉害，我看到  “只要选3个就可以了，比如125和152是同一种类型”  这句话的时候在想后面加个判断把数字相加比较就好了，知道看到你的回答。。[/quote] 他这样也不行，尽管换成了BREAK、其实一开始一开始我也想到了令其相加，但是想了下会有很多的代码而且好多的变量。其实到了这里发现又出现了新的问题[/quote] 不是C(5,3)吗？ (5*4*3)/(3*2*1)=10 换成break结果  i = 3, j = 2, k = 1 i = 4, j = 2, k = 1 i = 4, j = 3, k = 1 i = 4, j = 3, k = 2 i = 5, j = 2, k = 1 i = 5, j = 3, k = 1 i = 5, j = 3, k = 2 i = 5, j = 4, k = 1 i = 5, j = 4, k = 2 i = 5, j = 4, k = 3  少了哪一个了吗？

引用 24 楼 my_live_123 的回复:如果简单来论的话，套用公式直接计算即可！C（5，3）这是库内MATH.H里面的吗 那里面又发生饿了什么状况了呢？

量变很可能会引起质变。

引用 23 楼 my_live_123 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 引用 18 楼 zxh707wk 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 +1[/quote]  引用 9 楼 yeyu333 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 老师 收我为徒吧！[/quote]  复杂不复杂，不是用代码来衡量的。计算各种复杂度，以及证明它的归属，比如是P，NP，还是NPC等等才是正解。算法和程序存在区别。算法是抽象，程序是实例，抽象的具体描述！[/quote] 是的，我承认，一个Hello World代码和Windows操作系统的难度都是NP问题。

如果简单来论的话，套用公式直接计算即可！C（5，3）

引用 8 楼 zhao4zhong1 的回复:凡是不超过10000行代码能实现的算法都称不上复杂。 引用 18 楼 zxh707wk 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 +1[/quote]  引用 9 楼 yeyu333 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 老师 收我为徒吧！[/quote]  复杂不复杂，不是用代码来衡量的。计算各种复杂度，以及证明它的归属，比如是P，NP，还是NPC等等才是正解。算法和程序存在区别。算法是抽象，程序是实例，抽象的具体描述！

引用 10 楼 yeyu333 的回复:[quote=引用 7 楼 HiSoldier__ 的回复:] [quote=引用 5 楼 yeyu333 的回复:] [ [quote=引用 1 楼 HiSoldier__ 的回复:]  #include <stdio.h>  int main() {     int i, j, k;      for (i = 1; i <= 5; i++) {         for (j = 1; j <= 5; j++) {             if (j == i) continue;             for (k = 1; k <= 5; k++) {                 if (k == i || k == j) continue;                 printf("i = %d, j = %d, k = %d\n", i, j, k);              }            }        }        return 0; } 只要选3个就可以了，比如125和152是同一种类型[/quote] 那只要吧continue换成break就行了[/quote] 嗯 我试试啊 [/quote] 这样发现还是不行

引用 20 楼 a1385341 的回复:[quote=引用 7 楼 HiSoldier__ 的回复:] [quote=引用 5 楼 yeyu333 的回复:] [ [quote=引用 1 楼 HiSoldier__ 的回复:]  #include <stdio.h>  int main() {     int i, j, k;      for (i = 1; i <= 5; i++) {         for (j = 1; j <= 5; j++) {             if (j == i) continue;             for (k = 1; k <= 5; k++) {                 if (k == i || k == j) continue;                 printf("i = %d, j = %d, k = %d\n", i, j, k);              }            }        }        return 0; } 只要选3个就可以了，比如125和152是同一种类型[/quote] 那只要吧continue换成break就行了[/quote]  厉害，我看到  “只要选3个就可以了，比如125和152是同一种类型”  这句话的时候在想后面加个判断把数字相加比较就好了，知道看到你的回答。。[/quote] 他这样也不行，尽管换成了BREAK、其实一开始一开始我也想到了令其相加，但是想了下会有很多的代码而且好多的变量。其实到了这里发现又出现了新的问题

引用 7 楼 HiSoldier__ 的回复:[quote=引用 5 楼 yeyu333 的回复:] [ [quote=引用 1 楼 HiSoldier__ 的回复:]  #include <stdio.h>  int main() {     int i, j, k;      for (i = 1; i <= 5; i++) {         for (j = 1; j <= 5; j++) {             if (j == i) continue;             for (k = 1; k <= 5; k++) {                 if (k == i || k == j) continue;                 printf("i = %d, j = %d, k = %d\n", i, j, k);              }            }        }        return 0; } 只要选3个就可以了，比如125和152是同一种类型[/quote] 那只要吧continue换成break就行了[/quote]  厉害，我看到  “只要选3个就可以了，比如125和152是同一种类型”  这句话的时候在想后面加个判断把数字相加比较就好了，知道看到你的回答。。

引用 18 楼 zxh707wk 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 +1[/quote] 单纯用数量（代码行数）衡量算法的复杂度有点太片面。

引用 8 楼 zhao4zhong1 的回复:凡是不超过10000行代码能实现的算法都称不上复杂。 +1

引用 11 楼 yeyu333 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 凡是不超过10000行代码能实现的算法都称不上复杂。 请问C语言里用#include <graphics.h>  为什么会报错，好像是库里没有这个。那怎么办啊？ 我的 VISUAL C++6.0 32MB的[/quote]  graphics.h是borland公司在TC2.0,BC3.0及后继版本中提供的一套图形函数，并不是ANSI C建议的标准函数，不具备可移植性。因此别的C编译系统中（如MS 的visual C++)并没有这一套函数-----如果有对应类似的函数，也不用这个头文件

#include <stdio.h>  int main() { 	int i, j, k; 	int num = 0;//排列的种数 	char people[] = { 'a','b','c','d','e'}; 	for (i = 0; i < 3; i++) 	{ 		for (j = i+1; j < 4; j++) 		{ 			for (k = j+1; k < 5; k++) 			{ 				printf("%c\t%c\t%c\n",people[i],people[j],people[k]);//输出排列 				num += 1; 			} 		} 	} 	printf("%d\n",num); 	return 0; }


Question: 如何用C语言调用ping命令

引用 10 楼 philip_puma 的回复:[quote=引用 2 楼 mujiok2003 的回复:] #include <stdio.h> #include <stdlib.h> #define TARGET "www.baidu.com" int main( ) {    char   psBuffer[512];    FILE   *pPipe;     if( (pPipe = _popen( "ping -n 10 " TARGET, "rt" )) == NULL )       exit( 1 );     while(fgets(psBuffer, 512, pPipe))    {      printf("%s", psBuffer);    }    _pclose(pPipe); }    这个碉堡了好么？[/quote]我测试了，好象不行，我随意写了一个不存在的局域网地址，然后居然也通了

引用 7 楼 zhao4zhong1 的回复:仅供参考#include <windows.h> #include <stdio.h> #include <string.h> char YN(int k) {     FILE *f;     char fn[40];     char ln[80];     char yn;     int n;      yn='N';     sprintf(fn,"d:\\ping%d.txt",k);     f=fopen(fn,"r");     if (NULL!=f) {         n=0;         while (1) {             if (NULL==fgets(ln,80,f)) break;//             if (strstr(ln,"ms ")) {                 yn='Y';                 break;//             }             n++;             if (n>=4) break;//         }         fclose(f);     }     return yn; } void main(int argc,char **argv) {     char cmdstr[256];     int i;     int IP[3];     char c;      if (argc<2) {     USAGE:         printf("Usage example:\n    %s 192.168.60.\nto test 192.168.60.1-254\n",argv[0]);         return;     }     if (4==sscanf(argv[1],"%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&c)) {         if (0<=IP[0] && IP[0]<=255          && 0<=IP[1] && IP[1]<=255          && 0<=IP[2] && IP[2]<=255          && '.'==c) {             for (i=1;i<255;i++) {                 sprintf(cmdstr,"cmd /c ping %s%d -n 1 -w 1000 >d:\\ping%d.txt",argv[1],i,i);                 WinExec(cmdstr,SW_HIDE);             }             Sleep(3000);             for (i=1;i<255;i++) {                 printf("%c %s%d\n",YN(i),argv[1],i);             }             Sleep(3000);             WinExec("cmd /c del /q d:\\ping*.txt",SW_HIDE);         } else goto USAGE;     } else goto USAGE; }   高人呀！

以前我想用自己的程序发邮件，找了好几个现成的库，都不太满足要求，于是直接去了解邮件协议，按照协议进行连接、通讯，最终成功发送了。

你查查ping命令是如何通讯的，然后按照其方式自己编写程序进行ping就行了。

我也不知道哎

看看下边这个函数，可判断链路是否正常 netSt = get_netlink_status("eth1");//调用 // -1 -- error , details can check errno // 1 -- interface link up // 0 -- interface link down. int get_netlink_status(const char *if_name) {     int skfd;     struct ifreq ifr;     struct ethtool_value edata;      edata.cmd = ETHTOOL_GLINK;     edata.data = 0;      memset(&ifr, 0,sizeof(ifr));     strncpy(ifr.ifr_name, if_name,sizeof(ifr.ifr_name)- 1);     ifr.ifr_data =(char *) &edata;      if (( skfd= socket(AF_INET, SOCK_DGRAM, 0 )) < 0)         return -1;      if(ioctl( skfd, SIOCETHTOOL,&ifr ) == -1)     {         close(skfd);         return -1;     }      close(skfd);     return edata.data;   return 0; }

试试管道吧。

引用 2 楼 mujiok2003 的回复:#include <stdio.h> #include <stdlib.h> #define TARGET "www.baidu.com" int main( ) {    char   psBuffer[512];    FILE   *pPipe;     if( (pPipe = _popen( "ping -n 10 " TARGET, "rt" )) == NULL )       exit( 1 );     while(fgets(psBuffer, 512, pPipe))    {      printf("%s", psBuffer);    }    _pclose(pPipe); }    这个碉堡了好么？

你看一下ping程序的实现原理


Question: 调试发现错误，但不知为什么错

问题解决了？

3楼正解。。。。。

来学习，顺便接分，既然找到错误了，那么恭喜楼主又更上一层楼啦~

找到问题了，就是第27行的那个qsort调用，它的第一个参数应该是个数组名，而非指向数组的指针。 改成：qsort(students, SIZE, sizeof(INFO), comp);就好了。另外，还要去掉56、57两行，它们没有实际作用。

引用 1 楼 u012421456 的回复:C-Free，VS2005调试没错误啊！感觉写的有些费解，可以参考一下这个——http://blog.csdn.net/u012421456/article/details/26170519 编译没有报错，运行时就会出错。例如，我按照程序提示一个接一个输入了三组数据（姓名、分数）后，那个第47行的while循环并没有跳出，而是继续提示输入姓名，但无论是继续输入姓名按回车，还是直接按回车，程序都会崩溃。


Question: 结构体指针做函数参数

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

你的addPos函数生成的链表是个反向增长的链表，而且表头的指针你也没能更新 main函数里的pospatrn仍然指向一开始分配的内存，这块内存未赋值 你可以把“ppos->next=pospatrn”这句换成“pospatrn->next=ppos；ppos->next=NULL” 这样链表是正向增长，表头的指针也不需要更新

pospatrn=ppos; 这句只在函数内部起作用。指针也是一个变量，也是按值传递。 而且你里外都malloc, 这是干嘛？

大虾快来帮帮忙啊

共同学习！

谢谢各位，结合各位的答案看了些资料后发现对指针参数的理解错误了，正如3楼说的，指针也是一个变量，传到函数中去的是这个地址（实参）的一个副本，可以通过修改该地址指向的内存地址的值来实现修改实参指向的值，但企图通过修改形参中地址来修改实参中的地址仍是徒劳。只能修改形参指向的内存中的值。 谢谢各位不吝赐教～


Question: 获取linux系统下网络接口名称

获取指定接口IP  #include <stdio.h>   #include <stdlib.h>   #include <stdint.h>   #include <string.h>   #include <unistd.h>   #include <arpa/inet.h>   #include <sys/ioctl.h>   #include <sys/socket.h>   #include <net/if.h>      #define NIPQUAD(addr) \       ((unsigned char *)&addr)[0], \       ((unsigned char *)&addr)[1], \       ((unsigned char *)&addr)[2], \       ((unsigned char *)&addr)[3]   #define NIPQUAD_FMT "%u.%u.%u.%u"      uint32_t obtain_ip(const char *dev)   {       int fd = -1;       struct ifreq ifr;       struct sockaddr_in *addr;          strncpy(ifr.ifr_name, dev, IFNAMSIZ);          fd = socket(AF_INET, SOCK_DGRAM, 0);       if (fd < 0)       {           perror("socket()");           return 0;       }          if (ioctl(fd, SIOCGIFADDR, &ifr))       {           perror("ioctl()");           close(fd);           return 0;       }          close(fd);          addr = (struct sockaddr_in *)&(ifr.ifr_addr);       return addr->sin_addr.s_addr;   }      int main(int argc, char **argv)   {       uint32_t ip = obtain_ip(argv[1]);          if (ip)           printf("ip: %u.%u.%u.%u\n", NIPQUAD(ip));       return 0;   }     或指定接口MAC  #include <stdio.h>   #include <stdlib.h>   #include <string.h>   #include <sys/ioctl.h>   #include <sys/socket.h>   #include <netinet/in.h>   #include <net/if.h>   #include <assert.h>      int obtain_mac(const char *ifname, unsigned char *mac, int len)   {       int sk = -1, ret = 0;       struct ifreq ifreq;          assert(ifname);       assert(mac);       assert(len >= 6);          sk = socket(AF_INET, SOCK_STREAM, 0);       if (sk < 0)       {           perror("socket");           ret--;           goto OUT;       }          strcpy(ifreq.ifr_name, ifname);       if (ioctl(sk, SIOCGIFHWADDR, &ifreq) < 0)       {           perror("ioctl");           ret--;           goto OUT;       }       memcpy(mac, (unsigned char *)ifreq.ifr_hwaddr.sa_data, 6);      OUT:       if (sk >= 0)           close(sk);       return ret;   }      int main(int argc, char **argv)   {       unsigned char mac[12];          if (obtain_mac(argv[1], mac, sizeof(mac)) < 0)           return -1;          printf("%02X:%02X:%02X:%02X:%02X:%02X\n",               mac[0],              mac[1],              mac[2],              mac[3],              mac[4],              mac[5]              );          return 0;   }

楼主，求共享方法！

system("ifconfig >ifconfig.txt"); //然后读文件ifconfig.txt的内容  真想不用命令，请参考ifconfig命令对应的源代码。

亲，谢谢，已解决

引用 1 楼 buyong 的回复:ifconfig  不用命令

ifconfig

ioctl可以获取噢。


Question: C结构与指针的问题

你的第一个程序struct namect p; 你的第二个程序struct namect  *pst;

引用 9 楼 fancyfhb 的回复:[quote=引用 7 楼 mcmay 的回复:] [quote=引用 3 楼 fancyfhb 的回复:] [quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？ [/quote] 第二个程序中的指针变量struct namect * pst只是个struct namect型的指针变量，它并没有指向任何结构体（也就是没有为它分配内存空间）。例如，这里可以用malloc为它分配一个struct namect型的内存空间，pst = (struct namect *) malloc(sizeof(struct namect));，这样就可以使用pst->fname这样的引用了。而第一个程序中的函数getinfo中pst为什么可以使用呢？main函数中的&p这个结构体地址做为getinfo函数的实际参数传递（拷贝）给了这个函数中的pst，而结构体p是已经分配有地址的了，所以pst是有效的。再用malloc给它的fname成员分配空间是没有必要的，直接使用pst->fname即可。[/quote]  引用 7 楼 mcmay 的回复:[quote=引用 3 楼 fancyfhb 的回复:] [quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？ [/quote] 第二个程序中的指针变量struct namect * pst只是个struct namect型的指针变量，它并没有指向任何结构体（也就是没有为它分配内存空间）。例如，这里可以用malloc为它分配一个struct namect型的内存空间，pst = (struct namect *) malloc(sizeof(struct namect));，这样就可以使用pst->fname这样的引用了。而第一个程序中的函数getinfo中pst为什么可以使用呢？main函数中的&p这个结构体地址做为getinfo函数的实际参数传递（拷贝）给了这个函数中的pst，而结构体p是已经分配有地址的了，所以pst是有效的。再用malloc给它的fname成员分配空间是没有必要的，直接使用pst->fname即可。[/quote]   试了一下，把第1个程序中的pst->fname = (char *)malloc(strlen(temp)+1);语句删掉后，程序是会报错的，  但是在这行之前加一个	printf("pst->fname address:%p\n",pst->fname);   是可以显示地址的，不知道什么原因？ 如何解释？[/quote]       你的结构体p中的*fname和*lname成员都只是指向char型变量的指针而已。在你给它们赋值之前，它们是没有被 分配内存空间的。而说结构体p占有内存空间，这是正确的。因为当你定义这个p变量时，内存中为它分配了空间，用以存放两个char型指针变量（*fname和*lname）和一个int型变量。但是*fname和*lname这两个变量只是两个指针而已，它们在结构体p中所占用的空间只能用来存放这两个指针变量本身而已。而这两个指针变量并没有指向你所指定（赋予）的地址，因为你没有给它们赋值（这个值就是某个char型变量地址）。因此，你用pst->fname = (char *)malloc(strlen(temp)+1);这样的语句来给pst->fname赋值不仅是正确的，而且是有必要的，如果你要使用它的话。        至于printf("pst->fname address:%p\n",pst->fname);这个语句能够显示地址，那是因为在你定义*fname这个变量（即定义结构体变量p）之前，在*fname这个指针变量后来所占用的空间当中，已经有了你的电脑中其他程序运行时所存放过的某个值。这个“遗留值”没有被释放掉（这是操作系统为了节约系统资源、提高运行速度而“偷的懒”），也没有因为你对*fname赋值而被覆盖掉（因为你去掉了那个malloc语句，所以就没有给*fname赋值了），因此它还继续赖在那里。当你使用printf("pst->fname address:%p\n",pst->fname);这个语句来打印*fname这个变量所占用的内存空间中的“遗留值”时，这个遗留值就以地址的格式显示出来了（你用了%p）。当然，这个“遗留值”未见得就是个地址，你用其他的格式控制符输出时，恐怕显示的结果也会不一样。

引用 7 楼 mcmay 的回复:[quote=引用 3 楼 fancyfhb 的回复:] [quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？ [/quote] 第二个程序中的指针变量struct namect * pst只是个struct namect型的指针变量，它并没有指向任何结构体（也就是没有为它分配内存空间）。例如，这里可以用malloc为它分配一个struct namect型的内存空间，pst = (struct namect *) malloc(sizeof(struct namect));，这样就可以使用pst->fname这样的引用了。而第一个程序中的函数getinfo中pst为什么可以使用呢？main函数中的&p这个结构体地址做为getinfo函数的实际参数传递（拷贝）给了这个函数中的pst，而结构体p是已经分配有地址的了，所以pst是有效的。再用malloc给它的fname成员分配空间是没有必要的，直接使用pst->fname即可。[/quote]  引用 7 楼 mcmay 的回复:[quote=引用 3 楼 fancyfhb 的回复:] [quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？ [/quote] 第二个程序中的指针变量struct namect * pst只是个struct namect型的指针变量，它并没有指向任何结构体（也就是没有为它分配内存空间）。例如，这里可以用malloc为它分配一个struct namect型的内存空间，pst = (struct namect *) malloc(sizeof(struct namect));，这样就可以使用pst->fname这样的引用了。而第一个程序中的函数getinfo中pst为什么可以使用呢？main函数中的&p这个结构体地址做为getinfo函数的实际参数传递（拷贝）给了这个函数中的pst，而结构体p是已经分配有地址的了，所以pst是有效的。再用malloc给它的fname成员分配空间是没有必要的，直接使用pst->fname即可。[/quote]   试了一下，把第1个程序中的pst->fname = (char *)malloc(strlen(temp)+1);语句删掉后，程序是会报错的，  但是在这行之前加一个	printf("pst->fname address:%p\n",pst->fname);   是可以显示地址的，不知道什么原因？ 如何解释？

修改好了，感谢以上几位！ 修改后代码如下，顺便加了两行以查看内存地址： // get first name2 #include<stdio.h> #include<string.h> #include<stdlib.h> struct namect { 	char *fname; 	char *lname; 	int length; };   int main(void) { 	char temp[81]; 	struct namect *pst; 	 	pst = (struct namect *)malloc(100); 	printf("pst address:%p\n",pst); 	printf("input your first name:"); 	gets(temp); 	pst->fname = (char*)malloc(strlen(temp)+1); 	printf("pst.fname address:%p\n",pst->fname); 	strcpy( pst->fname,temp); 	     printf("your first name is: %s \n",pst->fname);      	 	free(pst->fname); }

引用 3 楼 fancyfhb 的回复:[quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？ [/quote] 第二个程序中的指针变量struct namect * pst只是个struct namect型的指针变量，它并没有指向任何结构体（也就是没有为它分配内存空间）。例如，这里可以用malloc为它分配一个struct namect型的内存空间，pst = (struct namect *) malloc(sizeof(struct namect));，这样就可以使用pst->fname这样的引用了。而第一个程序中的函数getinfo中pst为什么可以使用呢？main函数中的&p这个结构体地址做为getinfo函数的实际参数传递（拷贝）给了这个函数中的pst，而结构体p是已经分配有地址的了，所以pst是有效的。再用malloc给它的fname成员分配空间是没有必要的，直接使用pst->fname即可。

引用 4 楼 fancyfhb 的回复:[quote=引用 1 楼 user-4 的回复:] struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  还有，为什么在程序1的getinfo函数中，malloc可以正常执行内存分配呢？[/quote] 1中的pst是有地址的 2中的pst是没有地址的 不能直接p->fname 要先初始化

未分配内存 野指针   传值时 会暂时分配内存

引用 1 楼 user-4 的回复:struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  还有，为什么在程序1的getinfo函数中，malloc可以正常执行内存分配呢？

引用 1 楼 user-4 的回复:struct namect  *pst;  // 需要首先分配内存， 然后访问pst->fname  谢了先！！  能解释稍微具体一点吗？ 还是没理解，如何分配呢？


Question: error C2109: 下标要求数组或指针类型,不知道该怎么改，求指教

已经解决了，谢谢

数组是int a[]或者int* a，这样改：  #include<stdio.h> void fun(int a[],int n,int *odd,int *even) { int i; *odd=0; *even=0; for (i=0;i<n;i++) { if(a[i]%2==0) *even+=a[i]; else *odd+=a[i]; } } void main() { int a[5]={1,2,3,4,5},j,o; fun (a,5,&j,&o); printf("the sum of odd is %d,tne sun of even is %d",j,o); }


Question: 新手

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

我也推荐郝斌视频！！！！！！！

你这问题问的

i为什么等于1         longs=0,t=0;      能不能详细解释一下我完全不懂

Sn=a+aa+aaa+------+aaaaaaa(n  个  a),  其中  a  和  n  都从键盘中输入，如从键盘中输入  2,5  ，则计   算  S5=2+22+222+2222+22222

和你学中文一样，学了语文语法写篇文章。学了语言的语法就写几个简单程序练练。

多看书，对照书上的例子，再多敲代码

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

看百遍，写千遍，奇迹自现！

我真的不知道哎

一直看视频，也不是办法啊！有新手的练习题目吗?

有没有什么题目可以练习的，本人是新手

引用 10 楼 aaa53526561 的回复:引用 为什么Z=X,Z=Y；这个事什么意思，，求解释详细点  这个程序就是最后返回值z到主函数   if(x>y) z=x;  就是当x大于y时  输出的z就是较大的数x else z=y;  否则当x<y 那么z就是较大的数y 总之这个简单判断就是输出z 绝对是较大的那个数值  其实这个没比较这么复杂，一个函数体就可以做的 #include <stdio.h> void main () {      int a,b,c;      printf("\nEnter two Numbers:");      scanf("%d,%d",&a,&b);        if(a>b) c=a;      else c=b;        printf("Maximum:%d\n",c); }

什么意思啊？？？？？？

你在说话的时候有想过语法么？

有没有新手的练习题目，本人想做一做，请指导一下。


Question: C语言如何遍历结构体成员

打个断点。。。运行起来跟踪。。把这结构体的指针加到addwatch里。。直接就可以看内容。。全部字段都能看。。不用打印出来看的啦。。。这个方便哇。。

用RAD C++Builder 的话。。我有很简单的方法让你看到你这结构体的全部各个字段内容。。。^m^

我也需要这么一个函数 在不知道（假装不知道）结构体内部成员数量和类型的情况下能够读取，要不然那么多结构体和成员，一个个输出累呀  怎么办……

引用 30 楼 assassin5616 的回复:[quote=引用 12 楼 dailongzhen 的回复:] [quote=引用 11 楼 liuhengxiao 的回复:] 引用别人的结构体那也应该能查看到结构体的成员吧。。。 手动敲代码是能看到，但是传过来的结构体比较庞大，包含的成员类型丰富多样，结构体嵌套很多，总数据有的达到100多个甚至更多，如果全都手动敲一遍，甚是麻烦，而且效率也不高，因此想要寻找一种快捷有效的算法，不知有没有？[/quote]  这个真没有，除非你自己写一个可以读取结构体，并且自动生成输出代码的工具。有点类似一个很简单的分析器。[/quote]    引用 31 楼 dailongzhen 的回复:[quote=引用 30 楼 assassin5616 的回复:] [quote=引用 12 楼 dailongzhen 的回复:] [quote=引用 11 楼 liuhengxiao 的回复:] 引用别人的结构体那也应该能查看到结构体的成员吧。。。 手动敲代码是能看到，但是传过来的结构体比较庞大，包含的成员类型丰富多样，结构体嵌套很多，总数据有的达到100多个甚至更多，如果全都手动敲一遍，甚是麻烦，而且效率也不高，因此想要寻找一种快捷有效的算法，不知有没有？[/quote]  这个真没有，除非你自己写一个可以读取结构体，并且自动生成输出代码的工具。有点类似一个很简单的分析器。[/quote] 就是不懂该如何分析？求教[/quote]  要不就直接写代码读源文件，然后分析结构体，生成一个输出函数。想通用一点就用flex/Bison。这两样东西学习曲线挺陡的，需要花点时间

引用 36 楼 zhao4zhong1 的回复:任何编程语言都不能自省，只用人和某些高级动物才能自省。 任何编程语言都不能自省，只有人和某些高级动物才能自省。

它只是个工具，没有自主能力，还要有人来代劳！

没有办法，除非编译器有相应的扩展。C#之类的话倒是可以用反射。

c++是不能动态创建新类的，只能创建类的实例  类声明的本质就是一定长度的内存进行合理规划，这个是在编译期完成的，而不是在运行态  如果要在运行时动态创建类，那么所有的工作就得自己做  也就是你自己必须创建一个类的声明进行传递，如D3D编程中就有类似的操作，在将顶点数据传给显卡的时候，就有一个声明，声明就是保存这个数据流中偏移量和类型等信息。

引用 41 楼 akirya 的回复:没有办法，除非编译器有相应的扩展。C#之类的话倒是可以用反射。http://bbs.csdn.net/topics/390795780 请您打开这个链接，里面有一个问题待解，谢谢！

引用 42 楼 wenpinglaoyao 的回复:[quote=引用 19 楼 ForestDB 的回复:] C不是动态语言，没有元信息（字段名、字段类型），不能反射，所以只能一行行写代码。 http://http://bbs.csdn.net/topics/390795780请大神打开这个链接，这个帖子我发了两次！无人能够回答，所以在您身上碰碰运气，叨扰了。[/quote] http://bbs.csdn.net/topics/390795780

引用 19 楼 ForestDB 的回复:C不是动态语言，没有元信息（字段名、字段类型），不能反射，所以只能一行行写代码。 http://http://bbs.csdn.net/topics/390795780请大神打开这个链接，这个帖子我发了两次！无人能够回答，所以在您身上碰碰运气，叨扰了。

引用 38 楼 pubuzhixia 的回复:[quote=引用 4 楼 PDD123 的回复:] 事先不知道内部有哪些成员，怎么可能正确打印？  支持。  事先不知道有哪些成员，也就意味着都不知道如何去解释这一段内存，本来就无法打印。 比如这段内存放的是0xFFFFFFFF，如果只有一个int32成员，那结果就是-2147483648；如果为2个int16成员，那结果就是-32768，-32768了。。。[/quote] 我大概了解大家的意思了

引用 4 楼 PDD123 的回复:事先不知道内部有哪些成员，怎么可能正确打印？  支持。  事先不知道有哪些成员，也就意味着都不知道如何去解释这一段内存，本来就无法打印。 比如这段内存放的是0xFFFFFFFF，如果只有一个int32成员，那结果就是-2147483648；如果为2个int16成员，那结果就是-32768，-32768了。。。

引用 34 楼 dailongzhen 的回复:[quote=引用 33 楼 u012222342 的回复:] [quote=引用 32 楼 dailongzhen 的回复:] [quote=引用 29 楼 u012222342 的回复:] 知道啥叫数据结构吗 ， 兄弟  懂一点[/quote] 不知道结构怎么打印，智能分析吗  ，不知道类型你怎么分析结构里有多少项呢 struct A{int a; int b; char c[20];}     占28个字节 ，如果存全int 能存7个 ，short 14个，不一样的类型，不一样的个数，类型混合更麻烦，[/quote] 那个结构体就是很多不同类型的混合，结构体嵌套。。。[/quote]  不可能的 ，

任何编程语言都不能自省，只用人和某些高级动物才能自省。

我认为这是不可能的，因为你不知道保存的是什么数据，都是01010101，你不知道数据类型，怎么知道是什么数据呢

引用 33 楼 u012222342 的回复:[quote=引用 32 楼 dailongzhen 的回复:] [quote=引用 29 楼 u012222342 的回复:] 知道啥叫数据结构吗 ， 兄弟  懂一点[/quote] 不知道结构怎么打印，智能分析吗  ，不知道类型你怎么分析结构里有多少项呢 struct A{int a; int b; char c[20];}     占28个字节 ，如果存全int 能存7个 ，short 14个，不一样的类型，不一样的个数，类型混合更麻烦，[/quote] 那个结构体就是很多不同类型的混合，结构体嵌套。。。

引用 12 楼 dailongzhen 的回复:[quote=引用 11 楼 liuhengxiao 的回复:] 引用别人的结构体那也应该能查看到结构体的成员吧。。。 手动敲代码是能看到，但是传过来的结构体比较庞大，包含的成员类型丰富多样，结构体嵌套很多，总数据有的达到100多个甚至更多，如果全都手动敲一遍，甚是麻烦，而且效率也不高，因此想要寻找一种快捷有效的算法，不知有没有？[/quote]  这个真没有，除非你自己写一个可以读取结构体，并且自动生成输出代码的工具。有点类似一个很简单的分析器。

知道啥叫数据结构吗 ， 兄弟

用宏定义吧，稍微能省点事。


Question: c语言操作BMP文件

色彩空间压缩与变换。

我是来学习的

找图像处理的教程，高斯模糊？

思路就是: RGB888 -> RGB565 这个大家都懂，涉及到BMP，关键是存储的数据格式，读写，还有一个色彩空间的转换。  从RGB -> YCBR 也是一样的道理。


Question: C语言 输入输出流问题 诡异

引用 4 楼 zhao4zhong1 的回复:乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单，不用格式控制符！ 但是不用格式控制符，输入输出恰好是你期望的格式的时候好说；等到输入输出不是你期望的格式的时候，你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout！ 使用scanf、printf。  好吧，我换个版本。。

额，我承认，不应该C\C++混搭，不过是为了看得更清楚。。。

应为你没有删除缓冲区，你getchar时回车结束，这个回车会被下个getchar接受


Question: 请问物联网开发要学习哪些东西？

首先对C要熟悉，然后去学习Linux系统，然后去学习ARM，驱动编程等，做物联网要学的东西很多啊。

单片机若干知识，包括8051，ARM，无线通信等一系列 。。。。。

物联网就是嵌入式+Internet。分解来就是 linux+ARM+无线+Internet。这几块就看你对哪个感兴趣了。


Question: #define定义的名字一般在编译时被丢弃，而枚举名字则通常一直在调试器中可见，可以在调试代码是使用它们

参考gcc或g++相关源代码。

你还是看看c/c++的编译过程吧。#define的宏定义是在预处理阶段执行的，在预处理器里；而枚举是在编译阶段执行的