Question: 链表操作的疑问

建议学会画图 建议学会debugger。

引用 5 楼 u012299086 的回复:[quote=引用 3 楼 u010005508 的回复:] [quote=引用 2 楼 gqjjqg 的回复:] [quote=引用 楼主 u012299086 的回复:] 在使用链表解决约瑟夫环问题时有了一些疑惑，先贴上完成代码：  #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct _list {         int i;         struct _list *next; } list; void creatlist(list *head, int count) {         int i = 1;         list *pcur = head;         list *pnext;         while(--count)         {                 pnext = (list *)malloc(sizeof(list));                 i++;                 pnext->i = i;                 pcur->next = pnext;                 pcur = pnext;         }         pnext->next = head; }  void out(list *h,int m) {         int i = 1, cou = 0;         list *pc, *pn, *pp = NULL;         pc = pn = h;         while(pc != NULL)         {                 if(i == m)                 {                         printf("%d   \n", pc->i);                         pn->next = pc->next;  //1.pn = pc->next;                         free(pc);                        pc = pn->next; //  2.pc = pn;                         i = 1;                 }                 pn = pc;                 pc = pc->next;                 if(pc == pn)                 {                         printf("%d\n", pn->i);                         free(pc);                         break;                 }                 i++;         } } int main() {         int n;         list *head = (list *)malloc(sizeof(list));         head->i = 1;         head->next = NULL;         creatlist(head, 15);         out(head, 3); }    这个代码是从网上找的。 上述代码的1，2两处注释中是我的想法，但换照注释中的修改之后执行就会进入死循环。出错的原因是什么呢？  这段代码的目的是 释放PC，原本的写法，执行之后pn是不变的，pc释放之后pc变成了pc的next。 按楼主的写法，执行之后pn变成了pc的next，pc成了next的next。因为是环，所以最后剩下两个节点的时候，下面的判断进不去就死循环了。  [/quote] 如2楼所说，上图 [/quote] 嗯，非常感谢，已经明白了。大牛你这图是用什么工具做的啊？[/quote] 画图

引用 3 楼 u010005508 的回复:[quote=引用 2 楼 gqjjqg 的回复:] [quote=引用 楼主 u012299086 的回复:] 在使用链表解决约瑟夫环问题时有了一些疑惑，先贴上完成代码：  #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct _list {         int i;         struct _list *next; } list; void creatlist(list *head, int count) {         int i = 1;         list *pcur = head;         list *pnext;         while(--count)         {                 pnext = (list *)malloc(sizeof(list));                 i++;                 pnext->i = i;                 pcur->next = pnext;                 pcur = pnext;         }         pnext->next = head; }  void out(list *h,int m) {         int i = 1, cou = 0;         list *pc, *pn, *pp = NULL;         pc = pn = h;         while(pc != NULL)         {                 if(i == m)                 {                         printf("%d   \n", pc->i);                         pn->next = pc->next;  //1.pn = pc->next;                         free(pc);                        pc = pn->next; //  2.pc = pn;                         i = 1;                 }                 pn = pc;                 pc = pc->next;                 if(pc == pn)                 {                         printf("%d\n", pn->i);                         free(pc);                         break;                 }                 i++;         } } int main() {         int n;         list *head = (list *)malloc(sizeof(list));         head->i = 1;         head->next = NULL;         creatlist(head, 15);         out(head, 3); }    这个代码是从网上找的。 上述代码的1，2两处注释中是我的想法，但换照注释中的修改之后执行就会进入死循环。出错的原因是什么呢？  这段代码的目的是 释放PC，原本的写法，执行之后pn是不变的，pc释放之后pc变成了pc的next。 按楼主的写法，执行之后pn变成了pc的next，pc成了next的next。因为是环，所以最后剩下两个节点的时候，下面的判断进不去就死循环了。  [/quote] 如2楼所说，上图 [/quote] 嗯，非常感谢，已经明白了。大牛你这图是用什么工具做的啊？

引用 2 楼 gqjjqg 的回复:[quote=引用 楼主 u012299086 的回复:] 在使用链表解决约瑟夫环问题时有了一些疑惑，先贴上完成代码：  #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct _list {         int i;         struct _list *next; } list; void creatlist(list *head, int count) {         int i = 1;         list *pcur = head;         list *pnext;         while(--count)         {                 pnext = (list *)malloc(sizeof(list));                 i++;                 pnext->i = i;                 pcur->next = pnext;                 pcur = pnext;         }         pnext->next = head; }  void out(list *h,int m) {         int i = 1, cou = 0;         list *pc, *pn, *pp = NULL;         pc = pn = h;         while(pc != NULL)         {                 if(i == m)                 {                         printf("%d   \n", pc->i);                         pn->next = pc->next;  //1.pn = pc->next;                         free(pc);                        pc = pn->next; //  2.pc = pn;                         i = 1;                 }                 pn = pc;                 pc = pc->next;                 if(pc == pn)                 {                         printf("%d\n", pn->i);                         free(pc);                         break;                 }                 i++;         } } int main() {         int n;         list *head = (list *)malloc(sizeof(list));         head->i = 1;         head->next = NULL;         creatlist(head, 15);         out(head, 3); }    这个代码是从网上找的。 上述代码的1，2两处注释中是我的想法，但换照注释中的修改之后执行就会进入死循环。出错的原因是什么呢？  这段代码的目的是 释放PC，原本的写法，执行之后pn是不变的，pc释放之后pc变成了pc的next。 按楼主的写法，执行之后pn变成了pc的next，pc成了next的next。因为是环，所以最后剩下两个节点的时候，下面的判断进不去就死循环了。  [/quote] 非常感谢，终于明白了。

引用 2 楼 gqjjqg 的回复:[quote=引用 楼主 u012299086 的回复:] 在使用链表解决约瑟夫环问题时有了一些疑惑，先贴上完成代码：  #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct _list {         int i;         struct _list *next; } list; void creatlist(list *head, int count) {         int i = 1;         list *pcur = head;         list *pnext;         while(--count)         {                 pnext = (list *)malloc(sizeof(list));                 i++;                 pnext->i = i;                 pcur->next = pnext;                 pcur = pnext;         }         pnext->next = head; }  void out(list *h,int m) {         int i = 1, cou = 0;         list *pc, *pn, *pp = NULL;         pc = pn = h;         while(pc != NULL)         {                 if(i == m)                 {                         printf("%d   \n", pc->i);                         pn->next = pc->next;  //1.pn = pc->next;                         free(pc);                        pc = pn->next; //  2.pc = pn;                         i = 1;                 }                 pn = pc;                 pc = pc->next;                 if(pc == pn)                 {                         printf("%d\n", pn->i);                         free(pc);                         break;                 }                 i++;         } } int main() {         int n;         list *head = (list *)malloc(sizeof(list));         head->i = 1;         head->next = NULL;         creatlist(head, 15);         out(head, 3); }    这个代码是从网上找的。 上述代码的1，2两处注释中是我的想法，但换照注释中的修改之后执行就会进入死循环。出错的原因是什么呢？  这段代码的目的是 释放PC，原本的写法，执行之后pn是不变的，pc释放之后pc变成了pc的next。 按楼主的写法，执行之后pn变成了pc的next，pc成了next的next。因为是环，所以最后剩下两个节点的时候，下面的判断进不去就死循环了。  [/quote] 如2楼所说，上图

引用 楼主 u012299086 的回复:在使用链表解决约瑟夫环问题时有了一些疑惑，先贴上完成代码：  #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct _list {         int i;         struct _list *next; } list; void creatlist(list *head, int count) {         int i = 1;         list *pcur = head;         list *pnext;         while(--count)         {                 pnext = (list *)malloc(sizeof(list));                 i++;                 pnext->i = i;                 pcur->next = pnext;                 pcur = pnext;         }         pnext->next = head; }  void out(list *h,int m) {         int i = 1, cou = 0;         list *pc, *pn, *pp = NULL;         pc = pn = h;         while(pc != NULL)         {                 if(i == m)                 {                         printf("%d   \n", pc->i);                         pn->next = pc->next;  //1.pn = pc->next;                         free(pc);                        pc = pn->next; //  2.pc = pn;                         i = 1;                 }                 pn = pc;                 pc = pc->next;                 if(pc == pn)                 {                         printf("%d\n", pn->i);                         free(pc);                         break;                 }                 i++;         } } int main() {         int n;         list *head = (list *)malloc(sizeof(list));         head->i = 1;         head->next = NULL;         creatlist(head, 15);         out(head, 3); }    这个代码是从网上找的。 上述代码的1，2两处注释中是我的想法，但换照注释中的修改之后执行就会进入死循环。出错的原因是什么呢？  这段代码的目的是 释放PC，原本的写法，执行之后pn是不变的，pc释放之后pc变成了pc的next。 按楼主的写法，执行之后pn变成了pc的next，pc成了next的next。因为是环，所以最后剩下两个节点的时候，下面的判断进不去就死循环了。

仅供参考：//带表头结点的单向链表 #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-> //


Question: *string = toupper(*string++)出错的原因在哪里？

引用 18 楼 bravery36 的回复:不要做这种未定义行为然后问为什么，不作死就不会死，老老实实多写一行不是很好吗 当你还没有成为高手的时候，也会很明白什么叫“作死”吗，会知道自己怎么死的吗？

不要做这种未定义行为然后问为什么，不作死就不会死，老老实实多写一行不是很好吗

引用 15 楼 yangyunzhao 的回复:说个题外话，变量/参数名取个string是非常非常不好的习惯 由于该字符串没有特定功能，所以暂时没有想太多。 不过，谢谢提醒。

引用 13 楼 a30037338 的回复:前面那句我同意， 后面这句说的就像指针自增不是一种运算一样， 只要是运算， 难道没有优先级吗？ 有优先级 但是 优先级和表达式的副作用是没有关系的 有没有加一是副作用 优先级管不到

引用 9 楼 lin5161678 的回复:另外 ++优先级高于= 并不能得到赋值的时候指针已经加一这个判断 优先级 和 指针有没有加一 毫无关系  前面那句我同意， 后面这句说的就像指针自增不是一种运算一样， 只要是运算， 难道没有优先级吗？

说个题外话，变量/参数名取个string是非常非常不好的习惯

引用 9 楼 lin5161678 的回复:[quote=引用 8 楼 a30037338 的回复:] 如果不是，请说明你的见解， 而不是给个空泛的意见。 代码是错的 涉及未定义行为  你所说的 情况未必会出现   另外 ++优先级高于= 并不能得到赋值的时候指针已经加一这个判断 优先级 和 指针有没有加一 毫无关系 你根本没弄清楚优先级是干嘛的  这就是误人子弟[/quote] 如果说自增操作在语句中顺序不明，那么至少应该有输出吧？ 在toUpper函数开始处添加printf语句后，发现整个函数都没有执行。 我不知道将自增操作放入到赋值语句中后发生了什么事情，但为什么整个toUpper函数都不执行了呢？ 请给予解答，谢谢。

表达式求值序是一个偏序，不是全序，象++/--这种很容易出问题，改掉就好，由于行为未定义，运行结果就看编译器的人品了

同意5L，在彻底掌握++之前，实践时只把++单独写一行。

引用 8 楼 a30037338 的回复:如果不是，请说明你的见解， 而不是给个空泛的意见。 代码是错的 涉及未定义行为  你所说的 情况未必会出现   另外 ++优先级高于= 并不能得到赋值的时候指针已经加一这个判断 优先级 和 指针有没有加一 毫无关系 你根本没弄清楚优先级是干嘛的  这就是误人子弟

引用 6 楼 lin5161678 的回复:误人子弟的解释  请看置顶帖 学习 [/quote] 我只说一点， 造成程序崩溃的原因是不是如下解释： 后++的优先级要高于 = ， 也就是说 *string = toupper(*string++), 在赋值的时候， 指针已经加1（因为函数调用的关系，此时指针自增的值已经保存下来） 。这会造成每次赋值都给了后一位，致命的错误是最终把'\0'覆盖了， 导致下标越界。  如果不是，请说明你的见解， 而不是给个空泛的意见。

//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 | //+------------------+-----------------------------------------+---------------+

引用 4 楼 a30037338 的回复: void toUpper(char *string) {     while('\0' != *string){         *string = toupper(*string);  //优先级的问题， 后++的优先级要高于 = ， 也就是说 *string = toupper(*string++), 在赋值的时候，                                                         //指针已经加1了， 这会造成每次赋值都给了后一位，致命的错误是最终把'\0'覆盖了， 导致下标越界。         string++;     } } 误人子弟的解释  请看置顶帖 学习

置顶贴有说明.http://bbs.csdn.net/topics/370153775  如果看不懂就, 就永远把自加自减单独写一行.

引用 1 楼 user-9 的回复:右式求值后string指针就自增了，再赋值给左式。错了  你也去看置顶帖

看置顶帖

右式求值后string指针就自增了，再赋值给左式。


Question: 1>main.obj : error LNK2005: "class Student * stu" (?stu@@3PAVStudent@@A) 已经在 inp

从编译的错误提供看,是重定义问题. 在定义Sutdent.h文件的第一行加上  #pragma once

编译错误自己检查


Question: crc32算法求指点一二

引用 12 楼 u011845833 的回复:引用 11 楼 ForestDB 的回复:如果不是练习，建议使用库函数。windows下有何crc32库函数么? 这个应该问Google。

引用 10 楼 zhao4zhong1 的回复:这个挺好,感谢...

zlib难道不是windows下和linux下通用的？

如果不是练习，建议使用库函数。

引用 9 楼 u011845833 的回复:引用 8 楼 zhao4zhong1 的回复:zlib难道不是windows下和linux下通用的？这还真不知道耶,还没到你那个境界... http://blog.csdn.net/htttw/article/details/7616124

引用 4 楼 my_live_123 的回复:提供两个曾经用过的，一个直接计算，一个查表法非常感谢你的回答，很有帮助．

引用 3 楼 zhao4zhong1 的回复:我喜欢听话的孩纸。额，我想说，那个太复杂了，有木有简单点的，最好是windows下和linux下通用的...

提供两个曾经用过的，一个直接计算，一个查表法  #include <stdio.h>  #define CRC_G 	0x04C11DB7  int crc32(unsigned int m) { 	unsigned int reg = 0; 	unsigned char tmp; 	int i; 	for(i = 0; i < 32; ++i) 	{ 		tmp = (m >> (31 - i) & 1) ^ ((reg >> 31) & 1); 		reg <<= 1; 		reg ^=  tmp * CRC_G; 		reg >>= 1; 		reg <<= 1; 		reg |= tmp; 	} 	printf("0x%x, ", reg);  	return 0; }  int gen_crc() { 	unsigned int i; 	printf("unsigned int crc32_table[65536 * 65536] = {\n"); 	for(i = 0; i < 65536; ++i) 	{ 		crc32(i); 		if((i + 1) % 8 == 0) 		printf("\n"); 		getchar(); 	} 	printf("};\n"); 	return 0; }  int main() { 	gen_crc(); 	return 0; }   差表法  /*  * $Id: crc32.c,v 1.1.1.1 1996/02/18 21:38:12 ylo Exp $  * $Log: crc32.c,v $  * Revision 1.1.1.1  1996/02/18 21:38:12  ylo  * 	Imported ssh-1.2.13.  *  * Revision 1.2  1995/07/13  01:21:34  ylo  * 	Added cvs log.  *  * $Endlog$  */  /* The implementation here was originally done by Gary S. Brown.  I have    borrowed the tables directly, and made some minor changes to the    crc32-function (including changing the interface). //ylo */    /* ============================================================= */   /*  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or       */   /*  code or tables extracted from it, as desired without restriction.     */   /*                                                                        */   /*  First, the polynomial itself and its table of feedback terms.  The    */   /*  polynomial is                                                         */   /*  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0   */   /*                                                                        */   /*  Note that we take it "backwards" and put the highest-order term in    */   /*  the lowest-order bit.  The X^32 term is "implied"; the LSB is the     */   /*  X^31 term, etc.  The X^0 term (usually shown as "+1") results in      */   /*  the MSB being 1.                                                      */   /*                                                                        */   /*  Note that the usual hardware shift register implementation, which     */   /*  is what we're using (we're merely optimizing it by doing eight-bit    */   /*  chunks at a time) shifts bits into the lowest-order term.  In our     */   /*  implementation, that means shifting towards the right.  Why do we     */   /*  do it this way?  Because the calculated CRC must be transmitted in    */   /*  order from highest-order term to lowest-order term.  UARTs transmit   */   /*  characters in order from LSB to MSB.  By storing the CRC this way,    */   /*  we hand it to the UART in the order low-byte to high-byte; the UART   */   /*  sends each low-bit to hight-bit; and the result is transmission bit   */   /*  by bit from highest- to lowest-order term without requiring any bit   */   /*  shuffling on our part.  Reception works similarly.                    */   /*                                                                        */   /*  The feedback terms table consists of 256, 32-bit entries.  Notes:     */   /*                                                                        */   /*      The table can be generated at runtime if desired; code to do so   */   /*      is shown later.  It might not be obvious, but the feedback        */   /*      terms simply represent the results of eight shift/xor opera-      */   /*      tions for all combinations of data and CRC register values.       */   /*                                                                        */   /*      The values must be right-shifted by eight bits by the "updcrc"    */   /*      logic; the shift must be unsigned (bring in zeroes).  On some     */   /*      hardware you could probably optimize the shift in assembler by    */   /*      using byte-swap instructions.                                     */   /*      polynomial $edb88320                                              */   /*                                                                        */   /*  --------------------------------------------------------------------  */  static unsigned long crc32_tab[] = {       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,       0x2d02ef8dL    };  /* Return a 32-bit CRC of the contents of the buffer. */  unsigned long crc32(const unsigned char *s, unsigned int len) {   unsigned int i;   unsigned long crc32val;      crc32val = 0;   for (i = 0;  i < len;  i ++)     {       crc32val = 	crc32_tab[(crc32val ^ s[i]) & 0xff] ^ 	  (crc32val >> 8);     }   return crc32val; }

引用 2 楼 u011845833 的回复:引用 1 楼 zhao4zhong1 的回复:参考zlib\crc32.h和zlib\crc32.c好的，正在安装vm... 我喜欢听话的孩纸。


Question: #新手求帮忙修正！！！急！！拜托拜托

引用 2 楼 zhao4zhong1 的回复:仅供参考：//带表头结点的单向链表 #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-> //  非常仰慕赵老师

对链表的增删改参考用！ 链表的“增删改”  #include <stdio.h> #include <stdlib.h> struct node*creat(struct node *head); void Output(struct node *head); void Insert(struct node *head,int k); void Delete(struct node *head,int j); void Replace(struct node *head,int n); struct node {  	int data; 	struct node *next; }; int main(){      int a,b,c,d; 	struct node *head; 	head=NULL;   	head=creat(head);//新建链表 	Output(head);   	do{ 		printf("\n"); 		printf("请选择您要进行的操作：\n"); 		printf("----------------------------------------\n"); 		printf("1.添加新结点\n"); 		printf("2.删除结点\n"); 		printf("3.修改结点数据\n"); 		printf("4.退出\n"); 		printf("----------------------------------------\n"); 		printf("\n"); 		printf("请选择："); 		scanf("%d",&d);  	switch(d) 	{ 		case 1: 			printf("您选择了添加新结点\n"); 	       printf("请输入要插入结点位置:");//插入新结点 	       scanf("%d",&a); 	       Insert(head,a); 	       Output(head); 		   break; 		case 2: 			printf("您选择了删除结点\n"); 	       printf("请输入要删除的结点:");//删除结点 	       scanf("%d",&b); 	       Delete(head,b); 	       Output(head); 		   break; 		case 3: 			printf("您选择了修改结点数据\n"); 	       printf("请输入要修改结点的位置:");//修改结点数据            scanf("%d",&c); 	       Replace(head,c); 	       Output(head); 		   break; 		case 4: 			break; 	} 	}while(d!=4);  	//printf("\n"); 	//printf("请输入要插入结点位置:");//插入新结点 	//scanf("%d",&a); 	//Insert(head,a); 	//Output(head);  	//printf("\n"); 	//printf("请输入要删除的结点:");//删除结点 	//scanf("%d",&b); 	//Delete(head,b); 	//Output(head);   	//printf("\n"); 	//printf("请输入要修改结点的位置:");//修改结点数据 	//scanf("%d",&c); 	//Replace(head,c); 	//Output(head);  	return 0; } struct node *creat(struct node *head){  	int i,LEN; 	struct node *p,*s; 	printf("请输入链表的长度："); 	scanf("%d",&LEN); 	 	if(LEN>=1){ 		for(i=1;i<=LEN;i++){		           p=(struct node *)malloc(sizeof(struct node *)); 			 			if(head==NULL) 				s=head=p; 			printf("请输入第%d个结点中的数据：",i); 			scanf("%d",&p->data); 			p->next=NULL; 			s->next=p; 			s=p; 		} 	}return (head); } void Output(struct node *head){  	struct node *temp; 	temp=head; 	printf("新链表如下："); 	while(temp!=NULL){ 	 		printf("%d->",temp->data); 		temp=temp->next; 	} }  void Insert(struct node *head,int k){  	struct node *p1,*p2,*p3; 	int i; 	p3=p1=head; 	for(i=1;i<k;i++){ 		p1=p1->next; 	} 		for(i=1;i<k-1;i++){ 		p3=p3->next; 	} 	p2=(struct node *)malloc(sizeof(struct node)); 	printf("请输入新结点的数据："); 	scanf("%d",&p2->data); 	p2->next=p1; 	p3->next=p2; }  void Delete(struct node *head,int j){  	int i; 	struct node *p1,*p2,*p3; 	p1=p2=p3=head; 	for(i=1;i<=j;i++){ 		p2=p2->next; 	} 	/*p1->next=NULL; 	p3=p2->next; 	free(p2); 	p1->next=p3;*/  		for(i=1;i<j-1;i++){ 		p1=p1->next; 	} 			for(i=1;i<j+1;i++){ 		p3=p3->next; 	} 			p1->next=p3; 			//free(p2); }  void Replace(struct node *head,int n){  	int i,m; 	struct node *p; 	p=head; 	for(i=1;i<n;i++){ 		p=p->next; 	} 	printf("请输入该结点的新数据："); 	scanf("%d",&m); 	p->data=m; 	//free(p);  }

Create函数中的  p->next=NULL; r->next=p; r=p;  这三条语句放到  for(i=0;i<n;i++) { ... }  的最后面  for(i=0;i<n;i++) { ... p->next=NULL; r->next=p; r=p; }  不然链表只会存储最后一个学生的信息


Question: 虐心的问题，关于软件安全的，都快哭了

引用 6 楼 user-1 的回复:[quote=引用 5 楼 sinat_26815921 的回复:] [quote=引用 3 楼 user-1 的回复:] 2 A吧，3 B吧，不过这题目跟这个阅读有点搭不上的感觉啊。。有些东西阅读都没讲 第三题 a和d 好像也访问了非法内存了吧[/quote] 第三题感觉就没说清楚。。canary有很多种，AB可能都是对的，也可能都是错的对于不同的canary，比如如果只是在Buffer尾部存一个固定值，那么AB都是错的，D应该是错的，因为说了perhaps one outside the buffer's bounds，如果都超过Buffer了，那肯定没用。[/quote] 懂了 ，谢谢

引用 5 楼 sinat_26815921 的回复:[quote=引用 3 楼 user-1 的回复:] 2 A吧，3 B吧，不过这题目跟这个阅读有点搭不上的感觉啊。。有些东西阅读都没讲 第三题 a和d 好像也访问了非法内存了吧[/quote] 第三题感觉就没说清楚。。canary有很多种，AB可能都是对的，也可能都是错的对于不同的canary，比如如果只是在Buffer尾部存一个固定值，那么AB都是错的，D应该是错的，因为说了perhaps one outside the buffer's bounds，如果都超过Buffer了，那肯定没用。

引用 3 楼 user-1 的回复:2 A吧，3 B吧，不过这题目跟这个阅读有点搭不上的感觉啊。。有些东西阅读都没讲 第三题 a和d 好像也访问了非法内存了吧

能具体说一下吗？第一题是怎么回事呢？我也觉得给的材料很装B,希望能具体讲讲呗，谢谢了

楼主再顶

楼主自顶


Question: C语言习作：计算Mod型函数值源程序。感觉写得不简洁，高手看能不能改进下。

引用 3 楼 pathletboy 的回复:我都怀疑我用的是不是真的C语言了 怎么说？有什么不对的么

引用 1 楼 a1193561652 的回复:变量c未初始化就n=(a-c)/b;没问题吗？ 要得到余数可以 return   a-(a/b)*b; 另外汇编中的整除指令就是高位放余数，低位放商的。所以是可以用%直接得出余数，为什么要写这样一个函数？ 就是为了基础，所以要特别定义一下。

怎么说？有什么不对的么？

我都怀疑我用的是不是真的C语言了

被楼主惊出一身冷汗。


Question: VS控制台算除法出错

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

引用 2 楼 zxh707wk 的回复:不要把宏定义当成有括号的  好吧，谢谢

引用 1 楼 user-3 的回复:(SAMPLE/BEAT)* FID = (250 / 250 / 2) * 200 = (1 / 2) * 200 = 0 * 200 =0  啊，这样，！！！啊，好吧，，，谢谢！！！！

引用 1 楼 user-3 的回复:(SAMPLE/BEAT)* FID = (250 / 250 / 2) * 200 = (1 / 2) * 200 = 0 * 200 =0+1，不要把宏定义当成有括号的


Question: 文件指针问题

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

p->data.stuNam是地址，不需要再取地址，你是不是想输入一个字符串进去？

for(p=h;!(feof(fp));)  {         p -> next = (ListPtr) malloc (sizeof (ListNode));         //p=p->next;         fscanf(fp,"%ld %s",&(p->next->data.age),&(p->next->data.stuName));         h->data.age++;  }

lz想问啥

有什么问题？LZ

快来看哪，楼主提了一个和文件指针有关的问题！


Question: 测试的时候数字总是错误

试试将代码中的所有float替换为double 再将 if(s1=s2) 替换为 if (fabs(s1-s2)<1E6)

看不出其它问题了，楼主可以开始调试了....

引用 5 楼 zhouxiaofeng1021 的回复:void compare(float x[],float y[],float r[],int a,int b) 两个圆的关系计算 是不是有点问题： 两个圆可能相交，外离，内含，相切，或者重合 昨天已经修改了~thank you

引用 1 楼 hnwyllmm 的回复:if(s1=s2) { 比较相等不能这样比呀 还有，double类型的相等也不是这样做的，楼主搜索一下吧，拓展一下知识面  好的！还有其他的吗


Question: C语言自建目录的权限问题

对于umask的用法我自己查过的，但有两件事很奇怪： 1.为什么会有粘滞位T，umask只能设三位，对特殊位没法设 1.系统默认的umask是0002，这和输出的结果是一致的。可是，生成文件夹的权限是不一样的。奇数次和偶数次还不一样，如果我算的没错的话分别是426和567

The umask function sets the file mode creation mask for the process and returns the previous value. (This is one of the few functions that doesn’t have an error return.) #include <sys/stat.h> mode_t umask(mode_t cmask); Returns: previous file mode creation mask

umask返回旧的值。 第一次输出，说明是shell的位码，后面3个输出都是都是上次设置的值。

这事和C语言没有半点关系。


Question: 菜鸟求解释缓冲区和fflush函数

没会什么直接的方法,只有张 stdin缓冲区的数据读取出来,再输出 简单点这样就可以了  int main(int argc, char *argv[]) { 	char c; 	getchar(); 	 	while ( 10 != (c = getchar()) )    // 10 : 输入结束/换行符 		putchar(c);  	return 0; }

引用 7 楼 dooX8086 的回复:缓冲区是独立的. 这样不理解么~? getchar();  // 缓冲区张三 ----> stdin fflush( stdout); // 缓冲区李四 ----> stdout  ----------------------------------------------------------------- fflush(stdout)  // 叫缓冲区李四回家吃饭,  所以....缓冲张三还在网吧...  如果想要实现我原本的意图，该如何做。 将剩余的在屏幕上显示出来

引用 7 楼 dooX8086 的回复:缓冲区是独立的. 这样不理解么~? getchar();  // 缓冲区张三 ----> stdin fflush( stdout); // 缓冲区李四 ----> stdout  ----------------------------------------------------------------- fflush(stdout)  // 叫缓冲区李四回家吃饭,  所以....缓冲张三还在网吧... 赞！！！！！！！！！！！！！！ 意思stdin和stdout，占用了两个不同的缓冲区是吧

引用 5 楼 dooX8086 的回复:文件(句柄)缓冲区是"私有""的.如 fopen(A),  fopen(B)./ soket(A) socket(B) 等... 会产生两个独立的 A  B缓冲区.... 而 fflush 将缓冲的数据写回自己的文件(句柄) 没看懂，请问这个什么情况 #include<stdio.h> int main() { 	    getchar();    //输入“abcdef”，缓冲区产生亢余 		fflush(stdout);   //预想输出“bcdef”，实际输出为NULL 		return 0; }

引用 3 楼 my_live_123 的回复:你打开一个文件，没有执行相应的读写操作，也就不存在对应的缓冲区。你fflush当然会失败！因此在打开一个文件后，并没有给你分配缓冲区，这这个时间点上，其实给用户一个改变缓冲区大小的权利！你可以尝试对m进行一些读写操作，然后再fflush它 能否帮我看看一楼那个程序。

fflush Flushes a stream.  int fflush( FILE *stream );  Function Required Header Compatibility  fflush <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  fflush returns 0 if the buffer was successfully flushed. The value 0 is also returned in cases in which the specified stream has no buffer or is open for reading only. A return value of EOF indicates an error.  Note   If fflush returns EOF, data may have been lost due to a write failure. When setting up a critical error handler, it is safest to turn buffering off with the setvbuf function or to use low-level I/O routines such as _open, _close, and _write instead of the stream I/O functions.  Parameter  stream  Pointer to FILE structure  Remarks  The fflush function flushes a stream. If the file associated with stream is open for output, fflush writes to that file the contents of the buffer associated with the stream. If the stream is open for input, fflush clears the contents of the buffer. fflush negates the effect of any prior call to ungetc against stream. Also, fflush(NULL) flushes all streams opened for output. The stream remains open after the call. fflush has no effect on an unbuffered stream.  Buffers are normally maintained by the operating system, which determines the optimal time to write the data automatically to disk: when a buffer is full, when a stream is closed, or when a program terminates normally without closing the stream. The commit-to-disk feature of the run-time library lets you ensure that critical data is written directly to disk rather than to the operating-system buffers. Without rewriting an existing program, you can enable this feature by linking the program’s object files with COMMODE.OBJ. In the resulting executable file, calls to _flushall write the contents of all buffers to disk. Only _flushall and fflush are affected by COMMODE.OBJ.  For information about controlling the commit-to-disk feature, see Stream I/O, fopen, and _fdopen.  Example  /* FFLUSH.C */  #include <stdio.h> #include <conio.h>  void main( void ) {    int integer;    char string[81];     /* Read each word as a string. */    printf( "Enter a sentence of four words with scanf: " );    for( integer = 0; integer < 4; integer++ )    {       scanf( "%s", string );       printf( "%s\n", string );    }     /* You must flush the input buffer before using gets. */    fflush( stdin );    printf( "Enter the same sentence with gets: " );    gets( string );    printf( "%s\n", string ); }   Output  Enter a sentence of four words with scanf: This is a test This is a test Enter the same sentence with gets: This is a test This is a test   Stream I/O Routines  See Also   fclose, _flushall, setvbuf

另一个例子，依旧失败： #include<stdio.h> #include<stdlib.h> int main() { 	FILE *p,*m; 	char n; 		m=fopen("M","w"); 		n=getchar();  //输入“aaaaaaaa”,键盘输入产生缓冲区亢余 		fflush(m);      //想要将剩余的字符传入给m文件 		return 0; }


Question: C语言数组在内存的里是怎样布局的？

解释的很好啊，不错。Thank for sholber. :)

更正一下： “ 标准又说，除非做为运算符sizeof和一元&的操作数，数组类型的标识符将被转换为指向其首元素的指针。 ” 其中，数组类型的标识符改为“数组类型的表达式”。考虑如下声明： struct t {int a [22]; float f;} t [3]; 则表达式 t [0].a 是数组类型的表达式。它会被转换为指向其首元素的指针： int * p = t [0].a;

比如，现在有一维数组定义如下： int arr[5]={1,2,3,4,5};  我们都知道 数组名arr是代表数组首元素的地址即arr[0]的地址。 我很想知道，为什么成千上万的初学者，非得要纠结数组名，以及数组地址的问题。另：数组名代表数组首元素的地址，这个荒唐啊。   那在数组名前面加上取地址符&，即&arr，打印出的地址同样也是arr[0]的地址。   比如      printf("arr=%x\n&arr=%x\n&arr[0]=%x\n", arr, &arr, &arr[0]);    假设 现在有一个数组指针定义如下：  int (*p)[5]=NULL;   p=&arr;// 这样赋值就不会报错。  p=arr; // 但是这样赋值就会报错。&arr与arr的指向的地址相等的，那么为什么还会报错呢？ 这正是我恶心数组名和数组地址之类措辞的原因。因为，只用类型即可解释一切与数组有关的问题。标准说，对于表达式&E，若E的类型是T，则表达式&E的结果是指向T的指针。因为arr是数组，故&arr的结果是指向数组的指针。 标准又说，除非做为运算符sizeof和一元&的操作数，数组类型的标识符将被转换为指向其首元素的指针。因此，p=arr中，arr会被转换为指向其首元素的指针。因为元素的类型是int，故表达式arr转换后的类型是int *，与运算符=的左操作数p的类型不兼容。    假设，现在再定义一个二维数组如下：  int arr2[4][5]={...};   p=arr2;  // 而这样就不会报错。  p=&arr2; // 报错。 arr2是一个数组，其元素类型也是数组。从前面说的，arr2被转换为指向其首元素的指针，也就是指向数组的指针（元素类型也是数组嘛），即int (*) [5]与p的类型兼容。相应地，&arr2的结果是指向数组的指针int (*) [4][5]，尽管也是指向数组的指针，但与p的类型不兼容。   麻烦解释下 “数组名”与“&数组名”分别在一维、二维或更多维数组里的区别和作用？ 最好能给出它们在内存，组织的原理或示意图。  以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

理解和讨论之前请先学会如何观察！  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）


Question: Error: 2006: MySQL server has gone away

嗯，把 MYSQL_OPT_RECONNECT打开后会自动重连，，问题解决了。。感谢！

原因是长时间没有操作数据库，数据库连接自动断了。我去年也遇到过这个问题，方法是在连接数据库的时候启用MYSQL_OPT_RECONNECT，然后每次执行出错的时候ping一下server，我这里有部分代码：  int Mysql::insertRecord(std::string const &ip,     std::string const &path,     std::string const &operation,     char const *before,     char const *after) {   /**/   if (!connected_)     return -2;   /**/    std::string path2 = _convertText(path.c_str());   std::string before2 = _convertText(before);   std::string after2 = _convertText(after);    std::string sql =     "INSERT INTO ZooOp(ip,path,operation,`before`,`after`) VALUES(";   /* 1) ip */   sql += "'"; sql += ip; sql += "'";   /* 2) path */   sql += ",'"; sql += path2; sql += "'";   /* 3) operation */   sql += ",'"; sql += operation; sql += "'";   /* 4) before */   sql += ",'"; sql += before2; sql += "'";   /* 5) after */   sql += ",'"; sql += after2; sql += "')";    return _apply(sql);   /*   printf("[%s]\n", sql.c_str());   return 0;   */ }  int Mysql::_error_handler(std::string const &sql) {   do {     /* 1) ping */     int ping_ret = mysql_ping(&mysql_);     if (0 == ping_ret)       break;     /* 2) reconnect */     connect();     if (connected_)       break;     return -1;   } while (0);    mysql_query(&mysql_, "set names utf8");   if (0 != mysql_query(&mysql_, sql.c_str())) {     printf("mysql: %s\n", mysql_error(&mysql_));     return -2;   }   return 0; }  int Mysql::_apply(std::string const &sql) {   if (0 != mysql_query(&mysql_, sql.c_str()))     return _error_handler(sql);   return 0; }  int Mysql::connect() {   if (connected_) {     mysql_close(&mysql_);     connected_ = false;   }    int retval;   MYSQL *conn;    conn = mysql_init(&mysql_);   if (NULL == conn)     return -1;    do {     conn = mysql_real_connect(&mysql_,         host_.c_str(), username_.c_str(), password_.c_str(),         database_.c_str(), port_, NULL, 0);     if (NULL == conn)       break;     char value = 1;     retval = mysql_options(&mysql_, MYSQL_OPT_RECONNECT, &value);   } while (0);    if (NULL == conn || 0 != retval)     mysql_close(&mysql_);   else     connected_ = true;    mysql_query(&mysql_, "set names utf8");    return connected_ ? 0 : -2; }  int Mysql::disconn() {   if (connected_) {     mysql_close(&mysql_);     connected_ = false;   }   return 0; }


Question: 用链表存一组数，挂了，求大牛帮主

BUG:  Pnumber p,pTop,pTemp; void List_Init(Pnumber p){     p=(Pnumber)malloc(sizeof(numbdata));     if(!p){         printf("Error");         }  }  分析： 当调用 List_Init（p）时，全局作用域的p（Pnumber p）复制给局部作用域的参数p(void List_Init(Pnumber p){)，栈上生成一个新的栈帧，将参数p压栈，函数内执行动态内存分配，把内存地址赋值给p。当函数执行完毕，当前栈帧弹出，局部p自动消亡。全局的p没发生任何变化。  补丁：  - void List_Init(Pnumber p){ -    p=(Pnumber)malloc(sizeof(numbdata)); -    if(!p){ +void List_Init(Pnumber *p){ +    *p=(Pnumber)malloc(sizeof(numbdata)); +    if(!(*p)){  -List_Init(p); +List_Init(&p);

首先你的分配函数要修改如下：  // 因为要把地址传出去，所以参数要用指针的指针，并且最好把next赋NULL void List_Init(Pnumber *p){     *p=(Pnumber)malloc(sizeof(numbdata));     mallocTimes++;     if(!*p){         printf("Error");     }     (*p)->next = NULL; }  而且每次链表连接不对，并在最后没有释放内存，具体如下：      int a[ARRAY1_LENGTH],b[ARRAY2_LENGTH];     int i,j,k,elem1,elem2,d;     printf("请向数组a输入10个非递减数字：\n");      for(i=0;i<ARRAY1_LENGTH;i++){         scanf("%d",&a[i]);      }     printf("请向数组b输入8个非递减数字：\n");     for(i=0;i<ARRAY2_LENGTH;i++){         scanf("%d",&b[i]);     }      i=0,j=0,k=0;     List_Init(&p);     pTemp=p;     pTop=p;     while(i<ARRAY1_LENGTH-1&&j<ARRAY2_LENGTH-1){         Select(a,&elem1,i);         Select(b,&elem2,j);          d=Compare(elem1,elem2);         if(d){             Insert(&pTop->number,elem1);             List_Init(&p);             pTop->next = p;             pTop = p;             i++;         }         else{             Insert(&pTop->number,elem2);             List_Init(&p);             pTop->next = p;             pTop = p;             j++;         }     }     while(i<ARRAY1_LENGTH){         Select(a,&elem1,i);         Insert(&pTop->number,elem1);         List_Init(&p);         pTop->next = p;         pTop = p;         i++;     }     while(j<ARRAY2_LENGTH){         Select(b,&elem2,j);         Insert(&pTop->number,elem2);         List_Init(&p);         pTop->next = p;         pTop = p;         j++;     }     pTop=pTemp;     for(i=0;i<ARRAY1_LENGTH+ARRAY2_LENGTH;i++){         printf("%d\t",pTop->number);         pTop=pTop->next;     }      // 释放内存     pTop = pTemp;     Pnumber pTemp2 = pTop;     while (pTemp2){         pTop = pTop->next;         free(pTemp2);         pTemp2 = pTop;     }

仅供参考：//带表头结点的单向链表 #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-> //


Question: #if defined (_M_IA64) 的解释？

引用 5 楼 zhao4zhong1 的回复:Got it!

查MSDN是Windows程序员必须掌握的技能之一。  The #if, #elif, #else, and #endif Directives The #if directive, with the #elif, #else, and #endif directives, controls compilation of portions of a source file. If the expression you write (after the #if) has a nonzero value, the line group immediately following the #if directive is retained in the translation unit.  Syntax  conditional :  if-part elif-partsopt else-partopt endif-line  if-part :  if-line text  if-line :  #if constant-expression #ifdef identifier #ifndef identifier  elif-parts :  elif-line text elif-parts elif-line text  elif-line :  #elif constant-expression  else-part :  else-line text  else-line :  #else  endif-line :  #endif  Each #if directive in a source file must be matched by a closing #endif directive. Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. The #else directive, if present, must be the last directive before #endif.   The #if, #elif, #else, and #endif directives can nest in the text portions of other #if directives. Each nested #else, #elif, or #endif directive belongs to the closest preceding #if directive.  All conditional-compilation directives, such as #if and #ifdef, must be matched with closing #endif directives prior to the end of file; otherwise, an error message is generated. When conditional-compilation directives are contained in include files, they must satisfy the same conditions: There must be no unmatched conditional-compilation directives at the end of the include file.  Macro replacement is performed within the part of the command line that follows an #elif command, so a macro call can be used in the constant-expression.  The preprocessor selects one of the given occurrences of text for further processing. A block specified in text can be any sequence of text. It can occupy more than one line. Usually text is program text that has meaning to the compiler or the preprocessor.  The preprocessor processes the selected text and passes it to the compiler. If text contains preprocessor directives, the preprocessor carries out those directives. Only text blocks selected by the preprocessor are compiled.  The preprocessor selects a single text item by evaluating the constant expression following each #if or #elif directive until it finds a true (nonzero) constant expression. It selects all text (including other preprocessor directives beginning with #) up to its associated #elif, #else, or #endif.  If all occurrences of constant-expression are false, or if no #elif directives appear, the preprocessor selects the text block after the #else clause. If the #else clause is omitted and all instances of constant-expression in the #if block are false, no text block is selected.  The constant-expression is an integer constant expression with these additional restrictions:   Expressions must have integral type and can include only integer constants, character constants, and the defined operator.   The expression cannot use sizeof or a type-cast operator.   The target environment may not be able to represent all ranges of integers.   The translation represents type int the same as type long, and unsigned int the same as unsigned long.   The translator can translate character constants to a set of code values different from the set for the target environment. To determine the properties of the target environment, check values of macros from LIMITS.H in an application built for the target environment.    The expression must not perform any environmental inquiries and must remain insulated from implementation details on the target computer.  The preprocessor operator defined can be used in special constant expressions, as shown by the following syntax:  Syntax  defined( identifier )  defined identifier  This constant expression is considered true (nonzero) if the identifier is currently defined; otherwise, the condition is false (0). An identifier defined as empty text is considered defined. The defined directive can be used in an #if and an #elif directive, but nowhere else.  In the following example, the #if and #endif directives control compilation of one of three function calls:  #if defined(CREDIT)     credit(); #elif defined(DEBIT)     debit(); #else     printerror(); #endif  The function call to credit is compiled if the identifier CREDIT is defined. If the identifier DEBIT is defined, the function call to debit is compiled. If neither identifier is defined, the call to printerror is compiled. Note that CREDIT and credit are distinct identifiers in C and C++ because their cases are different.  The conditional compilation statements in the following example assume a previously defined symbolic constant named DLEVEL.  #if DLEVEL > 5     #define SIGNAL  1     #if STACKUSE == 1         #define STACK   200     #else         #define STACK   100     #endif #else     #define SIGNAL  0     #if STACKUSE == 1         #define STACK   100     #else         #define STACK   50     #endif #endif #if DLEVEL == 0     #define STACK 0 #elif DLEVEL == 1     #define STACK 100 #elif DLEVEL > 5     display( debugptr ); #else     #define STACK 200 #endif  The first #if block shows two sets of nested #if, #else, and #endif directives. The first set of directives is processed only if DLEVEL > 5 is true. Otherwise, the statements after #else are processed.  The #elif and #else directives in the second example are used to make one of four choices, based on the value of DLEVEL. The constant STACK is set to 0, 100, or 200, depending on the definition of DLEVEL. If DLEVEL is greater than 5, then the statement   #elif DLEVEL > 5 display(debugptr);  is compiled and STACK is not defined.  A common use for conditional compilation is to prevent multiple inclusions of the same header file. In C++, where classes are often defined in header files, constructs like the following can be used to prevent multiple definitions:  // EXAMPLE.H - Example header file  #if !defined( EXAMPLE_H ) #define EXAMPLE_H  class Example { ... };  #endif // !defined( EXAMPLE_H )  The preceding code checks to see if the symbolic constant EXAMPLE_H is defined. If so, the file has already been included and need not be reprocessed. If not, the constant EXAMPLE_H is defined to mark EXAMPLE.H as already processed.  Microsoft Specific   Conditional compilation expressions are treated as signed long values, and these expressions are evaluated using the same rules as expressions in C++. For example, this expression:  #if 0xFFFFFFFFL > 1UL  is true.  END Microsoft Specific

引用 3 楼 worldy 的回复:#if defined (_M_IA64)  生成菜单配置里面根据设置产生的宏奥~ 有些明白了

#if defined (_M_IA64)  生成菜单配置里面根据设置产生的宏

引用 1 楼 user-3 的回复:预编译宏处理，如果定义了_M_IA64这个宏则编译if defined这段，没有则编译else那一段这段代码是memcpy的源代码，第一个#if是按照顺序进行内存复制，#else则是检测到发生了源地址和目的地址有重叠，所以采取从后往前复制，所以这个if宏是分界点。我想问的是，_M_IA64有什么意义吗？我看博客说，_M_IA64：为Itanium处理器家族的64位处理器（IA64）架构定义。这个架构定义和本程序的逻辑判断有关系吗？


Question: 偶数求和（C）

自己写代码，有问题贴出来问问题.....

引用 1 楼 hnwyllmm 的回复:楼主，你有什么问题，倒是说啊求完整的C程序啊……

求完整的C程序啊……不是要求都写了么

楼主，你有什么问题，倒是说啊


Question: [SWU]用 echo $?只能看到最后的一个返回值，怎么看之前的函数中得返回值

但是我突然想到， 如果我没有搜索到模式字符串，我应该不再执行，但是我这个搜索是在函数里做的，我该怎么办，才能实现如果未找到模式字符串，就中断执行呢？

我把修改后的代码发上来。   1 #include<stdio.h>   2 #include<string.h>   3    4 #define FILE_NAME               "t0319.txt"   5 #define BUFFER_MAX              50   6    7 #define ERROR_FAIL_OPEN_FILE    -1   8    9 int judge();  10   11 char buffer[BUFFER_MAX];  12   13 int main()  14 {  15         FILE *fp;  16         int i, j;  17         char buffer[BUFFER_MAX];  18         int m, n;  19         char temp;  20   21         fp = fopen(FILE_NAME, "r+");  22   23         //Check for failing to open fiel  24         if(fp == NULL){  25   26                 printf("Fail to open file: %s\n", FILE_NAME);  27   28                 return ERROR_FAIL_OPEN_FILE;  29         }  30   31         //Get each char  32         for(i = 0; i < BUFFER_MAX; i++){  33   34                 buffer[i] = fgetc(fp);  35                 if(feof(fp))  36                         break;  37         }  38   39         printf("The length of the string: %d\n", i-1);  40   41         //judge string or not  42         int judge();  43   44         //Exchange  45         for(m = 0, n = i-2; m < n; m++, n--){  46   47                 temp = buffer[m];  48                 buffer[m] = buffer[n];  49                 buffer[n] =temp;  50         }  51   52         //Print out after exchange  53         printf("After exchange: \n");  54         for(j = 0; j < i-1; j++)  55                 printf("%c", buffer[j]);  56   57         printf("\n");  58   59         fclose(fp);  60   61         return 0;  62 }  63   64 //judge string or not  65 int judge(){  66   67         char *p;  68         p = strstr(buffer, "12");  69         if(p == NULL)  70                 return 0;  71         else  72                 return 1;  73   74 }

函数一旦返回就结束了。 echo $?就是函数的返回值。 可以适当用用gdb

引用 1 楼 arthuryangsh 的回复:39-47行：不应该在函数中定义函数。虽然编译器可以忍受，但现在的写法judge这个函数是不会执行的。应该在main函数外部定义此函数，并在main函数中调用此函数，就像调用printf那样。 要想看到judge的返回值，可以在main中调用并打印： printf("judge() return %d\n", judge());  我知道只能嵌套使用，但是不可以定义。 但是我好像没弄清嵌套和定义有啥区别。  就是 把函数的定义 移在main外面就叫嵌套使用了么？  不懂诶。 其实本来我查半天找到strstr这个函数。想重新定义个类似的让返回值直接满足要求。 但是那个strstr的函数实现中间的有点儿看不懂。


Question: 两个升序排列的数组，用一个for循环找出两个数组中相同元素的个数

for遍历第一个数组，每次遍历时又遍历第二个数组，看是否有相等  为了提高效率，遍历第二个数组时，如果发现当前遍历的数字已经大于第一个数组当前的数，则可退出循环

for循环遍历第一个数组，然后每个元素和第二个数组的元素比较，比如指向A数组的指针pa，和指向B数组的指针pb。for(pa=A.begin();pa!=A.end();){    if(pb==B.end())       break;    if(*pa==*pb){       ++count;       ++pa;       ++pb;    }    else if(*pa<pb){       ++pa;    }    else       ++pb;    } }

#include <stdio.h>  #define ARRARY_SIZE (5)  int main(void) { 	int count = 0; 	int a[ARRARY_SIZE] = {0, 1, 2, 3, 4}; 	int b[ARRARY_SIZE] = {0, 1, 3, 5, 6}; 	int* pa = a; 	int* pb = b;  	for(;pa != (a + ARRARY_SIZE);) 	{ 		if (pb == (b + ARRARY_SIZE)) 		{ 			break; 		}  		if (*pa == *pb) 		{ 		  count++; 		  pa++; 		  pb++; 		} 		else if(*pa < *pb) 		{ 			pa++; 		} 		else 		{ 			pb++; 	   } 	}  	printf("count = %d\n", count);  	return 0; }


Question: 字符串的排序问题

我搞错了一个 {  }， 	for(i=0;i<n-1;i++)        	{ 		k=i; 		for(j=i+1;j<n;j++) 			if(strcmp(str[k],str[j])>0) 				k=j; 		if(k!=i) 		{ 			strcpy(temp,str[i]); 			strcpy(str[i],str[k]); 			strcpy(str[k],temp); 		} 		}

把for(i=0;i<n;i++) { fputs(str[i],fp); fputs("\n",fp); printf("%s\n",str[i]); }  放在最后一个}之前


Question: 关于自加和自减的小白问题

带有a的表达式不影响a自身的值，比如a=20,则a+10的值是30，但是a的值依然是20.  a++属于自增表达式，既可等价于a = a+1,潜在的存在赋值过程。

++a 是先加再取值 a++ 是取完值再加 但是两个都能让a的值增加1

a++自身改变，a+1自身不改变

引用 18 楼 sholber 的回复:[quote=引用 17 楼 my_live_123 的回复:]  #include<stdio.h> int main(){    int a=100;    printf("%d\n",a++);          //把a = 100传参进去，printf得到100，然后a自加得a=101    printf("%d\n",++a);          //前缀++，先执行自加得a=102,然后把参数传102给printf，此时a=102    printf("%d\n",--a);           //前缀--，先执行自减得a=101，,然后把参数101传给printf，此时a=101    printf("%d\n",a--);           //把a = 101传参进去，printf得到101，然后a自减得a=100    printf("%d\n",a+1);         //a+1=101，传参101进去，此时a = 100    printf("%d\n",a);             //a=100    return 0; }   完全无视表达式求值的顺序。    printf("%d\n",a++);          //把a = 100传参进去，printf得到100，然后a自加得a=101 这个“传参”和“然后”用得好，意味着a++的副作用后序于参数传递。怎么这么肯定呢？ [/quote]    好吧，宏观上先这么理解吧。微观上对后缀自加自减，是先把旧值放到一个寄存器里，然后自加或自减后的值放入另外一个寄存器里，然后把A：旧值用于表达式，B：新值写回内存。至于A和B这个顺序和编译器有关了！目前都是先B后A！先A后B先也是正确的。因为都是寄存器里的值。

区别：a ++和++ a前者是先使用后加1，后者是先加1后使用，执行第一条语句printf("%d\n",a++); 属于先使用后加1，所以先打印100，然后加1变成101，在执行第二条语句printf("%d\n",++a);此时是先加1，再使用，所以打印出102，以下语句同上。

引用 13 楼 user-12 的回复:另外，++是一元运算符，它只作用于一个量，+是二元运算符，需要2个量  printf("%d\n",a++)   由于是一元运算符，只根据++位置对a操作，++运算完毕后，a的值发生改变 printf("%d\n",a+1)   由于是二元运算符，需要先完成a+1的运算，再输出，另外，a+1的结果是存在一个临时的内存中，a的值不会发生改变  谢谢 很详细

引用 10 楼 jiht594 的回复:[quote=引用 5 楼 z549069443 的回复:] [quote=引用 1 楼 u011041927 的回复:] a +1 时 a是100，运算过后，a还是100 我可以理解为 前面4个自加和自减都是依次给a赋值吗？后面的还是a=100。[/quote] 不论前置还是后置的++--都是赋值的. a+1没有赋值, a当然不变量[/quote]  谢谢 我不明白的地方就在这里原来是有赋值的

引用 17 楼 my_live_123 的回复: #include<stdio.h> int main(){    int a=100;    printf("%d\n",a++);          //把a = 100传参进去，printf得到100，然后a自加得a=101    printf("%d\n",++a);          //前缀++，先执行自加得a=102,然后把参数传102给printf，此时a=102    printf("%d\n",--a);           //前缀--，先执行自减得a=101，,然后把参数101传给printf，此时a=101    printf("%d\n",a--);           //把a = 101传参进去，printf得到101，然后a自减得a=100    printf("%d\n",a+1);         //a+1=101，传参101进去，此时a = 100    printf("%d\n",a);             //a=100    return 0; }   完全无视表达式求值的顺序。    printf("%d\n",a++);          //把a = 100传参进去，printf得到100，然后a自加得a=101 这个“传参”和“然后”用得好，意味着a++的副作用后序于参数传递。怎么这么肯定呢？

最后一个a+1,a不变的

没有问题，你这个不复杂。 不是这种 a+++a+++++a.没这种就好看啊。

引用 11 楼 sholber 的回复:[quote=引用 2 楼 jiht594 的回复:] a+1不是a++.  100+1(a+1)怎么想也不会是100  a++是类似于a=a+1的, 也就是说a++是有赋值操作的 这个可连类似都算不上。 前者，表达式的值是后缀++运算符的操作数的原值， 后者，表达式的值是运算符=左操作数修改后的存储值。[/quote] 我说的类似与a=a+1是相对与a+1之 你觉得a++和a=a+1或者a+1比, 哪个更像? 尤其是对于楼主不能理解为什么a++之后a变了, 而a+1不变.

printf("%d\n",a++);          //100 可以理解为    printf("%d\n",a);          //100    a =a +1; ===============================================    printf("%d\n",++a);          //102 可以理解为    a =a +1;    printf("%d\n",a);          //102

引用 2 楼 jiht594 的回复:a+1不是a++.  100+1(a+1)怎么想也不会是100  a++是类似于a=a+1的, 也就是说a++是有赋值操作的 这个可连类似都算不上。 前者，表达式的值是后缀++运算符的操作数的原值， 后者，表达式的值是运算符=左操作数修改后的存储值。

引用 3 楼 lin5161678 的回复:3+4 表达式的值是7  3的值是7吗？  显然不是阿，我意思就是前4个自加和自减都是依次给a赋值的吗？只存在自加减中，

引用 1 楼 u011041927 的回复:a +1 时 a是100，运算过后，a还是100 我可以理解为 前面4个自加和自减都是依次给a赋值吗？后面的还是a=100。

引用 2 楼 jiht594 的回复:a+1不是a++.  100+1(a+1)怎么想也不会是100  a++是类似于a=a+1的, 也就是说a++是有赋值操作的 我可以理解为 前面4个自加和自减都是依次给a赋值吗？后面的还是a=100。


Question: 求大神看一下我的蛮干求凸包问题。过程哪里错了。

int n,i;     scanf("%d",&n);     point p[n]; C语言 数组的定义支持 可变变量吗？

《算法精解（C语言描述）》


Question: 高手请看，C语言中这个东西的意义是什么？

就是给C语言考试增加一个没实际用处的考点

好吧，既然是多字符常量的实现依赖编译器的实现，那就不用它了。 果然是门万能的语言，细节学不完，呵呵

引用 15 楼 WizardOz 的回复:你确定C语言中的字符串可以用单引号？ 好吧我承认我错了，我收回上一个回复

你确定C语言中的字符串可以用单引号？

由便咦气（编译器）截断处理

引用 9 楼 mymtom 的回复:[quote=引用 7 楼 sholber 的回复:] [quote=引用 3 楼 mymtom 的回复:] 不要这么写，因为结果是不确定的。  3.1.3.4 Character constants ....  Semantics     An integer character constant has type int.  The value of an integer character constant containing a single character that maps into a member of the basic execution character set is the numerical value of the representation of the mapped character interpreted as an integer.  The value of an integer character constant containing more than one character, or containing a character or escape sequence not represented in the basic execution character set, is implementation-defined.  In particular, in an implementation in which type char has the same range of values as signed char, the high-order bit position of a single-character integer character constant is treated as a sign bit.  如果不让这么写，那么 wchar_t wc = '嗨'; 也不应该写，因为这同样是实现定义的。 你只看到'ab'是more than one character， 但你忘了， '嗨'同样是more than one character.[/quote] wchar_t wc = '嗨'; 这个写法本来就有问题[/quote]  什么问题？

引用 7 楼 sholber 的回复:[quote=引用 3 楼 mymtom 的回复:] 不要这么写，因为结果是不确定的。  3.1.3.4 Character constants ....  Semantics     An integer character constant has type int.  The value of an integer character constant containing a single character that maps into a member of the basic execution character set is the numerical value of the representation of the mapped character interpreted as an integer.  The value of an integer character constant containing more than one character, or containing a character or escape sequence not represented in the basic execution character set, is implementation-defined.  In particular, in an implementation in which type char has the same range of values as signed char, the high-order bit position of a single-character integer character constant is treated as a sign bit.  如果不让这么写，那么 wchar_t wc = '嗨'; 也不应该写，因为这同样是实现定义的。 你只看到'ab'是more than one character， 但你忘了， '嗨'同样是more than one character.[/quote] wchar_t wc = '嗨'; 这个写法本来就有问题

C++ Character Constants Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.  Microsoft Specific   For Microsoft C++, the source and execution character sets are both ASCII.  END Microsoft Specific  There are three kinds of character constants:   Normal character constants   Multicharacter constants   Wide-character constants  Note   Use wide-character constants in place of multicharacter constants to ensure portability.  Character constants are specified as one or more characters enclosed in single quotation marks. For example:  char ch = 'x';          // Specify normal character constant. int mbch = 'ab';        // Specify system-dependent                         //  multicharacter constant. wchar_t wcch = L'ab';   // Specify wide-character constant.  Note that mbch is of type int. If it were declared as type char, the second byte would not be retained. A multicharacter constant has four meaningful characters; specifying more than four generates an error message.  Syntax  character-constant :  'c-char-sequence' L'c-char-sequence'  c-char-sequence :  c-char c-char-sequence c-char  c-char :  any member of the source character set except the single quotation mark ('), backslash (\), or newline character escape-sequence  escape-sequence :  simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence  simple-escape-sequence : one of  \' \" \? \\ \a \b \f \n \r \t \v  octal-escape-sequence :  \octal-digit \octal-digit octal-digit \octal-digit octal-digit octal-digit  hexadecimal-escape-sequence :  \xhexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit  Microsoft C++ supports normal, multicharacter, and wide-character constants. Use wide-character constants to specify members of the extended execution character set (for example, to support an international application). Normal character constants have type char, multicharacter constants have type int, and wide-character constants have type wchar_t. (The type wchar_t is defined in the standard include files STDDEF.H, STDLIB.H, and STRING.H. The wide-character functions, however, are prototyped only in STDLIB.H.)  The only difference in specification between normal and wide-character constants is that wide-character constants are preceded by the letter L. For example:  char schar = 'x';               // Normal character constant wchar_t wchar = L'\x81\x19';    // Wide-character constant  Table 1.2 shows reserved or nongraphic characters that are system dependent or not allowed within character constants. These characters should be represented with escape sequences.  Table 1.2   C++ Reserved or Nongraphic Characters  Character ASCII  Representation ASCII  Value Escape Sequence  Newline NL (LF) 10 or 0x0a \n  Horizontal tab HT 9 \t  Vertical tab VT 11 or 0x0b \v  Backspace BS 8 \b  Carriage return CR 13 or 0x0d \r  Formfeed FF 12 or 0x0c \f  Alert BEL 7 \a  Backslash \ 92 or 0x5c \\  Question mark ? 63 or 0x3f \?  Single quotation mark ' 39 or 0x27 \'  Double quotation mark " 34 or 0x22 \"  Octal number ooo — \ooo  Hexadecimal number hhh — \xhhh  Null character NUL 0 \0    If the character following the backslash does not specify a legal escape sequence, the result is implementation defined. In Microsoft C++, the character following the backslash is taken literally, as though the escape were not present, and a level 1 warning (“unrecognized character escape sequence”) is issued.  Octal escape sequences, specified in the form \ooo, consist of a backslash and one, two, or three octal characters. Hexadecimal escape sequences, specified in the form \xhhh, consist of the characters \x followed by a sequence of hexadecimal digits. Unlike octal escape constants, there is no limit on the number of hexadecimal digits in an escape sequence.  Octal escape sequences are terminated by the first character that is not an octal digit, or when three characters are seen. For example:  wchar_t och = L'\076a';  // Sequence terminates at a char    ch = '\233';     // Sequence terminates after 3 characters  Similarly, hexadecimal escape sequences terminate at the first character that is not a hexadecimal digit. Because hexadecimal digits include the letters a through f (and A through F), make sure the escape sequence terminates at the intended digit.  Because the single quotation mark (') encloses character constants, use the escape sequence \' to represent enclosed single quotation marks. The double quotation mark (") can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a character constant, you must type two backslashes in a row (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)

引用 3 楼 mymtom 的回复:不要这么写，因为结果是不确定的。  3.1.3.4 Character constants ....  Semantics     An integer character constant has type int.  The value of an integer character constant containing a single character that maps into a member of the basic execution character set is the numerical value of the representation of the mapped character interpreted as an integer.  The value of an integer character constant containing more than one character, or containing a character or escape sequence not represented in the basic execution character set, is implementation-defined.  In particular, in an implementation in which type char has the same range of values as signed char, the high-order bit position of a single-character integer character constant is treated as a sign bit.  如果不让这么写，那么 wchar_t wc = '嗨'; 也不应该写，因为这同样是实现定义的。 你只看到'ab'是more than one character， 但你忘了， '嗨'同样是more than one character.

引用 2 楼 jiht594 的回复:你觉得''里面放2-4个字符对吗?谁告诉你这么写的?  C标准告诉我们这么写的。

%x默认是最4个字节来格式化成16进制显示.  单引号里面是放一个字符.  你的写法要看到为什么这么显示, 你可以查看反汇编, 就清楚了.

引用 2 楼 jiht594 的回复:你觉得''里面放2-4个字符对吗?谁告诉你这么写的? 既然编译器支持，就说明这是对的。我也是在群里看到大家讨论才来测试的，以为是C的偏门语法，但用下来感觉这样用很不靠谱啊。 char a = 'ab'; //编译器给警告，从int截断为char，而不是错误 我只是想，既然编译器支持肯定有它的用处，只是不知用在何处，特来问问

引用 11 楼 my_live_123 的回复:由便咦气（编译器）截断处理  是便一起。

你觉得''里面放2-4个字符对吗?谁告诉你这么写的?

看不懂你想说什么


Question: 能不能写出红色字体的每一行的意思！

int split(char *str,  char **pStr) {     int t = 0;     char *p = str;     int s = 0;      while (*p) // *p != NULL     {         if (*p == ' ') // *p == 空格         { 			if(1 == s) //判断意义不大,用来判断 只把第一个空格变成结尾 			{ 				*p = 0; //将空格符 变成 字符串结尾符'\0' 				s = 0;	//置标志位,表示需要记录下个字符串的首地址 			}         }         else if (0 == s) //只有标志位有效时才记录空格后的位置 		{ 			s = 1;			//清空标志位 			pStr[t++] = p; //记录空格后的位置,即下一个字符串的首地址 		} 		else {}          p++;     }      return t; //返回记录的个数 }

扫描字符串str，遇到空格，就将空格后面的字符位置填入pStr，同时在空格位置填0（作为上一个子字符串的结束）


Question: 关于整型提升的问题！请教

引用 9 楼 Czui1990 的回复:[quote=引用 8 楼 my_live_123 的回复:] 1-short int = short。32位机器是按照32位算，算的结果截断赋值给short 2-都可能溢出 3-同类型计算，不提升类型。int和long类型一块算，int提升到long  my_live_123你好，总算遇到一个明白我的意思的人了。  关于第3个问题，是否可理解为int类型乘法运算，若不设定操作数的大小，可能溢出？ 关于第2个问题，是否改变了符号位也算溢出？并不是超过表示范围才算溢出？[/quote]  3.如果数据类型不超过计算机位数，那么不论类型是多少位的都是按照固定位算，意思就是32位机器，它总是按32位算，不管你是8位数据还是16位数据。算完后再截断给你，不能保证截断后结果是正确的，意思就是可能溢出  如果等于计算机位数，那么只要结果值超过了它自己能表示的范围就算溢出。换言之：你平时吃一碗饭就吃饱了，但再让你吃一碗就吃不完！两碗饭超过了你的饭量。剩下的饭就是溢出 因此，从这一点而论，计算机上能表示的数值范围是有限的。（注意，这里不要喷我大整数相乘问题，大整数相乘，包括求素数问题都是用有限模拟无限完成的）  2-如果占用了符号位，那么看它本身的数据类型，如果是无符号类型，当然符号位扩展成了存储位。不算溢出；如果是有符号类型，当然溢出。比如4位，0111 + 0011 = 1010，如果是无符号，最高位1是有效数据位，因此解释成7+3=10，是正确的，4位的无符号能表达的最大数是15，没有溢出。如果是有符号数，那么最高位1是符号，表示负数。有效位是010，因此取反加一得原码110，即-6。很显然结果不对，7+3 = -6；

引用 10 楼 sholber 的回复:[quote=引用 8 楼 my_live_123 的回复:] 1-short int = short。32位机器是按照32位算，算的结果截断赋值给short 2-都可能溢出 3-同类型计算，不提升类型。int和long类型一块算，int提升到long  这是常规算术转换，不是整型提升。[/quote]  你好，他说的哪里有问题吗？

引用 8 楼 my_live_123 的回复:1-short int = short。32位机器是按照32位算，算的结果截断赋值给short 2-都可能溢出 3-同类型计算，不提升类型。int和long类型一块算，int提升到long  这是常规算术转换，不是整型提升。

引用 8 楼 my_live_123 的回复:1-short int = short。32位机器是按照32位算，算的结果截断赋值给short 2-都可能溢出 3-同类型计算，不提升类型。int和long类型一块算，int提升到long  my_live_123你好，总算遇到一个明白我的意思的人了。  关于第3个问题，是否可理解为int类型乘法运算，若不设定操作数的大小，可能溢出？ 关于第2个问题，是否改变了符号位也算溢出？并不是超过表示范围才算溢出？

引用 6 楼 u012421456 的回复:楼主的提升的意思是？  small integer做运算操作，不都是先自动提升至int类型，再做运算吗？ 如果small integer是16bit，int类型是32bit，就提升为32bit做运算。难道我理解错了？

楼主的提升的意思是？

引用么short类型做运算，提升至32bit的时

引用 2 楼 u012421456 的回复:溢不溢出看你什么数据了 这问题问的？  我说的是可能发出溢出的可能性。。若int类型是32bit，short类型是16bit，那么short类型做运算，提升至32bit的时，无论加法还是乘法，任何数据都不会溢出。但int类型和short类型都是16bit，那么short类型乘法运算可能会溢出。

引用 1 楼 sholber 的回复:先看下整型提升的定义再问。 溢出是你自己的事，和integer promotion无关。 嘎嘎~~~  我了解，可能没表示明白，分开的2个问题，我想确认下int类型乘法会提升至long类型吗？有明确的定义吗？

溢不溢出看你什么数据了 这问题问的？


Question: 请大神告诉我子函数那里哪里有问题了？？？？？？？？？？？？？？谢谢

p<p+25是必然的呀，你的循环会一直下去

楼主的目的是想排序嘛？

#include <stdio.h> #include <stdlib.h>  void move(int *p) { 	int *q, t;  	q = p + 12; 	for (; p < p + 25; p++) { //中间条件变量是叠加增长的,你会死循环的 		if (*q < *p) { 			t = *q; 			*q = *p; 			*p = t; 		} 	} }  void main() { 	int a[5][5], *p, i;  	for (i = 0; i < 5; i++) 		scanf("%d %d %d %d %d", &a[i][0], &a[i][1], &a[i][2], &a[i][3], &a[i][4]);  	p = &a[0][0]; 	putchar('\n'); 	move(p); 	for (i = 0; i < 5; i++) 		printf("%d %d %d %d %d\n", a[i][0], a[i][1], a[i][2], a[i][3], a[i][4]); }

楼上正解

for(;p < (q - 12 + 25); p++)

for(; p<p+25; p++) ？？？


Question: 用C编程

#include "stdlib.h"  #include "stdio.h" #include<windows.h>  #define N  20  void fun1(int * a,int n) {	 	int i,j,min,max,k; 	min=0;max=N; 	for(i=0;i<N;i++) 	{ 		for(j=i+1;j<N;j++) 		{ 			if(a[j]<a[i]) 			{ 				k=a[j]; 				a[j]=a[i]; 				a[i]=k; 			} 		} 	} 	for(i=0;i<N;i++) 	{ 		printf("%d ",a[i]); 	} 	printf("\n");   	do{ 	if((a[min]+a[max])>n) 		max--; 	if((a[min]+a[max])==n) 	{ 		printf("%d+%d",a[min],a[max]); 		min++,max--; 	} 	if((a[min]+a[max])<n) 		min++; 	}while(max>=min); 	printf("\n");  }  int main() { //	int h[]={0}; //	int m,i; //	scanf("%d",&m); //	printf("\n-----------------------------\n"); //	for(i=0;i<N;i++) //	{ //		scanf("%d ",h[i]); //	} 	int m=31; 	int h[]={1,45,29,68,23,65,32,87,16,95,31,46,48,14,54,78,20,21,22,30}; 	fun1(h,m); 	return 0; }

IdxMin<=IdxMax则结束 ===> IdxMin>=IdxMax则结束

排序, Idxmin=0，IdxMax=N again: A[IdxMin]+A[IdxMax] >a则IdxMax--; ==a,(IdxMin,IdxMax)为符合数序号，IdxMin++，IdxMax-- <a则IdxMin++;  IdxMin<=IdxMax则结束 goto again

用高效的算法排序，最快O(nlogn) 假设给定数S，排序后的数组为a,共n个元素 以a1-S/2为搜索区间， 在此区间每个元素ai做如下操作 在区间[S/2，an]中用折半查找S - ai，如果找到aj，那么满足条件输出，继续 因此时间复杂度依旧是O(nlogn) 如此整个算法的时间复杂度还是O(nlogn)

觉得最好排一下序，要不，不好处理。

1. hash，然后线性搜索。 2. 排序，然后线性搜索。


Question: C语言新手求助，程序中修改函数和删除函数用不了（用不同颜色标出部分），请帮忙看看..

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

求助啊 ~~~~

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> struct stu { 	char name[30]; 	char tel[30]; 	char email[30]; 	char job[30]; }stu[200]; int mm=0; int s1=0; int s2=0; int s3=0; int s4=0; int s5=0; int bz=0; int f=0; int k; int i=0; void read() { 	FILE *fp; 	if((fp=fopen("D:\\通讯录.txt","r"))==NULL) 	{  		printf("file cannot open!\n"); 	} 	int i=0; 	while(!feof(fp)) 	{ 	fread(&stu[i],sizeof(struct stu),1,fp); 	i++; 	} 	for(k=0;k<i-1;k++) 	{ 		printf("姓名:%s\t电话:%s\t邮箱:%s\t职务:%s\n",stu[k].name,stu[k].tel,stu[k].email,stu[k].job); 	} 	fclose(fp); } void add() { 	FILE* fp=fopen("D:\\通讯录.txt","a+"); 	int n; 	struct stu stu[200]; 	printf("新建联系人个数："); 	scanf("%d",&n); 	int i; 	for(i=0;i<n;i++) 	{ 		printf("\t姓名："); 		scanf("%s",stu[i].name); 		printf("\t电话："); 		scanf("%s",&stu[i].tel); 		printf("\t邮箱："); 		scanf("%s",&stu[i].email); 		printf("\t职务："); 		scanf("%s",&stu[i].job); 		fwrite(&stu[i],sizeof(struct stu),1,fp); 		mm++; 	} 	fclose(fp);  } void sorting()                                        //排序 { 	FILE *fp; 	fp=fopen("D:\\通讯录.txt","r+"); 	struct stu* p=(struct stu*)malloc(sizeof(struct stu)); 	struct stu temp; 	int st; 	for(st=1;st<200;st++) 	{ 		fread(&stu[st],sizeof(struct stu),1,fp); 		if(strcmp((p+st)->name,(p+st-1)->name)==1) 		{ 			temp=*(p+st); 			*(p+st)=*(p+st-1); 			*(p+st-1)=temp; 		} 		 	} } void listtop() { 	FILE *fp; 	if((fp=fopen("D:\\通讯录.txt","r"))==NULL) 	{  		printf("file cannot open!\n"); 	} 	int i=0; 	while(!feof(fp)) 	{ 	fread(&stu[i],sizeof(struct stu),1,fp); 	i++; 	} 	for(k=0;k<i-1;k++) 	{ 		printf("姓名:%s\t电话:%s\n",stu[k].name,stu[k].tel); 	} 	fclose(fp); } void list() { 	printf("    |                  |   \n"); 	printf("    |  1.查询联系人    |   \n"); 	printf("    |  2.编辑联系人    |   \n"); 	printf("    |  3.显示全部信息  |   \n"); 	printf("    |  4.退出通讯录    |   \n"); } void listcx() { 	printf("    |     查询联系人     |   \n"); 	printf("    |                    |   \n"); 	printf("    |   1.按姓名查找     |   \n"); 	printf("    |   2.按电话查找     |   \n"); 	printf("    |   3.按邮箱查找     |   \n"); 	printf("    |   4.按职务查找     |   \n"); 	printf("    |   5.返回上一级菜单 |   \n"); } void listbj() { 	printf("    |     编辑联系人     |   \n"); 	printf("    |                    |   \n"); 	printf("    |   1.添加联系人     |   \n"); 	printf("    |   2.修改联系人     |   \n"); 	printf("    |   3.删除联系人     |   \n"); 	printf("    |   4.返回上一级菜单 |   \n"); 	printf("    |                    |   \n"); } int main() { 	struct stu stu[200]; K:	printf("                       通        讯        录                     \n"); 	printf("=======================================================================\n"); 	listtop(); 	printf("=======================================================================\n"); G:	list(); 	int xz1; 	scanf("%d",&xz1); 	switch(xz1) 	{ 	case 1:                                        //查询 L:		system("cls"); 		listcx(); 		int xz2; 		scanf("%d",&xz2); 		switch(xz2) 		{ 		case 1: 			FILE *fp; 			fp=fopen("D:\\通讯录.txt","r"); 			int a,xz4; 			s1=0; 			char aname[20]; 			printf("姓名:"); 			scanf("%s",&aname); 			for(a=0;a<200;a++) 			{ 				fread(&stu[a],sizeof(struct stu),1,fp); 				if(strcmp(aname,stu[a].name)==0) 				{ 					s1++; 					system("cls"); 					printf("姓名:%s    电话:%s    邮箱:%s    职务:%s\n",stu[a].name,stu[a].tel,stu[a].email,stu[a].job); 				} 			} 			if(s1==0) 			{ 				system("cls"); 				printf("查无此人\n"); 			} 			break; 		case 2: 			FILE *fp1; 			fp=fopen("D:\\通讯录.txt","r+"); 			int a1,xz5; 			s2=0; 			char atel[20]; 			fflush(stdin); 			printf("电话:"); 			scanf("%s",&atel); 			for(a1=0;a1<200;a1++) 			{ 				fread(&stu[a1],sizeof(struct stu),1,fp); 				if(strcmp(atel,stu[a1].tel)==0) 				{ 					s2++; 					system("cls"); 					printf("姓名:%s    电话:%s    邮箱:%s    职务:%s\n",stu[a1].name,stu[a1].tel,stu[a1].email,stu[a1].job); 				} 			} 			if(s2==0) 			{ 				system("cls"); 				printf("查无此人\n"); 			} 			break; 		case 3: 			FILE *fp2; 			fp=fopen("D:\\通讯录.txt","r+"); 			int a2,xz6; 			s3=0; 			char aemail[20]; 			fflush(stdin); 			printf("邮箱:"); 			scanf("%s",&aemail); 			for(a2=0;a2<200;a2++) 			{ 				fread(&stu[a2],sizeof(struct stu),1,fp); 				if(strcmp(aemail,stu[a2].email)==0) 				{ 					s3++; 					system("cls"); 					printf("姓名:%s    电话:%s    邮箱:%s    职务:%s\n",stu[a2].name,stu[a2].tel,stu[a2].email,stu[a2].job); 				} 			} 			if(s3==0) 			{ 				system("cls"); 				printf("查无此人\n"); 			} 			break; 		case 4: 			FILE *fp3; 			fp=fopen("D:\\通讯录.txt","r+"); 			int a3,xz7; 			s4=0; 			char ajob[20]; 			fflush(stdin); 			printf("职务:"); 			scanf("%s",&ajob); 			for(a3=0;a3<200;a3++) 			{ 				fread(&stu[a3],sizeof(struct stu),1,fp); 				if(strcmp(ajob,stu[a3].job)==0) 				{ 					s4++; 					system("cls"); 					printf("姓名:%s    电话:%s    邮箱:%s    职务:%s\n",stu[a3].name,stu[a3].tel,stu[a3].email,stu[a3].job); 				} 			} 			if(s4==0) 			{ 				system("cls"); 				printf("查无此人\n"); 			} 			break; 		case 5: 			system("cls"); 			goto K; 		default: 			goto L; 		} Z:		int xz8; 		printf("==================================================================\n"); 		printf("   1.返回    \n"); 		scanf("%d",&xz8); 		if(xz8==1) 		{ 			system("cls"); 			goto K; 		} 		else 		{ 			system("cls"); 			goto Z; 		} 	case 2:                                        //编辑 M:		system("cls"); 		listbj(); 		int xz3; 		int v; 		scanf("%d",&xz3); 		switch(xz3) 		{ 		case 1:                                    //添加 			add(); 			system("cls"); 			goto K; 		case 2:                                    //修改 			system("cls"); 			FILE *fp; 			fp=fopen("D:\\通讯录.txt","rb+"); 			char xtel[30]; 			char xemail[30]; 			char xjob[30]; 			char cname[30]; 			char xname[30]; 			int cc; 			printf("姓名:"); 			scanf("%s",&cname); 			for(cc=0;cc<200;cc++) 			{ 				fread(&stu[cc],sizeof(struct stu),1,fp); 				if(strcmp(cname,stu[cc].name)==0) 				{ 					printf("修改姓名为:"); 					scanf("%s",&xname); 					strcpy(stu[cc].name,xname); 					printf("修改电话为:"); 					scanf("%s",&xtel); 					strcpy(stu[cc].tel,xtel); 					printf("修改邮箱为:"); 					scanf("%s",&xemail); 					strcpy(stu[cc].email,xemail); 					printf("修改职务为:"); 					scanf("%s",&xjob); 					strcpy(stu[cc].job,xjob); 					system("cls"); 					printf("修改后:\n"); 					printf("姓名:%s\t电话:%s\t邮箱:%s\t职务:%s\n",stu[cc].name,stu[cc].tel,stu[cc].email,stu[cc].job); 					fwrite(&stu[cc],sizeof(struct stu),1,fp); 					bz++; 				} 			} 			fclose(fp); 			if(bz==0) 			{ 				system("cls"); 				printf("无此联系人\n"); 			} 			break; 		case 3:                                    //删除 			system("cls"); 			FILE *fp1; 			fp1=fopen("D:\\通讯录.txt","rb+"); 			int aa; 			char bname[30]; 			int c; 			int fc; 			printf("姓名:"); 			scanf("%s",&bname); 			for(c=0;c<200;c++) 			{ 				fread(&stu[c],sizeof(struct stu),1,fp1); 				if(strcmp(stu[c].name,bname)==0) 				{ 					for(aa=c;aa<200;aa++) 					{ 						strcpy(stu[aa].name,stu[aa+1].name); 						strcpy(stu[aa].tel,stu[aa+1].tel); 						strcpy(stu[aa].email,stu[aa+1].email); 						strcpy(stu[aa].job,stu[aa+1].job); 						fwrite(&stu[aa],sizeof(struct stu),1,fp); 					} 					s5++; 				} 			} 			if(s5==0) 				printf("无此联系人\n"); 			else 				printf("删除成功\n"); 			break; 		case 4: 			system("cls"); 			goto K; 			break; 		default: 			goto M; 		} 		int xz9; 		printf("===============================================================\n"); O:		printf("1.返回   \n"); 		scanf("%d",&xz9); 		if(xz9==1) 		{ 			system("cls"); 			goto M; 		} 		else 		{ 			system("cls"); 			goto O; 		} 	case 3: 		system("cls"); 		printf("                       通        讯        录                     \n"); 		printf("=======================================================================\n"); 		read(); 		printf("=======================================================================\n"); 		goto G; 	case 4:                                         //退出 		exit(0); 	default: 		system("cls"); 		goto K; 	} 	return 0; }

代码先从新上传一下吧  ase 3: system("cls"); printf("                       通        讯        录                     \n"); printf("=======================================================================\n"); read(); printf("=======================================================================\n"); goto G; case 4:                                         //退出

= =没有人来看么？


Question: C语言  字符串中，怎样提取重复字符中之间的字符串

仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

引用 1 楼 user-2 的回复:时间复杂度要求是多少？ 什么意思？是问要很复杂吗？最好不要

时间复杂度要求是多少？


Question: 求问个算法问题

仅供参考：  #include<stdio.h> //对一个三位以上的数判断是否是ADAIV数s int is_ADAIV(int n) { 	if (n > 99)  //一位、两位直接就是 	{ 		int d, n1, n2; 		n2 = n % 10; 		n1 = n / 10 % 10; 		d = n1 - n2; 		n /= 10; 		while (n >= 10) 		{ 			n2 = n1; 			n1 = n / 10 % 10; 			if (n1 - n2 != d)   //差值改变 				return 0; 			n /= 10; 		} 	} 	return 1; } //对区间[A, B]内的数进行统计 int count_of_ADAIV(int A, int B) { 	int i, count; 	count = 0; 	for (i = A; i <= B; i++) 	{ 		if (is_ADAIV(i)) 			count++; 	} 	return count; } int main(void) { 	int A, B; 	while (scanf("%d %d", &A, &B)) 	{ 		printf("%d\n", count_of_ADAIV(A, B)); 	} 	return 0; } //1 100 //99 //112 160 //4 //128 134 //0 //123 135 //2

这题不难吧，应该就是把十亿以内的Ada数找出来而已，很简单的 啊，三楼已经接近真相了。 下面讨论三位数即100以上的正整数： 公差>=5或者<=-5的序列不存在 公差==4的序列，只有一个 159；对应的，公差==-4的序列只有951 公差==3的序列，有三个：147，258，369；公差==-3的序列也是对应的：741，852，963 公差==2的序列，有两个：13579，2468；公差==-2的序列：97531，8642，从这四个序列里取出三位数、四位数、五位数 公差==1的序列，123456789，公差==-1的序列：987654321，从这两个序列里取出三位数、四位数到九位数 以上用程序都不难算吧，下面处理特殊情况： 公差==0的序列，1-9，有几位算几位，比如111，1111，222，2222...999999这些 1-99的都是 经过上面的运算，我们就把十亿之内所有的Ada数找出来了，这些数排个序，来查吧，别说1sec，毫秒出结果

引用 7 楼 my_bkb 的回复:[quote=引用 6 楼 jinfengyiye 的回复:] [quote=引用 5 楼 my_bkb 的回复:] [quote=引用 3 楼 jinfengyiye 的回复:]  	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec[/quote] 你试试看就知道了。数组100个以内完全秒杀吧。而且这个算什么暴力，很多情况都会break出来的。[/quote]  引用 6 楼 jinfengyiye 的回复:[quote=引用 5 楼 my_bkb 的回复:] [quote=引用 3 楼 jinfengyiye 的回复:]  	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec[/quote] 你试试看就知道了。数组100个以内完全秒杀吧。而且这个算什么暴力，很多情况都会break出来的。[/quote] 真不行 ，其中一组测试数据是1到十亿。光遍历就已经超时了[/quote] 老大你真牛十亿数据,你对数据没有概念吗? 你都遍历都超时了还处理呢? 上面不是数组100以内啊.我也回复了. 不过我确定这个算法是可以优化的.可以优化,但是十亿的数据我真一个算法处理不了. 十亿啊.十亿啊.

引用 5 楼 my_bkb 的回复:[quote=引用 3 楼 jinfengyiye 的回复:]  	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec[/quote] 你试试看就知道了。数组100个以内完全秒杀吧。而且这个算什么暴力，很多情况都会break出来的。

引用 3 楼 jinfengyiye 的回复: 	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec

引用 6 楼 jinfengyiye 的回复:[quote=引用 5 楼 my_bkb 的回复:] [quote=引用 3 楼 jinfengyiye 的回复:]  	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec[/quote] 你试试看就知道了。数组100个以内完全秒杀吧。而且这个算什么暴力，很多情况都会break出来的。[/quote]  引用 6 楼 jinfengyiye 的回复:[quote=引用 5 楼 my_bkb 的回复:] [quote=引用 3 楼 jinfengyiye 的回复:]  	int min,max;  	cout<<"输入两个数"<<endl; 	cin>>min>>max;  	if(min>=max||min<0) 		cout<<"输入前数一定要比后面个数小 且不能小于0"; 	else 	{ 		int ct=0; 		int i=min; 		for(i=min;i<=max;i++){ 			int n=i; 			if(n<100) 			{ 				ct++; 				continue; 			}  			int pre=n%10; 			int d=(n/10)%10-pre; //距 			bool b=false; 			while(n%10!=n){ 				n=n/10; 				if(d!=n%10-pre){ 					b=true; 					break; 				} 				pre=n%10; 			}  			if(!b) 				ct++; 		} 		cout<<"个数"<<ct<<endl; 	}  	system("pause");  你这个暴力的恐怕不行 限时是1sec[/quote] 你试试看就知道了。数组100个以内完全秒杀吧。而且这个算什么暴力，很多情况都会break出来的。[/quote] 真不行 ，其中一组测试数据是1到十亿。光遍历就已经超时了

内个 用c可以吗 c++我还看不懂

public static void main(String[] args) {  		int A=112; 		int B=10000; 		String sAdaIV="123456789"; 		int maxStep=4; 		HashSet<Integer> allAdaIvs=new HashSet<Integer>(); 		for(int len=3;len<9;len++) 		{ 			for(int step=1;step<=maxStep;step++) 			{ 				System.out.println("------------"+step+"/"+len); 				for(int idx=0;idx<9;idx++) 				{ 					String s=""; 					for(int i=0;i<len;i++) 					{ 						int charAt=i*step+idx; 						if(charAt<9) 							s+=(sAdaIV.charAt(charAt)); 					} 					if(s.length()>=3&&s.length()==len) 					{ 						int tmp=Integer.parseInt(s); 						if(tmp>=A&&tmp<B) 						{ 							allAdaIvs.add(tmp); 							System.out.println(tmp); 						} 					} 				} 			} 		} 		System.out.println("all adaiv:"+allAdaIvs.size()); 	} --- 123456789 从中找出 AdaIV

这个用整数数组模拟就可以


Question: 求问个算法问题

动态规划~~~ 类似最大子数组

这题里的连续子序列指的是升序连续整数？ 3 4 5 6？5 6 7 8 9？要不要从1开始？