Question: 求助，结构体数组存储到文件夹中，出现问题的原因

引用 楼主 liu20682402 的回复:#include<stdio.h> #include<string.h> #include<stdlib.h> # define SIZE # define LEN sizeof(struct flight)  struct flight           //结构体 {     char number[20];    //航班号     char start[20];     //起点     char end[20];       //终点     char sche[20];      //航班期     char time1[20];     //出发时间     char time2[20];     //到达时间     char model[20];     //机型     int price;          //价格 }stu[SIZE];   //定义结构体数组，存储多个航班的记录    void main() {     ad_select(); }   void ad_select() //管理员界面 {     int m;     printf("\t\t\t**************************************\n");     printf("\t\t\t     *  后台管理员航班信息操作平台  * \n");     printf("\t\t\t     *     1.航班信息的输入         * \n");     printf("\t\t\t     *     2.航班信息的显示         * \n");     printf("\t\t\t     *     3.航班信息的保存         * \n");     printf("\t\t\t     *     4.航班信息的删除         * \n");     printf("\t\t\t     *     0.操作平台的退出         * \n");     printf("\t\t\t**************************************\n");     printf("\n\n");     printf("\n输入选择(0~4):\n");     scanf("%d",&m);     switch(m)           {               case 1:input();//输入信息                      break;               case 2:display(); //显示信息                      break;               case 3:save(); //保存信息                      break;               case 4:cancel();//删除信息                      break;               case 0:us_select();//退出操作平台，进入用户界面                      break;           } }    void input() {     FILE*fp;     int i,j,k;     SIZE k;     printf("将要输入的航班信息的数据个数：");     scanf("%d",&j);     for(i=0;i<k;i++)     {         printf("输入航班的航班号:");         scanf("%s",stu[i].number);         printf("输入航班的起点站站名:");         scanf("%s",stu[i].start);         printf("输入航班的终点站站名:");         scanf("%s",stu[i].end);         printf("输入航班的航班期:");         scanf("%s",stu[i].sche);         printf("输入航班的出发时间:");         scanf("%s",stu[i].time1);         printf("输入航班的到达时间:");         scanf("%s",stu[i].time2);         printf("输入航班的机型:");         scanf("%s",stu[i].model);         printf("输入航班的价格:");         scanf("%s",stu[i].price);      }     if((fp=fopen("flight1 message.txt","wb"))==NULL)     {         printf("文件无法打开！\n");         getchar();         getchar();         ad_select();     }     for(i=0;i<k;i++)     if(fwrite(&stu[i],LEN,1,fp)!=1)     printf("写入文件失败\n");     fclose(fp);  }   void display() {     FILE*fp;     int i,n;     if((fp=fopen("flight1 message.txt","rb"))==NULL)     {         printf("信息为空,请按回车键返回主菜单！\n");         getchar();         getchar();         ad_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     for(i=0;i<n;i++)     fread(&stu[i],LEN,1,fp);     fclose(fp);     printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n");     for(i=0;i<n;i++)     printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price); }    void save() {     int i,j,n;     FILE*fp;     struct flight s;     printf("输入航班的航班号:");     scanf("%s",s.number);     printf("输入航班的起点站站名:");     scanf("%s",s.start);     printf("输入航班的终点站站名:");     scanf("%s",s.end);     printf("输入航班的航班期:");     scanf("%s",s.sche);     printf("输入航班的出发时间:");     scanf("%s",s.time1);     printf("输入航班的到达时间:");     scanf("%s",s.time2);     printf("输入航班的机型:");     scanf("%s",s.model);     printf("输入航班的价格:");     scanf("%s",s.price);     if((fp=fopen("fligth1 message.txt","rb"))==NULL)     {        printf("\n文件无法打开！\n");        getchar();        getchar();        ad_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     for(i=0;i<n;i++)     fread(&stu[i],sizeof(struct flight),1,fp);     fclose(fp);     strcpy(stu[n].number,s.number);     strcpy(stu[n].start,s.start);     strcpy(stu[n].end,s.end);     strcpy(stu[n].sche,s.sche);     strcpy(stu[n].time1,s.time1);     strcpy(stu[n].time2,s.time2);     strcpy(stu[n].model,s.model);     strcpy(stu[n].price,s.price);     n=n+1;     printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n\n");     fp=fopen("fligth1 message.txt","wb");     for(i=0;i<n;i++)     {         fwrite(&stu[i],sizeof(struct flight),1,fp);         printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price);     }     fclose(fp); }    void cancel() {     FILE*fp;     int i,j,n,flag;     char number[10];     if((fp=fopen("flight1 message.txt","rb"))==NULL)     {         printf("\n文件无法打开！\n");         getchar();         getchar();         ad_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     printf("\n输入你将要删除的航班号:");     scanf("%s",number);     for(flag=1,i=0;i<n;i++)     {         if(strcmp(number,stu[i].number)==0)         {             for(j=i;j<n-1;j++)             {                 strcpy(stu[j].number,stu[j+1].number);                 strcpy(stu[j].start,stu[j+1].start);                 strcpy(stu[j].end,stu[j+1].end);                 strcpy(stu[j].sche,stu[j+1].sche);                 strcpy(stu[j].time1,stu[j+1].time1);                 strcpy(stu[j].time2,stu[j+1].time2);                 strcpy(stu[j].model,stu[j+1].model);                 strcpy(stu[j].price,stu[j+1].price);             }             flag=0;             n=n-1;         }      }      printf("\n所有航班号的信息为:\n");      fp=fopen("flight1 message.txt","wb");      for(i=0;i<n;i++)      fwrite(&stu[i],LEN,1,fp);      fclose(fp);      fp=fopen("flight1 message.txt","rb");      printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n\n");      for(i=0;fread(&stu[i],LEN,1,fp)!=0;i++)      printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price);      if(flag)      printf("\n将要删除的航班号不存在！\n");      fclose(fp); }        void us_select()//用户界面 {     int b;     printf("\t\t\t**************************************\n");     printf("\t\t\t     *  航班信息查询与检索系统  *     \n");     printf("\t\t\t     *     1.按航班号查询       *     \n");     printf("\t\t\t     *     2.按起点站查询       *     \n");     printf("\t\t\t     *     3.按终点站查询       *     \n");     printf("\t\t\t     *     4.用户帮助说明       *     \n");     printf("\t\t\t     *     0.退出系统           *     \n");     printf("\t\t\t**************************************\n");     printf("\n请输入您的选择(0~4):\n");     scanf("%d",&b);     switch(b)     {         case 1:sea_number();break;         case 2:sea_start();break;         case 3:sea_end();break;         case 4:help();break;         case 0:         printf("谢谢您的使用！");         exit(0);         default:printf("输入错误，请重新输入（输入范围为0~4）\n");break;     }  }   void sea_number() {     FILE*fp;     int i,flag,n;     char number[10];     if((fp=fopen("fligth1 message.txt","rb"))==NULL)     {         printf("文件无法打开！\n");         getchar();         getchar();         us_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     for(i=0;i<n;i++)     fread(&stu[i],LEN,1,fp);     fclose(fp);     printf("\n您将要查找的航班号:");     scanf("%s",number);     for(flag=0,i=0;i<n;i++)     {         if(strcmp(number,stu[i].number)==0)         {             printf("\n您想要查找的信息为\n:");             printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n");             printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price);             flag=1;         }      }      if(flag!=1)      printf("您所要查找的信息不存在！\n");      printf("航班所有信息如下：\n");      display(); }    void sea_start() {     FILE*fp;     int i,flag,n;     char start[10];     if((fp=fopen("fligth1 message.txt","rb"))==NULL)     {         printf("文件无法打开！\n");         getchar();         getchar();         us_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     for(i=0;i<n;i++)     fread(&stu[i],LEN,1,fp);     fclose(fp);     printf("\n您将要查找的起点站:");     scanf("%s",start);     for(flag=0,i=0;i<n;i++)     {         if(strcmp(start,stu[i].start)==0)         {             printf("\n您想要查找的信息为\n:");             printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n");             printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price);             flag=1;         }      }      if(flag!=1)      printf("您所要查找的信息不存在！\n");      printf("航班所有信息如下：\n");      display(); }     void sea_end() {     FILE*fp;     int i,flag,n;     char end[10];     if((fp=fopen("fligth1 message.txt","rb"))==NULL)     {         printf("文件无法打开！\n");         getchar();         getchar();         us_select();     }     for(i=0;fread(&stu[i],LEN,1,fp)!=0;)     i++;     n=i;     for(i=0;i<n;i++)     fread(&stu[i],LEN,1,fp);     fclose(fp);     printf("\n您将要查找的终点站:");     scanf("%s",end);     for(flag=0,i=0;i<n;i++)     {         if(strcmp(end,stu[i].end)==0)         {             printf("\n您想要查找的信息为\n:");             printf("航班号\t起点站\t终点站\t航班期\t出发时间\t到达时间\t机型\t价格\n");             printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\n",stu[i].number,stu[i].start,stu[i].end,stu[i].sche,stu[i].time1,stu[i].time2,stu[i].model,stu[i].price);             flag=1;         }      }      if(flag!=1)      printf("您所要查找的信息不存在！\n");      printf("航班所有信息如下：\n");      display(); }    void help() {      printf("\t该系统只能查找和显示已经具有的航班信息，用户不可对其进行更改。\n");      printf("\t\t请用户按根据自己的要求输入自己的选择\n"); }          SIZE是多大。。。。

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

有一个致命错误 # define SIZE  SIZE 没有值 那么 stu[SIZE];   //定义结构体数组，存储多个航班的记录 这是无效的。


Question: Matlab中的结果显示位数更改

百度随便搜一下，应该能找到答案。

我已经找到了，谢谢您的回答，还望以后多多帮助。

试试在你窗口的右上角“搜索文档”输入框中输入“数据格式”，回车，在弹出的联机帮助中寻找答案。

百度上都是这个答案'file-> preference->command window->text display->numeric format，我知道这个没错，可是我的matlab不是这个版本的，而是这个


Question: c语言

谢谢大家

写完这个程序，朕要觉觉了。明天还要上班，嘎嘎~~ # include <stdio.h>  int main (int argc, char * argv []) {     while (argc --)         printf ("argv [%d] is '%s'\n", argc, argv [argc]); }

程序的运行参数 argc参数个数 argv[0]指向程序绝对路径名，argv[1...argc - 1]是传递的参数，argv[argc] = NULL

同意楼上的。

main函数的第一个参数argc就是命令行参数个数，也就是第二个参数argv数组元素个数。而argv[0]是命令行的程序名。


Question: 菜鸟

处女贴留给你了，我也是新手，多多学习。

单片机如果自学的话就单片机原理及应用吧， 感觉随便一个都可以，讲的差不多。不过首先你要看微机原理及应用 ，这个是基础。还有c语言当然编程要会。没有基础就从基础开始学就行了 ，书多的是。

到底是学单片机还是C语言啊

主要看楼主将来用什么芯片了 51看这本可以 其他芯片的话就要找和芯片对应的书了


Question: 菜鸟求问C语言命令行参数?

return之前加上system("pause");

引用 3 楼 likfeng 的回复:[quote=引用 1 楼 user-6 的回复:] return前一句加上:getchar(); 需要带参数运行，比如 xxx.exe help[/quote]  应该就是这么回事。。

引用 1 楼 user-6 的回复:return前一句加上:getchar(); 需要带参数运行，比如 xxx.exe help

你传了几个参数啊， 在启动应用程序的瞬间传参数。

return前一句加上:getchar();


Question: 求各位大神帮忙软盘的问题

搜读写FAT16格式文件系统的相关开源项目参考之。


Question: C程序：写字符至磁盘文件出现内存越界，实在检查不出问题所在，望有心人提点一下

多谢，问题解决了。原来就是这里的问题

多谢一根烂笔头，我再去检查下。写此程序初衷是针对某个特定的问题，故严格控制了fp1文件的大小。

while(EOF!=(current=getc(fp1))) { if(current=='\n') { buffer[i][j] = '\0'; i++; j = 0; } else { buffer[i][j] = current; j++; } }  此循环可能导致数组越界


Question: 自定义类型的输出

解决方法： 1.宏+条件编译 2.定义输出函数 3.转向面向对象语言，对自定义类型重载运算符>>和<<

楼上的大神，小生受教了，谢谢大家啊

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //   十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

我就想不明白了，你既然定义了是 int，那为什么要输出 char 呢？不是难为自己吗

引用 22 楼 zhao4zhong1 的回复:[quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 zhao4zhong1 的回复:] 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~[/quote] [/quote]  我一贯是反对赵老湿的，今天突然宣布支持赵老师， 反观赵老湿，突然遭到表扬，还有点小小的不适应哈，嘎嘎~~

引用 20 楼 sholber 的回复:[quote=引用 19 楼 zhao4zhong1 的回复:] 操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~[/quote]

引用 19 楼 zhao4zhong1 的回复:操作符重载是语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。 我正式宣布， 支持赵老湿！！！嘎嘎~~

引用 17 楼 lincolnandlinda 的回复:[quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 lincolnandlinda 的回复:] 用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了…… [/quote] 受教了.但是有个问题: 如果用户把ElementType定义为一个自定义的结构体,或者增加一种新的类型,  那这需要修改宏的定义是不是?  [/quote] 对。 不过不是修改宏，是修改泛型选择表达式。它是可以扩充的嘛。

引用 16 楼 sholber 的回复:[quote=引用 15 楼 lincolnandlinda 的回复:] 用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了…… [/quote] 受教了.但是有个问题: 如果用户把ElementType定义为一个自定义的结构体,或者增加一种新的类型,  那这需要修改宏的定义是不是?

引用 15 楼 lincolnandlinda 的回复:用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.  本来懒得发言的，既然你这么说，我就来抬个杠。 实际上，C解决这个问题一点问题都没有，因为C11引入了泛型。以下是我的方案，嘎嘎~ # include <stdio.h>  typedef float Elemtype; # define print(x) printf ( \                     _Generic (x, \                        char : "%c\n", \                        int : "%d\n", \                        float : "%f\n" \                        ), x)  int main (void) {     Elemtype x = 2.0f;     print (x);      char c = 'x';     print (c);      int i = 10010;     print (i);      print (10086); }  是不是很有意思啊？嘎嘎~~我是用CLANG编译的。VS就不要做梦了……

用C语言是没法解决这个问题的, 通过C++的操作符重载可以实现.

我感觉一般用到这种typedef的，，基本都是接口里，一般都是写好几个仅供使用的函数直接用的，所以在具体的调用接口的程序里，输出的话，单独写个输出的函数，然后在改接口里的typedef定义的类型的时候，直接改输出函数里的格式控制符就好了。个人愚见，说的不好的话，，请喷！

楼主是不会学会了printf就可以包打天下了？就没有别的要学的了吗？知道sprintf不？

typedef int Elemtype; Elemtype作了int的别名，就不能再作char的别名~~~

感觉C语言不好去实现，用类吧。

引用 3 楼 kuangbao9 的回复:楼主是不是想要下面的这种呀？用cout就可以了。 #include<iostream> using namespace std; int main() { 	typedef int Elemtype; 	Elemtype a; 	cout<<a<<endl; 	return 0; }  这里讨论的是C语言，不是C++。 typedef会为已有的类型名取一个别名，这么干的唯一好处是，当类型发生变化时，只修改typedef 这一句即可，

自己写一个输出函数呗

typedef  只是给int起了一个别名， 本质还是int， printf("%d\n", i);


Question: 是fscanf的问题还是我的编译器的问题！

引用 7 楼 gqjjqg 的回复:输入文件里的内容超过缓冲区大小了吧。  不知道啊，，反复注释了几次后来成功了，如果是缓冲区的问题是用setvbuf这个函数吗，，这个函数一直不知道用在什么地方啊。。

输入文件里的内容超过缓冲区大小了吧。

引用 5 楼 hnwyllmm 的回复:测试了一下，运行的挺好，不过我没有VC6，用的GCC编译器，在Linux上执行的 int main(void) {     typedef struct word     {         char word[20];         int count;     }Item;//将这个结构体的名字换成Item     Item item;//定义个结构体变量     FILE * fp;     if ((fp = fopen("1.txt", "r")) == NULL)     {         fprintf(stderr, "Can't open the file.\n");         exit(1);     }     while(fscanf(fp, "%s", item.word) != EOF)     {         printf("%s\n", item.word) ; // 这里打印出来都是正确的     }     return 0 ; }  对啊，，，我一直觉得我fscanf写的根本没问题，但是一运行读取就出错，，反复试了好几次，感觉是不是编译器的原因。。。另外想问下，，我想学linux的话，，是最好装个linux呢还是用VMware模拟也行呢。。

引用 2 楼 user-4 的回复:fscanf函数一般用来读取文本文件中的数据，难道楼主的文件是二进制的？  读单词，，肯定是文本文件啊。。。

引用 1 楼 hnwyllmm 的回复:楼主的代码还真的贴出来，要把怎么读取字符串的代码贴出来 验证这个读取是否正确的方法很简单，把读取出来的内容打印出来不就好了  typedef struct word  { char word[20]; int count; }Item;//将这个结构体的名字换成Item Item item;//定义个结构体变量 FILE * fp; if ((fp = fopen("1.txt", "r")) == NULL) { fprintf(stderr, "Can't open the file.\n"); exit(1); } while(fscanf(fp, "%s", item.word) != EOF) //将文件里的单词临时保存在item.word里，然后在循环里进行添加到树的操作 ......  贴个大概，当时是一运行程序就停止工作，VC6上看的很明显是读取的问题，然后反复注释这行，最后一次消掉注释的时候，才运行成功了。

fscanf函数一般用来读取文本文件中的数据，难道楼主的文件是二进制的？

引用 6 楼 guicaisa 的回复:[quote=引用 5 楼 hnwyllmm 的回复:] 测试了一下，运行的挺好，不过我没有VC6，用的GCC编译器，在Linux上执行的 }[/code]  对啊，，，我一直觉得我fscanf写的根本没问题，但是一运行读取就出错，，反复试了好几次，感觉是不是编译器的原因。。。另外想问下，，我想学linux的话，，是最好装个linux呢还是用VMware模拟也行呢。。[/quote] 你感觉自己的电脑配置还可以，装个虚拟机不会卡，就用虚拟机好了 要是虚拟机卡，装双系统，Windows系统还是有必要用的，很多办公软件还是Windows系统好用


Question: 函数疑问

这个没啥问题，这个程序if的执行语句都是赋值，既然都是赋值只需要包括所有情况就行了，作者为什么不一个if或者2个if就解决问题？还是因为n_search变量在后面3个if语句初始值不是0，而是前面if里面for语句自加后的n_search?

int main() { 	int a =10,b=0; 	 	if(a > 3) 		b++; //执行 	if(a > 5) 		b++; //执行 	if(a > 9) 		b++; //也执行  	//所以进不进前面的if和后面的if条件判断是没有关系的只和if语句的条件有关 	 }

void make_search_table(int i1,int j1,int k, int data_w, int data_h) {   int i,j;   n_search=0;   if(k==0) return;   if((j1-k)>= -1)     for(i=i1-k;i<i1+k;i++)       if((i>= -1)&&(i<data_w))         {si[n_search]=i; sj[n_search++]=j1-k;}    if((i1+k)<data_w)     for(j=j1-k;j<j1+k;j++)       if((j>= -1)&&(j<data_h))            {si[n_search]=i1+k; sj[n_search++]=j;}    if((j1+k)<data_h)     for(i=i1+k;i>i1-k;i--)       if((i>= -1)&&(i<data_w))              {si[n_search]=i; sj[n_search++]=j1+k;}    if((i1-k)>= -1)     for(j=j1+k;j>j1-k;j--)       if((j>= -1)&&(j<data_h))                 {si[n_search]=i1-k; sj[n_search++]=j;} } 帮你排下。。


Question: 学习到按值传递机制的一点小问题

理解和讨论之前请先学会如何观察！

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解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

引用 3 楼 Lcumin 的回复:[quote=引用 1 楼 jiht594 的回复:] 每个格子是一块内存, a存在第一块内存中 |a=1|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |    值传递之后, b=1在另一个格子, 所以b是a的副本 |a=1|  |  |  |  |  |  |  |b=1 |  |  |  |  |  |  |  |    也就是说, 你修改a不影响b, 修改b不影响a ---------------- 如果引用传递, a,b在同一块内存中, 修改其中一个, 另一个也被修改了. |a=b=1|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  那请问如果一个指针作为变元按值传递时，也应该是传递一个地址副本，这个副本和原来的地址相同吗？该怎样理解？[/quote]                                                                         地址x         地址y |p1=地址x|  |  |  |  |  |  |  |p2=地址x |  |  |  |  |  |  |          |    |  |            | 不知道能看明白吗?  如果修改p1或者p2的值, 比如 p2=地址y, 则p1还是指向地址x. 这里和非指针变量是一样的, 引用传参你自己想把 如果修改 "地址x"的内容, p1和p2所指向的值, 都被修改.

副本，即意味着传入函数中的，是原值的一份拷贝。

传值调用时. 会在栈中重新分配一个空间,(可以理解为新定义了一个变量), 然后把原来的值赋给这个新"变量". 然后再调用函数.  要很好的理解这个东西, 需要你懂汇编, 然后看汇编代码即能明白

《汇编语言 》 -- 王爽 “研究实验 5” 函数如何接收不定数量的参数

“按值传递”这个术语不知道是谁发明的。 为了解释C语言的行为，人们不知道发明了多少这种根本不需要的垃圾术语啊！ 1，参数传递类似于赋值，所以，参数传递本来就是传递值而不是其它。 2，至于是否能够通过实参修改其它对象，这是指针的特征，和参数传递无关。

引用 20 楼 zhao4zhong1 的回复:[quote=引用 13 楼 Sandrer 的回复:] 在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 有时（在64位系统上几乎每次）值通过CPU的寄存器而非堆栈内存传递。[/quote]  刚刚看了一下，的确都是 mov 到寄存器的..........

引用 21 楼 Sandrer 的回复:[quote=引用 20 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 Sandrer 的回复:] 在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 有时（在64位系统上几乎每次）值通过CPU的寄存器而非堆栈内存传递。[/quote]  call 之前不是都会 push 入栈吗？[/quote] 要不我怎么会说： 理解和讨论之前请先学会如何观察！ 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  呢？

引用 20 楼 zhao4zhong1 的回复:[quote=引用 13 楼 Sandrer 的回复:] 在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 有时（在64位系统上几乎每次）值通过CPU的寄存器而非堆栈内存传递。[/quote]  call 之前不是都会 push 入栈吗？

引用 13 楼 Sandrer 的回复:在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 有时（在64位系统上几乎每次）值通过CPU的寄存器而非堆栈内存传递。

引用 18 楼 Sandrer 的回复:[quote=引用 16 楼 sholber 的回复:] 而不要似是而非的在卖弄你的学识 你所说的，正是矛盾的地方，你应当正视。 C本来是很清爽的，没有这些术语。虽然没有这些术语，却也解释得很清楚。 相反，这些术语都是一些写书的人生造出来的，造成了更多的混乱。 我说得不对吗？ C标准用一句话“参数传递类似于赋值”就解释清了所有问题，还需要这些轮子吗？[/quote]  就正是因为你的这个“类似”，所谓的垃圾术语就会这样诞生了 你要说就要说得明明白白，一个“类似”别人会有很多中理解的[/quote]  才发现你上一次的回帖中有这么一句“而不要似是而非的在卖弄你的学识”。 我不会回答你的任何问题了。你可以保留你的看法。

引用 16 楼 sholber 的回复:而不要似是而非的在卖弄你的学识 你所说的，正是矛盾的地方，你应当正视。 C本来是很清爽的，没有这些术语。虽然没有这些术语，却也解释得很清楚。 相反，这些术语都是一些写书的人生造出来的，造成了更多的混乱。 我说得不对吗？ C标准用一句话“参数传递类似于赋值”就解释清了所有问题，还需要这些轮子吗？[/quote]  就正是因为你的这个“类似”，所谓的垃圾术语就会这样诞生了 你要说就要说得明明白白，一个“类似”别人会有很多中理解的

引用 16 楼 sholber 的回复:你所说的，正是矛盾的地方，你应当正视。 C本来是很清爽的，没有这些术语。虽然没有这些术语，却也解释得很清楚。 相反，这些术语都是一些写书的人生造出来的，造成了更多的混乱。 我说得不对吗？ C标准用一句话“参数传递类似于赋值”就解释清了所有问题，还需要这些轮子吗？  哦，那请你指正一下我哪里说得矛盾了  void func(int &n) void func(int *n) void func(int n) 这几个函数请问怎样赋值？ 按你所说的类似赋值，只是“类似”，而不是“真正” 那怎样另不懂的人去明白？  那 vb 里面的 ByRef ByVal 那就是多余的了，C 里面的 *、& 也是多余的了

引用 15 楼 Sandrer 的回复:[quote=引用 14 楼 sholber 的回复:] [quote=引用 13 楼 Sandrer 的回复:] 在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 按值传递？按址传递？这种垃圾术语实在不知道从哪本书开始散播开来的…… 给定函数调用表达式 f (5); 试问，这里的变量是谁？怎么才能“将一个变量的值复制一份到函数参数的栈地址上”？[/quote]  你那么与众不同，为什么不去出书呢，你去出书一定很畅销 所谓的名词，自古以来都是为了通俗易懂为重 那 vb 中的 ByVal、ByRef 你怎样叫法？你的 f(5) 本来就可以理解成按值传递 很简单的一个概念，我给函数传递一个值为5的参数 按你7楼所说，难道这个 5 是指针吗  别人有错你可以指证，但你要为所说的话负责，既然你说它不应该存在，就请证明它为什么不存在 而不要似是而非的在卖弄你的学识[/quote] 你所说的，正是矛盾的地方，你应当正视。 C本来是很清爽的，没有这些术语。虽然没有这些术语，却也解释得很清楚。 相反，这些术语都是一些写书的人生造出来的，造成了更多的混乱。 我说得不对吗？ C标准用一句话“参数传递类似于赋值”就解释清了所有问题，还需要这些轮子吗？

引用 14 楼 sholber 的回复:[quote=引用 13 楼 Sandrer 的回复:] 在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 按值传递？按址传递？这种垃圾术语实在不知道从哪本书开始散播开来的…… 给定函数调用表达式 f (5); 试问，这里的变量是谁？怎么才能“将一个变量的值复制一份到函数参数的栈地址上”？[/quote]  你那么与众不同，为什么不去出书呢，你去出书一定很畅销 所谓的名词，自古以来都是为了通俗易懂为重 那 vb 中的 ByVal、ByRef 你怎样叫法？你的 f(5) 本来就可以理解成按值传递 很简单的一个概念，我给函数传递一个值为5的参数 按你7楼所说，难道这个 5 是指针吗  别人有错你可以指证，但你要为所说的话负责，既然你说它不应该存在，就请证明它为什么不存在 而不要似是而非的在卖弄你的学识

引用 13 楼 Sandrer 的回复:在汇编里面，所有的参数其实都是栈地址，编译时按照栈地址获得变量数据  所谓的按值传递，就是将一个变量的值复制一份到函数参数的栈地址上 而按址传递，就是将函数参数的地址替换成变量的地址，所以修改参数的值会直接作用到函数外部的变量中  程序中一个变量不论是否为指针，只要是变量就肯定会有一个变量地址 在汇编语言中的所有变量不是按名字记忆，而是按地址记忆 按值传递？按址传递？这种垃圾术语实在不知道从哪本书开始散播开来的…… 给定函数调用表达式 f (5); 试问，这里的变量是谁？怎么才能“将一个变量的值复制一份到函数参数的栈地址上”？

在函数调用的时候，在内存中开辟一块地址，用来存放形参的副本，函数调用完后释放，不会改变原来的值。

实参把值赋值给形参，就是副本机制


Question: C语言链表的内存泄露的问题

跟踪调试不就一切都明了了

NODE *q;  //这个debug版本的话貌似会置零.也就是说下面那个while循环不会进入  while(q!=NULL)

while(q!=NULL) { q=head; head=head->pNext; q->pNext=NULL; free(q); q=NULL;  } 你这只删除了链表的第一个节点。free(q)之后，q=NULL再到while(q!=NULL)这里判断时，这时q已经等于NULL，所以你的while实际上删除一个节点。

发现原因了。我是用strdup函数会自己malloc所以那些东西还是要free。谢谢你的答案非常有用

再供参考：//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

引用 7 楼 he596you237 的回复:[quote=引用 5 楼 xihu1364 的回复:] void clearList(NODE *IpNode) { NODE *q;  while(q!=NULL) { q=head;        //冒出个head来，有定义吗？...  难道head = IpNode？ head=head->pNext; q->pNext=NULL; free(q); q=NULL;  }  }   typedef struct IpList { 	char* startip;  	char* endip;  	char* domain;  	char* regtype;  	int nDomNum;  	struct IpList *pNext; }NODE;  void clearList(NODE* pNode) { 	NODE* pTemp = pNode;  	while(pTemp != NULL) 	{ 		pNode = pNode->pNext;  		//看到结构体中很多char*类型的敢问是malloc的吗？如果是就必须free掉 		/* 		free(pNode->startip);  		free(pNode->endip);  		free(pNode->domain);  		free(pNode->regtype); 		*/ 		free(pTemp);  		pTemp = pNode; 	} }     并不是的malloc出来的[/quote]  你那代码写错了 就删除了头，后面的都没删除  用我的代码不就好了....

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

引用 5 楼 xihu1364 的回复:void clearList(NODE *IpNode) { NODE *q;  while(q!=NULL) { q=head;        //冒出个head来，有定义吗？...  难道head = IpNode？ head=head->pNext; q->pNext=NULL; free(q); q=NULL;  }  }   typedef struct IpList { 	char* startip;  	char* endip;  	char* domain;  	char* regtype;  	int nDomNum;  	struct IpList *pNext; }NODE;  void clearList(NODE* pNode) { 	NODE* pTemp = pNode;  	while(pTemp != NULL) 	{ 		pNode = pNode->pNext;  		//看到结构体中很多char*类型的敢问是malloc的吗？如果是就必须free掉 		/* 		free(pNode->startip);  		free(pNode->endip);  		free(pNode->domain);  		free(pNode->regtype); 		*/ 		free(pTemp);  		pTemp = pNode; 	} }     并不是的malloc出来的

引用 2 楼 ahui5252 的回复:free只是简单稀放,并没有去清内存.并且指针仍指向了那块内存,一般单线程的话稀放后不遇上合区块的话马上再打印会正确,因为那段内存既然能申请到,证明是正确的.即使放了也一样,不过在多线程的话可能就错了,因为放后可能被其他线程呻请修改. 不过稀放再对指针进行写操作的话结果不确定. C的free有合区块的功能.可能会对内存进行破坏  那这么说的话我只free会造成内存泄露吗？结构体中的比如domain 需要memset(q->domain,0,sizeof(q->domain))吗？


Question: 菜鸟程序，找不到错误！！！

while((c=getchar())!='q'); 语句去掉后面的分号看看


Question: Win7环境下基于Eclipse的STM32F4x GCC 开发环境调试问题

楼主你到底是解决了还是没解决啊？我把jlink_path和server的名字改成jinkgdbserver，能启动gdbserver但是报错 Error in services launch sequence Starting J-Link GDB Server timed out.

解决了，就这样。

楼主解决了吗？小弟也遇到类似问题，若解决能否给小弟发一个工程例子，学习一下配置方法。991353018@qq.com不胜感激


Question: POJ1001在VC上能正确运行，提交到POJ就说编译错误。

自己没有测试吗？VC6下也不行吧？

VC下一般编译CPP文件用的是C++编译器，编译C文件用的是C编译器。 所以即使你是VC下的CPP编译通过，也只能说明你的代码 符合VC的C++标准，挂在OJ的标准C编译器上通不过，非常正常。  选用OJ的C++编译 会有较大概率通过。

windows下想做oj题目就用dev c++吧，只要是dev c++能够编译过。提交后肯定没问题。

不要用vc6.0  for(int i=0; i<6; i++) {}正常的C++, i的范围是在大括号里面的


Question: C-链表元素通过指针循环赋值  出现segment fault

已解决..pq双方面指针问题..

引用 1 楼 user-1 的回复:错误太多.写完一个函数, 用printf测试好了再写下一个.   			q=(DuLinkList)malloc(sizeof(DuLNode));//这里q指向了新分配的地址, 新的!所以q的data,pre,next都没赋值 			p=(*q).prev;//q的prev是未知地址, 这句后p就是未知地址 			q=p;//这句之后, q和p一样, 指向了未知地址 //终于成功的把p和q都弄的不可用了  那把p=(*q).prev;调到malloc前还是出现错误啊

那把p=(*q).prev;调到malloc前还是出现错误啊


Question: c声明中的数组问题

引用 40 楼 liang618 的回复:[quote=引用 38 楼 lin5161678 的回复:] [quote=引用 35 楼 liang618 的回复:]   那不是初始化值是具体值，赋值可以是具体指或者抽象值； 哪里来的 莫名其妙的具体值抽象值?  分不清什么初始化什么是赋值就看别人是怎么说的  谦虚接受   赋值在C里面是存在于表达式里面  初始化和表达式完全是两种东西  没什么关系  别看到 = 就说是赋值 这只是符号重用而已 [/quote]  好吧好吧，我只是说了我的疑问就被扣上不虚心接受的帽子， 难道你让新手一上来就说一番大道理？ 这是论坛，互相交流，各抒己见，当然你背地里骂楼主随你的便， 请不要在论坛上高高在上的说教。[/quote] 别人清清楚楚的告诉你 什么是初始化什么是初始化器的时候 你毫无根据的回复那 那不是初始化值  扯出了一个闻所未闻的 所谓具体值抽象值 不是狂妄是什么

引用 12 楼 lanxue_1988 的回复:a是一块栈上的内存标识符，内存大小10*sizeof(int)，元素类型int 需要向要转换成其他类型的话，比如字符型，可以这样 int a[10]; char *pC = (char*)&a; a是常量不可修改，但是pC是可以修改的。。。 概念性的错误。不存在从数组类型到其它类型的转换。对于转换表达式 (T) E 来说，类型名T所指定的类型应当是： 1，void； 2，标量（原子的，限定或无限定的）。 操作数E的类型应当是标量。标量包括算术类型和指针类型，但数组类型显然不符合这个要求。将数组转换为指针显然就可以进行转换，因为指针是完整的对象类型。但即使是这样， char * pC = (char *) & a; 也显得很笨拙，毕竟，它可以直接写成 char * pC = (char *)  a; 最后，一个指示数组的标识符，比如这里的a，不是常量，不知道你从哪里得到的这种知识。

int    a[10]是一个整形数组，里面存储的时10个整数，分别是a[0]~a[9] 从0开始计算和从1开始计数是程序员和业余人士的重要区别

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

四楼说的是 int a[10]表示 连续储存10个int类型 和 10个数组元素。 是一样还是不一样？ 如一样：看上下语句说明 如不一样：我理解好像一个是从整体看一个从局部看 我找个例子：

首先int a[10]不是一个常量， 是一个int型数组变量， 只不过和一般的常用类型变量赋值不太一样而已。

严重同意3楼的说法。

1  a是10个int的数组，把字符串赋值是什么意思？ 2 a里面有10个int

想要从本质上理解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

引用 26 楼 sholber 的回复:[quote=引用 24 楼 liang618 的回复:] [quote=引用 2 楼 zhao4zhong1 的回复:] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 赵老师推荐些书看呗，肚里墨水少，想学习数据库方向的，从低到高需要啃哪些书呢？[/quote] 你让他推荐？他指定给你推荐MS-DOS 6.22 + Visual Forpro 2.5，或者Foxbase。说不定给你推荐个更早的：dBase III[/quote] 我推荐看随便哪一版的中文SQL Server联机文档。

引用 38 楼 lin5161678 的回复:[quote=引用 35 楼 liang618 的回复:]   那不是初始化值是具体值，赋值可以是具体指或者抽象值； 哪里来的 莫名其妙的具体值抽象值?  分不清什么初始化什么是赋值就看别人是怎么说的  谦虚接受   赋值在C里面是存在于表达式里面  初始化和表达式完全是两种东西  没什么关系  别看到 = 就说是赋值 这只是符号重用而已 [/quote]  好吧好吧，我只是说了我的疑问就被扣上不虚心接受的帽子， 难道你让新手一上来就说一番大道理？ 这是论坛，互相交流，各抒己见，当然你背地里骂楼主随你的便， 请不要在论坛上高高在上的说教。

引用 37 楼 sholber 的回复:[quote=引用 34 楼 liang618 的回复:] [quote=引用 30 楼 sholber 的回复:] [quote=引用 28 楼 liang618 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 5 楼 u012881352 的回复:] 牛头不对马嘴。没认真学基础的知识吧？  a是一个变量名，它代表的变量是一个类型为int的数组变量 而变量a的内容是该变量在内存中的首地址，即a[0] 嘎嘎~这种说法是不对滴~ 首先，数组也是一种数据类型，“类型为int的数组”说不通，“int类型的数组”也不对。数组类型就是数组类型，元素类型就是元素类型，你可以说“元素类型为int的数组”，这没问题； 其次，因为a是数组，所以，变量a的内容是数组的内容，而不是数组的首地址。数组是对象类型（相对于函数类型），对象类型都是有值的。数组对象的值就是数组里存储的内容。[/quote]  int a[10] 变量a称为数组，a[4]的类型是整型，数组名a是指向int的常量指针，数组不等同于指针，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。[/quote]  1，你先说“数组名a是指向int的常量指针”，然后又说“数组不等同于指针”，这个互相矛盾； 2，你说“数组名a是指向int的常量指针”，“只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量”，那么试问，在下面的表达式中，如果数组名被转换为指针，它是怎么得到数组大小的： size_t t = sizeof (a); 3，“常量指针”和“指针常量”在C标准中，用于指那些声明为const限定的指针： int * const p; 试问，数组名是怎么成为常量指针的？我翻遍最新的C标准，也没发现。请你明示。 [/quote]   以下为《c和指针》P141 原文： 考虑下面这些声明： int a； int b[10]；     我们把变量a称为标量，因为它是一个单一的值，这个变量的类型是一个整数。我们把变量b称为数组，因为它是一些值的集合。下标和数组名一起使用，用于标识该集合中某个特定的值。     b[4]的类型是整型，但b的类型呢？在C中，几乎所有使用数组名的表达式中，数组名的值是一个指针常量，也就是数组第一个元素的地址。它的类型取决于数组元素的类型：如果它们是int类型，那么数组名的类型就是“指向int的常量指针”。     请不要根据这个事实得出数组和指针是相同的结论。数组具有一些和指针完全不同的特征。例如，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。      注意这个值是指针常量，而不是指针变量。你不能修改常量的值。你只要稍微回想一下，就会认为这个限制是合理的：指针常量所指向的是内存中数组的起始位置，如果修改这个指针常量，唯一可行的操作就是把整个数组移动到内存的其他位置。但是，在程序完成链接之后，内存中数组的位置是固定的，所以当程序运行时，再想移动数组就为时已晚了。因此，数组名的只是一个指针常量。     只有在两种场合下，数组名并不用指针常量来表示————就是当数组名作为sizeof操作符或单目操作符&的操作数时，siozeof返回整个数组的长度，而不是指向数组的指针的长度。取一个数组名的地址所产生的是一个指向数组的指针，而不是一个指向某个指针常量的指针。[/quote]  1，我曾经说过，有些书的本意是通俗易懂，但它们造成了更多的混乱，相比之下，它们的价值十分微弱。 首先，“我们把变量a称为标量”。这个十分可笑。也许是翻译的问题吧。标量是指算术类型的指针类型，充其量它可以这样说“变量a是标量”。还有，“这个变量的类型是一个整数”，怎么念怎么别扭。一个整数也成了类型？当然，也许是翻译问题，这些语文方面的偏差放下不表。 2，“我们把变量b称为数组，因为它是一些值的集合。”这个也十分滴荒谬，嘎嘎~~，在C中，类型（types）分为对象类型（object types）和函数类型（function types），前者用于描述对象，后者用于描述函数。每个对象都会有一个值（void类型也是对象类型，它具有空值，或者不存在的值），包括数组类型的对象。你不能武断地说数组不是一个对象，或者说数组是值的集合，这是十分可笑的。 3，“下标和数组名一起使用，用于标识该集合中某个特定的值。”这也是胡说八道。下标表达式的结果要看它的位置，有时指示一个数组元素，有时用于计算一个值。比如： int x = a [3], * px = & a [3]; 如果a [3]仅仅计算一个值，它是怎么用&生成一个指针的？ 4，“请不要根据这个事实得出数组和指针是相同的结论。”这就是典型的不要脸了。未必所有人都认为它们是相同的——在C标准中，数组并没有被特殊对待，它也是普通的对象类型，数组类型的对象也是普通的对象类型。有些书自说自话，提出一些他们自己没想清楚的、自己觉得是问题的问题，搅浑了一池清水，最后得了一个模棱两可的、他们自己也没有准确回答的结论。这些人是怎么想的不知道，我只知道他们是一群混蛋。 5，“注意这个值是指针常量，而不是指针变量。你不能修改常量的值。你只要稍微回想一下，就会认为这个限制是合理的：指针常量所指向的是内存中数组的起始位置，如果修改这个指针常量，唯一可行的操作就是把整个数组移动到内存的其他位置。”数组会转换为指针常量，这个，嘎嘎，C从来没说过，可以当放炮。另外，按它的逻辑，int i;这个i的地址也是不能随便乱动的，也同样是指针常量了。 6，其它问题不再一一解释。《C和指针》这本书没看过，不过我有PDF。建议大家不要乱看书。[/quote]  能留个联系方式吗？如果用qq的话，楼主qq：44326334 有问题请教

引用 35 楼 liang618 的回复:那不是初始化值是具体值，赋值可以是具体指或者抽象值； 哪里来的 莫名其妙的具体值抽象值?  分不清什么初始化什么是赋值就看别人是怎么说的  谦虚接受   赋值在C里面是存在于表达式里面  初始化和表达式完全是两种东西  没什么关系  别看到 = 就说是赋值 这只是符号重用而已

引用 34 楼 liang618 的回复:[quote=引用 30 楼 sholber 的回复:] [quote=引用 28 楼 liang618 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 5 楼 u012881352 的回复:] 牛头不对马嘴。没认真学基础的知识吧？  a是一个变量名，它代表的变量是一个类型为int的数组变量 而变量a的内容是该变量在内存中的首地址，即a[0] 嘎嘎~这种说法是不对滴~ 首先，数组也是一种数据类型，“类型为int的数组”说不通，“int类型的数组”也不对。数组类型就是数组类型，元素类型就是元素类型，你可以说“元素类型为int的数组”，这没问题； 其次，因为a是数组，所以，变量a的内容是数组的内容，而不是数组的首地址。数组是对象类型（相对于函数类型），对象类型都是有值的。数组对象的值就是数组里存储的内容。[/quote]  int a[10] 变量a称为数组，a[4]的类型是整型，数组名a是指向int的常量指针，数组不等同于指针，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。[/quote]  1，你先说“数组名a是指向int的常量指针”，然后又说“数组不等同于指针”，这个互相矛盾； 2，你说“数组名a是指向int的常量指针”，“只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量”，那么试问，在下面的表达式中，如果数组名被转换为指针，它是怎么得到数组大小的： size_t t = sizeof (a); 3，“常量指针”和“指针常量”在C标准中，用于指那些声明为const限定的指针： int * const p; 试问，数组名是怎么成为常量指针的？我翻遍最新的C标准，也没发现。请你明示。 [/quote]   以下为《c和指针》P141 原文： 考虑下面这些声明： int a； int b[10]；     我们把变量a称为标量，因为它是一个单一的值，这个变量的类型是一个整数。我们把变量b称为数组，因为它是一些值的集合。下标和数组名一起使用，用于标识该集合中某个特定的值。     b[4]的类型是整型，但b的类型呢？在C中，几乎所有使用数组名的表达式中，数组名的值是一个指针常量，也就是数组第一个元素的地址。它的类型取决于数组元素的类型：如果它们是int类型，那么数组名的类型就是“指向int的常量指针”。     请不要根据这个事实得出数组和指针是相同的结论。数组具有一些和指针完全不同的特征。例如，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。      注意这个值是指针常量，而不是指针变量。你不能修改常量的值。你只要稍微回想一下，就会认为这个限制是合理的：指针常量所指向的是内存中数组的起始位置，如果修改这个指针常量，唯一可行的操作就是把整个数组移动到内存的其他位置。但是，在程序完成链接之后，内存中数组的位置是固定的，所以当程序运行时，再想移动数组就为时已晚了。因此，数组名的只是一个指针常量。     只有在两种场合下，数组名并不用指针常量来表示————就是当数组名作为sizeof操作符或单目操作符&的操作数时，siozeof返回整个数组的长度，而不是指向数组的指针的长度。取一个数组名的地址所产生的是一个指向数组的指针，而不是一个指向某个指针常量的指针。[/quote]  1，我曾经说过，有些书的本意是通俗易懂，但它们造成了更多的混乱，相比之下，它们的价值十分微弱。 首先，“我们把变量a称为标量”。这个十分可笑。也许是翻译的问题吧。标量是指算术类型的指针类型，充其量它可以这样说“变量a是标量”。还有，“这个变量的类型是一个整数”，怎么念怎么别扭。一个整数也成了类型？当然，也许是翻译问题，这些语文方面的偏差放下不表。 2，“我们把变量b称为数组，因为它是一些值的集合。”这个也十分滴荒谬，嘎嘎~~，在C中，类型（types）分为对象类型（object types）和函数类型（function types），前者用于描述对象，后者用于描述函数。每个对象都会有一个值（void类型也是对象类型，它具有空值，或者不存在的值），包括数组类型的对象。你不能武断地说数组不是一个对象，或者说数组是值的集合，这是十分可笑的。 3，“下标和数组名一起使用，用于标识该集合中某个特定的值。”这也是胡说八道。下标表达式的结果要看它的位置，有时指示一个数组元素，有时用于计算一个值。比如： int x = a [3], * px = & a [3]; 如果a [3]仅仅计算一个值，它是怎么用&生成一个指针的？ 4，“请不要根据这个事实得出数组和指针是相同的结论。”这就是典型的不要脸了。未必所有人都认为它们是相同的——在C标准中，数组并没有被特殊对待，它也是普通的对象类型，数组类型的对象也是普通的对象类型。有些书自说自话，提出一些他们自己没想清楚的、自己觉得是问题的问题，搅浑了一池清水，最后得了一个模棱两可的、他们自己也没有准确回答的结论。这些人是怎么想的不知道，我只知道他们是一群混蛋。 5，“注意这个值是指针常量，而不是指针变量。你不能修改常量的值。你只要稍微回想一下，就会认为这个限制是合理的：指针常量所指向的是内存中数组的起始位置，如果修改这个指针常量，唯一可行的操作就是把整个数组移动到内存的其他位置。”数组会转换为指针常量，这个，嘎嘎，C从来没说过，可以当放炮。另外，按它的逻辑，int i;这个i的地址也是不能随便乱动的，也同样是指针常量了。 6，其它问题不再一一解释。《C和指针》这本书没看过，不过我有PDF。建议大家不要乱看书。

引用 33 楼 lanxue_1988 的回复:[quote=引用 25 楼 sholber 的回复:] [quote=引用 21 楼 lanxue_1988 的回复:] [quote=引用 19 楼 sholber 的回复:] [quote=引用 17 楼 lanxue_1988 的回复:] [quote=引用 15 楼 sholber 的回复:]  概念性的错误。不存在从数组类型到其它类型的转换。对于转换表达式 a 说到底只是一个地址，至于，这块地址上的内容如何解释，是由类型决定的， 这有什么问题吗？[/quote]  如果a只是一个地址，那么表达式&a怎么解释？取一个地址的地址？ 你能分得清标识符、对象、值之三者之间的关系吗？ [/quote] &a和a的值都是一样的，不一样的类型 int a[10]; // 比如 a+1//的值为a+1 &a +1 //的值为 &a + sizeof(a) 即 &a + 10*sizeof(int) [/quote] 你得先弄清楚“值”的概念。按照C标准的定义，值（value）是用对象所属的类型来解释的、精度意义上的内容。 所以，值一样，类型不同，这是个矛盾的、不明所以的说法，嘎嘎~~ C语言里有个术语叫“对象表示（object representation）”，专门用来描述对象的底层数据表示方法，你可以说表达式&a和a的值具有相同的对象表示，但这不意味着它们具有相同的值哩。 还有，a+1的值是a+1，这是个什么意思？我知道你的意思，但你的表述太乱。只能这么说，你读的书都打着通俗的旗号，干了混淆概念，滥造术语的勾当，这些书的影响实在太坏了。嘎嘎~~ [/quote] "指向不同类型的指针"在内存上均是一个地址,无任何差异,其不同之处在于其所寻址出来的objec类型不同,也就是说,"指针类型"会教导编译器如何解释某个特定地址中的内存内容以及其大小. 其实，我本意只想说，int a[10] ;就是一块内存，怎么使用可以灵活处理，只要编译器不抱怨，内存不越界就ok了。  还好你站出来指正了这么严重的概念性错误，不然，就又坑害了一些大好青年~~~[/quote]  要不要这么难，不好理解。

引用 32 楼 sholber 的回复:[quote=引用 31 楼 liang618 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 16 楼 liang618 的回复:] 你们都跑题了 没懂我的意思 只有四楼说对第一个问题。 char a[10] scanf(''%s'',a) printf(''%s'',a) 那么可以输出一个如“world”的字符串，这个数组就可以解释成一行10个的储存单元，每个单元储存一个字符，空字符\o结尾。  char a[10]={a,b,c,…}；是给数组初始化赋值，如a[0]=a,  a[1]=b…  我们讨论的内容延伸自你的问题……嘎嘎……我们讨论我们的，不影响，嘎嘎~ 初始化和赋值不是一回事，也不存在所谓的初始化赋值。[/quote]  初始化和赋值有啥不同？ 求解释[/quote]  初始化是指，在对象创建时，为它赋予一个初始值，这个初始值是在对象声明时，由声明语法中的初始化器（initializer）指定的。典型地，对于声明 int x = 100, (* f) (const char ...) = printf; 这里的printf和100就是初始化器。 赋值，是指赋值表达式修改对象的存储值的副作用。即使新值和原值相同，也算是修改。典型地，赋值表达式的例子可以是 x += 2[/quote]  那不是初始化值是具体值，赋值可以是具体指或者抽象值；

引用 30 楼 sholber 的回复:[quote=引用 28 楼 liang618 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 5 楼 u012881352 的回复:] 牛头不对马嘴。没认真学基础的知识吧？  a是一个变量名，它代表的变量是一个类型为int的数组变量 而变量a的内容是该变量在内存中的首地址，即a[0] 嘎嘎~这种说法是不对滴~ 首先，数组也是一种数据类型，“类型为int的数组”说不通，“int类型的数组”也不对。数组类型就是数组类型，元素类型就是元素类型，你可以说“元素类型为int的数组”，这没问题； 其次，因为a是数组，所以，变量a的内容是数组的内容，而不是数组的首地址。数组是对象类型（相对于函数类型），对象类型都是有值的。数组对象的值就是数组里存储的内容。[/quote]  int a[10] 变量a称为数组，a[4]的类型是整型，数组名a是指向int的常量指针，数组不等同于指针，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。[/quote]  1，你先说“数组名a是指向int的常量指针”，然后又说“数组不等同于指针”，这个互相矛盾； 2，你说“数组名a是指向int的常量指针”，“只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量”，那么试问，在下面的表达式中，如果数组名被转换为指针，它是怎么得到数组大小的： size_t t = sizeof (a); 3，“常量指针”和“指针常量”在C标准中，用于指那些声明为const限定的指针： int * const p; 试问，数组名是怎么成为常量指针的？我翻遍最新的C标准，也没发现。请你明示。 [/quote]   以下为《c和指针》P141 原文： 考虑下面这些声明： int a； int b[10]；     我们把变量a称为标量，因为它是一个单一的值，这个变量的类型是一个整数。我们把变量b称为数组，因为它是一些值的集合。下标和数组名一起使用，用于标识该集合中某个特定的值。     b[4]的类型是整型，但b的类型呢？在C中，几乎所有使用数组名的表达式中，数组名的值是一个指针常量，也就是数组第一个元素的地址。它的类型取决于数组元素的类型：如果它们是int类型，那么数组名的类型就是“指向int的常量指针”。     请不要根据这个事实得出数组和指针是相同的结论。数组具有一些和指针完全不同的特征。例如，数组具有确定数量的元素，而指针只是一个标量值。编译器用数组名来记住这些属性。只有在数组名在表达式中使用时，编译器才会为它产生一个指针常量。      注意这个值是指针常量，而不是指针变量。你不能修改常量的值。你只要稍微回想一下，就会认为这个限制是合理的：指针常量所指向的是内存中数组的起始位置，如果修改这个指针常量，唯一可行的操作就是把整个数组移动到内存的其他位置。但是，在程序完成链接之后，内存中数组的位置是固定的，所以当程序运行时，再想移动数组就为时已晚了。因此，数组名的只是一个指针常量。     只有在两种场合下，数组名并不用指针常量来表示————就是当数组名作为sizeof操作符或单目操作符&的操作数时，siozeof返回整个数组的长度，而不是指向数组的指针的长度。取一个数组名的地址所产生的是一个指向数组的指针，而不是一个指向某个指针常量的指针。

引用 25 楼 sholber 的回复:[quote=引用 21 楼 lanxue_1988 的回复:] [quote=引用 19 楼 sholber 的回复:] [quote=引用 17 楼 lanxue_1988 的回复:] [quote=引用 15 楼 sholber 的回复:]  概念性的错误。不存在从数组类型到其它类型的转换。对于转换表达式 a 说到底只是一个地址，至于，这块地址上的内容如何解释，是由类型决定的， 这有什么问题吗？[/quote]  如果a只是一个地址，那么表达式&a怎么解释？取一个地址的地址？ 你能分得清标识符、对象、值之三者之间的关系吗？ [/quote] &a和a的值都是一样的，不一样的类型 int a[10]; // 比如 a+1//的值为a+1 &a +1 //的值为 &a + sizeof(a) 即 &a + 10*sizeof(int) [/quote] 你得先弄清楚“值”的概念。按照C标准的定义，值（value）是用对象所属的类型来解释的、精度意义上的内容。 所以，值一样，类型不同，这是个矛盾的、不明所以的说法，嘎嘎~~ C语言里有个术语叫“对象表示（object representation）”，专门用来描述对象的底层数据表示方法，你可以说表达式&a和a的值具有相同的对象表示，但这不意味着它们具有相同的值哩。 还有，a+1的值是a+1，这是个什么意思？我知道你的意思，但你的表述太乱。只能这么说，你读的书都打着通俗的旗号，干了混淆概念，滥造术语的勾当，这些书的影响实在太坏了。嘎嘎~~ [/quote] "指向不同类型的指针"在内存上均是一个地址,无任何差异,其不同之处在于其所寻址出来的objec类型不同,也就是说,"指针类型"会教导编译器如何解释某个特定地址中的内存内容以及其大小. 其实，我本意只想说，int a[10] ;就是一块内存，怎么使用可以灵活处理，只要编译器不抱怨，内存不越界就ok了。  还好你站出来指正了这么严重的概念性错误，不然，就又坑害了一些大好青年~~~

引用 31 楼 liang618 的回复:[quote=引用 18 楼 sholber 的回复:] [quote=引用 16 楼 liang618 的回复:] 你们都跑题了 没懂我的意思 只有四楼说对第一个问题。 char a[10] scanf(''%s'',a) printf(''%s'',a) 那么可以输出一个如“world”的字符串，这个数组就可以解释成一行10个的储存单元，每个单元储存一个字符，空字符\o结尾。  char a[10]={a,b,c,…}；是给数组初始化赋值，如a[0]=a,  a[1]=b…  我们讨论的内容延伸自你的问题……嘎嘎……我们讨论我们的，不影响，嘎嘎~ 初始化和赋值不是一回事，也不存在所谓的初始化赋值。[/quote]  初始化和赋值有啥不同？ 求解释[/quote]  初始化是指，在对象创建时，为它赋予一个初始值，这个初始值是在对象声明时，由声明语法中的初始化器（initializer）指定的。典型地，对于声明 int x = 100, (* f) (const char ...) = printf; 这里的printf和100就是初始化器。 赋值，是指赋值表达式修改对象的存储值的副作用。即使新值和原值相同，也算是修改。典型地，赋值表达式的例子可以是 x += 2


Question: 新人求教 如何用visual studio 编写选座软件。

商业的东西要给钱 如果你是在研究过程中需要解决问题那有大把人教你 但你直接是在伸手问人拿商业的东西，你说有这可能吗


Question: 求助

一行100000这么长？ 十六制转八不需要转成什么十进制之类，直接3个字节一读转成4个八进制输出

仅供参考：#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汉

我的思想是，先把16进制数转为2进制数，再把2进制数转为8进制数。

仅供参考：  #include <stdio.h> #include <string.h> /* 给定n个十六进制正整数，输出它们对应的八进制数。 */ char *table1[16] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; char *table2[8] = { "000", "001", "010", "011", "100", "101", "110", "111" }; //转二进制，一位转四位 void toBinary(char **nums, int n) { 	int len, i, j, k, pos; 	for (i = 0; i < n; i++) 	{ 		len = strlen(nums[i]); 		j = 399998; 		for (k = len - 1; k >= 0; k--) 		{ 			if (nums[i][k] >= 'A' && nums[i][k] <= 'F') 				pos = nums[i][k] - 'A' + 10; 			else 				pos = nums[i][k] - '0'; 			strncpy(nums[i] + j, table1[pos], 4); 			j -= 4; 		} 		j += 4;  		memset(nums[i], '0', j); 	} } //转八进制，三位转一位 void toOctal(char **nums, int n) { 	int i, j, k, r, s; 	for (i = 0; i < n; i++) 	{ 		j = 0; 		k = 399999; 		while (nums[i][j] == '0') 			j++;  		s = 400001; 		while (k >= j - 3) 		{ 			for (r = 0; r < 8; r++) 			{ 				if (strncmp(nums[i] + k, table2[r], 3) == 0) 				{ 					nums[i][s--] = r + '0'; 					break; 				} 			} 			k -= 3; 		} 		s++; 		while (nums[i][s] == '0') 			s++; 		//打印 		puts(nums[i] + s); 	} } int main(void)    //14 { 	//读入数据 	int n; 	scanf("%d", &n);  	char **nums = malloc(sizeof(char*)*n); 	int i; 	for (i = 0; i < n; i++) 	{ 		nums[i] = malloc(sizeof(char) * 400003); 		memset(nums[i], 0, 400003); 		scanf("%s", nums[i]); 	}  	//先转二进制 	toBinary(nums, n);  	//再转八进制 	toOctal(nums, n);   	//释放内存 	for (i = 0; i < n; i++) 		free(nums[i]); 	free(nums);  	return 0; }   在vs下测试通过


Question: 矩阵转置算法，整个程序单步调试通过但是直接运行报错，网上看了看这种问题貌似是多线程问题，请问怎么解决呀？

是我搞错了，现在搞懂了这个的确没用到，还是程序写错了，谢谢了，我已经解决了，

哥们，你这没有使用多线程，哪来的多线程错误？ 什么运行错误？截个图或者详细介绍一下


Question: 这个是怎么回事呢？、每回开始编译都出现这个问题

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

高，实在是高。你们C语言老师是体育老师出身吧。

你是零基础自学的吧！照着书一一对比哪里不同！ { } 和[ ] 是不同的！

改成 int main () ??<     printf ("1234,\n"); ??> 就好了。嘎嘎~

[] 自动生成的？ 还是手写？ 这个~~~【】~~~

函数体用 { } 包含住语句块

int main() {      ......      return 0; }

我瞅了半天才发现原来是中括号。笑尿了（开始很容易犯这样的错误的，希望你坚持下来，一起加油）

高，实在是高！

#include <stdio.h> int main() {         printf("hello world!\n");         return 0; }  把这个赋值上去。。。。 main() 后面是 { } 。 不是 [ ]

大括号写成中括号。。


Question: 双链表插入函数实现的疑惑

做一件事有很多种方式，如果对性能提升帮助不大，就没有优化的必要了。不过如果是学习，那你玩玩吧

十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

仅供参考：//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>  //带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

引用 1 楼 zhao4zhong1 的回复:建议分别对： ◆空的双链表 ◆一个节点的双链表之前 ◆一个节点的双链表之后 ◆两个节点的双链表中这两个节点之间 测试你的插入结果是否达到预期。 老师这是授之以渔啊。达到预期了，这种问题还得想办法去测试一下，否则永远都是别人说的。谢谢老师


Question: malloc指针返回NULL（求大神指教）

引用 6 楼 QIULANZHU 的回复:sizeof(struct SUBASSYPART)这个结构你在哪里定义了。。  =============================== typedef struct         {                 int n_parts;                 struct SUBASSYPART                 {                         char partno[10];                         short quan;                 }*part;         }Subassyinfo;struct SUBASSYPART{...}*part不是定义了吗？

需要把  struct SUBASSYPART                 {                         char partno[10];                         short quan;                 } 拿出来定义，不能放在结构体里定义，作用域不对

是结构体里面定义一个结构体吗？这个联合结构不能被识别。

返回一直是0 就是内存没有分配成功

引用 3 楼 hlqhayq 的回复:返回一直是0 就是内存没有分配成功  sizeof(struct SUBASSYPART)这个结构你在哪里定义了。。

struct SUBASSYPART                 {                         char partno[10];                         short quan;                 }*part;   前面是不是少了typedef？

单步调试+测试输出

sizeof(struct SUBASSYPART)；  这个结构在哪里， 编译器访问不到这个结构体。。


Question: poj 1003 我觉得逻辑没问题，为什么，会粗问题？time exceed？

感谢各位，明白了

sum=sum+(1.0f/i); 把其中1改成1.0f就行了

保研之后尝试坚持把POJ一直刷下去，很遗憾的是，没想到保研之后更忙。。。不过这道题刚好做了。。。 代码： #include <iostream> using namespace std; int main() { 	double num; 	cin>>num; 	double i; 	while(num!=0.00) 	{ 		double result=0.0; 		for(i=2;;i++) 		{ 			result+=double(1/i); 			if(result>=num) 				break; 		} 		cout<<i-1<<" card(s)"<<endl; 		cin>>num; 	} }

目测 (float)(1/i) = 0，死循环。


Question: C语言中的强制转换，急！

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

int右移的规则比较复杂，尽量用unsigned int 参考第6章6.8节的说明

1、a右移应该是a>>1 2、不加强制转换会不会导致结果错误，楼主试一下就知道了，我在VS2010上试，加与不加结果是一样的~~~  #include <iostream> using namespace std; void main() { 	int a=100,b=5,c=0; 	a=100; 	cout<<(a>>1)<<endl; 	c = (_int16)((_int16)(a>>1) + b); 	cout<<c<<endl; 	c = ((a>>1) + b); 	cout<<c<<endl; }

感谢各位答复，我电脑上并没用VC之类的工具，公司电脑安装软件还需要向IT部门申请，所以比较麻烦。我是做自动代码生成的，正在比较不同版本的自动代码生成工具的差异，发现了这个问题，百度了很久也没有找到相关资料。  另外关于有符号整型相加会溢出我是否能这样理解？比如有以下代码： int8 a,b,c,d; （1） c = a + b;   即使发生溢出也不会影响结果，因为计算的2进制值和把a,b强制转换成uint8，所计算出来的值是一样的，所以不需要在a和b之前加强制转换uint8。 （2） c = a + b + d，如果a+b会发生溢出，那么再和d相加会影响到最终的2进制值，所以需要把a,b,d前面强制转换成uint8?


Question: 关于define预定义的问题？

关于2进制，8进制，10进制，16进制，36进制请看 http://blog.csdn.net/iamshaofa/article/details/44274751  收录在本书附录14里了， 《C/C++学习指南》 引用 2 楼 adusuccessfully 的回复:是不是把常量写成16进制，10进制，2进制没啥区别呢~~~

这个因开发中需要或者开发者习惯而定吧，没有什么必然的意义。

嗦嘎 明白一点了

16进制, 心算就可以转成2进制.  如果需要 &|>><<操作时, 容易懂  感觉写成2进制数也挺好  说白了就是程序怎么方便怎么写. 如果你能心算十进制数的&操作, 就都写成十进制也行.

是不是把常量写成16进制，10进制，2进制没啥区别呢~~~

#define 的作用是将一些值或操作命名成有意义且易记的名字 如果值为16进制的，那这些值一般用于按位“与、或”操作 否则为直接比对或赋值的内容


Question: 函数问题

用面象对象的思路来设计最好，当然内部加一个static int也是可以的  引用 2 楼 user-3 的回复:函数体内加一个 static int 的变量 初始化为零，每次调用函数的时候变量值+1 然后你去判断这个值是多少就是了

是不是可以设置一个全局变量，判断函数list调用是不是第一次呢？（我猜的，不一定说的对……）

请问应如判断?


Question: 关于字典的一点疑惑 ，在线等！

貌似没有特别高效的方法，只是发现了这个： http://quke.org/log-213.html 我能想到的也是将需要删除的键值复制出来，然后遍历删除，比如： >>> a = {1:0, 2:0, 3:1, 4:1} >>> del_keys = [] >>> for i in a.keys(): ... 	if a[i] == 0: ... 		del_keys.append(i) ... 		 >>> for i in del_keys: ... 	del a[i] ... 	 >>> a {3: 1, 4: 1}


Question: 求问个关于文件读取的问题

楼上的说的都很好

仅供参考：#include <mem.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <graphics.h> const unsigned char bit[8]={128,64,32,16,8,4,2,1}; //-------------------------------------------------------- void dis(xoff,code)     unsigned int xoff,code; {     unsigned char *buffer;     FILE *hzk;     unsigned long offset;     unsigned int q,w;     int x,y,width;      buffer=calloc(32,1);     if ((code&0xFF00)!=0) {         w=(code&0x00FF)-0xA1;         q=((code>>8)&0x00FF)-0xA1;         offset=q*0x5E+w;         offset*=32;         if ((hzk=fopen("HZK16","rb"))==NULL) {             closegraph();             printf("Can not open HZK16\r\n");             exit(1);         }         fseek(hzk,offset,SEEK_SET);         fread(buffer,1,32,hzk);         fclose(hzk);         width=2;     }     else {         if ((hzk=fopen("ASC16","rb"))==NULL) {             closegraph();             printf("Can not open ASC16\r\n");             exit(1);         }         offset=code*16;         fseek(hzk,offset,SEEK_SET);         fread(buffer,1,16,hzk);         fclose(hzk);         width=1;     }     for (y=0;y<16;y++) for (x=0;x<8*width;x++) {         if (buffer[y*width+x/8]&bit[x%8]) putpixel(xoff+x,y,15);     }     free(buffer); } //-------------------------------------------------------- void display(p)     unsigned char *p; {    int i;   unsigned int qw;    i=0;   while (1) {     if (p[i]==0x0D||p[i]==0x1A) break; 	if (p[i]>0xA0) { 		qw=((unsigned int)p[i]<<8)|((unsigned int)p[i+1]&0x00FF); 		dis(8*i,qw); 		i+=2; 	} 	else { 		qw=(unsigned int)p[i]&0x00FF; 		dis(8*i,qw); 		i++; 	}   }  } //-------------------------------------------------------- void main() { 	int gdriver = DETECT, gmode, errorcode; 	long fl; 	FILE *hz; 	unsigned char *p;  	initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi"); 	errorcode = graphresult(); 	if (errorcode != grOk) { 	   printf("Graphics error: %s\n", grapherrormsg(errorcode)); 	   exit(1); 	} 	hz=fopen("hz","rb"); 	fseek(hz,0,SEEK_END); 	fl=ftell(hz); 	p=calloc((int)fl,sizeof(unsigned char)); 	rewind(hz); 	fread(p,1,(int)fl,hz); 	fclose(hz); 	display(p); 	free(p); 	getch(); 	closegraph(); }

你可以先使用你字库中的第一个字来调试。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  要么你汉字的前后两个字节的顺序反了 要么你从0开始还是从1开始混了 要么你GBK编码还是Unicode编码亦或UTF8编码没弄清：对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A ……

引用 2 楼 zhao4zhong1 的回复:不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了不是很懂啊 我就是不明白我的算法哪里错了，我都看了好几天了


Question: 接口文件中读取保存指定结构文件中

DWORD GetPrivateProfileString 自己实现了 很麻烦，不过还是C强大#89 谢谢大家！

引用 1 楼 zhao4zhong1 的回复:很明显，两者的字节数不同。 正是因为这样，C#中的数据类型要求C来实现这种结构的文件。接口的.ini文件中取结构体变量

很明显，两者的字节数不同。

引用 9 楼 zhao4zhong1 的回复:建议使用XML格式保存数据。 谢谢，这倒是个方法，可以试试。不过我觉得直接读取接口文件应该能实现，因为要实现实时文件的生成。

建议使用XML格式保存数据。

建议楼主先补课：  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……   推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

引用 3 楼 zhao4zhong1 的回复:(14 00 OA 00 07 00 1A 00 00 00 01 00 2D 00 53 00 4E 00 6F 00 01 00 00 00 00 00 01 00 02 00 03 00) //←32个字节 //文件记录结构： typedef struct{     Uint16 oDate;                     // 2     Uint16 oTime;                     // 2     Uint16 sTime;                     // 2     Uint16 tfFlag;                    // 2     Uint16 ErrorCode[3];              // 6  2*3     Uint16 MoneyFlag[4];              // 8  2*4     Uint16 Ver;                       // 2     Uint16 Valuta;                    // 2     Uint16 CharNUM;                   // 2     Uint16 SNo[12];                   //24  2*12     Uint16 MachineSNo[24];            //48  2*24     Uint16 Reserve1       //保留字1   // 2 }                                     //合计102个字节 //请问：32个字节怎么和102个字节的信息建立对应关系？   是文件头。请教老师 DWORD GetPrivateProfileString 这个API的函数读出.ini文件的数据赋值给结构体变量，以生成上述文件结构不知道这样可以实现吗？

引用 4 楼 user-2 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 很明显，两者的字节数不同。  我猜楼主说的 (14 00 OA 00 07 00 1A 00 00 00 01 00 2D 00 53 00 4E 00 6F 00 01 00 00 00 00 00 01 00 02 00 03 00) 是文件头 文件头后面跟着的才是结构体  但是文件头的定义没给[/quote] 抱歉，叙述表达的问题。确实是给的文件头 typedef struct { Uint16  HeadStart[4];     //20,10,7,26 Uint16  HeadString[6];  // 0,1,2D Uint32  Counter;          //1 Uint16  HeadEnd[4];   //1,2,3,4 }

引用 1 楼 zhao4zhong1 的回复:很明显，两者的字节数不同。  我猜楼主说的 (14 00 OA 00 07 00 1A 00 00 00 01 00 2D 00 53 00 4E 00 6F 00 01 00 00 00 00 00 01 00 02 00 03 00) 是文件头 文件头后面跟着的才是结构体  但是文件头的定义没给


Question: 队列接口例题编译链接出现问题

其它也不多说了，把VC6扔掉再来试试

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

不贴代码妄图找问题的都是耍流氓

是STL里面的 list吗？  #include <list> using namespace std::list;  int main() { list<int> arr; arr.push_back(10); return 0; }


Question: c语言两个结构体互相干扰

Queue *guodao; 	Init(guodao);  指针没有指向具体实例，换言之，没有Queue 数据对象可用来初始化。

1、楼主定义的这两个结构体没有任何关系，是不会互相干扰的； 2、楼主初始化结构体的程序不对，因为指针没有指向，1楼的解答对对的。  #include<stdio.h> #define Max 100 typedef struct _messege { 	char name; 	int chepai; 	int time; }message; typedef struct _Queue { 	int base[Max]; 	int front,rear; }Queue; void Init(Queue *Q) { 	Q->rear=0; 	Q->front=0; } void main() { 	Queue guodao; 	Init(&guodao); 	printf("%d%d",guodao.front,guodao.rear);  	message a; 	Queue *p = new Queue(); 	Init(p); 	printf("%d%d",p->front,p->rear); }

2个都不对      Queue guodao;     Init(&guodao);     printf("%d%d",guodao.front,guodao.rear);      Queue *guodao = new Queue();     Init(guodao);     printf("%d%d",guodao->front,guodao->rear);


Question: C语言指针问题

引用 12 楼 zhangxiangDavaid 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] //C++ Operators ...  这张表哪里找到的？[/quote]  MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 下载安装MSDN98 mk:@MSITStore:D:\MSDN98\98VS\2052\vclang.chm::/html/_pluslang_c.2b2b_.operators.htm

赋值运算符+=低于一元运算符*，后缀运算符++优先于一元运算*，选哪个你看着办吧。

D错了，忘说答案了。。。上面解释的是为什么错，ABC对

[b]指针和++优先级一样，，结合方向是右结合性，即相当于*（p++),，输出的时候先输出的是2009 ，再将地址加1.

引用 10 楼 zhao4zhong1 的回复://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 | //+------------------+-----------------------------------------+---------------+   这张表哪里找到的？

D  *p++中*和++的优先级相同 按照从右至左的顺序结合 先将p增1再取地址

D。 先++ 再*

D *p++; 连指针p的指向都改变了，就不可能把year变为2010

没听说过定义语句。定义是定义语句是语句。 int x, * px = & x; px [0] = 'D';

ABC都可以


Question: 一个字符串处理的算法题

引用 1 楼 user-3 的回复:遇到左括号 入栈  ，遇到右括号 去匹配栈顶，匹配则出栈，不匹配直接返回false。最后检查栈不空 返回false，否则true。 算法思想就是这样，很简单，借用STL中的stack栈  #include <iostream> #include <stack> using namespace std; bool is_balance(const char *str) { 	//空串，也认为是平衡的 	if (!str) 		return true; 	//创建括号栈 	stack<char> sta; 	const char *p = str; 	while (*p) 	{ 		//遇到这四个括号即入栈 		if (*p == '(' || *p == ')' || *p == '[' || *p == ']') 		{ 			if (!sta.empty()) 			{ 				if ((*p == ')' && sta.top() == '(') || (*p == ']' && sta.top() == '[')) 					sta.pop();    //括号匹配则出栈 				else 				{ 					sta.push(*p); 				} 			} 			else   //空栈，则直接入栈 				sta.push(*p); 		} 		p++; 	} 	if (sta.empty()) 		return true; 	else 		return false; } int main(void) { 	char *strs[] = { "(10 20 [30 40] 50) 60 (70 80)", "(10 20 [30 40 50) 60", "(10 20 [30) 40] 50 60 (70 80)" }; 	for (int i = 0; i < sizeof(strs) / sizeof(*strs); i++) 	{ 		if (is_balance(strs[i])) 			cout << strs[i] << ends << "true" << endl; 		else 			cout << strs[i] << ends << "false" << endl; 	} 	cin.get(); 	return 0; }  经运行，通过测试

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


Question: 含有结构体的程序

引用 4 楼 tianzhenseu 的回复:[quote=引用 2 楼 mxway 的回复:] linklist point相当于lnode *point，你的point是一个指针，指向的内存地址为0。point->data=5，还没有指向任何有意义的地址就赋值。当然会运行出错了。已经按照你们说的解决了。  #include <stdio.h>  #include<stdlib.h>  typedef int datatype; typedef struct stacknode { 	datatype data; 	struct stacknode *next; }stacknode,*linkstack;  void InitStack(linkstack top) {   	top=NULL; }  int EmptyStack(linkstack top) { 	if(top==NULL)  		return 1; 	else         return 0; }  void Push(linkstack top,datatype x) { 	struct stacknode *p; 	p=(struct stacknode*)malloc(sizeof(struct stacknode)); 	p->data=x; 	p->next=top; 	top=p; }   void main() {     	linkstack top; 	InitStack(top); 	Push(top,3); 	Push(top,4); 	printf("%c\n",top->data); 	 } 这个链式堆栈的程序，为什么也会出现刚才那个问题呢？[/quote]写错了，是printf("%d\n",top->data);

引用 2 楼 mxway 的回复:linklist point相当于lnode *point，你的point是一个指针，指向的内存地址为0。point->data=5，还没有指向任何有意义的地址就赋值。当然会运行出错了。已经按照你们说的解决了。  #include <stdio.h>  #include<stdlib.h>  typedef int datatype; typedef struct stacknode { 	datatype data; 	struct stacknode *next; }stacknode,*linkstack;  void InitStack(linkstack top) {   	top=NULL; }  int EmptyStack(linkstack top) { 	if(top==NULL)  		return 1; 	else         return 0; }  void Push(linkstack top,datatype x) { 	struct stacknode *p; 	p=(struct stacknode*)malloc(sizeof(struct stacknode)); 	p->data=x; 	p->next=top; 	top=p; }   void main() {     	linkstack top; 	InitStack(top); 	Push(top,3); 	Push(top,4); 	printf("%c\n",top->data); 	 } 这个链式堆栈的程序，为什么也会出现刚才那个问题呢？

引用 1 楼 user-2 的回复:point 是指针，指针初始化为空所以出错太感谢了，终于解决了

point 是指针，指针初始化为空所以出错


Question: C语言编写点对点通信编译过不了

引用 18 楼 wyc7610 的回复:版主好认真......... 问题是这样的一个服务器能干什么？ 只能有一个连接进来， 还不检测这个连接是否有效不停止的接收， 即便编译通过意义不大， 建议再做功课， 补充下网络编程的理论知识和实现细节。 想学网络编程这类的有什么好的资料推荐吗

引用 17 楼 mymtom 的回复:还有一行也有问题 第10行  sockaddr_in sockaddr; 改为 struct sockaddr_in sockaddr; 谢谢版主不过还是不能呀  我比较笨求再指导

1. 在35行有中文空格 2. 在25行，send的第4个参数 NULL ===> 0 3. 在30行，recv的第4个参数 NULL ===> 0 4. 在03行，#pragma comment GCC不支持，注释掉 5. 链接参数加上 -lws2_32, 如六楼所说 然后就可以通过编译了。  #include <stdio.h>                   //用于printf等函数的调用 #include <winsock2.h>                //Socket的函数调用　 //#pragma comment (lib, "ws2_32")      //C语言引用其他类库时，除了.h文件外，还要加入对应的lib文件（这个不同于C#）  int main() {     WSADATA wsaData;     WSAStartup(MAKEWORD(2, 2), &wsaData);     SOCKET s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);     struct sockaddr_in sockaddr;     sockaddr.sin_family=PF_INET;     sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");   //需要绑定到本地的哪个IP地址     sockaddr.sin_port=htons(9000);                          //需要监听的端口     bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));        //进行绑定动作     listen(s, 1);                                           //启动监听     printf("listening on port [%d].\n", 9000);     while(TRUE)     {         SOCKADDR clientAddr;         int size=sizeof(SOCKADDR);         SOCKET clientsocket;         clientsocket=accept(s, &clientAddr, &size);               //阻塞，直到有新tcp客户端连接         printf("***SYS***    New client touched.\n");         char* msg="Hello, my client.\r\n";         send(clientsocket, msg, strlen(msg)+sizeof(char), 0);  //这里的第三个参数要注意，是加了一个char长度的         printf("***SYS***    HELLO.\n");         while(TRUE)         {             char buffer[MAXBYTE]={0};             recv(clientsocket, buffer, MAXBYTE, 0);            //一直接收客户端socket的send操作             printf("***Client***    %s\n", buffer);         }         closesocket(clientsocket);                                //关闭socket     }     closesocket(s);//关闭监听socket      WSACleanup();                                                //卸载     getchar();     exit(0); }

引用 10 楼 Eng_your 的回复:[quote=引用 8 楼 fly_dragon_fly 的回复:] 在link的右边 直接加上 -lws2_32 依然不行呀，是不是和我的编译器有关，我是CodeBlock，网上都是用VC？[/quote] 没仔细还以为是链接错误，原来是头文件不对 在mingw的gcc下只需要 #include <windows.h>就可以了

这样也不行

引用 12 楼 fly_dragon_fly 的回复:[quote=引用 10 楼 Eng_your 的回复:] [quote=引用 8 楼 fly_dragon_fly 的回复:] 在link的右边 直接加上 -lws2_32 依然不行呀，是不是和我的编译器有关，我是CodeBlock，网上都是用VC？[/quote] 没仔细还以为是链接错误，原来是头文件不对 在mingw的gcc下只需要 #include <windows.h>就可以了[/quote] 我#include<windows.h>放各种位置都不行

引用 7 楼 fanlvlgh 的回复:楼主你用的什么编译器？CodeBlocks

在link的右边 直接加上 -lws2_32

引用 7 楼 fanlvlgh 的回复:楼主你用的什么编译器？GNU GCC

引用 8 楼 fly_dragon_fly 的回复:在link的右边 直接加上 -lws2_32 依然不行呀，是不是和我的编译器有关，我是CodeBlock，网上都是用VC？

楼主你用的什么编译器？

但是对于第二条加了依然不行

引用 2 楼 user-6 的回复:1, 35行有中文空格 ,删掉  2, 右键project ->build option->linker setting  然后在lib libraries中添加: ws2_32 喔，但是对于第二条加了依然不行

因为你的程序是从网页上粘贴来的。

求教为什么编译过不了


Question: 菜鸟练习，求找错~

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

楼上说的是对的：  for(j=0;j<n;j++) 		printf("%lf\n",p[j]);

粗心： printf("%lf\n", p[j]);   //读取数据 误把j写成i

printf("%lf\n",p[j]);   //读取数据


Question: 快速排序算法出问题，求大神解释错在哪儿？

int m = low + (low + high)/2; 其中low=2,high=4，算一下m是多少

引用 1 楼 zhao4zhong1 的回复:先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c我主要是想知道，这个排序程序为什么会出错？

// 快速排序 void quick_sort (int data[], 	size_t left, size_t right) { 		size_t p = (left + right) / 2; 		int pivot = data[p]; 		size_t i = left, j = right; 		while (i < j) { 			for (; ! (i >= p || 				pivot < data[i]); ++i); 				if (i < p) { 					data[p] = data[i]; 					p = i; 				} 				for (; ! (j <= p || 					data[j] < pivot); --j); 					if (j > p) { 						data[p] = data[j]; 						p = j; 					} 		} 		data[p] = pivot; 		if (p - left > 1) 			quick_sort (data, left, p - 1); 		if (right - p > 1) 			quick_sort (data, p + 1, right); }

参考代码段 http://pan.baidu.com/s/17yIcQ

void qicksort(int a[],int left,int right)   {       int i,j;       if(left<right)       {           i=left;           j=right;           int temp=a[left];           do            {               while(a[j]>temp&&i<j)                   j--;               if(i<j)               {                   a[i]=a[j];                   i++;               }               while(a[i]<temp&&i<j)                   i++;               if(i<j)               {                   a[j]=a[i];                   j--;               }           } while (i<j);           a[i]=temp;           qicksort(a,left,i-1);           qicksort(a,i+1,right);       }   }

引用 5 楼 user-6 的回复:稍微读了一下代码： int m = low + (low + high)/2; 你确定m是这么计算的？是这样的，这一句只是为了选取中间位置的一个值而已，然后再在选出来的三个数中选择一个中间值。现在问题是在找三数中的中间值时，如果顺便交换下就会出现问题，如果不交换就正常。程序中注释的部分。不知道为什么？

引用 3 楼 xinsuixiaofeiyu 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c我主要是想知道，这个排序程序为什么会出错？[/quote] 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDEi中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 第十五章的课后题~~运行成功的程序有糊涂的地方

引用 1 楼 user-1 的回复:if((01&num) == 01)抱歉~~弄错了~~分没给你~~真是抱歉~~非常非常抱歉~~点错了~~

引用 1 楼 user-1 的回复:if((01&num) == 01)thank u~~

if((01&num) == 01)


Question: java代码转 c代码  求帮忙

帮啥。。自己根据java再看看c的写法不就成了，


Question: 关于LOWORD和HIWORD的使用

LOWORD The LOWORD macro retrieves the low-order word from the given 32-bit value.   WORD LOWORD(   DWORD dwValue  // value from which low-order word is retrieved );   Parameters dwValue  Specifies the value to be converted.  Return Values The return value is the low-order word of the specified value.   Remarks The LOWORD macro is defined as follows:   #define LOWORD(l)   ((WORD) (l))    QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in windef.h.  See Also Windows Overview, Window Macros, HIWORD, LOBYTE

我看介绍是在windef.h中定义的，加上windows.h头文件应该就可以了吧

引用 1 楼 hnwyllmm 的回复:明显没加头文件 网上搜一下头文件是哪个 加了显示重复定义

明显没加头文件 网上搜一下头文件是哪个


Question: 为什么while（feof(fp)）结束程序就结束了啊，求大神教导

没有必要用feof啊 很简单的题目，分成几个函数写，很简单的。  #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h>  #define WORDSIZE    15  struct word_list {     int    size;    /**< list size */     int    count;   /**< word count */     char **words;   /**< word array*/ };   /**   * @brief read a word from fp;  *   * @param fp  * @param word  *   * @return   */ char * read_word(FILE *fp, char *word) {     int num;      num = fscanf(fp, "%s", word);     if (num != 1)         return NULL;     return word; }   /**   * @brief initialize the word list  *   * @param list  * @param size  *   * @return   */ int init_list(struct word_list *list, int size) {     char **ptr;      ptr = (char **)malloc(sizeof(char *) * size);     if (ptr == NULL)         return -1;      list->size = size;     list->count = 0;     list->words = ptr;     return 0; }   /**   * @brief insert word into list;  *   * @param list  * @param word  *   * @return   */ int insert_word(struct word_list *list, const char *word) {     int i;      /* TODO: you can call realloc to resize the list */     if (list->count >= list->size)         return -1;      /* discard word 'THE' */     if (strlen(word) == 3         && toupper(word[0]) == 'T'         && toupper(word[1]) == 'H'         && toupper(word[2]) == 'E')         return -2;      /* Does the word already exist? */     for (i = 0; i < list->count; i++)         if (strcmp(word, list->words[i]) == 0)             return -3;      /* not exist, now insert it */     list->words[list->count++] = strdup(word);      return 0; }   /**   * @brief show list content  *   * @param list  */ show_list(const struct word_list *list) {     int i;      for (i = 0; i < list->count; i++) {         printf("%s\n", list->words[i]);     } }  int main(int argc, char *argv[]) {     struct word_list list;     char word[WORDSIZE + 1];      init_list(&list, 1024);     while (read_word(stdin, word)) {         insert_word(&list, word);     }      show_list(&list);      return 0; }

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


Question: 简单计算器程序求助

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


Question: 【EOF问题】ACM新手，在杭电做OJ exercise，为什么必须要有EOF才能通过？

当你把你的代码提交到OJ后，编译过后会通过重定向将预先写在文件中的测试用例来测试你的程序。但是文件中有多少组测试数据是不知道，所以只能通过判断是否读取到文件尾来判断。如果读取到文件尾，再用scanf等读取数据就会返回EOF

看题目只有一组数据还是多组数据

谢谢两位。


Question: 数据结构中MergeList中的ai和bj是什么意思

帮我改一下好么？  mergelist函数总是错误，刚刚学好多不懂的地方； #include <stdio.h> #include <malloc.h> #define MaxSize 50 typedef char ElemType; typedef struct  { 	ElemType elem[MaxSize];    	int length; } SqList;    void InitList(SqList *&L);    int ListEmpty(SqList *L);    void DispList(SqList *L);    int GetElem(SqList *L,int i,ElemType &e);    int ListInsert(SqList *&L,int i,ElemType e);    void MergeList(SqList La,SqList Lb,SqList &Lc);  int main()  	{    	SqList *La,*Lb,*Lc; 	ElemType e; 	printf("(1)初始化顺序表La\n"); 	InitList(La); 	printf("(2)依次采用尾插法插入3,5,8,11元素\n"); 	ListInsert(La,1,'3'); 	ListInsert(La,2,'5'); 	ListInsert(La,3,'8'); 	ListInsert(La,4,'11'); 	printf("(3)初始化顺序表Lb\n"); 	InitList(Lb); 	printf("(4)依次采用尾插法插入2,6,8,9,11,15,20元素\n"); 	ListInsert(Lb,1,'2'); 	ListInsert(Lb,2,'6'); 	ListInsert(Lb,3,'8'); 	ListInsert(Lb,4,'9'); 	ListInsert(Lb,5,'11'); 	ListInsert(Lb,6,'15'); 	ListInsert(Lb,7,'20'); 	MergeList(La,Lb,Lc); 	DispList(Lc); 	return 0; 	     }     void InitList(SqList *&L) { 	L=(SqList *)malloc(sizeof(SqList)*MaxSize); 	L->length=0; } int ListEmpty(SqList *L) { 	return(L->length==0); } void DispList(SqList *L) { 	int i; 	if (ListEmpty(L)) return; 	for (i=0;i<L->length;i++) 		printf("%c",L->elem[i]); 	printf("\n"); } int GetElem(SqList *L,int i,ElemType &e) { 	if (i<1 || i>L->length) 		return 0; 	e=L->elem[i-1]; 	return 1; } int ListInsert(SqList *&L,int i,ElemType e) { 	int j; 	if (i<1 || i>L->length+1) 		return 0; 	i--;							/*将顺序表位序转化为elem下标*/ 	for (j=L->length;j>i;j--)		/*将elem[i]及后面元素后移一个位置*/ 		L->elem[j]=L->elem[j-1]; 	L->elem[i]=e; 	L->length++;					/*顺序表长度增1*/ 	return 1; } void MergeList(SqList La,SqList Lb,SqList &Lc)  {  	InitList(Lc);  	int i=j=1; int k=0;  	La_len=ListLength(La); Lb_len=ListLength(Lb);  	while((i<=La_len)&&(j<=Lb_len))  	{ 	 	GetElem(La,i,ai); GetElem(Lb,j,bj); 	 	if(ai<bj){ListInsert(Lc ,++k,ai);++i;} 	 	else {ListInsert(Lc,++k,bj;)++j;} 	 } 	 while(j<=La_len){GetElem(La,i++,ai);ListInsert(Lc,++k,ai);} 	 while(j<=Lb_len){GetElem(Lb,j++,bj);ListInsert(Lc,++k.bj);}  }

额。。这个。 这个函数依赖于其他函数的，只是提供了一种思路，要把它写成可用的，需要根据不同语言来实现，这只是个算法思路