Question: C语言题目求助 ！

引用 1 楼 user-6 的回复:大约思路应该这样吧，具体汉字读音那里  准备一个装数本身的数组。 （一位一位取出来放进去）  准备一个数组装读音。（比如第5位的5读5万）  准备两个指针扫描装数的数组。 不等于0也不用检查前面那个指针，直接把对应的读音数组调出来读。 如果等于0就继续往前扫描，如果直接到尾就不读了。 否则的话扫到最后一个不是0的数那里读个0出来。  实现的代码很麻烦，就不具体实现了。  装读音的数组怎么初始化...示范一下可以么...

#include <stdio.h> #include <string.h> char hznum[100]; char hzunit[15][3]={"","十","百","千","万","十","百","千","亿","十","百","千","万","十","百"}; char hzdigit[10][3]={"零","一","二","三","四","五","六","七","八","九"}; char numstr[20]; char *ReadNumByHZ(double v) {     char *p,*d;     int u,i;      sprintf(numstr,"%.15lg",v);     printf("%s\n",numstr);     if ('-'==numstr[0]) {         sprintf(hznum,"不支持读负数");         return hznum;     }     p=strchr(numstr,'e');     if (NULL!=p) {         sprintf(hznum,"不支持读太大或太小的数");         return hznum;     }     d=NULL;     p=strchr(numstr,'.');     if (NULL!=p) {         p[0]=0;         d=p+1;     }     u=strlen(numstr);     hznum[0]=0;     for (i=0;i<u;i++) {         if ('0'==numstr[i] && 0!=((u-1-i)%4)) {             sprintf(hznum,"%s%s",hznum,hzdigit[numstr[i]-'0']);         } else {             sprintf(hznum,"%s%s%s",hznum,hzdigit[numstr[i]-'0'],hzunit[u-1-i]);         }     }     printf("%s\n",hznum);     u=strlen(hznum);     for (i=0;i<u;i+=2) {         if (0==strncmp(hznum+i,"零零",4)) {//多个连续的“零”改成一个“零”             memmove(hznum+i,hznum+i+2,u-i-2+1);             i-=2;             u-=2;         }     }     printf("%s\n",hznum);     if (0==strcmp(hznum+u-2,"零")) {//末尾“零”去掉         hznum[u-2]=0;         u-=2;     }     printf("%s\n",hznum);     for (i=0;i<u;i+=2) {         if (0==strncmp(hznum+i,"零万",4) || 0==strncmp(hznum+i,"零亿",4)) {//“万”“亿”前是“零”去掉             memmove(hznum+i,hznum+i+2,u-i-2+1);             u-=2;         }     }     printf("%s\n",hznum);     if (NULL!=d) {         sprintf(hznum,"%s点",hznum);         i=0;         while (1) {             if (0==d[i]) break;             sprintf(hznum,"%s%s",hznum,hzdigit[d[i]-'0']);             i++;         }     }     printf("%s\n",hznum);     return hznum; } void main() {     printf("\n%s\n",ReadNumByHZ(130040600090.012)); } //130040600090.012 //一千三百零零亿四千零六十零万零零九十零 //一千三百零亿四千零六十零万零九十零 //一千三百零亿四千零六十零万零九十 //一千三百亿四千零六十万零九十 //一千三百亿四千零六十万零九十点零一二 // //一千三百亿四千零六十万零九十点零一二  #include <afx.h> #include <stdio.h> CString ChineseCapitalMoney(double Num) {     CString szChMoney,szNum;     int iLen, iNum, iAddZero=0;     TCHAR* hzUnit[18]={_T("分"),_T("角"),_T("元"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟"),_T("亿"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟")};     TCHAR* hzNum[10]={_T("零"),_T("壹"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖")};     if (-0.01<Num && Num<0.01) return _T("零元整");     szNum.Format(_T("%18.0f"), Num*100); // 最小到分     szNum.TrimLeft();     iLen=szNum.GetLength();     if(iLen>15 || iLen==0 || Num<0) return _T(""); // 数据错误返回      for(int i=0;i<iLen;i++) {         iNum=_ttoi((LPCTSTR)szNum.Mid(i,1));         if (iNum==0) {             iAddZero++;         } else {             if (iAddZero>0) szChMoney+=_T("零");             szChMoney+=hzNum[iNum];             iAddZero=0;         }         if (iNum!=0 || iLen-i==3 || iLen-i==11 || ((iLen-i+1)%8==0 && iAddZero<4)) szChMoney+=hzUnit[iLen-i-1];     }     if (szNum.Right(2)==_T("00")) szChMoney+=_T("整"); // 没有角和分     return szChMoney; } void main() {     double d;     CString s;      d=-1.0            ;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=0.0             ;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1234501234567.89;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1000000000000.01;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1000000000001.00;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d= 130040600090.01;printf("%16.2f %s\n",d,ChineseCapitalMoney(d)); } //           -1.00 //            0.00 零元整 //1234501234567.89 壹万贰仟叁佰肆拾伍亿零壹佰贰拾叁万肆仟伍佰陆拾柒元捌角玖分 //1000000000000.01 壹万亿元零壹分 //1000000000001.00 壹万亿零壹元整 // 130040600090.01 壹仟叁佰亿零肆仟零陆拾万零玖拾元零壹分

按汉语的习惯 这个需求不转换为严格的rule,一定会造成很多bug

额 那个大家好 我是大白。。。你们说的我咋么都不懂。。。还有忘了说了 读出来不是汉字 是读拼音。。。对不起

引用 3 楼 黑马 的回复:我感觉从右往左分析比较好，首先将数字字符串话，然后从右往左一个一个分析，遇到第一次的'0'只做记录不处理，其他数字就往结果字符串左边加对应相应的汉字，然后再根据位数加不同的单位（个十百千等）。再遇到'0'时就加“零”，最后处理正负号 同意，好处是直接可以确定读音（知道后面加十或万）。遇到0就发零，然后连续的0就可以跳过。不过万的地方要再处理一下，放个万在那里。

好心帮忙被丢了块板砖。。。自己再丢一块凑个2吧


Question: 精通c语言之路，有哪些可推荐的书籍或方法？（大神们快来）

初学者建议看：《C语言程序设计-现代方法》，裘宗燕的C语言程序设计的书，C++之父《程序语言设计与实践》 进阶的话 《C++沉思录》 《C陷阱与缺陷》 《C专家编程》  还是强烈建议学完汇编再学C语言，效果极佳 。。。分数拿来。。。

重要多敲代码，多看书。

<c程序设计语言>

多写代码

引用 楼主 u014598100 的回复:新建了一个小号，给贴100分 如果只是为了考试，或者能看懂c代码，含C的那几本书都可以看，如果考C吃饭，语法通达只是基本

主要推荐下面的书籍，不必全部看，都是好书 初级级别：《c primer plus》这本书是C语言入门书籍，讲的比较详细，里面也有很多代码，可以跟着代码练习。 入门级别：《c 和指针》和《C程序设计语言》（K&R版本），《征服C指针》《C点滴》需要大量的代码练习，看书是学不会变成 进阶级别：《C陷阱与缺陷》，《C语言深度解剖》，《C专家编程》，回头看《C程序设计语言》。 剩下的就是数据结构和算法的学习了

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

《C语言课程设计案例精编》 《C语言点滴》

不看C的标准文档，只看别的书，就好比围着故宫打转转，根本无法深入内部，也好比隔靴骚痒。

http://bbs.csdn.net/topics/390638386 去年总结的帖子，看看吧！

《C和指针》

c语言程序设计

经典的巨作就不说了，像一楼说的那些书（除了《c陷阱和缺陷》和《c专家编程》以及正在看的《算法导论》以外，其他的都没读过还，被《设计模式》课程的老师吓唬的（据他说，《C++程序设计》谭浩强版里面关于继承派生的基本上都是错的，而我大一时候唯一学好的一门课就是谭浩强版《C++程序设计》，登时，有种觉得自己错的一塌糊涂的感觉，因此，以后的编程中，C++少了个尾巴，成了C！！），觉得自己一点点的都不懂什么时候OO思想，所以，C++的书籍目前读的不多）  刚吃完晚饭，废话那么多有助消化一哈  推荐一本知名度不是很高的，但是本人觉得还不错的书 《C语言深度解剖》作    者：陈正冲  很多地方作者都用了现实的比喻，让人更好理解。我觉得一本好的书，能把一些知识点结合现实现象来讲是最好的！ 不过我读的时候这不是一本书，只是在网上散播的试读本，不知道现在第二版怎么样了。 书里面将的知识点不算全，但是绝对算是最常用的，理解C语言（不是C++）基本特性差不多够了

crazy coding

看完K&R的那本《C程序设计语言》 看《C陷阱与缺陷》《C/C++高质量编程》《C专家编程》  看C标准库的实现  多写代码


Question: 请教大家C语言库连接的问题

引用 6 楼 dbzhang800 的回复:GCC 的C标准库是 libc.so，math.h对应的在 libm.so  MSVC的C标准库是 MSVCRT.dll MSVCR20.dll/MSVCR71.dll/...  MinGW 使用 MSVCRT.dll 貌似使用的system32里的msvcrt.dll？是嘛？ 或者我看到了应该是libcrtdll.a？这个文件？

MinGW使用的 MSVCRT.dll ，是MSVC4.2~MSVC6.0的C运行库，你需要去系统目录中寻找。

引用 6 楼 dbzhang800 的回复:GCC 的C标准库是 libc.so，math.h对应的在 libm.so  MSVC的C标准库是 MSVCRT.dll MSVCR20.dll/MSVCR71.dll/...  MinGW 使用 MSVCRT.dll 没有看到你所说的.so和.dll,在MINGW的lib文件夹里只看到一些.o和.a?

参考gcc相关源代码。 《编译原理》 《程序员的自我修养——链接、装载与库》 《Windows PE权威指南》

引用 4 楼 sdu_sky 的回复:#include <stdio.h> 头文件只是用来声明，提供编译的时候使用，而链接器会去标准库查找目标文件进行连接。 目标文件在哪儿呢？C语言的目标文件时什么样子的呢？.o吗？还是？

顶啊。C语言库如何连接？自己该怎么写C库？

引用 1 楼 jerry_dqh 的回复:头文件中只是一个声明，标准C库自动链接的。 那标准C库的二进制码在什么地方呢？表示疑惑。

头文件中只是一个声明，标准C库自动链接的。


Question: 求教：麻烦各位牛人给我看看我的程序为什么不能不正确的路径吧（可能是while循环）。多谢。

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

问题就看不懂。代码注意用C格式，否则很少人看的


Question: 关于栈的问题。为什么Push函数top始终是NULL？

StackNode *InitStack(StackNode *top){      top=(StackNode *)malloc(sizeof(StackNode));      top=NULL;      return top;  }  这句话是干嘛的，有问题吧   top=NULL;

引用 2 楼 N_sev7 的回复: #include<stdio.h> #include<malloc.h> #include<string.h> typedef char elemtype; typedef struct stacknode{     elemtype data;     struct stacknode *next; }StackNode; //建栈 StackNode *InitStack(StackNode *top){                  //你这是在做什么？？？？又申请空间，又复制NULL，你到底想干啥？     top=(StackNode *)malloc(sizeof(StackNode));     top=NULL;     return top; } int Judge(StackNode *top){     if(top==NULL)     {         printf("建栈成功.\n");         return 1;     }     else     {         printf("建栈失败！\n");         return 0;     } } //进栈 int Push(StackNode *top){     StackNode *p,*q;     char *ch = (char*)malloc(sizeof(char)*20);        ///只改了一下先把字符串接收完了，     gets(ch);                                                       ////然后逐一分析，具体你的方法该怎么改还没时间帮你看     while('#' != *ch)     {         if(*ch=='{'||*ch=='('||*ch=='['||*ch=='<')         {             p=(StackNode *)malloc(sizeof(StackNode));//如果是左边的，进栈。             p->next=NULL;             p->data=*ch;             p->next=top;             top=p;         }         if(*ch=='}'||*ch==')'||*ch==']'||*ch=='>')         {             if(top==NULL)             {                 printf("栈空.\n");//如果是右边的且top=NULL栈空，说明不平衡。还有符号没有平衡。                 return 0;             }             else             {                 switch(*ch)                 {                 case '{':if(top->data!='}')//如果是右边的且top！=NULL出栈                              return 0;                     else                         break;                 case '(':if(top->data!=')')                              return 0;                     else                         break;                 case '[':if(top->data!=']')                              return 0;                     else                         break;                 case '<':if(top->data!='>')                              return 0;                     else                         break;                 }                 q=top;                 top=top->next;                 free(q);             }         }         ++ch;     }     if(top==NULL)         return 1;     else         return 0; };   int main(){     StackNode *top = NULL;     int k;     //top=InitStack(top);     Judge(top);     printf("请输入带{} () [] <>的字符的字符串以“#”号键结束:");     k=Push(top);     if(k==1)         printf("符号平衡.\n");     else         printf("符号不平衡.\n");     return 0; }   我去，居然回到你那个帖子上去了   谢谢！我的方法我改过来了，不过你的我没懂啊。char *ch = (char*)malloc(sizeof(char)*20);      gets(ch);是什么意思啊？还有我的那个StackNode *InitStack(StackNode *top)是不是也没用，只需要将top=NULL，就可以了？是吗？


Question: 通过ldd命令查看，为什么没有关联到第三方库呢

还是先结帖了，慢慢弄把。

不调动态库的话，不会有依赖关系        a();         linux-gate.so.1 =>  (0xb77a6000)         libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb778f000)         ./libLGM.so (0xb778c000)         libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75e1000)         /lib/ld-linux.so.2 (0xb77a7000)   	//a(); root@ubuntu:/mnt/hgfs/LinuxShare# ldd c         linux-gate.so.1 =>  (0xb77c7000)         libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb77b0000)         libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7606000)         /lib/ld-linux.so.2 (0xb77c8000)

实际调用某个导出的函数，这个没问题，可以调用的。  我进行了。gcc  c.c -lLGM -o c -ldl ，然后用进行了ldd c,但打出的信息确实没有与LGM相关的 正常应该打出来libLGM.so => /usr/lib/libLGM.so (0x00007f6b8fe4e0才对的把  引用 8 楼 zhao4zhong1 的回复:[quote=引用 7 楼 lgmsyy 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 谁说ldd可以列出动态加载的.so来着？ 不能吗？我之前写过一个C程序，在这个C程序中调用过第三方提供的动态链接看，然后生成 SO文件。 我通过ldd 我自己的.so，可以观察到我自己的.so与第三方so的关联。  现在我写的C程序直接调用第三方SO，我以为通过ldd是可以关联的[/quote] 也许是因为你只 dlopen，没实际调用某个导出的函数，被操作系统哪个环节优化掉了也未可知。 试试随便加几句调用某个导出函数的代码，再ldd试试。[/quote]

引用 7 楼 lgmsyy 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 谁说ldd可以列出动态加载的.so来着？ 不能吗？我之前写过一个C程序，在这个C程序中调用过第三方提供的动态链接看，然后生成 SO文件。 我通过ldd 我自己的.so，可以观察到我自己的.so与第三方so的关联。  现在我写的C程序直接调用第三方SO，我以为通过ldd是可以关联的[/quote] 也许是因为你只 dlopen，没实际调用某个导出的函数，被操作系统哪个环节优化掉了也未可知。 试试随便加几句调用某个导出函数的代码，再ldd试试。

引用 6 楼 zhao4zhong1 的回复:谁说ldd可以列出动态加载的.so来着？ 不能吗？我之前写过一个C程序，在这个C程序中调用过第三方提供的动态链接看，然后生成 SO文件。 我通过ldd 我自己的.so，可以观察到我自己的.so与第三方so的关联。  现在我写的C程序直接调用第三方SO，我以为通过ldd是可以关联的

谁说ldd可以列出动态加载的.so来着？

我进行了修正，问题依旧 gcc -fPIC -D_REENTRANT -I/usr/jdk1.8/include -I/usr/jdk1.8/include/linux -c c.c gcc -shared c.o -o libc.so -lLGM  引用 2 楼 neustar1 的回复:另外，你本身没有静态链接，你加上编译选项又有何用呢？你是动态依赖的这个库，所以是不会有关联的。至于你dlopen失败，是库的路径不对。

引用 2 楼 neustar1 的回复:另外，你本身没有静态链接，你加上编译选项又有何用呢？你是动态依赖的这个库，所以是不会有关联的。至于你dlopen失败，是库的路径不对。  我的OPEN是正确的。呵呵，不是失败。

抱歉是我发帖的时候拼写错误：应该是 lLGM，但问题依旧没变。  引用 1 楼 neustar1 的回复:[quote=引用 楼主 lgmsyy 的回复:] 一、c.c文件内容： void *imglib = dlopen("./libLGM.so", RTLD_LAZY);//第三方提供的动态链接库 if(imglib!=NULL){   printf("Open with handle ok !!!\n"); }else{   printf("Open with handle fail !!!\n"); }   二、编译c.c gcc -o c c.c -ldl -g -L. -libLGM  三、ldd c  linux-vdso.so.1 =>  (0x00007fff2f4a5000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8b408cf000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8b4050f000) /lib64/ld-linux-x86-64.so.2 (0x00007f8b40ae6000)  为什么没有关联libLGM.so  四、执行./c的时候是打印出Open with handle ok !!!\ 编译选项写错了 -libLGM         ？？？？？[/quote]

引用 楼主 lgmsyy 的回复:一、c.c文件内容： void *imglib = dlopen("./libLGM.so", RTLD_LAZY);//第三方提供的动态链接库 if(imglib!=NULL){   printf("Open with handle ok !!!\n"); }else{   printf("Open with handle fail !!!\n"); }   二、编译c.c gcc -o c c.c -ldl -g -L. -libLGM  三、ldd c  linux-vdso.so.1 =>  (0x00007fff2f4a5000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8b408cf000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8b4050f000) /lib64/ld-linux-x86-64.so.2 (0x00007f8b40ae6000)  为什么没有关联libLGM.so  四、执行./c的时候是打印出Open with handle ok !!!\ 编译选项写错了 -libLGM         ？？？？？


Question: 求教。。。我想建立一个动态的单链表，两次输入分别确定元素的个数个元素中一个成员的值，然后再主函数中调用并输出单链表。。。但是我写的这个怎么不对。。

多谢

#include <stdio.h> #include <malloc.h>  #define null 0  typedef struct Lnode { 	int data; 	struct Lnode *next; }Linklist;  Linklist *create() { 	Linklist *h = NULL; 	Linklist *p = NULL; 	Linklist *s = NULL; 	int i,n; 	printf("请输入链表元素的个数"); 	scanf("%d",&n);    //////  ERR 1 	h=(Linklist *)malloc(sizeof(Linklist)); 	s=h; 	for(i=0;i < n;)   //ERR 2 	{ 		if (i > 0) 		{ 			h->next = (Linklist *)malloc(sizeof(Linklist)); 			h = h->next; 		} 		p=(Linklist *)malloc(sizeof(Linklist)); 		printf("请输入数据的值"); 		scanf("%d",&p->data); 		h->data = p->data; 		h->next = null; 		++i; 	} 	return s; } main() { 	Linklist *q; 	q=create(); 	while(q != null)  ///ERR 3 	{ 		printf("%d\n",q->data); 		q=q->next; 	} }


Question: libcurl  文件下载

什么情况， 没一个人了。。

大家来看看啊。。。 还有怎么理利用libmicrohttpd库怎么实现REST..


Question: gdb能否调试第三方提供的动态链接库(.so文件)，对方没有提供任何源码，仅仅提供了so文件

引用 14 楼 zhao4zhong1 的回复:不知道使用objdump能否反汇编.so中的汇编指令 Usage: objdump <option(s)> <file(s)>  Display information from object <file(s)>.  At least one of the following switches must be given:   -a, --archive-headers    Display archive header information   -f, --file-headers       Display the contents of the overall file header   -p, --private-headers    Display object format specific file header contents   -h, --[section-]headers  Display the contents of the section headers   -x, --all-headers        Display the contents of all headers   -d, --disassemble        Display assembler contents of executable sections   -D, --disassemble-all    Display assembler contents of all sections   -S, --source             Intermix source code with disassembly   -s, --full-contents      Display the full contents of all sections requested   -g, --debugging          Display debug information in object file   -e, --debugging-tags     Display debug information using ctags style   -G, --stabs              Display (in raw form) any STABS info in the file   -W[lLiaprmfFsoR] or   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]                            Display DWARF info in the file   -t, --syms               Display the contents of the symbol table(s)   -T, --dynamic-syms       Display the contents of the dynamic symbol table   -r, --reloc              Display the relocation entries in the file   -R, --dynamic-reloc      Display the dynamic relocation entries in the file   @<file>                  Read options from <file>   -v, --version            Display this program's version number   -i, --info               List object formats and architectures supported   -H, --help               Display this information

在编译你的测试程序的时候加 -lpthread 选项试试呢， 能否把你的 .so 文件传上来看看

不知道使用objdump能否反汇编.so中的汇编指令

还有能提供线索的没

set step-mode on gdb file c.out b 15 r layout asm 然后进行了以下si动作，得出：  0x0000000000400760 in dlopen@plt () (gdb) si 0x0000000000400766 in dlopen@plt () (gdb) si 0x000000000040076b in dlopen@plt () (gdb) si 0x00000000004006d0 in ?? () (gdb) si 0x00000000004006d6 in ?? () (gdb)   这些信息怎么看啊？？？？ 引用 11 楼 zhao4zhong1 的回复:set step-mode on 打开step-mode模式。在进行单步跟踪时，程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。  还有一个命令(disassemble)可以查看源程序的当前执行时的机器码，这个命令会把目前内存中的指令dump出来。如下面的示例表示查看函数func的汇编代码：

引用 9 楼 zhao4zhong1 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] layout asm：显示反汇编窗口 在反汇编窗口中单步执行下条汇编指令。[/quote]  类似些： (gdb) si si 0x0000000000400766 in dlopen@plt () (gdb) si si 0x000000000040076b in dlopen@plt () (gdb) si si 0x00000000004006d0 in ?? () (gdb)  这也看不明白啊。

引用 6 楼 zhao4zhong1 的回复:layout asm：显示反汇编窗口 在反汇编窗口中单步执行下条汇编指令。

引用 6 楼 zhao4zhong1 的回复:layout asm：显示反汇编窗口 void *imglib = dlopen("./libLGM.so", RTLD_LAZY);//第三方提供的动态链接库 一到调用第三方库的时候就提示以下：  Breakpoint 1 at 0x4008af: file c.c, line 9. (gdb) r Starting program: /home/pcd/workspace/myjava/jni/c   Breakpoint 1, main (argc=1, argv=0x7fffffffe1a8) at c.c:13 (gdb) s [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Cannot find new threads: generic error (gdb)

layout asm：显示反汇编窗口

layout regs：显示源代码/反汇编和CPU寄存器窗口

调试对应汇编指令。

引用 1 楼 user-4 的回复:readelf能看函数名 可以反汇编 readelf libTest.so???具体怎么查看？

这个需要看看编译的时候没有加 -g选项了，没有话，只是一些地址吧！

readelf能看函数名 可以反汇编


Question: 我想利用时钟写个无限弹窗的程序，可是他会自动停止，不知道为什么会出现这个问题，不知道这么解决

检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！

资源耗尽了，亲

引用 楼主 u012211232 的回复: void CALLBACK tanchuang(HWND hwnd,UINT Message,UINT ITimerID,DWORD dwTime) {      SYSTEMTIME stLocal; 	 GetLocalTime(&stLocal); 	 TCHAR strTime[256]; 	 wsprintf(strTime,"%i年%i月%i日 %i:%i:%i",stLocal.wYear,stLocal.wMonth,stLocal.wDay,stLocal.wHour,stLocal.wMinute,stLocal.wSecond); 	 SetDlgItemText(hwnd,IDC_EDIT1,strTime); 	 MessageBox(hwnd,TEXT("haha"),TEXT(""),MB_OK); 	 MessageBox(hwnd,TEXT("haha"),TEXT(""),MB_OK); }   BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { 	SetTimer(hwnd,0,1000,tanchuang);      return TRUE; }  你弹出的是模式对话框，等着你输入呢？这不就停止了嘛

应该是 1.Windows的一种系统自我保护机制或者 2.缺少可分配资源的问题 3.亦或者是每个应用程序所能运行的实例的个数是有限制的  觉得第三种可能性大一些，  记得又一次，我无聊就按住Win+E不放 过了一段时间久不在弹出对话框了


Question: 求解答，某个很简单的问题。链表中的

头插入法就是反序的，尾插入法就是顺序的

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

引用 3 楼 todo9351 的回复:    LNode->next=(*L)->next;    (*L)->next=LNode;   这样操作的话，就是新的节点插在前面，然后你再从前面开始遍历，这样当然是倒过来啦。 小白，不懂什么是代码风格啊。是不是格式？

另，代码风格实在看不下去。不知道是不是楼主不知道呢，还是觉得不重要。

引用 楼主 u014582483 的回复:#include<stdio.h> #include<stdlib.h>  #define size 6 #define ok 1 #define error 0 #define true 1 #define false 0  typedef int Elemtype; typedef int Status;  typedef struct	Node {Elemtype data; struct Node *next; }Node; typedef struct Node *LinkList;  Status InitList(LinkList *L)   {*L=(LinkList)malloc(sizeof(Node)); if(!(*L)){return error;} (*L)->next=NULL; return ok; }  Status ListLength(LinkList L) {int i=0; LinkList p=L->next; while(p) {i++; p=p->next; } return i; }  Status CreatList(LinkList *L,int a[],int n) {int i; LinkList LNode; *L=(LinkList)malloc(sizeof(Node)); (*L)->next = NULL; for (i=0;i<n;i++) {    LNode=(LinkList)malloc(sizeof(Node));    LNode->data=a[i];    LNode->next=(*L)->next;    (*L)->next=LNode; } LNode=*L; return ok; }  void main() {LinkList L; int i,n,a[]={0,1,2,7,4,6}; n=sizeof(a)/sizeof(int); i=InitList(&L); printf("初始化完毕ListLength(L)=%d\n",ListLength(L)); printf("\n"); CreatList(&L,a,n); for(i=0;i<n;i++) { printf("%d ",L->next->data); L=L->next; } printf("\n"); }   我自己写的，为什么输出的时候，顺序是反的呢？ 和你链表插入的方向有关，后插式则输出与插入顺序一致，前插式则相反。

F9 在关键步骤上设置断点 然后 F10  一步一步调试跟踪看变化  链表的问题可以自己动手画图，然后结合你自己的程序， 看画图的结果和程序的运行逻辑过程是不是一样的


Question: 数据结构c 版视频谁讲的通俗易懂啊

《大话数据结构》这本书不错啊

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

我了解的不多，不过我正在看郝斌的数据结构，当初看他的C语言感觉不错，所以现在看他的数据结构，这儿有——http://pan.baidu.com/share/link?shareid=150626133&uk=1647511849#dir/path=%2F%E9%83%9D%E6%96%8C%20%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84

郝斌的视频可以简单的入个门，讲得浅显通俗易懂，但是想提升的话，还是多看书吧。。

严蔚敏。配书看。

最好有实践，其实 严蔚敏奶奶的那一套是一直都经典


Question: DrawText函数的使用

建议楼主亲自阅读include\tchar.h的内容。

“DrawTextW”: 不能将参数 2 从“const char [6]”转换为“LPCWSTR”  这还叫没有错啊.  在VS中编程, 只要用到字符串的地方, 尽量用 _T("")或者TEXT("")包起来.   等你能正确区分环境与串相的参数的填写了, 也可以不用这么写了.  DrawText(hdc,TEXT("hello windows api"), -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);

看看你的hdc有没有问题啊，int DrawText(   HDC hDC,          // handle to DC   LPCTSTR lpString, // text to draw   int nCount,       // text length   LPRECT lpRect,    // formatting dimensions   UINT uFormat      // text-drawing options ); 该函数本质跟画图一样

SetDlgItemText()更好用啊

LPCWSTR 说明你用的是Unicode，使用_T("hello world")

TEXT("Hello")


Question: 关于printf 输出问题

引用 7 楼 zyaiwx 的回复:默认输出缓冲区放不下很多行的。参考赵老师与我所说。 恩，谢了

引用 6 楼 zhao4zhong1 的回复:内容在cmd窗口设定的缓冲行数内放不下，卷到上面去了。  在cmd窗口左上角的图标上点鼠标右键，属性、布局、屏幕缓冲区大小，高度：9999太感谢了~~~~~明白了

默认输出缓冲区放不下很多行的。参考赵老师与我所说。

引用 1 楼 zyaiwx 的回复:应该是因为，你加了%5d后，你的行数大于了控制台的最大行数，所以你最头上819 估计是其中的一部分 行数问题应该不是吧，比如用死循环输出数据，控制台那一直在输出，行数应该比我这个多吧，那时候数据都没出现数据的错误

额，抱歉那是还没运行，不过我调试的时候，变量值是正确的，输出时结果不正确

引用 2 楼 user-3 的回复:设断点，调试，查看变量的值 用了宽度，我调试的时候，fp指针错误。。。不知道怎么回事

设断点，调试，查看变量的值


Question: 关于文件读写请提供一些思路吧，大神

windows API: WritePrivateProfileString

printf("%s%d","OPID=", int_opid_var);

sprintf...

引用 3 楼 buyong 的回复:printf("%s%d","OPID=", int_opid_var); 引用 3 楼 buyong 的回复:printf("%s%d","OPID=", int_opid_var); printf有这个命令？？

引用 5 楼 zhao4zhong1 的回复:难者不会，会者不难： #pragma comment(lib,"ole32") #include <stdio.h> #include <objbase.h> GUID guid; char OPID[8]; char EMMCSN[11]; char fn[15]; unsigned char *p; FILE *f; int main() {     CoCreateGuid(&guid);     p=(unsigned char *)&guid;     sprintf(OPID,"%02X%02X%02X%X",p[0],p[1],p[2],p[3]&0x0F);     sprintf(EMMCSN,"%02X%02X%02X%02X%02X",p[4],p[5],p[6],p[7],p[8]);     sprintf(fn,"%s.txt",EMMCSN);     f=fopen(fn,"w");     if (NULL==f) {         printf("Can not create file %s!\n",fn);         return 1;     }     fprintf(f,"OPID=%s\n",OPID);     fprintf(f,"EMMCSN=%s\n",EMMCSN);     fclose(f);     printf("%s created.\n",fn);     return 0; }   引用 5 楼 zhao4zhong1 的回复:难者不会，会者不难： #pragma comment(lib,"ole32") #include <stdio.h> #include <objbase.h> GUID guid; char OPID[8]; char EMMCSN[11]; char fn[15]; unsigned char *p; FILE *f; int main() {     CoCreateGuid(&guid);     p=(unsigned char *)&guid;     sprintf(OPID,"%02X%02X%02X%X",p[0],p[1],p[2],p[3]&0x0F);     sprintf(EMMCSN,"%02X%02X%02X%02X%02X",p[4],p[5],p[6],p[7],p[8]);     sprintf(fn,"%s.txt",EMMCSN);     f=fopen(fn,"w");     if (NULL==f) {         printf("Can not create file %s!\n",fn);         return 1;     }     fprintf(f,"OPID=%s\n",OPID);     fprintf(f,"EMMCSN=%s\n",EMMCSN);     fclose(f);     printf("%s created.\n",fn);     return 0; }   感谢！你说的太对啦，我们还需要更努力呀，所以还要向前辈们多学学。谢谢，我再研究下

引用 1 楼 u012586257 的回复:你的意思是你会写变量反而不会写常量？ 先定义两个字符串常量 ”OPID=“ 和“EMMCSN=”，创建文件后依次写不就行了么 我刚开始写程式，所以没好的思路，可能我的描述不太正确，所以采集一下大家的意见，谢谢


Question: 用c语言完成，网站图片下载

引用 17 楼 hiroyukki 的回复:[quote=引用 16 楼 beiye90 的回复:] [quote=引用 15 楼 hiroyukki 的回复:] [quote=引用 14 楼 beiye90 的回复:] [quote=引用 12 楼 hiroyukki 的回复:] 建议使用libcurl，如果自己写TCP构造HTTP还是很麻烦的，libcurl很简单地构造HTTP请求。 分如下几步： 1. 将指定的网页内容下载到文件或内存(后面附下载到文件的代码) 2. 字符串分析下载到的内容，找 .jpg .bmp .gif .png 等指定的URL，记录下来。 3. 将2分析出来的所有图片的UTL使用1同样的方式进行下载到文件即可。 附URL下载到文件的示例：   static int _stream_writer(char* data, size_t size, size_t nmemb, FILE* f) {     fwrite(data, size, nmemb, f);     return nmemb * size; }  static int _download_to_file(const char* url, const char* file_name) {     int ret = 1;     FILE* f = 0;      do     {         f = fopen(file_name, "wb");         if (!f)         {             break;         }          curl_easy_setopt(gs_conn, CURLOPT_URL, url);         curl_easy_setopt(gs_conn, CURLOPT_WRITEFUNCTION, _stream_writer);         curl_easy_setopt(gs_conn, CURLOPT_WRITEDATA, f);          if (CURLE_OK == curl_easy_perform(gs_conn))         {             ret = 0;         }     } while (0);      if (f)     {         fclose(f);     }      return ret; } 有没有完整点的代码啊，我得分析下！[/quote] 上面代码是我的代码里抽出来的，原理我也说了，并且这思路一定能实现，自己动手吧，再要代码就是伸手党了，研究使用下libcurl也不错。 我也没用C写过类似你需求的程序，用python写过。[/quote]恩，我现在没有用libcurl，只是获取网站的源代码时放到一个文本里面查找,<img  这字符串 但是怎么输出 后面的链接啊？ 例如

 这个！如何在文本中把链接提取出来！[/quote] 你这是不道德的，N个问题在一个贴里问，连环问啊。 字符串截取这么基础都搞不定吗？比如对于上面的链接你可以这样： 1. 从<img后找第一个 " 位置计做N， N+1开始处即是http:，记做 S 2. 从 S 后找第一个 " 位置计做 M, M - 1处即是 .gif 的 f。记做 E 3. 截取 S - E 间的字串，http://www.baidu.com/img/bdlogo.gif  但HTML本身不像XML一样标准，可能没有"，方法多种多样，自己分析处理吧。[/quote]恩，现在我已经把图片的链接提取出来了，现在剩下最后一步下载图片了！目前不知道怎么办！

引用 15 楼 hiroyukki 的回复:[quote=引用 14 楼 beiye90 的回复:] [quote=引用 12 楼 hiroyukki 的回复:] 建议使用libcurl，如果自己写TCP构造HTTP还是很麻烦的，libcurl很简单地构造HTTP请求。 分如下几步： 1. 将指定的网页内容下载到文件或内存(后面附下载到文件的代码) 2. 字符串分析下载到的内容，找 .jpg .bmp .gif .png 等指定的URL，记录下来。 3. 将2分析出来的所有图片的UTL使用1同样的方式进行下载到文件即可。 附URL下载到文件的示例：   static int _stream_writer(char* data, size_t size, size_t nmemb, FILE* f) {     fwrite(data, size, nmemb, f);     return nmemb * size; }  static int _download_to_file(const char* url, const char* file_name) {     int ret = 1;     FILE* f = 0;      do     {         f = fopen(file_name, "wb");         if (!f)         {             break;         }          curl_easy_setopt(gs_conn, CURLOPT_URL, url);         curl_easy_setopt(gs_conn, CURLOPT_WRITEFUNCTION, _stream_writer);         curl_easy_setopt(gs_conn, CURLOPT_WRITEDATA, f);          if (CURLE_OK == curl_easy_perform(gs_conn))         {             ret = 0;         }     } while (0);      if (f)     {         fclose(f);     }      return ret; } 有没有完整点的代码啊，我得分析下！[/quote] 上面代码是我的代码里抽出来的，原理我也说了，并且这思路一定能实现，自己动手吧，再要代码就是伸手党了，研究使用下libcurl也不错。 我也没用C写过类似你需求的程序，用python写过。[/quote]恩，我现在没有用libcurl，只是获取网站的源代码时放到一个文本里面查找,<img  这字符串 但是怎么输出 后面的链接啊？ 例如

 这个！如何在文本中把链接提取出来！

引用 16 楼 beiye90 的回复:[quote=引用 15 楼 hiroyukki 的回复:] [quote=引用 14 楼 beiye90 的回复:] [quote=引用 12 楼 hiroyukki 的回复:] 建议使用libcurl，如果自己写TCP构造HTTP还是很麻烦的，libcurl很简单地构造HTTP请求。 分如下几步： 1. 将指定的网页内容下载到文件或内存(后面附下载到文件的代码) 2. 字符串分析下载到的内容，找 .jpg .bmp .gif .png 等指定的URL，记录下来。 3. 将2分析出来的所有图片的UTL使用1同样的方式进行下载到文件即可。 附URL下载到文件的示例：   static int _stream_writer(char* data, size_t size, size_t nmemb, FILE* f) {     fwrite(data, size, nmemb, f);     return nmemb * size; }  static int _download_to_file(const char* url, const char* file_name) {     int ret = 1;     FILE* f = 0;      do     {         f = fopen(file_name, "wb");         if (!f)         {             break;         }          curl_easy_setopt(gs_conn, CURLOPT_URL, url);         curl_easy_setopt(gs_conn, CURLOPT_WRITEFUNCTION, _stream_writer);         curl_easy_setopt(gs_conn, CURLOPT_WRITEDATA, f);          if (CURLE_OK == curl_easy_perform(gs_conn))         {             ret = 0;         }     } while (0);      if (f)     {         fclose(f);     }      return ret; } 有没有完整点的代码啊，我得分析下！[/quote] 上面代码是我的代码里抽出来的，原理我也说了，并且这思路一定能实现，自己动手吧，再要代码就是伸手党了，研究使用下libcurl也不错。 我也没用C写过类似你需求的程序，用python写过。[/quote]恩，我现在没有用libcurl，只是获取网站的源代码时放到一个文本里面查找,<img  这字符串 但是怎么输出 后面的链接啊？ 例如

 这个！如何在文本中把链接提取出来！[/quote] 你这是不道德的，N个问题在一个贴里问，连环问啊。 字符串截取这么基础都搞不定吗？比如对于上面的链接你可以这样： 1. 从<img后找第一个 " 位置计做N， N+1开始处即是http:，记做 S 2. 从 S 后找第一个 " 位置计做 M, M - 1处即是 .gif 的 f。记做 E 3. 截取 S - E 间的字串，http://www.baidu.com/img/bdlogo.gif  但HTML本身不像XML一样标准，可能没有"，方法多种多样，自己分析处理吧。

引用 14 楼 beiye90 的回复:[quote=引用 12 楼 hiroyukki 的回复:] 建议使用libcurl，如果自己写TCP构造HTTP还是很麻烦的，libcurl很简单地构造HTTP请求。 分如下几步： 1. 将指定的网页内容下载到文件或内存(后面附下载到文件的代码) 2. 字符串分析下载到的内容，找 .jpg .bmp .gif .png 等指定的URL，记录下来。 3. 将2分析出来的所有图片的UTL使用1同样的方式进行下载到文件即可。 附URL下载到文件的示例：   static int _stream_writer(char* data, size_t size, size_t nmemb, FILE* f) {     fwrite(data, size, nmemb, f);     return nmemb * size; }  static int _download_to_file(const char* url, const char* file_name) {     int ret = 1;     FILE* f = 0;      do     {         f = fopen(file_name, "wb");         if (!f)         {             break;         }          curl_easy_setopt(gs_conn, CURLOPT_URL, url);         curl_easy_setopt(gs_conn, CURLOPT_WRITEFUNCTION, _stream_writer);         curl_easy_setopt(gs_conn, CURLOPT_WRITEDATA, f);          if (CURLE_OK == curl_easy_perform(gs_conn))         {             ret = 0;         }     } while (0);      if (f)     {         fclose(f);     }      return ret; } 有没有完整点的代码啊，我得分析下！[/quote] 上面代码是我的代码里抽出来的，原理我也说了，并且这思路一定能实现，自己动手吧，再要代码就是伸手党了，研究使用下libcurl也不错。 我也没用C写过类似你需求的程序，用python写过。

引用 12 楼 hiroyukki 的回复:建议使用libcurl，如果自己写TCP构造HTTP还是很麻烦的，libcurl很简单地构造HTTP请求。 分如下几步： 1. 将指定的网页内容下载到文件或内存(后面附下载到文件的代码) 2. 字符串分析下载到的内容，找 .jpg .bmp .gif .png 等指定的URL，记录下来。 3. 将2分析出来的所有图片的UTL使用1同样的方式进行下载到文件即可。 附URL下载到文件的示例：   static int _stream_writer(char* data, size_t size, size_t nmemb, FILE* f) {     fwrite(data, size, nmemb, f);     return nmemb * size; }  static int _download_to_file(const char* url, const char* file_name) {     int ret = 1;     FILE* f = 0;      do     {         f = fopen(file_name, "wb");         if (!f)         {             break;         }          curl_easy_setopt(gs_conn, CURLOPT_URL, url);         curl_easy_setopt(gs_conn, CURLOPT_WRITEFUNCTION, _stream_writer);         curl_easy_setopt(gs_conn, CURLOPT_WRITEDATA, f);          if (CURLE_OK == curl_easy_perform(gs_conn))         {             ret = 0;         }     } while (0);      if (f)     {         fclose(f);     }      return ret; } 有没有完整点的代码啊，我得分析下！

使用WebSeizer软件。

引用 8 楼 kang2618 的回复:知道用java有第三方的类库，去模拟浏览器抓网页和解析，c语言不知道 不管什么语言，原理都是一样的，只是Java比较方便，可以用现成的库，c语言的话要自己一点一滴的去实现

引用 6 楼 kankan231 的回复:首先要知道tcp协议和http协议，利用http协议获取网页内容，然后用正则匹配所有图片标签，获取到图片的url，在用http协议去请求图片就可以了  是这样的。楼主要是没接触过，实现起来还是有点难度的。不过要是通过自己动手实现了，会很有成就感的

假设该基本HTML文件的URL为:www.xxx.com/path/index.html。 　　下面是具体步骡: 　　1.HTTP客户初始化一个与服务器主机www.xxx.com中的HTTP服务器的TCP连接。HTTP服务器使用默认端口号80监听来自HTTP客户的连接建立请求。 　　2.HTTP客户经由与TCP连接相关联的本地套接字发出—个HTTP请求消息。这个消息中包含路径名/path/index.html。 　　3.HTTP服务器经由与TCP连接相关联的本地套接字接收这个请求消息，再从服务器主机的内存或硬盘中取出对象/path/index.html，经由同一个套接字发出包含该对象的响应消息。 　　4.HTTP服务器告知TCP关闭这个TCP连接(不过TCP要到客户收到刚才这个响应消息之后才会真正终止这个连接)。        (非持久连接) 　　5.HTTP客户经由同一个套接字接收这个响应消息。TCP连接随后终止。该消息标明所封装的对象是一个HTML文件。客户从中取出这个文件，加以分析后发现其中有若干个图片对象的引用。 　　6.给每一个引用到的图片对象重复步骡1-4。         例如对 www.xxx.com/path/pic/xx.jpg 重复1-4。 可以使用相关的http库来完成  例如 WINHTTP。库可以自行选择。

大早上的，没人吗？

引用 2 楼 zxh707wk 的回复:只会c本地程序设计，不会网络编程额....这个好像网络那块挺多的...

只会c本地程序设计，不会网络编程

类似于这样类型的！

哎 我也正在学习这方面的  对自动搜集非常感兴趣

知道用java有第三方的类库，去模拟浏览器抓网页和解析，c语言不知道


Question: 求教C C++中 如何给字符串设条件

字符串不能直接== 需要借助额外的的一个一个字符的判断是否一致问题

C语言的话不能直接用==比较，而要用strcmp；如果是C++的话，在定义a是直接用String类型就可以了

如果是c++ 的 string 类可以 因为重写了==  #include<stdio.h> #include <string.h> void main() { 	char a[30]; 	scanf("%s",a); 	if(strcmp(a,"Yes")==0||strcmp(a,"yes")==0) 		printf("welcome!"); 	else printf("end!\n"); }   如果是c++ #include <iostream> #include <string> using namespace  std;  void main() { 	string a; 	cin>>a; 	if(a=="yes"||a=="Yes") 		printf("welcome!"); 	else printf("end!\n"); }   楼主思路没错 概念欠缺一点...


Question: 直线倒立摆 C语言模糊控制算法

这么专业性强的东西一般很少能遇到懂的吧 到百度上搜一下相关的论文看下吧 我搜了一下，感觉还是蛮多的 不过那么多都是数学计算！！！


Question: qt中怎样使用c语言编写成动态库？

一、如何编写DLL，可以参考http://blog.csdn.net/n_sev7/article/details/19368431（图片无法显示，可以到QQ空间看：284941821） 二、Qt中如何调用DLL中的功能函数，可以参考网上的这篇        http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810239.html  注：其实我也没用过，只是帮你搜一下而已！更好的文章就等着你自己慢慢搜了


Question: 新手求助

for(i=0;i<10;i++) { if(a[i] =0) continue ; else printf("不全是0"); }

引用 8 楼 u014539580 的回复:[quote=引用 2 楼 baichi4141 的回复:] 不能，只能一个元素一个元素比较 数量少的话直接写，数量多或者不定的话用循环  int F(int A[])     {         int i=0,j=0;         for(i=0;i<10;i++)         {             if(a[i]==0) j++;         }         if(j==10) return(1);         else return(0);     }大神帮忙看看，为什么会出现error C2601: 'F' : local function definitions are illegal这个错误[/quote]    你代码里面是不是没有主函数啊，还有F的形参是A[]，后面的数组写成a[]了

用for循环吧，只能一个一个元素的判断

不行！循环判断吧！

local 局部 function 函数 definitions 定义 are 是 illegal 非法的  不能在一个函数中定义另一个函数 不要求你精通英语，起码要会用字典

引用 2 楼 baichi4141 的回复:不能，只能一个元素一个元素比较 数量少的话直接写，数量多或者不定的话用循环  int F(int A[])     {         int i=0,j=0;         for(i=0;i<10;i++)         {             if(a[i]==0) j++;         }         if(j==10) return(1);         else return(0);     }大神帮忙看看，为什么会出现error C2601: 'F' : local function definitions are illegal这个错误

引用 6 楼 lzhui1987 的回复: #include<stdio.h> int main() {   int a[10]={};   for(int ix=0;ix<10;ix++)//遍历数组元素   {     if(a[ix]==0)           printf("a[%d]等于0\n",ix);   }     return 0; }   额  发错了上面的。。。。 正宗手打，只为得分。。。    int F(int A[])     {         int i=0,j=0;         for(i=0;i<10;i++)         {             if(a[i]==0) j++;         }         if(j==10) return(1);         else return(0);     }大神帮忙看看，为什么会出现error C2601: 'F' : local function definitions are illegal这个错误

#include<stdio.h> int main() {   int a[10]={};   for(int ix=0;ix<10;ix++)//遍历数组元素   {     if(a[ix]==0)           printf("a[%d]等于0\n",ix);   }  正宗手打，只为得分。。。   return 0; }

你如果这样写a[10],那只是进行了一个元素的判断，而却你这个元素还是越界的

你需要对每个元素逐个判断，通过循环实现。只要找到一个非零，那么这个数组就不全是0哈

不能，只能一个元素一个元素比较 数量少的话直接写，数量多或者不定的话用循环

不是啊，a[10]已经越界了。遍历判断。


Question: 16进制数 与 uint8_t 数据类型转换

严重怀疑不带长度的transmit函数如何工作。

引用 9 楼 xiaohuh421 的回复:因为函数的定义决定了你只能专指针,  如果你想输入常数, 那么你就需要想办法得到常数的地址.  因为常数就是一个立即数, 是没有存储空间的. 但函数又需要空间的地址  所以, 只能使用中间变量了. 我理解了。 现在已经解决了。也是通过再封装一个。 void transmit1(uint8_t data)  { 	const uint8_t *data11 = &data; 	transmit(data11); }   这样避免了修改接口，也避免了把要传输的数据先放在一个表里再一个个拿出来了。   谢谢，分给你。

如果这样的代码: const uint8_t a = 0xAA; transmit(&a); 你都懒得写.  那么你可以再封装一个函数出来 transmit( uint8_t  val) {      transmit(&val); } 好了, 现在你可以这样调用了 transmit(0x20);

引用 2 楼 xiaohuh421 的回复:只要你保证字节数不变即可.  内存中不管哪种数据类型基本单位都是字节, 只是占用字节不同而以.  int   intBuf[100] ; short   shBuf[100] char chBuf[100];  transmit( (const uint8_t*)intBuf);  发送 100*4字节   (假设int为4字节, int8_t为1字节) transmit( (const uint8_t*)shBuf);  发送 100*2字节  (假设short为2字节) transmit( (const uint8_t*)chBuf);  发送100字节. 谢谢回复。 字节数不变，所有数据都是8bit。0x20, 0x21....但是不能强制转换作为参数传入的数据。 比如transmit((const uint8_t *)0x20);这样不可以。。  我知道可以这样： const uint8_t a = 0xAA; transmit(&a);  但是我希望能够把数据直接作为传入参数。有什么其他办法么？谢谢。

引用 3 楼 zhao4zhong1 的回复:严重怀疑不带长度的transmit函数如何工作。 谢谢回复。 有其他参数，包括长度，我只给了这个有关的接口。。 spi_master_tx_rx(uint32_t *spi_base_address, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data)

引用 1 楼 u012586257 的回复:我觉得可以直接转吧，有什么问题吗？都是无符号8位整数 比如 unsigned char c  = 0xAC; transmit((uint8_t *)&c); 谢谢回复。 确实，你这样写是可以的。但是这就要我把所有需要传输的数据都先定义在一个数组里。。而我希望是能直接把0xAC这样的数据作为参数给函数直接使用。。

引用我需要传输一些16进制的数，比如0x11, 0xAC之类的。但是可用的传输函数接口如下： transmit(const uint8_t *tx)  1 16进制的字符串 “0x1123456789”这样，还是int的16进制数。这个处理是不一样的。 2 transmit(const uint8_t *tx) 这个函数的入口参数是什么意思，你是要传字符串的首地址吗，亲


Question: C++的特点是不是相当于无需自己写typedef struct{}...的C?

不是


Question: mfc这个库只在VC++中有吗（不考虑VS）？

奇怪，这问题都没人回答啊


Question: C语言有现成的树函数或链表吗？还是需要自己实现？

引用 2 楼 u014541584 的回复:[quote=引用 1 楼 u010570670 的回复:] 有这样的需求不要用C，用C++。 你还没说有还是没有呢！[/quote] 没仔细研究过C的标准，不过标准库里有的可能性很小，一般都自己写，要不用容器。

引用 1 楼 u010570670 的回复:有这样的需求不要用C，用C++。 你还没说有还是没有呢！

有这样的需求不要用C，用C++。


Question: 为什么结构要包含进头文件而不能用extern来调用？

不要自己发明概念，调用这个词没有你这么用的，除非你自己发明一门编程语言否则请遵守公用定义 extern是声明而不是定义，只告知编译器有这么一个名字的东西没有告知编译器关于这东西的任何细节，代码里要对一个结构体操作的时候必须知道这个结构体的细节，因此在该行代码前必须出现这个结构体的定义

比如说我在一个原文件中main（）函数前声明了一个结构 typedef struct { ... ...} Var； 然后我想在其他文件中引用

引用 4 楼 u014541584 的回复:[quote=引用 3 楼 user-2 的回复:] [quote=引用 2 楼 u014541584 的回复:] [quote=引用 1 楼 user-2 的回复:] extern是用来声明的 你说的调用是指？？ 不是吧，extren是用来调用在别的源文件中的全局变量声明，我的意思是想如此调用结构声明： extern struct TAB var;[/quote]  调用一般指的是call or invoke 一般我们所认为的就是函数调用，如果说对变量进行使用，我们可以说引用，也可以说使用，但是调用有点歧义。  extern struct TAB var;这句话的意思是var这个变量可以再其他文件中定义 [/quote] 我的意思是，为什么extern引用结构声明是错误的？而必须要把结构包含在一个头文件中再#include？[/quote]  什么叫引用结构声明

引用 3 楼 user-2 的回复:[quote=引用 2 楼 u014541584 的回复:] [quote=引用 1 楼 user-2 的回复:] extern是用来声明的 你说的调用是指？？ 不是吧，extren是用来调用在别的源文件中的全局变量声明，我的意思是想如此调用结构声明： extern struct TAB var;[/quote]  调用一般指的是call or invoke 一般我们所认为的就是函数调用，如果说对变量进行使用，我们可以说引用，也可以说使用，但是调用有点歧义。  extern struct TAB var;这句话的意思是var这个变量可以再其他文件中定义 [/quote] 我的意思是，为什么extern引用结构声明是错误的？而必须要把结构包含在一个头文件中再#include？

引用 2 楼 u014541584 的回复:[quote=引用 1 楼 user-2 的回复:] extern是用来声明的 你说的调用是指？？ 不是吧，extren是用来调用在别的源文件中的全局变量声明，我的意思是想如此调用结构声明： extern struct TAB var;[/quote]  调用一般指的是call or invoke 一般我们所认为的就是函数调用，如果说对变量进行使用，我们可以说引用，也可以说使用，但是调用有点歧义。  extern struct TAB var;这句话的意思是var这个变量可以再其他文件中定义

引用 1 楼 user-2 的回复:extern是用来声明的 你说的调用是指？？ 不是吧，extren是用来调用在别的源文件中的全局变量声明，我的意思是想如此调用结构声明： extern struct TAB var;

extern是用来声明的 你说的调用是指？？


Question: oj上一道题就是ac不掉，，，测试好多没有错呀

你先把代码里所有下标溢出的地方全修了再说。


Question: 关于字符串地址的问题

谢谢各位的耐心解答，在这个帖子中，我了解到了： 1. memcpy()、strcpy()、memset()的几种用法 2.对‘\0’的概念更清楚了

int Init(struct buffer *Buf, char *head_ptr_1, char *head_ptr_2)     {          memset(Buf->packet_head_1, 0, sizeof(Buf->packet_head_1) );          memset(Buf->packet_head_2, 0, sizeof(Buf->packet_head_2) );          strcpy(Buf->packet_head_1, head_ptr_1);          strcpy(Buf->packet_head_2, head_ptr_2);     } strcpy的时候注意数组越界

c++的字符串是以“\0”结束的，packet_head_1[4]相当于一个指针没有遇到“\0”就不会停止的。

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

数组访问越界

引用 1 楼 relaxisland 的回复:char packet_head_1[4]; -----> char packet_head_1[5]; 字符数组如果要当做字符串来使用， 其长度 应该 比 字符的个数多一个。 比把多余的哪一个设置为0x00 也就是\0  这是字符串的结束标识符， C语言是考这个来定位 字符串结束的地方。 谢谢relaxisland，我试过把长度增加为20，但是Buf->packet_head_1最后得到的值到最后还是"$ABC????????????$DEF\"，而我后面的程序是想用strcmp()比较一个temp[4]和Buf->packet_head_1的值，这样的话即使temp[4]内的值是"$ABC"，但是用strcmp()还是会得到两者不同的结果。

你这是字符数组，就不要当做字符串看了； 需要字符串的话直接 多定义几个字节strcpy； 字符数组，当字符串还是数组用主要还在乎你自己。  Debug的时候，VC6调试器，把字符数组当做字符串看了，所以就显示一大串。 他会不辞辛苦的一直找到'\0'为止。 你需要调试数组，就一个一个看每个元素，不要被VC6调试器迷惑了。

引用 2 楼 conanson 的回复:[quote=引用 1 楼 relaxisland 的回复:] char packet_head_1[4]; -----> char packet_head_1[5]; 字符数组如果要当做字符串来使用， 其长度 应该 比 字符的个数多一个。 比把多余的哪一个设置为0x00 也就是\0  这是字符串的结束标识符， C语言是考这个来定位 字符串结束的地方。 谢谢relaxisland，我试过把长度增加为20，但是Buf->packet_head_1最后得到的值到最后还是"$ABC????????????$DEF\"，而我后面的程序是想用strcmp()比较一个temp[4]和Buf->packet_head_1的值，这样的话即使temp[4]内的值是"$ABC"，但是用strcmp()还是会得到两者不同的结果。[/quote] int Init(struct buffer *Buf, char *head_ptr_1, char *head_ptr_2)     {         int i;         for (i = 0; i < 4; i++){             Buf->packet_head_1[i] = *(head_ptr_1 + i);             Buf->packet_head_2[i] = *(head_ptr_2 + i);         }           Buf->packet_head_1[4] = ‘\0’;            Buf->packet_head_2[4] = ‘\0’;     }

Buf->packet_head_1[i] = *(head_ptr_1 + i);         Buf->packet_head_2[i] = *(head_ptr_2 + i);  memcpy

引用 2 楼 conanson 的回复:[quote=引用 1 楼 relaxisland 的回复:] char packet_head_1[4]; -----> char packet_head_1[5]; 字符数组如果要当做字符串来使用， 其长度 应该 比 字符的个数多一个。 比把多余的哪一个设置为0x00 也就是\0  这是字符串的结束标识符， C语言是考这个来定位 字符串结束的地方。 谢谢relaxisland，我试过把长度增加为20，但是Buf->packet_head_1最后得到的值到最后还是"$ABC????????????$DEF\"，而我后面的程序是想用strcmp()比较一个temp[4]和Buf->packet_head_1的值，这样的话即使temp[4]内的值是"$ABC"，但是用strcmp()还是会得到两者不同的结果。[/quote] 应该在你想结束的地方 设置为 0 啊 或者字符数组赋值前，把所有的的元素 初期化为 0x00


用sprintf不行吗？

char buf[10]={0}; int i=sprintf_s(buf,12,"a");  函数原型： int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... );


Question: 我用的C-free编C语言。最近一件诡异的事。

已经解决了。 把C-free卸载，注册表所有关于它的记录全删，关于C-FREE的文件也全删。再重装就好了、。

引用 楼主 Forthe2012 的回复:我构建并运行所有程序代码时，都是这样的提示：  完成构建：0错误 0警告 运行。  就这样了。看起来是正常的提示。但我的代码明明有输出（包括简单如helloworld这种代码），可运行时没有控制台窗口出现。。。  我疑惑，于是故意改代码，把int main（）改成int min（）  结果还是提示我： 完成构建：0错误 0警告 运行。  看来不是软件，就是我电脑问题了。卸了重装，不行，又把系统还原，还是不行。。。  这是怎么回事？？ 为什么你认为没有main，就一定不能编过呢

http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装

把编译生成的一些文件都删除了吧！

引用我疑惑，于是故意改代码，把int main（）改成int min（）  哈哈，太有才了，main 是入口函数。  另 C-free是要收费的。壕

直接按 F5 编译运行

clean + rebuild all 没有显示console window? 加 system("pause");

没有控制台窗口出现？你试下开始执行不调试看看


Question: error C2064: term does not evaluate to a functio

sum()函数与局部变量sum重名了


Question: 关于int main()的问题

[quote=引用 1 楼 user-1 的回复:] 1，2是一样的，都是不带参数的。 3，4是带参数的。 3和4的区别： 虽然看起来不太一样，但是还是一样的。 3中的argv是个数组，数组中的数据是char *，此时argv就是这个char*数组的首地址，也就是指向char*的指针，也就是char **argv。[/quote谢谢34大哥，明白了~


Question: SWU if结构的使用

引用 2 楼 XWL1992 的回复:"="是赋值运算符，“==”是等于运算符，你要判断两个表达式是否相等，你应该使用等于运算符。所以你应该这样写:if(a == 5.5)  对浮点数进行相等判断是非常危险的。因为变量的值完全可能为5.5000001或者5.4999999之类的。 另外标题前缀应该是[SWU]，你忘记中括号了。

引用 4 楼 Falleyes 的回复:float a; do{    scanf("%d",&a);    if(a==5.5){       printf("t\n");       break;   //得到正确的值终止    }    else       printf("w\n"); while(1);   //一直为真，一直循环，直到内部跳出  补充一点，如果你想让人家继续回答，就引用别人那一楼层，这样别人的消息栏里面就能看到你的话。要不然，还要找到这个问题，进来看一看你有没有回复人家，很麻烦的。每一楼层右下角都有引用 谢谢，以后知道了 引用 4 楼 Falleyes 的回复:float a; do{    scanf("%d",&a);    if(a==5.5){       printf("t\n");       break;   //得到正确的值终止    }    else       printf("w\n"); while(1);   //一直为真，一直循环，直到内部跳出  补充一点，如果你想让人家继续回答，就引用别人那一楼层，这样别人的消息栏里面就能看到你的话。要不然，还要找到这个问题，进来看一看你有没有回复人家，很麻烦的。每一楼层右下角都有引用 谢谢，以后知道了

这和浮点数的存储原理有关系，浮点数的精度是有限的。

引用 7 楼 u013978386 的回复:[quote=引用 6 楼 arthuryangsh 的回复:] [quote=引用 2 楼 XWL1992 的回复:] "="是赋值运算符，“==”是等于运算符，你要判断两个表达式是否相等，你应该使用等于运算符。所以你应该这样写:if(a == 5.5)  对浮点数进行相等判断是非常危险的。因为变量的值完全可能为5.5000001或者5.4999999之类的。 另外标题前缀应该是[SWU]，你忘记中括号了。[/quote]  引用 6 楼 arthuryangsh 的回复:[quote=引用 2 楼 XWL1992 的回复:] "="是赋值运算符，“==”是等于运算符，你要判断两个表达式是否相等，你应该使用等于运算符。所以你应该这样写:if(a == 5.5)  对浮点数进行相等判断是非常危险的。因为变量的值完全可能为5.5000001或者5.4999999之类的。 另外标题前缀应该是[SWU]，你忘记中括号了。[/quote]   搬砖点错了，哈哈，一定遵守，哈哈 变量的值为什么会变？[/quote]因为计算机计算数据长度是有限的，而且有国际上的数据处理标准（什么时候四舍五入，浮点数归0啊什么的），这个你可以涉及一下计算机组成原理。

引用 6 楼 arthuryangsh 的回复:[quote=引用 2 楼 XWL1992 的回复:] "="是赋值运算符，“==”是等于运算符，你要判断两个表达式是否相等，你应该使用等于运算符。所以你应该这样写:if(a == 5.5)  对浮点数进行相等判断是非常危险的。因为变量的值完全可能为5.5000001或者5.4999999之类的。 另外标题前缀应该是[SWU]，你忘记中括号了。[/quote]  引用 6 楼 arthuryangsh 的回复:[quote=引用 2 楼 XWL1992 的回复:] "="是赋值运算符，“==”是等于运算符，你要判断两个表达式是否相等，你应该使用等于运算符。所以你应该这样写:if(a == 5.5)  对浮点数进行相等判断是非常危险的。因为变量的值完全可能为5.5000001或者5.4999999之类的。 另外标题前缀应该是[SWU]，你忘记中括号了。[/quote]   搬砖点错了，哈哈，一定遵守，哈哈 变量的值为什么会变？

奥，明白了，谢谢楼上诸位。    再问一个问题：           上面的循环只能够执行一次，如果我想要多次执行判断，也就是说，不断的输入值，判断正误，指导得到正确值为止。    应该怎么设计循环呢？  能不能劳烦再指点一下哈。


Question: 求大侠帮忙，关于C语言查找文件中对应的记录问题

引用 1 楼 zxhuser-1 的回复:用一个临时变量存储“无匹配记录”的个数 感谢回复，如果我不确定csv中某年的记录个数，那应该怎么办？具体怎么实现，能在教教我吗？不甚感激...

用一个临时变量存储“无匹配记录”的个数

我用单项链表动态创建存储的 具体可以参考一下我的统计成绩的代码 下载地址： http://pan.baidu.com/s/1ntuNH0X


Question: vc能测试函数吗？如果能的话，请教之。

可以直接调试啊

单元测试，用cppunit

莫非你说的是断点

我是一个新手，在自学c，可能一些表达不是太正确。就是对一些函数的功能，能一些让他run一下嘛？从而判断这个函数靠谱不靠谱？

目测是 设置断点

引用 楼主 u014082409 的回复:弱弱问一下大家，vc6.0能测试函数吗？如果能的话，该如何操作，请教之。 请说普通话

难道测试不能的函数有不同的测试标准吗？

你想怎么测试函数


Question: 关于栈的问题。if语句里面哪里错了啊？

#include<stdio.h> #include<malloc.h> #include<string.h> #define STACK_INIT_SIZE 10 #define STACK_GROW_SIZE 5 #define ELEMTYPE char #define OK 1 #define ERROR 0 typedef struct { /*建立一个栈的首结点*/     ELEMTYPE * base;     ELEMTYPE * top;     int stacksize; } SpStack; int InitStack(SpStack *s) { /*建立空的栈并返回首地址*/     s->base=((ELEMTYPE*)malloc(STACK_INIT_SIZE*sizeof(ELEMTYPE)));     if (!s->base) return ERROR;     s->top=s->base;     s->stacksize=STACK_INIT_SIZE;     return OK; } int StackEmpty(SpStack *s) { /*判断栈是否为空*/     if (s->top==s->base) return OK;     else                 return ERROR; } int Push(SpStack *s,ELEMTYPE e) { /*往栈顶插入元素即进栈*/     if (s->top-s->base>=s->stacksize) { /*判断是否栈满*/         s->base=((ELEMTYPE*)realloc(s->base,(s->stacksize+STACK_GROW_SIZE)*sizeof(ELEMTYPE)));         if (!s->base) return ERROR;         s->stacksize+=STACK_GROW_SIZE;         s->top=s->base+s->stacksize;     }     *s->top++=e;     return OK; } int Pop(SpStack *s,ELEMTYPE *e) { /*让栈顶元素依次输出即出栈*/     if (StackEmpty(s)) return ERROR;     *e=*(--s->top);     return OK; } int Comp(ELEMTYPE a,ELEMTYPE b) {     if ((a=='('&&b!=')')       ||(a=='['&&b!=']')       ||(a=='{'&&b!='}')) {         return ERROR;     } else return OK; } int Count(SpStack *s) {     ELEMTYPE e[STACK_INIT_SIZE*2];     ELEMTYPE e1;     int i;      InitStack(s);     fgets(e,STACK_INIT_SIZE*2,stdin);     if ('\n'==e[strlen(e)-1]) e[strlen(e)-1]=0;     printf("%s\n",e);     for (i=0;e[i]!='\0';i++) {         switch (e[i]) {         case '(':         case '[':         case '{':             Push(s,e[i]);             break;         case ')':         case ']':         case '}':             if (StackEmpty(s)) {                 printf("%*s↖右括号多余\n",i+1,"");                 return(ERROR);             } else Pop(s,&e1);             if (!Comp(e1,e[i])) {                 printf("%*s↖左右匹配出错\n",i+1,"");                 return(ERROR);             }         }     }     if (!StackEmpty(s)) {         printf("%*s↖左括号多余\n",i,"");         return(ERROR);     } else {         printf("匹配正确\n");         return(OK);     } } void main() {     SpStack s;     Count(&s);     free(s.base); }

我去，回错帖子了

#include<stdio.h> #include<malloc.h> #include<string.h> typedef char elemtype; typedef struct stacknode{     elemtype data;     struct stacknode *next; }StackNode; //建栈 StackNode *InitStack(StackNode *top){                  //你这是在做什么？？？？又申请空间，又复制NULL，你到底想干啥？     top=(StackNode *)malloc(sizeof(StackNode));     top=NULL;     return top; } int Judge(StackNode *top){     if(top==NULL) 	{ 		printf("建栈成功.\n"); 		return 1; 	}     else     {         printf("建栈失败！\n");         return 0;     } } //进栈 int Push(StackNode *top){     StackNode *p,*q;     char *ch = (char*)malloc(sizeof(char)*20);        ///只改了一下先把字符串接收完了， 	gets(ch);                                                       ////然后逐一分析，具体你的方法该怎么改还没时间帮你看     while('#' != *ch) 	{ 		if(*ch=='{'||*ch=='('||*ch=='['||*ch=='<')         {             p=(StackNode *)malloc(sizeof(StackNode));//如果是左边的，进栈。             p->next=NULL;             p->data=*ch;             p->next=top;             top=p;         }         if(*ch=='}'||*ch==')'||*ch==']'||*ch=='>')         {             if(top==NULL) 			{ 				printf("栈空.\n");//如果是右边的且top=NULL栈空，说明不平衡。还有符号没有平衡。 				return 0; 			}             else 			{ 				switch(*ch) 				{ 				case '{':if(top->data!='}')//如果是右边的且top！=NULL出栈 							 return 0; 					else 						break; 				case '(':if(top->data!=')') 							 return 0; 					else 						break; 				case '[':if(top->data!=']') 							 return 0; 					else 						break; 				case '<':if(top->data!='>') 							 return 0; 					else 						break; 				} 				q=top; 				top=top->next; 				free(q); 			}         } 		++ch;     }     if(top==NULL)         return 1;     else         return 0; };  int main(){ 	StackNode *top = NULL; 	int k; 	//top=InitStack(top); 	Judge(top); 	printf("请输入带{} () [] <>的字符的字符串以“#”号键结束:"); 	k=Push(top); 	if(k==1) 		printf("符号平衡.\n"); 	else 		printf("符号不平衡.\n"); 	return 0; }

引用 1 楼 user-4 的回复:                if(s==top->data)                 {                     q=(StackNode *)malloc(sizeof(StackNode));                     q->next=NULL;                     q=top->data;                     top=top->next;                     free(q);                 }   这里释放的是刚分配的内存，原来栈里面的没有释放 楼上正解，应该是q = top; top = top->next;free(p);


Question: hash函数：为字符串s生成散列值。

请问这不是就是传说中数据结构里面哈希表的问题啊？

算法问题。。。

函数的散列值值要这么求是约定俗成的规矩吗？

标题不是说这个函数是做散列值的吗？


Question: 自学C语言,一模一样对着例题敲的代码,却死活通不过,郁闷啊!求教!

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

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

lz粗心了。。

一般都是粗心大意的错。

引用 7 楼 u014571910 的回复:可是为什么我就一点点错误,它提示出错那么多?这个错误提示的意思是什么呢? 编译器看不出代码里你那里写错了，它只能把你的错误代码编译成程序，直到某个地方没办法编译了才报错 所以你一个小笔误可能会导致一系列需要这个地方正确写法的地方出错，编译器报错也未必就是你写错的那个地方 还是那句话，如果编译器能够发现一切错误，从逻辑上讲，它也能自己写程序，程序员都可以去死了

试试是不是这样啊  #include<stio.h> int main() { prinf("hello,world\n"); return 0; }  你试试吧 献丑了

据我所知，那些是编译器认为可能出错的地方，像你的这次情况，其实你只要改一个就没事了

可是为什么我就一点点错误,它提示出错那么多?这个错误提示的意思是什么呢?

还真的是因为小括号的原因,感谢上面两位,非常感谢!已经通过了,总算拾回一点信心.

好几个错误，你确定抄的一模一样？

main后面该是圆括号啊！lz确定没敲错？

不熟悉C，不过C++中，main后应该是小括号。

可是我还没有开始学VC++呢! 并且我很想知道代码是对着书一模一样敲的,没有错啊!

用visual c++吧,一下就通过了


Question: C程序趣味题疑惑求解释，谢谢

看了一下画出来的图形结果 跟y的初始值相对应的吧， 如果不用1-y而是直接用y 明显的出来的反余弦函数值不是从第一列开始的 具体的楼主可以再看看反余弦函数的特性


Question: （菜鸟求教）求大神指正代码出现的错误

1，对指针指向的内存管理不当， 2，对指针的处理不当

引用 楼主 linyujing6388 的回复:main.c 文件 #include "student.h" int main () {    STUDENT* Student; STUDENT* Student; Student是野指针。


Question: C语言

搜 C语言 日期库

直接上代码吧  #include <stdio.h>  /* 判断是否为润年，如果是，返回 1, 否则返回 0 */ static int is_leap(unsigned int year) {     if ((year%4==0) && (year%100!=0) || (year%400==0)) {         return 1;     } else {         return 0;     } }  /* 判断一个月是否属于大月分, 如果不是大月返回 0, 如果是大月返回 1, 如果是2月返回 2 */ static int is_big_month(unsigned char month) {     switch (month) {         case 1:         case 3:         case 5:         case 7:         case 8:         case 10:         case 12:             return 1;         case 4:         case 6:         case 9:         case 11:             return 0;         case 2:             return 2;     } }  /* 主函数 */ int main() {     int year, month, day;      while (1) {     printf("请输入 年 月 日\n");     scanf("%d%d%d", &year, &month, &day);          if (year<1 || month<1 || month>12 || day<1 || day>31) {         fprintf(stderr, "输入有误!\n");         return 1;     }      int ret = is_big_month(month);     int d;     if (ret != 2) {         d = 30 + ret;     } else {         d = 28 + is_leap(year);     }      ++day;     ++d;     month += day / d;     year += month / 13;     if ((month %= 13) == 0) {         month = 1;     }     if ((day %= d) == 0) {         day = 1;     }      printf("下一天 %d %d %d\n", year, month, day);     }     return 0; }

先判断是否是1231  然先判断是否它是否为闰年 再根据平闰年判断是否为 28 或者 29 再判断是否为31（1、3、5、7、8、10） 或者30 （4、6、9、11） 其余的都把日期加1就ok  这只是一种我刚刚想到  应该还有更优算法 多想想就能找到风向了


Question: 各位大神们帮我找找哪里有问题

晕了

case 'm':                          //乘法            int shuju(void);            float multiply(float a, float b);            break;        case 'd':                           //减法    int shuju(void);            float divide(float a, float b);            break; 有这样调用函数的吗？


Question: ClipCursor的实现

[color=#FF0000][color=#FF99CC][/color][/color]结贴结贴结贴结贴结贴结贴结贴结贴

结贴结贴结贴结贴结贴结贴


Question: 又遇到一个问题：求斐波那契数列前6项和

引用 8 楼 u014517899 的回复:嗯嗯 还有想问下  for(int ix=3;ix<=n;++ix)  里面的 ix 什么意思   书上没看到这样的用法   希望帮忙解答下。   ix只是一个变量名，随便起的，没什么意思，5楼的代码是有两个错误，所以把正确的写六楼了。。。

引用 19 楼 u014517899 的回复:谢谢大家了，虽然还有很多看不懂。。。。（18楼的解答对于我现在来说就是天书0.0） 突然发现自己到目前好像什么都没学到  不过还是感谢各位。 看来我还得加倍看书、练习。    不好意思！没环境，没有调试，有两个地方疏忽写错了： Fbl 的第3行为switch(N) Boch的第4行在Ad=0;后漏了break; Fbl主要是产生1、2、3、5、8菲波拉数并保存在数组A里，Boch是产生2/1、3/2、4/3、5/5、6/8，合在一起的已经有了，这里提供一种分开的

int *Fbl(unsigned int N,int *A) { 	switch(n){ 		case 0:A=0;break; 		case 2:A[1]=2; 		case 1:A[0]=1;break; 		default: 			A[0]=1;A[1]=2; 			for (unsigned int i=2;i<N;++i) 				A[i]=A[i-1]+A[i-2]; 		} 	return A;	 }  double *Boch(unsigned int N,double *Ad,int *A) { 	switch(N){ 		case 0:	Ad = 0; 		case 2:	Ad[1]=1.5; 		case 1: Ad[0]=2;break; 		default: 			Ad[0]=2;Ad[1]=1.5; 			Fbl(N,A); 			for(unsigned int i=2;i<N;++i) 				Ad[i]=duuble(i+2)/A[i];       //----- 2/1,3/2,4/3,5/5,6/8,7/13.... (n+1)/((n-1)+(n-2)) 		} 	return Ad; } 分子、分母不可能同时为非波拉数，否则函数不可能收敛，即函数将是发散的，没有极限值。 double Sum(unsigned int N,double *A) { 	double s=0; 	for(unsigned int i=0;i<N;++i) 		s+= A[i]; 	return s; }

谢谢1楼的解答。

刚看到数组。。。。。。

这种与前项相关的问题要用递归。

大致思想，供参考  #include <stdio.h> int main(void) { 	int x = 1, y = 2;//初始化数列，x为第一个,y为第二个 	int sum = x + y;//求和 	int n = 6;//n表示前6项 	int i; 	for(i = 3; i <= n; i++) 	{ 		if(i%2 == 1)//更新下一个数据 		{ 			x += y; 			sum += x; 		} 		else 		{ 			y += x; 			sum += y; 		} 	} 	printf("前%d项之和为：%d\n",n,sum); 	return 0; }

引用 16 楼 u014517899 的回复:额。。。。。。  是滴，分子、分母都是Fibonacci数列 不过12楼的解答我看不大懂。。。那里面是不是有函数的调用？（自学的，很多东西似乎都不懂。   ）对，是有函数的调用。跟人建议可以先找一本基础书，把语法好好学一学。 然后多练习。

这题目也看错了。。。。

额，貌似搞错了方向。。。。

#include<stdio.h>  int h(int i) { 	if(i==1||i==2) 		return 1; 	else 		return h(i-1)+h(i-2); } int main(void) { 	int n,i; 	long sum=0; 	printf("请输入项数:"); 	scanf("%d",&n); 		for(i=1;i<=n;i++) 		{ 			sum+=h(i); 			 		} 	printf("前%d项和为%ld\n",n,sum); 	return 0; }  函数的递归。 我也刚学没多久，楼主一起加油吧。

/* *  sum = 2/1 + 3/2 + 5/3 + 8/5 + 13/8 + 21/13...... */ #include "stdio.h"  float SumFun(int n) { 	int z = 0, temp = 0; 	int i = 2, j = 1; 	float sum = 0;  	for(z = 0; z < n; z++) 	{ 		sum += (float)i/j; 		temp = i; 		i += j; 		j = temp; 	} 	printf("sum = %f\n", sum); 	return sum; } int main(void) { 	float sum = SumFun(6);  	printf("sum = %f\n", sum); }

引用 10 楼 lovehuan54 的回复:请问题目是不是这个：sum = 2/1 + 3/2 + 5/3 + 8/5 + 13/8...... 分子是斐波那契数列吧？ 补充： 分子和分母都是斐波那契数列？

简单一点的写法： #include<stdio.h> #define LEN 20 int main() { 	int sum=2; 	int a[LEN]={1,1}; 	int i; 	for(i=2;i<LEN+1;i++) 	{ 		a[i]=a[i-1]+a[i-2]; 		sum=sum+a[i]; 	} 	printf("%d\n",sum); 	getchar(); 	return 0; }

5楼的运行结果不对   中间有两个错误：第8行sum写成sun                                最后return 0后面少分号。   还是谢谢了。 我去研究下这个方法。   没人指点学起来挺恼火的，感觉很多地方不是很懂，想找个人问都找不到。。。。。。

前面的代码有问题：如下，可参考。。。。     1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  	  #include<stdio.h> int main() { int n; printf("请输入一个数字(n>2)：\n");//输入你要求得前n相和的n scanf("%d",&n); int x=1,y=2; int sum=3; for(int ix=3;ix<=n;++ix) { sum+=(x+y);//sum等于前一个sum加第n个数字，而第n个数字为前面的x+y int temp=x;//定义中间变量储存现在的x x=y;//将x的值变成现在的y y=temp+y;//将y的值变成之前的x+y } printf("前n相和为%d\n",sum); return 0; }


Question: 请教 ：继C语言  9*9乘法表

#include <stdio.h> #include <string.h> int main() {     int a,b;     char s[73],t[10];      for (a=9;a>0;a--) {         s[0]=0;         for (b=a;b<10;b++) {             sprintf(t," %dx%d=%d",a,b,a*b);             if (a==2 && b==5) strcat(s," ");             strcat(s,t);             if (a==1 && b>=4) strcat(s," ");         }         printf("%60s\n",s);     }     return 0; } //                                                      9x9=81 //                                               8x8=64 8x9=72 //                                        7x7=49 7x8=56 7x9=63 //                                 6x6=36 6x7=42 6x8=48 6x9=54 //                          5x5=25 5x6=30 5x7=35 5x8=40 5x9=45 //                   4x4=16 4x5=20 4x6=24 4x7=28 4x8=32 4x9=36 //             3x3=9 3x4=12 3x5=15 3x6=18 3x7=21 3x8=24 3x9=27 //       2x2=4 2x3=6 2x4=8  2x5=10 2x6=12 2x7=14 2x8=16 2x9=18 // 1x1=1 1x2=2 1x3=3 1x4=4  1x5=5  1x6=6  1x7=7  1x8=8  1x9=9

#include <stdio.h> void main() { int i = 0, j = 0; int n; printf("输入数字："); while(scanf("%d",&n)!=EOF) { for (i = 1; i <= n; i++) for (j = 1; j <= i; j++) if(i==j) printf("%d*%d=%d\n",j,i,i*j); else printf("%d*%d=%d ",j,i,i*j); } }  /* 输入数字：9 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 */

#include <stdio.h> int main(void) {     int i,j;     for(i = 1; i <= 9; i++)     {         for(j = 1; j <= 9; j++)         {             printf("%dX%d=%d|",i,j,i*j);         }         printf("\n");     }     return 0; }

哈哈 坐等收分引用 4 楼 u014554246 的回复:谢谢  非常感谢

谢谢  非常感谢

亲，上午好， 百度出来的    结果不一样 ，不知道怎么写成想题目要求的格式

lz自己去写吧  这个都要来问？  百度一大把


Question: 一个死循环的功耗是多大?

引用在我的双核机上查看CPU使用率是50%,每个核各50% 有一半的时间在工作，一半的时间在休息，休息的时候能耗很低。

记得以前的电影里有在CPU上煎鸡蛋的段子,  并且要不停的敲键盘.  我学得CPU还是GPU在不停的运转时, 发热都会增加, 耗电自然会增加, 这点在老的笔记本上很容易测试.  CPU 100%后不一会, 就能听见摩托的声音了.

功耗？这样的问题你想测试什么？或是想搞什么？

啥叫“功耗”？

唉，不要这么考研它 好么？

你所谓的功耗是指的什么？

这也跟cpu没关系吧，只是程序一直执行而已

楼主你真是....绝对是吃饱了没事做的主。。

你看下cpu的瓦数，双核就除一下呗，大概差不多

你想干嘛？好奇

while(1){ Sleep(sometime);} 加个sleep函数就行了(不同环境下名称与参数值不一样)。进入sleep后就就会让出cpu的控制权给别的进程用。

就不会调度了额

lz，你去绕着操场全速跑一小时会累么？ 为什么会累呢？你又没做俯卧撑。

CPU的使用率和功耗没有绝对的关系，cpu占用率低，但是指令代码涉及的寄存器操作多，也会产生较大功耗。while（1）基本上就只设计一个寄存器操作，占用率可以高，但是功耗其实不高

占着坑不拉屎...

CPU占用率100%，功耗什么的不知道。

你叫cpu这匹马全速奔跑你还不让它吃草？

拒绝死循环。


Question: 从一个英语的句子字符串里面获取里面所有单词有没有什么好方法？

不知道长度可以使用链表。

用strtok（）函数，以空格为分割符，具体请搜索学习

istringstream

谭浩强的 c程序设计 第四版 上有计算单词个数的代码，你可以借鉴一下


Question: 二叉树的部分代码用法，看着甚是头大。

if(!(*T = (TREENODE *)malloc(sizeof(TREENODE)))) return-1 表示如果malloc失败则返回-1 因为要连续插入所以要ch[inc++]

引用 2 楼 phoenix_1992 的回复:ch[inc++] 这种奇怪的用法，虽然我大概知道它什么意思。还有return1、if(!(*T = (TREENODE *)malloc(sizeof(TREENODE)))) return-1、ch[inc-1]，不明白它为啥要这样写。接触2叉树不久，觉得理解起来很吃力。  lz底子太薄 能解答一下不？

这不是二叉树的问题，是你基础的问题。


Question: 打印单词长度直方图

这个源程序我还真不知道，能贴全吗？

#define MAXHIST 15      //直方图的最大长度   #define MAXWORD 11      //单词的最大长度   #define IN  1       //在单词中   #define OUT 0       //在单词外   void main()   {       int c, i, nc, state;    //nc：单词的长度       int len;        //直方图中每个直方条的长度       int maxvalue;       //wl数组的最大值       int ovflow;     //长度大于或等于MAXWORD的单词的数量       int wl[MAXWORD];    //按单词长度值0~11，统计输入中各长度的单词数，存放在wl数组中          state = OUT;       nc = 0;       ovflow = 0;       for(i = 0; i < MAXWORD; ++i)           wl[i] = 0;          while((c = getchar()) != EOF)           if(c == ' ' || c == '/n' || c == '/t')           {               state = OUT;               if(nc > 0)                   if(nc < MAXWORD)                       ++wl[nc];                   else                       ++ovflow;               nc = 0;           }           else if(state == OUT)           {               state = IN;               nc = 1;           }           else               ++nc;          maxvalue = 0;       for(i = 1; i < MAXWORD; ++i)           if(wl[i] > maxvalue)               maxvalue = wl[i];       for(i = 1; i < MAXWORD; ++i)       {           printf("%5d - %5d : ", i, wl[i]);           if(wl[i] > 0)           {               if((len = wl[i] * MAXHIST / maxvalue) <= 0)                   len = 1;           }           else               len = 0;           while(len > 0)           {               putchar('*');               --len;           }           putchar('/n');       }       if(ovflow > 0)           printf("there are %d words >= %d/n", ovflow, MAXWORD);     }


Question: C语言-小弟研究了两天还没完全看明白，求大神给讲解讲解，谢谢

貌似是一个实现四则运算的计算器

11楼的代码应该改改，使它有更好的重用性。

仅供参考/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

后缀表达式？

你应该说出你那里不懂？

其实我想问，如何才能像楼主一样把代码贴出来啊。对了，楼主，方便加的联系方式不，我最近也在学习这本书。

表达式求值？看不懂的先做个记号放一放，学习了数据结构以后再来看。

是不是不知道什么是栈?

逆波兰表达式 相关的

引用 2 楼 Idle_Cloud 的回复:没看出难的地方啊，就实现了一个计算器 有空给我说下流程啦

书上没注释吗？

没看出难的地方啊，就实现了一个计算器

我也看不懂  呵呵，的确很难。


Question: 计算一个班30人学生生日同一天概率的程序出问题了

引用 3 楼 u014541584 的回复:[quote=引用 2 楼 zxh707wk 的回复:] 你的思路本来就有问题，生日是月加日组成的，如果照你这种算法，那闰年和平年的天数就都一样了 这可以忽略了，题目要求的[/quote] 好吧。。。，在书上我也看过类似不考虑实际的题目

引用 4 楼 u014541584 的回复:2楼能说下随机数初始语句放那里有什么区别吗？  整个大循环在快点的cpu上用不了1秒就完了，而time是以秒为单位返回的，那每次初始化种子都是一样的，导致随机数序列也是一样的

2楼能说下随机数初始语句放那里有什么区别吗？

引用 2 楼 zxh707wk 的回复:你的思路本来就有问题，生日是月加日组成的，如果照你这种算法，那闰年和平年的天数就都一样了 这可以忽略了，题目要求的

#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { 	int arr[30],i,j,k,res,num=0,flag=0; 	srand((unsigned int)time(NULL));    //随机数种子初始化放这里 	//k代表统计次数10000次 	for (k=0;k<10000;k++) 	{ 		flag=0; 		 		for (i=0;i<30;i++) 		{ 			if ((res=rand()%365)>32485)      				i--; 			else 				arr[i]=res%365;     		} 		for (i=0;i<29;i++)    		{ 			for (j=i+1;j<30;j++) 			if (arr[i]==arr[j]) 			{ 				flag=1; 				break;    			} 			if (flag==1) 			{ 				num+=1;    				break;     			} 		} 	} 	printf("%d\n",num);     	return 0; }


Question: vc编译问题

编译器有bug 以前老遇到了 只能直接强制杀了进程

中病毒了？重装vc试试


Question: 问一个关于用break跳出循环的问题

好的  谢谢了！ 我是自己看书和视频学习的，也许有的地方遗漏了。。。我也在尽量在规范自己的代码。 谢谢提醒。

同上 附代码： # include <stdio.h>  int main(void) {     int choose ;     int i ;     char ch ;     int a[20]= {1,1};     int n ;     int k ;     for(i=2; i<=19; i++)         a[i]=a[i-2]+a[i-1];     while(1)     {          printf("请选择：\n1.查看Fibonacci数列第n项\n2.查看Fibonacci数列前n项\n");         scanf("%d",&choose);         getchar();         switch(choose)         {         case 1 :             printf("请输入你想查看的项数：\n");             scanf("%d",&n);             getchar();             if(i=n-1)                 printf("第%d项是：%d  \n",n,a[i]);             break ;         case 2 :             printf("请输入你想查看的项数：\n");             scanf("%d",&k);             getchar();             for(i=1; i<=k; i++)             {                 printf("%-5d ",a[i]);                 if(i%5==0)                     printf("\n");             }             printf("\n");             break ;         default :             printf("输入有误！\n");             break ;         }         printf("是否退出（Y/y）?\n");         if((ch=getchar())=='y'||(ch=getchar())=='Y')             break ;     }     return 0 ; }

这个是getchar()的问题，一定要注意，去查下getchar用法吧，getchar()是读取标准输入里的下一个字符，而之前scanf_s("%d", &choose);完了有个回车，这个回车正被后边的getchar()获取了。。。lz多规范下代码吧，对齐，换行，复用神马的  printf("是否退出（Y/y）?\n"); getchar(); ch = getchar(); if(ch == 'y'||ch == 'Y')       break; }

ls别误导啊

不是可以用if……break跳出循环么？ 怎么我把break;改成return 0;效果还是一样： 运行结果： --------------------------------------------------------------- 请选择： 1.查看Fibonacci数列第n项 2.查看Fibonacci数列前n项 2 请输入你想查看的项数：5 1     2     3     5     8  是否退出（Y/y）? y 请选择： 1.查看Fibonacci数列第n项 2.查看Fibonacci数列前n项 y 请输入你想查看的项数：1     2     3     5     8  是否退出（Y/y）? Press any key to continue ---------------------------------------------------------------

# include <stdio.h>  int main(void) { 		char ch = 'a' ; 	while(1) 	{ 		int choose; 		int i; 	  		int a[20] = {1, 1};  		for (i = 2; i <= 19; i++) 			a[i] = a[i-2] + a[i-1];  		printf("请选择：\n1.查看Fibonacci数列第n项\n2.查看Fibonacci数列前n项\n"); 		scanf_s("%d", &choose); 		switch (choose) 		{ 		case 1: 			int n; 			printf("请输入你想查看的项数：\n"); 			scanf_s("%d", &n);  			if (i = n - 1) 				printf("第%d项是：%d  \n",n, a[i]);break; 		case 2: 			int k; 			printf("请输入你想查看的项数：\n"); 			scanf_s("%d", &k);  			for (i = 1; i <= k; i++) 			{ 				printf("%-5d ", a[i]); 				if (i%5 == 0) 					printf("\n"); 			} 			printf("\n");break; 		default:printf("输入有误！\n");break; 		} 		printf("是否退出（Y/y）?\n"); 		ch = getchar(); 		if(ch  == 'y'||ch == 'Y') 		{ 			return 0; 		} 		 	} 	 	return 0; } 感觉应该是你if((ch = getchar()) == 'y'||(ch = getchar()) == 'Y')           break; }不应该这样写。if语句里面没有break吧。。


Question: 求解  如何在整型数组中查找出非数字的元素并提醒？

引用 3 楼 wang0635 的回复: if ((scanf("%d", &a)) != 1) {     ... }   这个我也考虑过 但具体怎么用呢

如果硬要这样的话，可以用getchar()读取输入的字符，然后再转化为数值

if ((scanf("%d", &a)) != 1) {     ... }

好吧  用查找函数不是我的水平能办到的  但是我发现把字母和符号按照%d格式输入的时候会都形成一个-800000以下的数  所以我写了以下的程序  确实能够识别单独的字母  可是 3f 4j这种错误输入却被忽略 直接看作是3和4  这怎么解决啊   int main() { int a[1000]; int i,t ; char l; printf("输入若干数字\n"); for(i=0;i<1000;i++) { scanf("%d",&a[i]); t=i; scanf("%c",&l); if(l=='x') break; } printf("输入完毕\n");  for(i=0;i<t;i++) { if(a[i]<-8000000) {printf("\a\a\a失败的输入\n "); goto lable;} }  for(i=0;i<t;i++) printf("%d \n ",a[i]); lable:  return 0; }

整型数组会把内存中的所有数据按照整型数值来对待，不存在什么“非数字的元素” 就像原子炉只认识质子中子电子，你非要它区分出一个人和一头牛一样没意义 楼主面临的问题本质，是处理错误输入，如果楼主愿意接受任何输入，那么就每次从输入中读取一个字符，自行判断是否是数字字符，如果是就组合成数值，不是就报错，不过对于不喜欢这么做甚至只会cin>>a的初学者来说，直接规定“不允许数值以外的输入，否则后果由输入者自负”更好


Question: c语言的二重指针数组项怎样在函数中初始化？

赵老师整解啊

先弄明白*是什么和**是什么就知道怎么初始化了

#include <stdio.h> struct struct_name {     int d1;     int d2; }; int i; void fun(struct struct_name ***a) {     static int v=1;      *a =(struct struct_name **)v;     v++; } int main() {     struct struct_name **aa[10];      for (i=0;i<10;i++) fun(&aa[i]);     for (i=0;i<10;i++) printf("aa[%d]==%p\n",i,aa[i]);      return 0; } //aa[0]==00000001 //aa[1]==00000002 //aa[2]==00000003 //aa[3]==00000004 //aa[4]==00000005 //aa[5]==00000006 //aa[6]==00000007 //aa[7]==00000008 //aa[8]==00000009 //aa[9]==0000000A //

int main()   {    struct_name **aa[10];    for(int i=0;i < 9; i++)       fun(aa[i]);   }   void (fun ***aa)//得用3重指针了 { aa[0]=...aa[1]=.... }

我认为初始化不应该在函数里而应该在main函数里声明之后初始化


Question: 关于scanf函数%c之前与之后使用空格的问题

谢谢你的回答，但是我在输入最后一个字符以后输入了一个空格才键入的回车

你看c标准里对scanf format的说明 Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).  如果你是"%c ", 读完所有的字符后，还需要匹配一个" ", 你输入任何空白字符或非空白字符都可以完成匹配. 但必须有这么一个字符。 如果是" %c", 第一个" "在碰到你输入的a时就完成匹配了 。(参见标准中最后那个including none)


Question: 初学fft变换，请大家指教！

去算法版问问吧！


Question: 求牛人帮忙pthread改成fifo算法 输出，谢谢！

求人帮看看，多谢～

顶一下，多谢～


Question: 关于命令行参数argc和argv，请教。

大哥，谢谢，但是我想知道vc的情况，你帮我发vs的流程。

argc 运行参数个数 argv 运行参数

因为程序名本身也算一个。 因此 = 1 ， 你不输入就是1 所以他是判断 !=2 即是否输入一个参数。

引用 2 楼 u014082409 的回复:我刚才自己用vc运行了程序，为什么这个点击run之后，就直接Usage：find pattern,然后按任意键就没了。 运行时需要参数 vs的：在项目（Project）菜单中打开当前程序属性（Properties）→配置属性（Configuration Properties）→调试（Debugging）→命令参数（Command Arguments），然后将需要的参数写在命令参数后面，有多少写多少参数间用空格间开即可。 命令行运行 写在程序名后面即可。 用空格隔开 如果本身有空格 用双引号

VC6：  工程、设置、Debug、U程序变量：填写命令行参数。 VS20XX：  项目、属性、配置属性、调试、命令参数：填写命令行参数。

就是在运行程序的时候需要输入一个参数


Question: div函数为何没有double版本？

div是对整数求商和余数的， 浮点数没有求余的说法。

引用 1 楼 zhao4zhong1 的回复:1.234除以0.567到底应该余几呢？ 但是不是说用/的话结果是取决于编译器的吗

1.234除以0.567到底应该余几呢？

div Computes the quotient and the remainder of two integer values.  div_t div( int numer, int denom );  Routine Required Header Compatibility  div <stdlib.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  div returns a structure of type div_t, comprising the quotient and the remainder. The structure is defined in STDLIB.H.  Parameters  numer  Numerator  denom  Denominator  Remarks  The div function divides numer by denom, computing the quotient and the remainder. The div_t structure contains int quot, the quotient, and int rem, the remainder. The sign of the quotient is the same as that of the mathematical quotient. Its absolute value is the largest integer that is less than the absolute value of the mathematical quotient. If the denominator is 0, the program terminates with an error message.  Example  /* DIV.C: This example takes two integers as command-line  * arguments and displays the results of the integer  * division. This program accepts two arguments on the  * command line following the program name, then calls  * div to divide the first argument by the second.  * Finally, it prints the structure members quot and rem.  */  #include <stdlib.h> #include <stdio.h> #include <math.h>  void main( int argc, char *argv[] ) {    int x,y;    div_t div_result;     x = atoi( argv[1] );    y = atoi( argv[2] );     printf( "x is %d, y is %d\n", x, y );    div_result = div( x, y );    printf( "The quotient is %d, and the remainder is %d\n",            div_result.quot, div_result.rem ); }   Output  x is 876, y is 13 The quotient is 67, and the remainder is 5     Floating-Point Support Routines  See Also   ldiv


Question: 新手求助，输出为什么是3

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

#define宏定义只是在预编译的时候进行了文本替换，所以如上就是3， lz可以这样写#define M(a,b) ((a)>(b)?(a):(b))

引用 1 楼 yaomoon 的回复:宏定义展开后： n=5+1+2>3+4?1+2:3+4; 根据运算符优先级，三目运算符（？：）优先级比+ 低，但比= 大，所以实际为： n=(5+1+2)>(3+4)?(1+2):(3+4);   输出结果n = 1+2  为3 谢谢！

5+a+b>c+d?a+b:c+d 然后看置顶表达式求值顺序的帖子。

运算符的顺序弄错了


Question: 代码功能是，将一个菜单项的字符串改变，运行没效果，哪位帮我看看

AdjustTokenPrivileges VirtualProtectEx WriteProcessMemory ……

SetMenuItemInfo不能跨进程修改吧

我已经解决了，里面还需要定义mii.DyTyoeDate,需要申请内存，不然就报错

引用 1 楼 buyong 的回复:SetMenuItemInfo不能跨进程修改吧 我想打开网银界面 然后把余额改为1000000000000.。。。。


Question: gcc内联arm汇编，汇编代码如何使用c中标号

引用 10 楼 u014538351 的回复:[quote=引用 8 楼 nadleeh123 的回复:] [quote=引用 7 楼 u014538351 的回复:] [quote=引用 3 楼 nadleeh123 的回复:] [quote=引用 2 楼 u014538351 的回复:] [quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 包含函数的.o文件加到命令链进来没[/quote] 你说的是单独的一个asm吗，内联汇编呢？[/quote] 一回事啊[/quote] 具体是?  void test(){  int a=0,b=1;  __asm("mov r1,r0 \n"  );  lab:  a=2*b;  }  比如这个，我怎么才能在汇编中使用标号lab[/quote] 这个真没干过，标签这个玩意儿在汇编阶段如果是以符号的形式存在，那是可以直接跳的，但我不确定是不是，或者说编译器怎么处理，如果在编译生产汇编的阶段就把标签拿掉了，换成函数+偏移的形式，那你也只能去算那个位置。

引用 3 楼 nadleeh123 的回复:[quote=引用 2 楼 u014538351 的回复:] [quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 包含函数的.o文件加到命令链进来没[/quote] 你说的是单独的一个asm吗，内联汇编呢？

gcc-inline-asm.pdf

这个是c和汇编联合编程吗

引用 2 楼 u014538351 的回复:[quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 语法上支持这么做的,像arm的boot通过srom把cpu,mmu,初始化之后,再通过sram初始化内存后,加载boot后半截到内存,再跳到内存去只执行,写的就是b main,但体是bl bx 还是b 我忘记了,这几个指令有点区别.

引用 2 楼 u014538351 的回复:[quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 包含函数的.o文件加到命令链进来没

引用 1 楼 nadleeh123 的回复:[quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义

引用 8 楼 nadleeh123 的回复:[quote=引用 7 楼 u014538351 的回复:] [quote=引用 3 楼 nadleeh123 的回复:] [quote=引用 2 楼 u014538351 的回复:] [quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 包含函数的.o文件加到命令链进来没[/quote] 你说的是单独的一个asm吗，内联汇编呢？[/quote] 一回事啊[/quote] 具体是?  void test(){  int a=0,b=1;  __asm("mov r1,r0 \n"  );  lab:  a=2*b;  }  比如这个，我怎么才能在汇编中使用标号lab

引用 楼主 u014538351 的回复:我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊

引用 7 楼 u014538351 的回复:[quote=引用 3 楼 nadleeh123 的回复:] [quote=引用 2 楼 u014538351 的回复:] [quote=引用 1 楼 nadleeh123 的回复:] [quote=引用 楼主 u014538351 的回复:] 我想根据汇编中的结果进行跳转。 (第一次来csdn论坛，不知可不可以发这种非技术贴，如果不能，请版主帮忙删帖) b指令+地址啊[/quote] 我在内联汇编中b+标号，编译器提示该标号未定义[/quote] 包含函数的.o文件加到命令链进来没[/quote] 你说的是单独的一个asm吗，内联汇编呢？[/quote] 一回事啊


Question: 大神们帮我看看哪里错了

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

lz可以规范一下吗  神马对齐啊，换行啊。。。。别乱用头函数

#include <stdio.h>

lz这是c代码还是c++代码啊？自己能确定吗？

# include <iostream>    printf("\n"); ???

改了，但我发现是工程上的错误，我只建立文件就可以运行

main的格式不对，改成int main（int argc, char* argv[]）

工程属性建错了，应该是console

如果你是先建立的工程 ，再建立的源代码文件。 那么你选工程时就要注意选择console程序不要选择成windows application程序了。

#include<stdio.h>  int main(void) {  int  a[4][4],b[4][4],i,j;    printf("input 16 numbers: ");      for(i=0;i<4;i++)  {  for(j=0;j<4;j++)        {  scanf("%d",&a[i][j]);           b[3-j][i]=a[i][j];         }  }    printf("array b:\n");    for(i=0;i<4;i++)       {  for(j=0;j<4;j++)          printf("%6d",b[i][j]);          printf("\n");        }     return 0; }


Question: break不起作用啊，求解释

引用 4 楼 u014045619 的回复:好象有时候我用一个break就跳出了所有嵌套的循环啊  for(;;)//循环1 {       for(;;)//循环2       {}       break;//此时的break是跳出了所有的循环 }   break是跳出break语句所在的循环，这个例子里，break跳出的就是循环1，但是循环1包含了循环2，那么这个break的效果就是跳出了所有的循环，但本质还是跳出一层循环

引用 1 楼 user-3 的回复:break可以跳出循环  但是不能跳出所有循环 引用 2 楼 huchenguang 的回复:#include <stdio.h> #include <math.h> int main(void) {     int i,k,n,tag=0;     int a[3][4]={{1,2,3},{4,5,6},{7,8,9}};     scanf("%d",&n);     for(i=0;i<3;i++)     {         for(k=0;k<4;k++)         {             if(a[i][k]==n)             {                 tag=1;                 printf("%d %d\n",i,k);                 break;//跳出内层for循环             }         } 		if(tag == 1)//这里加上判断，如果tag == 1，跳出外层循环 			break;     }     if(tag==0)         printf("-1\n");     return 0; }  break是跳出当前一层循环，你的程序里是2层for循环，第一个break是跳出内层for循环，但仍在外出循环中 引用 3 楼 jerry_dqh 的回复:你有好几个循环  好象有时候我用一个break就跳出了所有嵌套的循环啊

你有好几个循环

break可以跳出循环  但是不能跳出所有循环


Question: 指针赋值时提示类型不匹配

引用 2 楼 jerry_dqh 的回复:因为const 非const之间转换。我的疑问是，这个宏本来就是const与非const之间的转化，为什么其他的没有警告呢？

引用 1 楼 astrotycoon 的回复:自己顶一下！我的疑问是，这个宏本来就是const与非const之间的转化，为什么其他的没有警告呢？

引用补充：另外，对于这个宏我还有些疑惑，比如这个宏完全可以这样写啊 C/C++ code ? 1 2 #define container_of(ptr, type, member) ({                      \           (type *)( (char *)ptr - offsetof(type,member) );})  我想问的是，这个宏的不这样写的原因是什么呢  这样写是可以，但是有一定的隐患，不能在编译阶段发现错误，原来的写法可以在编译阶段做一个类型的检查,举个例子 有一个结构体 struct teacher {     char name[10];     int id[15];  //这里与student不一样。int型，原来为char     int age;    }; int main(int argc, const char *argv[]) {     struct student stu = {       };        struct teacher t1 = {};     struct student *pstu = container_of(&t1.id, struct student, id);      //直接用新定义的宏，检查不出来有问题。                                     printf("pstu->name = %s, pstu->id = %s, pstu->age = %d\n", pstu->name, pstu->id, pstu->age);      return 0; }  主要还是做一个表态的检查。

因为const 非const之间转换。

自己顶一下！


Question: 实现将文件最后一行写到该文件的第一行，覆盖第一行。

引用 7 楼 hmz6285603 的回复:[quote=引用 6 楼 my_live_123 的回复:] [quote=引用 5 楼 hmz6285603 的回复:] [quote=引用 4 楼 my_live_123 的回复:]  #include <stdio.h> #include <stdlib.h> #include <string.h>  #define LINE_MAX 64 //bug:当最后一行长于第一行时，会覆盖掉第二行的一些字符，抛砖引玉吧，我不修复这个不过了 int last_to_first(char *path) { 	FILE *fp; 	char line[LINE_MAX + 1] = {0}; 	int i;  	fp = fopen(path, "r+"); 	if(fp == NULL) 		exit(0);  //第一行清空 	fgets(line, LINE_MAX, fp); 	fseek(fp, 0, SEEK_SET); 	for(i = 0; i < strlen(line); ++i) 		fputc('0', fp);  //取最后一行 	fseek(fp, -LINE_MAX, SEEK_END); 	do{ 		fgets(line, LINE_MAX, fp); 	} 	while(!feof(fp));  	//printf("%s\n", line); //填充第一行 	fseek(fp, 0, SEEK_SET); 	fputs(line, fp); 	fclose(fp); 	return 0; }  int main(int argc, char *argv[])  { 	if(argc != 2) 		return 1; 	last_to_first(argv[1]); 	return 0; }  还有两种方案，1.全部读取到数组中，处理完毕写回。2.写到另一个新建文件中，写的过程中进行调整 感觉不合理，一行可能少于64个字符或者多于64个字符。感觉这个方法不合适。[/quote] 那个只是最大值，少于64，正常运行，多余64个，你改成那个大值不就可以喽，我给你写成宏喽，就是这个目的[/quote] 最后一行，我们不知道有多少字符直接用这个“fseek(fp, -LINE_MAX, SEEK_END);”不合适吧。 [/quote] 比如一般的文本编辑器一行都不会超过256个字符，那么去过MAX=256,则如果最后一行正好256，那么fseek正好。如果没有这么多，fseek后fp指向位置可能还有几行，函数中不是有个do，while循环嘛，一次取一行，直到取到最后一行为止，循环结束后line存的就是最后一行喽

引用 6 楼 my_live_123 的回复:[quote=引用 5 楼 hmz6285603 的回复:] [quote=引用 4 楼 my_live_123 的回复:]  #include <stdio.h> #include <stdlib.h> #include <string.h>  #define LINE_MAX 64 //bug:当最后一行长于第一行时，会覆盖掉第二行的一些字符，抛砖引玉吧，我不修复这个不过了 int last_to_first(char *path) { 	FILE *fp; 	char line[LINE_MAX + 1] = {0}; 	int i;  	fp = fopen(path, "r+"); 	if(fp == NULL) 		exit(0);  //第一行清空 	fgets(line, LINE_MAX, fp); 	fseek(fp, 0, SEEK_SET); 	for(i = 0; i < strlen(line); ++i) 		fputc('0', fp);  //取最后一行 	fseek(fp, -LINE_MAX, SEEK_END); 	do{ 		fgets(line, LINE_MAX, fp); 	} 	while(!feof(fp));  	//printf("%s\n", line); //填充第一行 	fseek(fp, 0, SEEK_SET); 	fputs(line, fp); 	fclose(fp); 	return 0; }  int main(int argc, char *argv[])  { 	if(argc != 2) 		return 1; 	last_to_first(argv[1]); 	return 0; }  还有两种方案，1.全部读取到数组中，处理完毕写回。2.写到另一个新建文件中，写的过程中进行调整 感觉不合理，一行可能少于64个字符或者多于64个字符。感觉这个方法不合适。[/quote] 那个只是最大值，少于64，正常运行，多余64个，你改成那个大值不就可以喽，我给你写成宏喽，就是这个目的[/quote] 最后一行，我们不知道有多少字符直接用这个“fseek(fp, -LINE_MAX, SEEK_END);”不合适吧。

引用 5 楼 hmz6285603 的回复:[quote=引用 4 楼 my_live_123 的回复:]  #include <stdio.h> #include <stdlib.h> #include <string.h>  #define LINE_MAX 64 //bug:当最后一行长于第一行时，会覆盖掉第二行的一些字符，抛砖引玉吧，我不修复这个不过了 int last_to_first(char *path) { 	FILE *fp; 	char line[LINE_MAX + 1] = {0}; 	int i;  	fp = fopen(path, "r+"); 	if(fp == NULL) 		exit(0);  //第一行清空 	fgets(line, LINE_MAX, fp); 	fseek(fp, 0, SEEK_SET); 	for(i = 0; i < strlen(line); ++i) 		fputc('0', fp);  //取最后一行 	fseek(fp, -LINE_MAX, SEEK_END); 	do{ 		fgets(line, LINE_MAX, fp); 	} 	while(!feof(fp));  	//printf("%s\n", line); //填充第一行 	fseek(fp, 0, SEEK_SET); 	fputs(line, fp); 	fclose(fp); 	return 0; }  int main(int argc, char *argv[])  { 	if(argc != 2) 		return 1; 	last_to_first(argv[1]); 	return 0; }  还有两种方案，1.全部读取到数组中，处理完毕写回。2.写到另一个新建文件中，写的过程中进行调整 感觉不合理，一行可能少于64个字符或者多于64个字符。感觉这个方法不合适。[/quote] 那个只是最大值，少于64，正常运行，多余64个，你改成那个大值不就可以喽，我给你写成宏喽，就是这个目的

引用 4 楼 my_live_123 的回复: #include <stdio.h> #include <stdlib.h> #include <string.h>  #define LINE_MAX 64 //bug:当最后一行长于第一行时，会覆盖掉第二行的一些字符，抛砖引玉吧，我不修复这个不过了 int last_to_first(char *path) { 	FILE *fp; 	char line[LINE_MAX + 1] = {0}; 	int i;  	fp = fopen(path, "r+"); 	if(fp == NULL) 		exit(0);  //第一行清空 	fgets(line, LINE_MAX, fp); 	fseek(fp, 0, SEEK_SET); 	for(i = 0; i < strlen(line); ++i) 		fputc('0', fp);  //取最后一行 	fseek(fp, -LINE_MAX, SEEK_END); 	do{ 		fgets(line, LINE_MAX, fp); 	} 	while(!feof(fp));  	//printf("%s\n", line); //填充第一行 	fseek(fp, 0, SEEK_SET); 	fputs(line, fp); 	fclose(fp); 	return 0; }  int main(int argc, char *argv[])  { 	if(argc != 2) 		return 1; 	last_to_first(argv[1]); 	return 0; }  还有两种方案，1.全部读取到数组中，处理完毕写回。2.写到另一个新建文件中，写的过程中进行调整 感觉不合理，一行可能少于64个字符或者多于64个字符。感觉这个方法不合适。

写临时文件。

引用 1 楼 icesky1stm 的回复:lseek，和操作数组的原理没啥区别。 具体怎么实现，教下。菜鸟，呵呵

lseek，和操作数组的原理没啥区别。


Question: 同样的代码为什么C和C++得出不同的结果呢。问题较复杂，我举例进行了说明。

再自己顶一顶

我用GDB工具进行了调试：  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>. (gdb) file c Reading symbols from /home/pcd/workspace/myjava/jni/c...done. (gdb) b 9 Breakpoint 1 at 0x4008af: file c.c, line 9. (gdb) r Starting program: /home/workspace/myjava/jni/c  warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000  Breakpoint 1, main (argc=1, argv=0x7fffffffe1a8) at c.c:13 13	int main(int argc, char* argv[]){ (gdb) s 15		int nRetCode = 0; (gdb) s 16		int imghandle = 0; (gdb) s 18	        void *imglib = dlopen("./libLGM.so", RTLD_LAZY); (gdb) p imglib $1 = (void *) 0x0 (gdb) s [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Cannot find new threads: generic error (gdb)

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

努力了这么久，就差这最后一步。居然停滞不前了。郁闷。

估计还是哪里写的有错误，要不不应该。

我也感觉这个问题挺为难大家，能提示就行。

P1和P2打印的结果如下，因为太多所以部分截取， C++调用后的结果和C/JAVA调用后的结果一样啊。我通过对比工具比较了。   P1：11820010001331961701930188143656352160651421561856534241159654221107621021371806424531196631251867065229211166169623519113164766310003000000000000000000000000000 --------------------------------- P2：118200100023463186193179710765139183107652371591956522622014265112413764229202256422014610164222181652351461371935367576319014820463192219110641951941861911342241866323613516719223612198192672512226410530118641711310063221611561901501241106425321466193199109138641701221619025451506410003000000000000000000000000000   引用 9 楼 lgmsyy 的回复:[quote=引用 8 楼 mujiok2003 的回复:] [quote=引用 6 楼 lgmsyy 的回复:] [quote=引用 1 楼 mujiok2003 的回复:]  //printf("%d",p1[i]); printf("%hhu",p1[i]); .... printf("%hhu",p2[i]);   z这事做什么[/quote]  %hhu--->unsigned char[/quote]  打印的结果是一样的[/quote]

引用 11 楼 max_min_ 的回复:这样看的话，有没有可能是第三方库的问题的呢？\ 如果是第三方库的问题，为什么我直接用C++调用是可行的。 而用C调用和JAVA调用都不成。

这样看的话，有没有可能是第三方库的问题的呢？

请大家帮忙啊。

一定要弄好它

引用 20 楼 zhao4zhong1 的回复:调试不了对应C/C++代码，但可以调试对应汇编指令。 --------------------------- layout regs：显示源代码/反汇编和CPU寄存器窗口 layout asm：显示反汇编窗口 这些我都用上了，可是 ---------------------------- void *imglib = dlopen("./libLGM.so", RTLD_LAZY);//第三方提供的动态链接库 一到调用第三方库的时候就提示以下：  Breakpoint 1 at 0x4008af: file c.c, line 9. (gdb) r Starting program: /home/pcd/workspace/myjava/jni/c   Breakpoint 1, main (argc=1, argv=0x7fffffffe1a8) at c.c:13 (gdb) s [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Cannot find new threads: generic error (gdb)

调试不了对应C/C++代码，但可以调试对应汇编指令。

int nSample = _ThridTestone(p, p1);  float result  = _ThridTesttwo(p1, p2);  这两个函数都是第三方动态链接库提供的对外函数，我通过GDB怎么才能进入函数体中进行调试。 当然，对方只提供个SO动态链接库而已。

引用 8 楼 mujiok2003 的回复:[quote=引用 6 楼 lgmsyy 的回复:] [quote=引用 1 楼 mujiok2003 的回复:]  //printf("%d",p1[i]); printf("%hhu",p1[i]); .... printf("%hhu",p2[i]);   z这事做什么[/quote]  %hhu--->unsigned char[/quote]  打印的结果是一样的

引用 6 楼 lgmsyy 的回复:[quote=引用 1 楼 mujiok2003 的回复:]  //printf("%d",p1[i]); printf("%hhu",p1[i]); .... printf("%hhu",p2[i]);   z这事做什么[/quote]  %hhu--->unsigned char

引用 5 楼 ningxialieri 的回复:C在编译时，直接保存了函数名。但是c++编译时的函数名包括signature信息，目的是为了重载  我用的而是重载，为了大家方便看所以 _ThridTestone(p, p1);	 实际上_Z35ThridTestoneXXXX类似这样的名字，冲裁函数我保证用的没错。

引用 1 楼 mujiok2003 的回复: //printf("%d",p1[i]); printf("%hhu",p1[i]); .... printf("%hhu",p2[i]);   z这事做什么

外部函数声明时前面加上 extern "C"


Question: 给刚学完C的出个题目,娱乐娱乐

我是新手，看不出来到底是要完成什么功能

小弟不才，刚开始自学c,看不出个所以然来！

楼主有点奸诈

引用 10 楼 u014556710 的回复:[quote=引用 8 楼 u010211892 的回复:] [quote=引用 楼主 u013573183 的回复:]  int main() {   Hero player;   player.Name = "爱丽丝";   player.Level = 1;    Enemy slime;   slime.Name = "史莱姆";   slime.Exp = 100;      while(player.Level < 5)   {     Fight(player, slime);   }    return 0; }   补全剩余代码  接分，如下，由于不是指针不能改level导致死循环 题目嘛，说是为了照顾c，结果Enemy申明还放在后面，c不能这样，用.而不是->这可怎么改，我没办法了  #include <stdio.h> typedef struct{ char *Name; int Level; int Exp; } Hero; typedef Hero Enemy ;  void Fight(Hero a,Enemy b) { a.Level++; }  int main() {   Hero player;   Enemy slime;   player.Name = ""爱丽丝"";   player.Level = 1;       slime.Name = "史莱姆"";   slime.Exp = 100;       while(player.Level < 5)   {     Fight(player, slime);   }     return 0; }[/quote]   你的typedef Hero Enemy 是怎么回事 Hero 和 Enemy 是两个不同的结构体[/quote] 原因很简单：我懒

引用 8 楼 u010211892 的回复:[quote=引用 楼主 u013573183 的回复:]  int main() {   Hero player;   player.Name = "爱丽丝";   player.Level = 1;    Enemy slime;   slime.Name = "史莱姆";   slime.Exp = 100;      while(player.Level < 5)   {     Fight(player, slime);   }    return 0; }   补全剩余代码  接分，如下，由于不是指针不能改level导致死循环 题目嘛，说是为了照顾c，结果Enemy申明还放在后面，c不能这样，用.而不是->这可怎么改，我没办法了  #include <stdio.h> typedef struct{ char *Name; int Level; int Exp; } Hero; typedef Hero Enemy ;  void Fight(Hero a,Enemy b) { a.Level++; }  int main() {   Hero player;   Enemy slime;   player.Name = ""爱丽丝"";   player.Level = 1;       slime.Name = "史莱姆"";   slime.Exp = 100;       while(player.Level < 5)   {     Fight(player, slime);   }     return 0; }[/quote]   你的typedef Hero Enemy 是怎么回事 Hero 和 Enemy 是两个不同的结构体

引用 楼主 u013573183 的回复: int main() {   Hero player;   player.Name = "爱丽丝";   player.Level = 1;    Enemy slime;   slime.Name = "史莱姆";   slime.Exp = 100;      while(player.Level < 5)   {     Fight(player, slime);   }    return 0; }   补全剩余代码  接分，如下，由于不是指针不能改level导致死循环 题目嘛，说是为了照顾c，结果Enemy申明还放在后面，c不能这样，用.而不是->这可怎么改，我没办法了  #include <stdio.h> typedef struct{ char *Name; int Level; int Exp; } Hero; typedef Hero Enemy ;  void Fight(Hero a,Enemy b) { a.Level++; }  int main() {   Hero player;   Enemy slime;   player.Name = ""爱丽丝"";   player.Level = 1;       slime.Name = "史莱姆"";   slime.Exp = 100;       while(player.Level < 5)   {     Fight(player, slime);   }     return 0; }

捉迷藏的游戏。。。

实现的话以最舒服的方式实现就可以了  之所以写成结构,是为了照顾只学了C的  高手可以任意实现   另外,不要被表面现象骗了,我这是个引导,并非显示了全部内容,可自行发挥  比如 while(player.Level < 5)   {     Fight(player, slime);   }  暗示着,1次或多次Fight 之后 player.Level 是会增加的.

开发模式是自顶向下, 半测试驱动开发  给新人引导一下软件开发的思路.

我打算逐步弄成RPG游戏  这是一个最基本的简单实现,之后慢慢增加功能,可不要往名字大战上写..

感觉是c++的入门知识呢！

#include <string> class Hero { public: Hero(const char* pName,int level):m_name(pName),m_level(level) {}  std::string m_name; int m_level; }; class Enemy { public:Enemy(const char* pName, int exp):m_name(pName),m_exp(exp){}  std::string m_name; int m_exp; }; void Fight(const Hero& a, const Enemy& b) {     printf("%s with level %d fight %s with exp %d\n",a.m_name.c_str(),a.m_level,b.m_name.c_str(),b.m_exp); } 引用 楼主 u013573183 的回复: int main() {   Hero player;   player.Name = "爱丽丝";   player.Level = 1;    Enemy slime;   slime.Name = "史莱姆";   slime.Exp = 100;      while(player.Level < 5)   {     Fight(player, slime);   }    return 0; }   补全剩余代码

以前玩过一款小游戏，叫做名字大作战，好像跟这个有点相似