Question: c 语言小白求教大神 无法运行

函数声明末尾要加分号 调用函数的时候要有括号 函数的实现要用大括号括起来

关注c语言基础

你函数定义有问题，应该把类型写在前面，声明带分号。  。

#include<stdio.h> void function1(void); void function2(void); int main (void) { printf("for he is a jolly good fellow!\n,for he is a jolly good fellow!\n"); function1(); function2(); return 0; } void function1(void) { printf("for he is a jolly good fellow!\n"); } void function2(void) { printf("which nobody can deny!\n"); } 从哪里学的语法~~   实践前也得学习才有效果~~

#include "StdAfx.h" #include"stdio.h" #include"string.h" #include<stdio.h> function1(void); function2(void); int main (void) { printf("for he is a jolly good fellow!\n,for he is a jolly good fellow!\n"); function1(); function2(); return 0; } function1(void) { printf("for he is a jolly good fellow!\n"); } function2(void) { printf("which nobody can deny!\n"); }


Question: C代码，求找错

传参 fun(a[5][10]),这个直接就写了个越界的东西，直接用a传二级地址就行了

fun(a[5][10]);调用错误，应该是fun(a); puts(a[i][j]);  调用错误，如果想一个字符一个字符打印是putchar(a[i][j]); M,K依赖用户输入，一旦输入大于5,10，访问内存越界；就算输入正确，后边输入的字符串长度过长会得到想不到的结果，刚开始试试可以，真正编程不能这么来的； printf("\n"), 不是/n ~~~~

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

错误已经注释在代码里了  #include"stdio.h" #include"string.h" int M,K; void fun(char (*a)[10]) {     int i,j;     for(i=0;i<M;i++)     {         for(j=0;j<K;j++)         {             putchar(a[i][j]);        //这里应该是putchar         }         printf("\n");             //应该是\n不是/n     } } int main() {     int i;     char a[5][10];     scanf("%d",&M);     scanf("%d",&K); 	fflush(stdin);     //这里要清空输入缓冲区     for(i=0;i<M;i++)         gets(a[i]);     fun(a);                  //传参不对，应该传a }


Question: 请问C语言这么分配了内存后，这么释放正确吗?

仅供参考：//在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19  //在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------

引用 3 楼 yyxgs 的回复:[quote=引用 2 楼 qq423399099 的回复:] 需要循环逐个释放  然后还要释放str本身吗?[/quote] 要的

引用 1 楼 user-3 的回复:for 循环里申请的空间仍然没有释放  如果里面释放了，str本身还需要释放吗?

引用 2 楼 qq423399099 的回复:需要循环逐个释放  然后还要释放str本身吗?

需要循环逐个释放

for 循环里申请的空间仍然没有释放


Question: 菜鸟求助，线程的同步设计

把每种功能的处理分别放在不同的线程中，每种需要处理的消息都用一个消息队列保存。  //功能1线程 msg_queue m1;//消息1的队列 msg_queue m2;//消息2的队列 void thread1() {       while(!stop)      {           wait_for(!msg_queue.empty());//使用条件变量来等待队列中是否有数据，如果有则继续后续处理，没有则继续等待                      handle();//处理消息1           msg_queue2.push_back(msg1);//处理过后，将结果加入到消息2队列，供后续的先处理                } }

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


Question: 关于VS2013中打开文件的问题

而且有一个很奇怪的问题就是,当我调试的时候,是可以打开文件的并写入的...

引用 2 楼 face_t0_sea 的回复:能打开，就是写不进去东西。 while (ch = getchar() != '@') 你这里运算符顺序错了，啥都没写进去，应该是： while ( ( ch = getchar() ) != '@')  确实是打不开文件啊,后面的运算符顺序错误改了之后还是这样

谢谢各位的指点

fopen_s这样用：   FILE* pFile; fopen_s(&pFile,filename,"w")   另需要判断是否打开文件成功  如果仍想用fopen可以选择以下任何一种方法： 1、新建项目时不要勾选安全开发生命周期检查 2、在项目属性C/C++命令行中加上 /D _CRT_SECURE_NO_WARNINGS

再另外，注意：fopen_s打开文件成功返回的是0  https://msdn.microsoft.com/zh-cn/library/z5hh6ee9.aspx

#pragma warning(disable:4996) ...

楼上正解，注意优先级（记不清就用小括号括起来）

标准打开文件方式 #iclude<stdio.h>      main()      {           FILE *fp;                /*定义一个文件指针*/           int i;           fp=fopen("CLIB", "rb");  /*打开当前目录名为CLIB的文件只读*/           if(fp==NULL)             /*判断文件是否打开成功*/              puts("File open error");/*提示打开不成功*/           i=fclose(fp);            /*关闭打开的文件*/           if(i==0)                 /*判断文件是否关闭成功*/             printf("O,K");         /*提示关闭成功*/           else             puts("File close error");/*提示关闭不成功*/      }


Question: codeblocks中输出中文就会出现这样的编译错误·

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

.CodeBlocks 默认情况下，是保存为windows本地编码的，也就是WINDOWS-936字符集，也就是GBK编码。    但是很神奇的是，GCC编译器默认编译的时候是按照UTF-8解析的。你存成GBK，但是当成UTF-8解析，这还能编译通过，这才有鬼了，所以这两个地方编码不统一好，编译的时候报错：error: converting to execution character set: Illegal byte sequence，你根本连通过编译的可能性都没有！  其实要解决这个问题很简单，编写Code：：Blocks的人只需要在调用编译器之前检测一下源文件是什么编码，然后就自动让编译器用什么编码进行解释，问题就解决了。


Question: 菜鸟求助，C语言 if 的问题。

最后一次的计算结果遗留在寄存器中，被返回 所以，虽然没有返回一个值， 在编译器没有报错的情况下，结果应该是对的 不过，很难保证，任何时候，都一定会这么巧

如果你使用汇编代码就能看出为什么不需要 return 了。 ax 寄存器直接返回。

引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 fff_kiseki 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 楼主居然能得到正确的结果？ 这样的代码在很多编译器连编译都过不去，返回值是int类型的，但又没有地方return  #include <stdio.h> bool IsPrime(int x) { 	int i; 	for(i=2;i<=x/2;i++) 	{ 		if(x%i==0) 			return false; 	} 	return true; } 		 		  int main() {     int x;     printf("input : ");     scanf("%d", &x);     if (IsPrime(x))         printf("%d is a prime number\n", x);     else         printf("%d is not a prime number\n", x);     system("pause");     return 0; }  是我的编译器太智能了吗？[/quote] GCC？[/quote]是的，用的codeblocks

引用 2 楼 fff_kiseki 的回复:[quote=引用 1 楼 qq423399099 的回复:] 楼主居然能得到正确的结果？ 这样的代码在很多编译器连编译都过不去，返回值是int类型的，但又没有地方return  #include <stdio.h> bool IsPrime(int x) { 	int i; 	for(i=2;i<=x/2;i++) 	{ 		if(x%i==0) 			return false; 	} 	return true; } 		 		  int main() {     int x;     printf("input : ");     scanf("%d", &x);     if (IsPrime(x))         printf("%d is a prime number\n", x);     else         printf("%d is not a prime number\n", x);     system("pause");     return 0; }  是我的编译器太智能了吗？[/quote] GCC？

引用 1 楼 qq423399099 的回复:楼主居然能得到正确的结果？ 这样的代码在很多编译器连编译都过不去，返回值是int类型的，但又没有地方return  #include <stdio.h> bool IsPrime(int x) { 	int i; 	for(i=2;i<=x/2;i++) 	{ 		if(x%i==0) 			return false; 	} 	return true; } 		 		  int main() {     int x;     printf("input : ");     scanf("%d", &x);     if (IsPrime(x))         printf("%d is a prime number\n", x);     else         printf("%d is not a prime number\n", x);     system("pause");     return 0; }  是我的编译器太智能了吗？


Question: 我是菜鸟  ，请指出错误。

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

引用 1 楼 qq423399099 的回复:不可能吧，肯定楼主在执行scanf("%c",&ch);之前输入缓冲区有遗留的数据（比如回车符） scanf("%c",&ch);之前加一句fflush(stdin);试试    解决

成功解决，确实是回车残留但是ffush (stdin)好像在xcode中用不了，使用getchar（）就可以了


Question: unsigned short *强制转换unsigned int *,另一个参数莫名被修改

楼上讲的都对，平均给分了

unsigned int是4个字节，unsigned short是占2个字节，写的时候已经写到后面的内存了

你把unsigned short d 这个short变量的地址当做int变量地址送给xxx函数处理，破坏了之后两个字节的内存，结果未定，在你的机器上就是那个结果~~~~

楼主自己sizeof(unsigned short)看看是不是2，如果是2的话那肯定修改了地址的跨度

这有什么好匪夷所思的？short型只占2字节，把它的地址强制成int*传参，当作占4个字节修改，自然修改到了其它地方。


Question: #line指令用法

这显然是用了什么别的预处理工具。而你那个.c是预处理过的文件。  预处理会改变源文件中行的位置，所以需要#line这个功能标记原本的位置。  比如预处理要把.h文件的内容插入到.c里，最终生成一个文件交给编译器。如果没有#line功能，编译器只能输出错误在这个最终的文件里的位置。而这个最终的文件一般来说用户根本看不到。而如果预处理器在这个最终文件中用#line标记当前行对应的原始文件和行号，编译器就可以输出错误在原始文件中的位置了。  #line并不是设计给人用的，这主要是预处理器和编译器间的一个协议。

引用 2 楼 caddor9100 的回复:如果没有关系的话，那为什么要在other_file里加上一些c语言的代码！， 当然也有一些怪异语法，如：  %(DEFAULT_BODY)s  我测试了，看到结果是没有影响，你可以换个文件名，对边写写东西，测试看看。但是关于你说到的怪异语法，真的不懂~~~

引用 1 楼 face_t0_sea 的回复:我也是刚学会。。。 确实是不经常用的一个宏，主要用于调试 程序编译后代码行号可能会有变化，这个宏能准确定位代码行，一般这么使用     # line100"other_file"     printf("current line number %d ,current file %s\n",__LINE__,__FILE__);return0; 执行了  # line100"other_file" 之后，下一行__LINE__变量会从100开始，__FILE__会变成你指定的文件名other_file；和other_file本身内容没有任何关系。不影响程序流程。在# line100"other_file"之前在打印下这两个变量，立即就懂了。  如果没有关系的话，那为什么要在other_file里加上一些c语言的代码！， 当然也有一些怪异语法，如：   %(DEFAULT_BODY)s


Question: 关于数据结构的问题，老是内存泄漏？？求大神指导

引用 4 楼 qq423399099 的回复:感觉你的add1函数逻辑上有问题(非常多的问题) add1函数里合并起来的h3肯定内存泄漏啊，即没有带出h3头结点的地址，也没有在函数里free (主函数中的两个链表用完也要free)  #include <stdio.h> #include <stdlib.h> typedef struct Node { 	int x1; 	int x2; 	struct Node *next; }List; void Create(List *l,int n) { 	List *h=l,*prev = NULL; 	h->next=NULL; 	while (n) { 		List *temp=(List *)malloc(sizeof(List)); 		temp->next=NULL; 		scanf("%d %d",&temp->x1,&temp->x2); 		if (h->next==NULL) { 			h->next=temp; 		} 		else 			prev->next=temp; 		prev=temp; 		n=n-1; 	} } void DisPlay(List *l) { 	List *h=l; 	while (h!=NULL) { 		printf("%d,%d\n",h->x1,h->x2); 		h=h->next; 	} }  void add1(List *l1,List *l2,List &l3) { 	List *h1=l1->next; 	List *h2=l2->next; 	List *h3 = NULL,*prev = NULL; 	while (h1!=NULL||h2!=NULL) { 		int a,b; 		if (h1 != NULL && h2 == NULL) 		{ 			a=h1->x1; 			b=h1->x2; 			h1=h1->next; 		} 		else if (h2 != NULL && h1 == NULL) 		{ 			a=h2->x1; 			b=h2->x2; 			h2=h2->next; 		} 		else if (h1->x2==h2->x2) { 			a=h1->x1+h2->x1; 			b=h1->x2; 			h1=h1->next; 			h2=h2->next; 		} 		else if (h1->x2<h2->x2) 		{ 			a=h1->x1; 			b=h1->x2; 			h1=h1->next; 		} 		else if (h2->x2<h1->x2) 		{ 			a=h2->x1; 			b=h2->x2; 			h2=h2->next; 		} 		List *temp=(List *)malloc(sizeof(List)); 		temp->next=NULL; 		temp->x1=a; 		temp->x2=b; 		if (h3==NULL) { 			h3=temp; 		} 		else 			prev->next=temp; 		prev=temp; 	} 	l3 = *h3;//通过引用带出 	/* 	while (h1!=NULL) { 	int a,b; 	a=h1->x1; 	b=h1->x2; 	h1=h1->next; 	List *temp=(List *)malloc(sizeof(List)); 	temp->next=NULL; 	temp->x1=a; 	temp->x2=b; 	if (h3->next==NULL) { 	h3->next=temp; 	} 	else 	prev->next=temp; 	prev=temp;  	} 	while (h2!=NULL) { 	int a,b; 	a=h2->x1; 	b=h2->x2; 	h2=h2->next; 	List *temp=(List *)malloc(sizeof(List)); 	temp->next=NULL; 	temp->x1=a; 	temp->x2=b; 	if (h3->next==NULL) { 	h3->next=temp; 	} 	else 	prev->next=temp; 	prev=temp; 	} 	DisPlay(h3);*/ 	 } int main(int argc, const char * argv[]) { 	// insert code here... 	List l,l1,l2; 	printf("第一个链表:\n"); 	Create(&l, 2); 	printf("第二个链表:\n"); 	Create(&l1, 3); 	add1(&l, &l1,l2); 	printf("------------------------------------------------\n"); 	DisPlay(&l2); 	printf("Hello, World!\n"); 	return 0; }  如果让h3变成带头结点的链表呢？

谢谢各位大神了

再加一个Destroy函数，来free掉链表的各个节点，在程序结束前调用这个Destroy函数

你malloc完了不free能不泄露吗。。。 在退出程序之前遍历一下链表进行free啊

求解答啊！！！


Question: windows下C语言实现的多线程实例

自己填自己挖的坑吧。

引用 8 楼 cutmelon 的回复:另外2楼说的问题是clientsocket这个变量的生命周期问题，按你的代码，一旦跳出主循环，clientsocket就失效了，如果这时候线程才启动的话，得到的参数就是一个未知的东西。一般而言，传给线程的参数不是全局有效的话，都是new/malloc出来，然后伺机释放(在线程里或者线程结束之后由主程序释放)可以给我讲讲socket多线程的逻辑吗？，同时多个客户端发送数据过来服务要怎么处理，（单线程的时候我把客户端发送过来的数据存入数据库的，）单线程是成功了的，  现在多线程我不知道怎么写进去，，，

引用 4 楼 pengzhixi 的回复:[quote=引用 3 楼 fyf350232349 的回复:] 什么意思？clientsocket这个参数怎么啦？ @pengzhixi首先弄清楚clientsocket所占内存是在哪，再确认作为参数这么传是否会引起问题。[/quote]可以和我讲讲socket多线程的逻辑吗？同时多个客户端发送数据过来服务要怎么处理，（单线程的时候我把客户端发送过来的数据存入数据库的，）  现在多线程我不知道怎么写进去，，，

大体意思没错，只不过接收线程没做tcp的分包粘包处理，所以程序结果就超出你想象了。 看你的代码大概是字符串协议吧，客户端发过来的字符串最后如果是exit，就表明关闭连接，现在问题来了： 如果客户端发送了123456789 exit，服务端接收到的可能分两次，第一次是123456，第二次是789 exit。按你现在的代码，是判断不出exit的啦。 这只是一个基础问题，其他的异常断线、超时、收发失败、数据处理现在的模型都还没处理，离实用还有好远，好好学习，嘿嘿

@pengzhixi 可以和我讲讲socket多线程的逻辑吗？同时多个客户端发送数据过来服务要怎么处理，（单线程的时候我把客户端发送过来的数据存入数据库的，）  现在多线程我不知道怎么写进去，，，

没有错啊，他能进入到线程函数，

引用 3 楼 fyf350232349 的回复:什么意思？clientsocket这个参数怎么啦？ @pengzhixi首先弄清楚clientsocket所占内存是在哪，再确认作为参数这么传是否会引起问题。

什么意思？clientsocket这个参数怎么啦？ @pengzhixi

if(strcmp(buffer, "exit"))

clientsocket这种参数你也敢传给多个线程做参数。


Question: 菜鸟求助，华为oj用链表提示内存超限，我自己试了几个例子，运行结果正确，求大神指出菜鸟程序需要改进的地方

引用 6 楼 face_t0_sea 的回复:你的数据结构有问题，遍历free都很麻烦，使用类析构函数释放内存；或者优化下逻辑，明知道节点个数，一次分配连续内存，一次释放节点数组内存吧大胸第，我错了，free(Head)只是释放了头节点

引用 6 楼 face_t0_sea 的回复:你的数据结构有问题，遍历free都很麻烦，使用类析构函数释放内存；或者优化下逻辑，明知道节点个数，一次分配连续内存，一次释放节点数组内存吧大胸第，这是一个链表，Head是表头，free(Head)就相当于把整个链表释放了吧，中间申请的节点只不过是这个链表的一部分而已。。。你没法预测输入节点个数，因为你要对链表添加或删除节点。

引用 4 楼 xusongge 的回复:malloc是为了开辟新节点，然后插入到原有的链表中，在输出之前根本不能free啊 你输出之后也没有free啊

引用 3 楼 face_t0_sea 的回复:malloc很多次，free只对head用了一次。会不会就是这个问题？ 按理来说Main退出内存会释放，我水平有限，不确认有没有其他调用方式会造成这里内存泄露，最好释放掉吧。 malloc是为了开辟新节点，然后插入到原有的链表中，在输出之前根本不能free啊

一楼说错了，是删除（2，5）（5，8）

一楼忘了放程序了#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<ctype.h> #include<stdbool.h> #include<string.h> #include<math.h> typedef struct node { 	int coor; 	int val; 	struct node *next; }Node; typedef Node *LinkList; int main(void) { 	LinkList Head,p; 	Head = (LinkList)malloc(sizeof(Node)); 	int m, n; 	scanf("%d%d", &m, &n); 	scanf("%d%d", &Head->coor, &Head->val); 	m--; 	Head->next = (LinkList)malloc(sizeof(Node)); 	p = Head->next; 	while (m--) 	{ 		scanf("%d%d", &p->coor, &p->val); 		if (m != 0) 		{ 			p->next = (LinkList)malloc(sizeof(Node)); 			p = p->next; 		} 		else 			p->next = NULL; 	} 	p = Head; 	LinkList p1,temp,temp1; 	int d,k; 	while (p->next != NULL) 	{ 		if (p->coor == p->next->coor) 		{ 			if (p->next->next == NULL) 				p->next = NULL; 			else 			{ 				p->next = p->next->next; 				d = p->next->coor - p->coor - 1; k = 1; 				temp = p->next; temp1 = p; 				while (d--) 				{ 					p1 = (LinkList)malloc(sizeof(Node)); 					p1->coor = temp1->coor + k; 					p1->val = temp1->val + ((temp->val - temp1->val) / (temp->coor - temp1->coor))*k++; 					p1->next = p->next; 					p->next = p1; 					p = p->next; 				} 				p = p->next; 			} 		} 		else 		{ 			d = p->next->coor - p->coor-1; k = 1; 			temp = p->next; temp1 = p; 			while (d--) 			{ 				p1 = (LinkList)malloc(sizeof(Node)); 				p1->coor = temp1->coor + k; 				p1->val = temp1->val + ((temp->val - temp1->val) / (temp->coor - temp1->coor))*k++; 				p1->next = p->next; 				p->next = p1; 				p = p->next; 			} 			p = p->next; 		} 	} 	p = Head; 	while (p->next != NULL) 	{ 		printf("%d %d ", p->coor, p->val); 		p = p->next; 	} 	printf("%d %d\n", p->coor, p->val); 	free(Head); 	system("pause"); 	return 0; }


Question: 用递归求x的y次幂，x是double类型，y是int 型

不要直接运行程序，运行调试程序，出错时点中断，通过调用堆栈、变量窗口等观察分析原因

y--应为--y或y-1，否则无限递归导致栈溢出 PS：建议换个便于分辨空格的字体


Question: 求大神指教任意多边形（凸或凹多边形）与点的关系

查MSDN是Windows程序员必须掌握的技能之一。

引用 3 楼 zhao4zhong1 的回复:PtInRegion The PtInRegion function determines whether the specified point is inside the specified region.   BOOL PtInRegion(   HRGN hrgn,  // handle to region   int X,      // x-coordinate of point   int Y       // y-coordinate of point );   Parameters hrgn  Handle to the region to be examined.  X  Specifies the x-coordinate of the point.  Y  Specifies the y-coordinate of the point.  Return Values If the specified point is in the region, the return value is nonzero.  If the specified point is not in the region, the return value is zero.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in wingdi.h.   Import Library: Use gdi32.lib.  See Also Regions Overview, Region Functions, RectInRegion赵老师，你这个是在VC++里面运行的么？

我是新人不太懂，所以不好意思啊！就是想看一个点与多边形的关系，判断这个点是在多边形内部还是外部还是在多边形上。现在就是这段代码有错误

给点背景描述别人才好帮你看啊~~~   想要什么效果，现在的结果什么样~~~~~~


Question: return()是什么意思？括号里不填

估计打错了，没有return() 这种的用法

引用 3 楼 TheBigBangWOW 的回复:[quote=引用 1 楼 yuelengdihai 的回复:] 转到定义看看，一般都是return 0； return 1；或者return；  谢谢，那为什么这里是return()，感觉这里应该是return 0才对[/quote] 我感觉也是return 0；

引用 4 楼 TheBigBangWOW 的回复:是的，是一道考试题目  这里不是需要填的，因为需要填的话会像前面那样有   （1） 的标记，表示第一题  return ()语法是错误的，如果不需要填就是题目打印错了。动手测试下就行了，多点怀疑精神

引用 2 楼 face_t0_sea 的回复:我感觉你在做题，return（） 的括号是让你填空的~~~~~~~~  不然return()通不过编译的。  是的，是一道考试题目  这里不是需要填的，因为需要填的话会像前面那样有   （1） 的标记，表示第一题

引用 1 楼 yuelengdihai 的回复:转到定义看看，一般都是return 0； return 1；或者return；  谢谢，那为什么这里是return()，感觉这里应该是return 0才对

转到定义看看，一般都是return 0； return 1；或者return；

谢谢各位，明白了 return应该只有1 0 或者什么都不加这几种情况

return 0;  排版的人不懂C，以为0是个()

它是不是想让读者自己思考那个地方应该return啥 那个地方是满足皇后相互攻击的条件，应当返回FALSE


Question: 菜鸟问大神C语言问题

运算符的优先级问题

引用 4 楼 qq_15340759 的回复:哦，懂了。那我应该用什么判别式让他们两同时执行并判断他们到结尾就终止呢 引用 3 楼 paschen 的回复:A && B  中：如果A为假，那么将不会去计算B  分开写，或者 A & B

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

A && B  中：如果A为假，那么将不会去计算B

fgets(buf,Max,SREfile）== NULL  这个是表示读文件失败吧？ 2个文件都读失败，怎么把读到的结果fputs？ 我糊涂啦。

大牛们，在线等啊。小弟求东啊


Question: PCHAR定义问题

是win32，不是MFC 看了之前的反汇编看明白了 不过还是谢谢回复   回复 验证码把我 头都看歪了...

vbx就是要显示的文本，转化为string就能显示了  CTime ctime=CTime::GetCurrentTime(); //得到当前系统时间 CString strTime=time.Format("%H:%M:%S"); ::SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_TIME,strTime); //送到指定控件 在vc6.0以后的版本中不支持AfxGetMainWnd()->m_hWnd来获取HWND，所以需要把这一句改为： SetDlgItemText(AfxGetApp()->m_pMainWnd->m_hWnd,IDC_TIME, strTime);


Question: 稀疏矩阵的十字链表存储，如何做到O(1)时间的随机访问？

十字链表，全称十字交叉链表，属于图数据结构之一，其数据结构是由不同的链表之间相互交错组成，形象的说，就像立交桥，只要知道所在位置，搜索效率是很高的。

int A[1000*1000]; struct LOC {  int y,x; } loc; map <int *,struct LOC *> v2yx;  loc.y=123; loc.x=456; A[loc.y*1000+loc.x]=789; v2yx[&A[loc.y*1000+loc.x]]=&loc;  ?

创建的时候就能记录每一个元素的行列index'

引用 1 楼 user-4 的回复:哈希表貌似可以 呃，好像可以。但是原文说加了一个索引矩阵

哈希表貌似可以


Question: c语言用二分法求解！！！求大神帮忙看看，运行之后总是等于0.

引用 3 楼 qq423399099 的回复:while(fabs(f0)<=1e-5);应该改为while(fabs(f0)>=1e-5); (楼主肯定能想明白) 改正后结果：   他是不是do while循环的终止条件搞错了？

引用 1 楼 yuelengdihai的回复:x是行参，你打印x值干嘛？ 我打印的是x0啊！！

x是行参，你打印x值干嘛？


Question: 求助，读取文件内容改个格式

for(ign=0;ign<9;ign++)	/*指针指向第10行开头*/ { memset(c,0,1024);	 fgets(c,1024,fpr); }     这里已经把t.txt里面的内容读到c中了   后面就把c按格式写到note.txt中就行 了


Question: 如何用void demo指令在C语言中编辑一个矩形，求急！

draw_rect( x, y, w, h, ch );  show_screen();  这个两个函数未完成的吧？是否声明在cab202_graphics.h文件中了


Question: C语言程序问题

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

引用 9 楼 gaopengon的回复:不给指针指定地址，系统会随机给指针指定一个地址，就可能去访问不能访问的地址。从而发生段错误。 解决了，谢谢…………

引用 6 楼 醉花阴柳的回复:name是数组指针，gets(name)会段错误 嗯，问题解决了，谢谢

引用 6 楼 醉花阴柳的回复:name是数组指针，gets(name)会段错误 打错了，上面是指针数组

name是数组指针，gets(name)会段错误

图片显示不出来……这

引用 2 楼 yuelengdihai的回复:你这怎么可能0错误0警告 参考下这个把 #include<stdio.h>   #include<conio.h>   int main()   {            void BubbleSort(int []);            int a[10];            int i,j,temp;            printf("Input tem integer numbers for a[10]:");            for(i=0;i<10;i++)               scanf("%d,",&a[i]);            printf("\n");            BubbleSort(a);            printf("The sorted array is:\n");               for(j=0;j<10;j++)                    printf("%d,",a[j]);            printf("\n\n");            getch();   }      void BubbleSort(int array[])   {            int i,j,temp;              for(j=0;j<9;j++)                 for(i=0;i<9-j;i++)                    if(array[i]>array[i+1])                     {                         temp=array[i];                         array[i]=array[i+1];                         array[i+1]=temp;                      }   }   真的是0错误0警告。冒泡排序上学期学过，不过这学期学到指针，要求用指针存放字符串，上次问老师老师说输入函数有问题，这样输入会随机分配到不同的地址，他说这是考点之一，可我看好久都不知道错在哪，我C语言太渣，求指教

如图，就是这种问题……

求各路大神帮帮忙，帮帮忙，


Question: 各位大神，为什么会运行会出错？

/*3、一个班上有30名学生，每个学生的数据作为 一个记录，每个记录包括 学号、姓名、三门课程的成绩和三门课程平均成绩。 从键盘输入学生的学号、姓名及三门课的成绩。 要求打印三门课程平均成绩最高分的学生记录（要求使用顺序表）。*/ #include"iostream" #include"stdlib.h" #include"string" #define MAXSIZE 3 using namespace std; typedef struct { 	int China; 	int math; 	int English; 	float average; }Date; typedef struct { 	int num; 	string name; 	Date score; }Stud_information; typedef struct { 	Stud_information *Stud; 	int Length; }SqList;  //初始化 void InitList(SqList *p) { 	p->Stud =(Stud_information*)malloc(MAXSIZE*sizeof(Stud_information)); 	p->Length = 0; }  //创建 void CreateList(SqList *p) { 	for (int i = 0; i < MAXSIZE;i++) 	{ 		cout << "学号" << "姓名"<< "语文" << "数学" << "英语" << endl; 		cin >> p->Stud[i].num>>p->Stud[i].name >> p->Stud[i].score.China >> p->Stud[i].score.math >> p->Stud[i].score.English; 		p->Length++; 	} }  //平均成绩 void Stud_average(SqList *p) { 	int N = p->Length - 1; 	for (int i = 0; i < N; i++) 		p->Stud[i].score.average = (p->Stud[i].score.China + p->Stud[i].score.math + p->Stud[i].score.English) / 3; }  //比较平均成绩 float bijiao(SqList *p) { 	float max = p->Stud[0].score.average; 	int N = p->Length; 	for (int i = 0; i < N; i++) 		if (p->Stud[i].score.average>max) 			max = p->Stud[i].score.average; 	return max; }    //查找最大平均成绩所在的位置及输出 void search(SqList *p, float max) { 	int N = p->Length - 1; 	for (int i = 0; i < N; i++) 		if (p->Stud[i].score.average = max) 		{ 		cout << "学号" << "姓名:" << "语文:" << "数学:" << "英语:" << "平均成绩" << endl; 		cout << p->Stud[i].num << "　" << p->Stud[i].name << "   " << p->Stud[i].score.China << "  " << p->Stud[i].score.math << "  " << p->Stud[i].score.English << "  " << p->Stud[i].score.average << endl; 		}  } int main() { 	SqList *L; 	L = new SqList; 	InitList(L); 	CreateList(L); 	Stud_average(L); 	float MAX = bijiao(L); 	search(L, MAX); 	return 0; } 现在呢？

引用 6 楼 gaopengon 的回复:空间开辟还不对啊，你可以把你开辟的空间的大小打印出来看看就知道还需要给stu开辟空间。 谢谢，你说的太对了，我现在知道还没给Stu开辟空间了，但怎么打印出来呢？

空间不是开辟了吗？L没有free？什么意思？

引用 1 楼 user-5 的回复:cin >> p->Stud->num>>p->Stud->name >> p->Stud->score.China >> p->Stud->score.math >> p->Stud->score.English;  这句里你还没未Stud分配内存  错误不在这吧~~ void CreateList(SqList *p)函数中的p是形参，在main函数中的调用点传递的实参是分配内存的。

*Stu没有申请空间，还有L没有free

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


Question: 大家好，我问一个很白的问题，求大神不要喷，比如我在本地运行一个计算器，这些数据是在计算机内存里面的，那么如果我在网络上运行一个计算器，数据是储存在哪里的呢？

引用 7 楼 u010165006 的回复:应该是的。不过如果网页上有一个用JavaScript写的计算器（也是静态网页），那就是在本机由浏览器运行JavaScript代码计算出来的。   明白了，感谢!

引用 4 楼 yyxgs 的回复:[quote=引用 2 楼 u010165006 的回复:] 在网络上运行一个计算器，指的是什么？在浏览器里运行，还是类似远程桌面之类的操纵另一台电脑上运行？还是分布式计算？  比如我用C写一个表达式计算器，输入1+1，得出结果2，这些数据都是运行在我的内存中的 如果我在百度上输入1+1，会有一个网页的计算器，那它们的数据是在哪里的呢?[/quote]  在百度上输入1+1，输入的信息会被提交到百度网站的某台服务器上，服务器后端会解析输入（动态网页），然后把结果翻译成静态网页（前端）回复给浏览器。ASP、JSP、PHP就是做动态网页的，根据用户提交的页面请求信息，动态网页的服务器程序（比如Tomcat）会执行动态网页的代码（比如JSP）代码，比如从数据库中检索到信息，生成HTML的表格形式（或其它的静态页面组织形式），返回给用户浏览器，浏览器显示页面得到想要的内容。

引用 5 楼 u010165006 的回复:[quote=引用 4 楼 yyxgs 的回复:] [quote=引用 2 楼 u010165006 的回复:] 在网络上运行一个计算器，指的是什么？在浏览器里运行，还是类似远程桌面之类的操纵另一台电脑上运行？还是分布式计算？  比如我用C写一个表达式计算器，输入1+1，得出结果2，这些数据都是运行在我的内存中的 如果我在百度上输入1+1，会有一个网页的计算器，那它们的数据是在哪里的呢?[/quote]  在百度上输入1+1，输入的信息会被提交到百度网站的某台服务器上，服务器后端会解析输入（动态网页），然后把结果翻译成静态网页（前端）回复给浏览器。ASP、JSP、PHP就是做动态网页的，根据用户提交的页面请求信息，动态网页的服务器程序（比如Tomcat）会执行动态网页的代码（比如JSP）代码，比如从数据库中检索到信息，生成HTML的表格形式（或其它的静态页面组织形式），返回给用户浏览器，浏览器显示页面得到想要的内容。[/quote]    也就是说我输入的1+1是在服务器上进行处理的?

引用 1 楼 zhao4zhong1 的回复:如果是java script，数据仍是在你本地计算机内存中。 如果是jsp或asp或cgi或php，数据应该是在Web服务器上的内存中。  谢谢,学习了!

引用 2 楼 u010165006 的回复:在网络上运行一个计算器，指的是什么？在浏览器里运行，还是类似远程桌面之类的操纵另一台电脑上运行？还是分布式计算？  比如我用C写一个表达式计算器，输入1+1，得出结果2，这些数据都是运行在我的内存中的 如果我在百度上输入1+1，会有一个网页的计算器，那它们的数据是在哪里的呢?


Question: debug没事，一运行就崩溃，哪位大神帮我看看这是怎么回事？

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

你只对Ps 分配了内存， 但是*Ps 的指针是不可预期的地址。 对了， 1楼已经说的很准确了。  另外， 有内存分配， 却没有内存释放， 应该要养成这样的习惯： 1. 有分配， 有释放。 2. 有open， 有close 3. 有lock， 有unlock。  祝你技术上不断进步。

二维数组不是像你这样申请的

debug没事？怎么可能，我debug就出问题了. Ps初始化了, 但是ps指向的东西没有


Question: 用C语言，读取TXT文档中的内容，读取文档中“[...]”里的内容。怎么编写

#include <iostream> #include <iomanip>   #include <fstream>   using namespace std;  int main() { 	ifstream myfile("F:\\test.txt");     if(!myfile){           cout << "Unable to open myfile";           exit(1); // terminate with error       }       else     {         char str[256] = {0};         char buff[256] = {0};         double a, b;         while(!myfile.eof())          {             myfile.getline (str,256);              sscanf(str, "%*[^[]%*c%[^,]", buff);  //(%*[^[]先过滤掉[之前的字符串,并且匹配到]为止)(%*c匹配掉[)                                                                //(%[^,]匹配字符串直到,)             cout << buff << endl;         }     } 	system("pause"); }

#include <stdio.h> char s[]=" xxx[jack,tony]"; char t[30]; int main() {     if (1==sscanf(s,"%*[^[][%29[^,]",t)) {         printf("(%s)\n",t);//(jack)     }     return 0; }

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

有没有相关编程的代码模板呢

[和, 匹配，读入一个[压栈，再读入一个,出栈，读取这之间的字符串

大致意思是  给你一个txt，里面有很多文章，其中有一些作者。 [jack,tony]， 我要读取其中的信息。    简单点就是读取文章中 “[  ]”里面的信息。而且只读取第一个作者。比如   [jack,tony]，只读取出  jack


Question: 怎么把调用的函数写进数组，然后通过数组调用函数

其实是可以通过编译的

哈哈，搞定了，谢咯

你的数组赋值应该通过不了编译，除非强制类型转化。 	unsigned int Color[2] = { 		{(unsigned int)*First_color}, 		{(unsigned int)*Second_color}, 	}; 然后调用的时候必须在转化回函数指针： typedef void (*FUNC_POINT)(void);   // 定义指针类型 ((FUNC_POINT)Color[0])();  // 这样就可以调用了。  其实可以直接定义函数指针数组的啊： typedef void (*FUNC_POINT)(void); FUNC_POINT funs[2] = {First_color, Second_color}; (funs[0])();


Question: 想请教一下void (*func)(int); 这样的函数定义应该怎么理解？？

表示不能理解void (*func)(int); 这类的形式  解释:func是一个函数指针，指向一个函数，此函数形参列表接受一个int值，返回值为void

函数名定义：void A(int); 函数指针定义：void (*B)(int);  括弧中的*B = A; B = &A;即B为指向函数首地址的指针。

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

引用 2 楼 face_t0_sea 的回复:void (*signal)(int signo, void (*func)(int)) (int);  是复杂句式定义  为了便于理解才分成两部分，是复杂句式是一致的： typedef void Sigfunc(int);  Sigfunc *signal(int, Sigfunc *);  typedef定义了一种函数类型，该类型接受一个int参数，返回值void; signal是这么一种函数，返回值是上面定义的函数指针（Sigfunc*）,参数有两个，一个是Int,第二个同样是上面定义的函数类型的指针（Sigfunc *）  感谢！

这是函数指针

void (*func)(int)转成人话的逻辑就是void(int)*func，void(int)是说返回类型是void参数是一个int的函数，void(int)*就是指向这么个函数的指针，然后void(int)* func就是定义一个这个指针的变量叫func。  C/C++里这种定义带括号的，除了参数表以外，表示的意义都是括号后面的内容要和括号前面的内容关联，而不是和自己前面的内容关联。最经典的还是那个int *[3]，[3]是三个int *，int (*)[3]人话是int[3]*，是指向int[3]的*。


Question: linux 开源作品非常操蛋的地方，让人恼火

引用 14 楼 csshow 的回复:[quote=引用 7 楼 jack960330 的回复:] 我也认为没必要debug版本，加日志即可，日志分析 高手就是这样做的[/quote] 恩

如果是CMake构建的项目，使用内建的CMAKE_BUILD_TYPE=Debug就行了； 如果是configure，需要看一下configure --help，类似于CFLAGS这类编译选项里可以添加你需要的东西。 debug这个东西比较灵活，不同的平台加的选项也不一样，就算作者提供了debug版本，使用者还是要自己修改掉的，所以也没必要提供了。

./configure CXXFLAGS=“-g -O0”  autotools 写的规矩的可以在 configure 的时候增加参数。

引用 7 楼 jack960330 的回复:我也认为没必要debug版本，加日志即可，日志分析 高手就是这样做的

可能你用的开源代码还不够成熟吧，一般都是有的 再说就算没有，也是作者愿意，有什么办法呢

不支持编译Debug版本

引用 3 楼 u012879787 的回复:[quote=引用 2 楼 mLee79 的回复:] 你直接 export  CFLAGS=-g 编译就有调试信息了。  去 O2 直接 sed 下就是了， 有啥麻烦的  指需要修改makefile文件吗？   autoconf之类的一类的工具，有没有一种可能性，把gcc的命令放到其她文件里（文件名字不同于makefile)[/quote]  不用手工改啥文件， 运行 configure  的时候指定下 CFLAGS 就可以了， 就像这样    CFLAGS="-g -Og" ./configure && make -j8 && sudo make install   就可以了。

我也认为没必要debug版本，加日志即可，日志分析

引用 5 楼 ynsenyu 的回复:那个库能弄出几十个makefile出来？说说名字看看? 引用 4 楼 zhao4zhong1 的回复:个人意见：没必要弄什么debug版本。加日志即可调试。  第三方库你有能耐就自己加日志吧！  自己写的代码，基本不调试， 只是第三方库才Debug

一般库都是release，调试要自己配置下参数 感觉自己加日志习惯了也挺好的

CFLAGS=“-g ..."  ./configure 就是指定个环境变量再运行 configure 。 如果有很多库要编译， 大家一般都 export CFLAGS="-g ...."  然后在运行 configure ...

引用 9 楼 chouxiaoya8100 的回复:[quote=引用 8 楼 mLee79 的回复:] [quote=引用 3 楼 u012879787 的回复:] [quote=引用 2 楼 mLee79 的回复:] 你直接 export  CFLAGS=-g 编译就有调试信息了。  去 O2 直接 sed 下就是了， 有啥麻烦的  指需要修改makefile文件吗？   autoconf之类的一类的工具，有没有一种可能性，把gcc的命令放到其她文件里（文件名字不同于makefile)[/quote]  不用手工改啥文件， 运行 configure  的时候指定下 CFLAGS 就可以了， 就像这样    CFLAGS="-g -Og" ./configure && make -j8 && sudo make install   就可以了。 [/quote]  CFLAGS="-g -Og"   这是什么语法？   如果， ./configure 生成的makefile文件里的， cflags后面跟着很多参数，你直接使用这个命令，会不会影响到其他参数？ [/quote]  这能有啥影响， 大部分库交叉编译的时候大家都是这样子编译， 就没啥问题过， 偶尔有写的有问题的 autoconf,  手工稍微改改就是了 。。。  CFLAGS="-I${TARGET_INSTALL_PATH}/usr/include -march=armv7-a -mtune=cortex-a8 -mfpu=neon"  \ LDFLAGS="-L${TARGET_INSTALL_PATH}/usr/lib"  \ ...... \ ./configure --build=${TARGET} --prefix=/usr ....  && make -j8 && make install DESTDIR=${TARGET_INSTALL_PATH}

引用 8 楼 mLee79 的回复:[quote=引用 3 楼 u012879787 的回复:] [quote=引用 2 楼 mLee79 的回复:] 你直接 export  CFLAGS=-g 编译就有调试信息了。  去 O2 直接 sed 下就是了， 有啥麻烦的  指需要修改makefile文件吗？   autoconf之类的一类的工具，有没有一种可能性，把gcc的命令放到其她文件里（文件名字不同于makefile)[/quote]  不用手工改啥文件， 运行 configure  的时候指定下 CFLAGS 就可以了， 就像这样    CFLAGS="-g -Og" ./configure && make -j8 && sudo make install   就可以了。 [/quote]  CFLAGS="-g -Og"   这是什么语法？   如果， ./configure 生成的makefile文件里的， cflags后面跟着很多参数，你直接使用这个命令，会不会影响到其他参数？

引用 2 楼 mLee79 的回复:你直接 export  CFLAGS=-g 编译就有调试信息了。  去 O2 直接 sed 下就是了， 有啥麻烦的  指需要修改makefile文件吗？   autoconf之类的一类的工具，有没有一种可能性，把gcc的命令放到其她文件里（文件名字不同于makefile)

那个库能弄出几十个makefile出来？说说名字看看?

个人意见：没必要弄什么debug版本。加日志即可调试。

为什么作者不提供debug编译选项？  不知道读者累吗？


Question: 程序执行错误。。。。求解？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

运行调试程序，出错点中断，通过调用堆栈、变量窗口等观察分析原因

楼主这里读入scanf("%d,%d", &G->n, &G->e); 必须输入3,3才行，楼主输入3 3,后面的G->e将读不到3


Question: c语言读文件中的字符串遇到换行符跳出循环

谢谢大大们，上周问了之后自己解决了，忘记上来结帖了

fscanf遇到空格和换行时结束 楼主可以考虑用fgets

int table_read(NODE *head) {     int index=0;     FILE *fp;     NODE*p=head;     char create_name[amount];     char buffer[amount]={0};     printf(">>Please enter a file name\n>>");     gets(create_name);     fp=fopen(create_name,"r");     if (NULL==fp)     {         printf("cannot open the file!\n");         exit(0);     }     while (1)     {         if (NULL==fgets(buffer,amount,fp)) break;         p->arr[index] = (char *)malloc(strlen(buffer) + 1);         strcpy(p->arr[index],buffer);         if (buffer[strlen(buffer)-1]=='\n')         {             p=p->next;             index=0;         }         else         {             index++;         }     }     fclose(fp);     return index; }

windows下文本文件换行是用\r\n


无符号整形 用%u，

用%u


Question: 菜鸟求助

LZ 这样跟你讲：  为什么a=%d    意思是  你定义是 相当于定义了整形的 a  和  b    然后没有赋值 你那个scanf（）语句就相当于输出的整数然后给你定义的整形字母 赋值，  所以相当于你输入的十进制数等于 给整形赋值十进制，明白？？？？ 了解？？？LZ？？？

引用 3 楼 qq_34274794 的回复:[quote=引用 1 楼 qq423399099 的回复:] 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。 如果我在中间加的是%*c，然后我输入两个逗号为什么会导致第二个数字读取的是1呢？[/quote] 楼主贴一下代码

引用 3 楼 qq_34274794 的回复:[quote=引用 1 楼 qq423399099 的回复:] 空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。 如果我在中间加的是%*c，然后我输入两个逗号为什么会导致第二个数字读取的是1呢？[/quote] 我用的是DEVc++    好像所有没有读入的随机值都是1

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt  参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c的内容。

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.

引用 1 楼 qq423399099 的回复:空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止。一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。 如果我在中间加的是%*c，然后我输入两个逗号为什么会导致第二个数字读取的是1呢？


Question: q的值丢了，求并集的时候

再供参考：#include <algorithm> #include <iostream> #include <functional> #include <cstring> using namespace std; int main() {     char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;     char *Vowels   = "aeiou" ;     char *AlphaNum = "0123456789abcdef" ;     char result[45] ;     char *last ;      int lenA  = strlen(Alphabet) ;     int lenV  = strlen(Vowels  ) ;     int lenAN = strlen(AlphaNum) ;      cout << "Alphabet = " << Alphabet << endl ;     cout << "Vowels   = " << Vowels   << endl ;     cout << "AlphaNum = " << AlphaNum << endl ;      cout << "\nusing non-predicate versions" << endl ;      //non-predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //non-predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      cout << "\nusing predicate versions" << endl ;      //predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result  , less<char>()) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result  , less<char>()) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result  , less<char>()) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result  , less<char>()) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      return 0 ; }

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

有以下几个问题：（我都在代码里注释了） 1.creatsl函数里感觉p=(lnode*)malloc(sizeof(lnode));这句多余的，没必要malloc,malloc以后你就让他指向别的了，内存泄漏！ 2.uns里当链表h2循环一次以后，需要让q重新再指回第一个节点，j也需要置1 3.合并好以后将h2的头结点free掉  #include <stdio.h> #include <stdlib.h> typedef struct NODE{ 	int data; 	struct NODE* next; }lnode,*node;  node creatsl(int A)//创建单链表 { 	node h; 	node p,s; 	int i; 	p=(lnode*)malloc(sizeof(lnode));  	h=(lnode*) malloc(sizeof(lnode));//初始化空表 	h->data=0; 	h->next=NULL;  	p=h; 	for(i=0;i<A;i++) 	{ 		s=(lnode*)malloc(sizeof(lnode)); 		scanf("%d",&s->data); 		p->next=s; 		p=s; 	} 	p->next=NULL; 	return h;   }  /*void insert(node h,int i,int x)//在第i个节点后插入 { node p,s; h->next=p; int j=0; while(j!=i-1) { p=p->next; j++; } s->data=x; s->next=p->next; p->next=s; }*/  void dele_node(node h,int i)//删除第i个节点 { 	node p,s; 	//p=h; 	int j=0; 	p=h;  	while(j!=(i-1)) 	{ 		p=p->next; 		j++; 	} 	s=p->next; 	p->next=s->next; 	free(s); }  node uns(node h1,node h2)//求并集 { 	void dele_node(node h,int i);  	node p,q,m,n; 	int i=1; 	int	j=1;   	p=h1->next; 	q=h2->next; 	 	m=h2->next;  	while(p) 	{ 		q = m;//重新让q指向h2的第一个结点 		j = 1;//j也要置1 		while(q) 		{ 			if((p->data)==(q->data))//执行到此处出现问题 			{ 				q=q->next;//删除前先指向先一下结点，否则的话该结点删除掉以后再运行q=q->next之后再取它的data会产生异常 				dele_node(h2,j); 				j--; 			} 			else 			{ 				q=q->next; 				j++; 			} 		} 		i++; 		n=p; 		p=p->next; 	} 	n->next=h2->next; 	m=h2; 	free(m); 	//dele_node(h1,i); 	return(h1);  }   int main(void) { 	node creatsl(int A); 	//void insert(node h,int i,int x); 	void dele_node(node h,int i); 	node uns(node h1,node h2); 	node p; 	node h1,h2; 	node p1,p2;  	//	node dpre; 	//	int dnum;  	int num_A,num_B;  	printf("请输入集合A的数目："); 	scanf("%d",&num_A); 	while(num_A<1) 	{ 		printf("请输入正整数"); 		printf("请输入集合A的数目："); 		scanf("%d",&num_A);  	} 	h1=creatsl(num_A);  	printf("请输入集合B的数目："); 	scanf("%d",&num_B); 	while(num_B<1) 	{ 		printf("请输入正整数"); 		printf("请输入集合B的数目："); 		scanf("%d",&num_B);  	} 	h2=creatsl(num_B);  	p1=h1->next; 	while(p1) 	{printf("%d,",p1->data); 	p1=p1->next;} 	printf("\n");  	p2=h2->next; 	while(p2) 	{printf("%d,",p2->data); 	p2=p2->next;}//创建并输出两链表 	printf("\n");   	p=uns(h1,h2)->next; 	while(p!=NULL) 	{ 		printf("%d ",p->data); 		p=p->next; 	} 	printf("\n");  	/*printf("请问您需要删除第几个节点："); 	scanf("%d",&dnum); 	while((dnum>num_B)|(dnum<0)) 	{ 	printf("请输入小于%d的正整数：",num_B); 	scanf("%d",&dnum); 	} 	dele_node(h2,dnum); 	dpre=h2->next;  	while(dpre) 	{ 	printf("%d,",dpre->data); 	dpre=dpre->next; 	}*/ 	return(0);  }


Question: C语言读图外加图像处理求答疑

先了解一下JPEG格式再提问。

libjpeg-turbo是用的最多的jpeg开源解码库，可以试试看，楼主的想法是bmp格式才可以，那也要去掉文件头

仅供参考：#include <iostream> #include <fstream> #include <string> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib")  using namespace std; using namespace Gdiplus;  int main() {     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);      wstring infilename(L"1.jpg");     string outfilename("color.txt");      Bitmap* bmp = new Bitmap(infilename.c_str());     UINT height = bmp->GetHeight();     UINT width  = bmp->GetWidth();     cout << "width " << width << ", height " << height << endl;      Color color;     ofstream fout(outfilename.c_str());      for (UINT y = 0; y < height; y++)     for (UINT x = 0; x < width ; x++) {             bmp->GetPixel(x, y, &color);             fout << x << "," << y << ";"                  << (int)color.GetRed()   << ","                  << (int)color.GetGreen() << ","                  << (int)color.GetBlue()  << endl;     }      fout.close();      delete bmp;     GdiplusShutdown(gdiplustoken);     return 0; }

引用 7 楼 u012947309 的回复:[quote=引用 5 楼 xr_zy1110 的回复:] 运行了一下 能通过，但查看的数字貌似不对 你看看是不是pBuffer根本没读满，后面有很多元素是0，而且你这样没读文件头。[/quote] 运行了一下 全部显示的是-52

jpg文件格式我不知道 bmp图片如果你用c读的话，是要自己解析文件头的。 比如你的图像是390*260=101400个像素值，你会发现其实这个文件的大小是101400+xxx； 多出来的xxx大小就是文件头等信息，包含了这个文件的色素通道调色板等等。 需要自己在c中写个struct来读。  jpg据说压缩过，所以文件应该小于101400，但是同样包含文件头信息头等内容需要自己写struct去读。 代码比较麻烦其实。

引用 5 楼 xr_zy1110 的回复:运行了一下 能通过，但查看的数字貌似不对 你看看是不是pBuffer根本没读满，后面有很多元素是0，而且你这样没读文件头。

能不能举个小例子，以代码的形式

运行了一下 能通过，但查看的数字貌似不对

#include<stdio.h> #include<stdlib.h> int main() { 	FILE *fp; 	char pBuffer[390*283]; 	int n=0, i;  	fp = fopen("a.jpg","rb"); 	if(!fp) 	{ 		printf("文件打开失败"); 		return -1; 	} while(!feof(fp)){   fread(pBuffer, 1, 1, fp);      n++; }   for(i=0;i<n;i++) 	  printf("  %d  ",pBuffer[i]); printf("%d",n);   return 0; }

JPEG 原理详细实例分析及其在嵌入式 Linux 中的应用 http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/

首先你要了解jpg文件的存储格式，然后才能知道怎么去读

JPEG图片是经过熵编码的，直接用fread读文件到缓冲区，缓冲区的数据是未解码的不可理解的。 可以用某种图像库函数读取JPG文件，然后可以操作它的每一个像素。


Question: 大神帮我看看 应该在哪释放内存！！！

没用了就释放，再用时再申请 记住申请释放要配对就行了

不再会使用的时候就可以free了。。。 不过要注意不要重复free free的空间不要有堆溢出的情况（或者已经被破坏） 不要访问已经free的空间

程序退出（也就是进程）时，操作系统会帮你自动free掉你malloc后没free的内存。 所以 只要 你的程序每次运行都是启动新进程（在cmd窗口中输入exe文件名运行或在资源管理器或桌面上双击运行）， 或 每次被其它程序调用都是用“通过文件将待加工数据传递给你，创建新进程运行你的程序；你的程序运行完毕，将处理后的数据保存到结果文件，退出程序；其它程序读取结果文件”方法， 在你的程序中就没必要free掉你malloc后没free的内存。

在不需要使用时即可释放，如果程序运行整个期间均需要，可以在程序结束前释放


Question: 苍天啊  又死在内存身上了。。求内存跟踪记录软件

valgrind可见检测内存泄漏

VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

malloc动态分配内存应该会好点。

引用 1 楼 user-5 的回复:你用C++是怎么搞出内存泄漏的  就是找不到所以的原因， 只是找到了一个 。   是我调用的库里面 的 窗口句柄没有释放。  这还是我不断观察程序句柄数目  才发现的。   其他的泄漏 我就找不到了/  所以需要一款软件记录目标程序的   句柄数目变化规律     内存变化规律

引用 2 楼 visoncomputer 的回复:malloc动态分配内存应该会好点。  多谢提醒  这个已经在用了  。。。 不是这个问题。。

引用 5 楼 paschen 的回复:http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio  感谢版主提供了这个链接。  链接所对应是一个叫Visual Leak Detector （建成VLD）的一个软件（或者称之为插件）之类的东西。  用于在Visual studio 环境下，使用C++编程的时候，帮助开发人员发现 内存泄漏。  ×××××××××××××××××× 链接中可以提供，这个软件（或者称之为插件），源代码。  并且提供了使用方法。   ×××× 蛮不错的软件，我会研究 学习 如何去使用它。   最后谢谢版主。

引用 6 楼 user-5 的回复:[quote=引用 4 楼 wenluderen 的回复:] [quote=引用 2 楼 visoncomputer 的回复:] malloc动态分配内存应该会好点。  多谢提醒  这个已经在用了  。。。 不是这个问题。。[/quote]  如果你老老实实使用RAII机制的话，C++里几乎是搞不出泄露的...[/quote]  感谢前辈  给出了这么好的一个机制，我大致看了下，  这个机制似乎是把资源释放 放到对象的 析构函数里面做的。   其实我是想有个  内存开销 记录 的软件，记录下我想要调试的那个程序的内存开销和时间的曲线。  用于分析我是那一段代码出了问题。  最如果这个软件   可以记录  句柄的数目变化过程，那就更好了。    谢谢

引用 4 楼 wenluderen 的回复:[quote=引用 2 楼 visoncomputer 的回复:] malloc动态分配内存应该会好点。  多谢提醒  这个已经在用了  。。。 不是这个问题。。[/quote]  如果你老老实实使用RAII机制的话，C++里几乎是搞不出泄露的...

你用C++是怎么搞出内存泄漏的


Question: [链式结构的栈]

InitStack的参数是按值传递的，只是main函数中mystack的一个复制品，所以你在InitStack中把申请到的内存赋予指针并不是对main中的mystack进行赋值

引用 4 楼 qq_34251172 的回复:typedef struct Stack { 	DataType data; 	Stack* next; }Stack;  void RemoveStack(Stack* temp); void getTop(Stack* temp); void InitStack(Stack* &temp,DataType data) { 	Stack* mid=temp; 	temp=(Stack *)malloc(sizeof(Stack)); 	temp->next=mid; 	temp->data=data; }  void RemoveStack(Stack* temp) { 	if(temp=NULL) 	{ 		printf("Empty Stack Error"); 		exit(OVERFLOW); 	} 	Stack* mid=temp; 	temp=temp->next; 	//free(mid); }  void getTop(Stack* temp) { 	printf("%d",temp->data); }   void main(int argc, char* argv[]) { 	Stack* mystack=(Stack *)malloc(sizeof(Stack)); 	mystack->next=NULL;  	InitStack(mystack,2); 	getTop(mystack); }  我改成了这样 感觉你多malloc了一次

引用 1 楼 qq423399099 的回复:有几个问题： 1.main函数里你的mystack也要malloc 2.InitStack中楼主应该是要让mystack指向新创建的temp结点吧？ 3.getTop的时候应该传参(mystack->next)才是打印的第一个结点的值 4.const int OVERFLOW=1;最好换个名字，OVERFLOW是定义在math.h中的一个宏定义（有些编译器过不了编译）  #include "stdafx.h" #include "stdio.h" #include "stdlib.h" //#define var "%d\n" const int MY_OVERFLOW=1; typedef int DataType;  typedef struct Stack { 	DataType data; 	Stack* next; }Stack;  void RemoveStack(Stack* temp); void getTop(Stack* temp); void InitStack(Stack* temp,DataType data) { 	Stack* mid=temp; 	temp=(Stack *)malloc(sizeof(Stack)); 	//temp->next=mid; 	mid->next = temp; 	temp->data=data; }  void RemoveStack(Stack* temp) { 	if(temp=NULL) 	{ 		printf("Empty Stack Error"); 		exit(OVERFLOW); 	} 	Stack* mid=temp; 	temp=temp->next; 	//free(mid); }  void getTop(Stack* temp) { 	printf("%d",temp->data); }   void main(int argc, char* argv[]) { 	Stack* mystack = (Stack *)malloc(sizeof(Stack)); 	InitStack(mystack,2); 	getTop(mystack->next); }    这样会不会算是多创建一个内存空间呢，就是至少要有一个malloc结构体是这样吗


Question: 关于c语言开发工具库的问题

引用 1 楼 user-1 的回复:音视频的openal portaudio ffmpeg都是c写的吧，gui的话gtk+windows下面支持不好的，可以试试iup，打包的话都支持静态链接的，可以做成单文件绿色版 gtk+windows支持的不好？指的是什么？iup又是什么？难道是面向对象的？


Question: 关于约瑟夫环问题

已解决  LZ把判断符号弄错了

程序崩溃返回的错误是什么？哪一步崩溃的，断点调试看看错误信息是什么

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


Question: 这个程序哪里错了？从文件中读取数据并输出，

验证正常

写入文件后，先关闭文件，然后再打开。 ... printf ("生成结束\n"); // 因为你写入文件时，fopen的模式为"w"，此时文件指针无法seek回文件的起始。 // 你可以检查一下fscanf的返回值，按你的代码，应该返回值均为-1，也就是说读取文件是失败的； // numbers[i]中的值只不过是栈上的内存中的一些随机值。 // 需要先关闭文件，再用“r"模式重新打开 fclose(bigarray); bigarray = fopen("bigarray.txt", "r");


curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);


Question: 类型转换的一个问题

浮点数是有精度误差的 float 有效位数大概就7位，转成float时存的其实大概是2.14748365e+009  注意最后是65，所以是比原来的整数要大的 之后转换回int导致溢出

float有效数字只有24位，2147483647一共31位有效数字所以就给近似成2147483648了。顺便2147483648是1 * 2 ^ 31，有效数字只有1位。  转回来的时候因为溢出了所以2147483648成了-2147483648

浮点数格式 http://bbs.csdn.net/topics/390676437

float只是表示的范围比Int大，精度的话就6位有效数字。

float的精度不是比int应该要大的吗？？在转化的时候为什么2147483647变成了2147483648？？？是什么原因 求解。新手实在搞不明白。


Question: 【提问】小程序问题

scanf没法读入空格，所以你一开始读进str的就是"fool"而不是"fool food",可以用gets读 scanf("%s",str);改为gets(str);


Question: 关于数组指针的标准输出

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

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

%s 需要的是以\0结尾的字符串，所以需要传递char*而不是char

char *head[5]={"hello","how","are","you","today"};是一个指针数组，每个元素都为一个指针 head[2]是一个char *指针（相当于head[2] = "are";）（当然要用%s输出） *head[2]就是取指针的第一个字符了(单个字符要用%c输出) *(head+2)和head[2]是一模一样的

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt  参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c的内容。

表达式的类型不同。 head 的类型是数组，元素类型是char *； head [2] 的类型是char * ； * head [2] 的类型是char 。


Question: 这个链表程序中 p1=head这句的用意是什么？

指针1=指针2的意思就是让指针1也指向指针2指向的对象。

使p1保存链表头节点地址，不然free(p1)就不能起到释放内存的作用了

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

存头节点指针以后释放头节点内存用，你的头节点指针可是一直在变化的

这个有用啊'用来释放一开始申请的头指针内存'不然那一段内存溢出


Question: 各位大哥，这是什么原因？库文件冲突？？？怎么解决

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

上面贴的代码一堆拼写错误

拼错系统找不到main函数了

int mian() ????  main

minGW去编译VC的项目么？ WinMain是VC内置在VC库里的伪入口函数，在minGW里不见得有实现。


Question: strstr（）函数不可以用于比较字符吗？

'c'和"c"是不同的两个东西，第一个表示一个字符，第二个表示一个字符串，这个字符串里有两个内容，一个是字符c还有一个隐含的结束符'\0'

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

strstr 比较的是以 \0 结尾的字符串，char b[]={'c'};的话后面是没有\0的

引用 3 楼 baidu_28726667 的回复:[quote=引用 2 楼 qq423399099 的回复:] 用单引号赋值不会自动加上'\0',这样的话调用strstr它就不会在比较一个字符以后就结束（因为没有碰到'\0'） 而且楼主sizeof(b)也是1，所以很明显只对某个位置赋值了，没有加'\0',后面紧跟着垃圾值 以下是strstr的实现，很明显在比较一个字符后还会继续比较一些垃圾值，  char *strstr(const char *find, const char *need) { 	assert(find !=NULL && need !=NULL); 	while( *find !='\0') 	{ 		const char *p=find; 		const char *q =need; 		const char *res= NULL;  		if(*p == *q) 		{     			res= p; 			while(*p++ == *q++) 				; 			if(*q == '\0') 				return res; 		} 		find ++; 	} 	return NULL; }   这里有点不懂，我这种数组初始化方式不就是让数组的大小自动识别为1吗？ 而且既然sizeof只有1. 那不就是证明我这个数组里面只有1个元素吗？ 这个'c' 后面还能有空间有随机值？[/quote] 你如果是双引号赋值char b[]={"c"};那么sizeof(b)是2，因为自动会加上'\0' 你如果是char b[]={‘c’};那么紧跟着字符c后面的可能是垃圾值（你没有紧跟'\0'，它又怎么知道你这个数组有多长呢） 你用char指针去读，它要读到'\0'才会停止或者越界崩溃

引用 2 楼 qq423399099 的回复:用单引号赋值不会自动加上'\0',这样的话调用strstr它就不会在比较一个字符以后就结束（因为没有碰到'\0'） 而且楼主sizeof(b)也是1，所以很明显只对某个位置赋值了，没有加'\0',后面紧跟着垃圾值 以下是strstr的实现，很明显在比较一个字符后还会继续比较一些垃圾值，  char *strstr(const char *find, const char *need) { 	assert(find !=NULL && need !=NULL); 	while( *find !='\0') 	{ 		const char *p=find; 		const char *q =need; 		const char *res= NULL;  		if(*p == *q) 		{     			res= p; 			while(*p++ == *q++) 				; 			if(*q == '\0') 				return res; 		} 		find ++; 	} 	return NULL; }   这里有点不懂，我这种数组初始化方式不就是让数组的大小自动识别为1吗？ 而且既然sizeof只有1. 那不就是证明我这个数组里面只有1个元素吗？ 这个'c' 后面还能有空间有随机值？

你先弄清楚c语言双引号和单引号的区别了吧，双引号会自动在字符串的末尾加上'\0'，单引号不会，而c语言函数库正是使用这个来判断该字符串是否结束，否则你的程序可能抛异常。


Question: 数据结构，逆波兰式，求高手帮忙解释一段代码，谢谢

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

引用 11 楼 Adonis044 的回复:以‘\0’结束我知道，可是他把str【i】复制给\0，为什莫，str[i应该在str[i++]前面才对呀。  str[i++]=c; str[i]='\0'; 相当于： str[i]=c; i++; str[i]='\0'; //字符串最后置0, 0在c这个字符后面；下一次循环的时候0这个位置又被赋为c，c后面又被赋为0  不是“复制给\0 ”，是赋0  推荐你看一本书：《深入理解C指针》

引用 8 楼 u010165006 的回复:[quote=引用 7 楼 qzhuorui的回复:][quote=引用 4 楼 u010165006 的回复:] str[i++]=c; str[i]='\0'; 相当于： str[i]=c; i++; str[i]='\0'; //字符串最后置0我理解为，c赋值给str[i++]，可是为什么紧接着要加上一句str[i]='\0';还有麻烦问下为什么要这样写，新手有点不太理解，麻烦你了，谢谢。[/quote] C语言中字符串是以0结尾的，你可以翻下书本。[/quote]以‘\0’结束我知道，可是他把str【i】复制给\0，为什莫，str[i应该在str[i++]前面才对呀。

引用 9 楼 paschen 的回复:引用 6 楼 Adonis044 的回复:[quote=引用 1 楼 paschen 的回复:] 出错时点中断，通过调用堆栈、变量窗口等观察分析原因，必要时也可单步跟踪程序运行听不懂啊，你说的好复杂.......  首先要学会调试，经常遇到BUG是肯定的，你不可能每次都来问  去网上搜索如何调试程序BUG[/quote]谢谢

引用 6 楼 Adonis044 的回复:引用 1 楼 paschen 的回复:出错时点中断，通过调用堆栈、变量窗口等观察分析原因，必要时也可单步跟踪程序运行听不懂啊，你说的好复杂.......  首先要学会调试，经常遇到BUG是肯定的，你不可能每次都来问  去网上搜索如何调试程序BUG

引用 7 楼 qzhuorui的回复:[quote=引用 4 楼 u010165006 的回复:] str[i++]=c; str[i]='\0'; 相当于： str[i]=c; i++; str[i]='\0'; //字符串最后置0我理解为，c赋值给str[i++]，可是为什么紧接着要加上一句str[i]='\0';还有麻烦问下为什么要这样写，新手有点不太理解，麻烦你了，谢谢。[/quote] C语言中字符串是以0结尾的，你可以翻下书本。

引用 4 楼 u010165006 的回复:str[i++]=c; str[i]='\0'; 相当于： str[i]=c; i++; str[i]='\0'; //字符串最后置0我理解为，c赋值给str[i++]，可是为什么紧接着要加上一句str[i]='\0';还有麻烦问下为什么要这样写，新手有点不太理解，麻烦你了，谢谢。

引用 2 楼 qq423399099 的回复:不知道楼主是哪里看不懂？红色字体标注的那，表示不理解

新手…过滤数字那里看不懂…

不知道楼主是哪里看不懂？

出错时点中断，通过调用堆栈、变量窗口等观察分析原因，必要时也可单步跟踪程序运行


Question: 在使用vs编辑c链表时出现的问题（节选），求告知错误解决方式

引用 4 楼 paschen 的回复:另外你Student结构体的定义在哪？ 我输出的只是节选

引用 3 楼 paschen 的回复:scanf_s("%d",pNew->iNumber); 改成 scanf_s("%d",&pNew->iNumber); 也没有用，还是那些报错

另外你Student结构体的定义在哪？

引用 6 楼 paschen 的回复:这里是不是打错了，应该是Student  struct Student { 	char cName[20]; 	int iNumber; 	struct Struct*pNext; };

改了，可是也没有任何变化啊

scanf_s("%s",pNew->cName); 改为 scanf_s("%s",pNew->cName,19);


Question: 程序为什么不能输出？

gets()函数不安全。你的程序当输入的字符不大于10个时可以正常工作，否则s1数组不足以存储所有字符，产生越界。

用楼主的代码可以输出啊。。。


Question: 小白求助

明白了，谢谢！

好像链表最后next 不是NULL

问题主要有两个： 1.ListInsert里的strncpy(s->hobby,c,sizeof(c)); 不能这样用，因为数组做实参传递，自动退化为指针 所以你sizeof(c)永远都是4，要改成strncpy(s->hobby,c,strlen(c) + 1); 不改的话可能会输出垃圾值，但崩溃的地方不在这 2.崩溃的地方在ListTraverse函数内，如果遍历到最后一个结点p=p->next直接崩 （因为你之前insert的时候没有将新插入结点的next指针置成NULL）所以访问p->next会报异常 所以要在之前的ListInsert函数内填上s->next=NULL; //我已经在代码里注释了  #include<stdio.h> #include<stdlib.h>  #include<string.h>  //所需状态语句 #define N 10  #define TURE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1   //infesible 不可实行的 #define OVERFLOW -2    //overflow 溢出  typedef int status; typedef int ElemType;   typedef struct Per  { 	char name[N]; 	status age; 	char hobby[N]; 	struct Per *next;   }per; typedef struct Per *LinkList;   status INitList(LinkList *L) { 	*L=(LinkList)malloc(sizeof(per)); 	if(!(*L)) 		return ERROR; 	(*L)->next=NULL; //因为 “先申请产生一个头结点” 其实就是建立一个带头结点的 空 单 	//链表，而一个带头结点的 空 单链表，其头结点也就是尾结点。因此，以后插入新结点（p） 	//就简单了：p->next = (*L)->next; (*L)->next = p;  //插入到表头 	return OK;  } int ListLength(LinkList L) { 	int i = 0; 	LinkList p = L->next;        /* p指向第一个结点 */ 	while (p) 	{ 		i++; 		p=p->next; 	}  	return i; } status ListInsert(LinkList *L,int i,ElemType e,char c[N],char h[N]) { 	/* 初始条件：单链表L已存在， 1<= i <= ListLength(L) */ 	/* 操作结果：在L中第i个位置之前插入新的数据元素e，L的长度加1 */ 	int j; 	LinkList s,p;  	p=*L; 	j=1; 	while(p&&j<i)   //p链表不为空成立  	{ 		p=p->next; 		j++;  	} 	if(!p||j>i) 		return ERROR;  	s=(LinkList)malloc(sizeof(per)); 	s->age=e;  	//strncpy(s->hobby,c,sizeof(c));   //s->hobby=*c;  	//strncpy(s->name,h,sizeof(h));    //s->name=*h;  	strncpy(s->hobby,c,strlen(c) + 1); 	strncpy(s->name,h,strlen(h) + 1);   	p->next=s; 	s->next=NULL; //这里要置成NULL！！！！！！！！！！！！！！！！！！！！！！！！！！！！！ 	return OK; 	 }  status visit(ElemType e,char c[N], char h[N]) { 	printf("%s        %s         %d",h,c,e); 	return OK;   }  status ListTraverse(LinkList L) { 	LinkList p=L->next; 	while(p) 	{ 		visit(p->age,p->name,p->hobby); 		p=p->next;  		printf("\n");  	}  	printf("是这里错了么？"); 	return OK;  } void main() { 	LinkList into;  	int i,k; 	int e; 	char c[N],h[N];  	printf("请问您统计了多少同学:"); 	scanf("%d",&i); 	getchar();  	status j; 	j= INitList(&into);  	for(k=1;k<=i;k++) 	{ 		scanf("%d",&e); 		scanf("%s",c); 		scanf("%s",h); 		j=ListInsert(&into,k,e,c,h);   	} 	ListTraverse(into);  	printf("验证是否为空：ListLength(L) = %d \n",ListLength(into)); }

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


Question: 菜鸟求助

else(judge_type[i]==2)这句不对，应该是else if(judge_type[i]==2)  #include<stdio.h> #include<string.h>  int cal_score(int score[],int judge_type[],int n) { 	int i,total_score; 	int e_sum=0; 	int p_sum=0; 	int e_num=0; 	int p_num=0; 	for(i=0;i<n;i++) 	{ 		if(judge_type[i]==1) 		{ 			e_sum+=score[i]; 			e_num++; 		} 		else if(judge_type[i]==2) 		{ 			p_sum+=score[i]; 			p_num++; 		} 	} 	if(p_num==0) 		total_score=e_sum/e_num; 	else 		total_score=(e_sum/e_num)*0.6+(p_sum/p_num)*0.4; 	printf("The score is:%d\n",total_score); }  int main() { 	int n=10; 	int score[10]={7,8,6,7,8,9,6,7,9,8.5}; 	int judge_type[10]={1,1,1,2,2,1,1,2,1,2}; 	cal_score( score,judge_type,n); }

嗯，明白了，感谢


Question: 一个递归问题

赵老师总是这么精妙

加else,putchar就会只在i <= 0时才执行, 否则无论i为几都会执行. return;不是必要的

不加else，任何时候均会执行putchar('0'+r);，否则仅在不满足if时执行 最后的return可以不需要

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


Question: 求一个md5的头文件，里面直接包含实现方法的那种

引用 7 楼 u012006886 的回复:你平时用的平台可以直接调用命令行吗，如果可以的话，直接用md5sum这个命令加上相关参数就可以获取到MD5值了 可以把头文件或dll文件放在项目里，然后调用里面的方法

直接使用Openssl里面的MD5加密，

引用 1 楼 paschen 的回复:http://blog.csdn.net/xhhjin/article/details/8450686 看不太懂，可以把md5.c里的代码直接放在md5.h里吗，而且最终调用的方法名和参数能简单介绍下吗

引用 3 楼 paschen 的回复:[quote=引用 2 楼 qq_25824067 的回复:] [quote=引用 1 楼 paschen 的回复:] http://blog.csdn.net/xhhjin/article/details/8450686 看不太懂，可以把md5.c里的代码直接放在md5.h里吗，而且最终调用的方法名和参数能简单介绍下吗[/quote]  网上很多讲解的，如果再不会你可以直接使用微软提供的API：Crypt开头系列的，可以实现MD5的加密[/quote] 我是放在loadrunner里使用的……

再供参考：#include <stdio.h> #include <math.h> #include <string.h> #include <memory.h> const unsigned int s[4][4]={{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}}; const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));  0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,  0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,  0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,  0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,  0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,  0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,  0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,  0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; const int serial[64]={  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,  1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,  5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,  0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 }; void func(unsigned long& a,           unsigned long b,           unsigned long c,           unsigned long d,           unsigned long M,           unsigned long t,           int s,           int turn) {     unsigned long temp;     switch(turn) {     case 0:         temp=(b&c)|((~b)&d);         break;     case 1:         temp=(d&b)|((~d)&c);         break;     case 2:         temp=b^c^d;         break;     case 3:         temp=c^(b|(~d));         break;     }     temp+=M+t+a;     _asm {         mov ecx,s         rol temp,cl     }     a=b+temp; } void MD512(const unsigned long M[16],unsigned long hash[4]) {     int i,j,index=0;     for (i=0;i<4;i++)         for (j=0;j<4;j++) {             func(hash[0],hash[1],hash[2],hash[3],M[serial[index]],t[index],s[i][0],i);             index++;             func(hash[3],hash[0],hash[1],hash[2],M[serial[index]],t[index],s[i][1],i);             index++;             func(hash[2],hash[3],hash[0],hash[1],M[serial[index]],t[index],s[i][2],i);             index++;             func(hash[1],hash[2],hash[3],hash[0],M[serial[index]],t[index],s[i][3],i);             index++;         } }  void MD5(char* M,int nLen,unsigned long output[4]) {     int i,j;     unsigned long Hash[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};     unsigned long hash[4];      //填充     __int64 BitsLen=nLen*8;     int oldlen=nLen;     while(nLen%64!=56) {         M[nLen++]=0;     }     M[oldlen]=0x80u;     *(__int64*)(M+nLen)=BitsLen;     nLen+=8;      //开始处理分组     for (i=0;i<nLen;i+=64) {         memcpy(hash,Hash,sizeof(long)*4);         MD512((const unsigned long*)&M[i],hash);//处理512bits分组         for (j=0;j<4;j++)             Hash[j]+=hash[j];     }      //处理输出。     for (i=0;i<4;i++)         for (j=3;j>=0;j--) {             *((char*)(output+i)+j)=*((char*)(Hash+i)+3-j);         } } int main() {     int i;     char szMessage[1000]={0};     printf("input a string:\n>>>");     scanf("%s",szMessage);     unsigned long output[4];     MD5(szMessage,strlen(szMessage),output);     for (i=0;i<4;i++)         printf("%08lx",output[i]);     printf("\n");     return 0; }

仅供参考：#pragma comment(lib,"advapi32") #include <windows.h> #include <wincrypt.h> #include <stdio.h> #include <string.h> int main() {     int L;     HCRYPTPROV hProv = 0;     HCRYPTHASH hHash = 0;     BYTE *pbHash = NULL;     DWORD dwHashLen;     #define BUFFER_SIZE 256     BYTE pbBuffer[BUFFER_SIZE];     DWORD dwCount;     DWORD i;      if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {//Get a handle to the default provider.         printf("Error %x during CryptAcquireContext!\n", GetLastError());         goto done;     }     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {//Create a hash object.         printf("Error %x during CryptBeginHash!\n", GetLastError());         goto done;     }     printf("Input a string:");fflush(stdout);     fgets((char *)pbBuffer,BUFFER_SIZE,stdin);     L=strlen((char *)pbBuffer);     if ('\n'==pbBuffer[L-1]) {pbBuffer[L-1]=0;L--;}     if(!CryptHashData(hHash, pbBuffer, L, 0)) {//Put the hash in buffer.         printf("Error %x during CryptHashData!\n", GetLastError());         goto done;     }     dwCount = sizeof(DWORD);     if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&dwHashLen,&dwCount, 0)) {//Read the hash value size and allocate memory.         printf("Error %x during reading hash size!\n", GetLastError());         goto done;     }     if((pbHash = (BYTE *)malloc(dwHashLen)) == NULL) {         printf("Out of memory!\n");         goto done;     }     if(!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) {//Read the hash value.         printf("Error %x during reading hash value!\n", GetLastError());         goto done;     }     for(i = 0 ; i < dwHashLen ; i++) {//Print the hash value.         printf("%02x",pbHash[i]);     }     printf("\n"); done:     if (pbHash) free(pbHash);//Free memory.     if(hHash) CryptDestroyHash(hHash);//Destroy the hash object.     if(hProv) CryptReleaseContext(hProv,0);//Release the CSP handle.     return 0; } //Input a string:abc //900150983cd24fb0d6963f7d28e17f72 //

引用 2 楼 qq_25824067 的回复:[quote=引用 1 楼 paschen 的回复:] http://blog.csdn.net/xhhjin/article/details/8450686 看不太懂，可以把md5.c里的代码直接放在md5.h里吗，而且最终调用的方法名和参数能简单介绍下吗[/quote]  网上很多讲解的，如果再不会你可以直接使用微软提供的API：Crypt开头系列的，可以实现MD5的加密


Question: 本人是小白，自己对着视频编了一个贪吃蛇能编译但是运行出错，求大神帮忙修改一下代码

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

在哪里出问题 找到相应的代码 打断点看


Question: 设计一个云台控制程序，每输入一个值就执行，而不需要用回车结束

Linux下可能要使用NCURSES库。

getche

我是linux开发的，稍微改了下就能用了！真的谢谢您！但是还有个小问题，getch怎么不回显输入，我想显示出当前控制，比如键入1后就显示出字符“上”，我用printf怎么好多报错，您会怎么写？

仅供参考：#include <conio.h> #include <windows.h>  void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } void 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);    } } void GetWH(int *w,int *h) {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         *w=csbi.srWindow.Right;         *h=csbi.srWindow.Bottom;     } else {         *w=80;         *h=25;     } } void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  int main() {     unsigned short k;     int x,y,w,h;      SetConsoleOutputCP(437);     ClearConsole();     GetWH(&w,&h);     x=w/2;y=h/2;     HideTheCursor();     ConPrintAt(x,y,"\xdb",1);     while (1) {         Sleep(50);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         switch (k) {             case 0x48e0:case 0x04800://上                 if (y>0) {                     ConPrintAt(x,y," ",1);                     y--;                     ConPrintAt(x,y,"\xdb",1);                 }             break;             case 0x50e0:case 0x05000://下                 if (y<h) {                     ConPrintAt(x,y," ",1);                     y++;                     ConPrintAt(x,y,"\xdb",1);                 }             break;             case 0x4be0:case 0x04b00://左                 if (x>0) {                     ConPrintAt(x,y," ",1);                     x--;                     ConPrintAt(x,y,"\xdb",1);                 }             break;             case 0x4de0:case 0x04d00://右                 if (x<w-1) {                     ConPrintAt(x,y," ",1);                     x++;                     ConPrintAt(x,y,"\xdb",1);                 }             break;         } //      cprintf("%04x pressed.\r\n",k);      }     ClearConsole();     ShowTheCursor();     return 0; }

能具体给个实例吗，结合switch语句，具体该怎么写呢，我自己试了几次都不合适，摁了数字但是不执行动作。。。

getch 。。

#include <windows.h> #include <conio.h> //...     while (1) {         Sleep(50);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         switch (k) {         case '0':       //停止            break;         case '1':       //向上            a[3]=0x08; break;         case '2':       //向下            a[3]=0x10; break;         }         // printf("%04x pressed.\r\n",k);     }

您这个写的好复杂，看不大懂，能不能在我的这个代码基础上


Question: curl 使用的疑惑 回调接口 数据为空

仅供参考：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }


Question: turbo c 项目编译提示未定义符号

TC有几种配置，分别对应不同模式 tiny ,small .... 每种模式需要一个对应的初始化代码模块，如果你的初始化代码没编译出来，可以调用 bld 编译一下

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

实现方法找不到，要连接库一起编译

现在还用Turbo C，建议直接用VS上手！

几个C文件都加入项目了吗？ 不过现在除了学习老代码，不推荐用TC了，至少也要用VC6

还是不明白，那单一文件编译的环境设置没有改变，怎么用项目编译就找不到库文件。那要怎么设置呢，或者如何处理？谢谢指点！

有头文件，没有链接对应的库


Question: 定义了全局变量，在input中list不为空，为什么print中list为空

改为如下可以得出结果：  #include<iostream> #include<stdio.h> using namespace std; #define N 4 struct node{     int score;     struct node*link; }; struct node node; struct node*list,*p,*r,*q; void input() {     int i;     int ch;     list = NULL;     for(i=0;i < N; i++)     {         p=(struct node*)malloc(sizeof(struct node));         printf("please input the score of %d\t",i+1);         scanf("%d",&p->score);         p->link=NULL;         if(list==NULL)             list=p;         else             r->link=p;         r=p;         printf("数据为%d",p->score);     } } void average() {     int s=0,i;     double average2;      if(list==NULL)         printf("链表为空");     for(i=0;i < N; i++)     {         s+=list->score;         list=list->link;     }     average2=(double)s/N;     printf("平均值为:%lf\n",average2); } void print() {     int i;     printf("顺利进入\n");     if(list==NULL)         printf("这是空链表");     else     {         q=list;         while(q!=NULL)//这里只需要判断q就行         {             printf("%d\n",q->score);             q=q->link;         }     }} int main() {     void input();     void average();     void print();     int ah;     system("cls");     while(1){         printf("链表操作系统:");         printf("\n1.建立链表\n2.输出数据\n3.求平均数\n");         scanf("%d",&ah);         switch(ah){         case 1:input();break;         case 2:print();break;         case 3:average();break;         default:printf("wrong!");break;         }     } }  有几个问题： 1.既然list指针已经变成全局的了，就不要传参了，楼主那样传一级指针是没有用的，操作的都是list的一个副本，所以就算插入的代码没错，也会输出是空链表（传二级指针可以解决） 2.输出的函数里while循环只要判断while(q!=NULL)就行了

//申请的是指针的空间 p=(struct node*)malloc(sizeof(struct node*)); //应该申请结构体的空间 p=(struct node*)malloc(sizeof(struct node));


Question: 我是C语言菜鸟，这是一个跟整型、字符型相关的基础问题……

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }  #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.

建议楼主看下c库函数，基本的还是要知道的

case 'd':     break; case 'x':     break;

控制台输入的都是ASCII码，包括输入的数字其实也是ASCII码，然后根据scanf中的%d再转化为整型 如果你输入格式是%d，但你输入的不是一串'0'~'9'的字符，那么就会转换失败，所以a的值没有变 建议深入了解一下scanf的原理

if (1 == scanf( "%d", &a )) { //a成功赋值。 }


Question: 该C程序，显示结果为什么为0？？

不知道怎么针对每一楼的回复进行相应的回复。再次统一感谢！ 对于一楼所说：其实调试过程已经单步追踪过了，因为不细心愣是没发现数据类型不匹配的问题。。。不过还是谢谢您的回答。 如二楼、三楼，进行了改正，再此不胜感激。谢谢！

printf("i=%f\n",i); printf("j=%f\n",j);

%d 改成 %.0f

为何不单步跟踪程序运行，观察每一步变量的值的变化情况，然后分析出原因