Question: c语言多线程的问题，请高手指教

代码里面的注释是乱码，由于用的vc++6.0日文版的，所以中文注释是乱码。但是代码执行是没有问题的

问题描述不清楚，你的代码是乱码。。

谢谢老师的指导，现在正在研究老师上传的程序。 另外我已开始提的问题的,如添付的图片那样设定的话，输出的结果就正确。 选定“不使用MFC类库”的话，输出的结果就跟开始发的帖子那样不正确。 原因不清楚

任何收发两端速度不一致的通讯，都需要在它们之间使用一个足够大的FIFO缓冲区。 对任何FIFO缓冲区的使用，都需要仔细考虑接收端接收时超时无数据和发送端发送时FIFO缓冲区已满这两种情况下该如何做。 这些概念都在这段经典代码中有所体现。 这段经典代码还包括以下必须考虑的因素： ◆跨Windows和Linux平台 ◆多线程锁 ◆多线程日志 ◆日志文件占用的磁盘空间可控 ◆日志中的时间包括毫秒 ◆传输的数据对应的每个字节到底是几 ◆如何退出多线程程序 ◆……

老师发的程序是什么意识，跟我的提问有什么关系，能否说明一下啊

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


Question: 数字图像处理中的相关是用的哪种

matlab opencv ？

引用 1 楼 zhao4zhong1 的回复:我《高等数学》里面的知识都还给大学老师了。  高等数学太简单了，这个相关有两种定义的原因找不到啊，看了看，国外普遍用的是第一种，国内好像基本是第二种

我《高等数学》里面的知识都还给大学老师了。


Question: Postgresql的C语言libpq接口PQexecParams函数

谢谢，正在看pg的动态sql

搜“动态SQL”


Question: 修改bin文件

引用 楼主 wtb1027 的回复:有一个设备的配置bin文件，我修改了里面的标识段，保存后，但是文件打开就报错了。有那位老师可以帮修改一下吗？ 用什么编辑器修改的？ 有的编辑器修改bin文件，在保存一些数值型的内容会被破坏掉。 最好是使用16进制编辑器修改。 如同赵老师说的，修改的时候，最好保持修改标识段的长度不变。

保持修改后长度不变再试试


Question: 自学指针，做图，看我的理解是否正确。

正确。 其它程序的地址不会和自己一起编址，可以看看分段和分页。不过和这指针不是一回事，理解没问题

地址通常不会是那样，其他应该没问题

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

引用 2 楼 user-5 的回复:告诉楼主一个小知识，字符指针可以引用字符串， char *p ="dhhshwj", p是字符串的首地址！  谢谢。如此就只能通过指针p找到这段字符串。可心里难受，觉得任何一段数据都应当既有普通变量又有指针变量。

正确的。  不是实际程序中地址不会从0x0000开始，数据是放在程序的数据区里面的。


Question: 基于ffmpeg的流解码报错

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

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

引用 1 楼 zhao4zhong1 的回复:可能不对。我猜。   那我也不知道为什么报错了

那我也不知道为什么了

可能不对。我猜。


Question: 运行结果不对

因为你用的是while(100-x-y>0) 第一次循环的时候就满足，然后在while循环里既没有修改x,y的值，也没有break所以陷入了死循环 你这个应该用if就行了吧？  #include<iostream> using namespace std; int main(){ 	int x, y; 	for (x = 0; x < 100; x++){ 		for (y = 0; y<50; y++){ 			if (100 - x - y>0){ 				if (0.5*x + 2 * y + 3 * (100 - x - y) == 100){ 					cout << x << " " << y << " " << 100 - x - y << endl; 				} 			} 		}  	} 	return 0; }


Question: 请教一个scanf语句的问题？

就是判断是否输入了两个数据，scanf返回输入数据的个数

就是判断是否成功读入两个数据

scanf返回的是正确输入参数的个数，这里判断是否为2，因为你是接收两个参数  http://en.cppreference.com/w/c/io/fscanf  Return value 1-3) Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned. 4-6) Same as (1-3), except that EOF is also returned if there is a runtime constraint violation.

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

1. scanf 函数是有返回值的，它的返回值可以分成三种情况   1) 正整数，表示正确输入参数的个数。例如执行 scanf("%d %d", &a, &b);        如果用户输入"3 4"，可以正确输入，返回2（正确输入了两个变量）；       如果用户输入"3,4"，可以正确输入a，无法输入b，返回1（正确输入了一个变量）。       2) 0，表示用户的输入不匹配，无法正确输入任何值。如上例，用户如果输入",3 4"，返回0。   3) EOF，这是在stdio.h里面定义的常量（通常值为-1），表示输入流已经结束。在Windows下，用户按下CTRL+Z（会看到一个^Z字符）再按下回车（可能需要重复2次），就表示输入结束；Linux/Unix下使用CTRL+D表示输入结束。

int imin(int n,int m); int main() {  int evil1,       evil2;  printf("Enter a pair of integers(q to quit):\n)");  while(scanf("%d%d",&evil1,&evil2)==2)  {   printf("The lesser of %d and %d is %d.\n",evil1,evil2,imin(evil1,evil2));   printf("Enter a pair of integers(q to quit):\n)");  }  printf("Bye.\n");    return 0;     // 提问区域可用时间    alog && alog('speed.set', 'c_ask', +new Date); alog.fire && alog.fire("mark");        F.context('answers')['1190817758'] = {uid:"734719339",imId:"6bed6c6f7665536c696d6c6565ca2b",isBest:"1",id:"1190817758",userName:"loveSlimlee",userNameEnc:"loveSlimlee",user:{sex:"1",iconType:"6",gradeIndex:"2",grAnswerNum:"3",carefield: [{cid:"866",cname:"C/C++"}],isAuth:"0",authTitle:"",isUserAdmin:"0",userAdminLevel:"",userAdminTitle:"",userAdminType:"",isFamous:"0",isMaster:"0",goodRate:"60",applyExcType:"0"},isAnonymous:"0",isCurrentUser:"0",mapUrl:"",refer:"",replyAskNum:"",threadId:"4763271033",hasComment:"0",qid:"476406884",raid:"",recommendCanceled:"0"};                	F.context('relateWords')['best-content-'+'1190817758'] = ["\u51fd\u6570\u539f\u578b","\u503c\u7c7b\u578b"];              2012-09-13 11:23 提问者采纳    scanf这个函数式有返回值的，函数原型为int scanf( const char *format, ... );可见其返回值类型为int类型的，返回值得含义是你成功读入数据的个数。具体到你的问题中就是，当你成功输入两个数字的时候，循环继续，当你输入的数字小于两个的时候就会跳出循环。多谢采纳。

scanf返回正确输入的参数个数，scanf("%d%d", &a, &b)在正常输入时返回2；若只输入一个整数，尝试输入第二个整数时遇到EOF（例如文件结尾），则返回1。程序输入失败返回EOF。建议使用while(EOF != scanf("%d%d", &a, &b))判断是否输入成功。

int n,m,a,b; a=scanf（“%d %d”，&n，&m）；//你只输入n的值，不给m值 b=scanf（“%d %d”，&n，&m）；//给m，n都赋值 printf（“%d %d”，a,b）； 看看结果就好了。

在每个最后不带\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: Return value     Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned.


Question: 为什么这个自动代码格式化出来的效果怪怪的呢？

可能他这功能实现的问题，你自己按退格吧...

astyle自动整理c,c++,java源代码格式命令行工具源代码。 用astyle --help查看使用帮助。 http://download.csdn.net/detail/zhao4zhong1/5605415


Question: 使用wpritf输出中文

可惜windows下和linux下的wprintf不完全兼容。

printf, wprintf Print formatted output to the standard output stream.  int printf( const char *format [, argument]... );  int wprintf( const wchar_t *format [, argument]... );  Routine Required Header Compatibility  printf <stdio.h> ANSI, Win 95, Win NT  wprintf <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns the number of characters printed, or a negative value if an error occurs.  Parameters  format  Format control  argument  Optional arguments  Remarks  The printf function formats and prints a series of characters and values to the standard output stream, stdout. If arguments follow the format string, the format string must contain specifications that determine the output format for the arguments. printf and fprintf behave identically except that printf writes output to stdout rather than to a destination of type FILE.  wprintf is a wide-character version of printf; format is a wide-character string. wprintf and printf behave identically otherwise.   Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tprintf printf printf wprintf    The format argument consists of ordinary characters, escape sequences, and (if arguments follow format) format specifications. The ordinary characters and escape sequences are copied to stdout in order of their appearance. For example, the line  printf("Line one\n\t\tLine two\n");   produces the output  Line one         Line two  Format specifications always begin with a percent sign (%) and are read left to right. When printf encounters the first format specification (if any), it converts the value of the first argument after format and outputs it accordingly. The second format specification causes the second argument to be converted and output, and so on. If there are more arguments than there are format specifications, the extra arguments are ignored. The results are undefined if there are not enough arguments for all the format specifications.  Example  /* PRINTF.C: This program uses the printf and wprintf functions  * to produce formatted output.  */  #include <stdio.h>  void main( void ) {    char   ch = 'h', *string = "computer";    int    count = -9234;    double fp = 251.7366;    wchar_t wch = L'w', *wstring = L"Unicode";     /* Display integers. */    printf( "Integer formats:\n"            "\tDecimal: %d  Justified: %.6d  Unsigned: %u\n",            count, count, count, count );     printf( "Decimal %d as:\n\tHex: %Xh  C hex: 0x%x  Octal: %o\n",             count, count, count, count );     /* Display in different radixes. */    printf( "Digits 10 equal:\n\tHex: %i  Octal: %i  Decimal: %i\n",             0x10, 010, 10 );     /* Display characters. */     printf("Characters in field (1):\n%10c%5hc%5C%5lc\n", ch, ch, wch, wch);    wprintf(L"Characters in field (2):\n%10C%5hc%5c%5lc\n", ch, ch, wch, wch);     /* Display strings. */     printf("Strings in field (1):\n%25s\n%25.4hs\n\t%S%25.3ls\n",    string, string, wstring, wstring);    wprintf(L"Strings in field (2):\n%25S\n%25.4hs\n\t%s%25.3ls\n",        string, string, wstring, wstring);     /* Display real numbers. */    printf( "Real numbers:\n\t%f %.2f %e %E\n", fp, fp, fp, fp );     /* Display pointer. */    printf( "\nAddress as:\t%p\n", &count);     /* Count characters printed. */    printf( "\nDisplay to here:\n" );    printf( "1234567890123456%n78901234567890\n", &count );    printf( "\tNumber displayed: %d\n\n", count ); }   Output  Integer formats:    Decimal: -9234  Justified: -009234  Unsigned: 4294958062 Decimal -9234 as:    Hex: FFFFDBEEh  C hex: 0xffffdbee  Octal: 37777755756 Digits 10 equal:    Hex: 16  Octal: 8  Decimal: 10 Characters in field (1):          h    h    w    w Characters in field (2):          h    h    w    w Strings in field (1):                  computer                      comp    Unicode                      Uni Strings in field (2):                  computer                      comp    Unicode                      Uni Real numbers:    251.736600 251.74 2.517366e+002 2.517366E+002  Address as:   0012FFAC  Display to here: 123456789012345678901234567890    Number displayed: 16   Floating-Point Support Routines |  Stream I/O Routines |  Locale Routines  See Also   fopen, fprintf, scanf, sprintf, vprintf Functions  s String  When used with printf functions, specifies a single-byte–character string; when used with wprintf functions, specifies a wide-character string. Characters are printed up to the first null character or until the precision value is reached.  S String When used with printf functions, specifies a wide-character string; when used with wprintf functions, specifies a single-byte–character string. Characters are printed up to the first null character or until the precision value is reached.

WPRINTF Section: Linux Programmer's Manual (3 ) Updated: 1999-11-20  --------------------------------------------------------------------------------    NAME wprintf, fwprintf, swprintf, vwprintf, vfwprintf, vswprintf - formatted wide character output conversion    SYNOPSIS #include <stdio.h> #include <wchar.h>  int wprintf(const wchar_t *format, ...); int fwprintf(FILE *stream, const wchar_t *format, ...); int swprintf(wchar_t *wcs, size_t maxlen,               const wchar_t *format, ...);  #include <stdarg.h>  int vwprintf(const wchar_t *format, va_list args); int vfwprintf(FILE *stream, const wchar_t *format, va_list args); int vswprintf(wchar_t *wcs, size_t maxlen,                const wchar_t *format, va_list args);     DESCRIPTION The wprintf family of functions is the wide-character equivalent of the printf family of functions. It performs formatted output of wide characters.  The wprintf and vwprintf functions perform wide character output to stdout. stdout must not be byte oriented; see function fwide for more information.   The fwprintf and vfwprintf functions perform wide character output to stream. stream must not be byte oriented; see function fwide for more information.   The swprintf and vswprintf functions perform wide character output to an array of wide characters. The programmer must ensure that there is room for at least maxlen wide characters at wcs.   These functions are like the printf, vprintf, fprintf, vfprintf, sprintf, vsprintf functions except for the following differences:   *  The format string is a wide character string.  *  The output consists of wide characters, not bytes.  *  swprintf and vswprintf take a maxlen argument, sprintf and vsprintf do not. (snprintf and vsnprintf take a maxlen argument, but these functions do not return -1 upon buffer overflow on Linux.)  The treatment of the conversion characters c and s is different:   c  If no l modifier is present, the int argument is converted to a wide character by a call to the btowc function, and the resulting wide character is written. If an l modifier is present, the wint_t (wide character) argument is written.  s  If no l modifier is present: The ``const char *'' argument is expected to be a pointer to an array of character type (pointer to a string) containing a multibyte character sequence beginning in the initial shift state. Characters from the array are converted to wide characters (each by a call to the mbrtowc function with a conversion state starting in the initial state before the first byte). The resulting wide characters are written up to (but not including) the terminating null wide character. If a precision is specified, no more wide characters than the number specified are written. Note that the precision determines the number of wide characters written, not the number of bytes or screen positions. The array must contain a terminating null byte, unless a precision is given and it is so small that the number of converted wide characters reaches it before the end of the array is reached. -- If an l modifier is present: The ``const wchar_t *'' argument is expected to be a pointer to an array of wide characters. Wide characters from the array are written up to (but not including) a terminating null wide character. If a precision is specified, no more than the number specified are written. The array must contain a terminating null wide character, unless a precision is given and it is smaller than or equal to the number of wide characters in the array.     RETURN VALUE The functions return the number of wide characters written, excluding the terminating null wide character in case of the functions swprintf and vswprintf. They return -1 when an error occurs.    CONFORMING TO ISO/ANSI C, UNIX98    SEE ALSO fprintf(3), fputwc(3), fwide(3), printf(3), snprintf(3), wscanf(3)    NOTES The behaviour of wprintf et al. depends on the LC_CTYPE category of the current locale.  If the format string contains non-ASCII wide characters, the program will only work correctly if the LC_CTYPE category of the current locale at run time is the same as the LC_CTYPE category of the current locale at compile time. This is because the wchar_t representation is platform and locale dependent. (The GNU libc represents wide characters using their Unicode (ISO-10646) code point, but other platforms don't do this. Also, the use of ISO C99 universal character names of the form \unnnn does not solve this problem.) Therefore, in internationalized programs, the format string should consist of ASCII wide characters only, or should be constructed at run time in an internationalized way (e.g. using gettext or iconv, followed by mbstowcs).   --------------------------------------------------------------------------------

引用 2 楼 K346K346 的回复:[quote=引用 楼主 K346K346 的回复:] 为何我的如下代码输出为空？ setlocale(LC_ALL,"chs"); wchar_t wtest[]=L"测试Test"; wprintf(L"%s\n",wtest);  运行环境：Linux，g++ 4.4.6wprintf是C标准库函数！[/quote] 差不多就这个意思。将代码换成如下内容就可以了： setlocale(LC_ALL,"zh_CN.UTF-8"); wchar_t wtest[]=L"0m~K0m~UTest"; printf("%ls\n",wtest); #或者 printf("%S\n",wtest); 这里需要指明的是代码中字符串的编码方式是UTF-8。

%ls替换%s。 %s还是按字节去读；sizeof(wchar_t) == 4，“测”的wchar_t内存为4b 6d 0 0，4b(K)，6d(m)，所以打印Km

引用 楼主 K346K346 的回复:为何我的如下代码输出为空？ setlocale(LC_ALL,"chs"); wchar_t wtest[]=L"测试Test"; wprintf(L"%s\n",wtest);  运行环境：Linux，g++ 4.4.6wprintf是C标准库函数！

wprintf是不是windows的东东？


Question: hbase启动报错


Question: zookeeper启动后不能连接，错误信息如下

原因为zookeeper配置中的文件myid错误，myid的顺序参照zoo.cfg配置文件，要确保两者一致


Question: 小问题，很困惑

地址就是一个位置 数据地址，是代表数据在内存位置的一种表示方法。通常用1个或者若干个整数表示。 地址和指针的关系是，地址本身是不牵扯这块内存内部数据类型的 指针是跟它指向的，这块内存里面的数据的类型，相关的，一种数据，是有类型的。 &取到的地址，本质上是一种指针数据， 虽然 &通常称之为，取址运算符，但是实际得到的结果，是一个指针。 这种附加了（内存中存储的）数据类型信息的地址，就是指针。  数组a 的名字 a， 作为表达式， 在 &a 中， a 直接表示数组本身， &a 数组的地址 &a[0] 是 a[0] 的地址  在表达式中 a， 单独出现的时候，通常解析为指针即 &a[0]; 因为 C，C++中，数组类型， 不能进行直接的读写（不能直接赋值）， 所以只能借助指针进行，操作。 所以早期的C语言，就直接用数组名 a， 表示数组第一个元素的地址了 至于后来的标准，和解释只是完善了一些概念。 对数组的定位，更加清晰了而已。 。。。。。。。。。。。。。。 实际上汇编语言中，变量只是对应一个地址 变量名常常作为地址（指针）使用。 不论是否数组，都可以。 。。。。。。。。。。。。。。。。。。。。。。 高级语言中，尤其是C，C++中， 只有数组，还保持数组名，可以当作地址（指针）使用的做法。 变量名，通常就表示变量的值。  变量地址（指向该变量的指针）， 就加个 & 来表示。  这样 变量和数组就产生了某种程度的不一致。 这就是 很多时候，提到数组，偏偏说是数组名的原因。 提到变量，就不说变量名了

mark，很收益，谢谢。

引用 7 楼 NotSimpleEasy 的回复:[quote=引用 5 楼 ipqtjmqj 的回复:] [quote=引用 4 楼 ipqtjmqj 的回复:] 第1个在传参时自动转成第3个了， 第2个与第3个的区别，好比你在一辆火车的车头，火车离目的地的距离，等于，你离目的地的距离 注意，我说的第1个第2个第3个是你在代码外的这三句，而不是代码里面的 printf("%x,\n",a); printf("%x,\n",&a); printf("%x,\n",&a[0]); [/quote]    你的意思是a和a[0]是一样的？还是他两个加了取地址符就一样了。。我只能理解为a是1的地址，a[0]是1，他们两个同时取地址肯定是不一样的啊。。[/quote]  已经说了，是取址后值一样，但类型是不同的，所以是不能说是一样

引用 24 楼 zhao4zhong1 的回复:http://edu.csdn.net/course/detail/2455/38534  我必认真学习，，，，，

http://edu.csdn.net/course/detail/2516 http://edu.csdn.net/course/detail/2517

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

引用 21 楼 ipqtjmqj 的回复:[quote=引用 19 楼 NotSimpleEasy 的回复:] [quote=引用 18 楼 ipqtjmqj 的回复:] [quote=引用 17 楼 NotSimpleEasy 的回复:] [quote=引用 16 楼 ipqtjmqj 的回复:] [quote=引用 8 楼 qq423399099 的回复:] 值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）[/quote] 不知道我这个问题怎么解释。。我蒙了。。[/quote] 你写个程序sizeof(a)返回20，就可以确认数组名代表的是整个数组，而不是什么地址[/quote]  那输出a和输出&a一样么？搞得我好晕。。[/quote] 传入a相当于传了&a[0],我前面说过了，这是隐式转换，因为传参是复制，数组天然的空间复杂度是O(n), 所以规定自动改传第1个元素的地址了。 &a[0]与&a的值一样，好比，你海拔1米8，那么你的头发海拔也是1米8[/quote] 多谢耐心讲解，我理解理解。。

引用 19 楼 NotSimpleEasy 的回复:[quote=引用 18 楼 ipqtjmqj 的回复:] [quote=引用 17 楼 NotSimpleEasy 的回复:] [quote=引用 16 楼 ipqtjmqj 的回复:] [quote=引用 8 楼 qq423399099 的回复:] 值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）[/quote] 不知道我这个问题怎么解释。。我蒙了。。[/quote] 你写个程序sizeof(a)返回20，就可以确认数组名代表的是整个数组，而不是什么地址[/quote]  那输出a和输出&a一样么？搞得我好晕。。[/quote] 传入a相当于传了&a[0],我前面说过了，这是隐式转换，因为传参是复制，数组天然的空间复杂度是O(n), 所以规定自动改传第1个元素的地址了。 &a[0]与&a的值一样，好比，你海拔1米8，那么你的头发海拔也是1米8

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

引用 18 楼 ipqtjmqj 的回复:[quote=引用 17 楼 NotSimpleEasy 的回复:] [quote=引用 16 楼 ipqtjmqj 的回复:] [quote=引用 8 楼 qq423399099 的回复:] 值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）[/quote] 不知道我这个问题怎么解释。。我蒙了。。[/quote] 你写个程序sizeof(a)返回20，就可以确认数组名代表的是整个数组，而不是什么地址[/quote]  那输出a和输出&a一样么？搞得我好晕。。

引用 17 楼 NotSimpleEasy 的回复:[quote=引用 16 楼 ipqtjmqj 的回复:] [quote=引用 8 楼 qq423399099 的回复:] 值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）[/quote] 不知道我这个问题怎么解释。。我蒙了。。[/quote] 你写个程序sizeof(a)返回20，就可以确认数组名代表的是整个数组，而不是什么地址

引用 16 楼 ipqtjmqj 的回复:[quote=引用 8 楼 qq423399099 的回复:] 值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）[/quote] 不知道我这个问题怎么解释。。我蒙了。。

引用 8 楼 qq423399099 的回复:值是一样的，但性质以及含义是不同的。 数组名代表数组中第一个元素的地址，数组名取地址代表整个数组的地址。 不要误导别人，数组名代表的当然是数组本身了，你sizeof(a),返回的是20。 只是数组的地址与数组第1个元素的地址一样罢了，以及数组传参时会隐式转换（为了效率）

引用 14 楼 ipqtjmqj 的回复:[quote=引用 11 楼 ipqtjmqj 的回复:] a与a[0]地址一样，值不一样,也就是你说的加了取地址符就一样了 在你的例子中，a的值00,00,00,01,00,00,00,02,00,00,00,03,00,00,00,04,00,00,00,05 a[0]的值是00,00,00,01(16进制，逗号分隔每个字节) 失误，int一般是小端，所以a的值是01,00,00,00,02,00,00,00,03,00,00,00,04,00,00,00,05,00,00,00  a[0]的值是01,00,00,00[/quote]

引用 11 楼 ipqtjmqj 的回复:a与a[0]地址一样，值不一样,也就是你说的加了取地址符就一样了 在你的例子中，a的值00,00,00,01,00,00,00,02,00,00,00,03,00,00,00,04,00,00,00,05 a[0]的值是00,00,00,01(16进制，逗号分隔每个字节) 失误，int一般是小端，所以a的值是01,00,00,00,02,00,00,00,03,00,00,00,04,00,00,00,05,00,00,00  a[0]的值是01,00,00,00

是不是一样，编译器已经给你答案了。 你打印一下他们+1以后的地址，你就看出区别来了。（代表的含义不同）


Question: 为什么一直提示函数声明有问题啊，刚学

int rec=(n2+add(n1+n2));// add函数声明的是两个参数，这里却只传入了n1+n2这一个参数。  改成int rec=(n2+add(n1,n2));

建议你详细看一下函数的参数，和返回值！

你在函数里面，递归调用的时候add只有一个参数 n1+n2是一个参数，还有你打印res，但是你之前定义了它，并没有初始化，这样程序会崩溃，


Question: 更换phy芯片有rgmii环卫rmii内核和dts需要修改的地方

stm32  ?


Question: 程序的一个BUG


Question: 请教一下C问题,为什么形参是一个指向指针的指针,传一个指向int的指针实参进去也编译通过的???

引用 13 楼 wjm9ooy9 的回复:[quote=引用 10 楼 qq423399099 的回复:] 一级指针只能修改指针所指区域的值，而无法修改指针本身的指向。 下面的代码不算修改了吗 #include <stdio.h> void testa(int *); int main(void) { 	int pa = 5; 	testa(&pa); 	return 0; } void testa(int * pc) { 	int pb = 8; 	printf("%d",*pc);   //输出了5,指向pa的地址 	pc  = &pb;  	printf("%d",*pc);   //输出了8,指向pb的地址 } [/quote]才发现原来这里没有修改传入的pa的指向,只是修改了pc的指针的指向,结贴了

引用 2 楼 wjm9ooy9 的回复:引用 1 楼 akirya 的回复:&end 就是 char**类型啊是啊,不过函数为什么要声明成指向指针的指针类型char **啊,我以后遇到类似的自定义函数是不是可以只声明char * aa这样吗,这也是指针类型啊,功能上无变化啊  strtol 第二个参数传出一个指针的值，所需需要指针的指针。

使用二级指针当参数，就可以在函数里修改指针的指向

水有很多种： 污水 自来水 蒸馏水 矿泉水 重水 忘情水 净瓶水 …… http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E6%B0%B4&oq=%E6%B0%B4&rsp=-1

引用 10 楼 qq423399099 的回复:一级指针只能修改指针所指区域的值，而无法修改指针本身的指向。 下面的代码不算修改了吗 #include <stdio.h> void testa(int *); int main(void) { 	int pa = 5; 	testa(&pa); 	return 0; } void testa(int * pc) { 	int pb = 8; 	printf("%d",*pc);   //输出了5,指向pa的地址 	pc  = &pb;  	printf("%d",*pc);   //输出了8,指向pb的地址 }

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

一级指针只能修改指针所指区域的值，而无法修改指针本身的指向。

引用 6 楼 paschen 的回复:你没有使用end，只是取end的地址而已的确是这样,到函数返回值得时候才使用,在函数内部有赋值了

引用 5 楼 akirya 的回复:引用 2 楼 wjm9ooy9 的回复:[quote=引用 1 楼 akirya 的回复:] &end 就是 char**类型啊是啊,不过函数为什么要声明成指向指针的指针类型char **啊,我以后遇到类似的自定义函数是不是可以只声明char * aa这样吗,这也是指针类型啊,功能上无变化啊  strtol 第二个参数传出一个指针的值，所需需要指针的指针。 [/quote]我搞糊涂了,其实好简单,就是那个strtol函数内部是返回了一个指向指针的指针,所以需要形参写成char**类型了,是这样吗,如果是的话就不纠结了,后面还有很多东西等着我...谢谢您回复 : )

引用 4 楼 qq423399099 的回复:使用二级指针当参数，就可以在函数里修改指针的指向前提是指针被定义成了const才这样吧,如果没有const限定符一级指针好似也能修改啊??

你没有使用end，只是取end的地址而已

long int strtol(const char *nptr,char **endptr,int base); 第一个参数是输入参数 第二个参数是输出参数 有些参数即使输入参数，也是输出参数  输出参数本身 会被改变 所提 char **end ，传入一个指针的地址就行了，指针本身不一定要先初始化  如果是输入参数，通常必须初始化 输入输出参数，也必须初始化 只有输出参数，因为会被改变，而不会被引用，所以可以不必初始化  不过，指针初始化，是个好习惯。

&end 就是 char**类型啊


Question: 关于opengl  2d纹理贴图 背景透明的问题

引用 4 楼 glunoy 的回复:楼主这个问题，启用alphaBlend就能解决。我懒得去整固定管线的开开关关。  你在frag里面 gl_FragColor =clr_tex1; 顶点不赋任何颜色即可。  如果用固定管线的做法，大概是： glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 感谢回答 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 把这句去掉就好了或者换成 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLREPLACE);

引用 3 楼 lishunihaoa 的回复:简单载入PNG的话，用opencv好 嗯嗯，多谢

引用 1 楼 lovesmiles 的回复:我没看懂你想问什么， 不过我猜颜色混合可能适合你  glBlendFunc()  你查一下这个函数 的用法，祝好运 感谢回答 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 把这句去掉就好了或者换成 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLREPLACE);

简单载入PNG的话，用opencv好


Question: 不运行程序，请给出结果和理由

引用 12 楼 Rbaggio92 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] 看了您的点评，我发现自己差的 远啊 没关系，谁都是从青春逐步走向成熟的。

想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！

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

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。

引用 5 楼 Rbaggio92 的回复:有结果的啊，在vc,Vmware里面运行都有结果  有结果不代表是正确

%s 是不小心写错的，改成%d，在此基础上来

引用 1 楼 acetaofaq 的回复:#include<stdlib.h> #include<stdio.h> #include<conio.h> int main() {     char* data="12345678";     short* tmp=NULL;        /*声明tmp指针,值为NULL,即0 */     char p[6]= {0};         /* 字符数组p,每个元素值为0,即'\0',注意不是'0' */     tmp = (short*)&p[2];    /* tmp(指针)的值为数组p的第3个元素(下标为2)的地址 */     *tmp = atoi(&data[4]);  /* tmp指向的内存单元存放一个整数5 */     printf("p[0]=%s\n",p[0]);/* %s意味着输出从p[0]这个地址开始的字符串,由于p[0]的值为0,即指针值为0,即NULL,所以输出p[0]=(null) */     printf("p[0]=%s\n",p[1]);/* %s意味着输出从p[1]这个地址开始的字符串,由于p[1]的值为0,即指针值为0,即NULL,所以输出p[0]=(null) */     printf("p[0]=%s\n",p[2]);/* %s意味着输出从p[2]这个地址开始的字符串,由于p[2]的值为5,即指针值为5,但我们不能直接把一个整数赋值给一个指针变量,根本原因是对内存的管理是由操作系统完成的，我们不能随意访问某个内存单元，所以此处非法,程序崩溃 */     printf("p[0]=%s\n",p[3]);     printf("p[0]=%s\n",p[4]);     getch();     return 0; }  *tmp = atoi(&data[4]);  单步跟，不是对tmp指向的内存单元中存放一个5，而是5678

有结果的啊，在vc,Vmware里面运行都有结果

引用 3 楼 Rbaggio92 的回复:发现了，是我写错了。应该是%d，这样来，结果怎样？  改成%d p[4]的时候也会越界，p大小只是6字节

发现了，是我写错了。应该是%d，这样来，结果怎样？

输出时很可能程序会崩溃，因为你的值不是字符串地址


Question: exit(1)可代替close(fd)和return 0吗?

引用 17 楼 hijack00 的回复:exit(1)是以一种简单粗暴的方式直接退出程序执行，会打乱程序的正常执行流程。而close(fd)和return 0则显得较温和。假如exit语句在子函数中，exit将直接中断程序运行，主程序中的其他语句不会被执行；而return则会返回主程序，之后的语句会继续执行。建议尽量使用return，exit一般用在程序发生严重错误的情况下。参考我这篇博客[利用python cmd模块开发小型命令行应用程序](http://blog.csdn.net/hijack00/article/details/52224372) 谢谢 谢谢

不要用exit代替return函数。  一个是退出进程的，一个是退出函数的。

不一样吧

1. exit用于结束正在运行的整个程序，它将参数返回给OS，把控制权交给操作系统；而return 是退出当前函数，返回函数值，把控制权交给调用函数。 2. exit是系统调用级别，它表示一个进程的结束；而return 是语言级别的，它表示调用堆栈的返回。 3. 在main函数结束时，会隐式地调用exit函数，所以一般程序执行到main()结尾时，则结束主进程。exit将删除进程使用的内存空间，同时把错误信息返回给父进程。

不能

引用 11 楼 paschen 的回复:exit 是一个函数， 后者是一个语句  exit 可在任何时候终止程序，return只是返回当前函数  [quote=引用 8 楼 Xiongzhizhu 的回复:] [quote=引用 2 楼 paschen 的回复:] exit 是一个函数， 后者是一个语句  exit 可在任何时候终止进程，return只是返回当前函数  如果用主函数return后也会去调用exit 谢谢，系统是在return之后自动调用exit吗？[/quote]  不是系统调用，而是你程序在main函数结束后会调用  [/quote] ++ C++ 运行时库中，另有程序启动点，他会调用 main 函数

顶6楼

没有return 0的话编译可能过不了。

exit 是一个函数， 后者是一个语句  exit 可在任何时候终止程序，return只是返回当前函数  引用 8 楼 Xiongzhizhu 的回复:[quote=引用 2 楼 paschen 的回复:] exit 是一个函数， 后者是一个语句  exit 可在任何时候终止进程，return只是返回当前函数  如果用主函数return后也会去调用exit 谢谢，系统是在return之后自动调用exit吗？[/quote]  不是系统调用，而是你程序在main函数结束后会调用

在我记忆中，VC  的库代码中-------VC6,VC8,VC9 都是这样的--------- 调用main 函数的方法是:  exit (main(__argc,__argv)); 并不是main 函数调用 exit  而是exit 的退出参数是main 的返回值 相当于 int n =main(__argc,__argv); exit(n); 确实是 main 退出后，在调用 的exit 退出程序执行。  具体可以参考mainCRTStartup,wMainCRTStartup,WinMainCRTStartup, wWinMainCRTStartup, 这四个函数的实现，这四个函数是VC c,c++ 程序缺省的入口点  他们可能被定义为  _tmainCRTStartup, _tWinMainCRTStartup 之类的宏

引用 5 楼 lm_whales 的回复:exit 是少数几个，可以控制程序流程的函数之一 exit 的参数，就是程序退出码 其他的 有  1) signal,raise 对 signal raise 2)abort 3)setjmp,longjmp 对 setjmp longjmp  此外，还有些 加载执行别的程序的函数。  谢谢，补充了

引用 2 楼 paschen 的回复:exit 是一个函数， 后者是一个语句  exit 可在任何时候终止进程，return只是返回当前函数  如果用主函数return后也会去调用exit 谢谢，系统是在return之后自动调用exit吗？

引用 1 楼 Equim 的回复:没有return 0的话编译可能过不了。  异常退出是exit(1)就可以啊，没有写return 0

exit(1)是退出程序 close(fd)是关闭文件 return 0是函数返回  功能不一样，要看场合

exit  虽然是一个函数，并不返回被调函数，而是退出程序的运行

exit  可以关闭所有打开的文件。。。。 ----------------至少 C FILE * 类型文fopen 打开的文件都能关闭----------- return 不可以


Question: 关于sscanf的问题

Mark，学习了。

引用 6 楼 zhao4zhong1 的回复:“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？指教的很对啊，单步调试的时候看的不是太懂。通过单步调试是可以发现这个问题的

把fopen 里的参数改成rb看看

你的Name[0]之所以变成了0是因为你的ID越界了一个字节（最后的'\0'可能覆盖到了Name[0]） 改成char ID[9]就可以了

char    Name[4], ID[9], Age[3]; if((sscanf(Str, "%3s%8s%2s", Name, ID, Age))!=3)

引用 1 楼 user-5 的回复:帮你测试可以读出  我是VC6.0，该不会是软件自身的问题？？？

帮你测试可以读出


Question: 如何编写一个C程序其功能是：占用指定数量的主机内存

GlobalAlloc(GMEM_FIXED, size);

malloc new 都可以。

malloc 一块需要大小的内存就可以了


Question: 新人，求大神看看代码！

1.变量最好都初始化一下 2.scanf("%c", &ab);最好清空一下输入缓冲区，否则可能会直接读入残留的回车符  #include<stdio.h> #define A 1.25 #define B 0.65 #define C 0.89 int main(void) { 	char ch, ab; 	float d = 0.0, e = 0.0, f = 0.0, g = 0.0, h = 0.0, i = 0.0, j = 0.0; 	printf("Welcome to ABC Mail Order Grocery!Please choose you farvorite:\n"); 	printf("a) thistle(1.25\\pound) b) beet(0.65\\pound) c) carrot(0.89\\pound) \n"); 	printf("q) quit\n"); 	while ((ch = getchar()) != 'q') 	{ 		switch (ch) 		{ 		case 'a': 			scanf("%f", &d); 			e = d*A; 			printf("Are you finishi?(y or n)"); 			fflush(stdin); 			scanf("%c", &ab); 			if (ab == 'y') 				break; 			if (ab == 'n') 				continue; 		case 'b': 			scanf("%f", &f); 			g = f*B; 			printf("Are you finishi?(y or n)"); 			fflush(stdin); 			scanf("%c", &ab); 			if (ab == 'y') 				break; 			if (ab == 'n') 				continue; 		case 'c': 			scanf("%f", &h); 			i = h*C; 			printf("Are you finishi?(y or n)"); 			fflush(stdin); 			scanf("%c", &ab); 			if (ab == 'y') 				break; 			if (ab == 'n') 				continue; 		default: 			printf("Please enter the right word\n"); 		}  		break; 	} 	j = e + g + i; 		printf("%f", j);  	return 0; }

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

引用 3楼千行百行 的回复:连续读写时候要注意收回“回车”...不懂什么意思，为什么我之前那个会连续输出are you finish和please enter therightword 而在再加上getchar后不会重复输出

引用 2楼千行百行 的回复:#include<stdio.h> #define A 1.25 #define B 0.65 #define C 0.89 int main(void) { 	char ch,ab; 	float d=0,e=0,f=0,g=0,h=0,i=0,j=0; 	printf("Welcome to ABC Mail Order Grocery! Please choose you farvorite:\n"); 	printf("a) thistle(1.25\\pound) b) beet(0.65\\pound) c) carrot(0.89\\pound) \n"); 	printf("q) quit\n"); 	while((ch=getchar())!='q') 	{ 		switch(ch) 		{ 			case 'a': 				//getchar(); 				scanf("%f",&d); 				getchar(); 				e=d*A; 				printf("Are you finish? (y or n)"); 				scanf("%c",&ab); 				if(ab=='y') break; 				if(ab=='n')  				{ 					getchar(); 					continue; 				} 			case 'b': 				//getchar(); 				scanf("%f",&d); 				getchar(); 				g=d*B; 				printf("Are you finish? (y or n)"); 				if(ab=='y') break; 				if(ab=='n')  				{ 					getchar(); 					continue; 				} 			case 'c': 				//getchar(); 				scanf("%f",&d); 				getchar(); 				i=d*C; 				printf("Are you finish? (y or n)"); 				if(ab=='y') break; 				if(ab=='n')  				{ 					getchar(); 					continue; 				} 			default: 				printf("Please enter the right word\n"); 		} 		break; 	} 	j=e+g+i; 	printf("%f\n",j); 	return 0; } 改成这样就好了，楼主试试看可以了！

我写的还是比较复杂，给提点意见吧。

连续读写时候要注意收回“回车”

你的break退出的是switch 你可以看看这个： http://zhidao.baidu.com/question/335566329.html


Question: 编写程序运行时提示触发一个断点

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\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需要取地址 同时要注意scanf_s读入%c或者%s的时候需要多加一个参数用来指定读取的字符的长度

scanf里是要变量的地址，也是就是改成 &number

scanf需要输入指针...不然怎么输出

&number


Question: 请问可以怎样修改，以至于不会Time Limit Exceeded！！！！

利用标准模板库中的算法，先sort再unique

＜1000个元素，冒泡排序 ＜100000个元素，qsort函数 ＜10000000个元素，放数据库中，建索引，（B+树排序） ≥10000000个元素，没用到过。

使用了scanf和printf还是不行，看来只能使用其他排序方法了 #include<iostream> using namespace std; int main(){ 	int a[100001],n,m,min; 	scanf("%d",&n); 	for(int i=0;i<n;i++){ 		scanf("%d",&m); 		a[i]=m; 	} 	for(int i=0;i<n;i++) 	  for(int j=n-1;j>i;j--){ 	  	if(a[j]<a[j-1]){ 	  		min=a[j-1]; 	  		a[j-1]=a[j]; 	  		a[j]=min; 		  } 	  } 	for(int i=0;i<n;i++){ 		if(a[i]!=a[i+1]) 		  printf("%d ",a[i]); 	}  }

1.考虑采用O(nlogn)的排序方法，像快排，堆排，归并之类的。你用的是O(n2)的选择排序，效率比较低。 2.去重和排序一起做，没必要单独做一遍去重工作，这样可以将去重的时间复杂度压为O(nlogn)。前提是你采用nlong的排序法 比如做归并排序的时候，“并”的过程中忽略重复元素。 3.如果这样还超时，那就将使用printf，scanf来进行输入输出。    如果还不行那就打读入优化吧（用getchar()来将输入数据一个一个读下来，再转化成你所需要的数据类型，相当与手写一个printf）  如果你不知道什么叫快排，堆排，归并。那你可以去可以找找别人写的文章，除了快速排序的优化有些难做以外，归并排序和堆排序并不算难。 还有就是，写算法题最好少用STL。

TLE的根本原因是排序时间复杂度太高了。一般而言，使用诸如冒泡、选择、插入这些简单的排序方法，其时间复杂度都是O(n^2)，n<=1000时，n^2就是10^6，不会有什么问题。但一旦达到10^7，就会TLE了，题目中n=100001，n^2已经达到10^10，所以肯定超时。优化建议：使用O(nlogn)的排序方法。

输入输出用scanf printf会减少运行时间 如果改了还超时，就要考虑算法的复杂度 可以考虑使用map


Question: 问下C语言代码是不是一行一行，逐行执行的？

多线程环境下不一定

单线程环境也不一定，编译器有一种优化叫乱序优化

printf后用fflush看看

一行一行的？那不是  int a = 0; int b = 0;  的效率比  int a = 0; int b = 0;  的高。。。


Question: sqlite的page中的cell的结构

帮顶

引用 1 楼 woshirenjun12 的回复:表示cell的个数和偏移？ 就你一个人答  分给你吧   我自己查出来了   07代表payload有7个bytes（payload是03 11 11 74 74 74 74，正好7个bytes） 03代表rowid，也就是行号，这是我插入的第三行 payload由key和data构成，data是74 74 74 74 ，代表 tt tt，key是sqlite内部自动找到的一个不重复的键值，在本例中key是03 11 11 还有一种情况是integer是主键的情况，和这个又不一样了

表示cell的个数和偏移？


Question: wdm驱动无法安装

cat  和  sys 需要签名吧

用2楼贴出来的inf文件，用inf2cat来创建cat文件无报错，但是还是无法安装

Windows驱动开发 http://www.osronline.com/

我nt 驱动用DriverMonitor可以正常加载。另外，下面的是使用signtool修改后的inf文件，选的 "inf文件签名"但是最后一次生成cat文件，跳出消息框"参数没有正确设置",但是在同目录下生成了一个mydriver3i64.cat文件》   ; ; MyDriver3.inf ;  [Version] Signature="$WINDOWS NT$" Class=huanDevice ClassGuid={3F82AC59-FDE7-4407-9E48-DBC375D2A7D0} Provider=Huan DriverVer=08/19/2016,0.0.0.0 CatalogFile=MyDriver3.cat CatalogFile.NTx86=MyDriver3X86.cat CatalogFile.NTAMD64=MyDriver3X64.cat CatalogFile.NT=MyDriver3I64.cat  [DestinationDirs] DefaultDestDir = 12   [SourceDisksNames] 1 = "MyDriver2",Disk1,,""  [SourceDisksFiles] MyDriver2.sys = 1,MyDriver_Check,  [Manufacturer] %ManufacturerName%=Standard,NTamd64,NTIA64  [Standard.NTamd64]  [Standard.NTIA64]  [Strings] ManufacturerName="" ClassName="" DiskName="MyDriver3 Source Disk"


Question: 第一次发帖好激动啊！-----关于标准IOfgetc()的小问题

引用 1 楼 user-1 的回复:usleep的参数单位是微秒吧，5000微秒是5毫秒 sleep(5); 暂停5秒    我知道原因了，是因为输出缓冲流，printf（）没有\n,改成usleep（300 0000）也没用，她的输出都存在输出缓冲区了，只有遇到换行符或者满了才打印，fflush刚好刷新缓冲区，加上fflush可以间隔5s打印了。


Question: 求助大神看看程序哪有问题！！！！！

会不会是因为缓冲区输入的问题。

百度百科：由于可以无限读取，所以在2011年12月，ANSI采纳了ISO/IEC9899:2011标准，标准中删除了gets()函数，使用一个新的更安全的函数gets_s()替代

引用 3 楼 iretf的回复:单词的定义，大小写字母表示的连续字符串 最后一个单词，并不是最后一段连续字符串 比如，输入下面字符串，输出应该是多少呢 hello world hello_world 这个我倒是没考虑，给出的结果里面有一个警告说gets可能会不安全，不知道是不是这个原因

引用 2 楼 user-4的回复:字符串最长有多长？比1023长吗 字符串长度不超过1024

字符串最长有多长？比1023长吗

能测试通过，可是只得90分，提示如下 OJ.c  D:\Project\\\solution\p2290\s1718295\source\OJ.c(10) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.  D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\stdio.h(254) : 参见“gets”的声明   这是怎么回事啊   这道题按说很简单，怎么才能得满分啊  满分是150


Question: fscanf函数不能读入数据

怎么fgetc,fclose上下矛盾，到底替不替换，按字符读写还是按字节读写，按字节读写是按二进制字节流读写吗

但是我想用fscanf实现

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

我好像知道了，fscanf只能读文本文件，fread 用在二进制文件

用 k= fread(&c[i], 1, sizeof(int), fp); 读出 返回值为 1 正常


Question: 如何把汇编程序嵌入到C语言中

你只是源码级别的嵌入，我们可以考虑目标文件级别的嵌入。即汇编代码用汇编程序编译成目标文件，C语言代码用C编译器编译成目标文件，然后利用连接器链接这两个目标文件。

引用 39 楼 zhao4zhong1 的回复:老师也有老师对的地方和难处。嗯哪嗯哪，我理解。

引用 41 楼 user-3 的回复:恭喜，蹭点分 欢迎欢迎

恭喜，蹭点分

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。

引用 30 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。我按F10或者F11，逐过程或者逐语句的调试，但是在main（）函数里运行到子函数的时候，跳入子函数，然后再按往下走的时候，马上他就又进行反汇编了。紧接着就在不同的文件中调用，跳转，最后退出。总之没有在我的子函数中继续往下走。是不是说明我的子函数有逻辑上的问题啊。

再重新编译

试试： 项目、属性、配置属性、C/C++、输出文件、汇编程序输出：程序集、机器码和源代码（/Facs） 在重新编译，查看生成的.asm文件内容。

最后是我嵌入C语言的代码。 #include<stdio.h> # define MAXINT 20 int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]); int main(int argc, char *argv[]) { 	unsigned char a[MAXINT]={10,0,9,8,7,6,5,4,3,2,1}; 	unsigned char b[MAXINT]={8,8,7,6,5,4,3,2,1}; 	unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商，d[]存放余数,g[]是除法时每次相乘的结果  	 bigplus(a,b,c); 	 return 0; }   int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]) { 	 int i,len;     len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度，len为较长的一个 	printf("len=%d\n",len); 	for(i=0;i<MAXINT;i++)       //将数组清0 	{   		c[i]=0; 	} 	__asm 	{ 		mov         dword ptr [i],1   		jmp         dian 	}  dian: 	__asm 	{         mov         eax,dword ptr [i]   		cmp         eax,dword ptr [len]   		jg          dian2 				//c[i]+=(a[i]+b[i]); 		mov         eax,dword ptr [a]   		add         eax,dword ptr [i]   		movzx       ecx,byte ptr [eax]   		mov         edx,dword ptr [b]   		add         edx,dword ptr [i]   		movzx       eax,byte ptr [edx]   		add         ecx,eax   		mov         edx,dword ptr [c]   		add         edx,dword ptr [i]   	    movzx       eax,byte ptr [edx]   		add         eax,ecx   		mov         ecx,dword ptr [c]   		add         ecx,dword ptr [i]   		mov         byte ptr [ecx],al   			//       if (c[i]>=10) 	    mov         eax,dword ptr [c]   		add         eax,dword ptr [i]   		movzx       ecx,byte ptr [eax]   		cmp         ecx,0Ah   		jl          dian3       //小于10，跳转到开始循环位置 		   // c[i]-=10;            //大于10的取个位 		mov         eax,dword ptr [c]   		add         eax,dword ptr [i]           movzx       ecx,byte ptr [eax]           sub         ecx,0Ah           mov         edx,dword ptr [c]           add         edx,dword ptr [i]           mov         byte ptr [edx],cl   	//        c[i+1]++;            //高位加1 		mov         eax,dword ptr [c]           add         eax,dword ptr [i]           mov         cl,byte ptr [eax+1]           add         cl,1           mov         edx,dword ptr [c]           add         edx,dword ptr [i]           mov         byte ptr [edx+1],cl   //	jmp         bigplus+7Ch (13315BCh)   	} dian3: 	__asm 	{      	mov         eax,dword ptr [i]   		add         eax,1   		mov         dword ptr [i],eax           mov         eax,dword ptr [i]   		cmp         eax,dword ptr [len]   		jg          dian2 				//c[i]+=(a[i]+b[i]); 		mov         eax,dword ptr [a]   		add         eax,dword ptr [i]   		movzx       ecx,byte ptr [eax]   		mov         edx,dword ptr [b]   		add         edx,dword ptr [i]   		movzx       eax,byte ptr [edx]   		add         ecx,eax   		mov         edx,dword ptr [c]   		add         edx,dword ptr [i]   	    movzx       eax,byte ptr [edx]   		add         eax,ecx   		mov         ecx,dword ptr [c]   		add         ecx,dword ptr [i]   		mov         byte ptr [ecx],al  		  		 //       if (c[i]>=10) 	    mov         eax,dword ptr [c]   		add         eax,dword ptr [i]   		movzx       ecx,byte ptr [eax]   		cmp         ecx,0Ah   		jl          dian3 	//	 jl          bg  //小于10，跳转到开始循环位置 		   // c[i]-=10;            //大于10的取个位 		mov         eax,dword ptr [c]   		add         eax,dword ptr [i]           movzx       ecx,byte ptr [eax]           sub         ecx,0Ah           mov         edx,dword ptr [c]           add         edx,dword ptr [i]           mov         byte ptr [edx],cl   			   //        c[i+1]++;            //高位加1 		mov         eax,dword ptr [c]           add         eax,dword ptr [i]           mov         cl,byte ptr [eax+1]           add         cl,1           mov         edx,dword ptr [c]           add         edx,dword ptr [i]           mov         byte ptr [edx+1],cl   //	jmp         bigplus+7Ch (13315BCh)   	} dian2: 	__asm 		{ 		mov         eax,dword ptr [c]           add         eax,dword ptr [i]           movzx       ecx,byte ptr [eax+1]           test        ecx,ecx           jle         dian4         mov         eax,dword ptr [len]           add         eax,1           mov         dword ptr [len],eax   		jmp        dian4 		}    //    c[0]=len;                //c[0]保存结果数组实际长度 	 dian4:   		__asm 		{ 		mov         eax,dword ptr [c]           mov         cl,byte ptr [len]           mov         byte ptr [eax],cl   		} 		printf("Big integers add: "); //	printf("10进制：");     for (i=len;i>=1;i--) 	{                 printf("%d,",c[i]); //打印结果  	}         printf("\n"); 		return 0; }   因为原始的的反汇编代码，要跳转，而且跳转的位置还是直接用地址表示的。而我在编写的时候无法知道地址信息。所以一开始我是把相应的地址对应的行给标上一个名字，比如jmp     jisuan。然后我把某一行前面标上jisuan：，然而，运行的结果是，貌似电脑无法识别这种标识。当然了，我记得在编写纯粹的汇编语言代码时是可以的，但是也许在C语言中是无法识别的。当然，没有报错，只是结果不对。  然后我把对应的跳转程序，分成一个个的小段，从这段跳转到另一段。结果是，程序不报错，但是结果不对。只有个位和十位正确，从百位开始就错了。往后更是都变成了0。 如果您忙的话，不用仔细看程序，跟我说说我是不是引用的格式（或者方式）不对啊。

接着  --- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------     19:      20: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法     21: { 00DB1540  push        ebp   00DB1541  mov         ebp,esp   00DB1543  sub         esp,0DCh   00DB1549  push        ebx   00DB154A  push        esi   00DB154B  push        edi   00DB154C  lea         edi,[ebp-0DCh]   00DB1552  mov         ecx,37h   00DB1557  mov         eax,0CCCCCCCCh   00DB155C  rep stos    dword ptr es:[edi]       22:     int i,len;     23:     len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度，len为较长的一个 00DB155E  mov         eax,dword ptr [a]   00DB1561  movzx       ecx,byte ptr [eax]   00DB1564  mov         edx,dword ptr [b]   00DB1567  movzx       eax,byte ptr [edx]   00DB156A  cmp         ecx,eax   00DB156C  jle         bigplus+3Bh (0DB157Bh)   00DB156E  mov         ecx,dword ptr [a]   00DB1571  mov         dl,byte ptr [ecx]   00DB1573  mov         byte ptr [ebp-0D9h],dl   00DB1579  jmp         bigplus+46h (0DB1586h)   00DB157B  mov         eax,dword ptr [b]   00DB157E  mov         cl,byte ptr [eax]   00DB1580  mov         byte ptr [ebp-0D9h],cl   00DB1586  movzx       edx,byte ptr [ebp-0D9h]   00DB158D  mov         dword ptr [len],edx       24:     for(i=0;i<MAXINT;i++)       //将数组清0 00DB1590  mov         dword ptr [i],0   00DB1597  jmp         bigplus+62h (0DB15A2h)   00DB1599  mov         eax,dword ptr [i]   00DB159C  add         eax,1   00DB159F  mov         dword ptr [i],eax   00DB15A2  cmp         dword ptr [i],14h   00DB15A6  jge         bigplus+73h (0DB15B3h)       25:         c[i]=0; 00DB15A8  mov         eax,dword ptr [c]   00DB15AB  add         eax,dword ptr [i]   00DB15AE  mov         byte ptr [eax],0   00DB15B1  jmp         bigplus+59h (0DB1599h)       26:     for (i=1;i<=len;i++)        //计算每一位的值 00DB15B3  mov         dword ptr [i],1   00DB15BA  jmp         bigplus+85h (0DB15C5h)   00DB15BC  mov         eax,dword ptr [i]   00DB15BF  add         eax,1   00DB15C2  mov         dword ptr [i],eax   00DB15C5  mov         eax,dword ptr [i]   00DB15C8  cmp         eax,dword ptr [len]   00DB15CB  jg          bigplus+0EDh (0DB162Dh)       27:     {     28:         c[i]+=(a[i]+b[i]); 00DB15CD  mov         eax,dword ptr [a]   00DB15D0  add         eax,dword ptr [i]   00DB15D3  movzx       ecx,byte ptr [eax]   00DB15D6  mov         edx,dword ptr [b]   00DB15D9  add         edx,dword ptr [i]   00DB15DC  movzx       eax,byte ptr [edx]   00DB15DF  add         ecx,eax   00DB15E1  mov         edx,dword ptr [c]   00DB15E4  add         edx,dword ptr [i]   00DB15E7  movzx       eax,byte ptr [edx]   00DB15EA  add         eax,ecx   00DB15EC  mov         ecx,dword ptr [c]   00DB15EF  add         ecx,dword ptr [i]   00DB15F2  mov         byte ptr [ecx],al       29:         if (c[i]>=10) 00DB15F4  mov         eax,dword ptr [c]   00DB15F7  add         eax,dword ptr [i]   00DB15FA  movzx       ecx,byte ptr [eax]   00DB15FD  cmp         ecx,0Ah   00DB1600  jl          bigplus+0EBh (0DB162Bh)       30:         {     31:            c[i]-=10;            //大于10的取个位 00DB1602  mov         eax,dword ptr [c]   00DB1605  add         eax,dword ptr [i]   00DB1608  movzx       ecx,byte ptr [eax]   00DB160B  sub         ecx,0Ah   00DB160E  mov         edx,dword ptr [c]   00DB1611  add         edx,dword ptr [i]   00DB1614  mov         byte ptr [edx],cl       32:            c[i+1]++;            //高位加1 00DB1616  mov         eax,dword ptr [c]   00DB1619  add         eax,dword ptr [i]   00DB161C  mov         cl,byte ptr [eax+1]   00DB161F  add         cl,1   00DB1622  mov         edx,dword ptr [c]   00DB1625  add         edx,dword ptr [i]   00DB1628  mov         byte ptr [edx+1],cl       33:         }     34:     } 00DB162B  jmp         bigplus+7Ch (0DB15BCh)       35:     if (c[i+1]>0) len++; 00DB162D  mov         eax,dword ptr [c]   00DB1630  add         eax,dword ptr [i]   00DB1633  movzx       ecx,byte ptr [eax+1]   00DB1637  test        ecx,ecx   00DB1639  jle         bigplus+104h (0DB1644h)   00DB163B  mov         eax,dword ptr [len]   00DB163E  add         eax,1   00DB1641  mov         dword ptr [len],eax       36:         c[0]=len;                //c[0]保存结果数组实际长度 00DB1644  mov         eax,dword ptr [c]   00DB1647  mov         cl,byte ptr [len]   00DB164A  mov         byte ptr [eax],cl       37:     printf("Big integers add: "); 00DB164C  mov         esi,esp   00DB164E  push        offset string "Big integers add: " (0DB5744h)   00DB1653  call        dword ptr [__imp__printf (0DB82B4h)]   00DB1659  add         esp,4   00DB165C  cmp         esi,esp   00DB165E  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)       38:     for (i=len;i>=1;i--) 00DB1663  mov         eax,dword ptr [len]   00DB1666  mov         dword ptr [i],eax   00DB1669  jmp         bigplus+134h (0DB1674h)   00DB166B  mov         eax,dword ptr [i]   00DB166E  sub         eax,1   00DB1671  mov         dword ptr [i],eax   00DB1674  cmp         dword ptr [i],1   00DB1678  jl          bigplus+15Dh (0DB169Dh)       39:                 printf("%d",c[i]); //打印结果 00DB167A  mov         eax,dword ptr [c]   00DB167D  add         eax,dword ptr [i]   00DB1680  movzx       ecx,byte ptr [eax]   00DB1683  mov         esi,esp   00DB1685  push        ecx   00DB1686  push        offset string "%d" (0DB5740h)   00DB168B  call        dword ptr [__imp__printf (0DB82B4h)]   00DB1691  add         esp,8   00DB1694  cmp         esi,esp   00DB1696  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)   00DB169B  jmp         bigplus+12Bh (0DB166Bh)       40:         printf("\n"); 00DB169D  mov         esi,esp   00DB169F  push        offset string "\n" (0DB573Ch)   00DB16A4  call        dword ptr [__imp__printf (0DB82B4h)]   00DB16AA  add         esp,4   00DB16AD  cmp         esi,esp   00DB16AF  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)       41:     return 0; 00DB16B4  xor         eax,eax       42: } 00DB16B6  pop         edi   00DB16B7  pop         esi   00DB16B8  pop         ebx   00DB16B9  add         esp,0DCh   00DB16BF  cmp         ebp,esp   00DB16C1  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)   00DB16C6  mov         esp,ebp   00DB16C8  pop         ebp   00DB16C9  ret

然后是反汇编出来的。 --- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------      1: #include <stdio.h>      2: #define MAXINT 20      3:       4: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);      5:       6: int main(int argc, char *argv[])      7: { 00DB13A0  push        ebp   00DB13A1  mov         ebp,esp   00DB13A3  sub         esp,158h   00DB13A9  push        ebx   00DB13AA  push        esi   00DB13AB  push        edi   00DB13AC  lea         edi,[ebp-158h]   00DB13B2  mov         ecx,56h   00DB13B7  mov         eax,0CCCCCCCCh   00DB13BC  rep stos    dword ptr es:[edi]   00DB13BE  mov         eax,dword ptr [___security_cookie (0DB7000h)]   00DB13C3  xor         eax,ebp   00DB13C5  mov         dword ptr [ebp-4],eax        8:   unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数 00DB13C8  mov         byte ptr [ebp-1Ch],0Ah   00DB13CC  mov         byte ptr [ebp-1Bh],5   00DB13D0  mov         byte ptr [ebp-1Ah],4   00DB13D4  mov         byte ptr [ebp-19h],6   00DB13D8  mov         byte ptr [ebp-18h],5   00DB13DC  mov         byte ptr [ebp-17h],4   00DB13E0  mov         byte ptr [ebp-16h],3   00DB13E4  mov         byte ptr [ebp-15h],2   00DB13E8  mov         byte ptr [ebp-14h],1   00DB13EC  mov         byte ptr [ebp-13h],1   00DB13F0  mov         byte ptr [ebp-12h],1   00DB13F4  xor         eax,eax   00DB13F6  mov         dword ptr [ebp-11h],eax   00DB13F9  mov         dword ptr [ebp-0Dh],eax   00DB13FC  mov         byte ptr [ebp-9],al        9:   unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数 00DB13FF  mov         byte ptr [ebp-38h],7   00DB1403  mov         byte ptr [ebp-37h],7   00DB1407  mov         byte ptr [ebp-36h],6   00DB140B  mov         byte ptr [ebp-35h],5   00DB140F  mov         byte ptr [ebp-34h],4   00DB1413  mov         byte ptr [ebp-33h],3   00DB1417  mov         byte ptr [ebp-32h],2   00DB141B  mov         byte ptr [ebp-31h],1   00DB141F  xor         eax,eax   00DB1421  mov         dword ptr [ebp-30h],eax   00DB1424  mov         dword ptr [ebp-2Ch],eax   00DB1427  mov         dword ptr [ebp-28h],eax       10:   unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商，d[]存放余数     11:   int div=1234;                               //小乘数或小除数 00DB142A  mov         dword ptr [ebp-7Ch],4D2h       12:   int k=0; 00DB1431  mov         dword ptr [ebp-88h],0       13:   int *res=&k;                                //小余数整数指针 00DB143B  lea         eax,[ebp-88h]   00DB1441  mov         dword ptr [ebp-94h],eax       14:   bigplus(a,b,c); 00DB1447  lea         eax,[ebp-54h]   00DB144A  push        eax   00DB144B  lea         ecx,[ebp-38h]   00DB144E  push        ecx   00DB144F  lea         edx,[ebp-1Ch]   00DB1452  push        edx   00DB1453  call        bigplus (0DB11B8h)   00DB1458  add         esp,0Ch       15:       16:   getchar(); 00DB145B  mov         esi,esp   00DB145D  call        dword ptr [__imp__getchar (0DB82B8h)]   00DB1463  cmp         esi,esp   00DB1465  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)       17:   return 0; 00DB146A  xor         eax,eax       18: } 00DB146C  push        edx   00DB146D  mov         ecx,ebp   00DB146F  push        eax   00DB1470  lea         edx,[ (0DB149Ch)]   00DB1476  call        @ILT+120(@_RTC_CheckStackVars@8) (0DB107Dh)   00DB147B  pop         eax   00DB147C  pop         edx   00DB147D  pop         edi   00DB147E  pop         esi   00DB147F  pop         ebx   00DB1480  mov         ecx,dword ptr [ebp-4]   00DB1483  xor         ecx,ebp   00DB1485  call        @ILT+15(@__security_check_cookie@4) (0DB1014h)   00DB148A  add         esp,158h   00DB1490  cmp         ebp,esp   00DB1492  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)   00DB1497  mov         esp,ebp   00DB1499  pop         ebp   00DB149A  ret   00DB149B  nop   00DB149C  db          05h   00DB149D  db          00h   00DB149E  db          00h   00DB149F  db          00h   00DB14A0  db          a4h   00DB14A1  db          14h   00DB14A2  db          dbh   00DB14A3  db          00h   00DB14A4  db          e4h   00DB14A5  db          ffh   00DB14A6  db          ffh   00DB14A7  db          ffh   00DB14A8  db          14h   00DB14A9  db          00h   00DB14AA  db          00h   00DB14AB  db          00h   00DB14AC  db          e8h   00DB14AD  db          14h   00DB14AE  db          dbh   00DB14AF  db          00h   00DB14B0  db          c8h   00DB14B1  db          ffh   00DB14B2  db          ffh   00DB14B3  db          ffh   00DB14B4  db          14h   00DB14B5  db          00h   00DB14B6  db          00h   00DB14B7  db          00h   00DB14B8  db          e6h   00DB14B9  db          14h   00DB14BA  db          dbh   00DB14BB  db          00h   00DB14BC  db          ach   00DB14BD  db          ffh   00DB14BE  db          ffh   00DB14BF  db          ffh   00DB14C0  db          14h   00DB14C1  db          00h   00DB14C2  db          00h   00DB14C3  db          00h   00DB14C4  db          e4h   00DB14C5  db          14h   00DB14C6  db          dbh   00DB14C7  db          00h   00DB14C8  db          90h   00DB14C9  db          ffh   00DB14CA  db          ffh   00DB14CB  db          ffh   00DB14CC  db          14h   00DB14CD  db          00h   00DB14CE  db          00h   00DB14CF  db          00h   00DB14D0  db          e2h   00DB14D1  db          14h   00DB14D2  db          dbh   00DB14D3  db          00h   00DB14D4  db          78h   00DB14D5  db          ffh   00DB14D6  db          ffh   00DB14D7  db          ffh   00DB14D8  db          04h   00DB14D9  db          00h   00DB14DA  db          00h   00DB14DB  db          00h   00DB14DC  db          e0h   00DB14DD  db          14h   00DB14DE  db          dbh   00DB14DF  db          00h   00DB14E0  db          6bh   00DB14E1  db          00h   00DB14E2  db          64h   00DB14E3  db          00h   00DB14E4  db          63h   00DB14E5  db          00h   00DB14E6  db          62h   00DB14E7  db          00h   00DB14E8  db          61h   00DB14E9  db          00h   --- 无源文件 ----------------------------------------------------------------------- 00DB14EA  int         3   00DB14EB  int         3   00DB14EC  int         3   00DB14ED  int         3   00DB14EE  int         3   00DB14EF  int         3   00DB14F0  int         3   00DB14F1  int         3   00DB14F2  int         3   00DB14F3  int         3   00DB14F4  int         3   00DB14F5  int         3   00DB14F6  int         3   00DB14F7  int         3   00DB14F8  int         3   00DB14F9  int         3   00DB14FA  int         3   00DB14FB  int         3   00DB14FC  int         3   00DB14FD  int         3   00DB14FE  int         3   00DB14FF  int         3   00DB1500  int         3   00DB1501  int         3   00DB1502  int         3   00DB1503  int         3   00DB1504  int         3   00DB1505  int         3   00DB1506  int         3   00DB1507  int         3   00DB1508  int         3   00DB1509  int         3   00DB150A  int         3   00DB150B  int         3   00DB150C  int         3   00DB150D  int         3   00DB150E  int         3   00DB150F  int         3   00DB1510  int         3   00DB1511  int         3   00DB1512  int         3   00DB1513  int         3   00DB1514  int         3   00DB1515  int         3   00DB1516  int         3   00DB1517  int         3   00DB1518  int         3   00DB1519  int         3   00DB151A  int         3   00DB151B  int         3   00DB151C  int         3   00DB151D  int         3   00DB151E  int         3   00DB151F  int         3   00DB1520  int         3   00DB1521  int         3   00DB1522  int         3   00DB1523  int         3   00DB1524  int         3   00DB1525  int         3   00DB1526  int         3   00DB1527  int         3   00DB1528  int         3   00DB1529  int         3   00DB152A  int         3   00DB152B  int         3   00DB152C  int         3   00DB152D  int         3   00DB152E  int         3   00DB152F  int         3   00DB1530  int         3   00DB1531  int         3   00DB1532  int         3   00DB1533  int         3   00DB1534  int         3   00DB1535  int         3   00DB1536  int         3   00DB1537  int         3   00DB1538  int         3   00DB1539  int         3   00DB153A  int         3   00DB153B  int         3   00DB153C  int         3   00DB153D  int         3   00DB153E  int         3   00DB153F  int         3

@赵4老师  我先是把程序写成了C语言的形式，就是这一段，用来实现大整数相加的。然后在调试的时候，按“alt+8”，反汇编，然后把反汇编的代码粘贴到相应的位置。结果是，C语言产生的结果正确，而嵌入了汇编的程序，结果完全错误。嗯，应该说是从第三位开始出错。 一下是C语言代码， #include <stdio.h> #define MAXINT 20  int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);  int main(int argc, char *argv[]) {   unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数   unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数   unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商，d[]存放余数   int div=1234;                               //小乘数或小除数   int k=0;   int *res=&k;                                //小余数整数指针   bigplus(a,b,c);     getchar();   return 0; }  int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法 {     int i,len;     len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度，len为较长的一个     for(i=0;i<MAXINT;i++)       //将数组清0         c[i]=0;     for (i=1;i<=len;i++)        //计算每一位的值     {         c[i]+=(a[i]+b[i]);         if (c[i]>=10)         {            c[i]-=10;            //大于10的取个位            c[i+1]++;            //高位加1         }     }     if (c[i+1]>0) len++;         c[0]=len;                //c[0]保存结果数组实际长度     printf("Big integers add: ");     for (i=len;i>=1;i--)                 printf("%d",c[i]); //打印结果         printf("\n");     return 0; }   然后是反汇编出来的。     ，最后是我嵌入的，因为要涉及到跳转，反汇编出来的跳转位置我无法确定，只好把他们分割成不同的小段。

老师也有老师对的地方和难处。

引用 36 楼 chimenghuanzhe 的回复:哈哈哈哈，嵌入成功了。感谢赵老师@赵4老师 ，感谢楼上各位的帮助。谢谢大家!!!!虽说老师交给我的任务离完成还遥遥无期，但是毕竟是迈出了第一步。接下来我只要把C语言编好的加减乘除都转化成汇编语言，就已经完成了10%。然后再完成cos函数的运算，这就完成了60%。最后用龙格库塔算法把微分积分方程的数值解求出来就算完成了90%，最后把结果写入txt文件中就是真正的完成了。  一开始接手这个任务时，我信心满满，可是当自己着手开始做的时候，才发现，对于一个512位的数据，我怎么表示，这就成了第一大难关，如果不解决了，接下来的计算就无法进行。之后我试着位运算来计算加减乘除，可是，却不知道减法和乘法如何实现，更别提除法了。于是只好用C语言的算术运算来解决。被老师狠狠地批了一顿，并要求我必须用汇编或者位运算来完成计算过程。从此接近5天了，终于把汇编嵌入到了C语言中。虽然对开学之前完成整个工作抱有悲观看法，但是还是要继续努力做下去。总之要把它完成。

引用 36 楼 chimenghuanzhe 的回复:哈哈哈哈，嵌入成功了。感谢赵老师@赵4老师 ，感谢楼上各位的帮助。谢谢大家!!!! 小确幸！

VS2010只能嵌入32位汇编，嵌入不了16位或64位汇编。 32位汇编参考下面： X86和X87汇编指令大全（有注释） ---------- 一、数据传输指令	---------------------------------------------------- 它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据. 1. 通用数据传送指令. 	MOV		传送字或字节. 	MOVSX	先符号扩展,再传送. 	MOVZX	先零扩展,再传送. 	PUSH	把字压入堆栈. 	POP		把字弹出堆栈. 	PUSHA	把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. 	POPA	把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈. 	PUSHAD	把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. 	POPAD	把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈. 	BSWAP	交换32位寄存器里字节的顺序 	XCHG	交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数) 	CMPXCHG	比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX) 	XADD	先交换再累加.(结果在第一个操作数里) 	XLAT	字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL) 2. 输入输出端口传送指令. 	IN		I/O端口输入. ( 语法: IN	累加器,	{端口号│DX} ) 	OUT		I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时,	其范围是 0-255;	由寄存器 DX	指定时,其范围是	0-65535. 3. 目的地址传送指令. 	LEA		装入有效地址.例: LEA DX,string ;把偏移地址存到DX. 	LDS		传送目标指针,把指针内容装入DS.例: LDS SI,string	;把段地址:偏移地址存到DS:SI. 	LES		传送目标指针,把指针内容装入ES.例: LES DI,string	;把段地址:偏移地址存到ES:DI. 	LFS		传送目标指针,把指针内容装入FS.例: LFS DI,string	;把段地址:偏移地址存到FS:DI. 	LGS		传送目标指针,把指针内容装入GS.例: LGS DI,string	;把段地址:偏移地址存到GS:DI. 	LSS		传送目标指针,把指针内容装入SS.例: LSS DI,string	;把段地址:偏移地址存到SS:DI. 4. 标志传送指令. 	LAHF	标志寄存器传送,把标志装入AH. 	SAHF	标志寄存器传送,把AH内容装入标志寄存器. 	PUSHF	标志入栈. 	POPF	标志出栈. 	PUSHD	32位标志入栈. 	POPD	32位标志出栈. ---------- 二、算术运算指令	---------------------------------------------------- 	ADD		加法. 	ADC		带进位加法. 	INC		加 1. 	AAA		加法的ASCII码调整. 	DAA		加法的十进制调整. 	SUB		减法. 	SBB		带借位减法. 	DEC		减 1. 	NEG		求反(以	0 减之). 	CMP		比较.(两操作数作减法,仅修改标志位,不回送结果). 	AAS		减法的ASCII码调整. 	DAS		减法的十进制调整. 	MUL		无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), 	IMUL	整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), 	AAM		乘法的ASCII码调整. 	DIV		无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX,	(字运算). 	IDIV	整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算). 	AAD		除法的ASCII码调整. 	CBW		字节转换为字. (把AL中字节的符号扩展到AH中去) 	CWD		字转换为双字. (把AX中的字的符号扩展到DX中去) 	CWDE	字转换为双字. (把AX中的字符号扩展到EAX中去) 	CDQ		双字扩展. (把EAX中的字的符号扩展到EDX中去) ---------- 三、逻辑运算指令	---------------------------------------------------- 	AND		与运算. 	OR		或运算. 	XOR		异或运算. 	NOT		取反. 	TEST	测试.(两操作数作与运算,仅修改标志位,不回送结果). 	SHL		逻辑左移. 	SAL		算术左移.(=SHL) 	SHR		逻辑右移. 	SAR		算术右移.(=SHR) 	ROL		循环左移. 	ROR		循环右移. 	RCL		通过进位的循环左移. 	RCR		通过进位的循环右移. 			  以上八种移位指令,其移位次数可达255次. 			  移位一次时, 可直接用操作码. 如 SHL AX,1. 			  移位>1次时, 则由寄存器CL给出移位次数. 			  如 MOV CL,04	SHL	AX,CL ---------- 四、串指令 ---------------------------------------------------------- 			  DS:SI	源串段寄存器 :源串变址. 			  ES:DI	目标串段寄存器:目标串变址. 			  CX 重复次数计数器. 			  AL/AX	扫描值. 			  D标志	0表示重复操作中SI和DI应自动增量; 1表示应自动减量. 			  Z标志	用来控制扫描或比较操作的结束. 	MOVS	串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. ) 	CMPS	串比较.( CMPSB 比较字符. CMPSW 比较字. ) 	SCAS	串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位. 	LODS	装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB	传送字符. LODSW	传送字.	LODSD 传送双字.	) 	STOS	保存串.是LODS的逆过程. 	REP			当CX/ECX<>0时重复. 	REPE/REPZ	当ZF=1或比较结果相等,且CX/ECX<>0时重复. 	REPNE/REPNZ	当ZF=0或比较结果不相等,且CX/ECX<>0时重复. 	REPC		当CF=1且CX/ECX<>0时重复. 	REPNC		当CF=0且CX/ECX<>0时重复. ---------- 五、程序转移指令	---------------------------------------------------- 1. 无条件转移指令 (长转移) 	JMP			无条件转移指令 	CALL		过程调用 	RET/RETF	过程返回. 2. 条件转移指令	(短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 ) 	JA/JNBE		不小于或不等于时转移. 	JAE/JNB		大于或等于转移. 	JB/JNAE		小于转移. 	JBE/JNA		小于或等于转移. 		以上四条,测试无符号整数运算的结果(标志C和Z). 	JG/JNLE		大于转移. 	JGE/JNL		大于或等于转移. 	JL/JNGE		小于转移. 	JLE/JNG		小于或等于转移. 		以上四条,测试带符号整数运算的结果(标志S,O和Z). 	JE/JZ		等于转移. 	JNE/JNZ		不等于时转移. 	JC			有进位时转移. 	JNC			无进位时转移. 	JNO			不溢出时转移. 	JNP/JPO		奇偶性为奇数时转移. 	JNS			符号位为 "0" 时转移. 	JO			溢出转移. 	JP/JPE		奇偶性为偶数时转移. 	JS			符号位为 "1" 时转移. 3. 循环控制指令(短转移) 	LOOP			CX不为零时循环. 	LOOPE/LOOPZ		CX不为零且标志Z=1时循环. 	LOOPNE/LOOPNZ	CX不为零且标志Z=0时循环. 	JCXZ			CX为零时转移. 	JECXZ			ECX为零时转移. 4. 中断指令 	INT			中断指令 	INTO		溢出中断 	IRET		中断返回 5. 处理器控制指令 	HLT			处理器暂停,	直到出现中断或复位信号才继续. 	WAIT		当芯片引线TEST为高电平时使CPU进入等待状态. 	ESC			转换到外处理器. 	LOCK		封锁总线. 	NOP			空操作. 	STC			置进位标志位. 	CLC			清进位标志位. 	CMC			进位标志取反. 	STD			置方向标志位. 	CLD			清方向标志位. 	STI			置中断允许位. 	CLI			清中断允许位. ---------- 六、伪指令 ---------------------------------------------------------- 	DW			定义字(2字节). 	PROC		定义过程. 	ENDP		过程结束. 	SEGMENT		定义段. 	ASSUME		建立段寄存器寻址. 	ENDS		段结束. 	END			程序结束. ---------- 七、处理机控制指令：标志处理指令	------------------------------------ 	CLC		进位位置0指令 	CMC		进位位求反指令 	STC		进位位置为1指令 	CLD		方向标志置1指令 	STD		方向标志位置1指令 	CLI		中断标志置0指令 	STI		中断标志置1指令 	NOP		无操作 	HLT		停机 	WAIT	等待 	ESC		换码 	LOCK	封锁 ========== 浮点运算指令集 ====================================================== ---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查，机器码去掉9B)---- FINIT				  初始化浮点部件				   机器码  9B DB E3 FCLEX				  清除异常						   机器码  9B DB E2 FDISI				  浮点检查禁止中断				   机器码  9B DB E1 FENI				  浮点检查禁止中断二			   机器码  9B DB E0 WAIT				  同步CPU和FPU					   机器码  9B FWAIT				  同步CPU和FPU					   机器码  D9 D0 FNOP				  无操作						   机器码  DA E9 FXCH				  交换ST(0)和ST(1)				   机器码  D9 C9 FXCH ST(i)			  交换ST(0)和ST(i)				   机器码  D9 C1iii FSTSW ax			  状态字到ax					   机器码  9B DF E0 FSTSW	word ptr mem  状态字到mem					   机器码  9B DD mm111mmm FLDCW	word ptr mem  mem到状态字					   机器码  D9 mm101mmm FSTCW	word ptr mem  控制字到mem					   机器码  9B D9 mm111mmm  FLDENV	word ptr mem  mem到全环境					   机器码  D9 mm100mmm FSTENV	word ptr mem  全环境到mem					   机器码  9B D9 mm110mmm FRSTOR	word ptr mem  mem到FPU状态					   机器码  DD mm100mmm FSAVE	word ptr mem  FPU状态到mem					   机器码  9B DD mm110mmm  FFREE ST(i)			  标志ST(i)未使用				   机器码  DD C0iii FDECSTP				  减少栈指针1->0 2->1			   机器码  D9 F6 FINCSTP				  增加栈指针0->1 1->2			   机器码  D9 F7 FSETPM				  浮点设置保护					   机器码  DB E4 ---------- 二、数据传送指令	---------------------------------------------------- FLDZ				  将0.0装入ST(0)				   机器码  D9 EE FLD1				  将1.0装入ST(0)				   机器码  D9 E8 FLDPI				  将π装入ST(0)					   机器码  D9 EB FLDL2T				  将ln10/ln2装入ST(0)			   机器码  D9 E9 FLDL2E				  将1/ln2装入ST(0)				   机器码  D9 EA FLDLG2				  将ln2/ln10装入ST(0)			   机器码  D9 EC FLDLN2				  将ln2装入ST(0)				   机器码  D9 ED  FLD	   real4 ptr mem  装入mem的单精度浮点数			   机器码  D9 mm000mmm FLD	   real8 ptr mem  装入mem的双精度浮点数			   机器码  DD mm000mmm FLD	  real10 ptr mem  装入mem的十字节浮点数			   机器码  DB mm101mmm  FILD	word ptr mem  装入mem的二字节整数			   机器码  DF mm000mmm FILD   dword ptr mem  装入mem的四字节整数			   机器码  DB mm000mmm FILD   qword ptr mem  装入mem的八字节整数			   机器码  DF mm101mmm  FBLD   tbyte ptr mem  装入mem的十字节BCD数			   机器码  DF mm100mmm  FST	   real4 ptr mem  保存单精度浮点数到mem			   机器码  D9 mm010mmm FST	   real8 ptr mem  保存双精度浮点数到mem			   机器码  DD mm010mmm  FIST	word ptr mem  保存二字节整数到mem			   机器码  DF mm010mmm FIST   dword ptr mem  保存四字节整数到mem			   机器码  DB mm010mmm  FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈	   机器码  D9 mm011mmm FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈	   机器码  DD mm011mmm FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈	   机器码  DB mm111mmm  FISTP	word ptr mem  保存二字节整数到mem并出栈		   机器码  DF mm011mmm FISTP  dword ptr mem  保存四字节整数到mem并出栈		   机器码  DB mm011mmm FISTP  qword ptr mem  保存八字节整数到mem并出栈		   机器码  DF mm111mmm  FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈	   机器码  DF mm110mmm  FCMOVB				  ST(0),ST(i) <时传送			   机器码  DA C0iii FCMOVBE				  ST(0),ST(i) <=时传送			   机器码  DA D0iii FCMOVE				  ST(0),ST(i) =时传送			   机器码  DA C1iii FCMOVNB				  ST(0),ST(i) >=时传送			   机器码  DB C0iii FCMOVNBE			  ST(0),ST(i) >时传送			   机器码  DB D0iii FCMOVNE				  ST(0),ST(i) !=时传送			   机器码  DB C1iii FCMOVNU				  ST(0),ST(i) 有序时传送		   机器码  DB D1iii FCMOVU				  ST(0),ST(i) 无序时传送		   机器码  DA D1iii ---------- 三、比较指令	-------------------------------------------------------- FCOM				  ST(0)-ST(1)					   机器码  D8 D1 FCOMI				  ST(0),ST(i)  ST(0)-ST(1)		   机器码  DB F0iii FCOMIP				  ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii FCOM   real4 ptr mem  ST(0)-实数mem					   机器码  D8 mm010mmm FCOM   real8 ptr mem  ST(0)-实数mem					   机器码  DC mm010mmm  FICOM	word ptr mem  ST(0)-整数mem					   机器码  DE mm010mmm FICOM  dword ptr mem  ST(0)-整数mem					   机器码  DA mm010mmm FICOMP	word ptr mem  ST(0)-整数mem并出栈			   机器码  DE mm011mmm FICOMP dword ptr mem  ST(0)-整数mem并出栈			   机器码  DA mm011mmm  FTST				  ST(0)-0						   机器码  D9 E4 FUCOM  ST(i)		  ST(0)-ST(i)					   机器码  DD E0iii FUCOMP ST(i)		  ST(0)-ST(i)并出栈				   机器码  DD E1iii FUCOMPP				  ST(0)-ST(1)并二次出栈			   机器码  DA E9 FXAM				  ST(0)规格类型					   机器码  D9 E5 ---------- 四、运算指令	-------------------------------------------------------- FADD				  把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器)	相加，并将结果存入目的操作数 FADDP  ST(i),ST		  这个指令是使目的操作数加上 ST	缓存器，并弹出 ST 缓存器，而目的操作数必须是堆栈缓存器的其中之一，最后不管目的操作数为何，经弹出一次后，目的操作数会变成上一个堆栈缓存器了 FIADD				  FIADD	是把 ST	加上来源操作数，然后再存入 ST 缓存器，来源操作数必须是字组整数或短整数形态的变数  FSUB				  减 FSUBP FSUBR				  减数与被减数互换 FSUBRP FISUB FISUBR  FMUL				  乘 FMULP FIMUL  FDIV				  除 FDIVP FDIVR FDIVRP FIDIV FIDIVR  FCHS				  改变 ST 的正负值  FABS				  把 ST	之值取出，取其绝对值后再存回去。  FSQRT				  将 ST	之值取出，开根号后再存回去。  FSCALE				  这个指令是计算 ST*2^ST(1)之值，再把结果存入 ST 里而 ST(1)	之值不变。ST(1)	必须是在 -32768	到 32768 (-215 到 215 )之间的整数，如果超过这个范围计算结果无法确定，如果不是整数 ST(1)	会先向零舍入成整数再计算。所以为安全起见，最好是由字组整数载入到 ST(1) 里。  FRNDINT				  这个指令是把 ST 的数值舍入成整数，FPU	提供四种舍入方式，由 FPU 的控制字组(control	word)中的 RC 两个位决定 						  RC	舍入控制 						  00	四舍五入 						  01	向负无限大舍入 						  10	向正无限大舍入 						  11	向零舍去 ================================================================================

引用 19 楼 zhao4zhong1 的回复:[quote=引用 18 楼 chimenghuanzhe 的回复:] [quote=引用 17 楼 zhao4zhong1 的回复:] 提醒： Win7下需要在DosBox中运行BC++3.1或TC  WinXP下，建一个批处理bc.bat,内容为下面两行，放在bc.exe同目录下，再将bc.bat发送到桌面快捷方式： del tc*.swp >NUL start command /c bc.exe 如果想在IDE里面使用鼠标，还应将快捷方式属性中的快速编辑模式关掉。啊，赵老师，你说的我不太懂。嗯，首先你这个程序我只是看了他的结构，如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看，刚才你一说与鼠标相关的话题，我没听懂。你这个程序是讲如何在BC下使用鼠标吗？可是我记得BC下本来就可以使用鼠标啊。[/quote] 我是担心你在比如Win7下或Win7 64位下用不了BC[/quote]  引用 19 楼 zhao4zhong1 的回复:[quote=引用 18 楼 chimenghuanzhe 的回复:] [quote=引用 17 楼 zhao4zhong1 的回复:] 提醒： Win7下需要在DosBox中运行BC++3.1或TC  WinXP下，建一个批处理bc.bat,内容为下面两行，放在bc.exe同目录下，再将bc.bat发送到桌面快捷方式： del tc*.swp >NUL start command /c bc.exe 如果想在IDE里面使用鼠标，还应将快捷方式属性中的快速编辑模式关掉。啊，赵老师，你说的我不太懂。嗯，首先你这个程序我只是看了他的结构，如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看，刚才你一说与鼠标相关的话题，我没听懂。你这个程序是讲如何在BC下使用鼠标吗？可是我记得BC下本来就可以使用鼠标啊。[/quote] 我是担心你在比如Win7下或Win7 64位下用不了BC[/quote]我用的是VS2010啊，VC++6.0在win7下面无法使用，所以安装了VS2010,（因为没有找到单独的VC2010），虽然很不熟悉。至于汇编语言，我只是准备编几个子函数，加减乘除，每个子函数把参数传递进去，然后用汇编计算，然后再把结果传出来。这样，函数的主体部分还是用C编写的，不过，里面涉及到cos函数，我看它的源代码，是按照泰勒公式展开的，一直展开到了x的14次方，我的天哪，我这个x本身就有100位，最少也是64个字节，即64位（我是用unsigned char型数组），然后它再14次方，要多少位，有可能会冲到1400位，然后，Oh，my god!我相信的电脑会崩溃的。

引用 18 楼 chimenghuanzhe 的回复:[quote=引用 17 楼 zhao4zhong1 的回复:] 提醒： Win7下需要在DosBox中运行BC++3.1或TC  WinXP下，建一个批处理bc.bat,内容为下面两行，放在bc.exe同目录下，再将bc.bat发送到桌面快捷方式： del tc*.swp >NUL start command /c bc.exe 如果想在IDE里面使用鼠标，还应将快捷方式属性中的快速编辑模式关掉。啊，赵老师，你说的我不太懂。嗯，首先你这个程序我只是看了他的结构，如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看，刚才你一说与鼠标相关的话题，我没听懂。你这个程序是讲如何在BC下使用鼠标吗？可是我记得BC下本来就可以使用鼠标啊。[/quote] 我是担心你在比如Win7下或Win7 64位下用不了BC


Question: AOE网上的关键路径中关于字典序的问题


Question: 如何在linux下，实现getch函数功能

#include <termio.h>  int getch(void) {      struct termios tm, tm_old;      int fd = 0, ch;        if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置           return -1;      }        tm_old = tm;      cfmakeraw(&tm);//更改终端设置为原始模式，该模式下所有的输入数据以字节为单位被处理      if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置           return -1;      }        ch = getchar();      if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子           return -1;      }           return ch; }  总体的思路就是设置终端的属性  设置为原始模式，这种模式下输入就是无缓冲的，  设置过去，输入完之后然后再更改回来  主要就是两个函数  tcgetattr()和tcsetattr()  这个可以百度获取详细信息

引用 4 楼 qq_35398857 的回复:[quote=引用 1 楼 baidu_30174103 的回复:] 看看这个！  [code=c/**************************************** 文件名: getkey.h 版本: 1.0 此头文件包含函数: int getch() char *getkey() 可用于获取按键信息,具体返回值请自行 测试,编译需加参数 -lpthread 此头文件适用平台: 诺亚舟同步搜学王NP1500/I新春版              made by pengyao1207 注:C++不可用             2013年8月 ****************************************/ #include <linux/unistd.h> #include <termios.h> #include <unistd.h>   #include <stdio.h> #include <pthread.h> #ifndef _PY_GETKER_H #define _PY_GETKEY_H int input; pthread_t thread[1]; pthread_mutex_t mut; char c[193]=""; void *memset(); void *regetch() {         int n = 0;         n = fgetc( stdin );         input += n;         pthread_exit(NULL); } int getch( void ) {          struct termios tm, tm_old;          int fd = STDIN_FILENO,c;          if(tcgetattr(fd, &tm) < 0)          return -1;           tm_old = tm;           cfmakeraw(&tm);           if(tcsetattr(fd, TCSANOW, &tm) < 0)          return -1;           unsigned int k;         int temp;         input = fgetc( stdin );         k = input;         if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;         if(k > 32){                 c = k;         }         else{                 while(1)                 {                         memset(&thread,0,sizeof(thread));                         if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)                         printf("用于获取按键输入的线程创建失败!\n");                         usleep(1000);                         pthread_cancel(thread[0]);                         pthread_join(thread[0],NULL);                         if(k == input) {                                 c=input;                                  break;                         }                         else{                                  k = input;                                 c=c+k;                         }                 }         }         return c;  }  char *getkey(void) { int n,i; char a; c[0]='"'; n=getch(); switch(n) { case 171:    return "UP"; case 172:    return "DOWN"; case 173:    return "RIGHT"; case 174:    return "LEFT"; case 27:    return "ESC"; case 13:    return "OK"; case 342:    return "AA"; case 343:    return "BB"; case 127:    return "DEL"; case 32:    return "SPACE"; case 39: return c; } if(n>96)if(n<123) { a='a'; for(i=97;i<n;i++)a++; c[0]=a; return c; } if(n>64)if(n<91) { a='A'; for(i=65;i<n;i++)a++; c[0]=a; return c; } } #endif][/code] 不知道为什么只要运行getch，测试代码如下面  但是输入就是没有反应，而且CTRL+c或者ctrl + \，也无法退出运行,[/quote]   getch()返回int

#include "getkey.h" main() { printf("%s",getkey()); /*printf("%d",getch());*/ } 试试，我当时测试用的。

引用 3 楼 zhao4zhong1 的回复:参考NUCRSES库？  怎么引用 我不会啊，

引用 1 楼 baidu_30174103 的回复:看看这个！  [code=c/**************************************** 文件名: getkey.h 版本: 1.0 此头文件包含函数: int getch() char *getkey() 可用于获取按键信息,具体返回值请自行 测试,编译需加参数 -lpthread 此头文件适用平台: 诺亚舟同步搜学王NP1500/I新春版              made by pengyao1207 注:C++不可用             2013年8月 ****************************************/ #include <linux/unistd.h> #include <termios.h> #include <unistd.h>   #include <stdio.h> #include <pthread.h> #ifndef _PY_GETKER_H #define _PY_GETKEY_H int input; pthread_t thread[1]; pthread_mutex_t mut; char c[193]=""; void *memset(); void *regetch() {         int n = 0;         n = fgetc( stdin );         input += n;         pthread_exit(NULL); } int getch( void ) {          struct termios tm, tm_old;          int fd = STDIN_FILENO,c;          if(tcgetattr(fd, &tm) < 0)          return -1;           tm_old = tm;           cfmakeraw(&tm);           if(tcsetattr(fd, TCSANOW, &tm) < 0)          return -1;           unsigned int k;         int temp;         input = fgetc( stdin );         k = input;         if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;         if(k > 32){                 c = k;         }         else{                 while(1)                 {                         memset(&thread,0,sizeof(thread));                         if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)                         printf("用于获取按键输入的线程创建失败!\n");                         usleep(1000);                         pthread_cancel(thread[0]);                         pthread_join(thread[0],NULL);                         if(k == input) {                                 c=input;                                  break;                         }                         else{                                  k = input;                                 c=c+k;                         }                 }         }         return c;  }  char *getkey(void) { int n,i; char a; c[0]='"'; n=getch(); switch(n) { case 171:    return "UP"; case 172:    return "DOWN"; case 173:    return "RIGHT"; case 174:    return "LEFT"; case 27:    return "ESC"; case 13:    return "OK"; case 342:    return "AA"; case 343:    return "BB"; case 127:    return "DEL"; case 32:    return "SPACE"; case 39: return c; } if(n>96)if(n<123) { a='a'; for(i=97;i<n;i++)a++; c[0]=a; return c; } if(n>64)if(n<91) { a='A'; for(i=65;i<n;i++)a++; c[0]=a; return c; } } #endif][/code] 不知道为什么只要运行getch，测试代码如下面  但是输入就是没有反应，而且CTRL+c或者ctrl + \，也无法退出运行,

参考NUCRSES库？

好的，我试试，谢谢


Question: 关于C语言单词统计程序的疑问

首先你得搞明白，在单词内和单词外是什么意思。例如，china，chi na是怎么统计的。你网上找的代码有可能只适用于别人，你的参考别人的代码改成自己需要的

有多个空格并不会造成统计错误啊。  因为它是先判断if (c == ' ' || c == '\n' || c == '\t')的


Question: C语言宏定义

就是把宏替换成 0, 0,  ，具体什么意思得看你代码

调到引用的地方去看看，单纯从这一句看不出什么来

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

宏只是文本替换, 具体什么意思得看这个宏在哪里用


Question: c语言中怎样将两个8位的二进制数合成为一个16位的二进制数?

仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

char 8位 short int 16位 char a,b; short int c; a = 10; b= 3; c = a; c <<= 8; c &=b; 这样就可以了。


Question: 红外线程序应该怎么写啊？求大神帮忙变一下或讲一下编写思路

这只是大体的代码，还要根据环境不同进行改动。  #include <stdio.h> #include <windows.h>  int main() { 	HANDLE hSensor1, hSensor2; 	char order[2] = { 0 }; 	int i = 0; 	int iManNum = 0; 	DWORD dwState;  	// hSensor1, hSensor2;要连接设备初始化才可以 	while (1) { 		dwState = WaitForSingleObject(hSensor1, 500);			// 不一定用等待函数 		if (dwState == WAIT_OBJECT_0) { 			order[0] = 1; 			dwState = WaitForSingleObject(hSensor2, 1000);		// 超时时间限定 			if (dwState == WAIT_OBJECT_0) { 				order[1] = 2; 			} 		}  		dwState = WaitForSingleObject(hSensor2, 500); 		if (dwState == WAIT_OBJECT_0) { 			order[0] = 2; 			dwState = WaitForSingleObject(hSensor1, 1000);		// 超时时间限定 			if (dwState == WAIT_OBJECT_0) { 				order[1] = 1; 			} 		}  		if ((order[0] == 1) && (order[1] == 2)) { 			iManNum++; 			pinrtf(_T("进入1人\t")); 		} 		else if ((order[0] == 2) && (order[1] == 1)) { 			iManNum--; 			pinrtf(_T("出去1人\t")); 		} 		pinrtf(_T("目前的人数是:%d\n"), iManNum); 		order[0] = 0; 		order[1] = 0; 	}  	return 0; }


Question: _WDF_DEVICE_EXTENSION_TYPE_INFO': undeclared

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项

链接时用-l把库加上