Question: 大神们，动态链表里指针的指向有什么理解方法啊，表示一个问题想不通

所谓数据，就是一个一个的箱子 char     是一个小箱子 short    是一个中箱子 long     是一个大箱子  char  *  是一个大箱子 short *  是一个大箱子 long  *  是一个大箱子  struct    同样是一个箱子，但是是一个定做的箱子 struct * 是一个大箱子  总的来说，带指针的就是同一规格的大箱子 而不带指针的就是大小不一样的各种箱子  那么区别呢 带指针的箱子规定永远放的只是写有另一个箱子的编号的字条 而不带指针的箱子规定放的就是实际的东西  现在来解析这个结构 typedef  struct    定制的超级箱 {        char   Fruits[20];    //20个小箱子，存放水果        long   toys;              //1个大箱子，存放玩具        struct student *pNext;  //1个大箱子，存放另一个档案箱的编号字条 }SUPPERBOX;  那么 SUPPERBOX   *Head；就是先写好了一个编号字条 new SUPPERBOX；就是制造一个超级箱子； Head = new SUPPERBOX；就是让这个编号字条和新造的箱子捆绑 剩下的事情就是找东西和放东西，加新箱子和剔除旧箱子  放东西： Head->Fruits[0]=苹果， 就是找到Head箱子，把苹果放这个箱子的装水果的第一个小箱子里 Head->next->Fruits[0]=苹果, 就是找到Head箱子的装编号的箱子，根据编号找到下一个箱子，把苹果放这个箱子的装水果的第一个小箱子里  找东西： SUPPERBOX  *p=Head;   //抄编号 while(p)  //如果编号存在，就进行如下操作 {            if（p->toys==小火车）   //开玩具箱看，如果是小火车，那么找到            {                     //找到了就做爱做的事情                     break；//然后走人            }            p=p->next;//没走人说明没找到，那就打开装编码的箱子，抄下一个箱子的编码，继续找  ｝ 加新箱子： SUPPERBOX  *p = new SUPPERBOX;  //造一个新箱子 p->next=NULL; //这里放东西,把编号箱先清空 SUPPERBOX  *Tail=Head;   //抄编号 while(Tail->next)  Tail=Tail->next; 找到最后一个箱子Tail; Tail->next=p; //把新箱子得编号字条放入最后一个箱子的编号箱  剔除旧箱子： 找到要剔除的箱子和上一个箱子 把本箱子的编号箱的字条抄一个替换上一个箱子得编号箱字条 然后把本箱子砸了

所谓数据，就是一个一个的箱子 char     是一个小箱子 short    是一个中箱子 long     是一个大箱子  char  *  是一个大箱子 short *  是一个大箱子 long  *  是一个大箱子  struct    同样是一个箱子，但是是一个定做的箱子 struct * 是一个大箱子  总的来说，带指针的就是同一规格的大箱子 而不带指针的就是大小不一样的各种箱子  那么区别呢 带指针的箱子规定永远放的只是写有另一个箱子的编号的字条 而不带指针的箱子规定放的就是实际的东西  现在来解析这个结构 typedef  struct    定制的超级箱 {        char   Fruits[20];    //20个小箱子，存放水果        long   toys;              //1个大箱子，存放玩具        struct student *pNext;  //1个大箱子，存放另一个档案箱的编号字条 }SUPPERBOX;  那么 SUPPERBOX   *Head；就是先写好了一个编号字条 new SUPPERBOX；就是制造一个超级箱子； Head = new SUPPERBOX；就是让这个编号字条和新造的箱子捆绑 剩下的事情就是找东西和放东西，加新箱子和剔除旧箱子  放东西： Head->Fruits[0]=苹果， 就是找到Head箱子，把苹果放这个箱子的装水果的第一个小箱子里 Head->next->Fruits[0]=苹果, 就是找到Head箱子的装编号的箱子，根据编号找到下一个箱子，把苹果放这个箱子的装水果的第一个小箱子里  [color=#FF0000找东西：[/color] SUPPERBOX  *p=Head;   //抄编号 while(p)  //如果编号存在，就进行如下操作 {            if（p->toys==小火车）   //开玩具箱看，如果是小火车，那么找到            {                     //找到了就做爱做的事情                     break；//然后走人            }            p=p->next;//没走人说明没找到，那就打开装编码的箱子，抄下一个箱子的编码，继续找  ｝ [color=#FF0000加新箱子：[/color] SUPPERBOX  *p = new SUPPERBOX;  //造一个新箱子 p->next=NULL; //这里放东西,把编号箱先清空 SUPPERBOX  *Tail=Head;   //抄编号 while(Tail->next)  Tail=Tail->next; 找到最后一个箱子Tail; Tail->next=p; //把新箱子得编号字条放入最后一个箱子的编号箱  [color=#FF0000剔除旧箱子：[/color] 找到要剔除的箱子和上一个箱子 把本箱子的编号箱的字条抄一个替换上一个箱子得编号箱字条 然后把本箱子砸了

建议先看懂理论再去看程序  http://blog.csdn.net/xubin341719/article/details/7091583/

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

1.比如a->pNext = b; 如果->在左边，表示a结点的pNext指针指向b结点(实现了a,b结点的相连) 2.a=b; 类似这样的式子，表示的是将a指针指向b结点 PS：建议楼主找个有图的（动态图）理解，会比较容易 http://blog.csdn.net/ggxxkkll/article/details/8661032

如果一个变量本身就是结构体变量，那么对它成员的引用是小数点号。如果这个变量是指针，而它指向的是一个结构体变量，那么对其成员的引用就用箭头->。 等号只是赋值，和结构体成员的引用没关系。 如果结构体成员中的某个指针变量指向了另一个同类结构体变量，那用这个指针就可以找到该变量。 这是指针的使用，建议再看看书。

还有一点，，结构体类型的指针变量是什么用的


Question: 求助大神 关于长整数的加法问题 编译通过 运行终止 应该是内存或数据溢出问题 但不知道哪里出错

哦 可以的。。。。。。

仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

现在能运行了，但结果不对。。。。  而且算9999+9999的时候程序还是会终止

你这个初始化函数InitList就不对，直接传一级指针是没法改变main函数里的L1的指向（换句话说就是：你根本没有给L1,L2初始化,） 必须传二级指针或者一级指针的引用才行。 下面这样才行  void InitList(BigInteger *L) { 	*L = (BigInteger)malloc(sizeof(Node)); 	(*L)->next = NULL; } ...... int main() { 	BigInteger L1, L2; 	InitList(&L1); 	InitList(&L2); ...... }

InitList错了


Question: 一道用c语言写的CCF编程题，得分只有50，希望给指点下

#include<stdio.h> #include<stdlib.h> int main() {     char c[13];     scanf("%s",c);     int r=0,i,j=1;     for(i=0;i<11;i++){         if(c[i]=='-'){             continue;         }         r+=(c[i]-'0')*j;         j++;     }     r=r%11;     if(r==10){         if(c[12]=='X')             printf("Right");         else{             c[12]='X';             printf("%s",c);         }     }     else{         if(r==(c[12]-'0'))             printf("Right");         else{             c[12]=r+'0';             printf("%s",c);         }     }     return 0; } 我把楼主的代码改了下，运行结果为100分

引用 2 楼 qq_20305395 的回复:题目中明确指出了“ISBN码包括9位数字、1位识别码和3位分隔符”以及“保证输入符合ISBN号码的格式要求”，你没有加判断语句啊，如果我输入的不是ISBN号码，例如：4-s34-46675-6，该作何处理？ 你不懂这种平台的套路…… “保证输入符合ISBN号码的格式要求”，不是让做题者保证，而是说出题者保证不拿乱七八糟的码来干扰你。

没看出来问题


Question: 初学者求助

类型不一样。。

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

你的a是一个浮点数，这里将用整数类型去解释，故会不正确

格式化规定符  ━━━━━━━━━━━━━━━━━━━━━━━━━━     符号                  作用  ──────────────────────────      %d              十进制有符号整数      %u              十进制无符号整数      %f               浮点数      %s              字符串      %c              单个字符      %p              指针的值      %e              指数形式的浮点数    %x, %X      无符号以十六进制表示的整数      %0              无符号以八进制表示的整数      %g              自动选择合适的表示法  ━━━━━━━━━━━━━━━━━━━━━━━━━━

C语言里的%x只能输出整数的十六进制，把float改成int就可以了


Question: 有10个整数，使前面各数顺序向后移三个位置，最后3个数变成最前面3个数，实现此功能；能帮看看源程序改下么，我编译错了！谢谢了！

几个问题： 1.void input(int *)应该是void input(int *a) 2.void swap(int *a[10])应该是void swap(int a[10]) 3.m + 2 = p + 9;也不对，你左边的m+2是个临时值，不能作为左值 PS：你根据编译器的错误提示一个个错误修改下去，遇到不会的拿去搜一下一般都能找到答案

memmove Moves one buffer to another.  void *memmove( void *dest, const void *src, size_t count );  Routine Required Header Compatibility  memmove <string.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  memmove returns the value of dest.  Parameters  dest  Destination object  src  Source object  count  Number of bytes of characters to copy  Remarks  The memmove function copies count bytes of characters from src to dest. If some regions of the source area and the destination overlap, memmove ensures that the original source bytes in the overlapping region are copied before being overwritten.  Example  /* MEMCPY.C: Illustrate overlapping copy: memmove  * handles it correctly; memcpy does not.  */  #include <memory.h> #include <string.h> #include <stdio.h>  char string1[60] = "The quick brown dog jumps over the lazy fox"; char string2[60] = "The quick brown fox jumps over the lazy dog"; /*                           1         2         3         4         5  *                  12345678901234567890123456789012345678901234567890  */  void main( void ) {    printf( "Function:\tmemcpy without overlap\n" );    printf( "Source:\t\t%s\n", string1 + 40 );    printf( "Destination:\t%s\n", string1 + 16 );    memcpy( string1 + 16, string1 + 40, 3 );    printf( "Result:\t\t%s\n", string1 );    printf( "Length:\t\t%d characters\n\n", strlen( string1 ) );     /* Restore string1 to original contents */    memcpy( string1 + 16, string2 + 40, 3 );     printf( "Function:\tmemmove with overlap\n" );    printf( "Source:\t\t%s\n", string2 + 4 );    printf( "Destination:\t%s\n", string2 + 10 );    memmove( string2 + 10, string2 + 4, 40 );    printf( "Result:\t\t%s\n", string2 );    printf( "Length:\t\t%d characters\n\n", strlen( string2 ) );     printf( "Function:\tmemcpy with overlap\n" );    printf( "Source:\t\t%s\n", string1 + 4 );    printf( "Destination:\t%s\n", string1 + 10 );    memcpy( string1 + 10, string1 + 4, 40 );    printf( "Result:\t\t%s\n", string1 );    printf( "Length:\t\t%d characters\n\n", strlen( string1 ) ); }   Output  Function:   memcpy without overlap Source:      fox Destination:   dog jumps over the lazy fox Result:      The quick brown fox jumps over the lazy fox Length:      43 characters  Function:   memmove with overlap Source:      quick brown fox jumps over the lazy dog Destination:   brown fox jumps over the lazy dog Result:      The quick quick brown fox jumps over the lazy dog Length:      49 characters  Function:   memcpy with overlap Source:      quick brown dog jumps over the lazy fox Destination:   brown dog jumps over the lazy fox Result:      The quick quick brown dog jumps over the lazy fox Length:      49 characters   Buffer Manipulation Routines  See Also   _memccpy, memcpy, strcpy, strncpy

lz需要memmove...


Question: 初学者求助

真的是看错了。。。

是8.000000，莫非你看错了？

vs2015测试正常, C/C++都测试了


Question: 请教，关于“数组的地址”和“数组第一个元素的地址”。

int a[3]={ 3. 4. 5 }; int *p; p= a; 正确，p= &a;错误 因为 &a 是一个指向数组的指针，而p是一个指向整型变量的指针，它们的类型不匹配。 大多数早起版本的C语言实现中，并没有所谓“数组的地址”这一概念，因此&a或者被视为非法，或者就等于a ——节选自《C陷阱与缺陷》第3章

地址值虽然相同，但代表的维度以及意义是不同的

&string[0]; //取数组第一个元素的地址。 string; //数据名不是数组的地址，是数组第一个元素的常量地址，与&string[0]等价。 &string; //这个才是数组的地址。  以上三种表达式从地址值上说，是一样的，即地址值是相等的。当把它们直接赋给char* p的时候，p的值都是一样的，因p是char*类型指针也就是元素地址，所以对p的++ --都仅仅是一个字符的地址跨度。  地址是没有类型的，但指针是有类型的。  元素指针跟数组指针是有区别的，即&string[0]和string是第一个元素常量指针，是char*类型，而&string是char (*p)[10]类型的常量数组指针（注意C语言指针一章里肯定会讲这个数组指针的），所以&string[0]+1与&string+1的结果地址值是不同的，可以自己试试。  一般来说，不同类型指针间赋值是需要强制转换的，又因为数组指针一般情况下在需要的时候都会自动退化为数组元素指针，所以char* p = &string也是可以的而不需要写成char* p = (char*)&string，但实际上相当于char (*temp) [10] = &string; char*p = temp;

char string[] = "my string"; auto ptr = &string; 这才是数组的地址...  &string[0] = &(*(string + 0)) = string + 0 = string.....


Question: 找不出哪个测试用例会出错

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

#define MAX 101  输入： 多组数据。每组数据输入包括3行， 第1行是包含多个单词的字符串 s， 第2行是待替换的单词a，(长度<=100)         需要空间 101 第3行是a将被替换的单词b。(长度<=100)    100  替换后空间 <= 101 +100  s, a, b 最前面和最后面都没有空格. 输出： 每个测试数据输出只有 1 行， 将s中所有单词a替换成b之后的字符串。  没有交代，如果找不到这个单词怎么处理。 姑且什么也不做，原字符串输出。  那么，这个 字符串缓冲区应该为 为101+100 因为a 受到 全长的限制，不可能超过101 但是b 不受那个字符串的限制 假设 b 100 个字符 a 1个字符 替换后至少200个字符才行 个人觉得，201 最方便

报了什么错，这样好分析！

引用 3 楼 user-4 的回复:有一个经典的程序，就是c程序设计语言中的单词计数程序，可以利用它修改一下来实现。 楼主给出了s,a,b，可以再给一个目标串t(注意t应该比较大，理论上s可以有50个单词，，但是b最大长度可以为100，替换的话需要长度大约为100*50+50)  不太优化的算法如下：对查找的每一个单词(比如放入w中)，比较w和a，如果不等，则在t中输出a，等则输出b，同时再输出单词分隔（如果是最一个则输出结尾那个符号）  这个算法不优化的地方是w和a比较，实际上可以在查找单词的过程中同时进行  楼主的移动建议就不要搞了 附单词计数程序（大神作品，请认真研读）    #include <stdio.h>    #define IN   1  /* inside a word */    #define OUT  0  /* outside a word */  /* count lines, words, and characters in input */    main()    {        int c, nl, nw, nc, state;        state = OUT;        nl = nw = nc = 0;        while ((c = getchar()) != EOF) {            ++nc;            if (c == '\n')                ++nl;            if (c == ' ' || c == '\n' || c = '\t')                state = OUT;            else if (state == OUT) {                state = IN;                ++nw;            }        }        printf("%d %d %d\n", nl, nw, nc);    }  晕，PDF中还有些广告信息，请以这个为准

有一个经典的程序，就是c程序设计语言中的单词计数程序，可以利用它修改一下来实现。 楼主给出了s,a,b，可以再给一个目标串t(注意t应该比较大，理论上s可以有50个单词，，但是b最大长度可以为100，替换的话需要长度大约为100*50+50)  不太优化的算法如下：对查找的每一个单词(比如放入w中)，比较w和a，如果不等，则在t中输出a，等则输出b，同时再输出单词分隔（如果是最一个则输出结尾那个符号）  这个算法不优化的地方是w和a比较，实际上可以在查找单词的过程中同时进行  楼主的移动建议就不要搞了 附单词计数程序（大神作品，请认真研读）    #include <stdio.h>    #define IN   1  /* inside a word */    #define OUT  0  /* outside a word */ Click to buy NOW! PDF-XCHANGE www.docu-track.com Click to buy NOW! PDF-XCHANGE www.docu-track.com   /* count lines, words, and characters in input */    main()    {        int c, nl, nw, nc, state;        state = OUT;        nl = nw = nc = 0;        while ((c = getchar()) != EOF) {            ++nc;            if (c == '\n')                ++nl;            if (c == ' ' || c == '\n' || c = '\t')                state = OUT;            else if (state == OUT) {                state = IN;                ++nw;            }        }        printf("%d %d %d\n", nl, nw, nc);    }


Question: 大家觉得有C语言基础，应该多长时间学完汇编语言？请有过经历的说，或者说你学习汇编语言用了多长时间吧？

引用 12 楼 u010165006 的回复:[quote=引用 11 楼 yyxgs 的回复:] [quote=引用 8 楼 u010165006 的回复:] 学习既要点（专注），又要面，心既要大，又要小，要处理好这个问题。 不要被赵老师骗了，一时热情想学这个。   赵老师说学汇编对学习数据结构有帮助。。。[/quote]  这个三段论亚，太隔山打牛了[/quote]  好吧。。

一般半个月左右

引用 25 楼 yyxgs 的回复:[quote=引用 23 楼 u014444402 的回复:] [quote=引用 22 楼 yyxgs 的回复:] [quote=引用 21 楼 u014444402 的回复:]  [quote=引用 15 楼 yyxgs 的回复:] [quote=引用 6 楼 u010165006 的回复:] 除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?[/quote] 是的, 破解看反汇编代码更蛋疼.[/quote]   为什么呢?不是像看普通程序代码一样吗?[/quote] 你学习了汇编之后就知道了.破解一般是要看反汇编代码.[/quote]   请问看汇编的代码，和看一般的汇编程序代码有区别吗?[/quote]  区别就是，欲破解软件反汇编的代码庞大冗长的离谱，逻辑错综复杂像谜团的离谱。

引用 23 楼 u014444402 的回复:[quote=引用 22 楼 yyxgs 的回复:] [quote=引用 21 楼 u014444402 的回复:]  [quote=引用 15 楼 yyxgs 的回复:] [quote=引用 6 楼 u010165006 的回复:] 除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?[/quote] 是的, 破解看反汇编代码更蛋疼.[/quote]   为什么呢?不是像看普通程序代码一样吗?[/quote] 你学习了汇编之后就知道了.破解一般是要看反汇编代码.[/quote]   请问看汇编的代码，和看一般的汇编程序代码有区别吗?

C语言要逻辑思维，我学不好C

引用 22 楼 yyxgs 的回复:[quote=引用 21 楼 u014444402 的回复:]  [quote=引用 15 楼 yyxgs 的回复:] [quote=引用 6 楼 u010165006 的回复:] 除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?[/quote] 是的, 破解看反汇编代码更蛋疼.[/quote]   为什么呢?不是像看普通程序代码一样吗?[/quote] 你学习了汇编之后就知道了.破解一般是要看反汇编代码.

引用 21 楼 u014444402 的回复:[quote=引用 15 楼 yyxgs 的回复:] [quote=引用 6 楼 u010165006 的回复:] 除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?[/quote] 是的, 破解看反汇编代码更蛋疼.[/quote]   为什么呢?不是像看普通程序代码一样吗?

引用 15 楼 yyxgs 的回复:[quote=引用 6 楼 u010165006 的回复:] 除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?[/quote] 是的, 破解看反汇编代码更蛋疼.

学无止境，多长时间学完要看你期望达到什么程度。

什么在电脑中不是二进制？

引用 17 楼 zhao4zhong1 的回复:电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  音频在电脑中也是二进制吗？

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 6 楼 u010165006 的回复:除非搞单片机、搞硬件、搞驱动，深入学习汇编意义不大，DOS年代还可以搞个TSR，C语言也可以嵌入汇编，现在搞软件几乎用不上汇编，都是越来越高级（比如Java，C#。C++还可以嵌入点汇编），越来越前端（网站）。   听朋友说如果想弄破解、解密这些的话就必须会汇编?

引用 7 楼 pengyw 的回复:学习当然可以学习，但是你要确定学习他做什么，还有，你准备学那些指令集，比如ARM汇编还是学intel的汇编，ARM的又有一些版本。   现在想学Intel的汇编，但是并不知道学了汇编可以干什么?

引用 11 楼 yyxgs 的回复:[quote=引用 8 楼 u010165006 的回复:] 学习既要点（专注），又要面，心既要大，又要小，要处理好这个问题。 不要被赵老师骗了，一时热情想学这个。   赵老师说学汇编对学习数据结构有帮助。。。[/quote]  这个三段论亚，太隔山打牛了

引用 8 楼 u010165006 的回复:学习既要点（专注），又要面，心既要大，又要小，要处理好这个问题。 不要被赵老师骗了，一时热情想学这个。   赵老师说学汇编对学习数据结构有帮助。。。

引用 8 楼 ooolinux的回复:学习既要点（专注），又要面，心既要大，又要小，要处理好这个问题。 不要被赵老师骗了，一时热情想学这个。 什么都了解一点不要求会做，还是精通一样（比如Java），看你的学习目的了，不排除为了多了解而学习的。

就像曾经很留恋的风景，时光过后都是浮云。 ——不要在汇编驻足太久


Question: 求助一个C语言程序 非递归算法实现九连环（锁链）问题

引用 1 楼 zhao4zhong1 的回复:http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and It do is the final solution！


Question: 关于C语言函数

6楼正解  即使这样，仍建议使用函数时进行声明，或者把函数声明放在头文件中，函数实现放在源文件中，然后使用时包含头文件即可

我测试了第二个，有一个警告 “*****”未定义；假设外部返回 int

引用 4 楼 Hamber_Bao 的回复:引用 3 楼 qq423399099 的回复:c语言的规定，因为系统默认的返回值类型是int型,这是规定好了的为什么有整型返回值的 可以不用定义在main函数之前，而无返回值的要么在调用前声明要么定义在调用前。  C语言 调用没有声明过的函数，会默认声明一个返回类型为 int 的函数。 然后看到了函数的定义，如果这个定义的函数类型与前面默认声明的不一致，就会出错。在C语言中，同名的函数只能有一个。对这个函数的多次声明/定义中，其类型必须一致。 后面那个将函数定义为返回int ，定义与默认声明是一致的。  =========== 建议，即使在 C 语言中，每一个需要被调用的函数都要提前声明一下。

因为历史原因，c语言在调用函数时，如果没有提前声明原型会默认认为是返回int型的函数。上述第一种因为定义是void型，调用前没声明，默认认为是int，链接时找不到返回是void的函数定义，自然错误了

c语言的规定，因为系统默认的返回值类型是int型,这是规定好了的

C语言默认返回int，为了兼容和char* a ="AAA"一样都 可以说是bug了...不过为了兼容没办法...

帮忙解答下


Question: typedef定义结构问题

刚发完贴就看出来了，应该是： printf("%d-%d-%d\n",test.year,test.month,test.day); 自己太粗心了。


Question: 文件读入读出

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: 最近可能要温习下c语言，先来混个脸熟

帮顶

java 跟C相通，只要看看那点不一样就行了

引用 1 楼 wen_eric 的回复:果断领分 引用 2 楼 qq423399099 的回复:  谢谢回复！

果断领分

引用 12 楼 qq_25868549 的回复:我也来混个脸熟，大家一起学习。  好的，一起加油！

引用 11 楼 dereck1314 的回复:看着分数我就进来了 引用 13 楼 qq_32296307 的回复:领分---------------------  没问题！

领分---------------------

我也来混个脸熟，大家一起学习。

看着分数我就进来了

引用 7 楼 zycxnanwang 的回复:突然觉得C,C++语言很重要，我还是先把C++弄扎实了，再学java！  嗯，一起加油！

引用 5 楼 user-9 的回复:http://bbs.csdn.net/topics/390966354/ 引用 6 楼 zhao4zhong1 的回复:C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817  二位的回复还是比较实在的东西，

引用 4 楼 lm_whales 的回复:java 跟C相通，只要看看那点不一样就行了  多谢指点！

突然觉得C,C++语言很重要，我还是先把C++弄扎实了，再学java！


Question: 关于数组的引用的问题

sResult指向它前面应该没有*吧？ sResult = charResult;

……时怎么做的。

引用 2 楼 langxiao12345 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？   那请问怎么把函数执行的结果取到呢？[/quote] 参考Windows API在需要读入数组信息或输出或返回数组信息是怎么做的。

引用 1 楼 zhao4zhong1 的回复:请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？   那请问怎么把函数执行的结果取到呢？


Question: C-struct-位段、无名字段以及填充字段

位段的位顺序，由实现决定 也就说说 位段中，字节顺序，位顺序。都是不确定的，由具体实现觉得。

仅供参考：#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07   再供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("AD sizeof %d\n", sizeof(AD));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("A1 sizeof %d\n", sizeof(A1));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("A2 sizeof %d\n", sizeof(A2));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("A4 sizeof %d\n", sizeof(A4));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("A8 sizeof %d\n", sizeof(A8));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("A16 sizeof %d\n", sizeof(A16));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！


Question: 求大神帮看看哪里出了问题

自己打断点，要学会调试程序

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

int max(int a, int b, int c) { if (a < b) { a = b; if (a < c) { a = c; return a;  } else { //return c;  ///////////////////这里应该是return a; return a; } } // a>b的情况你没考虑呀 else {     if (a > c) 	{ 		return a; 	} 	else 	{ 		return c; 	} }  }   int main() { int a,b,c,i; printf("请输入三个数字（中间用空格间隔）\n"); scanf("%d%d%d", &a, &b, &c); i = max(a, b, c); printf("最大的数字是%d",i );  ////////////////////////// 去掉&  }

printf("最大的数字是%d",/*去掉这个&*/i ); printf("最大的数字是%d",i );

你max函数中，如果a>b那么返回值不确定   int max(int a, int b, int c) { 	if(a < b) 		a = b; 	if(a < c) 		a = c; 	return a; }


Question: 帮忙改下这个列移动

在有重叠的情况下，一个要从后往前逐个移动，一个要从前往后逐个移动。

引用 6 楼 zhao4zhong1 的回复:在有重叠的情况下，一个要从后往前逐个移动，一个要从前往后逐个移动。赵老师，麻烦您能给出具体代码吗？谢谢了，后天答辩。

引用 2 楼 zhao4zhong1 的回复:if(col==poz)         return; else if (col>poz) { ... } else {//col<poz ... }老师这样为啥不行void MoveCol(Row* text,int col,int poz) { 	if(col==poz) 		return; 	Row* rp=text->next; 	while(rp) 	{ 		if(col>poz) 		{ 			Node* np=locate(rp->line,(col-1)); 			Node* nt=locate(rp->line,(poz-1)); 			Node* nq; 			if(np&&np->next&&nt) 			{ 				nq=np->next; 				np->next=nq->next;  				nq->next=nt->next; 				nt->next=nq;			 			} 		} 		if(col<poz) 		{ 			Node* np=locate(rp->line,(col-1)); 			Node* nt=locate(rp->line,(poz-1)); 			Node* nq; 			if(np&&np->next&&nt) 			{ 				np->next->next=nq->next; 				nq->next=np->next; 				np->next->next=nq; 			} 		}  		rp=rp->next; 	} }

引用 2 楼 zhao4zhong1 的回复:if(col==poz)         return; else if (col>poz) { ... } else {//col<poz ... }刚手写了一遍，懂了0.0，谢谢赵老师。

引用 2 楼 zhao4zhong1 的回复:if(col==poz)         return; else if (col>poz) { ... } else {//col<poz ... }老师麻烦您解释下或详细点，我不太懂（太笨了，刚学这个），谢谢您了。

MoveCol中要考虑重叠


Question: 新手比较迷茫，请大神解惑。

引用 2 楼 zhao4zhong1 的回复:建议楼主去学“易语言” 赵老师，不好意思，我不会选择易语言的，我宁愿学几年基础，即使什么都做不了，也不愿意速成的。 其实，我不应该提这问题的。我不像你们都是程序员，就是吃这口饭的。我学编程就是为了这点爱好而已。

建议楼主去学“易语言”

最恨开挂的人，要不然我早上王者了


Question: 关于线性表创建的，其中初始化，有个NULL

引用 6 楼 qq_32296307 的回复:是不是在主函数中 SeqList l；是开辟了一块空间，作为l的， 和int a一样；a可以直接赋值啊 没错

要通过InitList函数来修改main函数里的l的指向 必须传二级指针或者一级指针的引用，光传一级指针是没有用的（一级指针指向修改指针所指向的区域） （因为main函数的l和InitList函数的形参l他们仅仅是指向同一块内存区域， 但两者本身并不是同一个指针，所以你对InitList函数的l进行操作是影响不到main函数的l的）

lz犯了一个错误， 参数的传递只是传递一个副本，对于InitList来说， SeqList *l 这个只是 main 那个 l 的副本， 所以调用InitList后， main中的那个l， 并没有改变。由于在初始化时， l 的内容可能被初始化为0xcccccccc, 所以createLIst中打印不出来yes. 这样改 int InitList(SeqList **l) {     (*l)=(SeqList *)malloc(sizeof(SeqList));     if((*l)!=NULL)     {         (*l)->next=NULL;         return 1;     }     return 0; } void CreatList(SeqList *l) {     if(l->next==NULL)         printf("yes\n"); }   int main() {     SeqList *l;     InitList(&l);     CreatList(l);     return 0; }   P.S. 不要单字母命名变量， 特别是用l ///

#include <stdio.h> #include <stdlib.h> typedef struct SeqList{     char data;     struct SeqList *next; }SeqList;  int InitList(SeqList **l) {     *l=(SeqList *)malloc(sizeof(SeqList));     if(l!=NULL)     {         (*l)->next=NULL;         return 1;     }     return 0; } void CreatList(SeqList *l) {     if(l->next==NULL)         printf("yes\n"); }  int main() {     SeqList *l;      InitList(&l);     CreatList(l);     return 0; }

引用 1 楼 user-4 的回复:int InitList(SeqList *l) {     l=(SeqList *)malloc(sizeof(SeqList));  最后一句是修改这个参数本身，而不是传递过来的参数，可以试试 int InitList(SeqList *l) {     l->next =(SeqList *)malloc(sizeof(SeqList)); 第一次用这边的bbs，有点不熟悉


Question: VS导出模板后，出现文件丢失是什么情况？

楼主，后来用qt又是怎么解决的？

引用 5 楼 yaodewei111 的回复:你后来怎么搞的？  好像是VS本身的问题 没解决  我换成qt来做了

你后来怎么搞的？

在线等啊 1天了  头都大了 求帮忙啊！

没人知道怎么回事吗？ 求帮忙啊！

引用 1 楼 user-3 的回复:重新做一个吧  重做好几十次了 都一样  我连存储目录都改了 还是不行

重新做一个吧


Question: int *d = &i 与 int *d = 0区别

50分的帖子结了80分，好神奇呀

引用 4 楼 antiwise 的回复:感谢各位回答！ 好像  int *d = &i; *d = 0; 与 int *d = 0; 是不同的啊，是不是？ *d = 0;代表把d指针指向的值赋值为0？ int *d = 0代表声明一个指为空的指针？ 不知我理解是否正确 正确

引用 4 楼 antiwise 的回复:感谢各位回答！ 好像  int *d = &i; *d = 0; 与 int *d = 0; 是不同的啊，是不是？ *d = 0;代表把d指针指向的值赋值为0？ int *d = 0代表声明一个指为空的指针？ 不知我理解是否正确  对的

int *d = 0 表示指针指向了地址为0的地方（俗称的空指针） 空指针解引用是否导致异常应该是硬件设备和OS组合决定的。以前在VXwork下工作，空指针也可以解引用，可以访问内存0地址，还可以修改内容。这种情况下，为了便于程序员debug，印象中我们大概是采用了对于0地址内容监控，如果内容有改动则报告或者crash。NULL指针的访问异常是C程序员常见的bug，事实上部分情况下空指针可以解引用。

0=NULL  ;

int *d = 0 ， 那么d为一个空指针 你去解引一个空指针，当然会出错


Question: 在A类中定义C类的指针*p，现在需要在B类中获取*p的值或地址，用什么办法？

友元函数

顶一下 谢谢大家

C++ 以下方法，可以访问成员变量 1) get(）方法,也就是写个  public函数返回一个值     int get()const{return this->mx;}; 2）通过友元 直接取 3）访问属性设置为 public 可以直接 用 4）可以用过 out 参数传递 void get(int &x){return this->mx;};  5）访问多个成员，也可以通过  public 方法（成员函数）访问


Question: 请问是数组越界问题吗

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

赵四老师说的好，这事是你尿急要上厕所啊，我也帮不上你，只能看你尿裤子了


Question: 关于静态变量使用的问题

“ warning #2173: Pointer to local 'result' is an invalid return value.” 函数不能返回局部（非静态）变量的地址或者引用。

静态局部变量在函数内定义，但不象自动变量那样，当调用时就存在，退出函数时就消失。静态局部变量始终存在着，也就是说它的生存期为整个源程序。

static定义的变量是初始化为0的,所以没啥问题 但是你不用static定义又没有初始化字符数组的话,数组值未定 输出时一直输出直到碰巧遇到内存中一个0就停止


Question: 计算器程序计算出的结果错误

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

中文括号？改成英语的试试？ 或者先算算 1*(2+3)看看对不对？


Question: 编译出现这个问题，怎么回事，程序如下

1.有个位置的多了一个大括号 2.main函数的返回值类型没写  #include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> typedef char TElemType; typedef int status; typedef struct BiTPNode { 	TElemType data[10]; 	struct BiTPNode *parent, *lchild, *rchild;//父亲及左右孩子指针 }BiTPNode, *BiPTree;  BiPTree P; BiPTree T;   int Cre()//家谱的创建 { 	system("cls"); 	FILE *fp;//声明指向文件的指针 	char filename[40], str[10]; 	printf("请输入家谱名称:"); 	getchar(); 	gets(filename);//输入家谱名称 	while (filename[0] == NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	} 	if ((fp = fopen(filename, "w")) == NULL) 	{ 		printf("%s家谱创建失败!\n", filename); 		return 0; 	} 	printf("请输入家谱内容:\n"); 	while (strlen(gets(str)) > 0) 	{ 		fputs(str, fp);//向文件写入字符串 		putc('\n', fp); 	} 	fclose(fp);//关闭文件 	printf("按任意键继续!"); 	getch(); 	return 1; }   status loc(BiPTree T, BiPTree &P, TElemType name[10]) { 	if (T) 	{ 		P = T;//字符串的比较 		if (!strcmp(name, T->data)) return 1; 		if (loc(T->lchild, P, name)) return 1; 		if (loc(T->rchild, P, name)) return 1; 	} 	else 		return 0; }   status inittree(BiPTree &T)//构造二叉树 { 	T = (BiTPNode*)malloc(sizeof(BiTPNode)); 	if (T) 		return 0; 	T->lchild = NULL; 	T->rchild = NULL; 	T->parent = NULL; 	return 1; }   status Crt(BiPTree &T)//载入家谱 { 	FILE *fp; 	BiPTree Q, R, M, N; 	char filename[40], name[10]; 	system("cls");//清屏 	R = (BiTPNode*)malloc(sizeof(BiTPNode));//分配存储空间 	M = (BiTPNode*)malloc(sizeof(BiTPNode)); 	N = (BiTPNode*)malloc(sizeof(BiTPNode)); 	printf("请输入家谱名:"); 	getchar(); 	gets(filename);  	while (filename[0] == NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	}  	if ((fp = fopen(filename, "r")) == NULL) 	{ 		printf("%s家谱打开失败!\n", filename); 		return 0; 	}  	inittree(T); 	fscanf(fp, "%s", name);//从文件读入姓名 	strcpy(T->data, name); 	T->lchild = NULL; 	T->rchild = NULL; 	T->parent = NULL; 	fclose(fp);  	if ((fp = fopen(filename, "r")) == NULL) 	{ 		printf("%s家谱打开失败!\n", filename); 		return 0; 	}  	fscanf(fp, "%s", name);  	while (!feof(fp)) 	{ 		if (loc(T, P, name)) 		{ 			fscanf(fp, "%s", name); 			Q = (BiTPNode*)malloc(sizeof(BiTPNode)); 			strcpy(T->data, name); 			P->lchild = Q;//构建孩子 			Q->parent = P; 			Q->lchild = NULL; 			Q->rchild = NULL; 			N = P; 		} 		else if (!loc(T, P, name)) 		{ 			Q = (BiTPNode*)malloc(sizeof(BiTPNode)); 			R = N; 			R = R->lchild; 			while (R) 			{ 				M = R; 				R = R->rchild; 			} 			strcpy(Q->data, name); 			M->rchild = Q; 			Q->lchild = M; 			Q->lchild = NULL; 			Q->rchild = NULL; 		} 		fscanf(fp, "%s", name); 	} 	printf("信息载入成功,按任意键继续!"); 	getch(); 	return 1; }    status in(BiPTree &T)//添加成员 { 	char father[10], name[10]; 	BiPTree Q, M; 	system("cls"); 	printf("请输入要添加到该家谱中的人的父亲姓名:"); 	getchar(); 	gets(father); 	while (!loc(T, P, father)){  		printf("%s不在该家谱中!请重新输入:", father); 		gets(father); 	}  	printf("请输入要添加到该家谱中的人的姓名:"); 	gets(name); 	Q = (BiTPNode*)malloc(sizeof(BiTPNode)); 	M = (BiTPNode*)malloc(sizeof(BiTPNode)); 	strcpy(Q->data, name); 	Q->lchild = NULL; 	Q->rchild = NULL;  	if (!P->lchild) 	{ 		P->lchild = Q; 		Q->parent = P; 	} 	else 	{ 		P = P->lchild;  		while (P) 		{ 			M = P; 			P = P->rchild; 		} 		M->rchild = Q; 		Q->parent = M; 	} 	printf("成员添加成功,按任意键继续!"); 	getch(); 	return 1; }    //删除成员 status de(BiPTree &T) { 	char name[10]; 	system("cls"); 	printf("请输入要删除的人的姓名:"); 	getchar(); 	gets(name);  	while (!loc(T, P, name)) 	{ 		printf("%s不在该家谱中!请重新输入:", name); 		gets(name); 	}  	if (!P->rchild) 	{ 		if (P->parent->lchild == P) 			P->parent->lchild = NULL; 		else 			P->parent->rchild = NULL; 		free(P); 	} 	else if (P->rchild) 	{ 		if (P->parent->lchild == P) 			P->parent->lchild = P->rchild; 		else 			P->parent->rchild = P->rchild; 		free(P); 	} 	printf("删除成员成功,按任意键继续!"); 	getch(); 	return 1; }   status Show(TElemType e[10]) { 	printf("%s ", e); 	return 1; }     //二叉树的遍历  status pre(BiPTree T, status(*visit)(TElemType[10])) { 	if (T) 	{ 		if ((*visit)(T->data)) 		if (pre(T->lchild, visit)) 		if (pre(T->rchild, visit)) return 1; 		return 0; 	} 	else 		return 1; }    //家族成员查询  status Sea(BiPTree T) { 	char name[10]; 	BiPTree N; 	N = (BiTPNode *)malloc(sizeof(BiTPNode)); 	system("cls"); 	printf("请输入要查询的人的姓名:"); 	getchar(); 	gets(name); 	while (!loc(T, P, name)) 	{ 		printf("%s不在该家谱中!请重新输入:", name); 		gets(name); 	} 	N = P;  	if (P == T) 		printf("%s的父亲在该家谱中没有记载!\n", P->data); 	else 	{ 		while (N->parent->rchild == N) 			N = N->parent; 		printf("%s的父亲是:%s\n", P->data, N->parent->data); 	} 	N = P;  	if (P == N) 		printf("%s没有兄弟!\n", P->data); 	else if (!P->rchild&&P->parent->rchild != P) 		printf("%s没有兄弟!\n", P->data); 	else 	{ 		printf("%s的兄弟有:\n", name); 		while (N->rchild) 		{ 			printf("%s", N->rchild->data); 			N = N->rchild; 		} 		N = P;  		while (N->parent->rchild == N){ 			printf("%s", N->parent->data); 			N = N->parent; 		}  		printf("\n"); 	}  	if (P == T) 		printf("%s的祖先在该家谱中没有记载!\n", name);  	else 		printf("%s的祖先是:%s\n", name, T->data); 	N = P;  	if (!P->lchild) 	{ 		printf("%s没有孩子!\n", name); 		printf("%s没有后代!\n", name); 	}  	else 	{ 		printf("%s的孩子有:\n", name); 		printf("%s", P->lchild->data); 		N = N->lchild; 	}  	while (N->rchild){  		printf("%s", P->rchild->data);  		N = N->rchild; 	}  	printf("\n"); 	printf("%s的后代有:\n", name); 	pre(P->lchild, Show); 	printf("\n"); 	printf("按任意键继续!"); 	getch(); 	return 1; }    //文件的创建 status write(BiPTree T, char filename[40]) { 	FILE *fp; 	if ((fp = fopen(filename, "a+")) == NULL) 	{ 		printf("%s文件创建失败!\n", filename); 		return 0; 	} 	fprintf(fp, "%s", T->data); 	T = T->lchild; 	while (T) 	{ 		fprintf(fp, "%s", T->data); 		T = T->rchild; 	} 	fprintf(fp, "\n");//输出 	fclose(fp); 	return 1; }    status prewrite(BiPTree T, status(*visit)(BiPTree, char[40]), char filename[40]) { 	if (T) 	{ 		if (T->lchild) 			(*visit)(T, filename); 		prewrite(T->lchild, visit, filename); 		prewrite(T->rchild, visit, filename); 		return 1; 	} 	else 		return 1; }    status wrong() { 	char a; 	scanf("%c", &a); 	printf("无此选项,请重新选择!(按任意键继续!)"); 	getch(); 	return 1; }   status Sav(BiPTree T)//家谱的存储 { 	FILE *fp; 	char filename[40]; 	system("cls"); 	printf("请输入新的文件名:"); 	getchar(); 	gets(filename); 	while (filename[0] == NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	} 	prewrite(T, write, filename); 	printf("%s家谱保存成功,按任意键继续!", filename); 	getch(); 	return 1; }    //修改家谱 status Upd() { 	system("cls"); 	int xz; 	while (1) 	{ 		system("cls"); 		printf("\n\n\n\n"); 		printf("  家族成员的添加与删除操作  \n"); 		printf("  请选择  \n"); 		printf("  1.添加成员  \n"); 		printf("  2.删除成员  \n"); 		printf("  3.返回上一级  \n"); 		printf("  请选择  \n"); 		scanf("%d", &xz); 		switch (xz) 		{ 		case 1: in(T); break; 		case 2: de(T); break; 		case 3:	return 0; 		default: 			wrong(); 			break; 		} 	} }   int main() { 	P = (BiTPNode*)malloc(sizeof(BiTPNode)); 	int xz; 	while (1) 	{ 		system("cls"); 		printf("\n\n\n\n"); 		printf("  家族关系查询系统  \n"); 		printf("  具体操作如下  \n"); 		printf("  1.创建家谱  \n"); 		printf("  2.载入家谱  \n"); 		printf("  3.修改家谱  \n"); 		printf("  4.查询成员  \n"); 		printf("  5.保存家谱  \n"); 		printf("  6.退出程序  \n"); 		printf("  请选择操作  \n"); 		scanf("%d", &xz); 		switch (xz) 		{ 		case 1:Cre(); break; 		case 2:Crt(T); break; 		case 3:Upd(); break; 		case 4:Sea(T); break; 		case 5:Sav(T); break; 		case 6: return 0; 		default: 			wrong(); 			break; 		} 	} }

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> typedef char TElemType; typedef int status; typedef struct BiTPNode { 	TElemType data[10]; 	struct BiTPNode *parent,*lchild,*rchild;//父亲及左右孩子指针 }BiTPNode,*BiPTree;  BiPTree P; BiPTree T;   int Cre()//家谱的创建 { 	system("cls"); 	FILE *fp;//声明指向文件的指针 	char filename[40],str[10]; 	printf("请输入家谱名称:"); 	getchar(); 	gets(filename);//输入家谱名称 	while(filename[0]==NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	} 	if((fp=fopen(filename,"w"))==NULL) 	{ 		printf("%s家谱创建失败!\n",filename); 		return 0; 	} 	printf("请输入家谱内容:\n"); 	while(strlen(gets(str))>0) 	{ 		fputs(str,fp);//向文件写入字符串 		putc('\n',fp); 	} 	fclose(fp);//关闭文件 	printf("按任意键继续!"); 	getch(); 	return 1; }   status loc(BiPTree T,BiPTree &P,TElemType name[10]) { 	if(T) 	{ 		P=T;//字符串的比较 		if(!strcmp(name,T->data)) return 1; 		if(loc(T->lchild,P,name)) return 1; 		if(loc(T->rchild,P,name)) return 1; 	} 	else 		return 0; }   status inittree(BiPTree &T)//构造二叉树 { 	T=(BiTPNode*)malloc(sizeof(BiTPNode)); 	if(T) 		return 0; 	T->lchild=NULL; 	T->rchild=NULL; 	T->parent=NULL; 	return 1; }   status Crt(BiPTree &T)//载入家谱 { 	FILE *fp; 	BiPTree Q,R,M,N; 	char filename[40],name[10]; 	system("cls");//清屏 	R=(BiTPNode*)malloc(sizeof(BiTPNode));//分配存储空间 	M=(BiTPNode*)malloc(sizeof(BiTPNode)); 	N=(BiTPNode*)malloc(sizeof(BiTPNode)); 	printf("请输入家谱名:"); 	getchar(); 	gets(filename);  	while(filename[0]==NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	}  	if((fp=fopen(filename,"r"))==NULL) 	{ 		printf("%s家谱打开失败!\n",filename); 		return 0; 	}  	inittree(T); 	fscanf(fp,"%s",name);//从文件读入姓名 	strcpy(T->data,name); 	T->lchild=NULL; 	T->rchild=NULL; 	T->parent=NULL; 	fclose(fp);  	if((fp=fopen(filename,"r"))==NULL) 	{ 		printf("%s家谱打开失败!\n",filename); 		return 0; 	}  	fscanf(fp,"%s",name);  	while(!feof(fp)) 	{ 		if(loc(T,P,name)) 		{ 			fscanf(fp,"%s",name); 			Q=(BiTPNode*)malloc(sizeof(BiTPNode)); 			strcpy(T->data,name); 			P->lchild=Q;//构建孩子 			Q->parent=P; 			Q->lchild=NULL; 			Q->rchild=NULL; 			N=P; 		} 		else if(!loc(T,P,name)) 			{ 				Q=(BiTPNode*)malloc(sizeof(BiTPNode)); 				R=N; 				R=R->lchild; 				while(R) 				{ 					M=R; 					R=R->rchild; 				} 				strcpy(Q->data,name); 				M->rchild=Q; 				Q->lchild=M; 				Q->lchild=NULL; 				Q->rchild=NULL; 			} 			fscanf(fp,"%s",name); 	} 	printf("信息载入成功,按任意键继续!"); 	getch(); 	return 1; }    status in(BiPTree &T)//添加成员 { 	char father[10],name[10]; 	BiPTree Q,M; 	system("cls"); 	printf("请输入要添加到该家谱中的人的父亲姓名:"); 	getchar(); 	gets(father); 	while(!loc(T,P,father)){  		printf("%s不在该家谱中!请重新输入:",father); 		gets(father);}  		printf("请输入要添加到该家谱中的人的姓名:"); 		gets(name); 		Q=(BiTPNode*)malloc(sizeof(BiTPNode)); 		M=(BiTPNode*)malloc(sizeof(BiTPNode)); 		strcpy(Q->data,name); 		Q->lchild=NULL; 		Q->rchild=NULL;  		if(!P->lchild) 		{ 			P->lchild=Q; 			Q->parent=P; 		} 		else 		{ 			P=P->lchild;  			while(P) 			{ 				M=P; 				P=P->rchild; 			} 			M->rchild=Q; 			Q->parent=M; 		} 		printf("成员添加成功,按任意键继续!"); 		getch(); 		return 1; 	}    //删除成员 status de(BiPTree &T) { 	char name[10]; 	system("cls"); 	printf("请输入要删除的人的姓名:"); 	getchar(); 	gets(name);  	while(!loc(T,P,name)) 	{ 		printf("%s不在该家谱中!请重新输入:",name); 		gets(name); 	}  	if(!P->rchild) 	{ 		if(P->parent->lchild==P) 			P->parent->lchild=NULL; 		else 			P->parent->rchild=NULL; 		free(P); 	} 	else if(P->rchild) 	{ 		if(P->parent->lchild==P) 			P->parent->lchild=P->rchild; 		else 			P->parent->rchild=P->rchild; 		free(P); 	} 	printf("删除成员成功,按任意键继续!"); 	getch(); 	return 1; }   status Show(TElemType e[10]) { 	printf("%s ",e); 	return 1; }     //二叉树的遍历  status pre(BiPTree T,status(*visit)(TElemType[10])) { 	if(T) 	{ 		if((*visit)(T->data)) 			if(pre(T->lchild,visit)) 				if(pre(T->rchild,visit)) return 1; 				return 0; 				} 	else 		return 1; }    //家族成员查询  status Sea(BiPTree T)  { 	char name[10]; 	BiPTree N; 	N=(BiTPNode *)malloc(sizeof(BiTPNode)); 	system("cls"); 	printf("请输入要查询的人的姓名:"); 	getchar(); 	gets(name); 	while(!loc(T,P,name)) 	{ 		printf("%s不在该家谱中!请重新输入:",name); 		gets(name); 	} 	N=P;  	if(P==T) 		printf("%s的父亲在该家谱中没有记载!\n",P->data); 	else 	{ 		while(N->parent->rchild==N) 			N=N->parent; 		printf("%s的父亲是:%s\n",P->data,N->parent->data); 	} 	N=P;  	if(P==N) 		printf("%s没有兄弟!\n",P->data); 	else if(!P->rchild&&P->parent->rchild!=P) 		printf("%s没有兄弟!\n",P->data); 	else 	{ 		printf("%s的兄弟有:\n",name); 		while(N->rchild) 		{ 			printf("%s",N->rchild->data); 			N=N->rchild; 		} 		N=P;  		while(N->parent->rchild==N){ 			printf("%s",N->parent->data); 			N=N->parent;}  		printf("\n"); 	} 	 	if(P==T) 		printf("%s的祖先在该家谱中没有记载!\n",name); 	 	else 		printf("%s的祖先是:%s\n",name,T->data); 	N=P;  	if(!P->lchild) 	{ 		printf("%s没有孩子!\n",name); 		printf("%s没有后代!\n",name); 	}  	else 	{ 		printf("%s的孩子有:\n",name); 		printf("%s",P->lchild->data); 		N=N->lchild; 	}  	while(N->rchild){  		printf("%s",P->rchild->data);  		N=N->rchild;}  	printf("\n"); 	printf("%s的后代有:\n",name); 	pre(P->lchild,Show); 	printf("\n"); } 	printf("按任意键继续!"); 	getch(); 	return 1; }    //文件的创建 status write(BiPTree T,char filename[40]) { 	FILE *fp; 	if((fp=fopen(filename,"a+"))==NULL) 	{ 		printf("%s文件创建失败!\n",filename); 		return 0; 	} 	fprintf(fp,"%s",T->data); 	T=T->lchild; 	while(T) 	{ 		fprintf(fp,"%s",T->data); 		T=T->rchild; 	} 	fprintf(fp,"\n");//输出 	fclose(fp); 	return 1; }    status prewrite(BiPTree T,status(*visit)(BiPTree,char[40]),char filename[40]) { 	if(T) 	{ 		if(T->lchild) 			(*visit)(T,filename); 		prewrite(T->lchild,visit,filename); 		prewrite(T->rchild,visit,filename); 		return 1; 	} 	else 		return 1; }    status wrong() { 	char a; 	scanf("%c",&a); 	printf("无此选项,请重新选择!(按任意键继续!)"); 	getch(); 	return 1; }   status Sav(BiPTree T)//家谱的存储 { 	FILE *fp; 	char filename[40]; 	system("cls"); 	printf("请输入新的文件名:"); 	getchar(); 	gets(filename); 	while(filename[0]==NULL) 	{ 		printf("家谱名不能为空,请重新输入:"); 		gets(filename); 	} 	prewrite(T,write,filename); 	printf("%s家谱保存成功,按任意键继续!",filename); 	getch(); 	return 1; }    //修改家谱 status Upd() { 	system("cls"); 	int xz; 	while(1) 	{ 		system("cls"); 		printf("\n\n\n\n"); 		printf("  家族成员的添加与删除操作  \n"); 		printf("  请选择  \n"); 		printf("  1.添加成员  \n"); 		printf("  2.删除成员  \n"); 		printf("  3.返回上一级  \n"); 		printf("  请选择  \n"); 		scanf("%d",&xz); 		switch(xz) 		{ 		case 1: in(T);break; 		case 2: de(T);break; 		case 3:	return 0; 		default: 			wrong(); 			break; 		} 	} }   main() { 	P=(BiTPNode*)malloc(sizeof(BiTPNode));  	int xz; 	while(1) 	{ 		system("cls"); 		printf("\n\n\n\n"); 		printf("  家族关系查询系统  \n"); 		printf("  具体操作如下  \n"); 		printf("  1.创建家谱  \n"); 		printf("  2.载入家谱  \n"); 		printf("  3.修改家谱  \n"); 		printf("  4.查询成员  \n"); 		printf("  5.保存家谱  \n"); 		printf("  6.退出程序  \n"); 		printf("  请选择操作  \n"); 		scanf("%d",&xz); 		switch(xz) 		{ 		case 1:Cre(); break; 		case 2:Crt(T); break; 		case 3:Upd(); break; 		case 4:Sea(T); break; 		case 5:Sav(T); break; 		case 6: return 0; 		default:  			wrong(); 			break; 		} 	} } 求大神找到错误

整个代码贴出来看看


Question: 关于循环变量i的作用域

跟编译器的语法检查又关呢,不需要过于纠结这个问题；遵循先声明后使用的原则吧

#include <stdio.h> int main(void) { 	for(int i=0;i<5;i++) 		printf("Gee!"); 	return 0; }   用gcc(Mingw)编译这个代码，首次报错（如图），提示加"-std c99"，之后成功（如图），可见只有C99支持这个操作。

C语言的写法一般都是把int i;写在for前面的

引用 5 楼 Hamber_Bao 的回复:[quote=引用 1 楼 user-7 的回复:] 和编译器有关。楼主用的什么？ 这个写法在最早的c语言里没有，后来加上的。所以有些编译器可能不支持；或者默认不支持要加选项才支持。我用的是VS2010里带的编译器，我设置了环境变量。在CMD手动编译的[/quote] CL并不是很好的支持标准C哦,楼主可以把后缀改成CPP再编译,或者使用GCC开启C99支持编译

引用 1 楼 user-7 的回复:和编译器有关。楼主用的什么？ 这个写法在最早的c语言里没有，后来加上的。所以有些编译器可能不支持；或者默认不支持要加选项才支持。我用的是VS2010里带的编译器，我设置了环境变量。在CMD手动编译的

-std=c99，以前版本不支持

你这有的trubo c 还是vc6.0啊，赶快下个vs最新版的开发工具

c++都没问题。如果是c语言，应该是c99才有的吧。 我用gcc，默认不支持，要加个选项-std=c99 VS2012的命令行cl.exe，也不支持，不知道有没有办法可以支持的。 楼主看看你的编译器有没有设置支持c99


Question: 求解答  下面代码在vc上可运行通过，但在codeblock上显示出错

引用 5 楼 zhao4zhong1 的回复:将源代码的扩展名从.c改为.cpp   谢谢谢谢你  成功了

将源代码的扩展名从.c改为.cpp

引用 2 楼 zhao4zhong1 的回复:codeblock使用gcc/g++作为编译器，不支持conio.h个getch() 建议参考NCURSES库。   编译还是出错   显示第12行代码有问 题  去掉里面的&取地址符就么有问题。但那样程序会崩溃  求解答

或者简单点，删掉#include <conio.h>，再将getch();改为getchar();


Question: 计算器程序中比较运算符的优先级函数

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

编译器是VC6，补充一句


Question: 计算字符串的长度

size_t char_len(const char *s) { 	const char *ss = s; 	while (*ss) 		ss++; 	return ss - s; }

char类型和int类型的长度不一样，这是最基本的字符串函数哈，写法也可以是可以是多种多样的：  int char_len1(char *s)         //常规思路 {     int len;     for(len=0;*s++;len++);      return(len); }  int char_len2(char *s)        //计算指针偏移量 {     char *p;     for(p=s;*p;p++);      return((p-s)/sizeof(char)); }

#include <stdio.h>  int char_len(char *str) { 	int lens = 0; 	while(*str++ != '\0') 	{ 		lens++; 	} 	return lens; }  int main() { 	char *name; 	int length; 	name= "Hello World!"; 	length = char_len(name); 	printf("%d\n",length); 	return 0; }

形参类型改下就行了

引用 4 楼 sds428 的回复:刚试了下代码，把int char_len(int *str)这里面的int改为char，就一切ok了，运行结果正确  正常了吗？真的吗  把 char *name = "Hello World!"; int length = char_len(name);  改成 int length = char_len( "Hello World!");  试试

还有 int char_len(int *str) 字串定义居然不是char *str，而是int  *str，我也是醉了

int char_len(int *str) {         int lens = 0;         char  *p=str;       //不这样做，你就是找死，不解释         while(p)              //很讨厌那种自以为是的嵌套，逻辑思维都不成熟，非要装什么逼嘛，踏实很难吗？         {                lens++;                       p++;          }                         //另外，*p==‘0’了，p也就NULL了，用*p和用p作为循环条件一个鸟样         return lens; }


Question: 请写出函数mygets和myputs，其功能分别与gets和puts相同，函数中用getchar和putchar读入和输出字符

引用 2 楼 u011661665 的回复:谢谢大神！刚刚看到这贴，差点跪了！厉害！我出现的问题是\n写成了\0。另外很像请教预处理那里的几个引用，malloc是分配内存吧。。。。这个应该不要用吧。修改后的代码，额，出现乱码和滴滴的声音。复制了大神的代码以后，也就是加了预处理，就没有了，为什么啊？求解释。 原谅我ISOstream没学过。 在c语言中malloc是申请内容的方式，一般都用malloc和free配对使用。 出现乱码是因为你没有初始化char str[5];或者没有putchar正确的字符造成的。 你输出正确的putchar并跳出循环，滴滴声自然就没了。

调戏一下楼主 #define  mygets  gets #define  myputs  puts

# include <stdio.h> # include <malloc.h> # include <stdlib.h> #include <iostream> void mygets(char str[]){ 	char ch; 	int i = 0;  	while((ch = getchar()) != '\n'){ 		str[i] = ch; 		i++; 	} 	str[i] = '\n'; }  void myputs(char str[]){ 	int i = 0; 	char ch; 	for(;;){ 		ch = str[i]; 		if(ch == '\n') 			break; 		i++; 		putchar( ch ); 	} }  int main(){ 	char str[5]; 	printf("Input less than 5\n"); 	mygets( str ); 	myputs( str );  	return 0; }


Question: 关于FOR循环变量i的问题

没有i=0的第二个for循环i的值是第一个循环后i的值，但第二个程序里的两个i开始都是0。

引用 1 楼 zybz2009 的回复:这两个for是想表达什么 你看不明白吗

引用 2 楼 renwotao2009 的回复: #include <stdio.h> #define SIZE 10   int main(void) {    int i = 0;      int array[SIZE];      for(;i < SIZE;++i)       array[i] = i;      for(;i < SIZE;++i) // 此时，i=SIZE，也就没有进入循环体       printf("array[%d] = %d\n",i,array[i]); } 多谢 是这样的。我刚试了试

引用 1 楼 zybz2009 的回复:这两个for是想表达什么多谢 是的，懂了。

这两个for是想表达什么


Question: 怎么在这个链表中互换字符串？

链表排序为何要换节点数据呢?不觉得效率很低下吗? 设待交换两节点为2,3号,直接把1号的next指向3,3的next指向2,2的next指向4 不一样达到"交换"节点的效果?

# include <stdio.h> # include <malloc.h> # include <stdlib.h>  struct stduent * creat_list(void); void printf_list(struct stduent *);  struct stduent { 	int age; 	char * name;                                	struct stduent * pnext; };   int _tmain(int argc, _TCHAR* argv[]) { 	struct stduent * phead; 	phead = creat_list(); 	printf_list(phead);  	return 0; }   // 创建一个链表； struct stduent * creat_list() { 	// 创建头结点； 	struct stduent * phead = (struct stduent *)malloc(sizeof(struct stduent)); 	struct stduent * ptemp = phead;  	// 创建后续节点； 	int ren,i; 	printf ("请输入学生的人数：\n"); 	scanf ("%d",&ren); 	for (i = 0; i<ren; i++) 	{ 		struct stduent * pnew = (struct stduent *)malloc(sizeof(struct stduent)); 		printf ("请输入第%d个学生的年龄:",i+1); 		scanf ("%d",&pnew->age); 		printf ("请输入第%d个学生的姓名:",i+1); 		char *p;  		p = (char*) malloc(10 * sizeof(char)); 		pnew->name = p; 		for(int j = 0;j<10;j++) 		{ 			*p = 0; 			p++; 		} 		scanf ("%s",pnew->name);    		pnew->pnext = NULL; 		ptemp->pnext = pnew; 		ptemp = pnew; 	}    	return phead; }  // 遍历输出每一个节点；  void printf_list(struct stduent * phead) {  	struct stduent * p, * h; 	int temp1; 	char * temp2;   // 看这里！！！！！！！！！！！！！！！！！！！！！！！！！！ 	for (p = phead->pnext; p != NULL; p = p->pnext) 	{ 		for (h = p->pnext; h != NULL; h = h->pnext) 		{ 			if (p->age < h->age) 			{ 				temp1 = p->age; 				p->age = h->age; 				h->age = temp1;  				// 看这里！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！ 				temp2 = p->name; 				p->name = h->name; 				h->name = temp2;  			} 		} 	}  	for (p = phead->pnext; p != NULL; p = p->pnext) 	{ 		printf ("%d\n",p->age); 		printf ("%s\n",p->name); 	} }

几个问题： 1.需要为pnew->name给malloc字符数组空间 2.printf_list函数里字符串拷贝要用strcpy,而不是直接用= 3.char temp2[32] = {0}; 要分配空间，而不是char *temp2;  # include <stdio.h> # include <malloc.h> # include <stdlib.h> #include<string.h>  struct stduent * creat_list(void); void printf_list(struct stduent *);  struct stduent { 	int age; 	char * name;                                // 看这里！！！！！！！！！！！！！！！ 	struct stduent * pnext; };  int main(void) { 	struct stduent * phead; 	phead = creat_list(); 	printf_list(phead);  	return 0; }  // 创建一个链表； struct stduent * creat_list() { 	// 创建头结点； 	struct stduent * phead = (struct stduent *)malloc(sizeof(struct stduent)); 	struct stduent * ptemp = phead;  	// 创建后续节点； 	int ren, i; 	printf("请输入学生的人数：\n"); 	scanf("%d", &ren); 	for (i = 0; i<ren; i++) 	{ 		struct stduent * pnew = (struct stduent *)malloc(sizeof(struct stduent)); 		pnew->name = (char *)malloc(32); 		printf("请输入第%d个学生的年龄:", i + 1); 		scanf("%d", &pnew->age); 		printf("请输入第%d个学生的姓名:", i + 1); 		scanf("%s", pnew->name);        // 看这里！！！！！！！！！！！！！！！！！！！！！！！！  		pnew->pnext = NULL; 		ptemp->pnext = pnew; 		ptemp = pnew; 	}    	return phead; }  // 遍历输出每一个节点；  void printf_list(struct stduent * phead) {  	struct stduent * p, *h; 	int temp1; 	char temp2[32] = {0};   // 看这里！！！！！！！！！！！！！！！！！！！！！！！！！！ 	for (p = phead->pnext; p != NULL; p = p->pnext) 	{ 		for (h = p->pnext; h != NULL; h = h->pnext) 		{ 			if (p->age < h->age) 			{ 				temp1 = p->age; 				p->age = h->age; 				h->age = temp1; 				printf("%s %s\n", p->name, h->name); 				// 看这里！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！ 				strcpy(temp2, p->name); 				strcpy(p->name, h->name); 				strcpy(h->name, temp2); 				//temp2 = p->name; 				//p->name = h->name; 				//h->name = temp2;  			} 		} 	}  	for (p = phead->pnext; p != NULL; p = p->pnext) 	{ 		printf("%d\n", p->age); 		printf("%s\n", p->name); 	}  }

不是留个位子，是六个位置

不是互换字串，是互换结构指针  比如原来排序head,a,b,c,d,e,f,null 那么就是如下意思 a->next=b; b->next=c; c->next=d; d->next=e; e->next=f;  现在要实现，b和d互换位置 因为是单链表，所以就是要实现 a->next=d; d->next=c; c->next=b; b->next=e;  也就是说，单链互相换位置，需要保存留个位子信息 节点1本身，节点1上家，节点1下家 节点2本身，节点2上家，节点2下家


Question: 为什么删掉浏览器缓存目录里的内容后网页上的历史网址还存在？

兄弟 你肯定发错地方了 ！！

引用 10 楼 ztt920725 的回复:因为是新手，不好意思哈，不知道往哪里发，想用C来实现，在考虑的过程中就把缓存目录里的删除了，可是在网页浏览历史中还是存在，刚才重启了浏览器还是有的 有个专门C/C++的模块，去那里发

兄弟 你是不是发错地方了 ??

兄弟，你确确实实发错地方了！！

你到底是手动的还是用c实现的

你确定重新打开浏览器了？

兄弟，我真的不知道怎么接了

技术问题，不懂

兄弟，你确确实实发错地方了！！

兄弟 你一定发错地方了 ！！

兄弟 你肯定发错地方了 ！！

兄弟 你是不是发错地方了 ??


Question: 学生求助

爱莫能助嗷(补字数)


Question: char *str="abcdefg";  这条 语句这样写合法吗？

看了一下这个帖子,我觉得ryxcaixia开头本来就说错了呀,有啥好吵得,这是被人指出错误然后恼羞成怒了?

任何常量区都是伪常量区！

合法，就是指针str指向“abcdefg”这个常量区

理论上是合法的，但是你这样写之后就不能用str来修改这个字符串了，因为对于这种形式的语句来说这个是一个const char

引用 7 楼 u014444402 的回复:[quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针 你错了, char* p = NULL; p = "abcde"; 这样是没有问题的.不会"自然报错"的.一个指针变量赋给他一个地址能有什么错.[/quote] 不要纠结编译器会不会报错，至少这样写本身是错误的。就跟：char *p = "Hello world!";应该写成：const char *p = "Hello world!";char *p; p = "Hello world!";应该写成：const char *p; p = "Hello world!"; 一样的。虽然编译器不一定报错，但毕竟不是可写的，就不要这样写，防止程序崩溃。

《深入理解C指针》这本书不错，也比较薄，有大量的图解，指针不再难。

引用 16 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   求再贴一下 3q 赵4老师

引用 16 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   赵4老师 我记得你有一段话 经常会贴出来 但是找不到了 就是那句 不迷信教科书 课本  要新密反汇编 cpu 这是一段  还一段是关于IDE 大概意思是一个IDE如果能精准的反汇编每一句源代码 那这个IDE是可以用的 并且是好用的

引用 17 楼 wen_eric 的回复:[quote=引用 11 楼 ryxcaixia 的回复:] [quote=引用 10 楼 wen_eric 的回复:] [quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。[/quote]  XB[/quote]错了就好好反省，下次不要不负责任的误导别人。[/quote]  本来呢 不想骂人 但是你自己还找骂 那在下不客气了 请允许我优雅真诚的对你说一句 我去年买了个登山包 超耐磨 超耐磨

完全可以这样写...

完全可以这写，标准中没有任何约束不允许这样写。 char *str="abcdefg"; 这里str不是常量指针（不管这个词指啥，constant pointer还是pointer to const-qualified），"abcdefg"也不是常量字符串。

引用 11 楼 ryxcaixia 的回复:[quote=引用 10 楼 wen_eric 的回复:] [quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。[/quote]  XB[/quote]错了就好好反省，下次不要不负责任的误导别人。

C++ 不允许这样写。  但是 C 允许。  为了兼容性考虑，现在有很多 C++ 编译器支持这种写法（其中有一些虽然支持，但是会给一个 warning）。

按理要写成const char* 不过允许写成char* 算是一个特例吧，历史遗留原因

引用 12 楼 u014444402 的回复:[quote=引用 11 楼 ryxcaixia 的回复:] [quote=引用 10 楼 wen_eric 的回复:] [quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。[/quote]  XB[/quote] 讨论就讨论,骂人就不对了. 首先,在PC平台,常量指针与内存指针位数是一样的,不会有错,可能一些嵌入平台会有错,例如 picc编译器 "ddddd"这个指针是24位的,普通的指针才是16位的,所以会有错.[/quote]  为啥要生气呢 亲? 上述所有说的指针无非都是基于vs 编译器和gcc/g++编译器 例如masm5.0 16位汇编 那他的指针又是多少位? 估计他还没指针的概念  有问题大家拿出来讨论下 对就是对 错就是错 我把代码拿到编译器去试了下 得出之前我的结论是错的 提高不就是在互相交流(更多时候是喷)中产生的么 你说我说的对吧亲

引用 11 楼 ryxcaixia 的回复:[quote=引用 10 楼 wen_eric 的回复:] [quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。[/quote]  XB[/quote] 讨论就讨论,骂人就不对了. 首先,在PC平台,常量指针与内存指针位数是一样的,不会有错,可能一些嵌入平台会有错,例如 picc编译器 "ddddd"这个指针是24位的,普通的指针才是16位的,所以会有错.

引用 10 楼 wen_eric 的回复:[quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。[/quote]  XB

引用 6 楼 ryxcaixia 的回复:只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针  如char* p = NULL; p = "abcde"； 这样不会报错。

引用 7 楼 u014444402 的回复:[quote=引用 6 楼 ryxcaixia 的回复:] 只在第一次合法 如char* p = NULL; p = "abcde" 这种自然报错  char* p = "abcde" 这种可以让一个非常量指针直接指向常量, 是因为字符串常量的地址是在编译期就确定的 存在于程序的静态常量区 符号表中  一个编译期间确定好的地址 自然可以在初始化的时候赋值给一个非常量指针 你错了, char* p = NULL; p = "abcde"; 这样是没有问题的.不会"自然报错"的.一个指针变量赋给他一个地址能有什么错.[/quote]  还有 你也错了 "个指针变量赋给他一个地址能有什么错" 你让一个常量指针指向这个字符串地址 再让一个普通指针指向这个常量指针 自然报错


Question: 程序还差修改，求大神帮忙把修改的程序补上，谢谢！

引用 1 楼 zhao4zhong1 的回复:百度搜“C源代码 学生信息系统”

百度搜“C源代码 学生信息系统”


Question: 怎么实现题中第二个输入条件

必须还得有个结尾标志啊，还是你输入一行输出一行？

引用 4 楼 qq_34598319的回复:[quote=引用 1 楼 zycxnanwang 的回复:] while(scanf("%s",s) )//s为你存储的字符数组的首地址 你可以输入一个字符串，然后处理后，直接输出，但是每次的字符数组必须清空！ 这样是不是要先定义s char s[max] 有没有不需要事先定义大小的，因为后边输入的字符串大小不确定[/quote] 你学过string类型吗？可以定义一个string类型 while(cin>>s) s为你定义的字符串，这样也可以

引用 1 楼 zycxnanwang 的回复:while(scanf("%s",s) )//s为你存储的字符数组的首地址 你可以输入一个字符串，然后处理后，直接输出，但是每次的字符数组必须清空！ 这样是不是要先定义s char s[max] 有没有不需要事先定义大小的，因为后边输入的字符串大小不确定

是从控制台输入的吗？还是读一个文件啊

引用 2 楼 user-3的回复:是从控制台输入的吗？还是读一个文件啊 是从控制台输入的 这种情况怎么实现啊


Question: 求助，关于scanf输入的问题！

引用 3 楼 user-1 的回复:[quote=引用 2 楼 qq_35228050 的回复:] [quote=引用 1 楼 user-1 的回复:] 加上getchar  我想这道这样为什么不能实现输入？谢谢。[/quote] 回车符没有被丢掉[/quote]  非常感谢！

引用 2 楼 qq_35228050 的回复:[quote=引用 1 楼 user-1 的回复:] 加上getchar  我想这道这样为什么不能实现输入？谢谢。[/quote] 回车符没有被丢掉

引用 1 楼 user-1 的回复:加上getchar  我想这道这样为什么不能实现输入？谢谢。

加上getchar


Question: 关于= 和==

非零既是真！

建议比较时写成 if (2 == a)  这样就算错写成if (2 = a)，编译器会报错提醒

表达式的值和操作符的副作用

是的，非零既是真。

非零既是真！   好的判断就是 ==   而且一般要 2==x  这样写，可以防止你出错

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

微机原理学过了吗  计算机执行每一条指令都会根据执行效果设置相应的标志位 判断语句就是检查标志位 标志位为1就真，标志位为零就假  a=2就是个赋值代码，永远不会有让不让赋值的问题，CPU自然把标志位直接置1，表示永远让 a==2是个比较代码，CPU自然把比较结果给标志位  标志位是电脑硬件的潜规则。你纠结个鸡巴，关你毛事

if(a =2)执行后，我感觉和if(2)差不多吧，真假理解为if(1)了，

C ,C++,一般来说， 像这样有副作用的表达式，表达式本身有个值, 求这个值，是表达式求值的主要作用（ 虽然直观看来， 这个值很多时候没啥用途）。  副作用会对某个子表达式产生影响，使之变化。

C： if.while ,for 都是判断的整型，而非bool类型（甚至浮点型也能凑乎） 为0 为假，非0为真 -------char,指针类型 也没问题---------- -------C，如今也有bool 类型了，但是历史原因，这个bool类型作用不大，         但是可以用true，false 不必另外定义了。 C++：虽然结果是同样的，但是判断依据 ----至少可以理解成，先转换成bool ，为0 为假，非0 (转换成 1)为真。 因为C++有bool类型 C,C++的方式本质上没有区别， 只是C++有正式的bool类型。 可以不必用int 代替 bool了  if(expr) s;  if(expr)s1; else s2; while(expr)s; for(expr1,expr2,expr3)s;' do ...while(expr); 这里 的表达式 expr 都是先求出结果，再判断是否非 0 a=b; a=2; a=b+3; 这些 赋值表达式 的结果为 ： 将 = 右边的表达式的值赋值给 a 以后 ，a的新值。 他判断的是，表达式 a=2 的值  复合赋值表达式 a+=3 的值为 a+=3 得到的a的新值 ， 假设a原来为3，a+=3;  则 a的值为 5   表达式  a+=3  的值也是5 赋值表达式的值，是赋值这个副作用影响下 赋值表达式左边的子表达式，的新值

这样是能成功啊~只是把a做为判断条件，而不是为a的值做判断~噗哈哈~蛮有意思的其实~

引用 7 楼 wzxq123 的回复:上面的代码会一直输出yes，感觉是不是少打了个=号 if(a= =2)//这样正常点吧 {     printf("YES"); } 我没有写错，就是if(a=2) 我纠结于IF头判断的 依据不是布尔类型吗，1 或者0，这个if(a = 2),也没说让它判断a ，他怎么就依据a的值得出结论了呢

if (a = 2) 等同于： a = 2; if (a)

因为a =2，此时非零，条件为真，就执行if语句了，个人这样认为。

对的


Question: 关于C语言中自增问题

说实话，纠结这样子的问题一点意义也没有。因为任何一个审核代码的人也不会让这样的代码存在工程中。

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

What Every C Programmer Should Know About Undefined Behavior http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

这是不确定行为，取决于表达式求值顺序  不要写这种表达式，也不要纠结于这种表达式  如果真想了解，仔细读下面这文章：  关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

答案是12。 int a = 1; printf("%d\n", ++a + ++a + ++a); 在這裏是這樣的，首先 a是一個變量，不是多個。 第一次算第一個++a,此時a = 2;所以後面的兩個a的值也是2 第二次算第二個++a時，此時a = 2, ++a 的值是3，這裏要注意的是，此時的三個a是同一個變量，所以三個a的值都有是3， 如果算值的話，此時已經是9. 第三次算第三個值，此時a = 3，再執行++a時，些時a = 4,三個a是同一個變量，所以其實三個a = 4, 答案自然是 4 + 4 + 4 = 12.

++a + ++a + ++a = 9本身没有错，但是这个值并没有保存在a中，a一直都只是在进行自增而已。顺便说一下，那个9其实是保持在一个临时变量中。

不同的编译器输出结果是不一样

不同的编译器输出结果是不一样的，我这边输出是10.

居然还有人考这么无聊的题目。

楼上已给出答案，不要纠结于这些问题，这些都不是这门语言的关键

书上这是扯淡。 一个表达式里有多次++，这属于未定义行为，标准并未强制规定，不同的编译器会得出不同的结果。 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！ 参考：http://blog.csdn.net/qq423399099/article/details/51774359


Question: unsigned int 和int 问题

(ui - 1)的结果是unsigned  int类型，所以肯定不会小于1  楼主是不是应该写成；   int main(void) { 	unsigned ui = 0; 	int a = 0;  	if(0 > (int)(ui - 1)) 		a = 1;  	printf("%d\n",a); 	printf("%u\n",ui-1); }

unsigned int比int"大"  所以ui - 1中的1会转换成unsigned int进行运算，ui-1的结果也是unsigned int永远不会比0小 值 -1 赋值给unsigned int 类型的时候 存储形式为 1111,1111,1111,1111

ui - 1 结果是unsigned int 所以 if里面的条件表达式始终是false

if(0 > int(ui - 1))

if(0 > int(ui - 1))

if(0 > (ui - 1))


Question: unsigned int 和 int 的问题

这涉及到C语言的隐式类型转换哦,我记得C陷阱与缺陷里有讲 ui-1并不是把ui提升到int再去减一,而是把1提升到unsigned int 这样一来结果就是最大的整数了

引用 楼主 Hamber_Bao 的回复: #include <stdio.h>  int main(void) {      unsigned ui = 0;      int a = 0;       if(0 > (ui - 1))               a = 1;       printf("%d\n",a);      printf("%u\n",ui-1); }    输出结果为 0 4294967295   我想问下，为什么a的值没有改变呢？ui  的值为0，0-1等于-1，是小于0的，得执行a=1，输出a 的值应该为1  第二个问题  ui-1的值为什么会是4294967295呢 这个数是怎么得出来的呢       if(0 > (ui - 1)) 如果表达式中同时有int和unsigned，那么在演算表达式时，所有的int会“提升”成unsigned，然后再演算， 那么上述if其实就是：     if (0U > (0U - 1U)) 那么0U - 1U为多少呢？就是4294967295U，这里发生了下溢。 0U > 4294967295U吗？显然false，所以if语句不执行。

if(0 > int(ui - 1))


Question: 我是初学者，找不出这有什么问题，能帮帮忙吗？谢谢

引用 3 楼 user-2 的回复: 我试过了，你编译器有问题，你尝试包含stdio.h这个头文件，我的编译器把你的代码重新编译了一遍，是没有问题的。。  嗯谢谢，加了include可以了，我用的是Visual Studio 2015编译的，现在多了一个问题：就是为什么你不用头文件可以？

-Wall -Wextra 把警告都打开，你就能看到相关警告了。  不包含需要的头文件会有什么问题？ a. 编译出错，例如类型未定义 b. 编译有警告但是可通过，不过运行会出错 c. 编译有警告但可通过，当时运行也没问题，但是换个环境（例如换了编译器，或现有编译器、依赖库升级，或换了操作系统），结果程序就运行出错了。  在你搞不清楚不包含头文件会有什么问题的时候，就老老实实的按照要求包含需要的头文件。

引用 4 楼 hanshulun 的回复:[quote=引用 3 楼 user-2 的回复:]  我试过了，你编译器有问题，你尝试包含stdio.h这个头文件，我的编译器把你的代码重新编译了一遍，是没有问题的。。  嗯谢谢，加了include可以了，我用的是Visual Studio 2015编译的，现在多了一个问题：就是为什么你不用头文件可以？[/quote]  编译器的问题把，，可能你的编译器 要调用printf函数就一定要包含stdio.h头文件，，我的看版主说的很多编译器是默认包含stdio.h和stdlib.h，，，编译器差异就不用管了，，我vc++里数组越界还不报错呢！这个都是没有关系的

引用 1 楼 user-2 的回复:你是不是没有包含头文件stdio，，他说你的printf为外部符号，就应该取不到printf这个函数，你开头用#include<stdio.h>吧这个头文件包含进去，，可能就是这个原因你编译器我没用过，而且是中文的诶，，，编译器还是得看英文的，有助于学习， 正常的vc++编译器该是不包含也可以我记得，但是你试一下嘛，main入口函数前加一个 include<stdio.h>  该就没有问题了


Question: 求一个小程序把用“-”这个符号连接的三部分单独分开，比如A-B-C,分成A B和C,谢谢啦

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

你如果A,B,C的类型固定的话，比如是int的话，直接用sscanf就好  #include<stdio.h> void main() { 	int a, b, c; 	char buffer[32] = "23-45-67"; 	sscanf(buffer, "%d-%d-%d", &a, &b, &c); }

纠正下ret= strtok(NULL, spl);的spl换成"-"

#include <stdio.h> #include <string.h>  int main() {     char* str = "A-B-C";     char *ret= NULL;     ret= strtok(str, “-”);     while( ret!= NULL )     {         printf("%s\n",ret);         ret= strtok(NULL, spl);     }     return 0; } 你试试吧，我没运行，不过应该没问题


Question: 求大神细说一下typedef的理解，表示不太懂

就是以后定义结构体变量时直接用后面那个别名定义声明就好

typedef typedef type-declaration synonym;  The typedef keyword defines a synonym for the specified type-declaration. The identifier in the type-declaration becomes another name for the type, instead of naming an instance of the type. You cannot use the typedef specifier inside a function definition.  A typedef declaration introduces a name that, within its scope, becomes a synonym for the type given by the decl-specifiers portion of the declaration. In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types.  Example  // Example of the typedef keyword typedef unsigned long ulong;  ulong ul;     // Equivalent to "unsigned long ul;"  typedef struct mystructtag {    int   i;    float f;    char  c; } mystruct;  mystruct ms;   // Equivalent to "struct mystructtag ms;"  typedef int (*funcptr)();  // funcptr is synonym for "pointer                            //    to function returning int"  funcptr table[10];   // Equivalent to "int (*table[10])();"

typedef struct stack_node stack_list;表示可以用stack_list替代struct stack_node 如：stack_list a等同于struct stack_node a; typedef stack_list *slink;可以用slink替代stack_list *（注意*是跟着stack_list的） 如：stack_list *a等同于slink a;  http://www.cnblogs.com/afarmer/archive/2011/05/05/2038201.html

typedef给指定类型起一个别名


Question: 毕业设计管理系统还不完善，求大神指点

建议去找百度。

这有点偏，百度不到


Question: 大家好，我想用VS2015编写一个无窗口的C语言程序，请问该怎么创建工程？

你可以将原来Win32 Console程序的main改成上面例子中的WinMain，将其中所有的scanf和printf改为fscanf和fprintf,然后放到Win32 项目（空项目）中。

引用 10 楼 yyxgs 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] #include <windows.h> #include <tchar.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {  MessageBox(NULL,_T("OK"),_T("Test"),MB_OK);//如果没这句，就不会有任何窗口。  return 0; }  请问怎么把这个单独写成一个函数啊？我想在不想有窗口的程序中添加这个函数就行，能不能这样？[/quote] 不能。

引用 8 楼 zhao4zhong1 的回复:#include <windows.h> #include <tchar.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {  MessageBox(NULL,_T("OK"),_T("Test"),MB_OK);//如果没这句，就不会有任何窗口。  return 0; }  请问怎么把这个单独写成一个函数啊？我想在不想有窗口的程序中添加这个函数就行，能不能这样？

引用 8 楼 zhao4zhong1 的回复:#include <windows.h> #include <tchar.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {  MessageBox(NULL,_T("OK"),_T("Test"),MB_OK);//如果没这句，就不会有任何窗口。  return 0; }  赵老师太棒了！谢谢！

引用 6 楼 zhao4zhong1 的回复:Win32 项目    然后我该选哪个呢？

Win32 项目

引用 2 楼 zhao4zhong1 的回复:Windows Application  没有这个选项

引用 1 楼 woshirenjun12 的回复:菜单栏：开始--->文件-->新建项目   选择visual C++里面的win32控制台项目   还是有窗口的

Windows Application


引用 11 楼 Ainew 的回复:[quote=引用 8 楼 CharlesSimonyi 的回复:] 密码控件需要驱动级的键盘模拟，如WinIO、DD虚拟键盘 请问这个驱动的怎么写啊，谢谢[/quote]  简单点，使用现成的winio或dd虚拟键盘就行了 自己去实现一个键盘驱动，太麻烦

引用 8 楼 CharlesSimonyi 的回复:密码控件需要驱动级的键盘模拟，如WinIO、DD虚拟键盘 请问这个驱动的怎么写啊，谢谢

引用 9 楼 songyachao 的回复:[quote=引用 8 楼 CharlesSimonyi 的回复:] 密码控件需要驱动级的键盘模拟，如WinIO、DD虚拟键盘  keybd_event(13,0,0,0); keybd_event(13,0,KEYEVENTF_KEYUP,0); 单个shift键可以控制输入法的状态 为啥组合键 ctr+space 或 ctr+shift 就不能控制了，好奇怪啊         keybd_event(18,0,0,0); 	keybd_event(121,0,0,0); 	keybd_event(121,0,KEYEVENTF_KEYUP,0); 	keybd_event(18,0,KEYEVENTF_KEYUP,0);[/quote] 上面写错了，改为：                         keybd_event(VK_CONTROL,0,0,0); 		        //keybd_event(13, MapVirtualKey(13, 0), 0, 0); 			//keybd_event(13, MapVirtualKey(13, 0), KEYEVENTF_KEYUP, 0); 			keybd_event(VK_SPACE,0,0,0); 			keybd_event(VK_SPACE,0,KEYEVENTF_KEYUP,0); 			keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);

引用 8 楼 CharlesSimonyi 的回复:密码控件需要驱动级的键盘模拟，如WinIO、DD虚拟键盘  keybd_event(13,0,0,0); keybd_event(13,0,KEYEVENTF_KEYUP,0); 单个shift键可以控制输入法的状态 为啥组合键 ctr+space 或 ctr+shift 就不能控制了，好奇怪啊         keybd_event(18,0,0,0); 	keybd_event(121,0,0,0); 	keybd_event(121,0,KEYEVENTF_KEYUP,0); 	keybd_event(18,0,KEYEVENTF_KEYUP,0);

密码控件需要驱动级的键盘模拟，如WinIO、DD虚拟键盘

QQ对类似自动输入做了专门的屏蔽。

请问密码区域支持keybd_event 吗，我 模拟 123456\t123456 在QQ上尝试，结果账号区输入123456光标移动到密码区域后没什么反应了，请问是不支持还是我的想法本来就不行

键码表：https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

输入中文用SendInput方便点，SendInput是keybd_event的升级版。  #include <windows.h> #include <iostream> using namespace std;  void InputString(const wchar_t *str) { 	int words_num = wcslen(str); 	KEYBDINPUT *keyinput = new KEYBDINPUT[words_num]; 	memset(keyinput, 0, words_num * sizeof(KEYBDINPUT)); 	for (int i = 0; i < words_num; i++) 	{ 		keyinput[i].wScan = str[i]; 		keyinput[i].dwFlags = KEYEVENTF_UNICODE; 	} 	INPUT *input = new INPUT[words_num]; 	for (int i = 0; i < words_num; i++) 	{ 		input[i].type = INPUT_KEYBOARD; 		input[i].ki = keyinput[i]; 	} 	SendInput(words_num, input, sizeof(INPUT)); 	delete[] input; 	delete[] keyinput; }  void main() { 	::Sleep(3000); 	InputString(L"你好，我是小明"); }

KeyNote keyboard_NUM[]={ 	{0, 96, ZERO}, {1, 97, ZERO}, 	{2, 98, ZERO}, {3, 99, ZERO}, 	{4, 100, ZERO},{5, 101, ZERO}, 	{6, 102, ZERO},{7, 103, ZERO}, 	{8, 104, ZERO},{9, 105, ZERO} }; void CMainFrame::decodeGBK( unsigned char* data_word) { 	unsigned short datavalue=((data_word[0] << 8) | data_word[1]); 	char numstr[10]; 	int numL,i,report_i; 	unsigned char report[8] = {0}; 	report_i=0; 	numL=sprintf(numstr,"%d",datavalue);  	keybd_event(18,0,0,0); 	for(i=0;i<numL;i++) 	{ 		keybd_event(keyboard_NUM[numstr[i] - '0'].kvalue,0,0,0); 		 		keybd_event(keyboard_NUM[numstr[i] - '0'].kvalue,0,KEYEVENTF_KEYUP,0); 	} 	keybd_event(18,0, KEYEVENTF_KEYUP,0);    } 请问两位我这样输入一个中文的时候怎么没反应那，例如“我”字我调试得到的是对应的52946，好像ALT组合键没起作用，请问是我的写法不对吗

http://baike.baidu.com/link?url=zt_1cauNfVDN3GUrqPfk-j7xgVU5-Gp2YMUzpB9A-8flJPCdp1uGZVdF7WqtlbZfFgxfIDQeGcQzZ63N1oLfK_   那些括号里面不也有!

在MSDN里面搜“Key Scan Codes”


Question: 求助！！！有关栈的应用

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


Question: vs2013 栈发生错误

你为啥要将函数内部声明的变量名起的和函数参数变量名一样呢？

引用 12 楼 codesnail 的回复:[quote=引用 10 楼 codesnail 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 重建所有 ？  试过了，release和debug都试过了，都不行。[/quote] 各位老总，还有一个现象，就单步执行刚进这个函数时候，这个唯一的参数时一个值，然后单步执行一步，这一步是函数内的变量声明，这个参数就编程另外一个值了。。。[/quote] 然后再次在函数内单步执行，这个参数的值就不变了，一直是一个特定的错误值。

引用 11 楼 qq423399099 的回复:hmi_axis_init这个函数的参数类型是？ unsigned int的， 我函数调用改成 hmi_axis_init(0u);问题依旧

引用 10 楼 codesnail 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 重建所有 ？  试过了，release和debug都试过了，都不行。[/quote] 各位老总，还有一个现象，就单步执行刚进这个函数时候，这个唯一的参数时一个值，然后单步执行一步，这一步是函数内的变量声明，这个参数就编程另外一个值了。。。

引用 8 楼 zhao4zhong1 的回复:重建所有 ？  试过了，release和debug都试过了，都不行。

hmi_axis_init(0) 进去之后，这个唯一的参数就是一个很大的值，不是0

重建所有 ？

引用 6 楼 qq423399099 的回复:[quote=引用 4楼我是你的主体 的回复:][quote=引用 2 楼 qq423399099 的回复:] 建议贴出代码 无法贴出，实在太多。。。[/quote]你少贴点呗： 1.调用处代码 2.函数形参的类型（如果是结构体，那就贴一下结构体）[/quote]   int main(void) { 	int result = 0;     KEY_TYPE key = KEY_NULL;     static unsigned int plc_send_sta = 0;     unsigned int send_sta = 0;     unsigned int init_process_bar_pos = 0;      hmi_axis_init(0);

引用 4楼我是你的主体 的回复:[quote=引用 2 楼 qq423399099 的回复:] 建议贴出代码 无法贴出，实在太多。。。[/quote]你少贴点呗： 1.调用处代码 2.函数形参的类型（如果是结构体，那就贴一下结构体）

引用 1 楼 zhao4zhong1 的回复:调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx 我尝试换别的调用方式问题依旧。。。。

引用 2 楼 qq423399099 的回复:建议贴出代码 无法贴出，实在太多。。。

引用 楼主 codesnail 的回复:各位大侠：      我遇到一个问题，就是所有的函数传递参数都发生错误，比如 func(0);  到函数里面这个参数就变为一个随机值，比如2456783.。。  跪谢。！！  好久没上csdn，就这么多分了，见谅。  感谢赵总回复，我想应该不是这个问题，我是突然出现这个问题，工程有30万行代码

建议贴出代码


Question: 关于 && 问题

引用 5 楼 yang004 的回复:[quote=引用 4 楼 qq_34607669 的回复:] 在VS 2010中     printf("|%03D|");输出结果是  |D|   而在 Linux下用gcc编译结果是  |%03D|  也就是原样输出又是为什么呢？ D改为d[/quote]我的意思是问为什么在两个环境中有不同的结果？

结果是true &&操作符运算结果只有true和false  true的宏定义是1 false的宏定义是0

引用 4 楼 qq_34607669 的回复:在VS 2010中     printf("|%03D|");输出结果是  |D|   而在 Linux下用gcc编译结果是  |%03D|  也就是原样输出又是为什么呢？ D改为d

结果是：1 a+b=3 b-c=-1 3&&-1=1 逻辑与&&，当两个数都非0的时候为真

对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

1,&&逻辑判断,两都是是真就为1.


Question: IO按字节采集，怎么按位提取？

循环移位 判断1  0

2个字节天然就对应16位，还需要转化什么？

这个要看用什么CPU了,CPU够快也行.对AD采集卡不了解,按字面意思不是采集模拟量吗?开关应该是个数字量吧?

16路波形

开关量，采集到的是脉冲序列。宽窄不一。16路脉冲序列

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

采集模拟量？


Question: linux read

The following example reads data from the file associated with the file descriptor fd into the buffer pointed to by buf.     #include <sys/types.h> #include <unistd.h> ... char buf[20]; size_t nbytes; ssize_t bytes_read; int fd; ... nbytes = sizeof(buf); bytes_read = read(fd, buf, nbytes); ...  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: 哈夫曼树的代码

根据编译器提示的错误一个个改。 比如第一个错误：你使用了引用（C语言里是没有引用的） 对于自己看不懂的错误可以拿去搜一下。

忘了讲，这是Dev c++编写的，是.cpp文件，用C语言运行好多报错的。。。有木有人呐。。。

强势围观


Question: 谁有jpg文件格式说明文档，分享下。

谢谢，

百度一下更容易得到，http://wenku.baidu.com/link?url=zYkqxKu7NpSOJJ3UiwYuZR5bvM9CF-H-zopXf3T3T555RXghMWqNbXenZFJf25XXwGaW9XHmVQEFLzzmkZRNFbtxe0snmlZmt-2Vd2syQQi


Question: 大神们进来看看是哪出错了

一眼扫过去，第10行的j都没有初始化，就用了，好大胆啊，23行的j可以取到4吗，

看一下能实现不？  #include <stdio.h>  int main() { 	int a[3][4] = {}; 	int i = 0, j = 0; 	 	for ( i = 0; i < 3; i++) { 		j = 0; 		printf("please input the name of %d student:\n", i+1); 		scanf("%d", &a[i][j]); 		 		for (j = 1; j < 4; j++) { 			printf("please input the score of %d subject for the %d student :\n", j,i+1); 			scanf("%d", &a[i][j]); 		} 		 	} 	 	for (i = 0; i < 3; i++) { 		int sum = 0; 		for (j = 1; j < 4; j++) { 			sum += a[i][j]; 		} 		 		printf("The total score of %d student is %d\n", i+1, sum); 			 	} }

引用 4 楼 qq423399099 的回复:不要截图，直接贴代码。 发现几个问题： 1.你输入学号的时候，第一次你的j没有初始化过，所以会越界，之后你的j每次都是4，也越界 2.第23行你j从1循环4，a[i][4]也会造成越界 对！ 23行j<5应改为j<4  “多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

2楼不对。  应该是：  将第10行的j改为0 将第12行的j=0改为j=1

将12、13行挪到第8行。

定义了一个三行四列的二维数组 用循环来输入它们的学号和成绩 然后在用循环吧学号 成绩 总分 名次打印出来


Question: turbo c3.0 64位 使用求助

学习了  HAHAHAHAHAH

tc3有64位版本？？

Alt - F5可以吗？

计算下列EDLIN.COM多少岁？ D:\DOS>dir edlin.com  驱动器 D 中的卷是 Q_HD2_8  卷的序列号是 54FC-A4FD   D:\DOS 的目录  1998-12-24  18:16           164,450 EDLIN.COM                1 个文件        164,450 字节                0 个目录 17,854,615,552 可用字节

这个软件都快30岁了 装个DOSBOX，在DOSBOX中运行tc3


Question: C语言程序停止工作

稍微调试下发现：answer[lenc + 1] = '\0';这句越界了 char answer[] = "0";你这样的写法表示answer数组长度只有1（一个字符'0'外加一个自动补上的'\0'） PS :count同理 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

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


Question: 初学者遇到了一个不理解的问题。

有些打印信息，不一定要printf的，比如av_log(......);（这是ffmpeg内的一些东西）照样能打印许多信息的，其内也不是直接调用printf的，搞不清他是如何打印的，但确实能打出来的

我这个原因大概是什么方面的原因造成的呢？我写的程序为什么会自动输出这些东西啊，我一句打印的语句都没写？

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

在linux下面开发程序的吧？你先安装中文语言包吧。装好了就不会有乱码了。


Question: style of function definition is now obsolete 求助

问题已经解决,谢谢大虾,两个max函数的参数都要制定类型.

谢谢:qq423399099  目前警告warning:style of function definition is now obsolete        还是存在 同时我运行程序时,遇到错误:undefined symbol max(int,int) in module text_max.cpp  我已经按照你指出的错误修改了.但还是面临上面的错误.

三处错误： 1.int max(a, b);应该是int max(int a, int b); 2.int max(a,b)应该是int max(int a, int b) 3.esle应该是else  #include<stdio.h>  int max(int a, int b);  void main() { 	int x, y, z; 	printf("input two numbers \n"); 	scanf("%d,%d", &x, &y); 	z = max(x, y); 	printf("maxnum is :%d", z); }  int max(int a, int b) { 	if (a>b) 		return a; 	else 		return b; }   PS：scanf("%d,%d", &x, &y);这样的写法输入的时候要注意两个数之间要用逗号分隔

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


Question: 有那位大神可以教教我这个编程的题目，在线等，实在是毫无思路

引用 5 楼 a18729562128 的回复:怎么说呢，我才大一才学C语言，学校要我们编一个这个，然后就是没有思路，我觉得这个得用数据库的知识，但是我们还没有学这个，那我应该怎么办呢  存文件里。 用fprintf 和fscanf 来写/读。

仅供参考： 从C语言的菜单界面管理系统到C++ Builder的图形用户界面，一个简单的电话簿Demo例子   http://blog.163.com/tab_98/blog/static/1192409720158673337998/

网上找找信息管理系统，主要就是一个数据库设计和数据库的增删改查功能，加上界面就行了

https://www.baidu.com/s?wd=C源代码%20学生公寓门卫管理系统  里面挺多内容符合楼主需要啊。

我之前也是在网上找了关于这个的，但是没找到，有没有和这个相关的我也可以改改

在百度搜“C源代码 学生公寓门卫管理系统”


Question: C语言  动态执行函数 求教!

可以遍历目录下所有文件，然后再依次执行

可以写一个脚本，把所有的demo的可执行文件都编译出来，执行脚本的时候传入参数，根据参数执行相关demo的可执行文件。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！

把这些函数放到一个动态库里面，LoadLibrary加载这个库，接收函数名，通过GetProcAddress函数获取函数地址，然后调用

system函数


Question: 万能的大神们 帮忙改错下这题

引用 2楼user-2 的回复:请问下，这个函数是干嘛用的，输出的m值有什么意义。统计子串的个数. 比如你输入： aaaasdsdf sd 输出: 2 表示：字符串"aaaasdsdf"中，包含两个子串"sd"

请问下，这个函数是干嘛用的，输出的m值有什么意义。

if (r == '\0')应该是if (*r == '\0') 你这个仅仅只是统计子串的个数，而不是位置对吧？  #include  <conio.h> #include  <stdio.h> #include  <string.h> int fun(char *s, char *t) { 	int n;   char *p, *r; 	n = 0; 	while (*s) 	{ 		p = s;   r = t; 		while (*r) 		if (*r == *p) 		{ 			r++; 			p++; 		} 		else 			break; 		if (*r == '\0') 			n++; 		s++; 	} 	return  n; } void main() { 	char s[100], t[100];   int m; 	//clrscr(); 	printf("\nPlease enter string S:"); 	scanf("%s", s); 	printf("\nPlease enter substring t:"); 	scanf("%s", t); 	m = fun(s, t); 	printf("\nThe result is : m = %d\n", m); }  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 哈夫曼树编码

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


Question: 谁帮我看看这语音识别的代码能通过，但无法运行！

检查错误码....运行期错误就要这么干


Question: 求大神用c语言改一下这个日程管理系统的代码谢谢了

呃。。。。。突然感觉怪怪的，我快写完了的，跟你这个很不一样，你别担心。。。。。。

哈哈哈哈，我挑的题目也是这个，莫不是校友来着

治大国如烹小鲜； 调程序似雕玉器。

调试的过程跟破案差不多, 其实也很有乐趣

#include<stdio.h> #include<stdlib.h> #include<string.h> //#include <conio.h> #include <time.h>  typedef struct User {     char Name[20];     char Pass[7]; }User;  typedef struct Date {     int Year;     int Month;     int Day; }Date;  typedef struct Data {     int No;     int Count;     char Name[20];     Date Time;     char Info[401];     struct Data *Next; }Data;   int Enroll(); Data *Creat(); void Clock(); int See(); int Add(); void Browse(Data *Head, int count); int Delete(); void Menu(); int Login(); int Mode(int slec, char Name[]);  int main() {     FILE *fp;     int slec;     int Run=1;      char New[20]="Admin",Key[20]="admin";      if (fopen("Users.list","rb") == NULL)     {         printf("初始化...");         fp = fopen("Users.list","wb");          printf("内置账户：%s，长度：%u\n", New, strlen(New));         fwrite(New, 20, 1, fp);         printf("初始密码：%s，长度：%u\n", Key, strlen(Key));         fwrite(Key, 20, 1, fp);          fclose(fp);         printf("完成！\n");     }      while (Run)     {         printf("====================欢迎使用日程管理系统！======================\n");         printf("                    请选择 1.注册 2.登录   ");         scanf("%d",&slec);          if (slec==1)             Run = Enroll();         else if (slec==2)             Run = Login();         else printf("该功能尚未开发。\n");     }     return 0; }  int Enroll() {     FILE *fp;     char Name[20],New[20],Key[20];      getchar();     fp=fopen("Users.list","rb+");     if (fp == NULL) {         printf("文件打开失败！\n");         return 1;     }      printf("请输入要新建的用户名（至多19个字符）：");     fgets(New, 20, stdin);     New[strlen(New)-1]='\0';      while(1)     {         if(fread(Name,20,1,fp) != 1)             break;         if (strcmp(New, Name) == 0)         {             printf("用户名已存在！请重新创建...\n" );             fclose(fp);             return 1;         }         fread(Key,20,1,fp);     }     printf("请输入密码：（至多19个字符）");     fgets(Key,20,stdin);     Key[strlen(Key)-1]='\0';      fwrite(New,20,1,fp);     fwrite(Key,20,1,fp);     printf("创建完成，请重新登录！\n");     fclose(fp);      return 1; }  void Clock() {     time_t t;     struct tm *tp;      t=time(NULL);     tp=localtime(&t);     printf("当前本机时间为     ");     printf("%d:%d:%d\n ",tp->tm_hour,tp->tm_min,tp->tm_sec);     printf("%d年%d月%d日 ",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday);     printf("今天是本周第%d天，今年的第%d天\n ",tp->tm_wday,tp->tm_yday); }  Data *Creat(Data *Last, Data node) {     Data *New=NULL;      New=(Data*)malloc(sizeof(Data));     if (New == NULL)     {         printf("内存分配失败！\n");         return NULL;     }     Last = New;      Clock();      printf("请输入日程时间（格式：年.月.日）");     scanf("%d.%d.%d",&New->Time.Year,&New->Time.Month,&New->Time.Day);     getchar();      printf("请输入日程内容：(至多400字符)\n");     fgets(New->Info, 400, stdin);     //New->Info[400]='\0'; //not need     New->Next=NULL;      return Last; }  int Add(char Name[20]) {     FILE *fp;     Data New;      fp=fopen("Users.list","rb+");     if (fp == NULL)    {printf("文件打开失败！\n");    return 1;}      Clock();     printf("请输入日程时间（格式：年.月.日）");     scanf("%d.%d.%d",&New.Time.Year,&New.Time.Month,&New.Time.Day);     getchar();      printf("请输入日程内容：(至多400字符)\n  ");     fgets(New.Info,400,stdin);     //New.Info[400]='\0'; /* not need */      fwrite(&New.Time.Year,sizeof(int),1,fp);     fwrite(&New.Time.Month,sizeof(int),1,fp);     fwrite(&New.Time.Day,sizeof(int),1,fp);     fwrite(New.Info,401,1,fp);      return 1; }  int Mode(int slec, char Name[20]) {     FILE *fp;     Data *New=NULL,*Temp=NULL,*Head=NULL;     int count=0;      fp=fopen(Name,"rb+");     if (fp == NULL)    {printf("文件打开失败！\n");    return 1;}      while(1)     {          New=(Data*)malloc(sizeof(Data));         if (New == NULL)         {             printf("内存分配失败！\n");             return 1;         }         if (Head == NULL)    {Head=New;Temp=New;}                       printf("ready!\n");          if(fread(&New->Time.Year,sizeof(int),1,fp) != 1)    break;       printf("start!\n");         fread(&New->Time.Month,sizeof(int),1,fp);         fread(&New->Time.Day,sizeof(int),1,fp);         fread(New->Info,401,1,fp);    New->Next=NULL;         New->Count=(++count);                                             printf("over!\n");          printf("序号%d 日期%d.%d.%d", Head->Count,                 New->Time.Year, New->Time.Month, New->Time.Day);         puts(New->Info);           Temp=New;     }      if (slec==3)    Browse(Head,count);     fclose(fp);     return 1; }  void Menu(char Name[20]) {     int Run=1;     int slec;     FILE *fp;      printf("===========================登录成功=============================\n");     if (fopen(Name,"rb") == NULL)     {         printf("您是新用户，来创建您的第一个日程！\n");         fp = fopen(Name, "wb");         fclose(fp);         Run = Add(Name);     }      while (Run)     {         printf("================================================================\n");         printf("已登录为%s\n",Name);         printf("================================================================\n");         printf("                         1.新建日程\n");         printf("                         2.查看当前日程\n");         printf("                         3.浏览所有日程\n");         printf("                         4.删除日程\n");         printf("                         5.退出登录\n");         printf("                         请选择相应序号： ");          scanf("%d", &slec);          if  (slec == 1)             Add(Name);         else if (slec>=2 && slec<=4)    Run=Mode(slec,Name);         else if (slec==5)    break;         else printf("该功能尚未开发。\n");     } }  int Login() {     FILE *fp;     int Run=0;     char Name[20],Pass[20],New[20],Key[20];      getchar();     fp=fopen("Users.list","rb+");     if (fp == NULL)    {printf("文件打开失败！\n");    return 1;}      printf("请输入用户名：");     gets(New);      printf("Input name: %s\n", New);     while(1)     {         if(fread(Name,20,1,fp) != 1)             break;         puts(Name);         fread(Pass,20,1,fp);         if (strcmp(New, Name) == 0) {             Run = 1;             break;         }     }     fclose(fp);      if (Run == 1)     {         printf("请输入密码：");         gets(Key);         if (strcmp(Key,Pass) != 0)             printf("密码错误！\n");         else         {             Menu(Name);             printf("已退出登录！three\n");         }     }     else         printf("用户不存在！\n");      return 1; }  void Browse(Data *Head, int count) {     printf("以下为您的所有日程，共%d条：\n", count);     while(count--)     {         printf("序号%d 日期%d.%d.%d", Head->Count,                 Head->Time.Year, Head->Time.Month, Head->Time.Day);         puts(Head->Info);         Head = Head->Next;     } }  改了一部分你的程序，目前登录和注册没问题了。 日程管理部分，逻辑本身有问题，不好改。日程链表没有调用，自然也无法查询和删除日志节点。建议将创建日程链表和保存文件分开，先创建好日程链表，然后单独一个功能（在menu菜单里加一项保存文件）用于保存文件。

建议一个用户一个用户文件，先得到目录下文件名，在判断输入用户名与文件名是否重复 system("dir /b >>direct.txt"); 再用fgets逐行读取direct.txt。

楼主解决了吗？

这是要求   现在的问题是 大体成功了但是 建立的日程之后 运行时出了问题 并且注册的时候 不能判断用户名重复