Question: 求教一个多线程的问题

引用 13 楼 lovesmiles 的回复:我要把赵老师的帖子模板全收集了，以后我帮你贴 哈！本人百年之后，未尽的CSDN回帖事业后继有人了！！

我要把赵老师的帖子模板全收集了，以后我帮你贴

看着赵老师每个帖子都有回复啊，够专业。但是有点人不一定能看到，建议只回复核心的部分，一下就一大篇代码......

有的好东西重复使用次数越多越差； 但这一点也不妨碍 有的好东西重复使用次数越多越好！

sorry  说的赵老师的那个程序

引用 3 楼 o303028708 的回复:1、创建一个时间对象，对线程进行同步，在线程函数里，waitforsingleobject（）等待 2、兼容设备描述表 3、srw锁 自己好好研这个用过好多遍了啊

当然是了。

引用 4 楼 zhao4zhong1 的回复:仅供参考//循环向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; }   这么犀利，一串代码就送上了，赵老师是不是留了很多代码留着在论坛里回答问题。

启动两个线程，每个线程处理一个函数，如果公用一个全局变量需要加锁，不能同时操作同一个全局变量。

赵老师，你要不要这么牛啊

其实有很多方法，比如全局变量+互斥锁；全局变量+信号量； 推荐看此博客http://blog.csdn.net/morewindows/article/details/7442333

直接就可以访问全局变量，只是访问全局变量要加锁


Question: 怎么让这个程序正确的输出运算24的公式

引用 13 楼 zhao4zhong1 的回复:[quote=引用 11 楼 u012006886 的回复:] 说赵老师，赵老师就到了 可惜7楼把本人的ID敲错了（或者记错了）。 [/quote] soooooooorry! 记忆错误，特此更正，决不再错。

也就是说加进一个控制 只有这个控制被触发时才会显示运算公式。

各位大哥 请我我那个代码要怎么样才能让在执行除法时，只要可以整除的数才可以进行相除，还有就是 怎么样才能让生成随机数的那块和运算公式的那块分开来？

主要修改: 1 要区分参加运算的是原始字符还是中间结果,前者要转化为数值,而后者不必转化.因此把原来的calc_sign拆出一个新函数convert 2 补关于j的循环  #include <stdio.h>  #include <stdlib.h> #include <time.h> #include <ctype.h> #define MAX 13  int convert(char a) //改 {   int b;   if(a=='O')     b = 10;   else if(a=='J' )     b =11;   else if(a=='Q')     b =12;   else if(a=='K' )     b =13;   else b = (int)a - '0';    return b; }  int calc_sign(int a1, int a2, int b) //改 {   switch (b) {     /*开关控制语句     根据变量b的不同值。     执行相对应的case语句~     */   default:   case 0: return (a1+a2);    case 1: return (a1-a2);    case 2: return (a1*a2);    case 3: if (a2!=0&&(a1/a2)!=0)/* return*/ (a1/a2);           else return 0;    }  }/*运算模块*/  void calc_24point() {   int c = 0;   int a = 0;   char b[4][13]={   {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},  /*扑克牌，10用O来表示*/   {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},   {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},   {'1','2','3','4','5','6','7','8','9','O','J','Q','K'}};   char num[4];   char sign[5]="+-*/";   int i=0;   int j=0;   int k=0;   int l=0;   int n=0;   int m=0;   int r=0;   int tem1=0;   int tem2=0;   int tem3=0;   srand( (unsigned)time(0));/*随机数发生器的初始化函数*/   a = rand()%MAX;/*产生的随机数num[0]作为增量，范围1-10*/   c =rand()%4;   num[0] =b[c][a];    a = rand()%MAX;   c = rand()%4;   num[1] =b[c][a];    a = rand()%MAX;   c = rand()%4;   num[2] = b[c][a];    c = rand()%4;   a = rand()%MAX;   num[3] = b[c][a];    printf("%c,%c,%c,%c\n",num[0],num[1],num[2],num[3]);    for(i = 0;i<4 ;i++)   {     for (j=0; j<4; j++) //加     { //加       if (j==i)continue;       for(k=0;k<4;k++)       {         if(k==i||k==j)continue;/*返回循环起始处*/         for(l = 0; l<4; l++)         {           if(l==i||l==j||l==k)continue; //改 if(l==k||l==j||l==k)continue;           for(n = 0;n<4; n++)           {              for(m = 0;m<4; m++)             {               for(r = 0;r<4; r++)               {                  tem1=calc_sign(convert(num[i]), convert(num[j]), n); //改 tem1=calc_sign(num[i],num[j],n);                 tem2=calc_sign(tem1, convert(num[k]), m); //改 tem2=calc_sign(tem1,num[k],m);                 tem3=calc_sign(tem2, convert(num[l]), r); //改 tem3=calc_sign(tem2,num[l],r);                 if(tem3==24)                 {                   printf("(%c%c%c)%c%c}%c%c=24\n",num[i],sign[n],num[j],sign[m],num[k],sign[r],num[l]);                 }                 else if(tem3==-24)                 {                   printf("%c%c(%c%c%c)}%c%c=24\n",num[k],sign[m],num[i],sign[n],num[j],sign[r],num[l]);                 }                 else                 {                   tem1=calc_sign(convert(num[i]), convert(num[j]), n); //改 tem1=calc_sign(num[i],num[j],n);                   tem2=calc_sign(convert(num[k]), convert(num[l]), r); //改 tem2=calc_sign(num[k],num[l],r);                   tem3=calc_sign(tem1,tem2,m);                   if(tem3==24.0)                   {                     printf("(%c%c%c)%c(%c%c%c)=24\n",num[i],sign[n],num[j],sign[m],num[k],sign[r],num[l]);                   }                 }               }             }           }         }       }     } //加   } }   int main() {   while(1)   {     calc_24point();     if(getchar() != 'e') continue;     else break;   } }

你这个代码完全看不懂，没注释

你应该从排列组合的观点出发考虑这个题目 1.给定的四个数的排列位置有哪些 2.四个数之间的运算符有哪些 3.考虑可用括号改变的运算次序有哪些  写出它们的排列  在本坛的搜索关键字是：zhao1zhong4     ，   24点

引用 11 楼 u012006886 的回复:说赵老师，赵老师就到了 可惜7楼把本人的ID敲错了（或者记错了）。

感谢各位大哥的帮忙， 小弟还有一个问题 怎么样才能让它输出a1/a2是整数 而不是浮点数

说赵老师，赵老师就到了

各位大哥，怎么才能让这个程序只输出运算结果等于24的公式啊！

规则就是 我只要它输出运算结果等于24的公式，但是参与运算的4个数字是我上面那个程序随机生成的1到k这13个字符，其中10=O,11=J,12=Q,13=K。

我这个程序会输出随机生成数运算公式，但是这些运算公式有一些的运算结果根本不等于24，所以我想的是怎么样才能让它输出随机生成数运算结果等于24的公式，意思就是说怎么让这个程序正确的输出运算结果等于24的公式

说清楚点，要做什么，什么规则

大哥 你这个代码我测试了 不行，没法正确的输出运算结果等于24的公式虽然有点是正确的有的是错误的 但我要的是正确输出运算结果等于24的公式

#include <stdio.h>  #include <stdlib.h> #include <time.h> #include <ctype.h> #define MAX 13 int calc_sign(char a1, char a2, int b) {         if(a1=='O')          a1 = 10;        else if(a1=='J' )          a1 =11;        else if(a1=='Q')          a1 =12;        else if(a1=='K' )          a1 =13;       else a1 = (int)a1;         if(a2=='O')          a2 = 10;        else if(a2=='J' )          a2 =11;        else if(a2=='Q')          a2 =12;        else if(a2=='K' )         a2 =13;       else a2 = (int)a2;      switch (b) {     /*开关控制语句       根据变量b的不同值。       执行相对应的case语句~     */         default:         case 0: return (a1+a2);          case 1: return (a1-a2);          case 2: return (a1*a2);          case 3: if (a2!=0&&(a1/a2)!=0)/* return*/ (a1/a2);         else return 0;      }  }/*运算模块*/ void calc_24point() {   int c = 0;     int a = 0;     char b[4][13]={                     {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},  /*扑克牌，10用O来表示*/                     {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},                     {'1','2','3','4','5','6','7','8','9','O','J','Q','K'},                     {'1','2','3','4','5','6','7','8','9','O','J','Q','K'}};     char num[4];     char sign[5]="+-*/";     int i=0;     int j=0;     int k=0;     int l=0;     int n=0;     int m=0;     int r=0;     int tem1=0;     int tem2=0;     int tem3=0;     srand( (unsigned)time(0));/*随机数发生器的初始化函数*/     a = rand()%MAX;/*产生的随机数num[0]作为增量，范围1-10*/     c =rand()%4;     num[0] =b[c][a];      a = rand()%MAX;     c = rand()%4;     num[1] =b[c][a];      a = rand()%MAX;     c = rand()%4;     num[2] = b[c][a];      c = rand()%4;     a = rand()%MAX;     num[3] = b[c][a];      printf("%c,%c,%c,%c\n",num[0],num[1],num[2],num[3]);          for(i = 0;i<4 ;i++)         {             if (j==i)continue;                  for(k=0;k<4;k++)                  {                     if(k==i||k==j)continue;/*返回循环起始处*/                     for(l = 0; l<4; l++)                     {                         if(l==k||l==j||l==k)continue;                         for(n = 0;n<4; n++)                         {                             for(m = 0;m<4; m++)                            {                                 for(r = 0;r<4; r++)                                 {                                      tem1=calc_sign(num[i],num[j],n);                                     tem2=calc_sign(tem1,num[k],m);                                     tem3=calc_sign(tem2,num[l],r);                                     if(tem3==24)                                     {                                         printf("(%c%c%c)%c%c}%c%c=24\n",num[i],sign[n],num[j],sign[m],num[k],sign[r],num[l]);                                     }                                     else if(tem3==-24)                                     {                                         printf("%c%c(%c%c%c)}%c%c=24\n",num[k],sign[m],num[i],sign[n],num[j],sign[r],num[l]);                                     }                                     else                                     {                                         tem1=calc_sign(num[i],num[j],n);                                         tem2=calc_sign(num[k],num[l],r);                                         tem3=calc_sign(tem1,tem2,m);                                         if(tem3==24.0)                                         {                                             printf("(%c%c%c)%c(%c%c%c)=24\n",num[i],sign[n],num[j],sign[m],num[k],sign[r],num[l]);                                         }                                     }                                 }                            }                         }                      }                    }          }   }   int main() {     while(1)     {         calc_24point();         if(getchar() != 'e') continue;         else break;     } }


Question: 编译比链接慢，是不是因为编译的时候解析字符串的原因，才使得编译的过程比较慢呢？

因为编译阶段，需要包含头文件，特别是当头文件特别大，特别多时，编译速度就更是受不了了。

编译比链接慢 -> 可有明确的数据？

没学过编译原理，果然是不懂编译器啊。

额，这样子啊。呵呵

总的来说编译比连接处理复杂，尤其是语法复杂的语言，又尤其是歧义语法，不能归约为LR(k)文法的语言（k为定值），比如C++。

或者对比 gcc或g++ 与 ld 对应的源代码。

可参考Tiny C

编译比链接复杂，所需步骤比链接多而已。


Question: 请问,  char 如何用数字来赋值呢？

直接给数字

没错。char esc = 92;// 92 == '\'  引用 7 楼 starytx 的回复:直接 char cavl = 97;

直接 char cavl = 97;

char是Java中的保留字，与别的语言不同的是，char在Java中是16位的，因为Java用的是Unicode。不过8位的ASCII码包含在Unicode中，是从0~127的。 Java中使用Unicode的原因是，Java的Applet允许全世界范围内运行，那它就需要一种可以表述人类所有语言的字符编码。Unicode。但是English，Spanish，German, French根本不需要这么表示，所以它们其实采用ASCII码会更高效。这中间就存在一个权衡问题。 因为char是16位的，采取的Unicode的编码方式，所以char就有以下的初始化方式： char c='c'; //字符，可以是汉字，因为是Unicode编码 char c=十进制数，八进制数，十六进制数等等; //可以用整数赋值 char c='\u数字'; //用字符的编码值来初始化，如：char='\0',表示结束符，它的ascll码是0，这句话的意思和 char c=0 是一个意思。

楼主来错地方了

byte c=-100;

顶起来啊 顶起来啊

byte c=-100;

是不是应该发到java版块呢亲


Question: 求助，排序

可以去搜一下白话快速排序，点进去那个人的博客有一个白话算法的标签，里面讲了一些排序，讲的浅显易懂。http://blog.csdn.net/column/details/algorithm-easyword.html

碰到问题还是得尽量自己去解决。自己写的程序要一步一步的F10（但不调试），相信你会有很大进步的。

输入多个数字  保存在数组里 这个用到了动态分配内存，可以参考这个——http://blog.csdn.net/u012421456/article/details/23374213 排序，简单的话，冒泡就行了，可以参考这个——http://blog.csdn.net/u012421456/article/details/26170519  自己不会的话，还是建议先看书或搜索，实在不行可以来论坛

看书看书还是看书，别的没的说，给你代码对你没帮助，自己写的有问题，贴过来还行。。。。

大一刚学C，还是在自学C？

你这是什么情况？

把问题分成两部分岂不是容易很多。 第一、把数据读到数组里 第二、对数组排序 相信这两个在书本上都能找到

各种排序算法动画演示http://www.webhek.com/misc/comparison-sort/  ＜1000个元素，冒泡排序 ＜100000个元素，qsort函数 ＜10000000个元素，放数据库中，建索引，（B+树排序） ≥10000000个元素，没用到过。

有效率要求吗？最简单的冒泡排序总会吧， 各种排序google一下一大把，不要说你懒得 搜。


Question: gcc 4.9.0 安装后，无法编译 C11程序,能编译 C++2011,缺  threads.h

c语言由于没有命名空间，标准库里的线程库虽然来源于pthread，但是名称不一样。  我建议是你先按pthread来命名，然后等c11标准支持之后，再#define过来。

theads.h只是 建议标准 LLVM都不支持的。

语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。

最新的 glibc 2.19 和 glibc 2.17(也就是红帽子昨天发布的版本携带的) 也没有发现这个  threads.h   真是啧啧怪事啊！！！

引用 24 楼 hzhxxx 的回复:创建文件test_gcc4.9.c,内容如下: #include <string.h> #include <stdio.h> //注意这行,路径不一致 #include <thr/threads.h>  //注意这个,函数定义必须是 //typedef int(*_Thrd_start_t)(void *); int fun(void *data) {         printf("thread=%d\n", thrd_current());         return 0; }  int main(int argc,char *argv[]) {         thrd_t loc;     thrd_create(&loc, fun,0);     thrd_join(loc,0);         return 0; }  编译执行,注意看参数 -std=c11,-lgcc_s,证明是使用新标准 查看链接的动态库,是新的库 呜呼,无法编译成功，无法执行正常!!! #/usr/local/gcc-4.9.0/bin/gcc -Wwrite-strings -std=c11 test_gcc4.9.c -o test_gcc4.9 -I/usr/local/gcc-4.9.0/include -L/usr/local/gcc-4.9.0/lib64 -lgcc_s -lpthread; #test_gcc4.9.c:4:21: 致命错误：threads.h：没有那个文件或目录  #include <threads.h>                      ^ 编译中断。  后记： 安装免费的 visual studio express 2013 后,正确编译后运行正常; 看来，学习 c++ 2011 或者 C11 的选择还是 vs2013靠谱。  C11不如C++11有意思。

我也认为这个是不是会造成 分裂，嘿嘿

引用 13 楼 mymtom 的回复:是thread吧，不是thread.h啊  #include <iostream> #include <thread> #include <chrono> #include <mutex>   std::mutex g_display_mutex;   void foo() {     std::thread::id this_id = std::this_thread::get_id();       g_display_mutex.lock();     std::cout << "thread " << this_id << " sleeping...\n";     g_display_mutex.unlock();       std::this_thread::sleep_for(std::chrono::seconds(1)); }   int main() {     std::thread t1(foo);     std::thread t2(foo);       t1.join();     t2.join(); }   ++ ， 楼主 ， C++中标准库都是没有.h后缀的。

vs2013 express 安装完成后，终于把例子运行起来了！！！很多差异，大家看看 C11。  #include <map> //注意这行,路径不一致 #include <thr/threads.h> #include <string> #include <stdio.h> #include <iostream> using namespace std;  //注意这个,函数定义必须是 //typedef int(*_Thrd_start_t)(void *); int f(void * data) { 	printf("thread=%d\n", thrd_current()); 	std::map<std::string, std::string> m; 	m.insert(std::make_pair("a1", "b2")); 	m.insert(std::make_pair("a2", "b1")); 	for (auto iter = m.begin(); iter != m.end(); ++iter) 	{ 		std::cout << "key=" << iter->first << ",value=" << iter->second << endl; 	} 	return 0; }  int _tmain(int argc, _TCHAR* argv[]) { 	thrd_t t; 	//typedef int (*_Thrd_start_t)(void *); 	thrd_create(&t, f, 0); 	thrd_join(t,0); 	system("pause"); 	return 0; }

引用 21 楼 daiweifeng 的回复:我的Visual Studio Express 2013里倒是有支持threads.h库，看来是gcc自己的问题  错误	1	error C1083: 无法打开包括文件: “threads.h”: No such file or directory	d:\cpp11\consoleapplication1\consoleapplication1\consoleapplication1.cpp	8	1	ConsoleApplication1   我安装的 vs2013 express 没有这个文件啊，悲剧鸟？？

引用 19 楼 hzhxxx 的回复:按C11标准,线程库确实是   threads.h  那就是现在没有编译器完整支持这东西。我的4.8.1也没有这东西。

按C11标准,线程库确实是   threads.h

引用 17 楼 hzhxxx 的回复:[quote=引用 16 楼 daiweifeng 的回复:] 楼主先确定到底是C语言还是C++语言。 编译时使用g++作编译程序，参数使用-std=c++11。C++和C的默认头文件是不一样的。  标题上说明很清楚吧。  编译也是用的 gcc,链接也是 libgcc,不是 libstdc++.so啊 #/usr/local/gcc-4.9.0/bin/gcc -Wwrite-strings -std=c11 test_gcc4.9.c -o test_gcc4.9 -I/usr/local/gcc-4.9.0/include -L/usr/local/gcc-4.9.0/lib64 -lgcc_s -lpthread; [/quote]  C语言里没有threads.h这个头文件，C++里有thread这个头文件。 你想用C++11标准的线程库的话当然要用C++标准编译器咯。  或者你换成pthread.h试试看。

引用 16 楼 daiweifeng 的回复:楼主先确定到底是C语言还是C++语言。 编译时使用g++作编译程序，参数使用-std=c++11。C++和C的默认头文件是不一样的。  标题上说明很清楚吧。  编译也是用的 gcc,链接也是 libgcc,不是 libstdc++.so啊 #/usr/local/gcc-4.9.0/bin/gcc -Wwrite-strings -std=c11 test_gcc4.9.c -o test_gcc4.9 -I/usr/local/gcc-4.9.0/include -L/usr/local/gcc-4.9.0/lib64 -lgcc_s -lpthread;

传说，貌似，可能，GCC对C11标准支持不完整吧？

-std=c++11 #include<thread>  必须是C++11不是C11，一般现在只有C99，C11和以后的可能更多的用于异构计算

我记得用的是pthread.h这个头文件。。。


Question: 指针问题，真心给跪了

char *s="hello,china,hello,bejing!";  这样s是指向字符串常量，不能通过 *p=*q;修改里面的值，*p 是不能作为左值。  你可以定义 char s[]="hello,china,hello,bejing!"; 或者 	char *s = NULL; 	s = malloc(30); 	memcpy(s,"hello,china,hello,bejing!",strlen("hello,china,hello,bejing!")); 这样是变量，可以赋值修改了

明白，谢谢楼上了

char *s="hello,china,hello,bejing!"; "hello,china,hello,bejing!"这个字符串存储在常量存储区， 你不能改变其中的内容的，比如删除几个字符，用堆栈 都可以。

引用 2 楼 u013523101 的回复:[quote=引用 1 楼 xihu1364 的回复:] char *s="hello,china,hello,bejing!"; strdele(s,5,6);  。。。修改const char *  试试  char s[100] = "hello,china,hello,bejing!"; strdele(s,5,6); 是这样没错。char *s="hello,china,hello,bejing!";为什么不能那样写呢？是应为没有开辟出内存吗？[/quote]  不是说了是const char*    char *s="hello,china,hello,bejing!";  s指向全局内存区  是const char*  char s[100] = "hello,china,hello,bejing!"; s指向栈上 或者char* s= new char[100]; memcpy(s,"hello,china,hello,bejing!",strlen(...));s指向堆上

引用 1 楼 xihu1364 的回复:char *s="hello,china,hello,bejing!"; strdele(s,5,6);  。。。修改const char *  试试  char s[100] = "hello,china,hello,bejing!"; strdele(s,5,6); 是这样没错。char *s="hello,china,hello,bejing!";为什么不能那样写呢？是应为没有开辟出内存吗？


Question: gsoap 实现onvif 发现不了设备

楼主，你问题解决了吗？？我也遇到类似的问题了？？？

header.wsa__Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Prob" ; 最后面是Probe，不是Prob


Question: 懂C语言和JAVA的朋友帮帮看看，给个提示。用C语言生成SO后，为什么同样的程序，普通JAVA main可以执行正确，但是java servlet就不行呢？

有人帮忙吗，这个问题真是太奇怪了。

谢谢楼上，但这个帮不了我现在的程勋。

有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #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); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #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} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

引用 1 楼 user-2 的回复:以下是个人推测： 自己写main调用时，是可控的。 写servlet，是要靠tomcat调用运行的，可能tomcat创建了多个对象或者多个线程。导致无法close。  可以负责任的说，只开启了一个线程。


Question: "你可以分配多大的内存"问题答案求证

话说lz你确定没忘记free? 1+2+2^2+...+2^n=2^(n+1)-1

答案是要少一些。。。那我请求的内存还有一部分我不能用？？？ 内存按分页来分配，总是要多一些才对。

有在这里空谈的工夫，为什么不去研读Linux的malloc源代码呢？

上面写错了,应该是这样   1 #include <stdio.h>   2 #include <stdlib.h>   3 main()   4 {   5     double MB=0;   6     while(malloc(1<<18))   7         ++MB;   8     printf("Allocated %lf MB total\n",MB/4);   9 } 我的答案是比原来小了,这样的结果正确吗?

我的意思是我把程序改成这样之后,输出比原来大还是小?   1 #include <stdio.h>   2 #include <stdlib.h>   3 main()   4 {   5     double MB=0;   6     while(malloc(1<<20))   7         ++MB;   8     printf("Allocated %lf MB total\n",MB);   9 }

实际分配的内存总是比你需要的多一嗲

引用 5 楼 zhao4zhong1 的回复:有在这里空谈的工夫，为什么不去研读Linux的malloc源代码呢？ 有个蛋用。区区一个hosted impl就敢代婊C了？ 就是知道hosted impl也没什么意义。dt的实现有权自己多swap点东西过来，不预设具体环境根本就说不清什么是malloc能拿到的“内存”。

看看内存分页的原理。


Question: c语言，子线程控制进程退出问题求教

引用 1 楼 user-1 的回复:可以直接退出。嗯嗯 多谢 那这样退出的话会不会有什么隐患呢

可以直接退出。


Question: 请教#define SFR @0x0001

请给出具体的代码，而不是你的描述。  最好给出“一般”的代码，同时也给出“不一般”的代码。

引用 1 楼 user-1 的回复:有无调用SFR的代码，这样可以分析出是否是扩展。  有调用SFR的代码,一般就是给SFR赋值操作!!!

有无调用SFR的代码，这样可以分析出是否是扩展。


Question: 结构体数组 使用fwrite 重新覆盖写入  编译通过，程序就执行到这一步，就错误了

fp = fopen(.....);

这是什么意思？

我之前 试了试  他就执行到写入文件的时候  错误  字节格式 应该没问题 我是重新生成文件  并且 我用追加 写入 就可以  老师能否 帮忙修改一下  谢谢

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

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。  请检查每个函数的返回值。  请设置字节对齐。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

折磨好几天了 一直解决不了  求大神 帮忙给看看


Question: 为什么scanf函数无法将‘；’读取为单个字符？

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

非ASCII字符都是双字节表示

a没有初始化。  中文的分号，ASCII表示不了。

什么情况下输入的字符呢？

char表示的范围里，没有中文的"；"这个字符。


Question: C语言选择法排序，有时排序正确，有时错误，求大神指教

把这一段 if(k!=i)             {                 temp=a[i];                 a[i]=a[k];                 a[k]=temp;             } 放入 for(j=i+1;j<10;j++)         {             if(a[j]<a[i])                 k=j;         }  这个循环就可以了

多谢了,继续学习

for(j=i+1;j<10;j++) 		{ 			if(a[j]<a[k])//这儿错了把i改成k就行了，自己想想逻辑上的问题 				k=j; 		}


Question: 黑箱子，穿越千年的超时

由题意可知, 需要用一种有序的数据结构对所有的数进行存储. 那么, Add 操作是一个向有序表插入的操作, 而Get操作则是一个有序表的查询操作. 要想在两种操作之间取得平衡的时间复杂度, 那么可以选择采用平衡二叉树作为存储结构, 推荐使用红黑树, 这样的话, Add操作能在O(logN)内完成, 如果为树中的每个结点维护一个表示"子结点总数"的数据成员, 那么Get操作也能在O(logN)内完成. 综上所述, 对于输入数据中的N组操作, 总复杂度为O( N*logN ), 对于10^5的数据规模, 能在1秒内出结果. 欢迎吐槽.

[quote=引用 7 楼 xuzhouweihao 的回复:] B树可以吗？你可以试试吧，下面的代码可以参考下。  [code=c]#include <stdio.h> #include <stdlib.h> #include <unistd.h>  /* Balance flag */ #define RH 1 #define LH -1 #define BH 0 有建设性意见

我的树啊！

B树可以吗？你可以试试吧，下面的代码可以参考下。  #include <stdio.h> #include <stdlib.h> #include <unistd.h>  /* Balance flag */ #define RH 1 #define LH -1 #define BH 0  static int lev_m=0;  typedef struct avlNode{ 	int data; 	int balance; 	int level; 	struct avlNode *right; 	struct avlNode *left; }*PavlNode;  void lltree(PavlNode *node) { 	PavlNode lnode;  	lnode = (*node)->left; 	(*node)->left = lnode->right; 	lnode->right = *node; 	*node=lnode; }  void lrtree(PavlNode *node) { 	PavlNode rnode,lnode;  	lnode = (*node)->left; 	rnode = lnode->right;	 	(*node)->left = rnode; 	lnode->right =  rnode->left; 	rnode -> left = lnode;  	lltree(node); }  void left_balance_tree(PavlNode *node) { 	PavlNode rnode,lnode; 	lnode = (*node)->left;  	switch(lnode->balance){ 		case LH: 			(*node)->balance = lnode->balance = BH; 			lltree(node); 			break; 		case RH: 			rnode = lnode->right; 			switch(rnode->balance){ 				case BH: 					(*node)->balance = BH; 					lnode->balance = BH; 					break; 				case LH: 					(*node)->balance = RH; 					lnode->balance = BH; 					break; 				case RH: 					(*node)->balance = BH; 					lnode->balance = LH; 					break; 			} 			rnode->balance = BH; 			lrtree(node); 			break; 		defult: 			// do nothing 			break; 	} }  void rrtree(PavlNode *node) { 	PavlNode rnode;  	rnode = (*node)->right; 	(*node)->right = rnode->left; 	rnode->left = *node; 	*node=rnode; }  void rltree(PavlNode *node) { 	PavlNode rnode,lnode;  	rnode = (*node)->right; 	lnode = rnode->left;	 	(*node)->right = rnode->left; 	rnode->left = lnode->right; 	lnode -> right = rnode;  	rrtree(node); }  void right_balance_tree(PavlNode *node) { 	PavlNode rnode,lnode; 	rnode = (*node)->right;  	switch(rnode->balance){ 		case LH: 			lnode = rnode->left; 			switch(lnode->balance){ 				case BH: 					(*node)->balance = BH; 					rnode->balance = BH; 					break; 				case LH: 					(*node)->balance = LH; 					rnode->balance = BH; 					break; 				case RH: 					(*node)->balance = BH; 					rnode->balance = RH; 					break; 				defult: 					break; 			} 			lnode->balance = BH; 			rltree(node); 			break; 		case RH: 			(*node)->balance = rnode->balance = BH; 			rrtree(node); 			break; 		default: 			break; 	} }  int create_tree(PavlNode *node, int data,  int* taller){  	if((*node) == NULL){ 		(*node) = malloc(sizeof(struct avlNode)); 		(*node)->data = data; 		(*node)->balance = BH; 		(*node)->level = 0; 		(*node)->right = NULL; 		(*node)->left = NULL; 		return 1; 	}   	if( data <= (*node)->data ){ 		if(!create_tree(&((*node)->left),data,taller)){ 			return 0; 		} 		if(*taller){ 			switch((*node)->balance){ 				case BH: 					(*node)->balance = LH; 					*taller = 1; 					break; 				case LH: 					left_balance_tree(node); 					*taller = 0; 					break; 				case RH: 					(*node)->balance = BH; 					 *taller = 0; 					break; 				default: 					// do nothing 					break; 			} 		} 	}else{ 		if(!create_tree(&((*node)->right),data,taller)){ 			return 0; 		} 		if(*taller){ 			switch((*node)->balance){ 				case BH: 					(*node)->balance = RH; 					*taller = 1; 					break; 				case LH: 					(*node)->balance = BH; 					*taller = 0; 					break; 				case RH: 					right_balance_tree(node); 					*taller = 0; 					break; 				default: 					// do nothing 					break; 			} 		} 	}  	return 1; } void delete_tree(PavlNode* node){ 	if((*node) == NULL){ 		return; 	}  	if((*node)->right != NULL ){ 		delete_tree(&((*node)->right)); 	}  	if((*node)->left !=NULL ){ 		delete_tree(&((*node)->left)); 	}  	if(((*node)->right == NULL) && ((*node)->right == NULL)){ 		free((*node)); 		(*node) == NULL; 	}  	return; }  int main(void) { 	int tmp; 	int i,j; 	int taller; 	int lev_tmp=0;  	PavlNode root=NULL;  	srand((unsigned)time(NULL));  	for(i=0; i<50; i++){ 		taller=1; 		tmp = rand()%100; 		create_tree(&root,tmp,&taller); 	}  	delete_tree(&root); 	return 0; }

不知道B树，行不？

那就试试Splay Tree

引用 2 楼 u012061345 的回复:试试SBT。 难道就没有其它更简单的算法了。

试试SBT。

大师兄们指点下，谢谢


Question: 求教我这个删除信息的代码哪里错了

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

好吧！我就是想问问我这个代码为什么不能删除车龄大于8的汽车信息！

人家那是在教你提问的态度。  你这只是读取文件的代码，文件是怎样写的？是否和读操作逻辑上对应？

你这是什么意思！不就是我的代码吗？

void cancel() {     int i,j = 0,k = 0,count=0;     int t = car[0].sum;     if((fp = fopen("car.dat","rb"))==NULL)     {         printf("不能打开文件\n");         system("pause");         return;     }     for(i = 0;i<=car[0].sum;i++)     {         fread(&car[i],sizeof(struct car_type),1,fp);         if(car[i].age>=8)         {              count = 0;              for(j=i;j<=t;j++)              {                  car[j].NUM = car[j+1].NUM;                  car[j].num=car[j+1].num;                  car[j].name=car[j+1].name;                  car[j].age=car[j+1].age;                  car[j].price=car[j+1].price;                  k++;                  k=i;                  t--;                  count++;              }              if(count!=0)              {                  car[0].sum = car[0].sum -1;              }         }   // i = k;       //  printf("%d",car[i].age);     }      save();     if(k==0)     {          printf("没有该汽车的信息！\n");          system("pause");     }     else     {             output();     }  }

for(j=i;j<t-1;j++)              {                  car[j].NUM = car[j+1].NUM;                  car[j].num=car[j+1].num;                  car[j].name=car[j+1].name;                  car[j].age=car[j+1].age;                  car[j].price=car[j+1].price;                  k++;                  k=i;                               count++;              }


Question: 用c程序写的socket下载网页，有个url的网页死活下不下来

调试下啊，使用抓包工具

看看内容是不是用gzip压缩了.

同意老赵。。

建议楼主先学会使用抓包软件比如wireshark


Question: 字符串 转 unsigned int 的问题

将你放在工程中的代码片断帖上来。

引用 11 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。 #include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.  是不是sscanf 函数对编译环境还有要求呢？我在VC++中调试好，没有问题，可一放到工程中调用就不行了，嵌入式系统不能用么？

学习了！每天这么累居然还有心情给别人改错误，是不是有的大神在代码里找错误的感觉就像当初马克思写资本论时写累了做微积分题目的感觉。每天有你们这些大神在，学习的路上永远不会孤独！

明白原理是关键，如果不明白原理，会很费解的。

引用 13 楼 zhao4zhong1 的回复:将你放在工程中的代码片断帖上来。  请忽略pbm_ucs2_to_ucs2_81 中后半部分，测试加的比较乱 test_LOG("pbm_ucs2_to_ucs2_81 instrlen 1 %d",instrlen); for(i=0;i<instrlen;i++) { test_LOG(" outstr_tmp[%d] %02x",i,*(outstr_tmp+i)); } instrlen=wcslen(outstr_tmp2); test_LOG("pbm_ucs2_to_ucs2_81 2 %d",instrlen); ....... }

boolean pbm_ucs2_to_ucs2_81(uint8 *instr,uint8 *out_octets,uint16 outlen) { 	uint16 i=0; 	uint16 instrlen=0; 	uint16 outstr_tmp[(PBM_TEXT_SIZE_BYTES/4)+1]={0};  	test_LOG("instr %s len is %d",instr,strlen(instr)); 	test_asc_to_uint16_hex(outstr_tmp,instr,strlen(instr)); 	instrlen=wcslen(outstr_tmp); 	test_LOG("pbm_ucs2_to_ucs2_81 instrlen 1 %d",instrlen); 	for(i=0;i<instrlen;i++) 			{ 			test_LOG(" outstr_tmp[%d] %02x",i,*(outstr_tmp+i)); 			} 	instrlen=wcslen(outstr_tmp2); 	test_LOG("pbm_ucs2_to_ucs2_81 2 %d",instrlen); 	....... }  uint32 wcslen(const uint16 *ucs2_str) {    uint32 retval = 0;                  /* Value to be returned. */    if (ucs2_str)       while (*ucs2_str++)       {          retval++;       } /* Increment retval until 0x0000 */    return retval;                      /* Return what we counted. */ } void test_asc_to_uint16_hex (uint16 *pcHex, char *pcASC, unsigned int iLength) {     int i;          test_LOG("test_pbm:test_asc_to_uint16_hex");        for (i=0;i<iLength/4;i++)    { 	   sscanf(pcASC+i*4,"%4X",pcHex+i); 	   test_LOG("test_pbm:pcHex+%d =%02x",i,*(pcHex+i));    } } 现在打印出的log信息  instr 04320430044B043204300432043F04320430044B04320430 len is 48" 	 test_pbm:test_asc_to_uint16_hex" 	 test_pbm:pcHex+0 =432" 	 test_pbm:pcHex+1 =00" 	 test_pbm:pcHex+2 =44b" 	 test_pbm:pcHex+3 =00" 	 test_pbm:pcHex+4 =430" 	 test_pbm:pcHex+5 =00" 	 test_pbm:pcHex+6 =43f"                     	 test_pbm:pcHex+7 =00"                     	 test_pbm:pcHex+8 =430"                     	 test_pbm:pcHex+9 =00"                     	 test_pbm:pcHex+10 =432"                    	 test_pbm:pcHex+11 =00"           每隔一个不正常

引用 2 楼 zhao4zhong1 的回复:char str[]="044B04320430044B“; usigned int  is[4];//{0x044B,0x0432,0x0430,0x044B}; int i; for (i=0;i<4;i++) sscanf(str+i*4,"%4X",&is[i));

引用 7 楼 ForestDB 的回复:[quote=引用 6 楼 yaya237 的回复:] [quote=引用 1 楼 user-7 的回复:] 先将字符串4个一组的截取出来，然后将每一组用atoi转换  atoi 转出来的是16进制的么？[/quote] 这个问题就有问题，int无所谓16进制 int a = 1; int b = 0x1; a和b就是一回事。[/quote]  弱弱的再问一下，但是0x1234 跟1234 不一样吧？

老赵的方法就很好。

引用 6 楼 yaya237 的回复:[quote=引用 1 楼 user-7 的回复:] 先将字符串4个一组的截取出来，然后将每一组用atoi转换  atoi 转出来的是16进制的么？[/quote] 这个问题就有问题，int无所谓16进制 int a = 1; int b = 0x1; a和b就是一回事。

引用 1 楼 user-7 的回复:先将字符串4个一组的截取出来，然后将每一组用atoi转换  atoi 转出来的是16进制的么？

引用 4 楼 ak47_wz 的回复:[quote=引用 1 楼 user-7 的回复:] 先将字符串4个一组的截取出来，然后将每一组用atoi转换 +1[/quote] 回复错了。。 我以为是赵老师那一层的。。。不需要这样子做啊，直接sscanf，然后格式就行了。

引用 1 楼 user-7 的回复:先将字符串4个一组的截取出来，然后将每一组用atoi转换 +1

for (i=0;i<4;i++) sscanf(str+i*4,"%4X",&is[i]);

先将字符串4个一组的截取出来，然后将每一组用atoi转换


Question: 请教一个指针的指针做形参的问题

my_func(a)， 调用这个函数， 你没有把a的地址发过去， 是这个问题吗， 你自己在试试嗯

理解指针的好方法就是学会debugger

仅供参考 //请用c++编译器运行 #include <stdio.h> void my_func(int (&a)[10][8]) { printf("flow : 0x%x\n0x%x\n0x%x\n",a,a[0],&a[0][0]); }  int main() { 	int a[10][8] = {0}; printf("0x%x\n0x%x\n",a,a[0]); my_func(a); return 0; //0x12fe08 //0x12fe08 //flow : 0x12fe08 //0x12fe08 //0x12fe08 //Press any key to continue }

计算机组成原理→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

引用 2 楼 surepretty 的回复:[quote=引用 1 楼 xihu1364 的回复:] [quote=引用 楼主 surepretty 的回复:] void my_func(A** line) { 	printf("flow : 0x%x,0x%x,0x%x\n",line,line[0],&line[0][0]); }  main（） { A a[10][8]; printf("0x%x,0x%x\n",a,a[0]); my_func(a)  }  输出是 0x7edf0b10,0x7edf0b10, 0x7edf0b10,0x6,0x6。 为什么,line,line[0],&line[0][0]不是一个地址呢？ 你将函数改成void my_func(A**& line)就一样了  不是引用，就会出现参数拷贝[/quote]  e，帮确认一下是要改成my_func(A*& line)还是my_func(A**& line)？  关于这个c参数copy，能否帮忙详细说明一下呢》  感谢[/quote]  百度吧 亲

引用 1 楼 xihu1364 的回复:[quote=引用 楼主 surepretty 的回复:] void my_func(A** line) { 	printf("flow : 0x%x,0x%x,0x%x\n",line,line[0],&line[0][0]); }  main（） { A a[10][8]; printf("0x%x,0x%x\n",a,a[0]); my_func(a)  }  输出是 0x7edf0b10,0x7edf0b10, 0x7edf0b10,0x6,0x6。 为什么,line,line[0],&line[0][0]不是一个地址呢？ 你将函数改成void my_func(A**& line)就一样了  不是引用，就会出现参数拷贝[/quote]  e，帮确认一下是要改成my_func(A*& line)还是my_func(A**& line)？  关于这个c参数copy，能否帮忙详细说明一下呢》  感谢

引用 楼主 surepretty 的回复:void my_func(A** line) { 	printf("flow : 0x%x,0x%x,0x%x\n",line,line[0],&line[0][0]); }  main（） { A a[10][8]; printf("0x%x,0x%x\n",a,a[0]); my_func(a)  }  输出是 0x7edf0b10,0x7edf0b10, 0x7edf0b10,0x6,0x6。 为什么,line,line[0],&line[0][0]不是一个地址呢？ 你将函数改成void my_func(A**& line)就一样了  不是引用，就会出现参数拷贝


Question: 物理win7安装了VM9.0.如何让虚拟机上网。求大神解救

将虚拟机的网络连接设置改为桥接试试  如下图，勾选Bridged  祝你好运！

我的物理win7，虚拟机VMware10.02，安装ubuntu 12.04和14.04都可以自动上网，不需要做任何配置。 所谓桥接或NAT，就是虚拟机里如何配置虚拟机中网络参数的方式，这两种方式对于ubuntu来说，缺省值都可以直接上网。

引用 12 楼 sniffer12345 的回复:求解，我的虚拟机里貌似没有苹果的网卡驱动和USB驱动。求解啊，貌似就是这个版本和电脑不融合，具体操作应该是怎样呢，我是新手，求详细！！！ 虚拟机装黑苹果？没那么简单[/quote] 就是物理win7装VNware9.0

引用 11 楼 sxcm_Gyt 的回复:求解，我的虚拟机里貌似没有苹果的网卡驱动和USB驱动。求解啊，貌似就是这个版本和电脑不融合，具体操作应该是怎样呢，我是新手，求详细！！！ 虚拟机装黑苹果？没那么简单

用nat方式不需要设置，你也可以用virtualbox更小巧。

这个东西百度一搜一大把的啊

Windows 7系统Internet连接共享了没？NAT方式虚拟机自动获取IP应该可以直接上网，桥接方式IP地址设置要和宿主机同一个子网段。

与其QQ请教，不如自己先行将VMWare的帮助文档好好读读，里面都有写。 不要说你的英文不好。

底如何上网。。。求图求详解，是9.0.求QQ详细请教

不是有上网配置

虚拟机什么操作系统？ 我装的XP自动就能上网

选桥接或者nat都能上网

2楼正解、。。。

最好是能QQ教我的大神。不要说NAT什么的  我能找到 但是不会设置 而且用NAT还会报错。


Question: 该选用哪种C语言软件？

vim 控

强烈推荐Qt Creator

c-free安装和使用都挺方便的，codeblocks从网上下要下gcc有时不好找，想简单就用c-free就行了下个软件编译器就都包括了

wintc可以，但不支持中文路径

VC4, 比VC6兼容性好，内建的帮助很强大，不用联网看乱七八糟的MSDN

codeblocks吧，下载自带gcc的版本，不用自己配置，直接用。你总得相信gcc吧？

QT     功能强大

vc++6.0比较好，调试方便

不知道你说什么问题，我猜，你要是编写c代码，windows下小的就用wintc（几兆而已），大的用vc++或者vs.linux下直接就可以写代码

VC Express Code Blocks

要想在Windows环境下稳定运行tc.exe 建一个批处理tc.bat,内容为下面两行，放在tc.exe同目录下，再将tc.bat发送到桌面快捷方式： del tc*.swp >NUL start command /c tc.exe 如果想在IDE里面使用鼠标，还应将快捷方式属性中的快速编辑模式关掉。

引用 7 楼 wen_eric 的回复:引用 5 楼 maomaodelaogong 的回复:现在的学生怎么这么不专业啊……选择什么C语言软件……那叫编译器……说的就是 他想说的是肯定是IDE，不单单是一个编译器。不然的话，Windows也就gcc/msvc两个主流编译器，没有什么可以纠结的了。

codeblocks

引用 2 楼 proof1 的回复:[quote=引用 1 楼 linux_hsylar 的回复:] 装个linux 虚拟机，强烈推荐vi 编辑，用gcc编译器，还有man当助手，啥不会就找man。 跑偏了。 就是Windows下 练习 C语言源码的《数据结构》，其它因素越少越好。[/quote]+++++

可以试试vc6

其实 说实在的初学者用tc就挺好的！ 很小巧！

codeblocks真心不错啊

现在的学生怎么这么不专业啊……选择什么C语言软件……那叫编译器……

个人喜欢codeblocks


Question: define的复杂用法

ceph的dout/eout系列宏必须跟dendl宏搭配使用，这样才能保证dout_impl展开后，do...while循环闭合以及及时flush。注意dendl的定义，定义了do...while的后半部分。   define里面根本没有嵌套define，dout_impl宏展开到“std::ostream* _dout = &_dout_os;”这句就完毕了，注意这句后面没有\符号连接下一行。 后续的define是完全独立的。

理解和讨论之前请先学会如何观察！

std::ostream* _dout = &_dout_os; ================ 看到这样的代码我就怕 即便写代码的是老手 这样的代码也得小小心翼翼啊。。

再怎么复杂，不过就是文本替换。 gcc -E查看替换后的结果即可。

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

引用 3 楼 itxyy 的回复: 我也只是个新手，没往这儿看过，没有，看别人吧，不好意思啊

引用 2 楼 u012421456 的回复:如果一般用不到，没必要深究，如果想知道，先看书和搜索 http://www.2cto.com/kf/201104/89377.html http://blog.csdn.net/djsl6071/article/details/1549539 http://www.baidu.com/s?ie=utf-8&bs=define的复杂用法&f=8&rsv_bp=1&wd=define的用法&rsv_sug3=3&rsv_sug4=114&rsv_sug1=1&rsv_sug2=0&inputT=600能不能给介绍本书，我需要把这段代码看懂

gcc -E


Question: 多线程问题

atomic counter  简单点做，弄个int，每个线程结束的时候++，发个信号，主线程wait后判断int值够了就继续往下走，要加锁哦，windows下API不太熟，顺着这个思路想下吧。。

#include <stdio.h> #include <windows.h> #include <process.h> #include<time.h> #include <direct.h> #pragma comment(lib, "ws2_32.lib") using namespace std; HANDLE g_hThreadParameter; unsigned _stdcall  asdf(LPVOID pParam) { int* pInt = (int*)pParam; char FileImageNameX[255]; sprintf(FileImageNameX,"D:\\%d.txt",*pInt );//这里使用线程的计数为文件名 FILE *fp; fp=fopen(FileImageNameX,"w"); CloseHand(fp); return 0; } void main() { 	 int i=0; HANDLE handle[100]; printf("开始"); for(i=0;i<100;i++) { handle[i]=(HANDLE)_beginthreadex(NULL, 0, asdf, &i, 0, NULL); //这里使用参数传进去 } printf("%d",i); //WaitForMultipleObjects(i,handle,TRUE,INFINITE);   //你这程序，这句主要起到不让主线程结束可以如下： while (TRUE) { Sleep(100); } }

仅供参考//循环向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; }

笨点的方法就是你可以把你要等待的拆开，比如waitfor（1-50），waitfor（51-100）。 聪明点如下： 1.首先定义一个变量 i = 0； 2.create一个Event问hEvent，而这个Event是永远不会被触发的，具体参考MSDN； 3.使你的句柄数组+1，比如你的是HANDLE handle[100]，现在改为HANDLE handle[101]，并使handle[101]=hEvent； 4.ok现在开始执行一个while(true)的无限循环，循环内执行int cur = WaitForMultipleObjects(),可以不设置INFINITE了。cur减去OBJECT_0为index就是handle数组的下标了，让handle[index]=hEvent，并且是i=i+1，当i=100的时候推出循环就好了。

引用 4 楼 bbs2241 的回复:WaitForMultipleObjects最多只能支持64个等待句柄，而你设置了100个，明显的不行，自己再去看MSDN找解决办法。目前等待线程的函数只有这个了，还有什么好的解决办法吗，多谢！

beginex是自动调用end的，tid是自分配资源，会回收的，估计是后面的id都一样了

没人？

求大神解答下什么问题！


Question: 关于malloc和free的问题

引用 11 楼 zhao4zhong1 的回复:使用前malloc分配一个估计足够大的内存， 使用中万一发现不够大，用realloc增大， 使用完free。  赵老师说的对啊，可以先分配一个大的数组，用完一次清空一下然后再用比较好。用内存池也可以，就是复杂了点儿，但是用一用就当学习学习了

有借有还就没事，这是基本节操。  当然频繁的分配／释放，会导致内存碎片。 简单点的结决方法就是一次性分配足够的大的内存，反复使用； 复杂点就是内存池。

就是分配一个大的内存， 比反复分配释放好多了

看样子大家说的建议是使用前分配一个大的内存

引用 11 楼 zhao4zhong1 的回复:使用前malloc分配一个估计足够大的内存， 使用中万一发现不够大，用realloc增大， 使用完free。 正解，也可以先设定个比较大的数组，不够时再malloc； malloc还有一个栈版本，alloca，不用free。 不停地malloc+free是下下策

代码贴出来，或许能找到问题的所在。

需要就申请，不需要就释放，没什么纠结的

在循环里动态分配内存不妥吧。。。既然每次都用到干嘛不在外面分配好。

不能这样，一旦free了以后对应的指针就成了悬浮指针，再想用malloc来分配是不可能的。就算在for循环里面malloc，要想free也要在for循环结束以后

malloc do something free  technically, u r right

不停地分配释放，很容易产生内存碎片的

做法没错，但是如果循环终止在某一步，应该就是控制循环的算法有问题了

错是没有错，不过很二  记录个大小，malloc一次或几次就可以，没必要每次都malloc和free，除了浪费cpu，什么用也没有

可是这个循环运行到第四步就停止运行了，本来要运行10步的。

malloc 和 free要成对出现 一一对应，不要多也不要少。  话说你也可以用list、vector之类的

虽然命题没有听太明白。这样应该没问题


Question: socket编程问题，收到回不去

我的UDP串口传数据好用，但是TCP不会用，求助

是不是丢包了，UDP网络状况不好时丢包很正常

楼主学会使用抓包软件比如wireshark正当时！

调试一下吧〉

可以使用gdb调试啊，太乱了，先把UDP那个strcmp去掉，估计是你过滤条件给过滤了

这是udp客户端的 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>  #define MYPORT  8887 #define BUFFER_SIZE 1024 #define MULCAST_IP  "224.0.0.1"	 int main() {     ///定义sockfd     int sock_cli = socket(AF_INET,SOCK_DGRAM, 0);     char sendbuf[BUFFER_SIZE];     char recvbuf[BUFFER_SIZE]; //reuseraddr：地址重用（设置后多个客户端可以同时运行） 	{                 int cnt = -1; 		int val = 1; 		cnt = setsockopt(sock_cli, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); 		if(0 > cnt) 		{ 			perror("set reuser addr err:"); 			exit(1); 		} 	}          ///定义sockaddr_in     struct sockaddr_in servaddr;     socklen_t length = sizeof(servaddr);      memset(&servaddr, 0, sizeof(servaddr));     servaddr.sin_family = AF_INET;     servaddr.sin_port = htons(MYPORT);  ///服务器端口     servaddr.sin_addr.s_addr = inet_addr(MULCAST_IP);  ///服务器ip       ///连接服务器，成功返回0，错误返回-1     if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)     {         perror("connect problem");         exit(1);     }           while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)     {         sendto(sock_cli, sendbuf, strlen(sendbuf),0,(struct sockaddr *)&servaddr, length); ///发送         if(strcmp(sendbuf,"exit\n")==0)             break;         recvfrom(sock_cli, recvbuf, sizeof(recvbuf),0,(struct sockaddr *)&servaddr, &length); ///接收         fputs(recvbuf, stdout);          memset(sendbuf, 0, sizeof(sendbuf));         memset(recvbuf, 0, sizeof(recvbuf));     }      close(sock_cli);     return 0; }

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/shm.h>  #define MYPORT  8887 #define LISTENQ   20 #define BUFFER_SIZE 1024 #define MULCAST_IP  "224.0.0.1" int main() {     char buffer[BUFFER_SIZE];     int server_tcp_sockfd,server_udp_sockfd;     int connfd;     fd_set fd;     int max1;     int n;     struct ip_mreq mreq;     struct sockaddr_in server_sockaddr;     struct sockaddr_in client_addr;     socklen_t length = sizeof(client_addr); //------tcp---------------      ///定义sockfd     server_tcp_sockfd = socket(AF_INET,SOCK_STREAM, 0);     if(server_tcp_sockfd<0)         {           perror("socket problem\n"); 	  exit(1);  	}          memset(&server_sockaddr, 0, sizeof(server_sockaddr));     server_sockaddr.sin_family = AF_INET;     server_sockaddr.sin_port = htons(MYPORT);     server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);      ///bind，成功返回0，出错返回-1     if(bind(server_tcp_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)     {         perror("bind problem\n");         exit(1);     }      ///listen，成功返回0，出错返回-1     if(listen(server_tcp_sockfd,LISTENQ) == -1)     {         perror("listen problem\n");         exit(1);     } //---------udp---------------     if ((server_udp_sockfd= socket( AF_INET, SOCK_DGRAM,0))<0) {     printf("udpsocket problem\n");      exit(1);     }      if (bind(server_udp_sockfd, (struct sockaddr *) &server_sockaddr, sizeof   (server_sockaddr))<0) {     printf("udpbind problem\n");     exit(0);     }     int cnt=-1;     int val = 1; //reuseraddr：地址重用（设置后多个服务器可以同时运行）     cnt = setsockopt(server_udp_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));     if(0 > cnt) 	{ 		perror("set reuser addr err:"); 		exit(1); 	}     //设置回环许可         int loop = 1; 	cnt = setsockopt(server_udp_sockfd,IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); 	if(0 > cnt) 	{ 		perror("multicast loop problem"); 		exit(1); 	} 	 	mreq.imr_multiaddr.s_addr = inet_addr(MULCAST_IP);	//广播地址 	mreq.imr_interface.s_addr = htonl(INADDR_ANY);		//网络接口为默认 	//将本机加入多播组 	cnt = setsockopt(server_udp_sockfd,IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); 	if(0 > cnt) 	{ 		perror("ip add membership problem"); 		exit(1); 	}       max1 = (server_tcp_sockfd >server_udp_sockfd ? server_tcp_sockfd+1 : server_udp_sockfd+1);      /* Inialize the fd_set */     FD_ZERO(&fd);     FD_SET(server_tcp_sockfd,&fd); /* add passive tcp socket */     FD_SET(server_udp_sockfd,&fd); /* add udp socket */ /*--------------select--------------*/ /* call select */      if (select(max1,&fd,NULL,NULL,NULL)<0) {     perror("select problem");     exit(1);     }    //------if tcp--------------------------              if (FD_ISSET(server_tcp_sockfd,&fd) ) {        	connfd = accept(server_tcp_sockfd, (struct sockaddr*)&client_addr, &length);     	if(connfd<0)     	{     	    perror("connect problem\n");     	    exit(1);     	} 	     	while(1)     	{     	    memset(buffer,0,sizeof(buffer));     	    int len = recv(connfd, buffer, sizeof(buffer),0); 	    if (n<0) { 		perror("Error receiving data"); 		}       	    if(strcmp(buffer,"exit\n")==0)     	        break;     	    fputs(buffer, stdout);     	    buffer[BUFFER_SIZE]='\0'; 	    send(connfd, buffer, sizeof(buffer), 0); 	     	}     	close(connfd);     	close(server_tcp_sockfd);     return 0;     }  //-------------if udp---------------     if (FD_ISSET(server_udp_sockfd,&fd))      { 	while(1) 	{ 		memset(buffer,0,sizeof(buffer));     		n=recvfrom(server_udp_sockfd,buffer,BUFFER_SIZE,0,(struct sockaddr*)&client_addr,&length); 		if(strcmp(buffer,"exit\n")==0)     	        break; 		fputs(buffer, stdout);     		if (n<0) { 			perror("Error receiving data"); 		} else { 			 			sendto(server_udp_sockfd,buffer,BUFFER_SIZE,0,(struct sockaddr*)&client_addr,length); 		}         }         close(server_tcp_sockfd); 	return 0;     }	 }


Question: c语言死循环问题

还有为什么用%d就不行呢？字符不就是范围小一点的整数吗？  理论上是这样。 但对scanf函数就不一样了，仔细看下说明。

谢谢，在scanf ("%c", &is_quit) ;前加rewind(stdin);就可以了，每一个printf后面加fflush(stdout);都不起作用（如果不加ewind(stdin);），想问一下，为什么？还有为什么用%d就不行呢？字符不就是范围小一点的整数吗？

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。


Question: C语言线程编程问题 其实是scanf的问题

没看出来你这个程序的目的是啥

楼主这个问题仅次于i++++j++类问题，大概也该属于月经帖。  Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

第一张图那个输入一次之后  就不能输入了 加入空格后就可以 再次输入了 为什么


Question: VC6.0中，我写的程序 无法重新生成二进制文件 把数据写入原文件

小心字节对齐问题。 建议扔掉旧的数据文件。 加#pragma pack(1)后重新生成新的数据文件。 字节对齐问题参考这个：#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 // //

我怎么不行。。。。你怎么做到的

哥们 我主要是revise 这个修改函数有问题  上面那个add  没有问题 你把传递给flag参数 改变了  那还能追加吗？

没问题，可追加，可覆盖。

兄弟....你好像没修改啊

#include<stdio.h> #include<stdlib.h> #include<string.h>  struct Employee {     char name[20]; 	char sex[5]; 	char deparment[20]; 	double pay;	 };  void Show(void);// 展示界面 void PassWord(void);//系统通过口令 void Menu(void);//系统主菜单 void ExitSystem(void);//退出系统 void SaveEmp(struct Employee[], int, int);//保存员工数据 void LoadEmp(struct Employee[], int *);//载入员工数据 void AddEmp(struct Employee[], int *);//添加员工信息 void Result(struct Employee[], int *);//浏览员工信息 void Revise(struct Employee[], int *);//修改员工信息   void LoadEmp(struct Employee emp[], int *emp_number) { 	FILE * fp; 	int i = 0; 	if((fp = fopen("emp.dat","rb"))==NULL) { 		printf("无法打开员工数据文件\n"); 		exit(0); 	} 	 	while(fread(&emp[i], sizeof(struct Employee), 1, fp) == 1){ 		i++; 	} 	 	*emp_number = i; 	fclose(fp); }   void SaveEmp(struct Employee emp[], int k, int flag) { 	FILE * fp; 	int i; 	 	if ((fp = flag ? fopen("emp.dat", "ab") : fopen("emp.dat", "wb")) == NULL) { 		printf("不能打开数据文件\n"); 		exit(0); 	} 	 	for(i=0; i<k; i++) { 		if(fwrite(&emp[i], sizeof(struct Employee), 1, fp) != 1) { 			printf("无法写入数据\n"); 			exit(0); 		} 	} 	fclose(fp);	 }   void AddEmp(struct Employee emp[], int *emp_number) { 	char ch = 'y'; //接收回车符 	system("cls"); 	system("title 添加员工"); 	printf("\n\t\t--------------------增加员工信息------------------\n"); 	printf("\n\n\t\t 请输入员工信息:\n"); 	 	LoadEmp(emp, emp_number); 	fflush(stdin); 	while ((ch=='y')||(ch=='Y')) { 		printf("\n\t\t员工的姓名："); 		scanf("%s", emp[*emp_number].name); 		printf("\n\t\t员工的性别："); 		scanf("%s", emp[*emp_number].sex); 		printf("\n\t\t员工的部门："); 		scanf("%s", emp[*emp_number].deparment); 		printf("\n\t\t员工的工资："); 		scanf("%lf", &emp[*emp_number].pay); 		fflush(stdin); 		printf("\n\t\t是否继续添加员工信息(y/n)?："); 		scanf("%c",&ch); 		fflush(stdin); 		(*emp_number)++; 	} 	SaveEmp(emp, *emp_number, 0);// 追加在数据文件末尾 	system("pause");	 }  void Result(struct Employee emp[], int *emp_number) { 	int i; 	system("cls"); 	system("title 员工信息"); 	printf("\n\t读取中...");  	LoadEmp(emp, emp_number); 	printf("\n\n\t\t员工信息：\n\n\n"); 	printf("姓名	     性别            部门          工资\n"); 	for (i = 0; i<*emp_number; i++) {		 		printf("%-20s  %-5s %-20s %-15.2f\n", emp[i].name, emp[i].sex, emp[i].deparment, emp[i].pay); 	} 	//putchar(10); 	//system("pause");	 }  void Revise(struct Employee emp[], int *emp_number) { 	int i; 	int find; 	char str[20]; 	char ch = 'y'; 	system("cls"); 	system("title 修改信息"); 	fflush(stdin); 	LoadEmp(emp, emp_number); 	printf("\n\t\t--------------------修改员工信息------------------\n"); 	while ((ch=='y')||(ch=='Y')) { 		printf("\n\n\t\t请输入员工的姓名："); 		scanf("%s", str); 		find = 0; 		 		for (i = 0; i<*emp_number; i++) { 			if (strcmp(str, emp[i].name) == 0) { 				printf("\n\n\t\t您要修改的员工信息为：\n"); 				printf("\t\t姓名        性别        部门      工资"); 				printf("\t\t%-10s  %-10s %-10s %-15.2f\n",emp[i].name,emp[i].sex,emp[i].deparment,emp[i].pay); 				find = 1; 				break; 			} 		} 		fflush(stdin); 		if(find == 1) { 			printf("\n\n\t\t请重新输入修改的员工信息为：\n"); 		 			printf("\n\t\t员工的姓名："); 			scanf("%s", emp[i].name); 			printf("\n\t\t员工的性别："); 			scanf("%s", emp[i].sex); 			printf("\n\t\t员工的部门："); 			scanf("%s", emp[i].deparment); 			printf("\n\t\t员工的工资："); 			scanf("%lf", &emp[i].pay); 		} else { 			printf("\n\t没找到该员工！\n"); 		} 		fflush(stdin); 		printf("\n\t\t是否继续修改员工信息(y/n)?："); 		scanf("%c", &ch); 		fflush(stdin); 	} 	 	SaveEmp(emp, *emp_number, 0);//重新生成数据文件 	system("pause");	 }

嗯 rb+可以进行 读写操作  要不您能帮我修改修改？ 我怎么都改不好  进死胡同了。。。 就写  覆盖写入文件 这段  就好  谢谢了

“rb+" 和 "rb" 不是一回事！

你不用fseek函数想实现期望的功能比较悬。

我试了 不管用啊

想覆盖写入用"rb+"  The character string mode specifies the type of access requested for the file, as follows:  "r"  Opens for reading. If the file does not exist or cannot be found, the fopen call fails.  "w"  Opens an empty file for writing. If the given file exists, its contents are destroyed.  "a"  Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn’t exist.  "r+"  Opens for both reading and writing. (The file must exist.)  "w+"  Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.  "a+"  Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.  When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek or rewind, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.  The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.  When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.  In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:  t  Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z, may cause fseek to behave improperly near the end of the file.   Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).  b  Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.   If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.

您好 我可以用“ab”的方式 打开文件 并且能够添加数据进去  但是我想覆盖写入就不行了 编译能够通过 就是存储不了   我把我的所有代码 都贴上吧 我不知道为什么   # include <stdio.h> # include <stdlib.h> # include <windows.h> # include <string.h> # include <conio.h> # include <ctype.h>   struct Employee {     char name[20]; 	char sex[5]; 	char deparment[20]; 	double pay; 	 };  void Readme(void);//打开readme.txt void Show(void);// 展示界面 void PassWord(void);//系统通过口令 void Menu(void);//系统主菜单 void ExitSystem(void);//退出系统 void SaveEmp(struct Employee[],int,int);//保存员工数据 void LoadEmp(struct Employee[],int *);//载入员工数据 void AddEmp(struct Employee[],int *);//添加员工信息 void Result(struct Employee[],int *);//浏览员工信息 void Revise(struct Employee[],int *);//修改员工信息 void Delete(struct Employee[],int *);//删除员工信息 //void NewSaveEmp(struct Employee[],int);   /*void NewSaveEmp(struct Employee emp[],int * emp_number) { 	FILE * fp; 	int i = 0; 	fopen("emp.dat", "wb"); 	for(i = 0;i < * emp_number; i++) 	{ 		fwrite(&emp[i], sizeof(struct Employee), 1, fp); 		 	} 	printf("1"); 	fclose(fp); }*/  void LoadEmp(struct Employee emp[],int * emp_number) { 	FILE * fp; 	int i = 0; 	if((fp = fopen("emp.dat","rb"))==NULL) 	{ 		printf("无法打开员工数据文件\n"); 		exit(0); 	}  	while (fread(&emp[i], sizeof(struct Employee), 1, fp) == 1 && i < 50) 	{ 		i++; 	}  	* emp_number = i; 	if (feof(fp)) 	{ 		fclose(fp); 	}  }   void SaveEmp(struct Employee emp[],int k,int flag) { 	FILE * fp; 	int i;  	if ((fp = flag ? fopen("emp.dat", "ab") : fopen("emp.dat", "wb")) == NULL) 	{ 		printf("不能打开数据文件\n"); 		exit(0); 	}  	for(i = 0;i < k; i++) 	{ 		if (fwrite(&emp[i], sizeof(struct Employee), 1, fp) != 1) 		{ 			printf("无法写入数据\n"); 			exit(0); 		} 	} 	fclose(fp);  }    void Readme(void)//打开readme 创建数据文件 { 	FILE * fp; 	 	if ((fp = fopen("emp.dat","w"))==NULL) 	{ 		system ("start ./Readme.txt"); 		fclose(fp); 		system("pause"); 	} } void Show(void) { 	system("title 员工管理系统"); 	system("color 0e"); 	printf("\n\n\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	printf("\t\t\t|                                   |\n"); 	printf("\t\t\t|           员工管理系统            |\n"); 	printf("\t\t\t|                                   |\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	Sleep(1000); 	printf("\t\t\t|-----------------------------------|\n"); 	printf("\t\t\t|                                   |\n"); 	printf("\t\t\t|         中国华冶科工集团          |\n"); 	printf("\t\t\t|                                   |\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	Sleep(1000);     printf("\t\t\t|-----------------------------------|\n"); 	printf("\t\t\t|           石家庄项目部            |\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	Sleep(1000);  	system("cls"); 	Sleep(1000); 	printf("\n\n\n\n\n\n\n\n"); 	system("color 0d"); 	printf("\t\t             小猪熊   制作             \n"); 	Sleep(2000);  } void PassWord(void) { 	system("title 登陆"); 	system("cls"); 	system("color 0a"); 	int i = 0; 	char c; 	char passwd[10] = "1602"; 	char scanfwd[20]=""; 	fflush(stdin); 	for (i = 3;i >=1;i--) 	{ 		int j = 0; 		printf("\n\n\n\n\t 密码长度最大是6位！\n"); 		printf("\n\n\n\n\t 请输入密码(你还有%d次机会):", i); 		while ((c = getch()) != '\r') 		{ 			if (j < 20 && isprint(c)) // ISprint 只接收可打印的字符 			{ 				scanfwd[j++] = c;  				putchar('*'); 			}  			if (0 < j && c == '\b') //删除密码操作 			{ 				j--; 				putchar('\b'); 				putchar(' '); 				putchar('\b'); 			}  		} 		scanfwd[j] = '\0'; 		if (strcmp (passwd,scanfwd) == 0) 		{ 			system("cls"); 			system("title 欢迎页面"); 			printf("\n\n\n"); 			printf("\t\t-----------------------------------------\n"); 			printf("\t\t*                                       *\n"); 			printf("\t\t*        欢迎使用员工信息管理系统       *\n"); 			printf("\t\t*                                       *\n"); 			printf("\t\t-----------------------------------------\n\n\t\t"); 			break; 		} 		else  		{ 			system("cls"); 			printf("\n\n\n\n\t 密码错误!请重新输入!\n"); 			continue; 		} 	} 	if (i == 0) 	{ 		system("cls"); 		system("color 0c"); 		printf("\n\n\t\t\t 对不起!你无权使用该系统!\n\n\t\t"); 		Sleep(2000); 		exit(0); 	}  }  void Menu(void) { 	printf("\n\n\n\n\t\t载入中...."); 	Sleep(2000); 	system("cls"); 	system("title 主菜单"); 	printf("\n\n\n\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	printf("\t\t\t|         员工信息管理系统          |\n"); 	printf("\t\t\t|-----------------------------------|\n"); 	printf("\t\t\t|         1---增加员工信息          |\n"); 	printf("\t\t\t|         2---浏览员工信息          |\n"); 	printf("\t\t\t|         3---修改员工信息          |\n"); 	printf("\t\t\t|         4---删除员工信息          |\n"); 	printf("\t\t\t|         5---【反馈留言】          |\n"); 	printf("\t\t\t|         0---【退出系统】          |\n"); 	printf("\t\t\t|-----------------------------------|\n");  }  void ExitSystem(void) { 	system("cls"); 	system("title 再见");     system("color 0c"); 	printf("\n\n\n\n\n"); 	printf("\t*****************************************************************\n"); 	printf("\t*****************************************************************\n"); 	printf("\t* *                                                           * *\n"); 	printf("\t* *                     感谢您的使用，再见!                   * *\n"); 	printf("\t* *                                                           * *\n"); 	printf("\t*****************************************************************\n"); 	printf("\t*****************************************************************\n"); 	Sleep(2000); 	exit(0); 	 }  void AddEmp(struct Employee emp[],int * emp_number) { 	system("cls"); 	system("title 添加员工"); 	printf("\n\t\t--------------------增加员工信息------------------\n"); 	printf("\n\n\t\t 请输入员工信息:\n"); 	int k = 0;//员工添加的次数 	char ch = 'y'; //接收回车符 	char c; 	LoadEmp(emp,emp_number); 	fflush(stdin); 	while ((ch=='y')||(ch=='Y')) 	{ 		printf("\n\t\t员工的姓名："); 		scanf("%s",&emp[k].name); 		printf("\n\t\t员工的性别："); 		scanf("%s",&emp[k].sex); 		printf("\n\t\t员工的部门："); 		scanf("%s",&emp[k].deparment); 		printf("\n\t\t员工的工资："); 		scanf("%lf",&emp[k].pay); 		fflush(stdin); 		printf("\n\t\t是否继续添加员工信息(y/n)?："); 		scanf("%c",&ch); 		c = getchar(); 		k++; 	} 	* emp_number += k; 	SaveEmp(emp,k,1);// 追加在数据文件末尾 	system("pause");  }  void Result(struct Employee emp[],int * emp_number) {  	system("cls"); 	system("title 员工信息"); 	printf("\n\n\n\n\t\t读取中..."); 	Sleep(2000); 	system("cls"); 	LoadEmp(emp,emp_number); 	printf("\n\n\t\t员工信息：\n\n\n"); 	printf("\t\t姓名        性别        部门      工资"); 	for (int i = 0; i < * emp_number; i++) 	{ 		 	     printf("\n\n\t\t%-10s  %-10s %-10s %-15.2f",emp[i].name,emp[i].sex,emp[i].deparment,emp[i].pay); 		 printf("\n\n"); 	} 	putchar(10); 	system("pause"); 	 }  void Revise(struct Employee emp[],int * emp_number) { 	int i; 	char str[20]; 	char c,ch = 'y'; 	system("cls"); 	system("title 修改信息"); 	fflush(stdin); 	LoadEmp(emp,emp_number); 	printf("\n\t\t--------------------修改员工信息------------------\n"); 	while ((ch=='y')||(ch=='Y')) 	{ 		printf("\n\n\t\t请输入员工的姓名："); 		scanf("%s",str); 	 		for (i = 0;i < * emp_number;i++) 		{ 			if (strcmp(str, emp[i].name) == 0) 			{ 				printf("\n\n\t\t您要修改的员工信息为：\n\n\n"); 				printf("\t\t姓名        性别        部门      工资"); 				 printf("\n\n\t\t%-10s  %-10s %-10s %-15.2f",emp[i].name,emp[i].sex,emp[i].deparment,emp[i].pay); 			} 		} 		fflush(stdin); 		printf("\n\n\t\t请重新输入修改的员工信息为：\n\n\n");  		printf("\n\t\t员工的姓名："); 		scanf("%s",&emp[i].name); 		printf("\n\t\t员工的性别："); 		scanf("%s",&emp[i].sex); 		printf("\n\t\t员工的部门："); 		scanf("%s",&emp[i].deparment); 		printf("\n\t\t员工的工资："); 		scanf("%lf",&emp[i].pay); 		fflush(stdin); 		printf("\n\t\t是否继续修改员工信息(y/n)?："); 		scanf("%c",&ch); 		c = getchar(); 	} 		 	SaveEmp(emp, * emp_number,0);//重新生成数据文件 	system("pause"); 	  } void Delete(struct Employee emp[],int * emp_number) {  }  	 int main(void) { 	struct Employee emp[50]; 	int choose,emp_number = 0; 	Readme(); 	Show(); 	PassWord(); 	Sleep(2000); 	while (1) 	{ 		system("cls"); 		Menu(); 		printf("\n\n\t\t\t请选择0~5功能菜单序号："); 		scanf("%d",&choose); 		switch (choose) 		{ 		       case 0:ExitSystem();break; 			   case 1:AddEmp(emp,&emp_number);break; 			   case 2:Result(emp,&emp_number);break; 			   case 3:Revise(emp,&emp_number);break; 			   case 4:Delete(emp,&emp_number);break; 			   case 5:system("start http://www.baidu.com/?tn=56060048_4_pg"); 		} 			  	 	}  	return 0; }

在cmd窗口中输入以下命令运行程序 cd /d "exe程序所在盘符和全路径" "exe程序名"  或者VS IDE中 VC6：  工程、设置、Debug、工作目录：填写emp.dat所在目录。 VS20XX：  项目、属性、配置属性、调试、工作目录：填写emp.dat所在目录。 再按F5运行。

#pragma pack(push,1) struct Employee {     char name[20];     char sex[5];     char deparment[20];     double pay;       }; #pragma pack(pop)  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

我截取了部分代码   无法重新生成文件  也没有办法存储   求大神 指点  谢谢


Question: 菜鸟求助！！！

抱歉，sum应该是x

窃以为： 以1969年12月31日（星期三）为基准， 闰年跟平年的sum应该分开算， 闰年取sum=366*（n-1）+365*（year-1970-n+1）； 平年取sum=366*n+365*(year-1970-n); 另外，switch语句部分应该改为： switch(week) {     case 0: printf("Wednesday\n");break;     case 1: printf("Thursday\n");break;     case 2: printf("Friday\n");break;     case 3: printf("Saturday\n");break;     case 4: printf("Sunday\n");break;     case 5: printf("Monday\n");break;     case 6: printf("Tuesday\n");break;  }

1、七楼说的一样，if后面的语句缺少了{}. 2、就是year的处理出现了问题，楼主的思路没看明白，然后改了下，你看下下面代码吧。 3、在month的护理，怎么对sum再次进行了定义？而且是在{}内，根据就近原则{}内的处理只是改了这里定义的sum的值，当走出{}后，取的sum值不是你{}赋的值。 4、1970-1-1是周四吧，这个好像在代码中没有处理。。。。  代码修改后如下所示：ps:后面定义的变量名看起来很费劲 #include<stdio.h> int main() { 	int year; 	int month; 	int day; 	int week; 	int j; 	int x; 	int y; 	int z; 	int n; 	int p; 	int sum;  	printf("please enter(year=month-day):"); 	scanf("%d-%d-%d", &year, &month, &day); 	if (year<1970||year>9999) 	{ 		printf("year is error.\n"); 		return 0; 	}   	if (month>12||month<0) 	{ 		printf("month is error.\n"); 		return 0; 	}  	if (day<0) 	{ 		printf("day is error.\n"); 		return 0; 	}   	if (month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12) 	{ 		if (day>31) 		{ 			printf("day is error.\n"); 			return 0; 		} 	} 	if (month == 4||month == 6||month == 9||month == 11) 	{ 		if (day>30) 		{ 			printf("day is error.\n"); 			return 0; 		} 	}  	if ((year%4 == 0&&year%100!= 0)||year%400 == 0) 	{ 		if (month == 2) 		{ 			if (day>29) 			{ 				printf("day is error.\n"); 				return 0; 			} 		} 	} 	else 	{ 		if (month == 2) 		{ 			if (day>28) 			{ 				printf("day is error.\n"); 				return 0; 			} 		} 	} 	int i = 1970;  	int  k = 0; //	int  k = 1; //	while (i<= year) 	while (i< year) 	{ 		if ((i%4 == 0&&i%100!= 0)||i%400 == 0) 		{ 			k++; 		} 		i++; 	} 	n = k; 	x = 366*n+365*(year-1970-n); //	x = 366*n+365*(year-1970-n-1);   	sum = 0; 	if ((year%4 == 0&&year%100!= 0)||year%400 == 0) 	{ //		int sum = 0; 		int a1[13] = {0,31,29,31,30,31,30,31,31,30,31,30,31}; 		for (i = 0; i<month; i++){ 			sum+= a1[i]; 		} 	} 	else 	{ //		int sum = 0; 		int a2[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 		for (i = 0; i<month; i++){ 			sum+= a2[i]; 		} 	} 	y = sum; 	z = day; 	p = x+y+z+3; //	p = x+j+day; 	week = p%7; 	switch(week) 	{ 		case 0: printf("Sunday\n"); break; 		case 1: printf("Monday\n"); break; 		case 2: printf("Tuesday\n"); break; 		case 3: printf("Wednesday\n"); break; 		case 4: printf("Thursday\n"); break; 		case 5: printf("Friday\n"); break; 		case 6: printf("Saturday\n"); break; 		defult: printf("PG error\n");break; 	} 	return 0; }

七楼好像还没有纠正算法的问题吧！？

主要是你的那个return 0； if(day>29) printf("day is error.\n"); return 0; 应该把它修改成 if(day>29) {printf("day is error.\n"); return 0;}  不然在没有else的情况下，就容易跳出去，然后我修改了一下你的程序。 #include<stdio.h> int main() { 	int year; 	int month; 	int day; 	int week; 	long int x; 	int y; 	int z; 	int n; 	long int p; 	int sum=0; 	int i=1970; 	int  k=0;  	scanf("%d-%d-%d",&year,&month,&day);  	if(year<1970||year>9999) 	{ 		printf("year is error.\n"); 		return 0; 	}  	else 	{  		while(year>i) 		{ 			if((i%4==0&&i%100!=0)||i%400==0) 			{ 				k++; 			} 			i++; 		} 	} 	n=year-1970; 	x=366*k+365*(n-k);  	if(month>12||month<0) 	{ 		printf("month is error.\n"); 		return 0; 	} 	else 	{ 		if((year%4==0&&year%100!=0)||year%400==0) 		{ 			int a1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; 			for(i=0;i<month;i++) 				sum+=a1[i]; 		} 		else 		{ 			int a2[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 			for(i=0;i<month;i++) 				sum+=a2[i]; 		} 		y=sum; 	}  	if(day<0) 	{ 		printf("day is error.\n"); 		return 0; 	}  	else  	{ 		if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) 		{ 			if(day>31) 			{ 				printf("day is error.\n"); 				return 0; 			} 		} 		else if (month==4||month==6||month==9||month==11) 		{ 			if(day>30) 			{ 				printf("day is error.\n"); 				return 0; 			} 		} 		if((year%4==0&&year%100!=0)||year%400==0) 		{ 			if(month==2) 			{ 				if(day>29)  				{ 					printf("day is error.\n"); 					return 0; 				} 			} 		} 		else 		{ 			if(month==2) 			{ 				if(day>28)  				{ 					printf("day is error.\n"); 					return 0; 				} 			} 		}  	} 	z=day; 	p=x+y+z-4; 	week=p%7; 	switch (week) 	{ 	case 0: printf("Sunday\n");   break; 	case 1: printf("Monday\n");   break; 	case 2: printf("Tuesday\n");  break; 	case 3: printf("Wednesday\n");break; 	case 4: printf("Thursday\n"); break; 	case 5: printf("Friday\n");   break; 	case 6: printf("Saturday\n"); break; 	} 	return 0; }

1 x=366*n+365*(year-1970-n-1); 2 p=x+j+day; 3 switch (week) {     case 0: printf("Sunday\n");   break; case 1: printf("Monday\n");   break; case 2: printf("Tuesday\n");  break; case 3: printf("Wednesday\n");break; case 4: printf("Thursday\n"); break; case 5: printf("Friday\n");   break; case 6: printf("Saturday\n"); break;      } 感觉有问题

你应该是从1969年12月31日（星期三）为基准算起的吧！？

引用 1 楼 ml0719787 的回复:scanf("%d-%d-%d",&year,&month,&day);这个不能这样用 scanf("%d%d%d",&year,&month,&day) 嗯。这个可以的。这个在这儿是非输入控制符，输入时需要原样输出，像3楼说的那样

引用 1 楼 ml0719787 的回复:scanf("%d-%d-%d",&year,&month,&day);这个不能这样用 scanf("%d%d%d",&year,&month,&day) scanf("%d-%d-%d",&year,&month,&day);//可以这样用，只不过要输入2014-6-3而已。 请楼主检查scanf函数的返回值！


Question: 关于两个unsigned char型字符数组异或加解密

unsigned char a[20]; unsigned char m[16]; int i; for (i=0;i<20;i++) a[i]^=m[i%16];

1和0x1是同一个东西。

int无所谓16进制。

引用 1 楼 user-3 的回复:如果楼主知道什么叫异或，那就该知道异或根本不分unsigned和signed 至于十六进制，那是给人看的，内存中不分十六进制二进制十进制八进制 就是按字节异或，那么我异或后的结果也得保存在unsigned char数组里？也是16进制的？

有人帮帮忙吗


Question: C语言 结构体指针申请内存空间

prev->next=current;                                   current->next=NULL;  其实这两句话在很多基于链表的实现中很常见的，具体的语义就是将前一个节点指向现在新加的节点，并且将现在的节点的next指针指向空指针。在逻辑上应该还是很好理解的。

引用 7 楼 Jeadystraw 的回复:楼主mcmay回答的狠规范！谢了!!其他都是吭爹的！有的人还说程序有错误！麻烦你运行下还行？？ prev->next=current这句话current指向哪儿啊？？怎么next还指向current啊？？不太懂啊  current指向通过malloc新产生的链表成员（链表中的新的末端），而prev-next是保存这个新产生链表成员（新末端）。

对于“prev->next=current这句话current指向哪儿啊？？”这个问题，其实mcmay已经解释清楚了，这个current是一个中间指针，是临时的，总是指向最新生成的指针， prev->next=current;  主要作用是将后来产生的新成员挂在当前链表成员的next指针上，置于链表尾端。

我这是运行过 发现 问题 才 会的贴.

奇怪了！难道书上是错误的啊？？按照你的逻辑也有道理啊

自己有错,还 犟. while(current!=NULL)   {          free(current);//  current  都已经free 了          current=current->next;// 哪来的 next ??             }

这是C Primer Plus当中的的例题吧？ current只是个临时指针，其值是随着接收malloc所产生的指针而不断变化的。它的作用是让通过malloc分配内存而新产生的链表成员，以prev-next = current的方式一个一个接续下去。 当链表为空，即head == NULL时，首先将第一个产生的链表成员的指针赋给head，这样整个链表就有了head（第一个元素了）。 否则，即链表不为空，则将新产生的链表成员通过prev-next = current的方式挂到前面已经产生的链表成员的next指针上（成为新的链表末端成员），以此类推，直到不再产生新的链表成员为止。    while(gets(input)!=NULL && input[0]!='\0') {          current=(struct filem *)malloc(sizeof(struct film));   /*产生新的链表成员*/                   if(head==NULL)            head=current;    //如果链表为空，则将第一个产生的链表成员的指针赋给head          else             prev->next=current;  //将后来产生的链表成员挂在链表成员的next指针上，使其成为新的链表末端成员          current->next=NULL;   //开放新的链表尾巴的next指针，以便接收可能会挂上来的下一个新的末端成员          strcpy(current->title,input);          puts("请输入电影等级");          scanf("%d",¤t->rating);          while(getchar()!='\n')            continue;                puts("请输入下一个电影标题");          prev=current;                  //记录当前新产生的链表末端成员的指针，这个指针即为                                                 //下一轮prev->next当中的prev的值 }

/* 任务完成 清空内存 */   	current=head; 	while(current != NULL) 	{ 		tmp=current->next; 		free(current); 		current=tmp; 	} 	printf("再见");

这程序很多错误啊

付空值。  擦。。。又打错了。

引用 1 楼 user-6 的回复:prev->next=current;          //这句话的意思：前一节点指向当前申请的加单                                 current->next=NULL;//当前申请的节点付控制，表示后面已到了链表的末尾  prev=current           //表示指针后移，prev始终指向末尾节点。  画个图你能更好的理解。  改正错别字：浮空值


Question: 字符串传参数的困惑

char *str="abcdef";  这是个字符串常量，而且强烈建议写为const char*类型，这样更好一些

char *str1 = "abcdef";//只读 C语言没有字符串这种数据类型，虽然可以用字符指针操作一个C风格字符串，但必须清楚这个指针指向的内存归谁管

引用 4 楼 huruzun 的回复:[quote=引用 1 楼 a515360208 的回复:] char *str1 = "abcdef"; char str2[] = "abcdef"; 你要弄清楚这两者的区别，str1指向了一个常量字符串，常量字符串是不允许更改的， str2是一个字符串数组，存放在栈上，可以更改 你要实现你开始交换的目的，字符串指针使用后者  再问下我调试进去交换代码，每次都显示access violation 越界错误！如果是常量不让写按道理是提示无法改写啊， 为什么编译器这么提示？我用的是VS2010，这个错误让我纠结了半天！[/quote] CSDN.exe 中的 0x001e109d 处有未经处理的异常: 0xC0000005: 写入位置 0x001e7830 时发生访问冲突这是我调试时的错误，至于你的错误，我也不明白， 你查一查吧

引用 1 楼 a515360208 的回复:char *str1 = "abcdef"; char str2[] = "abcdef"; 你要弄清楚这两者的区别，str1指向了一个常量字符串，常量字符串是不允许更改的， str2是一个字符串数组，存放在栈上，可以更改 你要实现你开始交换的目的，字符串指针使用后者  再问下我调试进去交换代码，每次都显示access violation 越界错误！如果是常量不让写按道理是提示无法改写啊， 为什么编译器这么提示？我用的是VS2010，这个错误让我纠结了半天！


Question: 帮忙看看这是怎么回事？

你怎么调用的

E:\csz\csz.c(188) : error C2198: 'c_jifenbang' : too few actual parameters 其实错误说的很明显啊，too few actual parameters---》实参太少。 这种问题自己得学会看出错信息解决

这句错了：printf("用户%c的积分为%5d,nickname,score"); 改为：printf("用户%c的积分为%5d“,nickname,score);

引用 1 楼 Symfund 的回复:printf("用户%c的积分为%5d",nickname,score);  顶


Question: strcmp

引用 2 楼 hjl0508 的回复:strcmp是比较字符串的，你哪个tmp[0]是一个字符，肯定不行啊，二楼说的挺对的！ 说错了，是一楼说的挺对的！

error C2664: “strcmp”: 不能将参数 2 从“char”转换为“const char *”  意思是strcmp的第二个参数不能转换成const char* ，tmp[0]是一个字符，一个字符怎么和字符串比较呢？？？ 不清楚你要比较啥？ 如果比较第一个字符if('d' == tmp[0])就行了


Question: 求推荐 算法/数据结构 书籍!

引用 4 楼 hollebab 的回复:[quote=引用 2 楼 FightForProgrammer 的回复:] 算法导论  花个一两年时间啃掉，顺便写个博客，督促自己也给别人参考 你算是推荐了本书,不过我想不通780页的书得花1-2年?是指把书反复看2~3遍以上吗?[/quote]  真正理解。烂熟于心。 当然水平高可以另当别论

引用 2 楼 FightForProgrammer 的回复:算法导论  花个一两年时间啃掉，顺便写个博客，督促自己也给别人参考 你算是推荐了本书,不过我想不通780页的书得花1-2年?是指把书反复看2~3遍以上吗?

引用 1 楼 user-2 的回复:一本书够看好几十年的了 嗯,那你是指哪本书呢?

算法导论  花个一两年时间啃掉，顺便写个博客，督促自己也给别人参考

一本书够看好几十年的了


Question: HMMIO句柄是高度保密的东西吧...

引用 3 楼 ForestDB 的回复:SDK里的吧  另外对我来说，所有的Windows API都是高度保密的东西。好吧

引用 2 楼 sd530842780 的回复:嗯，很保密，我都不知道是啥玩意哈，接分啦真坏!

SDK里的吧  另外对我来说，所有的Windows API都是高度保密的东西。

嗯，很保密，我都不知道是啥玩意哈，接分啦

脑子有阬..自己想通了..来几个接分的人吧..等会结贴..


Question: 求孙鑫的c视频教程

郝斌的看完了，你水平怎么样啊？看完一个，入门以后，可以自己想办法继续深入学习，视频看一个就可以了，这句话不错，而且，这个你网上一搜，不难搜到吧

去淘宝买

网上没有下载的资源，我不想在线看，希望有资源的同学分享一下

没有视频不知道要学些什么，看了赫斌的视频我感觉他讲的不完全，比如字符的操作和宏还有函数，想看看其他人的视频重点学习一下这部分的内容。我是学数学专业的，只是课外时间学c语言，后来学了赫斌的数据结构，感觉算法真的好多，要具备独立开发程序的能力真的好难，所以希望听听大家的看法，要学些什么才能具备独立开发小程序的能力

去优酷，直接搜“孙鑫”就可以了

视频看一个就行了，入个门而已。自己动手做才是真理。


Question: C语言4圣经看完了干什么?

写代码的话书上习题不就够了么,而且我认为学了这些浅显的东西能写出什么好东西吗?每天写十遍hello world?我刚学完C语言本身,看的最深的书也就是C专家编程, 接下去干些什么呢?

c语言四圣经是神马？ 学编程就是看书->写代码->看书->写代码...etc.

看完圣经，接着去做圣人


Question: c 中的ASCLL码 (⊙_⊙)？

#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> wchar_t a2w[256]={ 0x0020,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022, 0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c, 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8, 0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027, 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037, 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7, 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00e9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9, 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba, 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556, 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f, 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b, 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4, 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248, 0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00ff, }; extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t ws[256];     unsigned char s[256];     int i;       system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(16,  0, 0, 0, 0, 0, 0, 0, 0           , 0, 0, 0, 0, "Lucida Console");     SelectObject(hdc,hfont);     TextOutW(hdc,10,10,L"你好",2);     for (i=0;i<256;i++) s[i]=i;     for (i=0;i<256;i++) ws[i]=a2w[s[i]];     TextOutW(hdc,10, 40,ws    ,32);     TextOutW(hdc,10, 80,ws+ 32,32);     TextOutW(hdc,10,120,ws+ 64,32);     TextOutW(hdc,10,160,ws+ 96,32);     TextOutW(hdc,10,200,ws+128,32);     TextOutW(hdc,10,240,ws+160,32);     TextOutW(hdc,10,280,ws+192,32);     TextOutW(hdc,10,320,ws+224,32);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }

后面的也可以输出来，只是你的控制台能不能显示它，就和你的系统有关系了。比如，如果你用的是欧洲的windows系统，默认字符集是Latin1/Latin2/... 那么肯定是没问题，  如果你用的中文Windows，其默认编码是gbk/big5，那么肯定就显示不出来

引用 5 楼 sdu_sky 的回复:后面是不可见字符 啥叫”不可见“？

多出的是扩展的部分

后面是不可见字符

那扩展后的ASCLL码 用在怎么地方？

只有128，扩展后的才有256 ascII 使用7位


Question: 用十字链表实现图遇到的问题

data是char类型，为什么用%d？


Question: 问下用C连接MYSQL数据库无法连上

MySQL你看dBASE的DSN做甚？  请检查ODBC控制面板 注意查看驱动那里的显示项，最好能截图

MYSQL C API 访问程序(更新升级版本)  http://blog.csdn.net/hzhxxx/article/details/6100752

你到mysql安装目录下，有个include目录，在vs中包含这个目录和同目录下的lib目录，使用mysql.h中提供的函数直接连接mysql就可以了，不需要设定数据源的