Question: C语言extern字符数组，无法在循环中输出？？

引用 13 楼 lm_whales 的回复:[quote=引用 12 楼 qldsrx 的回复:] [quote=引用 11 楼 lm_whales 的回复:] 其实你不需要回答那么多，看他二楼的错误信息就知道，肯定是那个变量的定义位置错了，实际我们自己故意将其位置换到函数下面试下，就可以重新那样的错误信息了。[/quote] 我只是示范一下， 回答少了，他不看 [/quote] 不管回答的少不少我都会看的，在这个问题上回复一句我散分 http://bbs.csdn.net/topics/391844721

引用 9 楼 qldsrx 的回复:[quote=引用 7 楼 GZQ0821 的回复:] [quote=引用 3 楼 qldsrx 的回复:] 你这个变量的定义写在了函数定义的后面了  #include<stdio.h> #include<stdlib.h> #include<string.h>  extern char rxtBuf[256];  int mian(void) {   int i=0;   //.......   printf("=======%s\n",rxtBuf);     //可以正常输出   while(i<5)   {     printf("=====%c\n",rxtBuf[i]);    //编译出错     i++;   }   return 0; }  顺序应该没有错吧？？[/quote] 这个int mian(void)不是主函数吧。我刚用主函数测试了下，没任何问题，不然你自己用一个简单的测试程序试试，肯定是你复杂项目里有啥顺序问题错了。[/quote]  非常感谢，是我的疏忽  声明没错是我把变量名字写错了

引用 13 楼 lm_whales 的回复:[quote=引用 12 楼 qldsrx 的回复:] [quote=引用 11 楼 lm_whales 的回复:] 其实你不需要回答那么多，看他二楼的错误信息就知道，肯定是那个变量的定义位置错了，实际我们自己故意将其位置换到函数下面试下，就可以重新那样的错误信息了。[/quote] 我只是示范一下， 回答少了，他不看 [/quote] 多谢多谢  引用 11 楼 lm_whales 的回复:修改一下： [quote=引用 10 楼 lm_whales 的回复:] #include <stdlib.h> #include <string.h> extern char txtBuf[256];  int main(){     strcpy(txtBuf,"Hello Worlds!\n");     printf("%s\n",txtBuf);     int i=0;     while(txtBuf[i]){           printf("%c",txtBuf[i++]);     }     printf("\n");      return 0; }  //注释掉这一行，则编译通不过,其实是链接有问题，，， txtBuf 没定义，所以链接时，找不到这个符号 //char txtBuf[256];  ||=== Build: Debug in extern_dcl (compiler: GNU GCC Compiler) ===| obj\Debug\main.o||In function `main':| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| obj\Debug\main.o:E:\Devlops\CB\extern_dcl\main.c|8|more undefined references to `txtBuf' follow| ||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|  注: extern  char txtBuf[256];///仅仅是外部引用声明，只是多了一个数组大小信息。 ///这种形式，可以提供数组大小信息 ///所有写在这句之后的代码，都能通过 sizeof( txtBuf) 得到数组大小， ///但是有可能造成 数组定义不一致， ///如果只在定义处修改数组大小的话。  ///通常写作 extern char txtBuf[];  ///这种写法，数组定义处，可以随便修改数组大小，二者互不妨碍。[/quote]  非常感谢！！问题找出来了，是我的疏忽  声明没错是我把变量名字写错了

引用 12 楼 qldsrx 的回复:[quote=引用 11 楼 lm_whales 的回复:] 其实你不需要回答那么多，看他二楼的错误信息就知道，肯定是那个变量的定义位置错了，实际我们自己故意将其位置换到函数下面试下，就可以重新那样的错误信息了。[/quote] 我只是示范一下， 回答少了，他不看

引用 11 楼 lm_whales 的回复: 其实你不需要回答那么多，看他二楼的错误信息就知道，肯定是那个变量的定义位置错了，实际我们自己故意将其位置换到函数下面试下，就可以重新那样的错误信息了。

修改一下： 引用 10 楼 lm_whales 的回复:#include <stdlib.h> #include <string.h> extern char txtBuf[256];  int main(){     strcpy(txtBuf,"Hello Worlds!\n");     printf("%s\n",txtBuf);     int i=0;     while(txtBuf[i]){           printf("%c",txtBuf[i++]);     }     printf("\n");      return 0; }  //注释掉这一行，则编译通不过,其实是链接有问题，，， txtBuf 没定义，所以链接时，找不到这个符号 //char txtBuf[256];  ||=== Build: Debug in extern_dcl (compiler: GNU GCC Compiler) ===| obj\Debug\main.o||In function `main':| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| obj\Debug\main.o:E:\Devlops\CB\extern_dcl\main.c|8|more undefined references to `txtBuf' follow| ||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|  注: extern  char txtBuf[256];///仅仅是外部引用声明，只是多了一个数组大小信息。 ///这种形式，可以提供数组大小信息 ///所有写在这句之后的代码，都能通过 sizeof( txtBuf) 得到数组大小， ///但是有可能造成 数组定义不一致， ///如果只在定义处修改数组大小的话。  ///通常写作 extern char txtBuf[];  ///这种写法，数组定义处，可以随便修改数组大小，二者互不妨碍。

#include <stdio.h> #include <stdlib.h> #include <string.h> extern char txtBuf[256];  int main(){     strcpy(txtBuf,"Hello Worlds!\n");     printf("%s\n",txtBuf);     int i=0;     while(txtBuf[i]){           printf("%c",txtBuf[i++]);     }     printf("\n");      return 0; } char txtBuf[256]; 输出 Hello Worlds!  Hello Worlds!  #include <stdlib.h> #include <string.h> extern char txtBuf[256];  int main(){     strcpy(txtBuf,"Hello Worlds!\n");     printf("%s\n",txtBuf);     int i=0;     while(txtBuf[i]){           printf("%c",txtBuf[i++]);     }     printf("\n");      return 0; }  //注释掉这一行，则编译通不过 //char txtBuf[256];  ||=== Build: Debug in extern_dcl (compiler: GNU GCC Compiler) ===| obj\Debug\main.o||In function `main':| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| E:\Devlops\CB\extern_dcl\main.c|7|undefined reference to `txtBuf'| obj\Debug\main.o:E:\Devlops\CB\extern_dcl\main.c|8|more undefined references to `txtBuf' follow| ||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|  extern  char txtBuf[256];///仅仅是外部引用声明，只是多了一个数组大小信息。 通常写作 extern char txtBuf[];

引用 7 楼 GZQ0821 的回复:[quote=引用 3 楼 qldsrx 的回复:] 你这个变量的定义写在了函数定义的后面了  #include<stdio.h> #include<stdlib.h> #include<string.h>  extern char rxtBuf[256];  int mian(void) {   int i=0;   //.......   printf("=======%s\n",rxtBuf);     //可以正常输出   while(i<5)   {     printf("=====%c\n",rxtBuf[i]);    //编译出错     i++;   }   return 0; }  顺序应该没有错吧？？[/quote] 这个int mian(void)不是主函数吧。我刚用主函数测试了下，没任何问题，不然你自己用一个简单的测试程序试试，肯定是你复杂项目里有啥顺序问题错了。

引用 5 楼 lm_whales 的回复:extern char txtBuf[256];     。。。。。。。 char txtBuf[256]; 。。。。。 或者  extern char txtBuf[]; 。。。。   char txtBuf[256];;    。。。。。  不行还是会出错，直接printf输出或者rxtBuf[0]字节输出都行 为什么偏偏不能循环呢？？？ 下面是输出的错误： error:'txtBuf' undeclared (first use in this function) error:(Each undeclared identifier is reported only once for each function it appears in)

引用 3 楼 qldsrx 的回复:你这个变量的定义写在了函数定义的后面了  #include<stdio.h> #include<stdlib.h> #include<string.h>  extern char rxtBuf[256];  int mian(void) {   int i=0;   //.......   printf("=======%s\n",rxtBuf);     //可以正常输出   while(i<5)   {     printf("=====%c\n",rxtBuf[i]);    //编译出错     i++;   }   return 0; }  顺序应该没有错吧？？

引用 4 楼 zhao4zhong1 的回复:头文件重复包含了。 那为什么直接用printf输出就可以？

头文件重复包含了。

你这个变量的定义写在了函数定义的后面了

引用 1 楼 qldsrx 的回复:把错误信息贴出来看呢  error:'txtBuf' undeclared (first use in this function) error:(Each undeclared identifier is reported only once for each function it appears in)

把错误信息贴出来看呢


Question: 冒泡法说有一个错误

哪个单词不会直接百度，还能学点英语。

VS2010中文版的编译错误提示是中文的。

printf("请输入第%d个学生的成绩: "(i+1)); 少个逗号  printf("请输入第%d个学生的成绩: ",(i+1));


Question: 求大神看一下这个哪里出错了，初学者求教数人未果

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

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


Question: 求助！在其他电脑都可以运行，但自己电脑出现内存不能为read

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

点取消调试程序

我自己搞定了多谢帮助的人

@赵4老师 按alt+7并没有反应啊，可以说详细点吗，这个程序是没有问题的只有在我的电脑上运行会出现内存不能为read，多谢了

@user-2 程序没问题啊只有在我自己电脑上会出现这个问题


Question: 有关switch的问题

while((i=getchar())!=q) { switch(i) {...} fflush(stdin); }

执行scanf("%lf",&x)时，输入数据后会有一个回车符‘\n’一起放在缓存，当x读取数据后，遇break退出switch，第二次循环会直接读取缓存里面的回车符，即i=‘\n’，所以就会跳到default

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

像这种问题，自己加断点。一目了然

引用 7 楼 zhao4zhong1 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] switch case里面的break和想退出循环时用的break貌合神离！ 此时最直接最简单的办法就是用goto语句goto到紧接循环外面和后面的下一条语句，如果刚好是退出函数的话，还可以用return。[/quote] 这里如果goto的循环外的话，就起不到多次选择要买的东西了。但是如果goto到switch外而在循环内的话，那岂不是结果不变，像1,2楼说的。

引用 2 楼 anquan88 的回复:因为getchar()也会读取你按的回车键，进入第二次循环。 设个断点看看i的值。 这里我有个疑问，既然getchar会把回车也读进去，开始假设选a然后按回车，那就是把回车放到寄存器里了是吧，那为什么他还会进入到循环里面，而不是继续等待下一个输入字符一块放到寄存器里呢？

我这个是在，vs2013中调试的。我也一直在思考4楼的问题  引用 4 楼 qq_30446977 的回复:[quote=引用 2 楼 奋起无迹的回复:]因为getchar()也会读取你按的回车键，进入第二次循环。 设个断点看看i的值。 我这有个问题。那个a选项后面不是有个break吗，那为什么还进入到第二次循环？[/quote]

引用 5 楼 zhao4zhong1 的回复:switch case里面的break和想退出循环时用的break貌合神离！ 此时最直接最简单的办法就是用goto语句goto到紧接循环外面和后面的下一条语句，如果刚好是退出函数的话，还可以用return。

switch case里面的break和想退出循环时用的break貌合神离！

引用 2 楼 奋起无迹的回复:因为getchar()也会读取你按的回车键，进入第二次循环。 设个断点看看i的值。 我这有个问题。那个a选项后面不是有个break吗，那为什么还进入到第二次循环？

回车被读取了

嗯，懂了，谢谢各位大神

你的情况应该是将回车字符作为一次输入，所有会再进入default一次。我测试的结果，试着随便输入一个数字5回车显示结果是进入两次default。应该用给scanf();输入之后加上getchar(),就好了。getchar()作用是吃掉非法字符

引用 9 楼 xiaoxiaoqiang666 的回复:[quote=引用 2 楼 anquan88 的回复:] 因为getchar()也会读取你按的回车键，进入第二次循环。 设个断点看看i的值。 这里我有个疑问，既然getchar会把回车也读进去，开始假设选a然后按回车，那就是把回车放到寄存器里了是吧，那为什么他还会进入到循环里面，而不是继续等待下一个输入字符一块放到寄存器里呢？[/quote]  http://baike.baidu.com/link?url=glkSPh9bVshd35jmw_W2hOoB-0xFQZ-9CHt3mMUGQtv2hR1Tc9yTcdc6mW2njQ5c2E4AYN7i6BpPXrDrVGrhnq 仔细看看就明白了。

引用 2 楼 奋起无迹的回复:因为getchar()也会读取你按的回车键，进入第二次循环。 设个断点看看i的值。 2楼说的很对，赞一个。受益匪浅。

肯定是回车被接收了，也被switch函数作为参数去检验了，所以才会出现除外的情况。但是怎么解决我也不知道。


Question: 关于Modbus ASCII通讯要发送的字符串中LRC校验字节的处理

没找到答案，先结贴吧，这个问题看来没人感兴趣。自己去研究了，谢谢赵老师。

楼主应该先忘掉字符串，脑中只认识字节和长度（字节数）。

Modbus ASCII  sendbuf[1024]=":0103040a47\xed\r\n"  我猜。

嗯，谢谢赵老师。 我现在想重新问我的问题，就是，Modbus ASCII 和Modbus RTU要发送的字符串是什么样子的。 比如： LRC算出来的是16进制的字节值，若发送的数据是字符串形式，不需任何转换，直接放在字符串最后位置就行了。若发送的数据是数组形式，则需要转换为ASCII值，即由1字节的16进制转换为2字节的ASCII值，4D应该转换为34 44。 是这样的吗？ 又比如： Modbus ASCII  sendbuf[1024]=":0103040a470D0A"  ，这个字符串数组对吗，能直接这样发吗？  有哪位高手能给个详细的程序及说明。

开始、运行、cmd、确定：下面<>括住表示相应按键 chcp 437<Enter> :0103040a<按住Alt键不放，依次按数字小键盘上的<2><3><7>，松开Alt键>

有没有高手帮忙指点下啊？

看不懂啊，赵老师。

嗯，最关键的地方在于： lrc 是BYTE类型，而BYTE类型实际上就是unsigned char类型， 而temp[0]是char类型，做下面这个赋值有没有问题： temp[0]=(char)lrc ;

你的冒号：似应改为半角冒号: 想将237显示为正常的字符，在cmd窗口中输入命令chcp 437

调试结果如下图：

求高手帮忙！

引用 12 楼 xiaobicai 的回复:赵老师，你这个程序没注释，看不懂，对我的问题有什么联系吗？ 你可以把其中的HexDump函数搬到你代码中，随时查看某个字符串在内存中的字节值。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

赵老师，你这个程序没注释，看不懂，对我的问题有什么联系吗？

引用 9 楼 xiaobicai 的回复:赵老师，你发的那个HexDump函数是干什么用的，是将一个字符串转换成16进制的吗，其中第三个参数addr是做什么的？ addr是你想显示的基地址。 例如：#include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; }

有没有对Modbus通讯程序比较熟悉的高手啊。 我这样转换对吗？ 我在百度知道里面找到下面这段说明，有更详细的程序及说明吗？  LRC算出来的是16进制的字节值，若发送的数据是字符串形式，不需任何转换，直接放在字符串最后位置就行了。若发送的数据是数组形式，则需要转换为ASCII值，即由1字节的16进制转换为2字节的ASCII值，4D应该转换为34 44。


Question: 请教如何提取字符串中的运算符

字符串提取出来比较？看看符合列表中的哪种类型的就行了


Question: c语言 如何不用清屏实现某个字符移动？如何不分清屏？

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

引用 1楼user-3 的回复:没变化的地方不用画, 要清除的用背景画啥意思 给个例子白

引用 2楼赵4老师 的回复:仅供参考：#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  Linux下使用NCURSES库。谢谢啦  回来上机试试

百度：C控制台编程

没变化的地方不用画, 要清除的用背景画


Question: C语言的三级指针指向内存地址的问题

多级指针并没有什么神奇，递归定义罢了~

中间任何一级都不能跳过

《牛肉干》 C语言上机课，某女同学偷偷吃起牛肉干。 有一粒牛肉干掉到了键盘上，卡在7和8键之间。 女同学就在键盘上抠啊、抠啊、抠啊…… 程序里一行代码变成这个样子： int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a; 后来的结局是 ————程序顺利通过编译，运行结果正确！ //在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------

多级指针，必须逐级赋值（初始化），否则是野指针


Question: 为什么vc6上可以完美运行的代码到vs2015上编译可通过但不能达到预期效果？

都说了不是system（"pause"）的问题,怎么有这么多人还是回答这个，无语。 自己把问题解决了，还是vs2015的标准问题，为了不用scanf_s特意在工程属性里加了一行_CRT_SECURE_NO_DEPRECATE 结果问题就解决了。

引用 5 楼 弓长羊羽的回复:[quote=引用 4 楼 Ounce1 的回复:] VC6和VS2015的标准不同，举个简单的例子i=5,k=(i++)+(++i)+(++i)在VC中k=13,在VS2015里是15,他们采用的C语言标准不同，建议还是以VS2015为准，VC6太老了 这个问题与C标准无关~[/quote] 诶，那和什么有关？一直觉得是标准的问题，不过好像Dev运行的结果是14，反正我觉得以vs为准没错

引用 8 楼 Ounce1 的回复:[quote=引用 5 楼 弓长羊羽的回复:][quote=引用 4 楼 Ounce1 的回复:] VC6和VS2015的标准不同，举个简单的例子i=5,k=(i++)+(++i)+(++i)在VC中k=13,在VS2015里是15,他们采用的C语言标准不同，建议还是以VS2015为准，VC6太老了 这个问题与C标准无关~[/quote] 诶，那和什么有关？一直觉得是标准的问题，不过好像Dev运行的结果是14，反正我觉得以vs为准没错[/quote] 不管哪个都是错的,在你这么写的时候就注定了没有正确答案.

Ctrl+F5 运行

VS2015表示并没有什么问题

引用 4 楼 Ounce1 的回复:VC6和VS2015的标准不同，举个简单的例子i=5,k=(i++)+(++i)+(++i)在VC中k=13,在VS2015里是15,他们采用的C语言标准不同，建议还是以VS2015为准，VC6太老了 这个问题与C标准无关~

Ctrl+F5 运行  或者最后加getchar();  否则程序运行完竟然退出了

在return 0;前面加个 getchar() 或者system("pause")


Question: C程序求助

仅供参考：#include <stdio.h> #include <string.h> #include <time.h> struct tm st; time_t tt; char timstr[40]; char tmpbuf[128]; char c; int t; int AP() {     if ('P'==c || 'p'==c) {st.tm_hour+=12;return 1;}     if ('A'==c || 'a'==c)                 return 1;                                           return 0; } int dtparse() {     if (7==sscanf(timstr,"%d/%d/%4d %d:%d:%d %c",&st.tm_mday,&st.tm_mon ,&st.tm_year,&st.tm_hour,&st.tm_min,&st.tm_sec,&c)) if (AP()) goto STEP2;     if (6==sscanf(timstr,"%d/%d/%4d %d:%d%c"    ,&st.tm_mday,&st.tm_mon ,&st.tm_year,&st.tm_hour,&st.tm_min           ,&c)) if (AP()) goto STEP1;     if (6==sscanf(timstr,"%4d/%d/%d %d:%d %c"   ,&st.tm_year,&st.tm_mon ,&st.tm_mday,&st.tm_hour,&st.tm_min           ,&c)) if (AP()) goto STEP1;     if (5==sscanf(timstr,"%d.%d.%4d %d:%d"      ,&st.tm_mon ,&st.tm_mday,&st.tm_year,&st.tm_hour,&st.tm_min              ))           goto STEP1;     if (6==sscanf(timstr,"%4d-%d-%d %d:%d:%d"   ,&st.tm_year,&st.tm_mon ,&st.tm_mday,&st.tm_hour,&st.tm_min,&st.tm_sec   ))           goto STEP2; STEP1:     st.tm_sec=0; STEP2:     st.tm_year-=1900;     if (st.tm_mon>12) {t=st.tm_mon;st.tm_mon=st.tm_mday;st.tm_mday=t;}     st.tm_mon-=1;     tt=mktime(&st);     if (-1!=tt) {         strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S",localtime(&tt));         return 1;     } else {         printf("[%s] is Invalid time string!\n",timstr);         return 0;     } } int main() {     strcpy(timstr,"10.01.2012 15:43"        );if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     strcpy(timstr,"8/11/2006 11:10AM"       );if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     strcpy(timstr,"2006/10/31 04:50 PM"     );if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     strcpy(timstr,"1/6/2010 5:20:12 PM"     );if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     strcpy(timstr,"13/12/2012 11:16:17 a.m.");if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     strcpy(timstr,"2013-06-08 09:56:59"     );if (dtparse()) printf("[%s] is [%s]\n",timstr,tmpbuf);     return 0; } //[10.01.2012 15:43] is [2012-10-01 15:43:00] //[8/11/2006 11:10AM] is [2006-11-08 11:10:00] //[2006/10/31 04:50 PM] is [2006-10-31 16:50:00] //[1/6/2010 5:20:12 PM] is [2010-06-01 17:20:12] //[13/12/2012 11:16:17 a.m.] is [2012-12-13 11:16:17] //[2013-06-08 09:56:59] is [2013-06-08 09:56:59] //

恩，是作业。

这是作业作业？


Question: C语言运行过程中修改变量

引用 3 楼 lm_whales 的回复:因为C语言，没有运行时类型信息。 C的类型信息，只在编译期间有效。 只有自己采取措施，才能解决 1）同一 名字， 2）同一内存， 等 同一事物，表示不同内容的方法。  谢谢

当然你可以用union，一块内存可以同时表示多种类型变量，或者使用指针，然后转换指针类型去解释同一个变量，这样的话可以

这是语法规定，你要修改变量类型可以重新申明一个对象 随便一个可以运行的程序都是例子，因为他们都得遵循这个前提


Question: 求帮忙！！！

修改如下：   #include <stdio.h>, int b(int s) { 	int f1 = 0, f2 = 1, fn; 	fn = f1 + f2; 	while(fn <= s) 	{ 		fn = f1 + f2; 		f1 = f2; 		f2 = fn; 	} 	return fn; } int main() { 	int s; 	printf("please input : "); 	scanf("%d", &s); 	printf("%d\n", b(s)); 	return 0; }

fn没初始化，里面的数值是不定的。 再运行几次看看。

单步调试一下不就ok了


Question: Inet——addr（）

问题是sacnf("%s\n",ip);这句话  我多加了一个换行符

我自己写的函数，用来获取ip地址的uint表示形式，也就是你那个server_addr.sin_addr.s_addr的值，处理速度超快（第二个参数输出IP，返回值为字符串的下一个指针位置，为NULL表示IP字符串格式有误）  #include <sys/types.h> #include <stdint.h> char const dex_table[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02,         0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; char* getip(char *input, uint *ip) {     uint tmp = 0, i = 0;     uint8_t *src = (uint8_t*) input, *dst = (uint8_t *) ip, value;     *ip = 0;     while ((value = *src++)) {         if (dex_table[value] != -1)         break;     }     do {         if (value == '.') {             dst[i] = tmp;             tmp = 0;             if (i++ == 3)             return (char*) src;         } else {             if (dex_table[value] == -1)             break;             tmp = (tmp << 3) + (tmp << 1) + dex_table[value];         }         if (tmp > 0xff) return NULL;     }     while ((value = *src++));     if (i == 3) {         if (tmp > 255)         return NULL;         dst[3] = tmp;         return (char*) src;     }     return NULL; }

编译器有什么提示


Question: 定义一个大小为10的整形数组，使用初始化方法为数组元素赋初值，编程计算这10个元素的平均值，并查找比平均值大的数组元素。

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

楼主的aver计算是除了10次10，把aver这个放到for循环外部

引用然后呢，你那个求平均的位置也不对，怎么能在循环里面呢？这里确实写错了

然后呢，你那个求平均的位置也不对，怎么能在循环里面呢？

没调试过，但是我觉得吧 首先你sum是 int类型的 然后你sum/10最后的结果应该也是int类型。 你这样强制转成double类型应该会有问题才对。

引用aver=(sum*1.00)/10;这里的写法有什么意义？？结果是对的，这里的写法是对他的和值进行一个格式定义吗？？

会不会是定义类型出了错？？或者输出格式出现了错误？

引用aver=sum/10,这个语句的位置写错了，应写在循环外面。然后有个建议，所有循环里面的printf函数最好加个\n，这样更容易看。 写在外循环还是不对

楼上两个说的很对，赞一下。

修改如下：  #include<stdio.h> #include<math.h> int main() { 	int i; 	double sum, aver; 	double a[10] = { 3,6,1,7,8,4,9,5,10,2 }; 	printf("数组中的初值是:\n "); 	for (i = 0; i < 10; i++) 	{ 		printf("%g ", a[i]); 	} 	printf("\n"); 	sum = a[0]; 	printf("平均值是："); 	for (i = 1; i < 10; i++) 	{ 		sum += a[i]; 	} 	aver = sum / 10; 	printf("%g\n", aver); 	printf("数组中比平均值大的数是："); 	for (i = 0; i < 10; i++) 	{ 		if (a[i] > aver) 			printf("%g\t", a[i]); 	} 	printf("\n"); 	return 0; } //数组中的初值是: //3 6 1 7 8 4 9 5 10 2 //平均值是：5.5 //数组中比平均值大的数是：6	 7	 8	 9 	10


Question: 关于strcat的问题

C中字符串以'\0'结尾，你\0后就算还有其他内容，输出时字符串也只判断到\0为止，所以后面的东西显示不出来 另外strcat直接strcat(p,"World"); 这样用，他连接时会自动判断字符串结尾的，不需要写成p+5

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\strcat.c /*** *strcat.c - contains strcat() and strcpy() * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       Strcpy() copies one string onto another. * *       Strcat() concatenates (appends) a copy of the source string to the *       end of the destination string, returning the destination string. * *******************************************************************************/  #include <cruntime.h> #include <string.h>  #ifndef _MBSCAT #pragma function(strcat,strcpy) #endif  /* _MBSCAT */  /*** *char *strcat(dst, src) - concatenate (append) one string to another * *Purpose: *       Concatenates src onto the end of dest.  Assumes enough *       space in dest. * *Entry: *       char *dst - string to which "src" is to be appended *       const char *src - string to be appended to the end of "dst" * *Exit: *       The address of "dst" * *Exceptions: * *******************************************************************************/  char * __cdecl strcat (         char * dst,         const char * src         ) {         char * cp = dst;          while( *cp )                 cp++;                   /* find end of dst */          while( *cp++ = *src++ ) ;       /* Copy src to end of dst */          return( dst );                  /* return dst */  }   /*** *char *strcpy(dst, src) - copy one string over another * *Purpose: *       Copies the string src into the spot specified by *       dest; assumes enough room. * *Entry: *       char * dst - string over which "src" is to be copied *       const char * src - string to be copied over "dst" * *Exit: *       The address of "dst" * *Exceptions: *******************************************************************************/  char * __cdecl strcpy(char * dst, const char * src) {         char * cp = dst;          while( *cp++ = *src++ )                 ;               /* Copy src over dst */          return( dst ); }  void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }


Question: 求12864显示超声波测距的多级菜单程序


Question: 辗转相除法求最大公约数

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

按照大家提的意见改了，但是还是出错。。难道是我的编译器的问题？我用的dev c++

引用 4 楼 wang0635 的回复:scanf("%d，%d",&u,&v); 中间的中文逗号，你输入了吗？ 其他没有什么问题，不用考虑谁大谁小，循环一轮后就进入正轨了 最好改成 scanf("%d%d",&u,&v);  同意。

这样行吗 int gcd(int a,int b){         return !b ? a : gcd(b,a%b);     }

v和u要先比较大小，用大的那个除以小的取余


Question: 求助c语言大神。关于php扩展开发中使用第三方库的问题

EXAMPLE Load the math library, and print the cosine of 2.0:  #include <stdio.h> #include <dlfcn.h>  int main(int argc, char **argv) {     void *handle;     double (*cosine)(double);     char *error;      handle = dlopen ("libm.so", RTLD_LAZY);     if (!handle) {         fprintf (stderr, "%s\n", dlerror());         exit(1);     }      dlerror();    /* Clear any existing error */     *(void **) (&cosine) = dlsym(handle, "cos");     if ((error = dlerror()) != NULL)  {         fprintf (stderr, "%s\n", error);         exit(1);     }      printf ("%f\n", (*cosine)(2.0));     dlclose(handle);     return 0; }  If this program were in a file named "foo.c", you would build the program with the following command:   gcc -rdynamic -o foo foo.c -ldl   Libraries exporting _init() and _fini() will want to be compiled as follows, using bar.c as the example name:   gcc -shared -nostartfiles -o bar bar.c

LDCONFIG Section: Linux Programmer's Manual (8) Updated: 2002-05-06  --------------------------------------------------------------------------------    NAME /sbin/ldconfig - configure dynamic linker run time bindings    SYNOPSIS /sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cache ] [ -r root ] directory ...  /sbin/ldconfig -l [ -v ] library ...   /sbin/ldconfig -p     DESCRIPTION ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and file names of the libraries it encounters when determining which versions should have their links updated.  ldconfig will attempt to deduce the type of ELF libs (ie. libc5 or libc6/glibc) based on what C libs, if any, the library was linked against. Therefore, when making dynamic libraries, it is wise to explicitly link against libc (use -lc).   Some existing libs do not contain enough information to allow the deduction of their type. Therefore, the /etc/ld.so.conf file format allows the specification of an expected type. This is only used for those ELF libs which we can not work out. The format is "dirname=TYPE", where TYPE can be libc4, libc5, or libc6. (This syntax also works on the command line.) Spaces are not allowed. Also see the -p option. ldconfig should normally be run by the superuser as it may require write permission on some root owned directories and files.     OPTIONS -v  Verbose mode. Print current version number, the name of each directory as it is scanned, and any links that are created. Overrides quiet mode.  -n  Only process directories specified on the command line. Don't process the trusted directories (/lib and /usr/lib) nor those specified in /etc/ld.so.conf. Implies -N.  -N  Don't rebuild the cache. Unless -X is also specified, links are still updated.  -X  Don't update links. Unless -N is also specified, the cache is still rebuilt.  -f conf  Use conf instead of /etc/ld.so.conf.  -C cache  Use cache instead of /etc/ld.so.cache.  -r root  Change to and use root as the root directory.  -l  Library mode. Manually link individual libraries. Intended for use by experts only.  -p  Print the lists of directories and candidate libraries stored in the current cache.      FILES /lib/ld.so  run-time linker/loader  /etc/ld.so.conf  File containing a list of colon, space, tab, newline, or comma spearated directories in which to search for libraries.  /etc/ld.so.cache  File containing an ordered list of libraries found in the directories specified in /etc/ld.so.conf.  --------------------------------------------------------------------------------


Question: C/C++

while(j=100000-S.right!=10)     {     while(j<10)         {         n=S.data[position][0];         t=0;         for(i=0;i<n;i++)         {             if(S.data[S.left][0]>n)              {                 S.data[S.right][1]=S.data[S.left][1];                 S.data[S.right--][0]=S.data[S.left][0];                 S.left--;             }             else             {                 k=S.data[t][0];                 m=S.data[t][1];                 S.data[t][1]=S.data[S.left][1];                 S.data[t++][0]=S.data[S.left][0];                 S.data[S.left][1]=m;                 S.data[S.left][0]=k;             }         }         position++;     } 赋值运算符的优先级低于关系运算符所以j=100000-S.right!=10应改为（j=100000-S.right）!=10  while(j<10)   {   ................ }你的这条循环语句感觉好像要么不循环，要么死循环 还有你的for循环语句好像也有问题吧，假如S.data[S.left][0]到S.data[0][0]之间S.data[S.left][0]最大而S.data[0][0]最小，那不是怎么循环都没有结果么

学会下断点调试~

Students S;     S.left=-1;            S.right=100000;     int i,j,t,k,m,position=0,n;     scanf("%ld %d",&n,&k);     for(;S.left<n;S.left++)     {            scanf("\n");            S.data[S.left][0]=0;                for(j=0;j<=k;j++)         {             scanf("%d",&t);             getchar();             if(j==0) S.data[S.left][1]=t;     //前面 S.left=-1，这儿不会出错吗             else S.data[S.left][0]=S.data[S.left][0]+t;         }     }

输入输出是什么? 直接快速排序, 得出前10个就可以,,


Question: GDB分屏显示的时候，如何移动GDB的命令行中的光标

在GDB文本界面中，有4个窗口： command 命令窗口.，可以键入调试命令 source 源代码窗口.，显示当前行,断点等信息 assembly ，汇编代码窗口 register ，寄存器窗口 可以使用focus  next命令将窗口的焦点进行下移，就可以在cmd窗口进行以前的那种操作了。

引用 1 楼 zhao4zhong1 的回复:http://my.oschina.net/jiangwave/blog/126552 ？我已经知道了，使用Ctrl+x+a这个快捷键可以进行分屏的切换，也就可以退出分屏的显示了。

您好，请问楼主知道gdb如何退出当前分屏吗？


Question: 单链表的创建与输出

引用 12 楼 zhao4zhong1 的回复:最后供膜拜： 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*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;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     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; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //

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

引用 8 楼 赵4老师的回复:#include <stdio.h> #include <time.h> #include <stdlib.h> typedef struct Node {     int data;     struct Node *next; }Node,*LinkList; void CreateList(LinkList*,int);  int main() {     LinkList L;     int n=5;     CreateList(&L,n);     LinkList p=L;     while(p->next!=NULL)     {         p=p->next;         printf("%d ",p->data);     }     printf("\n");     return 0; }  void CreateList(LinkList* L,int n) {     LinkList p,q;     int i;     //srand(time(0));     *L=q=(LinkList)malloc(sizeof(Node));     (*L)->next=NULL;     for(i=0;i<n;i++)     {         p=(LinkList)malloc(sizeof(Node));         p->data=i+1;//rand()%100+1;         p->next=NULL;         q->next=p;         q=q->next;     } } //1 2 3 4 5 //  哦哦，我知道哪里错了！我输出链表的循环写错了！！无语O__O"…我用的是头插法，你直接给我改成了尾插法，不过发现了我错在哪里了！非常感谢！！！还有你的代码里*L=q=(LinkList)malloc(sizeof(Node));这句可以不给q动态分配一个内存，q只是尾指针嘛，函数结束后就可以释放掉了，节省了内存

引用 6 楼 HXY22765616的回复:引用 5 楼 HXY22765616 的回复:L要在CreateList函数里面创建的空间，当CreateList函数调用结束后L的空间也就释放掉了所以CreateList函数过后L没什么变化 malloc函数不是需要手动释放的吗！！在堆上分配的空间好像在函数结束后不会自动释放的~

引用 3 楼 diligent_snail的回复:P=L没错，问题是你在输出p->data后，指针变量P并没有后移，即p=p->next，所以p->next一直不等于NULL，while循环一直会输出第一个节点的数据 哦，那句话本来是有的，少打了一句，但是有那句的话还是报错！！！

引用 1 楼 弓长羊羽的回复:这里的调用不对  CreateList(&L,n);  即使改过来：  CreateList(L,n);  也不对。 除非…… 一种方法是  LinkList CreateList(int n); 如此调用 p = CreateList(n);   即可  好像问题就出在LinkList p=L;这句话上，CreatList里面的参数给的是（LinkList *L,int n）是因为用的地址传递，如果把LinkList *L改成LinkList L就变成值传递了，形参的变化就影响不了实参了，要是去掉的话肯定可以，但问题好像不是出在这！


Question: 顺序栈操作集，错在哪里啊

引用 6 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 一年前，你给我回复了，后来忙着考试没再学C，没想到啊现在又给我回复了。 好人一生平安。

引用 5 楼 anquan88 的回复: #include <stdio.h> #define MaxSize 100  struct StackNode { 	int data[MaxSize]; 	int top; };  typedef struct StackNode *PtrStackNode; bool PushStack(PtrStackNode);  PtrStackNode create(int N) { 	//要函数声明，否则将PushStack看成int返回值类型，造成类型不匹配  	PtrStackNode stack = new StackNode; 	int i;  	stack->top = -1;  	for (i = 0; i<N; i++) 	{ 		if(!PushStack(stack)) 			break; 	}  	return stack; }  int IsEmpty(PtrStackNode stack) { 	if (stack->top == -1) 		return 1; 	else 		return 0; }  int IsFull(PtrStackNode stack) { 	if (stack->top == MaxSize - 1) 		return 1; 	else 		return 0; }  bool PushStack(PtrStackNode stack) { 	int item;  	if (!IsFull(stack)) 	{ 		scanf_s("%d", &item);  		stack->top++; 		stack->data[stack->top] = item; 		return 1; 	} 	else 	{ 		printf("栈已满\n"); 		return 0; 	} }   void PopStack(PtrStackNode stack) { 	if (IsEmpty(stack)) printf("栈已空，无法出栈\n");   //有返回值的函数无返回 	else 		printf("已删除%d\n", stack->data[stack->top--]);   //如果是stack->top减2，可以将其赋值给一个变量，减2后再返回      }   void OutPutStack(PtrStackNode stack) { 	int k; 	k = stack->top; 	while (k>-1) 	{ 		printf("%d\n", stack->data[k]); 		k--; 	} 	printf("已输出完毕\n"); 	return;  }   int main() {  	int N; 	PtrStackNode stack;  	printf("请输入栈中元素个数:"); 	scanf_s("%d", &N); 	printf("\n");  	stack = create(N); //建栈N个元素,返回栈结点指针  	OutPutStack(stack);  	PopStack(stack);  	OutPutStack(stack);  	PushStack(stack); 	delete stack; }  看着你的代码总算改好了，调用IsEmpty,IsFull函数竟然没写实参 建立栈时竟然忘记建立空间保存栈这种结构  #include <stdio.h> #include <stdlib.h> #define MaxSize 100  struct StackNode { 	int data[MaxSize]; 	int top; }; typedef struct StackNode *PtrStackNode; void PushStack( PtrStackNode stack );  PtrStackNode create( int N ) {     void PushStack( PtrStackNode stack );//要函数声明，否则将PushStack看成int返回值类型，造成类型不匹配      PtrStackNode stack = (PtrStackNode) malloc( sizeof (struct StackNode) ) ;//建立栈时需要开辟一个空间让指针指向它，在空间内有元素data数组	 	int i;  	 	stack->top=-1;  	for( i=0 ; i<N ; i++ ) 	{		 		PushStack( stack ); 	}  	return stack; }   int IsEmpty( PtrStackNode stack ) { 	if( stack->top==-1 ) 		return 1; 	else 		return 0; }   int IsFull( PtrStackNode stack ) { 	if( stack->top == MaxSize-1 ) 		return 1; 	else 		return 0; }   void PushStack( PtrStackNode stack ) { 	int item; 	 	if( !IsFull(stack) )	 	{	 		scanf("%d",&item); 	 		stack->top++; 		stack->data[stack->top] = item ; 		return; 	} 	else 	{ 		printf("栈已满\n"); 		return; 	} }   void PopStack( PtrStackNode stack ) { 	if(IsEmpty(stack)) printf("栈已空，无法出栈\n");   //有返回值的函数无返回 	else 		printf ( "已删除%d\n" , stack->data[stack->top--] ) ;   //如果是stack->top减2，可以将其赋值给一个变量，减2后再返回	  }   void PrintfPutStack(PtrStackNode stack) { 	int k; 	k=stack->top; 	while(k>-1) 	{ 		printf( "%d\n" , stack->data[k] ); 		k--; 	} 	printf("已输出完毕\n") ; 	return;  }   int main() { 	 	int N; 	PtrStackNode stack;  	printf("请输入栈中元素个数:"); 	scanf("%d",&N); 	printf("\n");      stack = create( N ) ; //建栈N个元素,返回栈结点指针  	PrintfPutStack(stack);  	PopStack(stack);  	PrintfPutStack(stack);  	PushStack(stack); 	 }

引用 1 楼 anquan88 的回复:PtrStackNode create( int N ) {     void PushStack( stack );//要函数声明，否则将PushStack看成int返回值类型，造成类型不匹配                                        //这儿的函数声明不对，stack又不是某种变量类型，改成PtrStackNode      PtrStackNode stack;     int i;           stack->top=-1;       for( i=0 ; i<N ; i++ )     {                PushStack( stack );     }       return stack; } 改了下还是不行 会不会和函数的调用有关

引用 2 楼 zhangxiangDavaid 的回复:学会设置断点调试~ 我把那句错误的声明改了下， void PushStack( PtrStackNode stack );还是运行不了。 试着调试看了，不知道错在哪

学会设置断点调试~


Question: 结构体指针成员和数组成员赋值的区别

结构体整体复制，本来是不可以的，后来可以了（包括内含数组的结构体，但是用初始化表初始化，似乎还不可以， C++11就不清楚了） 结构体初始化，则始终可以。

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）

另外： struct A a={"hello"};        //结构体指针成员可以初始化  struct B b={"hello"};        //结构体数组成员可以初始化   这两句中，第一句是让结构体中的name指向常量区中的字符串，第二句则是复制到数组中 结构体初始化时语法允许这样写，其他时候则不允许这样写（包括已初始化后的结构体不能再这样进行赋值）

引用 1 楼 user-8 的回复:听说普通数组也可以赋值     char  name[20];     name = "hello1";  这种肯定不可以

数组的指针是个常量，你不能改变他的值（他指向的位置），只能把内容复制进去 而写成char*则只是一个指针，a.name="hello1";则让他指向了常量区的hello1字符串，故可行  char[50]数组你定义时就分配好了50的大小，故可以复制内容进去 而char*只是一个指针，你定义后他可能指向任何位置，并没为你分配任何空间，如果需要strcpy，可以动态分配一块内存，如：b.name = new char[50];

char *name name是个指针变量, 可以直接把地址赋给它 char name[20] name是个数组名, 已经是个地址了

谢谢大家～～～～～～～

这个和结构体没关系。  引用 楼主 zzl_zZ 的回复:#include <stdio.h> #include<string.h> struct A { 	char *name; }; struct B { 	char name[50]; }; int main(void) { 	struct A a={"hello"};		//结构体指针成员可以初始化 //上面A中只有一个char*指针，而hello是放在常量区的，a={"hello"}只是让指针指向了常量区的hello，成员变量name没有分配内存，他只是一个指针变量  	struct B b={"hello"};		//结构体数组成员可以初始化 这个b成员变量是数组，当初始化结构体的时候为成员变量分配了50个字符空间，所以，这个hello不会在常量区存放，会直接存在分配的50个字符空间中。他与A中的char*型变量不同，char*成员变量在结构体a初始化时只分配了一个指针变量的空间，一般是4个字节或者8个字节(这和平台有关) 	a.name="hello1";			//指针成员可以直接赋值 //这里指针可以直接赋值，是因为可以改变a中的指针变量name的指向，指向了常量区的"hello1“，注意name只是改变了指向 	b.name="hello1";			//error 数组成员不能这样赋值 //上面b是数组，数组没有这样赋值的。 	strcpy(a.name,"hello2");	//error 指针成员不能这样赋值  需要用malloc分配内存才行  //strcpy两个参数实际上是两个数组，第一个参数是需要有分配空间来接收第二个参数的值，因此第一个参数不能是没有分配空间的指针 	strcpy(b.name,"hello2");	//数组成员可以这样赋值  //b的name是数组，可以调用strcpy，strcpy实际上是内存拷贝，第二个可以字符串常量或者数组或者分配空间的指针变量。 	return 0; }  为什么结构体变量两种不同成员的赋值的方式都不一样？ 普通数组变量和指针变量都可以这样赋值啊。。。

字符串指针变量和字符串数组之间的差别…

这个问题和结构体关系不大。关键是数组在定义完成后不能再赋值的。  可以把数组名理解为一个指针常量： 定义的时候可以让它指向一个字符串，之后就不能再指向别的字符串了。


Question: 求帮忙啊！！

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

我觉得应该这样才好 #include<stdio.h> int main(void) { 	double a=0,i=14875,j=17850,k=23900,l=29750,sum=0; 	double m=0.15,n=0.28; 	printf("您的收入：\n"); 	scanf("%lf",&a); 	 	if(j>a>i) 	sum=i*m+(a-i)*n; 	else if(k>a>j) 	sum=j*i+(a-j)*n; 	else if(l>a>k) 	sum=k*m+(a-k)*n; 	else if(a>l) 	sum=l*m+(a-l)*n; 	else 	sum=a*m; 	printf("税金：%.2lf\n",sum); 	return 0; }

谢谢各位大神，一下子明白了。嘿嘿。这道题要求是用switch来编写的。

楼主调用scanf("%d", t);的目的是让scanf函数把用户输入的值放到变量 t 里。 可是，要想让一个函数把信息通过参数反馈回来，这个参数就需要是某变量的地址。  楼主的这种写法，scanf（）会把t的值（0，也就是0x00000000)当做变量的地址，用户输入数据后， scanf就会试图在0x00000000起始的地址写入数据，引起异常。  另外，楼主网上查询下pass by value和pass by reference这两个概念的区别会对处理类似问题有帮助的。

scanf("%d", t);  改成  scanf("%d", &t);  其他scanf的地方同理改

我看不懂哎，麻烦能不能讲清楚点啊，大锅

C语言的类型不安全不适合新手啊.


Question: 链式存储结构多项式加法错在哪里？

引用 1 楼 zhangxiangDavaid 的回复:学会设置断点调试~ 一元多项式参考：http://blog.csdn.net/zhangxiangdavaid/article/details/31032251 看完了灰常感谢


Question: fwrite读写文件

引用 2 楼 zhanglusmile 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  其实一直没懂，是什么意思？？ [/quote] 不懂，就尝试下~

在内容写入之后或文件关闭之前调用一下fflush函数试试。

引用 1 楼 zhao4zhong1 的回复:推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  其实一直没懂，是什么意思？？


没有具体提示"5 个错误, 1 个警告"是什么么？ 另外，看你用了中文，自己好好查查是不是代码里有符号不小心也输入了中文（全角）的

引用 4 楼 baidu_32324411 的回复:一开始打开CFREE要怎么设置,直接关闭弹出的对话框吗??????? 定位错误~

引用 7 楼 baidu_32324411 的回复:IDE环境  是什么  求详解? http://baike.baidu.com/link?url=J2cZN94zywPOP2C7j26T-jK8z3OTQaCvmVbfUGSoFotGpx772Peas00ph7yJZNb7NZKQb1SoSMNkktdNHJTx6TiSkVgooq4BK-r34Q5Rmc3

重装软件没用,还是显示有错.

我运行了没有问题 建议你卸载重装软件

IDE环境  是什么  求详解?

cfree没有用过，是不是IDE环境没有配好？

没给文件命名吧，文件名现在是未命名.cpp

直接关闭弹出来的那个，然后左上角文件新建

一开始打开CFREE要怎么设置,直接关闭弹出的对话框吗???????

粗略看下，没什么问题~


Question: 请教一个c栈程序的问题

引用 2 楼 qq_21747999 的回复:[quote=引用 1 楼 u010231493 的回复:] #define MD（a）a<<2这是一个宏。 首先我们按照宏替换的原则来看。。结果如下: MD(1)----->1<<2   再来看1<<2  。<<是按位运算符，百度即可。 1的二进制是1，进行按位运算就是1向左移动俩位，就是100（二进制）     ；然而100刚好是4 那MD是什么意思呢，是个函数？[/quote]  恩，是个宏，宏的作用是替换就成了我上面说的那样了。楼主可以多百度看看宏的用法。好了，谢谢！给分。

带参数的宏，类似于函数

MD不就是个宏定义吗？ 1<<2 不就是1左移两位，是4了吗？ 楼主基础很差啊

引用 1 楼 u010231493 的回复:#define MD（a）a<<2这是一个宏。 首先我们按照宏替换的原则来看。。结果如下: MD(1)----->1<<2   再来看1<<2  。<<是按位运算符，百度即可。 1的二进制是1，进行按位运算就是1向左移动俩位，就是100（二进制）     ；然而100刚好是4 那MD是什么意思呢，是个函数？


Question: C语言求前辈看一段小代码

仅供参考：/*--------------------------------------- 函数型计算器(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=='%'||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] = fmod(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=='/'||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] = fmod(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] = fmod(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; }

对算术表达式的解析，没有这么简单，可以参看鄙人的一个不入流的方法：http://blog.csdn.net/zhangxiangdavaid/article/details/27176751

代码还存在数组越界问题，需要注意……

for (i = 0; i < 100; i++){          //搜索乘号，先算第一次乘法的值// if (b[i] == '*') sb = a[i] * a[i + 1];  //  b[0]是+，这一句不会执行，sb==1  break;   //这句执行，跳出循环。后面就成了1+1*4=5。这两句加上{}就行了。 }

for (i = 0; i < 100; i++){          //搜索乘号，先算第一次乘法的值// if (b[i] == '*') sb = a[i] * a[i + 1]; break;    //break会导致b[0]不是*就直接跳出循环。 }


Question: 结构体数组为何要在声明时定义

a[50] = a[temp]; 越界了

struct Student  {      int num;       char name[20];        float score;       int age;  }; 这样定义后，使用是需要struct Student student [ 50]; 也就是说变量声明需用struct 结构体名 变量名。  改成 typedef struct Student {     int num;      char name[20];       float score;      int age; }Student; 就没有上面问题了

1.越界  2.定义位置不同，越界造成的后果不同。  struct Student a[50]; 这是局部变量，越界访问影响到函数体。  struct Student {     int num;      char name[20];       float score;      int age; }a[50];  这是全局变量，越界访问未影响到函数体，会造成未知后果。

26行明显越界~

引用 5 楼 ZipperLin 的回复:[quote=引用 3 楼 ahacsdn 的回复:] struct Student a[50]; 那么 a 的范围是 a[0]-a[49]; 你排序的时候用a[50]做临时变量导致了越界。 你在声明了 a[50] 后，紧接着的声明： int temp, sum, num, times; 这样 a[50] 所在的这块内存其实是这几个变量所在的内存区域，排序时由于给 a[50]  做了赋值，导致该内存区域中 temp和time的值改变，并未按照你的意愿在 for 循环中递增。  如果在结构声明后紧接着声明 a[50]  ，两处内存就不是连在一起的，程序就正常跑了。 也不能说正常吧，越界总是危险的。为什么排序时由于给 a[50]  做了赋值，会导致该内存区域中 temp和time的值改变?我调试的时候是正常的[/quote]   你把这几个变量的地址输出一下看看：

引用 6 楼 hshshaaa 的回复:  即便改成在结构体声明那里，也会报错。估计是编译器没有识别吧。我用的xcode，都会提示a[50]超过数组所包含的50个元素了。 我记得书上有这么一句话“系统不会检测数组元素的下标是否越界，编程时，必须保证数组下标不能越界”，这就能解释为什么编译没出问题，运行时出问题了。可能这是针对老一点的编程软件吧。

引用 3 楼 ahacsdn 的回复:struct Student a[50]; 那么 a 的范围是 a[0]-a[49]; 你排序的时候用a[50]做临时变量导致了越界。 你在声明了 a[50] 后，紧接着的声明： int temp, sum, num, times; 这样 a[50] 所在的这块内存其实是这几个变量所在的内存区域，排序时由于给 a[50]  做了赋值，导致该内存区域中 temp和time的值改变，并未按照你的意愿在 for 循环中递增。  如果在结构声明后紧接着声明 a[50]  ，两处内存就不是连在一起的，程序就正常跑了。 也不能说正常吧，越界总是危险的。为什么排序时由于给 a[50]  做了赋值，会导致该内存区域中 temp和time的值改变?我调试的时候是正常的

也不知道对不对，共同学习啊

引用 1 楼 zhangxiangDavaid 的回复:另一种方法：  typedef struct Student {     int num;      char name[20];       float score;      int age; }Student; Student a[50]; 问题是为什么第一种会错误


Question: 译密码

相减取余

char*str = "ABCDE"; char* p = str; while(*p)     *p = *p + 4;

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

引用 2 楼 fly_dragon_fly 的回复:while((ch=getchar())!=EOF)         if(isupper(ch)) putchar((ch-'A'+4)%26+'A');    EOF   isupper 这俩个是什么意思

用进制可以实现，，，，


Question: 做个统计空格数的程序，为什么总数打印不出来

使用楼上的的输入，程序是没有问题的~

Linux:Ctrl+D Windows:Enter,Ctrl+Z,Enter

while(c!=EOF)     //c一直不等于EOF一直循环

程序没有问题。  运行的时候，输入Ctrl+Z就可以跳出循环了。

win : Ctrl+D linux: Ctrl+Z

为什么c一直不等于EOF啊？

EOF不是文件末尾吗...本人傻，说错勿喷

在windows下，按回车，ctrl+z，回车，就输入EOF了


Question: 在书上看到的一个非递归后序遍历二叉树的算法，求思路讲解，而且这段代码运行不了····

不要沉呀！求大神！！！！

为什么会一直提示q未初始化

遍历二叉树 http://blog.csdn.net/zhangxiangdavaid/article/details/37115355


Question: 100分求一数组元素位置标记算法，请高手赐教

B[m,n]个头指针节点，和B[m,n]个整数存储点[m,n]数值为1的年数。//结构体1 year节点int型村具体的年份，next指针节点存下一个满足条件的年份。 //结构体2

现在最希望使用一个二维数组就能满足标记位置的算法，而且我的现在的开发平台，对数组都是整体操作的，类似matlab一样，比如找小于0的元素，直接就是B=A<0即可（B值即为0或1），使用结构体不是很方便。


Question: 顺序表求解！！！（我要实现插入删除计字符数，程序没有错，但不能实现我想要的功能）

至少  	k = strlen(Data); 	//for (k = 0; k < 1024; k++) 	//{ 	//	if (Data[k] != '!') 	//		continue; 	//	else 	//		break; 	//}  当然，还有其它问题~

puts(Data) gets(Data) 这个怎么编过去的


Question: [求助帖]我想编一个程序，谁帮我一下

引用 3 楼 gwbzx 的回复:#include<stdio.h> int main(void) { system("shutdown -s -t 0");  return 0; } 运行即可! 大忽悠~

搜“网络爬虫 源代码”

写个爬虫呗，会点http和socket 和正则就行了，当然你想整复杂的也行


Question: 段错误

先输出"aaaa,"，然后是出错。

引用 5 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  教坏小盆友

引用 2 楼 u010424970 的回复:看错了，因是先执行第五行，输入aaaa,然后出现段错误。所以选C 我看也是

看错了，因是先执行第五行，输入aaaa,然后出现段错误。所以选C

A 在我现在了解的，有以下： char *s="aaaa";，这里，s会是一个不能变的char*型常数指针，相应的引用s的地方，应该都是变成了固定的地址值了，它指向一个固定的地址，就是字符串"aaaa"的首地址，然后，像这种定义的字符串，是不能改变的，因为它在编译后，值保存在代码段，代码段的内存页是没有写权限。 另一个偏点的信息就是，只有使用像bash这样的shell才会提示：段错误。个别久远的shell直接死进程不提示信息，比如我们在IA32系统里，运行bash编写代码，会有提示，但是嵌入式里的sh,使用的是/bin/sh命令，它是不提示信息错误信息的。这个信息请看linux的信息机制。


Question: 为什么我在C里面打印的EOF的值为10？？？？

因为你输入a后输入了一个回车键 回车键的%d是10

回车是10吧


其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

具体你要看汇编代码，看函数运行后是返回到哪条指令，把那条指令覆盖成你的函数地址 另外用Release版，因为Debug会去检查是否栈平衡等可能会提示错误，我发那个在VC6下可以运行显示“I'm Come In!!!” 具体楼主也不用纠结，知道有这么回事就行

引用 9 楼 LIGHTSWORNLEIHAO 的回复:[quote=引用 3 楼 paschen 的回复:] 地址你可能没搞对，参看这个：   void fun() { 	printf("I'm Come In!!!"); }  int main() { 	int array[1] = {1}; 	array[2] = (unsigned int)fun; 	return 0; }    这也是 缓冲区溢出攻击基本原理这个不行，实测是array【6】。我估计是1占个位置，、0占个位置，ebp四个位置[/quote而且这个在我把数组类型变成char后不管用了，不管最后那个array【】]方括号里是几

引用 3 楼 paschen 的回复:地址你可能没搞对，参看这个：   void fun() { 	printf("I'm Come In!!!"); }  int main() { 	int array[1] = {1}; 	array[2] = (unsigned int)fun; 	return 0; }    这也是 缓冲区溢出攻击基本原理这个不行，实测是array【6】。我估计是1占个位置，、0占个位置，ebp四个位置

引用 1 楼 LIGHTSWORNLEIHAO 的回复:另外c语言堆栈结构的书大家能不能推荐几本 数据结构： 毛遂自荐下：http://blog.csdn.net/zhangxiangdavaid/article/details/25082013

引用 4 楼 zhangxiangDavaid 的回复:[quote=引用 1 楼 LIGHTSWORNLEIHAO 的回复:] 另外c语言堆栈结构的书大家能不能推荐几本 “堆栈结构”~，你是说“数据结构”吧！[/quote]我可能理解错了，堆栈和链表好像就是数据结构的内容。

引用 3 楼 paschen 的回复:地址你可能没搞对，参看这个：   void fun() { 	printf("I'm Come In!!!"); }  int main() { 	int array[1] = {1}; 	array[2] = (unsigned int)fun; 	return 0; }    这也是 缓冲区溢出攻击基本原理谢谢，我现在去试试。

引用 2 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）谢谢老师，学习了。

引用 1 楼 LIGHTSWORNLEIHAO 的回复:另外c语言堆栈结构的书大家能不能推荐几本 “堆栈结构”~，你是说“数据结构”吧！

另外c语言堆栈结构的书大家能不能推荐几本


Question: 请问，C语言一个被调用函数可不可以有两个return语句，该怎么使用第二个返回的值呢？

不可以，一个函数只能有一个返回值

可以作为参数传递，c/c++ return后面都是只返回一个对象 或者返回一个空的 例如 return； 如果想要返回多个可以考虑传参    另外像Matlab这种代码就可以返回多个值

求高手来指点


Question: 出現 undefined reference to `WinMain' 和 [Error] ld returned 1 exit status

winmain在那里, 你是GUI的还是console的程序


Question: C语言右移结果出错？

从结果来说，这个结果是完全正确的，并没有任何错误。 你的rsNum在掩码处理后的值为50331648，右移21位就好比除以2的21次方，你用计算器试下，结果就是24.

仅供参考：#include <stdio.h> unsigned short int ui;   signed short int si; int main() {     ui=(unsigned short int)0x8000u;     si=(  signed short int)0x8000;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui>>1;     si=si>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned short int)0x8000u;     si=(  signed short int)0x8000;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed short int)ui)>>1;     si=((unsigned short int)si)>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      return 0; } //ui=32768 //si=-32768 //ui=16384 //si=-16384 //-------------- //ui=32768 //si=-32768 //ui=49152 //si=16384


Question: linker command failed with exit code 1 (use -v to see invocation)问题

程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。

请贴出编译器完整的输出。


Question: winsocket编程

可参考：http://bbs.csdn.net/topics/330006557

将wsock32.dll复制到你生成程序的文件夹下。

没有lib文件的意思吗，用LoadLibrary

引用 1 楼 zhangxiangDavaid 的回复:什么意思？这个主要看你喜欢~

什么意思？这个主要看你喜欢~


Question: 新手问题，求大牛高抬贵手

如果if块中有个return，如果满足if，函数就返回了，否则会继续调用该函数，这样就一直不会结束，直到程序栈空间不够而崩溃。。

IF是条件判断语句 没有IF则陷入了另外一个条件 自然就出现另外一个模式  自然就意外了 看来你是盲人摸象啊

1、递归是需要退出条件的。  2、VS下单步跟踪，看的最详细。

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

因为你的这个函数会一直调用自己！永远不会停止！

楼主你好，这个是函数的递归调用，s1函数的调用了自身a次（算第一次本身在内），所以其意义是输出a个Smile!，函数定义中是int s1，意味着应返回一个整数值，如果没有if，则函数不会有返回值从而陷入无尽循环……有了if后到调用到s1(1)时就会执行换行并返回0，返回值的地方就是函数终止的地方，所以后面没有继续输出了

递归调用至少需要有个退出的地方, 如果没有if那句话, lz可以试试手动模拟一下程序执行, 会发现一直循环, 加了这句话, 就在a等于1的时候打破该循环, 退出函数调用链了.


Question: 问题求助

三角形: #include <stdio.h> int main (void) { 	int i,j; 	for(i = 0 ; i < 7 ; i++) 	{ 		for(j = 0 ; j <= i ; j++) 		{ 			printf("*"); 		} 		printf("\n"); 	} 	for(i = 5 ; i >= 0 ; i--) 	{ 		for(j = 0 ; j <= i ; j++) 		{ 			printf("*"); 		} 		printf("\n"); 	}  	return 1; }

下一问代码:  #include <stdio.h> #define ABS(a,b) (a>b?a-b:b-a) int main (void) { 	int i,j; 	for(i = 1 ; i < 2*7 ; i++) 	{ 		for(j = 1 ; j < 2*7 ;j >= 1 + ABS(i,7) && j <= 13 - ABS(i,7) ? printf("*") : printf(" "),j++); 		printf("\n"); 	} 	 	return 1; }

另一种方法:  #include <stdio.h> #define ABS(a,b) (a>b?a-b:b-a) int main (void) { 	int i,j; 	 	for(i = 1 ; i < 2*7 ; i++) 	{ 		for(j = 1 ; j <= 7-ABS(i,7) ; j++) 		{ 			printf("*"); 		} 		printf("\n"); 	}  	return 1; }

还有这个用循环怎么写？求助       *      ***     *****    *******   *********  *********** *************  ***********   *********    *******     *****      ***       *


Question: linux下C的网络编程题？

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

1. 如果客户端和服务器端所使用的整数的大小端是相同的，直接发送就行了.     int x;     send(cs, (char*)&x, 4, 0)     recv(cs, (char*)&x, 4, 0)  2. 如果传输过程中网络连接没有断开，TCP 就保证了你的数据是完整的。     如果连接有问题中途出错了，你需要的是断点续传了

快来人啊。。。。。。。


Question: 题目在图片上 蛮简单的一道题 可提交上去怎么总是错的！！！求大神指导！

纸上学来终觉浅，绝知此事要躬行。

已经溢出了吧

给你组测试数据：2 2 0 0

是一次多个输入  #include <stdio.h> #include <string.h> #include <stdlib.h>  typedef struct _input { 	int heads; 	int legs; 	struct _input *next; }input_t; //////////////////////////////////////  void calc_result(int heads, int legs) { 	int rabbit;  	int pigeon;  	 	pigeon = (4 * heads - legs) / 2;  	rabbit = heads - pigeon;  	  	if ((pigeon * 2 + rabbit * 4) != legs)  	{  		printf("Error\n"); 	} 	else 	{ 		printf("%d %d\n", pigeon, rabbit); 	}	 } ///////////////////////////////////////////////  int main(void)  {  	int heads = 0; 	int legs = 0; 	input_t* store, *tmp1, *tmp2; 	 	store = calloc(sizeof(input_t), 1); //link table empty header 	tmp2 = store; 	 	//get input 	while (1) 	{ 		scanf("%d %d", &heads, &legs); 		if ((0 == heads) && (legs == 0)) 		{ 			break; 		} 		tmp1 = (input_t*)malloc(sizeof(input_t)); 		tmp1->heads = heads; 		tmp1->legs = legs; 		tmp1->next = NULL; 		tmp2->next = tmp1; 		tmp2 = tmp1; 	}   	//proc input  	tmp2 = store->next;  	while (tmp2 != NULL)  	{  		calc_result(tmp2->heads, tmp2->legs);  		tmp1 = tmp2;  		tmp2 = tmp2->next;  		free(tmp1); 	} 	 	free(store);    }

这不是解方程，怎么搞这么复杂

int  改成 long long %d 改成 %lld

是，看错了，你写了判断，那应该是别的问题了

输入改成 while(scanf("%d %d",&n,&m)！=EOF)  {       ..... }

题目要求一次输入多组数据，输完数据后才输出结果，你的一次只能输入一组数据，用链表结构试试

m、n最大能到2的30次方 你的算式中出现了4乘以n，这个数超出了int的范围，溢出了 变化一下，把 (4*n-m)/2 变成 n*2-m/2 试试


Question: 钱币大写金额变成小写金额

引用 8 楼 zhao4zhong1 的回复:以前继(piao)承(qie)谁的忘了，仅供参考： #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 壹仟叁佰亿零肆仟零陆拾万零玖拾元零壹分  这个完美实现啊！！！多谢大神！

引用 5 楼 ahacsdn 的回复:这样可以吗？ 这个只能转换不超过一万的。 如果输入时几万几亿的，应该可以把这个改一下的 比如把输入看成“_____亿_____万_____元，用这个函数读横线上的，然后读到亿就乘以一亿，读到万就乘以一万什么的。  这个函数是按照中文习惯把输入看成两个一组，数字+基数，比如”两千  三百  二十  五元“，结果就是2*1000+3*100+2*10+5*1=2325. 有几个特例： 1.入股输入”十五元“之类，十前面没有基数。 2.如果每组第一个数字是”零“”元“则组忽略。比如”三百  元整“=3*100，”两千 零五 元整“= ”两千 五元 整“=2*1000+5*1  #include<stdio.h> #include<string.h>   char* cn_base[]={"千","百","十","元","角","分"};  float ma_base[]={1000,100,10,1,0.1,0.01}; char* cn_numb[]={"九","八","七","六","五","四","三","二","一"}; int   ma_numb[]={9,8,7,6,5,4,3,2,1};  float function(char* cn_money) { 	if (cn_money[0] == '\0')  	    return 0; 	         char cur[3];   	strncpy(cur,cn_money,2); 	cur[2]='\0'; 	if( !strcmp(cur,"十") ) 	    return 10+function(&cn_money[2]);       if( !strcmp(cur,"零") || !strcmp(cur,"整") || !strcmp(cur,"元") )         return function(&cn_money[2]);              int num;     for(int pos=0;;pos++){     	if( !strcmp(cur,cn_numb[pos]) ){     		num = ma_numb[pos];     		break; 		} 	    else 	    	continue; 	} 	 	float base; 	strncpy(cur,&cn_money[2],2); 	cur[2]='\0';     for(int pos=0;;pos++){     	if( !strcmp(cur,cn_base[pos]) ){     		base = ma_base[pos];     		break; 		}     	else 		    continue;     	} 	 	return num*base+function(&cn_money[4]); }  int main() { 	char* cn_money="四千零五十三元七角五分";  	float money=function(cn_money); 	printf("%.2f",money); }  可以可以，谢谢了。

继(piao)承(qie)5楼：//按照中文习惯把输入看成两个一组，数字+基数，比如”贰千  叁百  贰拾  伍元”，结果就是2*1000+3*100+2*10+5*1=2325. //有几个特例： //1.如果输入“拾伍元”之类，拾前面没有基数。 //2.如果每组第一个数字是“零”“元”则组忽略。比如“叁百  元整”=3*100，“贰仟 零伍 元整”= “贰仟 伍元 整”=2*1000+5*1 #include <stdio.h> #include <string.h> char* cn_base[]={"仟","佰","拾","元","角","分"}; double ma_base[]={1000.0,100.0,10.0,1.0,0.1,0.01}; char* cn_numb[]={"玖","捌","柒","陆","伍","肆","叁","贰","壹"}; int   ma_numb[]={9,8,7,6,5,4,3,2,1}; double qian(char* cn_money) {     if (cn_money[0]=='\0') return 0.0;     if (!strncmp(cn_money,"拾",2)) return 10.0+qian(cn_money+2);     if (!strncmp(cn_money,"零",2) || !strncmp(cn_money,"整",2) || !strncmp(cn_money,"元",2)) return qian(cn_money+2);      int num,i;     for (i=0;i<9;i++){         if (!strncmp(cn_money,cn_numb[i],2)) {             num = ma_numb[i];             break;         } else continue;     }      if (cn_money[2]=='\0') return (double)num;          double base;     for (i=0;i<6;i++){         if (!strncmp(cn_money+2,cn_base[i],2)) {             base = ma_base[i];             break;         } else continue;     }     return num*base+qian(cn_money+4); } double convert(char* cn_money) {     char *p,*q;     double d;      d=0.0;     q=cn_money;     p=strstr(q,"万");     if (p) {         if (strstr(p+2,"亿")) {             p[0]=0;             d=10000.0*qian(q);             q=p+2;         }     }     p=strstr(q,"亿");     if (p) {         p[0]=0;         d=100000000.0*(d+qian(q));         q=p+2;     }     p=strstr(q,"万");     if (p) {         p[0]=0;         d=d+10000.0*qian(q);         q=p+2;     }     d+=qian(q);     return d; } int main() {     char cn_money1[]="壹万贰仟叁佰肆拾伍亿零壹佰贰拾叁万肆仟伍佰陆拾柒元捌角玖分";     double money1=convert(cn_money1);     printf("%.2lf\n",money1);     char cn_money2[]="壹仟叁佰亿零肆仟零陆拾万零玖拾元零壹分";     double money2=convert(cn_money2);     printf("%.2lf\n",money2);     return 0; } //1234501234567.89 //130040600090.01 //

引用 5 楼 ahacsdn 的回复:这样可以吗？ 这个只能转换不超过一万的。 如果输入时几万几亿的，应该可以把这个改一下的 比如把输入看成“_____亿_____万_____元，用这个函数读横线上的，然后读到亿就乘以一亿，读到万就乘以一万什么的。  这个函数是按照中文习惯把输入看成两个一组，数字+基数，比如”两千  三百  二十  五元“，结果就是2*1000+3*100+2*10+5*1=2325. 有几个特例： 1.入股输入”十五元“之类，十前面没有基数。 2.如果每组第一个数字是”零“”元“则组忽略。比如”三百  元整“=3*100，”两千 零五 元整“= ”两千 五元 整“=2*1000+5*1  #include<stdio.h> #include<string.h>   char* cn_base[]={"千","百","十","元","角","分"};  float ma_base[]={1000,100,10,1,0.1,0.01}; char* cn_numb[]={"九","八","七","六","五","四","三","二","一"}; int   ma_numb[]={9,8,7,6,5,4,3,2,1};  float function(char* cn_money) { 	if (cn_money[0] == '\0')  	    return 0; 	         char cur[3];   	strncpy(cur,cn_money,2); 	cur[2]='\0'; 	if( !strcmp(cur,"十") ) 	    return 10+function(&cn_money[2]);       if( !strcmp(cur,"零") || !strcmp(cur,"整") || !strcmp(cur,"元") )         return function(&cn_money[2]);              int num;     for(int pos=0;;pos++){     	if( !strcmp(cur,cn_numb[pos]) ){     		num = ma_numb[pos];     		break; 		} 	    else 	    	continue; 	} 	 	float base; 	strncpy(cur,&cn_money[2],2); 	cur[2]='\0';     for(int pos=0;;pos++){     	if( !strcmp(cur,cn_base[pos]) ){     		base = ma_base[pos];     		break; 		}     	else 		    continue;     	} 	 	return num*base+function(&cn_money[4]); }  int main() { 	char* cn_money="四千零五十三元七角五分";  	float money=function(cn_money); 	printf("%.2f",money); }  好多错字大侠莫怪

1 以元角分为分隔符提取相应的数字 2 对每个提取的数字, 使用拾、佰、仟、万、亿为分隔符提取 3 壹、贰、叁、肆、伍、陆、柒、捌、玖转为对应1-9

可以说下思路么

1)个十百千万亿的处理，以及某一个十进制位的处理 2）元角分的处理 3）0 的处理 解决好这些，基本就可以了

这个细节太多，且要统一中文货币的表达形式~


Question: 函数返回一个int参数打开的位的数量

显然是在统计int二进制位上1的个数~ 下面的这个方法，效率更高：  int countOne(int a) { 	int count = 0; 	while (a) 	{ 		count++; 		a = a&(a - 1); 	} 	return count; }

while(a/2)                        //a被2整除  整数部分不为零则执行。     {         count+=a%2;          //count = count + a被2整除的余数         a=a>>1;                   //a右移一位    等价于a = a / 2     }

计算a的二进制表示中的1的个数 while的条件实际上是a大于1 循环体中将a最低位加到count中，然后a除以2 循环后再将a小于或等于1中等于1时的一位加进来


Question: 后缀表达式转中缀表达式程序遇到堆损坏及访问位置问题

你的string们分配的内存不够长


楼上快说说了，是由于浮点数表示不精确  如果楼主想精确转换，可以使用如下方法；   double round(double d,unsigned p = 0) //d为原浮点数， p为精确位数 { 	if(d==0) 		return 0; 	double n=0.01; 	for(unsigned tmp=p;tmp>0;tmp--) 		n/=10; 	if(d>0) 		d+=n; 	else 		d-=n; 	//先转成字符串 	char chs[10],data[200]; 	sprintf(chs,"%%.%uf",p); 	sprintf(data,chs,d); 	//再转成double 	return atof(data); }

引用 10 楼 fefe82的回复:[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？[/quote]  内存中存储的二进制数，不是十进制数。 一般来说，double 使用的浮点数。 浮点数一般是用 1.xxx * 2^yyyy 的形式表示的。xxxx 的二进制位数一般是固定的。 这就是说，虽然他们的十进制小数部分都是 .345 ，但是他们浮点数表示的 1.xxxx 的部分很不相同。xxxx 的最后以为对应的十进制的值也不相同（因为 yyyy 是不同的）。  =====================  那十进制打个比方吧。十进制浮点小数假设为 x.xxxx * 10 ^ yyyy 的形式。 于是 2.345 表示为 2.3450 * 10 ^ 0000 100.345 表示为  1.0034 * 10 ^ 0002 （只有四位小数可用，剩余的被丢弃。[不确定 IEEE754 里怎么处理的，这里假设为丢弃]） 于是当你均以两位小数输出的时候，前者会变成 2.35, 后者是 100.34 。[/quote] 嗯，谢谢，我已经明白了

引用 7 楼 qq_29120981 的回复:[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？[/quote]  内存中存储的二进制数，不是十进制数。 一般来说，double 使用的浮点数。 浮点数一般是用 1.xxx * 2^yyyy 的形式表示的。xxxx 的二进制位数一般是固定的。 这就是说，虽然他们的十进制小数部分都是 .345 ，但是他们浮点数表示的 1.xxxx 的部分很不相同。xxxx 的最后以为对应的十进制的值也不相同（因为 yyyy 是不同的）。  =====================  那十进制打个比方吧。十进制浮点小数假设为 x.xxxx * 10 ^ yyyy 的形式。 于是 2.345 表示为 2.3450 * 10 ^ 0000 100.345 表示为  1.0034 * 10 ^ 0002 （只有四位小数可用，剩余的被丢弃。[不确定 IEEE754 里怎么处理的，这里假设为丢弃]） 于是当你均以两位小数输出的时候，前者会变成 2.35, 后者是 100.34 。

引用 8 楼 wang0635的回复:[quote=引用 7 楼 qq_29120981 的回复:] [quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？[/quote] 比如，十进制中，如果只能保存2位小数，那么区间 [2.345, 2.355) 中的所有数都只能用 2.35 表示[/quote] 虽然还是有些不明白，但还是谢谢大家了

引用 7 楼 qq_29120981 的回复:[quote=引用 6 楼 wang0635的回复:][quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？[/quote] 比如，十进制中，如果只能保存2位小数，那么区间 [2.345, 2.355) 中的所有数都只能用 2.35 表示

引用 6 楼 wang0635的回复:[quote=引用 5 楼 qq_29120981 的回复:] [quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的[/quote] 我还是没弄明白之前的问题，2.345存储略大2.00345e2存储略小，它们不都是double？

引用 5 楼 qq_29120981 的回复:[quote=引用 4 楼 wang0635的回复:][quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？[/quote] 要看浮点数用的什么编码。二进制中只有分母是2的幂的分数才能是有限小数，而编码只能针对有限位的。几乎所有的浮点数都不准确，因为表示的范围太大，含有无穷多个数，而只有有限个数是准确的

引用 4 楼 wang0635的回复:[quote=引用 3 楼 qq_29120981 的回复:] [quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了[/quote] 2.345和2.00345e2保存的方法不同？一个是略大一个是略小？这个行为是无法预测的全看编译器实现吗？

引用 3 楼 qq_29120981 的回复:[quote=引用 1 楼 user-5的回复:]2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...[/quote] 2.345变成二进制是无限小数，而计算机只能保存有限位，所以实际上存成了跟它最接近的那个有限小数了

引用 1 楼 user-5的回复:2.00345e2作为double实际上是200.3449999999989, 所以四舍五入会失败 2.345也是double型啊...

几乎所有的浮点数都不准确


Question: NCURSES中的画图问题

提醒：NCURSES是开源的。


Question: MPI环境变量问题，新人求解

用depends.exe查看exe依赖的dll及其版本号。

引用 1 楼 zhao4zhong1 的回复:设置该exe的属性为以管理员身份运行。 能再说明白一点吗，我试了一下管理员运行，结果闪退了。生成的可执行文件不是应该用控制台实现的吗，那要怎么设置管理员运行呢

设置该exe的属性为以管理员身份运行。


Question: 关于NCURSES库中box的使用问题

提醒：NCURSES是开源的。


Question: 后缀表达式转换为中缀表达式问题

第一次用csdn，还完全不熟悉规则多包涵

楼主，为了提高别人回答你的可能性，我觉得你可以 用CSDN发帖的代码格式，代码部分的显示格式会更清晰易懂


Question: 扔一个的渣渣NES模拟器

引用 8 楼 mLee79 的回复:就 NES 那还不到 QVGA 的分辨率, 用啥都慢不了啊, 我在 Tegra2 的板子上跑测试都刷了 200+fps ..  因为以后会逐渐开这种窗口，这种扩展辅助的窗口我觉得才是真正有意思的地方。

引用 5 楼 mLee79 的回复:用啥引擎的, infoNES 么,以前我弄了个跑 ARM 上. 这东西有必要用 DDraw, D3D 么, 我用 GDI 画, 在我本子上也能跑 400+ fps. 这个渣渣例程速度还凑合，每帧时间片没跑偏的情况下1ms都没用到，我在考虑怎么用剩下的时间做更多有用的事情，(比如Filter滤波，自绘PPU状态图UI，寄存器观察图表，这几个窗口基本设想都是要占大半个屏幕的)，这种东西以后会有很多，不用direct很难想象帧数。即使是原始的dx9 surface 在LOCK_BUFFER + SSE movdqa 在全屏写入的时候要比GDI快上 5~6倍左右。要是用GDI，估计会惨不忍睹(主显示屏幕使用GDI还蛮强凑合我想。。。。至于你说的infoNES，没有用过我是看了模拟器源代码写出来的(或多或少点virtuanes/nesterj的影子0_0)

引用 4 楼 dustpg 的回复:[quote=引用 3 楼 u013550545 的回复:] [quote=引用 2 楼 dustpg 的回复:] 前排占座， 自己也写了个, 5个月没更新了, 只完成了指令模拟。 话说C语言用COM组件会不会很麻烦啊.dx头文件有个简化调用的宏可以隐藏vtbl调用。。其余的就是多传一个this指针的事情了。dx到了xact之前版本的header都会保留这组宏,全是用c源文件编译的。倒不是闲的蛋疼。pc机配置低不给力。cpp编译速度太慢了，本身vs就卡。里面的cpu是用汇编写的。ppu也不难。ppu有两种模拟方式一种是粗浅的模拟ntsc下约113 cycles画一帧线 240根时候提交渲染，之后就是vblank和nmi中段处理。另外一种是根据ppu的具体周期来写精灵读nt at等这种方法比较难理解速度也慢但是模拟精度高。apu和mapper都没怎么看。。整个过程最让我意外的就是以jit方式模拟的nes在全屏下使用gdi渲染的时候也很流畅 。[/quote]   编译速度倒是没什么，因为核心没用第三方库, 标准库也是仅仅几个必要的, 编译速度哧溜溜的和hello world一样.  因为目标是跨平台所以到是没用汇编. 唉, 说得我又想继续搞了, 挖坑太多了[/quote]neswiki上面有很多资料，国内基本折腾这些东西的人还在少数

引用 3 楼 u013550545 的回复:[quote=引用 2 楼 dustpg 的回复:] 前排占座， 自己也写了个, 5个月没更新了, 只完成了指令模拟。 话说C语言用COM组件会不会很麻烦啊.dx头文件有个简化调用的宏可以隐藏vtbl调用。。其余的就是多传一个this指针的事情了。dx到了xact之前版本的header都会保留这组宏,全是用c源文件编译的。倒不是闲的蛋疼。pc机配置低不给力。cpp编译速度太慢了，本身vs就卡。里面的cpu是用汇编写的。ppu也不难。ppu有两种模拟方式一种是粗浅的模拟ntsc下约113 cycles画一帧线 240根时候提交渲染，之后就是vblank和nmi中段处理。另外一种是根据ppu的具体周期来写精灵读nt at等这种方法比较难理解速度也慢但是模拟精度高。apu和mapper都没怎么看。。整个过程最让我意外的就是以jit方式模拟的nes在全屏下使用gdi渲染的时候也很流畅 。[/quote]   编译速度倒是没什么，因为核心没用第三方库, 标准库也是仅仅几个必要的, 编译速度哧溜溜的和hello world一样.  因为目标是跨平台所以到是没用汇编. 唉, 说得我又想继续搞了, 挖坑太多了

引用 8 楼 mLee79 的回复:就 NES 那还不到 QVGA 的分辨率, 用啥都慢不了啊, 我在 Tegra2 的板子上跑测试都刷了 200+fps ..  http://bbs.csdn.net/topics/391846638  高手帮忙看看帖子，多谢

引用 2 楼 dustpg 的回复:前排占座， 自己也写了个, 5个月没更新了, 只完成了指令模拟。 话说C语言用COM组件会不会很麻烦啊.dx头文件有个简化调用的宏可以隐藏vtbl调用。。其余的就是多传一个this指针的事情了。dx到了xact之前版本的header都会保留这组宏,全是用c源文件编译的。倒不是闲的蛋疼。pc机配置低不给力。cpp编译速度太慢了，本身vs就卡。里面的cpu是用汇编写的。ppu也不难。ppu有两种模拟方式一种是粗浅的模拟ntsc下约113 cycles画一帧线 240根时候提交渲染，之后就是vblank和nmi中段处理。另外一种是根据ppu的具体周期来写精灵读nt at等这种方法比较难理解速度也慢但是模拟精度高。apu和mapper都没怎么看。。整个过程最让我意外的就是以jit方式模拟的nes在全屏下使用gdi渲染的时候也很流畅 。


Question: 【求助】数组中n个相邻数累加算法

我也来凑热闹，除了while循环加了个printf方便看到运算过程和结果。   void formatInfo(int n, char* pInfo) { 	if(NULL == pInfo) return;  	char cFactor = (n%2 == 1 ? '+':'-');  	if(n > 1) 	{ 		sprintf(pInfo+strlen(pInfo), " %c ", cFactor); 	} 	sprintf(pInfo+strlen(pInfo), "%d", n); }  int sum(int nEnd, char* pInfo) { 	int s = 0; 	int n = 1; 	while( n <= nEnd ) 	{ 		int factor = ( 1 == n%2 ? 1 : (-1) ); 		s += n*factor;  		formatInfo(n, pInfo);  		n++; 	}  	sprintf(pInfo+strlen(pInfo), " = %d", s); 	return s; }  int _tmain(int argc, _TCHAR* argv[]) { 	char info[1000]; 	memset(info, 0, sizeof(info)); 	int s = sum(5, info); 	printf("%s\r\n", info); }   输出结果： 1 - 2 + 3 - 4 + 5 = 3

同意楼上的~

#include <stdio.h> int main() {     const int n=6;     int d[n]={1,2,3,4,5,6};     int L,F,sum,i;      for (L=2;L<=n;L++) {         printf("----%d----\n",L);         for (F=0;F<=n-L;F++) {             sum=d[F];printf("%d",d[F]);             for (i=F+1;i<F+L;i++) {                 sum+=d[i];                 printf("+%d",d[i]);             }             printf("=%d\n",sum);         }     }      return 0; } //----2---- //1+2=3 //2+3=5 //3+4=7 //4+5=9 //5+6=11 //----3---- //1+2+3=6 //2+3+4=9 //3+4+5=12 //4+5+6=15 //----4---- //1+2+3+4=10 //2+3+4+5=14 //3+4+5+6=18 //----5---- //1+2+3+4+5=15 //2+3+4+5+6=20 //----6---- //1+2+3+4+5+6=21 //

int* addfun(int *arr, int step, int *ret); int main() {                int i=0;     int arr[6] = {0, 1, 2, 3, 4, 5};      int ret[6] = {0, 0, 0, 0, 0, 0};      addfun(arr, 2, ret);     printf("result: \n");     while(ret[i] > 0)         printf("%d ", ret[i++]); }                         int* addfun(int *arr, int step, int *ret) {                int j = 0, num = 0;     for(int i=0; i<6; i++)     {                j = i + step;         if(j < 6)         {                printf("%d - %d: ", i, j);                                                                  for(int k=i; k<=j; k++)                 ret[num] += arr[k];             printf("%d\n", ret[num++]);         }        }            return ret; }

引用 1 楼 user-5 的回复:外层循环 i 从1到6 内存循环从1到n，要两个数n就是2，三个数就是3 内层循环累加每次累加 我要的是每个相邻累加的结果，比如上面的3，5，7。。。，而不是3+5+7... 你这个循环的思路也不太明白，请问这个外层循环的意义是什么？


Question: 格式控制符f和lf的差异

因为 %f,%lf 本质上输出时候，都是输出的 double  制定标准的某些人，就认为，  %f,%lf 只需要一个，另一个是多余的 但是，他们觉得，%lf 更加多余，于是就废了%lf ， 似乎后来又给补上了，不过是作为可选处理  也就是说，float,double 浮点数输出,标准里面是 %f ,但是 double 也可以用 %lf了（某个版本又补了回来）

我一直“好读书，不求甚解”~

printf Type Field Characters f double Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.   scanf Type Field Characters e, E, f, g, G Floating-point value consisting of optional sign (+ or –), series of one or more decimal digits containing decimal point, and optional exponent (“e” or “E”) followed by an optionally signed integer value. Pointer to float.

是的，表示的确实不一致

printf 和 scanf 中的格式控制符的含义并不完全相同。  printf 请看： http://en.cppreference.com/w/c/io/fprintf scanf 请看：http://en.cppreference.com/w/c/io/fscanf

感谢大家的回答，看了一些资料后发现书上也有说printf和scanf函数的这点差异，谢谢大家的解答

因为输出是转成字符串,占个空间由使用者控制, 而且没标注的浮点常量默认是double类型, 所以没必要分float和double. 而输入是由字符串转成float或double类型, float才4字节, 比较节约内存, 运算起来也比较快, 有这个需求, 所以分开.


Question: http协议，是不是可以不出现网页？

随便找一本cpp的教材 都有个案例是写个聊天程序的服务端与客户端 而服务端就是监听某个端口 收到请求后返回 你说的是这个？

你说http接口？ http://ip.taobao.com/service/getIpInfo.php?ip=123.32.11.22 这样？就是返回一个JSON字符串  另外感觉楼主概念的确有点混乱

引用 9 楼 pb8 的回复:[quote=引用 8 楼 u012879787 的回复:] 还有 如果是主流开源http服务器，我想用它实现上面提到的功能，可行否？或者说它有没有类似的虚函数接口来解析客户端命令？  最后:主流服务器如何区分头和body? 如果是根据换行，那么是否靠不断recv,直到接受到换行才知道body开始了?这效率很低。 没这么复杂的，你不是基于TCP层去理解内容，对于WEB服务端，请求的数据会自动分隔到内置对象，如Request对象，请求的信息都可以从这里得到[/quote]  这样的。 web服务器段？  你看这个字眼是什么？ web服务器，  你再看我前面问什么？ 我说，这个http协议都没有web这个概念，  那么在这种情况下，你的web服务器还能够去 从你的request对象里提取出   我的命令吗？   因为我没用过 http服务器。  所以问题有点多

引用 8 楼 u012879787 的回复:还有 如果是主流开源http服务器，我想用它实现上面提到的功能，可行否？或者说它有没有类似的虚函数接口来解析客户端命令？  最后:主流服务器如何区分头和body? 如果是根据换行，那么是否靠不断recv,直到接受到换行才知道body开始了?这效率很低。 没这么复杂的，你不是基于TCP层去理解内容，对于WEB服务端，请求的数据会自动分隔到内置对象，如Request对象，请求的信息都可以从这里得到

引用 2 楼 pb8 的回复:soap与RESTFull方式写的Web服务通常都是基于HTTP协议这上的，HTTP协议与浏览器没有必然的联系，HTTP是TCP/IP协议簇里面的应用层协议，而浏览器是一种应用软件，浏览器只是用HTTP来与服务端来交互数据，像目前的微信支付、支付宝支付、微信工作号，还有很多WEBSERVICE/WEBAPI的接口，都是基于HTTP协议的，这个和浏览器都没半点必然的联系   我说的是：我见过一种实现方式,  没有任何web页，  http请求头里，一般常见的是：  get/post  请求url  http1.0/1.1  我见过的那个，由于没有web页，所以就没有 只好这么做：  get "命令" http1.1  命令： 验证用户名、修改用户名，等一系列自定义的命令。  另外：  报文头里有 “ Connection: Keep-Alive  ”    keep-alive是减少socket的连接次数，   由于http客户端、服务端都是自己实现， 我想问：    １.　这种算不算http协议？  ２.　这里的keep-alive 有效不？   个人感觉，这种http协议，完全就是一个私有的协议， 和普通的私有协议没有区别，只是挂着http的羊头

引用 6 楼 pb8的回复:另外，下面你的理解也是错误的 http请求头里，一般常见的是：  get/post  请求url  http1.0/1.1  我见过的那个，由于没有web页，所以就没有 只好这么做：  get "命令" http1.1   HTTP协议里面不是说是WEB页，而是URI，术语是请求的资源， 请求的资源可以是一个服务，一个网页，也可以是一个图片，或一个文本文件 如果你请求的是首页，就是/，如果是一个服务，服务本身就会有一个URI，就是它的地址 我已经说了 get后是跟一个命令字符串 服务器根据这个串来判断是什么命令，然后调用虚函数解析消息体，

你的概念混乱。一会客户端显示，一会服务端处理的，你连什么是http协议都不知道，更不用说自己在问什么了。 我用C语言自己写了一个http服务器，不知道算不算。

另外，只要符合HTTP协议规范的就可以称为HTTP通讯，对请求头、请求体、响应头、响应体按HTTP协议规定的格式进行通讯的，都是HTTP通讯

http与web页没有必然的联系，http是传输层的协议，就好比是货车，web页是内容 报文里面的Connection: Keep-Alive，是指的客户端要求服务端保留请求的连接，这个是在http1.1协议以后才支持，至于服务器是否断开，是由服务端去控制的，前端只是表示它的能力（我可以进行长连接通讯）与意愿（我想让你保持这个连接），keep-alive方式常用于实时推送的实现


Question: VS2008如何读取Excel表格某一特定工作表（sheet）的内容？

//得到当前活跃sheet       //如果有单元格正处于编辑状态中，此操作不能返回，会一直等待       //Excel.Worksheet sheet=(Worksheet)(book.Worksheets.get_Item(0)); 	//lpDisp=book.get_ActiveSheet();  	//lpDisp=books.get_Item(COleVariant((long)1)); 	//打开需要读取的工作表，数字2表示sheet2 	lpDisp=sheets.get_Item(COleVariant((long)2));     sheet.AttachDispatch(lpDisp);       //读取第一个单元格的值       range.AttachDispatch(sheet.get_Cells());       range.AttachDispatch(range.get_Item (COleVariant((long)8),COleVariant((long)2)).pdispVal );    已经解决了，把关联sheet那一块的操作，换成上面的那句就能够实现了，注释上已经描述了，谢谢大家！

在Excel 2003中开始记录宏，手动完成所需功能，结束记录宏，按Alt+F11键，查看刚才记录的宏对应的VBA代码。


Question: 移位过程中 出现了 类似于 1+2=4 的问题

运算符优先级,移位小于加减