Question: 不带头节点单链表删除第一个结点出错

引用 9 楼 qybao的回复:[quote=引用 6 楼 肥牛肉^*^ 的回复：][quote=引用 2 楼 qybao的回复:][quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] delete里面用一级指针只是删除i=1这个位置有乱码，删除i为2的位置就可以，如果这样里面的参数没有改变，那为什么删除2这个位置结果就有效呢，[/quote]你没理解我说的，传二级指针是为了修改函数外的头指针，如果删除第二个位置，不需要修改函数外的头指针，所以没问题；而删除第一个位置，因为头指针被释放了，如果不修改函数外的头指针就会出问题（就像你说的问题一样，野指针的东西内容是不确定的，所以就可能出现乱码）。要修改函数外的头指针，那参数只能传函数外的头指针的地址，即&head（明白我举的例子的意思了吗？你觉得&head和head都是地址，但它们等效吗？），所以就是二级指针（head是一级指针，&head就是二级指针）[/quote] 理解了。。。

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

引用 6 楼 肥牛肉^*^ 的回复：[quote=引用 2 楼 qybao的回复:][quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] delete里面用一级指针只是删除i=1这个位置有乱码，删除i为2的位置就可以，如果这样里面的参数没有改变，那为什么删除2这个位置结果就有效呢，[/quote]你没理解我说的，传二级指针是为了修改函数外的头指针，如果删除第二个位置，不需要修改函数外的头指针，所以没问题；而删除第一个位置，因为头指针被释放了，如果不修改函数外的头指针就会出问题（就像你说的问题一样，野指针的东西内容是不确定的，所以就可能出现乱码）。要修改函数外的头指针，那参数只能传函数外的头指针的地址，即&head（明白我举的例子的意思了吗？你觉得&head和head都是地址，但它们等效吗？），所以就是二级指针（head是一级指针，&head就是二级指针）

引用 5 楼 肥牛肉^*^ 的回复：[quote=引用 2 楼 qybao的回复:][quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] 要把p的地址传给函数，但p不就是一个地址了吗，[/quote]你好好理解我给你的例子，p也是个指针，但是传二级指针和一级指针是有区别的，传二级指针是传p自己的地址，传一级指针是传p指向的地址，自己的地址和指向的地址不是一回事。

引用 6 楼 肥牛肉^*^ 的回复:[quote=引用 2 楼 qybao的回复:][quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] delete里面用一级指针只是删除i=1这个位置有乱码，删除i为2的位置就可以，如果这样里面的参数没有改变，那为什么删除2这个位置结果就有效呢，[/quote]  楼主的删除函数传的是一重指针还是二重指针？这个需要明确了，提问题的时候如果不确定讨论起来就不好说了。  传二重指针，删除头结点没问题。原因是二重指针*head = p->next;这句就是相当于修改了main函数里的head节点，更新了main函数里的head指针指向，因为传的是二重指针嘛，如果传一重指针不可以的原因是head = p->next;这里的head是形参的head并不是main函数里的head了。

引用 2 楼 qybao的回复:[quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] delete里面用一级指针只是删除i=1这个位置有乱码，删除i为2的位置就可以，如果这样里面的参数没有改变，那为什么删除2这个位置结果就有效呢，

引用 2 楼 qybao的回复:[quote=引用 1 楼 qybao 的回复:]  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。 [/quote] 要把p的地址传给函数，但p不就是一个地址了吗，

引用 1 楼 qybao 的回复:int ListDelete(pSingLink* head, int i, ElemType *x) //这里用二级指针，是因为函数里有 *head=p->next; //这样修改也能改变函数外的head的指向  int ListDelete(pSingLink head, int i, ElemType *x) //如果是一级指针，函数里 head=p->next; //这样修改是不能改变函数外的head的指向  具体原因解释过很多遍了，要想在函数内修改参数也能影响函数外，参数要用指针类型，且函数里不能用 参数=xxx 来修改（这样是修改函数栈的参数的栈内存的信息，这样参数的内存就不再保存原来指针指向的地址信息了，所以就不会影响函数外的变量），而是要用 *参数=xxx 来修改（这样是不修改函数栈的参数的栈内存的信息，而是修改它指向的内存地址的信息，所以会影响函数外的变量）。 你删除第一个元素，要修改头指针，要想在函数内修改也影响函数外的变量，就必须把函数外的变量的地址传给函数，因为函数外的变量是指针类型，传它的地址，就是二级指针，所以ListDelete(pSingLink* head, int i, ElemType *x)  要用二级指针  举个例子，好好理解其中的差别  int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 楼主用的好像就是二重指针～

#include <stdio.h> #include <malloc.h> #include <stdlib.h>  typedef int ElemType;  typedef struct SLNode {     ElemType data;     struct SLNode *next; }SingLink,*pSingLink;  pSingLink TailCreatList(); void DisPlay(pSingLink L); int ListDelete(pSingLink* head, int i, ElemType *x);  int main(void) {     int i,x;     pSingLink head=NULL;     head=TailCreatList();     DisPlay(head);     printf("请输入删除位置:");     scanf("%d",&i);     if(ListDelete(&head,i,&x)) {         printf("删除成功, ");         printf("删除的元素是:%d\n ",x);     } else {         printf("删除失败\n");     }     DisPlay(head);     return 0; } pSingLink TailCreatList() {     pSingLink head,r;     pSingLink s;     int i,len,x;      head = NULL;     r=head;     printf("请输入单链表的长度");     scanf("%d",&len);     printf("请输入单链表中的元素");     for(i=0;i<len;i++)     {         scanf("%d",&x);         s=(pSingLink)malloc(sizeof(SingLink));         s->data=x;         if(head==NULL)         {             head=s;             r=s;             continue;         }         r->next = s;         r = s;     }     if(r!=NULL)         r->next = NULL;      return head; }  void DisPlay(pSingLink L) {     while(L!=NULL)     {         printf("%d ",L->data);         L=L->next;     }     putchar(10);     return; }  int ListDelete(pSingLink* head, int i, ElemType *x) {     pSingLink p,s;     int j;      if (!(*head))    //需要判断头结点         return 0;      j=1;     p = *head;     while(p->next!=NULL&&j<i-1)     {         p=p->next;         j++;     }     if(i==1)     {         *head=p->next;         *x=p->data;         free(p);          return 1;     }     //else if(j!=i-1)     if(j != i-1 || !p->next)    //需要考虑p->next是否为NULL     {         printf("位置出错");         return 0;     }     else     {         s = p->next;         *x=s->data ;         p->next =s->next ;         free(s);     }      return 1; } 供参考～  不是删除头结点出的错，是i的值如果大于链表长度出的段错误；需要考虑p->next是否为NULL；  其他小问题一并修改了，比如如果删除失败，x的值是一个随机值～

引用 1 楼 qybao 的回复: int a=5,b=6; void change1(int *p) {p=&b;} void change2(int **p) {*p=&b;} int main() {     int *p = &a; //*p=5     printf("%p, %p\n", &a, &b); //查看a，b的地址     change1(p);      printf("%p, %d\n", p, *p); //函数内的修改不影响函数外的p，p还是指向a的地址     change2(&p); //要想在函数修改p也能影响函数外的p，就要传p的地址，p本身是指针，p的地址就是二级指针，所以参数就是二级指针类型     printf("%p, %d\n", p, *p); //函数内的修改影响函数外的p，p指向b的地址 } 补充说明，例子代码的意思就是，p是个指针，刚开开始指向a的地址，change1是在函数内修改参数p指向b的地址，结果无效；change2是在函数内修改参数*p指向b的地址，结果有效，所以想在函数内改变也能影响p，就要把p的地址&p传给函数，函数里用*p=xxx的方式修改。因为p本身是指针，所以它的&p就是二级指针。


Question: 求解创建双链表的问题

引用 1 楼 user-1的回复:scanf("%d\n", &q->data);   改为 scanf("%d", &q->data); 谢谢谢谢谢谢


Question: 隐式转换的问题

会不会是你认为是UINT8是int类型？如果是编译器帮你转换了int，还会emit出来个error，那么所有的UINT8和UINT16赋值运算都会需要(type)强制转换了。

引用 1 楼 自信男孩的回复:应该是隐式类型提升了：C语言中比int小的整型（包括short 、unsigned short 、 unsigned char和char）在运算中都要转换成int然后进行运算，至于为什么选择转换为int，应该是从效率上考虑的，因为通常情况下int的长度被定义为机器处理效率最高的长度，比如32位机上，一次处理4个字节效率是最高的，所以虽然short（我机器上占2个字节）更节省内存，但是在运算中的效率，是int更高。所以上面，无论是逻辑运算a>b还是算术运算a+b中a和b都默认转换成了int，所以算术运算的结果也是带符号的。   注意标红的前提条件 后面我把循环条件里的语句改为sum =(UINT16)(sum + data[10+i]); 这样就没问题了，估计就是你所说的原因。

错误我是照抄的，所以没有我认为这个UINT8是int类型。

不同的编译器可能对字面量的类型存储不一样，可以参考以下链接 https://zh.wikipedia.org/wiki/字面常量_(C语言) 对于你的代码，i < 39 的 39 编译器都当做是int，所以自动把 i 转成 int 来比较 对于上面链接的，如果 39 转成long，有另一种写法，即 39L（后面带个L表示long）能很容易做到，但是做成UINT16或UINT8好像没有专门的修饰，这种情况只能强行转换了，如 i < (UINT16)39

引用 1 楼 自信男孩 的回复:应该是隐式类型提升了：C语言中比int小的整型（包括short 、unsigned short 、 unsigned char和char）在运算中都要转换成int然后进行运算，至于为什么选择转换为int，应该是从效率上考虑的，因为通常情况下int的长度被定义为机器处理效率最高的长度，比如32位机上，一次处理4个字节效率是最高的，所以虽然short（我机器上占2个字节）更节省内存，但是在运算中的效率，是int更高。所以上面，无论是逻辑运算a>b还是算术运算a+b中a和b都默认转换成了int，所以算术运算的结果也是带符号的。   注意标红的前提条件 但是还需要注意一个问题就是转换成int类型的时候，高位补齐的问题。  如果是unsigned的类型转换成int类型，高位补0.  如果是signed的类型转换成int类型，如果原来最高位是1则补1，如果是0则补0。


Question: 输入整数a,b,c，输出最大值，为什么我这个总是错误

引用 8 楼 ly93969 的回复:[quote=引用 1 楼 自信男孩的回复:]测试了没什么问题；  代码有冗余，改一下；  #include<stdio.h>  int main() {     int a,b,c,max;      scanf("%d%d%d", &a,&b,&c);     if (a > c)         max = a;     else         max = c;      if (max < b)         max = b;         //max = max;     //else      //   max = b;     printf("%d\n", max);     return 0; } 楼主是怎么测试的？  max = a > c ? ((a > b) ? a:b) : ((b > c) ? b:c); 一条语句搞定，不过有点复杂，根据自己的理解选择那种方式～ 我又重新创建了一个空项目，然后就可以运行了 应该是软件出问题了吧，一直显示Debug错误[/quote]  恩，那是环境问题，跟代码没关系～

引用 7 楼 ggglivw的回复:对AB取最大，然后用这个结果和C取最大不就搞定了吗？哪里需要这么复杂把自己绕晕 明白了。。。

引用 2 楼 user-4的回复:哪儿错了？？？？ 我又重新创建了一个空项目，然后就可以运行了☒ 应该是软件出问题了吧，之前一直显示Debug错误

引用 1 楼 自信男孩的回复:测试了没什么问题；  代码有冗余，改一下；  #include<stdio.h>  int main() {     int a,b,c,max;      scanf("%d%d%d", &a,&b,&c);     if (a > c)         max = a;     else         max = c;      if (max < b)         max = b;         //max = max;     //else      //   max = b;     printf("%d\n", max);     return 0; } 楼主是怎么测试的？  max = a > c ? ((a > b) ? a:b) : ((b > c) ? b:c); 一条语句搞定，不过有点复杂，根据自己的理解选择那种方式～ 我又重新创建了一个空项目，然后就可以运行了 应该是软件出问题了吧，一直显示Debug错误

对AB取最大，然后用这个结果和C取最大不就搞定了吗？哪里需要这么复杂把自己绕晕

引用 5 楼 qq_51590857 的回复:[quote=引用 4 楼 自信男孩的回复:][quote=引用 3 楼 qq_51590857 的回复:][quote=引用 楼主 ly93969的回复:]#include<stdio.h> int main() { 	int a,b,c,max; 	scanf("%d%d%d", &a,&b,&c); 	if (a > c) 		max = a; 	else 		max = c; 	if (max > b) 		max = max; 	else 		max = b; 	printf("%d\n",max); 	return 0; } #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  printf("%d\n",max); return 0; }[/quote] 你的代码有问题，如果a > b 且a < c的情况没有考虑～[/quote] #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  else if(a<c) max=c； printf("%d\n",max); return 0; } 这样对吗[/quote] 自己测测吧，程序写出来通过了测试才能说没问题～

引用 4 楼 自信男孩的回复:[quote=引用 3 楼 qq_51590857 的回复:][quote=引用 楼主 ly93969的回复:]#include<stdio.h> int main() { 	int a,b,c,max; 	scanf("%d%d%d", &a,&b,&c); 	if (a > c) 		max = a; 	else 		max = c; 	if (max > b) 		max = max; 	else 		max = b; 	printf("%d\n",max); 	return 0; } #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  printf("%d\n",max); return 0; }[/quote] 你的代码有问题，如果a > b 且a < c的情况没有考虑～[/quote] #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  else if(a<c) max=c； printf("%d\n",max); return 0; } 这样对吗

引用 3 楼 qq_51590857 的回复:[quote=引用 楼主 ly93969的回复:]#include<stdio.h> int main() { 	int a,b,c,max; 	scanf("%d%d%d", &a,&b,&c); 	if (a > c) 		max = a; 	else 		max = c; 	if (max > b) 		max = max; 	else 		max = b; 	printf("%d\n",max); 	return 0; } #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  printf("%d\n",max); return 0; }[/quote] 你的代码有问题，如果a > b 且a < c的情况没有考虑～

引用 楼主 ly93969的回复:#include<stdio.h> int main() { 	int a,b,c,max; 	scanf("%d%d%d", &a,&b,&c); 	if (a > c) 		max = a; 	else 		max = c; 	if (max > b) 		max = max; 	else 		max = b; 	printf("%d\n",max); 	return 0; } #include<stdio.h> int main() { int a,b,c,max; scanf("%d%d%d", &a,&b,&c); max=a; if (a < b) { if (b < c) max=c; else   max=b; }  printf("%d\n",max); return 0; }

哪儿错了？？？？


Question: 链表求助

基本符合要求了，是否有bug未详细测试  #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h>  typedef struct node {     int data;     struct node *next; }linknode, *linklist;  //创建链表 linklist createLink() {     linklist pHead = (linknode*)malloc(sizeof(linknode));     if ( pHead == NULL )     {         printf("内存分配失败\n");         return NULL;     }     pHead->data = 0;     pHead->next = NULL;     return pHead; }  //链表赋值 void AddNode(linklist pHead) {     int a;     linklist pTemp = NULL, pCurr = pHead;     printf("输入链表结点的值，-1结束\n");     while ( 1 )     {         scanf("%d", &a);         if ( a != -1 )         {             pTemp = (linknode*)malloc(sizeof(linknode));             pTemp->data = a;             pTemp->next = NULL;             pCurr->next = pTemp;             pCurr = pTemp;         }         else         {             break;         }     } }  //输出链表 void printLink(linklist pHead) {     linklist pTemp = pHead->next;     while ( pTemp != NULL )     {         printf("%d ", pTemp->data);         pTemp = pTemp->next;     }     printf("\n"); }  //删除大于x不大于y的结点值 void deletedata(linklist L, int x, int y) {     linklist pOne = L, pTwo = L->next, pTemp = NULL;          //遍历查找符合条件的结点     while ( pTwo != NULL )     {         if ( pTwo->data > x && pTwo->data <= y )         {             if ( pTwo->next != NULL )             {                 pOne->next = pTwo->next;                 pTemp = pTwo;                 free(pTemp);                 pTemp = NULL;                 pTwo = pOne;             }             else             {                 pOne->next = NULL;                 free(pTwo);                                 pTwo = pOne;             }         }         pOne = pTwo;         pTwo = pTwo->next;     } }  int main() {     linklist pHead;     pHead = createLink();     AddNode(pHead);     printLink(pHead);      deletedata(pHead, 60, 70);     printLink(pHead);      system("pause");     return 0; }

先自己写写吧，比如先创建一个带头结点的链表，然后输出链表。这两个函数先写出来，后面再写删除的函数～

//删除大于x不大于y的结点值 void deletedata(linklist L, int x, int y) {     linklist pOne = L, pTwo = L->next, pTemp = NULL;      //遍历查找符合条件的结点     while ( pTwo != NULL )     {         if ( pTwo->data > x && pTwo->data <= y )         {             pTemp = pTwo;             pOne->next = pTwo->next;             free(pTemp);             pTwo = pOne->next;             continue; #if 0             if ( pTwo->next != NULL )             {                 pOne->next = pTwo->next;                 pTemp = pTwo;                 free(pTemp);                 pTemp = NULL;                 pTwo = pOne;             }             else             {                 pOne->next = NULL;                 free(pTwo);                 pTwo = pOne;             } #endif         }         pOne = pTwo;         pTwo = pTwo->next;     } } 供参考～ 楼上写的没问题，如上是我在他的基础上修改的，可以对比一下～

最好将main修改为 int main() {      int x,y;  	linklist pHead;     pHead = createLink();     AddNode(pHead);     printLink(pHead);  	scanf("%d%d",&x,&y);//指出x,y的范围     deletedata(pHead, x, y);     printLink(pHead);       system("pause");     return 0; }

deletedata函数可以简化为如下 void deletedata(linklist L, int x, int y) {     linklist pOne = L, pTwo = L->next, pTemp = NULL;           //遍历查找符合条件的结点     while ( pTwo != NULL )     {         if (pTwo && pTwo->data > x && pTwo->data <= y )         {                 pOne->next = pTwo->next;                 pTemp = pTwo;                 free(pTemp);                 pTemp = NULL;                 pTwo = pOne;         }         pOne = pTwo;         pTwo = pTwo->next;     } }


首先a是整型数，把整型数用%f输出输出0是可能的。  另外，a = 1.0 / 3 * 3;由于a是整型数，1.0/3  *3得到的结果可能是0.999xxxx；这样再转成整型数就是0了。  修改方法：  float a;//定义a为float类型 试试～

引用 3 楼 Cardistalive的回复:将第4行代码: int a; 修改成 float a; 这样就将，原先数据类型为整型的数据a，修改成，支持有效数字至少为6位小数的单精度浮点型数据a ,以容纳第5行的计算结果 支持有效数字至少为6位的单精度浮点型数据

double a；


Question: 调试过程中遇到的一个问题,不解..求 解答.

引用 4 楼 UIUI 的回复:这个函数是返回了局部变量的地址，是无意义的。因为局部变量在函数调用结束后会自动释放的，不能再次使用了。可以考虑加上static将其变成全局变量；  void* CheckRangeInit(void) { #define MaxArray 50     static int i = 0;     static long temp[MaxArray][2] = { 0 };     if (i < 49)         return (void*)temp[i++];     else         return (void*)-1; }    确实加上 static 就可以了..  找了半天问题, 就是没想到这儿的问题. 谢谢. 奇怪! 为什么原贴中不写打印函数就可以直接用,不会有问题呢.[/quote]  在函数外使用局部变量是未定义行为，结果可能是随机的～

这个函数是返回了局部变量的地址，是无意义的。因为局部变量在函数调用结束后会自动释放的，不能再次使用了。可以考虑加上static将其变成全局变量；  void* CheckRangeInit(void) { #define MaxArray 50     static int i = 0;     static long temp[MaxArray][2] = { 0 };     if (i < 49)         return (void*)temp[i++];     else         return (void*)-1; }  [/quote]  确实加上 static 就可以了..  找了半天问题, 就是没想到这儿的问题. 谢谢. 奇怪! 为什么原贴中不写打印函数就可以直接用,不会有问题呢.

啊平, 用VS2008 上述程序就没有问题.          用VS2019 就有问题......          如何避免.呀...

void* CheckRangeInit(void) { #define MaxArray 50     static int i = 0;     long temp[MaxArray][2] = { 0 };     if (i < 49)         return (void*)temp[i++];     else         return (void*)-1; }   这个函数是返回了局部变量的地址，是无意义的。因为局部变量在函数调用结束后会自动释放的，不能再次使用了。可以考虑加上static将其变成全局变量；  void* CheckRangeInit(void) { #define MaxArray 50     static int i = 0;     static long temp[MaxArray][2] = { 0 };     if (i < 49)         return (void*)temp[i++];     else         return (void*)-1; }

如果用 printf_s( printf)  改成 puts(),  句柄里的值也不会发生变化 . 怎么这么奇怪?


Question: 求最大公约数

引用 12 楼 m0_51348310 的回复:[quote=引用 11 楼 绿色盒子的回复:]报错？请贴出报错代码 default. c:1:4:error:stray'\302'in program int Maxcommomdivisor(int a,int b) default. c:1:5:error:stray'\240'in program int Maxcommomdivisor(int a,int b) default. c:1:26:error:stray'\302'in program int Maxcommomdivisor(int a,int b)  default. c:1:27:error:stray'\240'in program int Maxcommomdivisor(int a,int b)[/quote] 你这个是有非法字符，你可以尝试删除之后手打代码

引用 11 楼 绿色盒子的回复:报错？请贴出报错代码 default. c:1:4:error:stray'\302'in program int Maxcommomdivisor(int a,int b) default. c:1:5:error:stray'\240'in program int Maxcommomdivisor(int a,int b) default. c:1:26:error:stray'\302'in program int Maxcommomdivisor(int a,int b)  default. c:1:27:error:stray'\240'in program int Maxcommomdivisor(int a,int b)

报错？请贴出报错代码

楼主复制了八楼、九楼的答案。虽然答案很厉害的样子，但运行时都显示错误。楼主只是个初学者啊，看不懂也改不了

int Maxcommomdivisor(int a, int b)  {     while(a%b){         int tmp = a;         a = b;         b = tmp%b;     }     return b; }

#include <iostream> using namespace std;  int Func(int a, int b) { 	int c = a%b; 	if (c == 0) 	{ 		return b; 	} 	else 	{ 		a = b; 		b = c; 		return Func(a,b); 	} }  int main() { 	int a, b; 	cout << "输入两个数："; 	cin >> a; 	cin >> b; 	cout << "接收到数据：" << a << "和" << b << endl; 	cout << "最大公约数为：" << Func(a,b);     return 0; }

min=(a<b)?a:b;

楼主的min变量没初始化就直接使用，会有问题的～

你想让大家帮你做啥呢

引用 6 楼 一根烂笔头的回复:反过来计算，i值就是结果，省一次赋值         for(i=min;i>=1;i--)         {              if(a%i==0&&b%i==0)                break;         }  回六楼： 谢谢你的方法， 不过， 我的老师讲过这种从大到小的方法。 然而， 我需要的是从小到大的方法。

楼主写了一个程序（错的）。老师发现后，添加了一个变量使程序正确。然后老师要求楼主用另一种方法修正程序。 楼主写的程序： #include<stdio.h> int main() {       int a,b,min,i;       scanf("%d,%d",&a,&b);        min=(a<b)? a:b;        for(i=1;i<=min;i++)         {              if(a%i==0&&b%i==0)                continue;         }        printf("输出最大公约数%d",i-1); } 老师写的程序： #include<stdio.h> int main() {       int a,b,min,x,i;       scanf("%d,%d",&a,&b);        min=(a<b)? a:b;        for(i=1;i<=min;i++)         {              if(a%i==0&&b%i==0)                x=i;         }        printf("输出最大公约数%d",x); }

楼主写了一个代码（可惜是错的），如下： #include<stdio.h> int main() {       int a,b,min,i;       scanf("%d,%d",&a,&b);        min=(a<b)? a:b;        for(i=1;i<=min;i++)         {              if(a%i==0&&b%i==0)                continue;         }        printf("输出最大公约数%d",i-1); } 老师发现后改为 #include<stdio.h> int main() {       int a,b,min,x,i;       scanf("%d,%d",&a,&b);        min=(a<b)? a:b;        for(i=1;i<=min;i++)         {              if(a%i==0&&b%i==0)                x=i;         }        printf("输出最大公约数%d",x); } 然后，老师要求我用另一种方法从小到大筛选最大公约数。


Question: 求大佬帮忙

引用 1 楼 user-2的回复:for 后面的分号去掉 我昨晚解决了，原来的空格的内循环没效果

引用 1 楼 user-2的回复:for 后面的分号去掉 不好使的我试了

看逻辑上，可以再优化下 假设你的金子塔有n层，你需要输出n行，每行有两个东西 ：1.前面的空格，2.字母 第一行  前面是（n-1)/2个空格 1个字母  第二行  前面是  (n-2)/2个空格 2个字母  以此类推  第i行 前面输出(n-i)/个空格  i个字母  这样两层循环就可以了

for 后面的分号去掉


Question: 求求C语言大佬带带萌新

你的循环里面 下面那个break多余了，会导致循环只执行以此就退出了，把它去掉

#include<stdio.h>  int main(void) {     int n,even=0,odd=0;     float sumeven=0,sumodd=0;     while(1)     {         scanf("%d",&n);         if(n==0){             break;         }          if(n%2==0)         {             sumeven+=n;             even++;         }         else         {             sumodd+=n;             odd++;         }         //break;     }     printf("Number of even:%d;Average of even:%.2f\n",even,sumeven/even);     printf("Number of odd:%d;Average of odd:%.2f\n",odd,sumodd/odd);      return 0; } 供参考～  多一个break；


Question: OJ练习题   C语言求解  输入N后输出1+1/2+1/3+…+1/N的和

引用 1 楼 user-3的回复:i是int，所以1/i被转成int，i大于1时int结果就是0 所以改成 sum=sum+1.0/i //1.0是double，就算结果就不再是int了 谢谢！！！！！！知道哪里错了就舒服多了！

是个好方法！谢谢

逐步学会调试程序，是找到程序问题的关键。 在此题中，可以在循环中增加显示i/1的值的输出语句，观察输出结果，以判断问题出在何处，从而找出解决问题的方法

引用 2 楼 自信男孩的回复:1/i；由于i是int类型，因此1/i是按照整型数的除法来计算的，因此得到的是整型的结果，如果改成1.0/i，由于1.0编译器会认为其是double，所以1.0/i是按照浮点数来计算除法，因此得到的是double结果。 嗯嗯，好的好的👌，谢谢


Question: 求一个编程技巧...

主要问题是最后一个函数怎么实现的.

不客气！学习愉快~~

非常感谢你的回复.   谢谢呀. 真的谢谢.

#include <stdio.h> #include <stdlib.h> void* CheckRangeInit(void); void  CheckRangeExit(void *); void  CheckRangeSet(void* ptHandle, long ForOffset, long BackOffset, long Target, long Resolution); unsigned short CheckRangeDetect(void* ptHandle, long Current);   int main(void) {     void* test1 = 0;     test1 = CheckRangeInit();  //为每一个变量分配地址.  我猜的.     //实际数值在40 与 70 之单     CheckRangeSet(test1, 10, 20, 50, 360);  //设置 检测检测范围      // test1 当前值为60 在40与70之间, 所以打印. Yes!     if(CheckRangeDetect(test1, 60))         printf("Yes!\n");     else         printf("No!\n");      CheckRangeExit(test1);     return 0; } void* CheckRangeInit(void) //为每个变量分配一个地址, 如果是这样, 我可以实现. {     return (void *)malloc(sizeof(long)*4); } void  CheckRangeExit(void * r) {     long * rp = (long *)r;     free(rp); }  //这个函数,我不会实现, /* 参数1是 变量句柄 参数2是 最小, 参数3是 最大 参数4是 基准值 参数5是 最大范围值.只能在范围值内偏移.  */ void  CheckRangeSet(void* ptHandle, long ForOffset, long BackOffset, long Target, long Resolution) {     long * set = (long *) ptHandle;     set[0] = ForOffset;     set[1] = BackOffset;     set[2] = Target;     set[3] = Resolution; } /* 检测 当前值是否在设置的最小最大范围内. 我的主要疑问是这个函数. ptHandle 里面只能存一个数字, 然后,用当前值怎么去和两个数字(最小值,最大值) 比大小呢? */ unsigned short CheckRangeDetect(void* ptHandle, long Current) {     const long * set = (const long *) ptHandle;     return Current >= set[2] - set[0] && Current <=set[2] + set[1]; }

也不知道我想的对不对，初始化函数中，可能有一个2维数组，返回值一个地址，该地址中指向的地方是一个2维数组，然后，那个设置函数，把最大值与最小值 计算后，存到相应句柄地址的数组中，这样，每一个句柄实际上有两个变量，所以最后一个比较大小的函数直接取出来用就可以。

引用 2 楼 丁劲犇 的回复:ptHandle 是void*，可以指向很多类型，比如数组（int *)，甚至结构体。所以，void * 可以存储N多东西的。  void * 这个我明白.我主要是没明白  unsigned short CheckRangeDetect(void* ptHandle, long Current) 主要是这个我没明白, 他是怎么实现只用一个 pthandle 来与当前值对比的.  如果我做这个东西. 我只会一个简单的方法.  void  CheckRangeSet(void* ptHandle, long ForOffset, long BackOffset, long Target, long Resolution) {   } 在这个里面, 计算出,最大值,与最小值, 然后, 存放到 两个全局变量中.. 然后,用 CheckRangeDetect () 这个函数 读入当前值,来与 那两个全局变量作比较.,然后,返回 0 或1.  可是,我看别人的程序的时候, 是没有设置那两个全局变量呀.


Question: 关于stdout是行缓冲的问题

能把你的程序出来看看吗？谢谢！

因为程序退出了，那么行也结束了。stderr是无缓冲的，会直接输出； 楼主的程序，在我的代码里运行的是 World!Hello


Question: 关于c语言链表指针的一些问题，希望大神帮我解答，感谢！

引用 11 楼 qybao的回复:我觉得已经讲的挺清楚了，只是你没好好理解。 free只是设置一个flag告诉系统这块内存不再使用了，系统可以把这块内存让给其他程序使用。但是并不代表立刻有别的程序来占用这块内存，所以这块内存的信息一时半会没有被擦写，还是原来的老信息，所以可能继续访问时还能读出原来的信息。 然而一旦这块内存被系统重新份配给别的程序，别的程序就有可能重新修改了这块内存的信息，那么这块内存的信息就未必符合原来的结构体形式，比如原来老信息是一个int，一个长度为10的char数组，新的信息是一个char，一个int，这样你按原来的结构体形式来读取，结果必然出错，而且新的内存空间没有老的内存空间大，按原来的结构体形式读取还可能造成越界。打个比方，原来某个地址有一块地被你租用，你建了一栋500平米的楼房，后来你free把地退租了，地和楼房被房东收回，此时房东还没把楼拆了，你偷偷溜回来那自然还可以正常使用房子，然而如果房东把它拆了把地分割租给了别的租户，别的租户只建了50平米的平房租，这时你非要闯进人家的平房，并按原来500平米的楼房来使用，那可不就出错了吗？而且，人家平房的租客有可能把门锁了不让你进来，你进不来不就造成非法访问了吗？ 所以，同样是野指针，也分野指针指向的地址是什么情况，楼房还没拆，那就一时半会还能使用，楼房拆了被改建为平房了，那如果平房们没锁你还可以溜进去，只是房子布局不一样了，人家没2楼你非要上2楼，那就会出错，甚至如果平房锁着禁止进入，你就成了非法入侵的窃贼。 所以，你在delete函数里的野指针属于楼房没拆的情况（地址是明确的，只是房东还没来得及拆楼）；在main里的野指针属于没有乱闯入民宅并把民宅当楼房使用的情况（因为没分配过内存，地址是随机的，也就是你随机闯入任何一家民宅）。 能理解吗？ 我理解了，大神别生气，本人比较愚笨，还有一小点儿疑问，，就是 我上面 又重新定义了一个方法void 在 void方法里面定义了一个指针 freeaid 这个时候，这个指针还没有分配内存，这个野指针跟free函数里，已经指向了被释放空间的指针(被释放前不是野指针，释放后就是野指针了)的情况还不太一样。 我在void的方法里面调num参数也是能打印出值的，也没有报错。但是在main里 随便定义一个*stu类型的指针 取他的 num值就会报错(这个经过你的提点我已经知道是咋回事了)   我就是想知道。为啥 同样都是没分配空间的野指针，在主函数就会报错，在void函数里就不会报错   大神关于房子的解答真的很形象，我理解的更透彻了。感谢。。。100分都是你的

引用 6 楼 qybao的回复:[quote=引用 5 楼 qq_35541626 的回复：]感谢两位大大的答复，我把之前的代码改了一下，现在p_freeAid可以打印 p_free->next->num 的值了。  void free_node(STU **p_head){     STU*p_free;     STU*p_freeAid;     printf("p_freeAid的值是：0X%x\n",p_freeAid->num);     p_free=*p_head;     if(*p_head==NULL){         printf("这个链表为空，无需释放\n");     }     else{         while (p_free!=NULL) {             p_freeAid=p_free->next;             if(p_freeAid!=NULL){                 printf("p_freeAid0000000的值是：0X%x\n",p_free->next->num);             }              printf("p_freeAid的值是：0X%x\n",p_freeAid);             printf("p_free的值是：0X%x\n",p_free->next);             int num=p_free->num;             printf("%d\n",num);             free(p_free);             printf("%d\n",p_free->num);             p_free=p_freeAid;         }     }     //*p_head=NULL; }   但是又有一些新的问题出现。 int main() {     STU* link_head=NULL;    STU*test_01;    //test();    printf("0X%x\n",test_01);    //printf("0X%x\n",test_01->num);     //test_01=NULL;    int num=test_01->num;    printf("0X%x\n",test_01);     return 0; }  我在主函数 main 里面直接定义了一个 STU格数的test函数，然后直接调test->num.果然出现了，之前那样的段错误提醒。  但是 void test(){     STU*test_02;     printf("0X%x\n",test_02->num); }  int main() {     STU* link_head=NULL;    STU*test_01;    test();    printf("0X%x\n",test_01);    //printf("0X%x\n",test_01->num);     //test_01=NULL;    int num=test_01->num;    printf("0X%x\n",test_01);     return 0; }  当我在函数 test里面定义了一个STU类型的*test指针，然后调用test函数，这里编译通过，然后值就出来了（虽然是没有意义的值，但是编译通过了），所以我就不太明白，同样都是指空的指针，为什么一个出现了段错误，一个没有。 这也是我一直想不明白的。 就是我在最开始的链表释放函数node_free里面，刚开始定义的指针 *stu p_freeAid 后，马上打印p_freeAid->num 是有值的，但是当我给他赋值，free->next的时候，他就出现了段错误。 所以我的核心问题就是 同样都是野指针，然后我调里面的值，为什么一个直接出现段错误，一个就没有，能打出来值（虽然值没有什么意义。。）  还有一个问题就是我之前的 链表释放函数node_free里面，我已经free过的空间，我再次用 p_free去调里面的值，按理说，这时空间已经被释放，这个时候，p-free就是个野指针，我用debug看，p-free里面的值已经变成了“-16168940”之类的数，我理解就是已经释放掉了，但是我用p-free去调里面的 num 居然可以打印出来值，也没有报段错误，那么我这个free（）函数究竟有没有生效呢？ 这种情况应该怎么解释呢？ 费解....  再次感谢两位大大的解答，谢谢。 既然是野指针，那就说明指针指向的地址是不确定的。你刚释放内存，又继续访问该内存，如果该内存没有被其他程序占用，那你访问它不会出错；如果该内存被其他程序占用了，那就有问题了，如果该内存被其他程序设定不可读写，你非要读写，就会出非法内存访问错误了。[/quote] 你好，非常感谢您的回复，但是我的问题是 我free了之后，为什么访问被free的区域还是有值，我也知道不能访问，但是访问之后为什么有值是我比较纠结的，所以我这个free到底有没有成功?  还有就是 为什么我同样都是野指针，我在函数里面调值就可以调，但是在主函数那里就会报段错误。这两个问题请您再解释一下。 解决完问题我就结帖了。   希望您再回复一下。谢谢。

引用 7 楼 赵4老师的回复:数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633 您好，请您再看下我的问题好不，我不是纠结链表怎么做，我是在纠结c语言本身的机制问题，为什么free了还有数值，还有 为什么 同样都是野指针，在函数里定义野指针就不会报段错误，在主方法里定义就会报段错误呢？

引用 5 楼 qq_35541626 的回复：感谢两位大大的答复，我把之前的代码改了一下，现在p_freeAid可以打印 p_free->next->num 的值了。  void free_node(STU **p_head){     STU*p_free;     STU*p_freeAid;     printf("p_freeAid的值是：0X%x\n",p_freeAid->num);     p_free=*p_head;     if(*p_head==NULL){         printf("这个链表为空，无需释放\n");     }     else{         while (p_free!=NULL) {             p_freeAid=p_free->next;             if(p_freeAid!=NULL){                 printf("p_freeAid0000000的值是：0X%x\n",p_free->next->num);             }              printf("p_freeAid的值是：0X%x\n",p_freeAid);             printf("p_free的值是：0X%x\n",p_free->next);             int num=p_free->num;             printf("%d\n",num);             free(p_free);             printf("%d\n",p_free->num);             p_free=p_freeAid;         }     }     //*p_head=NULL; }   但是又有一些新的问题出现。 int main() {     STU* link_head=NULL;    STU*test_01;    //test();    printf("0X%x\n",test_01);    //printf("0X%x\n",test_01->num);     //test_01=NULL;    int num=test_01->num;    printf("0X%x\n",test_01);     return 0; }  我在主函数 main 里面直接定义了一个 STU格数的test函数，然后直接调test->num.果然出现了，之前那样的段错误提醒。  但是 void test(){     STU*test_02;     printf("0X%x\n",test_02->num); }  int main() {     STU* link_head=NULL;    STU*test_01;    test();    printf("0X%x\n",test_01);    //printf("0X%x\n",test_01->num);     //test_01=NULL;    int num=test_01->num;    printf("0X%x\n",test_01);     return 0; }  当我在函数 test里面定义了一个STU类型的*test指针，然后调用test函数，这里编译通过，然后值就出来了（虽然是没有意义的值，但是编译通过了），所以我就不太明白，同样都是指空的指针，为什么一个出现了段错误，一个没有。 这也是我一直想不明白的。 就是我在最开始的链表释放函数node_free里面，刚开始定义的指针 *stu p_freeAid 后，马上打印p_freeAid->num 是有值的，但是当我给他赋值，free->next的时候，他就出现了段错误。 所以我的核心问题就是 同样都是野指针，然后我调里面的值，为什么一个直接出现段错误，一个就没有，能打出来值（虽然值没有什么意义。。）  还有一个问题就是我之前的 链表释放函数node_free里面，我已经free过的空间，我再次用 p_free去调里面的值，按理说，这时空间已经被释放，这个时候，p-free就是个野指针，我用debug看，p-free里面的值已经变成了“-16168940”之类的数，我理解就是已经释放掉了，但是我用p-free去调里面的 num 居然可以打印出来值，也没有报段错误，那么我这个free（）函数究竟有没有生效呢？ 这种情况应该怎么解释呢？ 费解....  再次感谢两位大大的解答，谢谢。 既然是野指针，那就说明指针指向的地址是不确定的。你刚释放内存，又继续访问该内存，如果该内存没有被其他程序占用，那你访问它不会出错；如果该内存被其他程序占用了，那就有问题了，如果该内存被其他程序设定不可读写，你非要读写，就会出非法内存访问错误了。

printf("p_freeAid的值是：0X%x\n",p_freeAid->num); 这条语句是在哪里打印的，从你的函数里可以知道，这条语句是在定义两个变量后直接打印的，你定义的变量没有初始化呀，没初始化就是野指针，之所以说是可能出现段错误，是因为野指针指向的位置可能是不可以读写的，既然不可以读写，那么必然会出现段错误。   //printf("p_freeAid的值是：0X%x\n",p_free->next->num); 这条语句是因为不能保证p_free->next指向的内容不是链表的末尾，如果指向了链表末尾，即NULL，那么这条语句打印必然会导致段错误～

你好，首先非常感谢您的解答，我初学c，以前用Java模拟过链表，但是好像没c语言要考虑的那么多。关于您的回答我还是有一些疑问。 “printf("p_freeAid的值是：0X%x\n",p_freeAid->num);这句之前p_freeAid是野指针，这样操作可能导致段错误” 关于这句话，P-freeAid 的指向，我认为明明是指向 p-free->next 的。 而且在执行这行代码的时候，明明在free.next里面还是有值的。所以按照我的理解P-freeAid里面应该是有值的，而且 我debug里面， p-freeAid里面的“num”也是有值的，但是我用 printf函数调的时候，程序就进行不下去，所以就不太理解，所以还是希望您能就这点再给解答一下。  而且之前那个 showLink函数里面，我就把p_head->next的值赋给了p_mov。然后我在打印的时候  就是调用的 p_mov->num,来取值的。 在free函数里面 我用p_freeAid 来接收 p_free->next的值，然后同样想调用 p_freeAid->num 来取值为什么就不行了呢？   费解中。。。。

在free_node函数里有多处问题， 1. printf("p_freeAid的值是：0X%x\n",p_freeAid->num);这句之前p_freeAid是野指针，这样操作可能导致段错误； 2.  printf("p_freeAid的值是：0X%x\n",p_free->next->num);这条打印也可能出现多错误，因为p_free不是NULL，不等于p_free->next不为NULL； 3.  free(p_free);             printf("%d\n",p_free->num); 在释放之后打印这条语句，结果是未定义的，因为已经释放的空间，其内容具有不确定性，释放的空间不能再次直接使用，需要重新malloc； 4.  //*p_head=NULL;这句不能注释掉，因为头结点已经释放掉了，为了保证后面对头结点的使用不出现问题，这句需要加上（去掉注释）；  void free_node(STU **p_head) {     STU*p_free;     STU*p_freeAid;     //printf("p_freeAid的值是：0X%x\n",p_freeAid->num);     p_free=*p_head;     if(*p_head==NULL){         printf("这个链表为空，无需释放\n");         return;     }     //else{     while (p_free!=NULL) {         p_freeAid=p_free->next;         //printf("p_freeAid的值是：0X%x\n",p_free->next->num);         printf("p_freeAid的值是：0X%x\n",p_freeAid);         printf("p_free的值是：0X%x\n",p_free->next);         int num=p_free->num;         printf("%d\n",num);         free(p_free);         printf("%d\n",p_free->num);         p_free=p_freeAid;     }     //}     *p_head=NULL; } 代码逻辑可以稍微改一下，去掉else， 另外，打印指针建议用%p


Question: 请问这个题

引用 3 楼 均陵鼠侠 的回复:[quote=引用 2 楼 我当时害怕极了QAQ 的回复:][quote=引用 1 楼 均陵鼠侠 的回复:]谢邀。 题目不是问CPU如何选择，是问CPU如何用地址线来访问模块板。第（5）回答已经明确了。  嗯，就是那个最高3位，次高3位是怎么得出来的呢？[/quote]  不管地址线几根，从中划出N根线，可以访问的模块板是2^N块，剩余的线访问模块板内的芯片。从剩余部分划出M根线，可访问的芯片数量是2^M。你用这个方法倒推一下。[/quote]  引用 5 楼 qybao 的回复:模板块总数=8=2^3，即用3位即可覆盖模板号代表的地址信息 因为是8位机，芯片只有4位，所以用两片芯片组合成8位，比如A芯片负责高4位，B芯片负责低4位，这样就能从8位换算的结果区分是A芯片B芯片（比如是0-127就是B，128-255就是A），这样32k/4k=8=2^3，用3位也能覆盖芯片号代表的地址信息  懂了懂了，谢谢大神

剩下的就是18-3-3=12位，用来区分片内地址

引用 3 楼 均陵鼠侠 的回复:[quote=引用 2 楼 我当时害怕极了QAQ 的回复:][quote=引用 1 楼 均陵鼠侠 的回复:]谢邀。 题目不是问CPU如何选择，是问CPU如何用地址线来访问模块板。第（5）回答已经明确了。  嗯，就是那个最高3位，次高3位是怎么得出来的呢？[/quote]  不管地址线几根，从中划出N根线，可以访问的模块板是2^N块，剩余的线访问模块板内的芯片。从剩余部分划出M根线，可访问的芯片数量是2^M。你用这个方法倒推一下。[/quote]  嗯嗯，N=3我懂了，M不会求。。

引用 2 楼 我当时害怕极了QAQ 的回复:[quote=引用 1 楼 均陵鼠侠 的回复:]谢邀。 题目不是问CPU如何选择，是问CPU如何用地址线来访问模块板。第（5）回答已经明确了。  嗯，就是那个最高3位，次高3位是怎么得出来的呢？[/quote]  不管地址线几根，从中划出N根线，可以访问的模块板是2^N块，剩余的线访问模块板内的芯片。从剩余部分划出M根线，可访问的芯片数量是2^M。你用这个方法倒推一下。

引用 1 楼 均陵鼠侠 的回复:谢邀。 题目不是问CPU如何选择，是问CPU如何用地址线来访问模块板。第（5）回答已经明确了。  嗯，就是那个最高3位，次高3位是怎么得出来的呢？


Question: 这么简单怎么不会呢？？？ 啊 我.. 我...不会[face]qq:9.gif[/face]

输入会不会 判断奇数偶数会不会 其他会不会 都会 你已经能写出来了 都不会 看书去

如果一点不会，那要找一下自己的问题～这个问题确实不难，动手写一下，遇到具体问题再发出来～

我写出来了，写出来了！ 在此谢谢两位！

自己的作业自己做。 你写完代码结果不对可以贴上来。相信有人可以帮你看看


Question: 小白想请教一个关于C语言指针的问题，大神可不可以指点一下，用的是VS2019

引用 9 楼 lin5161678 的回复:[quote=引用 7 楼 自信男孩 的回复:] 跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？ 哪怕是按照入栈理解你的解释也是错的 两个++ 一个操作p 一个操作某个元素的y 也就是说p只操作1次 也就是说没越界  你按照越界理解才是错误的解释  顺便如果入栈顺序能解释 请你解释#4的结果 [/quote] 第二个结构体，我的测试结果是：4,3 不是4,4 可以查一下传参，对于参数是表达式的是传表达式还是传值。参数传递是传值吧，怎么传值呢，必然先计算；所以printf打印之前是先把值计算出来再穿进去了，既然这样跟入参的顺序是有关系的～

引用 7 楼 自信男孩 的回复:跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？ 哪怕是按照入栈理解你的解释也是错的 两个++ 一个操作p 一个操作某个元素的y 也就是说p只操作1次 也就是说没越界  你按照越界理解才是错误的解释  顺便如果入栈顺序能解释 请你解释#4的结果

引用 5 楼 lin5161678 的回复:[quote=引用 3 楼 自信男孩的回复:]函数调用，要把参数入栈，一般参数入栈是从左向右依次入栈的，因此出栈就是从右向左了，最后一个参数先出栈，也就是最后一个参数表达式先计算，这样可以解释第一个输出为什么是3,1；后面的一个是1；但是对于3这个输出是随机的，因为p指向的内容已经是越界了～ 这是常见误解 入栈顺序和这个错误无关 这里出现错误是求值无序 而求值顺序和入栈顺序没有必然联系[/quote] 跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？

----------------------------------------------------再试图分析一波 printf("%d,%d", (++p)->y,++p->y); 从结果上看，标准仅规定了在执行printf第一个语句之前。一定会完成【对p的自增】以及【对p中y的自增】两个副作用 但并没有明确具体时间与具体顺序。 乍一看两个自增副作用是彼此独立的。但实际上是存在相互影响的可能的

引用 19 楼 lin5161678 的回复:[quote=引用 18 楼 自信男孩 的回复:] 这个结果跟入栈参数的顺序有关系 没看懂吗  入栈是从右到左 但计算顺序和这个没关系 (++p)->y 他可以计算++p 后面不计算->y 而是求值另一个参数 中间的参数求值完成 再把最后的参数的 ->y处理完 这个求值顺序你说和入栈顺序有关系? 这不是胡扯么  [/quote] 我的想法是入栈顺序决定了计算顺序，你的理论是跟入栈没关系，先计算后入栈（我是赞同的，但是先计算哪个实参的问题，先计算那个实参，会导致p的指向指向那个结构元素问题）

引用 21 楼 千梦一生 的回复:不过非要去讨论他是怎么算出这些答案的实属浪费时间。 正常人正常情况不会写出也不会遇到这样的写法。  如同讨论空气。 探讨就有探讨的价值，不是讨论空气。通过探讨希望能注意到更多的问题和知识点～

printf("%d,%d", ++p->y,(++p)->y); 这个地方的结果 4，4 只能想到一种顺序可能： <1>【p自增副作用完成】p指向第二个元素 <2>【p.y自增副作用完成】p.y变成4 <3>++p->y这个表达式的值作为参数入栈 <4>p->y这个表达式的值作为参数入栈 <5>call printf  <3><4>操作决定的入栈顺序也许可以交换，不过在这里实际没有区别。 所以<1><2><3><4>可以是（如果不考虑入栈顺序的前提之下）任何顺序进行。 ----------------------------------------------------------------------------------------------------------  这里有个重要的地方在于，一个容易忽略的概念： b = 1; a = ++b;  a获得的是等号右边表达式++b的值：在理论上是属于临时的，为'='操作符而生的临时变量。 而表达式++b的值仅仅是 2。 而 b的自增只保证在分号之前，和上一个分号之后。仍和时候去处理。任何时候，所以虽然是前置自增。但即便是在a赋值完毕之后b才自增完毕也是符合约定的。 ------------------------------------------------------------------------------------------------------------ func(b++); 这种我认为也是同理

引用 18 楼 自信男孩 的回复:这个结果跟入栈参数的顺序有关系 没看懂吗  入栈是从右到左 但计算顺序和这个没关系 (++p)->y 他可以计算++p 后面不计算->y 而是求值另一个参数 中间的参数求值完成 再把最后的参数的 ->y处理完 这个求值顺序你说和入栈顺序有关系? 这不是胡扯么

引用 16 楼 lin5161678 的回复:[quote=引用 13 楼 自信男孩 的回复:] 对于楼主的结果，你的解释是什么？  你可以看到这个是从右到左传递参数的 但是结果是4 4  001C39D0  mov         eax,dword ptr [p]   001C39D3  add         eax,8  这个是++p 001C39D6  mov         dword ptr [p],eax   001C39D9  mov         ecx,dword ptr [p]   001C39DC  mov         edx,dword ptr [ecx+4]   001C39DF  add         edx,1  p存到寄存器eax 后+4是取结构体的y 然后add 1 这一段是计算 ++p->y  看到了么 (++p)->y 编译器可以就算一半 就去算++p->y 回头再计算 最后的参数的->y   并且 直到此刻 全部参数都没开始入栈 入栈顺序和求值毫无关系  都求值完了 再入栈也是完全合理的 [/quote] 我明白了，这个4是3+1得到的。++p->y这个++是对y而言的，不是p的++。  根据从右向左入栈，(++p)->y这个是p指向了第二个元素地址，这样传入的y是3。++p->y，因为p已经指向了第二个结构体元素，因此++p->y是对y的+1，因此得到的是4.  这是我的LInux下的编译和运行结果。所以我们的讨论还是在相同编译器下，不然讨论没有意义。  这个结果跟入栈参数的顺序有关系

我是在LINUX编译运行的。另外，这个4是怎么回事？不是越界导致的？你的解释这个4是合理的吗？ss数组里没有4这个初始化项呢  引用 16 楼 lin5161678 的回复:[quote=引用 13 楼 自信男孩 的回复:] 对于楼主的结果，你的解释是什么？  你可以看到这个是从右到左传递参数的 但是结果是4 4  001C39D0  mov         eax,dword ptr [p]   001C39D3  add         eax,8  这个是++p 001C39D6  mov         dword ptr [p],eax   001C39D9  mov         ecx,dword ptr [p]   001C39DC  mov         edx,dword ptr [ecx+4]   001C39DF  add         edx,1  p存到寄存器eax 后+4是取结构体的y 然后add 1 这一段是计算 ++p->y  看到了么 (++p)->y 编译器可以就算一半 就去算++p->y 回头再计算 最后的参数的->y   并且 直到此刻 全部参数都没开始入栈 入栈顺序和求值毫无关系  都求值完了 再入栈也是完全合理的 [/quote]

引用 13 楼 自信男孩 的回复:对于楼主的结果，你的解释是什么？  你可以看到这个是从右到左传递参数的 但是结果是4 4  001C39D0  mov         eax,dword ptr [p]   001C39D3  add         eax,8   这个是++p 001C39D6  mov         dword ptr [p],eax   001C39D9  mov         ecx,dword ptr [p]   001C39DC  mov         edx,dword ptr [ecx+4]   001C39DF  add         edx,1   p存到寄存器eax 后+4是取结构体的y 然后add 1 这一段是计算 ++p->y  看到了么 (++p)->y 编译器可以就算一半 就去算++p->y 回头再计算 最后的参数的->y   并且 直到此刻 全部参数都没开始入栈 入栈顺序和求值毫无关系  都求值完了 再入栈也是完全合理的

引用 14 楼 lin5161678 的回复:[quote=引用 13 楼 自信男孩 的回复:] 咱们还是基于固定的编译器来谈吧，你的连接打不开。编译器不同，传参的顺序可能不一样，基于相同的编译器来分析比较合适～  对于楼主的结果，你的解释是什么？ 你不把传参顺序和求值顺序混为一谈 你会发现想怎么解释就怎么解释[/quote]  传参顺序解决定了p的指向问题。  你解释一下楼主的结果是什么原因吧～

引用 13 楼 自信男孩 的回复:咱们还是基于固定的编译器来谈吧，你的连接打不开。编译器不同，传参的顺序可能不一样，基于相同的编译器来分析比较合适～  对于楼主的结果，你的解释是什么？ 你不把传参顺序和求值顺序混为一谈 你会发现想怎么解释就怎么解释

引用 12 楼 lin5161678 的回复:[quote=引用 10 楼 自信男孩的回复:][quote=引用 9 楼 lin5161678 的回复:][quote=引用 7 楼 自信男孩 的回复:] 跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？ 哪怕是按照入栈理解你的解释也是错的 两个++ 一个操作p 一个操作某个元素的y 也就是说p只操作1次 也就是说没越界  你按照越界理解才是错误的解释  顺便如果入栈顺序能解释 请你解释#4的结果 [/quote] 第二个结构体，我的测试结果是：4,3 不是4,4 可以查一下传参，对于参数是表达式的是传表达式还是传值。参数传递是传值吧，怎么传值呢，必然先计算；所以printf打印之前是先把值计算出来再穿进去了，既然这样跟入参的顺序是有关系的～[/quote] https://ideone.com/zADGup 这是一个在线编译器的运行结果 请按照你的理论解释解释[/quote] 咱们还是基于固定的编译器来谈吧，你的连接打不开。编译器不同，传参的顺序可能不一样，基于相同的编译器来分析比较合适～  对于楼主的结果，你的解释是什么？

引用 10 楼 自信男孩的回复:[quote=引用 9 楼 lin5161678 的回复:][quote=引用 7 楼 自信男孩 的回复:] 跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？ 哪怕是按照入栈理解你的解释也是错的 两个++ 一个操作p 一个操作某个元素的y 也就是说p只操作1次 也就是说没越界  你按照越界理解才是错误的解释  顺便如果入栈顺序能解释 请你解释#4的结果 [/quote] 第二个结构体，我的测试结果是：4,3 不是4,4 可以查一下传参，对于参数是表达式的是传表达式还是传值。参数传递是传值吧，怎么传值呢，必然先计算；所以printf打印之前是先把值计算出来再穿进去了，既然这样跟入参的顺序是有关系的～[/quote] https://ideone.com/zADGup 这是一个在线编译器的运行结果 请按照你的理论解释解释

引用 10 楼 自信男孩的回复:[quote=引用 9 楼 lin5161678 的回复:][quote=引用 7 楼 自信男孩 的回复:] 跟出栈顺序是有关系的，当然也跟入栈舒心有关了。  这两个参数那个先出栈，那个表达式就要先计算了。不然，怎么解释楼主的输出呢？ 哪怕是按照入栈理解你的解释也是错的 两个++ 一个操作p 一个操作某个元素的y 也就是说p只操作1次 也就是说没越界  你按照越界理解才是错误的解释  顺便如果入栈顺序能解释 请你解释#4的结果 [/quote] 第二个结构体，我的测试结果是：4,3 不是4,4 可以查一下传参，对于参数是表达式的是传表达式还是传值。参数传递是传值吧，怎么传值呢，必然先计算；所以printf打印之前是先把值计算出来再穿进去了，既然这样跟入参的顺序是有关系的～[/quote] 你测试结果就是测试结果 其他人测试结果就不算？ 为什么

未定义行为 结果没意义 不用讨论结果 更重要的是了解什么是未定义行为并避免写出这样的代码

引用 3 楼 自信男孩的回复:函数调用，要把参数入栈，一般参数入栈是从左向右依次入栈的，因此出栈就是从右向左了，最后一个参数先出栈，也就是最后一个参数表达式先计算，这样可以解释第一个输出为什么是3,1；后面的一个是1；但是对于3这个输出是随机的，因为p指向的内容已经是越界了～ 这是常见误解 入栈顺序和这个错误无关 这里出现错误是求值无序 而求值顺序和入栈顺序没有必然联系


Question: C语言编程加法运行后无法计算

可以采用单步执行的方法，或者在scanf下增加printf("%lf,%lf",a,b)的输出语句，观察a，b的输出值，从而快速找到错误所在。实际上此题在编译时就会给出变量a,b没有使用的警告信息，从这个警告信息就可分析出问题所在

scanf的双引号的内容超出了，后面应该跟变量地址，楼主这样写导致scanf确实参数，%lf对应的参数；  	 scanf("%lf%lf", &a, &b); 这样试一下～

scanf("%lf%lf",&a,&b);

求各位大佬帮我解答一下  跪求


Question: 八分法画圆

搜Bresenham画圆算法，图形学最基础的东西

那咋画圆形呀

我只看到你画了8个点


Question: 如何生成从0-1亿之间的随机数，尽量不要循环和乘除法

#include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79


Question: 新手遇到的小问题

函数运用啊

main()函数中对max函数进行了声明和调用， 但是你没有定义max函数， 图片中int max(int x,int y)的部分也要打全。

int max(int a,int b);是函数声明，c=max(a,b)是函数调用，这里缺少函数的定义。

很显然这是代码没打全。。  书上的max函数定义也要打呀  就是下面的int max(int x, int y)的那部分

max函数的定义在哪里？如果需要用到库函数里的，建议引入math.h


Question: vc++(绿色版)，程序编译没有错误，但是运行只弹出窗口却不能输入

好的，十分感谢

#include<stdio.h> #include<malloc.h> #include<stdlib.h>    typedef struct Node {     char data;     struct Node *next; }NODE,*PNODE; //NODE等价于struct Node，PNODE等价于struct Node *  PNODE creat_linklist(); //创建单链表 PNODE travel_link( PNODE phead); //遍历单链表  int main() {     PNODE phead=NULL;     //PNODE creat_linklist();     phead = creat_linklist();     //PNODE travel_link( PNODE phead);     travel_link(phead); }    PNODE creat_linklist() {     int len; //用来存放有效节点的个数     int i;     char val;     PNODE pnew;//先定义     PNODE phead=(PNODE)malloc(sizeof(NODE));//向系统申请空间，表示头节点     if(phead==NULL)     {         printf("空间分配失败\n");         exit(-1);     }     PNODE ptail = phead;//尾指针，开始指向头节点     ptail->next=NULL;     printf("请输入要生成的链表节点的个数：len=");     scanf("%d",&len); //输入len     getchar();    //for '\n'     for(i=0;i<len;i++)     {         printf("请输入第%d个节点的值：",i+1);         scanf("%c",&val);         getchar();    //for '\n'         pnew=(PNODE)malloc(sizeof(NODE));         if(pnew==NULL)         {             printf("空间分配失败\n");             exit(-1);         }         pnew->data=val;         ptail->next=pnew; //将新节点挂到ptail的next域（将新节点的地址传到上一个节点的next域中）         pnew->next=NULL;         ptail=pnew; //尾节点一直指向新元素，因为插入的新节点即为此刻的尾节点      }      return phead; }   PNODE travel_link( PNODE phead) //遍历单链表 {     PNODE p=phead->next; //指向首节点     while(p!=NULL)     {         printf("%c",p->data);         p=p->next;     }     printf("\n");     return 0; } 供参考～   函数调用有问题～


Question: hitSSE困难：统计字符

#include <stdio.h> #include <ctype.h> #define BUFFER_SIZE 80 #define COUNT_SIZE 26 int main( ) {     char str[BUFFER_SIZE+1];  //2     int count[COUNT_SIZE]={0}; //2     int i = 0;     gets(str); //2     for(i=0; str[i]!='\0'; i++)  //1     {         if(islower(str[i])) //2             count[str[i]-'a']++;  //4     }      for(i=0; i<COUNT_SIZE; i++) //1     {         if(count[i]>0) //1         {              printf("%c=%d\n", i+'a', count[i]); //2         }     } 	return 0; }

#include <stdio.h> #include <ctype.h>  #define BUFFER_SIZE 80 #define COUNT_SIZE 26  int main(void) {     char str[BUFFER_SIZE+1];  //2     int count[COUNT_SIZE]={0}; //2     int i = 0;     //gets(str); //2     fgets(str, sizeof(str), stdin); //2     //for(i=0; str[i]!='\0'; i++)  //1     for(i=0; str[i]; i++)  //1     {         //if ((str[i]>='a') && (str[i]<='z')) //2         if (islower(str[i])) //2             count[str[i]-'a']++;  //4     }      for(i=0; i<COUNT_SIZE; i++) //1     {         //if(count[i]>0) //1         if (count[i]) //1         //{             printf("%c=%d\n", i+'a', count[i]); //2         //}     } } 供参考～


Question: 图邻接矩阵删除顶点

没有全部代码，说的都是瞎猜

引用 2 楼 肥牛肉^*^ 的回复:如果这样改，v为3，i＜n-1，假设n为4，那这样for就不循环了，那怎样达到删除的效果？ n为4，v为3，v就是最后一个节点，删除最后一个节点，最后一行一列的关系也没必要往前移了，直接舍弃

引用 1 楼 user-2的回复:代码有问题，像你理解的一样会越界 删除行应该是 for(i=v; i<n-1; i++)//数组删除元素，要把后续的元素往前移  同样的删除列应该是 for(j=v; j<n-1; j++) 如果这样改，v为3，i＜n-1，假设n为4，那这样for就不循环了，那怎样达到删除的效果？


Question: 大佬求带

Grammar of C++ Statements statement:   labeled-statement  expression-statement  compound-statement  selection-statement  iteration-statement  jump-statement  declaration-statement asm-statement try-except-statement try-finally-statement   labeled-statement:   identifier : statement  case constant-expression : statement  default  : statement  expression-statement:   expressionopt ;  compound-statement:   { statement-listopt }  statement-list:   statement  statement-list  statement  selection-statement:   if  (  expression ) statement  if  ( expression  ) statement else statement  switch  ( expression ) statement  iteration-statement:   while  ( expression ) statement  do statement while  ( expression ) ;  for  ( for-init-statement  expressionopt ; expressionopt ) statement  for-init-statement:   expression-statement  declaration-statement  jump-statement:   break  ;  continue  ;  return  expressionopt ;  goto identifier ;  declaration-statement:   declaration  try-except-statement:   __try compound-statement __except ( expression ) compound-statement  try-finally-statement:   __try compound-statement __finally ( expression ) compound-statement

语句是以;分号为标准的。变量声明需要是以;号结束，因此可以认为是语句；宏定义不一定，头文件还是以分号作为判断吧


Question: 顺序表的基本操作  ；顺序表的实现

#include <stdio.h> #include <stdlib.h> #include <malloc.h>   #define LIST_INIT_SIZE 100//顺序表存储空间的初始分配量 #define LISTINCREMENT 10//线性表存储空间的分配增量   typedef struct{     int *elem;//存储空间基址     int length;//当前长度     int listsize;//分配存储容量 }SqList;  int InitList_Sq(SqList&L) {     //构造一个空的线性表L     L.elem = (int*)malloc(LIST_INIT_SIZE*sizeof(int));     if (!L.elem)         exit (1);     L.length = 0;     L.listsize = LIST_INIT_SIZE;      return 1; }  int ListInsert_Sq (SqList&L,int i,int e) {     int *newbase;     //在顺序线性表的L中的第i个位置插入新的元素e     if(i<1||i>L.length +1 )         return 0;//i值不合法      if(L.length>=L.listsize ){ //当前储存空间已满，增加分配         newbase=(int*)realloc(L.elem, (L.listsize+LISTINCREMENT)*sizeof(int));         if(!newbase)exit(1);         L.elem  = newbase;         L.listsize += LISTINCREMENT;     }     int *p;     int *q=&(L.elem [i-1]);     for (p=&(L.elem [L.length -1]); p >= q; --p)         *(p+1) = *p;     *q=e;     ++L.length;      return 1; }  int ListDelete_Sq(SqList &L,int i,int &e)//删除第i个位置上的元素,并用e返回 {     if((i<1)||(i>L.length))         return 0;      int *p=&(L.elem[i-1]);     e = *p;     int *q = L.elem+L.length-1;     for (++p;p<=q;++p)         *(p-1)=*p;     --L.length ;     return 1; } int LocateElem_Sq(SqList L,int e,int (*compare)(int,int)) //定位满足compare函数的元素的下标 {     int i=1;     int *p=L.elem;     while(i<=L.length &&!(*compare)(*p++,e)) ++i;     if (i<=L.length) return i;     else return 0; }  int print(SqList L) //遍历打印顺序表中元素 {     for(int i=0;i<L.length ;i++)         printf("%d ", L.elem [i]);     printf("\n");     return 0; }  int main (){      SqList L;//声明一个顺序表     InitList_Sq(L);     //int e[10];     int e;     printf("请输入10位数学号:");      for (int i=0;i<10;i++)     {         //scanf("%d",&e[i]);         scanf("%d",&e); #if 0         L.elem[i] = e;         /*L.elem[i]=i;*/         L.length++; #else         ListInsert_Sq(L, i+1, e); #endif     }     print(L);      ListInsert_Sq (L,L.length+1,8); //在第二个位置插入8     //ListInsert_Sq (L,2,8); //在第二个位置插入8     print(L);      int g;     //ListDelete_Sq(L,2,g); //删除第2个位置上的元素 ，e返回其值     if (ListDelete_Sq(L, L.length,g)) //删除第2个位置上的元素 ，e返回其值         printf("%d\n", g);     print(L); } 做了部分修改，供参考～


Question: 新手请教大家一个问题：用指针方法，在一个一维数组int a[10]的元素中，查找给定的数，若找到则输出该数，若没找到，输出No

建议换个程序或者环境，测试运行的时候会报哪里出错，什么错

啊，第几次犯这个错误了每次都没找出来，谢谢了，以后会注意的。

scanf("%d",b); 加&号  scanf("%d",&b);


Question: 数据类型长度与sizeof

我自己搞错了。确实是32位的。

指针就要加倍，你试试

c++ 标准规定int 只保证大于等于32位，并没有说一定是64位。

引用 楼主 无名D小兵的回复:为什么在64位机上，sizeof(int)的值是4而不是8？64位及上int型的长度不是64位吗？ int 长度都是4个字节，64和32位机器一样


Question: 利用π4=1−13+15−17+…，编程计算π的近似值，直到最后一项的绝对值小于10−4时为止，输出π的值并统计累加的项数

谢谢谢谢谢谢

供参考 #include<stdio.h> int main() {     double a=1,d=1;     int sign=1,count=1;     while(1)     {         a+=2;         sign*=(-1);         d+=1/a*sign;         count++;         if(1/a<0.0001) break;     }     printf("pi=%lf\ncount=%d\n",4*d,count);     return 0; }

a=1001,b=1003退出，但是题目要求最后一项是绝对值小于10-4,所以这个1/a还是要加进结果里面。

但是计算出来的a最后一项是 997 b最后一项是999 c=1/997-1/999 然后 下一次就是 a+4=1001,b+4=1003  b<0.0001 就退出了呀  后面在弄这些不是多余？

for结束后加一句 if(1/a<0.0001) d+=1/a; else d=d+1/a-1/b;

最后一项绝对值小于10-4，也就是要计算这一项，函数里面没有计算


Question: 求大佬帮我看看这段二叉树Morris后序遍历的代码

引用 2 楼 weixin_45906870 的回复:改成你的代码后编译没问题，但是运行时编译器会停止工作，但是我不知道问题出在哪  不好意思，因为没调试，有笔误 void postorderTraverse(struct TreeNode *root) {     if (root==NULL) return;     struct TreeNode *p = NULL;     //struct TreeNode *t1 =malloc(sizeof(struct TreeNode)); //没必要用t1     //t1->left = root;     //t1->right = NULL;     //struct TreeNode *t = t1;     struct TreeNode* t = root; //直接t从root开始就可以     while (t){         p = t->left;         //if (t->left){         //if (p->left){         if(p) { //这里笔误了             //p = t->left;             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;             }             else{                 //printreverse(t->left, p);                 p->right = NULL; //为了节点逆转的判断，先恢复右节点为NULL                 printreverse(t->left); //再逆向打印                 t = t->right;             }         }         else{             t = t->right;         }     }     //free(t1); }

给你一个递归和morris遍历的完整代码 其实我觉得morris的后序遍历为了省空间，需要逆向打印（遍历），时间上也多消耗的，以时间换空间，也不见得有多好  struct TreeNode {     int val;     struct TreeNode *left;     struct TreeNode *right; };   struct TreeNode* reverse(struct TreeNode *node) {     struct TreeNode* pre = NULL;     struct TreeNode* next = NULL;     while (node != NULL){         next = node->right;         node->right = pre;         pre = node;         node = next;     }     return pre; }   void printreverse(struct TreeNode *node) {     struct TreeNode* tail =reverse(node);     struct TreeNode* cur = tail;     while (cur != NULL ){         printf("%d ", cur->val);         cur =cur->right;     }     reverse(tail); }  void postorderTraverse(struct TreeNode *root) //morris后序 {     if (root==NULL) return;     struct TreeNode *p = NULL;     struct TreeNode* t = root;     while (t){         p = t->left;         if(p) {             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;                 continue;             }             else{                 p->right = NULL;                 printreverse(t->left);             }         }         t = t->right;     }     printreverse(root); //最后打印右子树 }  void preorderTraverse(struct TreeNode *root) { //morris前序     if(root == NULL) return;     struct TreeNode* cur = root;     struct TreeNode* right = NULL;     while (cur != NULL){         right = cur->left;         if(right != NULL){             while (right->right != NULL && right->right != cur){                 right = right->right;             }             if(right->right == NULL){                 right->right = cur;                 printf("%d ", cur->val);                 cur = cur->left;                 continue;             }else {                 right->right = NULL;             }         }else {             printf("%d ", cur->val);         }         cur = cur->right;     } }  void inorderTraverse(struct TreeNode *root) { //morris中序     if(root == NULL) return;     struct TreeNode* cur = root;     struct TreeNode* right = NULL;     while (cur != NULL){         right = cur->left;         if(right != NULL){             while (right->right != NULL && right->right != cur){                 right = right->right;             }             if(right->right == NULL){                 right->right = cur;                 cur = cur->left;                 continue;             }else {                 right->right = NULL;             }         }         printf("%d ", cur->val);         cur = cur->right;     } }  void preOrder(struct TreeNode* root) {     if (root==NULL) return;     printf("%d ", root->val);     preOrder(root->left);     preOrder(root->right); }  void inOrder(struct TreeNode* root) {     if (root==NULL) return;     inOrder(root->left);     printf("%d ", root->val);     inOrder(root->right); }  void postOrder(struct TreeNode* root) {     if (root==NULL) return;     postOrder(root->left);     postOrder(root->right);     printf("%d ", root->val); }  void createTree(struct TreeNode** node, int *data, int length, int *index) {     if(data[*index]==-1) {         (*index)++;         return;     }     if(*node==NULL) *node=(struct TreeNode*)malloc(sizeof(struct TreeNode));     (*node)->left = NULL;     (*node)->right = NULL;     (*node)->val = data[(*index)++];     if (*index<length)         createTree(&((*node)->left), data, length, index);     if (*index<length)         createTree(&((*node)->right), data, length, index); }  void destroyTree(struct TreeNode* root) {     if (root==NULL) return;     destroyTree(root->left);     destroyTree(root->right);     free(root); }  int main() {     struct TreeNode *root=NULL;     int data[]={0,1,2,-1,-1,3,-1,-1,4,5,-1,-1,6};     int index=0;     createTree(&root, data, 13, &index);     printf("递归前序\n");     preOrder(root);     printf("\nmorris前序\n");     preorderTraverse(root);     printf("\n递归中序\n");     inOrder(root);     printf("\nmorris中序\n");     preorderTraverse(root);     printf("\n递归后序\n");     postOrder(root);     printf("\nmorris后序\n");     postorderTraverse(root);     printf("\n");     destroyTree(root);     return 0; }

引用 1 楼 user-1 的回复：这是morris后序遍历必须的步骤，也就是先遍历到左子树的最右节点，才开始逆向打印。所以逆向打印步骤省不了，优化的地方有限，关键就看逆向打印怎么实现。通常的做法就是先把节点逆转，打印结束后再把节点逆转回来。 如果非要改进，参考以下代码吧  struct TreeNode {     int val;     struct TreeNode *left;     struct TreeNode *right; };  struct TreeNode* reverse(struct TreeNode *node) {     struct TreeNode* pre = NULL;     struct TreeNode* next = NULL;     while (node != NULL){         next = node->right;         node->right = pre;         pre = node;         node = next;     }     return pre; }  void printreverse(struct TreeNode *node) {     struct TreeNode* tail =reverse(node);     struct TreeNode* cur = tail;     while (cur != NULL ){         printf("%d\n", cur->val);         cur =cur->right;     }     reverse(tail); }  void postorderTraverse(struct TreeNode *root) {     if (root==NULL) return;     struct TreeNode *p = NULL;     //struct TreeNode *t1 =malloc(sizeof(struct TreeNode)); //没必要用t1     //t1->left = root;     //t1->right = NULL;     //struct TreeNode *t = t1;     struct TreeNode* t = root; //直接t从root开始就可以     while (t){         p = t->left;         //if (t->left){         if (p->left){             //p = t->left;             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;             }             else{                 //printreverse(t->left, p);                 p->right = NULL; //为了节点逆转的判断，先恢复右节点为NULL                 printreverse(t->left); //再逆向打印                 t = t->right;             }         }         else{             t = t->right;         }     }     //free(t1); }改成你的代码后编译没问题，但是运行时编译器会停止工作，但是我不知道问题出在哪


Question: 逻辑运算   有点小问题，

scanf("%d,%d,%d",&a,&b,&c); // 给a和b赋值 你的输入格式里面带了逗号，输入也要带逗号  例如输入 3,4,5   m = a > b && a < c;   // 条件运算  如果a=5,b=3,c=6  输出结果应该是m=1  为什么是0 这种格式代码可读性不是很好，虽然高手知道运算符有限顺序，但是项目接手人不一定都是高手 建议m = ((a > b) && (a < c));  这样更明确些

引用 3 楼 明天就会D 的回复:[quote=引用 1 楼 自信男孩 的回复:]输入的格式不对，因为scanf的""中每个输入之间是有,逗号的（注意逗号的中英文要和scanf中的保持一致）。  谢谢，不过，我刚刚又试试了 好像还是不对结果还是 m= 0[/quote] 就是输入带空格的原因啊 你输入5,3,6就可以了

int a = 2,b = 4,c = 6,x,y; y = (a+b),(b+c);结果是y=6，但整个逗号表达式的值是10，要想获取这个10，则应该写成 y=（a+b,b+c）;

#include<stdio.h> int main() {     int a = 0;int b = 0; int c = 0;  //定义2个变量     int m;  // 定义m变量     scanf("%d %d %d",&a,&b,&c); // 给a和b赋值     m = a > b && a < c;   // 条件运算  如果a=5,b=3,c=6  输出结果应该是m=1  为什么是0     printf("m = %d",m); //  输出 	return 0; }

引用 7 楼 5250 的回复:[quote=引用 2 楼 明天就会D 的回复:]#include<stdio.h> int main() {   /* int a = 0,b = 0, c = 0;    int m = 0;    scanf("%d,%d,%d",&a,&b,&c);    m = (a + b),(c * a);    printf("m = %d",m);  */     int a = 2,b = 4,c = 6,x,y;     y = (a+b),(b+c);     printf("y = %d,x = %d\n",x,y);     return 0; } 运行结果y = 8,x = 6,有点懵，明明按照逗号表达式计算第二表达式为最终结果，a+b=6,b+c=10,为什么运行结果差这么远，，， 希望有路过的朋友，懂的话，帮忙解答一下，谢谢！ 我一个人自学看书，有些点还是理解不了，  逗号表达式需要加括号  即x=(p1,p2,p3) 你的程序改一下  y = （(a+b),(b+c));[/quote] 收到，我理解了，感谢！

引用 6 楼 自信男孩 的回复:[quote=引用 2 楼 明天就会D 的回复:]#include<stdio.h> int main() {   /* int a = 0,b = 0, c = 0;    int m = 0;    scanf("%d,%d,%d",&a,&b,&c);    m = (a + b),(c * a);    printf("m = %d",m);  */     int a = 2,b = 4,c = 6,x,y;     y = (a+b),(b+c);     printf("y = %d,x = %d\n",x,yprintf("y = %d,x = %d\n",x,y);    return 0; } 运行结果y = 8,x = 6,有点懵，明明按照逗号表达式计算第二表达式为最终结果，a+b=6,b+c=10,为什么运行结果差这么远，，， 希望有路过的朋友，懂的话，帮忙解答一下，谢谢！ 我一个人自学看书，有些点还是理解不了，  这样的能对上号吗？能不蒙吗？  printf("y = %d,x = %d\n",x,y);  y=x的值，x = y的值[/quote]   我粗心大意了，自身本领不过关，结果导致运算结果不一样，感谢您的发现！

引用 4 楼 深渊亦是鹏程万里 的回复:y = (a+b),(b+c);这一句逗号运算符左边为一个表达式，右边为一个表达式，y=(a+b)和（b+c）,所以y=6，如果是y = ((a+b),(b+c)); y=10,x由于是临时变量且没有赋初值，x在栈空间中，它的值是内存中的一个垃圾值    谢谢朋友，理解了

引用 2 楼 明天就会D 的回复:#include<stdio.h> int main() {   /* int a = 0,b = 0, c = 0;    int m = 0;    scanf("%d,%d,%d",&a,&b,&c);    m = (a + b),(c * a);    printf("m = %d",m);  */     int a = 2,b = 4,c = 6,x,y;     y = (a+b),(b+c);     printf("y = %d,x = %d\n",x,y);     return 0; } 运行结果y = 8,x = 6,有点懵，明明按照逗号表达式计算第二表达式为最终结果，a+b=6,b+c=10,为什么运行结果差这么远，，， 希望有路过的朋友，懂的话，帮忙解答一下，谢谢！ 我一个人自学看书，有些点还是理解不了，  逗号表达式需要加括号  即x=(p1,p2,p3) 你的程序改一下  y = （(a+b),(b+c));

引用 2 楼 明天就会D 的回复:#include<stdio.h> int main() {   /* int a = 0,b = 0, c = 0;    int m = 0;    scanf("%d,%d,%d",&a,&b,&c);    m = (a + b),(c * a);    printf("m = %d",m);  */     int a = 2,b = 4,c = 6,x,y;     y = (a+b),(b+c);     printf("y = %d,x = %d\n",x,yprintf("y = %d,x = %d\n",x,y);    return 0; } 运行结果y = 8,x = 6,有点懵，明明按照逗号表达式计算第二表达式为最终结果，a+b=6,b+c=10,为什么运行结果差这么远，，， 希望有路过的朋友，懂的话，帮忙解答一下，谢谢！ 我一个人自学看书，有些点还是理解不了，  这样的能对上号吗？能不蒙吗？  printf("y = %d,x = %d\n",x,y);  y=x的值，x = y的值

楼主为啥不加上括号呢？？

引用 1 楼 自信男孩 的回复:输入的格式不对，因为scanf的""中每个输入之间是有,逗号的（注意逗号的中英文要和scanf中的保持一致）。  谢谢，不过，我刚刚又试试了 好像还是不对结果还是 m= 0


Question: 自定义函数实现四舍五入

引用 3 楼 自信男孩的回复:楼主想一下a - (int)a >5怎么大于5呢？这个判断就是一个一直假呢 不是应该大于0.5吗？ main函数里的scanf应该是%f，不是f 确实如此，谢谢你

恩， 你用的是vs2010吗？  可能要把abs换成fabs

浮点数不是精确的数字吧， 用==或!=是有可能得不到想要的结果。 试试abs(a) < 0.0001这样

引用 2 楼 user-2 的回复:恩， 你用的是vs2010吗？  可能要把abs换成fabs 谢谢你的回复，是vs2010 我看书上说用集成编程工具学不好c语言，是这么回事么？


Question: 链表储存的一元多项式计算器，进行乘法时，有时会超时，有时能运行出结果，原因可能是啥？救救孩子吧  求助！！！！

#include<stdio.h> #include<stdlib.h> #include<malloc.h>    typedef struct polynode {     int coef;     int exp;     struct polynode *next; }polynode, *polylist;  polylist poly_create(void) {     polynode *rear, *head, *s;      int c, e;      rear = head = (polynode *)malloc(sizeof(polynode));     scanf("%d%d", &c, &e);      while (c) {         s = (polynode*)malloc(sizeof(polynode));         s->coef = c;         s->exp = e;         rear->next = s;         rear = s;         scanf("%d%d", &c, &e);     }     rear->next=NULL;      return(head); }    static void insert_node(polylist phead, polylist new_node) {     polylist pcur, pprev;      pprev = phead;     pcur = phead->next;      while (pcur && pcur->exp != new_node->exp) {         pprev = pcur;         pcur = pcur->next;     }     if (!pcur) {         pprev->next = new_node;         return;     }      pcur->coef += new_node->coef;     free(new_node);     if (pcur->coef == 0) {         pprev->next = pcur->next;         free(pcur);     } }  polylist multyploy(polylist pa, polylist pb) {     polylist pa_node, pb_node, pc_node, pc;     int coef, exp;       pc = (polynode*)malloc(sizeof(polynode));     if (!pc)         return NULL;      pa_node = pa->next;     pb_node = pb->next;      if (!pa_node || !pb_node) {         pc = pa_node ? pa : pb;     }     while (pa_node) {         while (pb_node) {             coef = pa_node->coef * pb_node->coef;             exp = pa_node->exp + pb_node->exp;              pc_node = (polylist)malloc(sizeof(polynode));             if (!pc_node)                 exit(0);             pc_node->coef = coef;             pc_node->exp = exp;             pc_node->next = NULL;              insert_node(pc, pc_node);             pb_node = pb_node->next;         }         pa_node = pa_node->next;         pb_node = pb->next;     }      return pc; }  void free_polylist(polylist phead) {     polylist pdel, pcur;      pcur = phead;      while (pcur) {         pdel = pcur;         pcur = pcur->next;         free(pdel);     } }  static void show_polylist(polylist phead) {     if (!phead)         return;      polylist pcur = phead->next;      while(pcur) {         printf("%d", pcur->coef);         printf("*x^%d", pcur->exp);         if (pcur->next)             printf(" + ");         pcur = pcur->next;     }     printf("\n"); }  int main(void) {     polylist pa, pb, pc;      pa = poly_create();     //show_polylist(pa);     pb = poly_create();     //show_polylist(pb);     pc = multyploy(pa, pb);      show_polylist(pc);      free_polylist(pa);     pa = NULL;     free_polylist(pb);     pb = NULL;     free_polylist(pc);     pc = NULL;      return 0; }  供参考～

谢谢 才看到


Question: C语言，建立了文件，向文件中输入了数据，但不知道为什么输出时显示不出来？？可以帮忙看看代码哪里有问题吗？？谢谢大神们！！

引用 6 楼 自信男孩的回复:[quote=引用 5 楼 up___lqw 的回复:][quote=引用 4 楼 自信男孩的回复:][quote=引用 3 楼 up___lqw 的回复:][quote=引用 1 楼 自信男孩的回复:]#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）[/quote] fscanf和scanf是一样的，只是fscanf指定了读取内容的文件。scanf如果加,fscanf也是要加&的～[/quote] 知道啦，谢谢！还能再问一个别的问题吗？就是刚开始在创立文件前我先创建了一个空的链表头，链表头和头指针这个为什么可以直接在文件里使用啊？？不需要在打开文件后创建吗？？今天突然发现这个不明白了。万分感谢！！[/quote] 个人认为，链表创建一般是在读文件的时候创建的，而楼主是相当于在写文件的时候创建了（但是没有使用链表），正好这些创建的节点在下面的读文件操作里使用了，也是可以的。[/quote] 可不可以帮我看一下代码呢？感觉传入的函数参数没有用呢，就是调用函数时，在这个函数中沿头结点找对应的节点位置，不知道为什么找不到😢，看了好几遍都不知道问题出在哪里。编译是没有问题的，就是运行出了bug。如果可以的话，我把代码私发给您！！真的太太太感谢啦！！大作业真的蛮重要的！

引用 6 楼 自信男孩的回复:[quote=引用 5 楼 up___lqw 的回复:][quote=引用 4 楼 自信男孩的回复:][quote=引用 3 楼 up___lqw 的回复:][quote=引用 1 楼 自信男孩的回复:]#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）[/quote] fscanf和scanf是一样的，只是fscanf指定了读取内容的文件。scanf如果加,fscanf也是要加&的～[/quote] 知道啦，谢谢！还能再问一个别的问题吗？就是刚开始在创立文件前我先创建了一个空的链表头，链表头和头指针这个为什么可以直接在文件里使用啊？？不需要在打开文件后创建吗？？今天突然发现这个不明白了。万分感谢！！[/quote] 个人认为，链表创建一般是在读文件的时候创建的，而楼主是相当于在写文件的时候创建了（但是没有使用链表），正好这些创建的节点在下面的读文件操作里使用了，也是可以的。[/quote] 好的，太感谢你啦！！抱歉这么久才回复~  其实这个程序是我们要写的大作业的一部分，然后现在我的代码刚刚全部写好，也通过编译了，但是有个地方出了一个bug,已注册的用户找不到信息，我也不知道哪里出了问题。代码行数也有点多，不太方便放到这个上面。如果您有时间，不嫌我麻烦的话，可以把代码私发给您，然后帮我看看吗？？如果可以的话真是太感谢了！！（实在找不到人帮忙看看哪里有问题了）

引用 5 楼 up___lqw 的回复:[quote=引用 4 楼 自信男孩的回复:][quote=引用 3 楼 up___lqw 的回复:][quote=引用 1 楼 自信男孩的回复:]#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）[/quote] fscanf和scanf是一样的，只是fscanf指定了读取内容的文件。scanf如果加,fscanf也是要加&的～[/quote] 知道啦，谢谢！还能再问一个别的问题吗？就是刚开始在创立文件前我先创建了一个空的链表头，链表头和头指针这个为什么可以直接在文件里使用啊？？不需要在打开文件后创建吗？？今天突然发现这个不明白了。万分感谢！！[/quote] 个人认为，链表创建一般是在读文件的时候创建的，而楼主是相当于在写文件的时候创建了（但是没有使用链表），正好这些创建的节点在下面的读文件操作里使用了，也是可以的。

引用 4 楼 自信男孩的回复:[quote=引用 3 楼 up___lqw 的回复:][quote=引用 1 楼 自信男孩的回复:]#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）[/quote] fscanf和scanf是一样的，只是fscanf指定了读取内容的文件。scanf如果加,fscanf也是要加&的～[/quote] 知道啦，谢谢！还能再问一个别的问题吗？就是刚开始在创立文件前我先创建了一个空的链表头，链表头和头指针这个为什么可以直接在文件里使用啊？？不需要在打开文件后创建吗？？今天突然发现这个不明白了。万分感谢！！

引用 3 楼 up___lqw 的回复:[quote=引用 1 楼 自信男孩的回复:]#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）[/quote] fscanf和scanf是一样的，只是fscanf指定了读取内容的文件。scanf如果加,fscanf也是要加&的～

引用 1 楼 自信男孩的回复:#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； 我知道啦，fscanf是读取并没有输出，但是我看您后来改的后三个多加了＆是为什么呢？？而第一个name没有加，这点想不太明白，请您指教！（因为我想fprintf的时候都没加）

引用 1 楼 自信男孩的回复:#include <stdio.h> #include <string.h> #include <stdlib.h>   struct acc_message                 //定义结点的结构 {  char name[12];     int  cardnum;     int  password;     double acc_balance;     struct acc_message *next; };  int main() {     struct acc_message *head;            //创建空链表     head =(struct acc_message *)malloc(sizeof (struct acc_message));     head-> next = NULL ;     struct acc_message *p, *q ;     q = head ;       FILE *fp;                                //建立原有银行客户信息文件     if ((fp = fopen("message.txt","wt+"))==NULL){         //printf("Open this file error,press any key exit!/n ");         printf("Open this file error,press any key exit!\n ");         getchar();         exit(0);     }     int i=0;     while(i<5){         p =(struct acc_message*)malloc(sizeof (struct acc_message));    //创建新节点         if (p==NULL)  break;         switch (i)         {             case 0:             //fprintf (fp,"Jane 62221111 123456 8000/n",p->name,p->cardnum,p->password,p->acc_balance);             fprintf (fp,"Jane 62221111 123456 8000\n");//, p->name,p->cardnum,p->password,p->acc_balance);             break;             case 1:             fprintf (fp,"Alan 62221112 123456 500\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 2:             fprintf (fp,"Mary 62221113 123456 600000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 3:             fprintf (fp,"Alice 62221114 123456 0\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;             case 4:             fprintf (fp,"Kivin 62221115 123456 70000\n");//,p->name,p->cardnum,p->password,p->acc_balance);             break;         }         q -> next=p;         q=p;         i++;     }     q->next = NULL;     rewind (fp);      struct acc_message *r = head->next;     while (r!=NULL){         //fscanf(fp,"%s %d %d %d/n",r->name,r->cardnum,r->password,r->acc_balance);         fscanf(fp,"%s %d %d %lf\n",r->name, &r->cardnum, &r->password, &r->acc_balance);         r=r->next;     }      r = head->next;     while (r) {         fprintf(stdout,"%s %d %d %lf\n", r->name, r->cardnum, r->password, r->acc_balance);         r = r->next;     }     fclose(fp);  }  供参考～  没有任何输出，那么是因为楼主没有输出。  代码的其他问题，详见上面的代码； fscanf函数不是用来输出的吗？？我看您写的后面输出列表上后三个加上了＆，这是为什么呢？（小白不懂就问），还有我现在在这个后面（关闭文件后）写printf语句，然后也没有输出，怎么回事不知道


Question: epoll水平触发读取数据的问题

顶


Question: 利用栈实现任意进制转换的一道题

既然有ABCDEF，因此不能直接用整形，N可以采用 字符串，大致代码如下  #include<iostream> #include<string> #include <stack> #include<ctype.h> using namespace std; char strmask[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; int main() {     int P, Q;     string N;     cin >> P >> Q >> N;     int tmp=0;     size_t slen = N.length();     for(int i=0;i<N.length();i++)     {         char c = N[i];         if (isdigit(c)) {             tmp += (c-'0')*pow(P,slen-i-1);         }         else {             c = toupper(c);             tmp += ((c - 'A') + 10)*pow(P,slen-i-1);         }     }        stack<char> stresult;     while (tmp) {         int n = tmp % Q;         stresult.push(strmask[n]);         tmp = tmp / Q;     }     while (!stresult.empty()) {         cout << stresult.top();         stresult.pop();     }     cout << endl;     return 0; }

引用 7 楼 真相重于对错 的回复:你的栈存放是int啊，所以输出要处理一下  嗷嗷我懂了！谢谢前辈！

你的栈存放是int啊，所以输出要处理一下

引用 5 楼 真相重于对错 的回复:你肯定不对，原题是： 给出一个 P 进制整数 N，求 N 的 Q 进制表示。 其中 0<= N <= 32767 , 2 <= P <= 16, 2 <= Q <= 16。 大于 9 的数字用 A、B、C、D、E、F 表示。 输入 P Q N（用 P 进制表示的） 因为P可能是大于10的进制，那么N就不能直接用int表示，而需要字符串，比如一个十三进制的A5。转换为8进制，你怎么接受N呢？  嗷嗷 前辈我把你的用stl的栈手写了下（因为我C++这块还不太熟悉 才刚学一直用C手写）但是我没还是查出来哪里错 #include<iostream> #include<math.h> #include<string.h> using namespace std;  typedef struct SNode{ 	int data; 	struct SNode *next; }SNode,*Stack; int InitStack(Stack &s){ 	s=NULL; 	return 0; } int Empty(Stack s){ 	return (s==NULL); } int Top(Stack s){ 	return(s->data); } int Push(Stack &s,int x){ 	Stack p; 	p=new SNode; 	p->data=x; 	 	p->next=s; 	s=p; 	return 0; } int Pop(Stack &s,int &x){ 	if(Empty(s)) return -1; 	Stack p=s; 	s=s->next; 	x=p->data; 	delete p; 	return x; } int main(){ 	char strmask[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; 	Stack s; 	InitStack(s); 	int P,Q; 	char N[32768]; 	int temp; 	scanf("%d %d",&P,&Q); 	scanf("%s",&N); 	int slen=strlen(N); 	for(int i=0;N[i]!='\0';i++){ 		char c=N[i]; 		if (isdigit(c)) {//判断是否是数字              temp += (c-'0')*pow(P,slen-i-1); //是数字          }         else {             c = toupper(c); //不是数字，转化为大写英文字母              temp += ((c - 'A') + 10)*pow(P,slen-i-1);         } 	} 	 	while(temp){ 		int n = temp % Q;         Push(s,strmask[n]);         temp = temp / Q; 	} 	while(!Empty(s)){ 		int x=0; 		x=Pop(s,x); 		printf("%d",x); 	} 	return 0; }

13 8 4A5

引用 2 楼 自信男孩 的回复:#include<iostream> #include<math.h>  using namespace std;  typedef struct SNode{     int data;     struct SNode *next; } SNode,*Stack; int InitStack(Stack &s){     s=NULL;     return 0; } int Empty(Stack s){     return (s==NULL); } int Top(Stack s){     return(s->data); } int Push(Stack &s,int x) {     Stack p;     p=new SNode;     p->data=x;      p->next=s;     s = p;      return 0; } int Pop(Stack &s,int &x) {     if(Empty(s)) return -1;     Stack p=s;     s=s->next;     x=p->data;     delete p;     return 1; }  int main() {     Stack s;     InitStack(s);     int N,P,Q;     int m=0,n=0;     scanf("%d %d %d",&P,&Q,&N);     if(P>Q){         while(N>0){             m=N%Q;             Push(s,m);             N=N/Q;         }         while(!Empty(s)){             Pop(s,n);             //printf("n = %d\n", n);             if (n >= 10) {                 printf("%c", n - 10 + 'A');             } else {                 printf("%d", n);             }         }     }      else if(P<Q){         int i=0,sum=0;         while(N>0){             m=N%10;             sum+=m*(pow(P,i));             i++;             N = N/10;         }          while(sum>0){             m=sum%Q;             Push(s, m);             sum = sum/Q;         }         while(!Empty(s)){             Pop(s,n);             //printf("n = %d\n", n);             if (n >= 10) {                 printf("%c", n - 10 + 'A');             } else {                 printf("%d", n);             }         }         printf("\n");     }      else if(P==Q){         printf("%d",N);     }      return 0; } 供参考～    if (n >= 10) {                 printf("%c", n - 10 + 'A');             } else {                 printf("%d", n);             } 判断一下pop的n是否大于10，然后根据输出的值做分支输出～ 前辈我试了下有几个example不能AC啊..是哪里的问题呢 这个是OJ的错误反馈  ========[test9.out]========= Expected						      |	Yours 111111111111110						      /	111  ============================== ========[test8.out]========= Expected						      |	Yours 32767							      /	7  ============================== ========[test4.out]========= Expected						      |	Yours 11111							      /	100101  ============================== ========[test5.out]========= Expected						      |	Yours ABC							      /	32767  ============================== ========[test6.out]========= Expected						      |	Yours 0							      |


Question: c语言

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

闲来无事，写一个玩玩。 #include <stdio.h> #include <stdlib.h>  int main (void) {     # define N 5     unsigned gusum = 0, inpud [1];      for (unsigned m = 0; m < N; m ++)         scanf ("%d", inpud), gusum += * inpud % 10;      printf ("%u\n", gusum); }


Question: 我没弄懂其原理，求大佬讲解

回调函数，根据栈的原理：先进后出。  回调函数是申请函数栈。

关于递归 需要搞清楚最核心的一点是 函数结束会返回到函数调用的地方这句话  你在reverse里面调用reverse 在内层的reverse调用完成 返回是返回到reverse里面而不是main里面 这里 main调用reverse 进入reverse 第一件事给c分配地址 假设 1000 然后调用getchar 给地址1000赋值 假设是a 这时候调用了reverse 进入reverse 第一件事给c分配地址 假设 1004 然后调用getchar 给地址1004赋值 假设是b 这时候调用了reverse 进入reverse 第一件事给c分配地址 假设 1008 然后调用getchar 给地址1008赋值 假设是\n 然后判断地址1008的值是\n 所以不执行输出  函数结束 释放占用内存 1008 开始返回 返回这时候调用了reverse 后面的代码是 判断1004的值是不是\n 结果不是\n输出1004地址的内容 也就是b 函数结束 释放占用内存 1004 开始返回 返回这时候调用了reverse 后面的代码是 判断1000的值是不是\n 结果不是\n输出1000地址的内容 也就是a 函数结束 释放占用内存 1000 开始返回 返回这里 main调用reverse ......

reverse是个递归函数， 递归函数分析首先找退出条件， void reverse() { char c; if((c=getchar())!='\n')  ==》这边是退出的条件   reverse();   ==》这边自己掉了自己   if(c!='\n')      putchar(c);       } 程序是一步步向下执行的，那看一下你这个程序执行顺序： 1.执行main里面的reverse函数，然后从键盘获得一个字符’a'，这个时候字符没有putchar，然后又进入到reverse函数，输入‘b'，这个时候又没有putchar，继续进入reverse函数，这个时候输入’\n‘ 2.判断是'\n'，退出，回到你输入’b'的然后调用reverse，程序继续执行，这个时候putchar，再回到你输入a的时候。。。 就是倒着输出的了


Question: 如何评价这些代码？（来自一位初学加自学者，就是我了h'h'h）

具体内容没可看，看了下数量及运用了比较多的循环、条件等结构之类。 初学者的话，如果代码能跑起来，且运行效果观感上没有什么毛病的话。可以给个70~80。

#include<stdio.h>  #define H_WAGE1 8.75 #define H_WAGE2 9.33 #define H_WAGE3 10.00 #define H_WAGE4 11.20 #define TIME1 30 #define TIME2 40 #define RATE_T 1.5 #define RATE1 0.15 #define RATE2 0.2 #define RATE3 0.25 #define BREAK1 300 #define BREAK2 450  int main(void) {     float time,total,tax,net,H_WAGE;     int choice;      printf("*****************************************************************\n");     printf("Enter the number corresponding to the desired pay rate or action:\n") ;     printf("(1)$8.75/hr                          (2)$9.33/hr\n");     printf("(3)$10.00/hr                         (4)$11.20/hr\n");     printf("(5)quit\n");     printf("*****************************************************************\n");      while (1) {         printf("Enter the choice:\n");         scanf("%d",&choice);         //if(choice==1||choice==2||choice==3||choice==4||choice==5)         //{         switch(choice)         {             case 1:                 H_WAGE=H_WAGE1;                 printf("Your choice is 1,$8.75/hr.\n");                 break;             case 2:                 H_WAGE=H_WAGE2;                 printf("Your choice is 2,$9.33/hr.\n");                 break;             case 3:                 H_WAGE=H_WAGE3;                 printf("Your choice is 3,$10.00/hr.\n");                 break;             case 4:                 printf("Your choice is 4,$11.20/hr.\n");                 H_WAGE=H_WAGE4;                 break;             case 5:                 printf("Your choice is 5,to quit.\n");                 H_WAGE=0;                 break;              default:                 printf("Enter the right number.\n");                 break;         }         if (choice <= 5 && choice >= 1)             break;     }     //else     //   printf("Enter the right number.\n");     while(H_WAGE!=0)     {         printf("Please enter the working time per week:\n");          while(scanf("%f",&time)==1)         {              if(time>=0)             {                 if(time<=TIME1)                 {                     total=time*H_WAGE;                     tax=total*RATE1;                 }                 else if(time<TIME2)                 {                     total=time*H_WAGE;                     tax=TIME1*H_WAGE*RATE1+(time-TIME1)*H_WAGE*RATE2;                 }                 else                 {                     time=TIME2+(time-TIME2)*RATE_T;                     total=time*H_WAGE;                     if(total<BREAK2)                         tax=TIME1*H_WAGE*RATE1+(time-TIME1)*H_WAGE*RATE2;                     else                         tax=TIME1*H_WAGE*RATE1+(BREAK2-BREAK1)*RATE2+(total-BREAK2)*RATE3;                 }                 net=total-tax;                 printf("Time is %.2f hours,total income is %.2f,tax is %.2f,net income is %.2f\n"                         ,time,total,tax,net);              }             else                 printf("Time cannot be negtive.\n") ;             printf("Enter time again or q to quit.\n");             H_WAGE=0;         }     }     printf("Done!\n");      return 0; } 上面的回复有误，用这个吧～

#include<stdio.h>  #define H_WAGE1 8.75 #define H_WAGE2 9.33 #define H_WAGE3 10.00 #define H_WAGE4 11.20 #define TIME1 30 #define TIME2 40 #define RATE_T 1.5 #define RATE1 0.15 #define RATE2 0.2 #define RATE3 0.25 #define BREAK1 300 #define BREAK2 450  int main(void) {     float time,total,tax,net,H_WAGE;     int choice;      printf("*****************************************************************\n");     printf("Enter the number corresponding to the desired pay rate or action:\n") ;     printf("(1)$8.75/hr                          (2)$9.33/hr\n");     printf("(3)$10.00/hr                         (4)$11.20/hr\n");     printf("(5)quit\n");     printf("*****************************************************************\n");      while (1) {         printf("Enter the choice:\n");         scanf("%d",&choice);         //if(choice==1||choice==2||choice==3||choice==4||choice==5)         //{         switch(choice)         {             case 1:                 H_WAGE=H_WAGE1;                 printf("Your choice is 1,$8.75/hr.\n");                 break;             case 2:                 H_WAGE=H_WAGE2;                 printf("Your choice is 2,$9.33/hr.\n");                 break;             case 3:                 H_WAGE=H_WAGE3;                 printf("Your choice is 3,$10.00/hr.\n");                 break;             case 4:                 printf("Your choice is 4,$11.20/hr.\n");                 H_WAGE=H_WAGE4;                 break;             case 5:                 printf("Your choice is 5,to quit.\n");                 H_WAGE=0;                 break;              default:                 printf("Enter the right number.\n");                 break;         }         if (choice <= 5 && choice >= 1)             break;     }     //else     //   printf("Enter the right number.\n");     //while(H_WAGE!=0)    //H_WAGE初始化了吗？没初始化不能用     while(1)    //H_WAGE初始化了吗？没初始化不能用     {         printf("Please enter the working time per week:\n");          while(scanf("%f",&time)==1)         {              if(time>=0)             {                 if(time<=TIME1)                 {                     total=time*H_WAGE;                     tax=total*RATE1;                 }                 else if(time<TIME2)                 {                     total=time*H_WAGE;                     tax=TIME1*H_WAGE*RATE1+(time-TIME1)*H_WAGE*RATE2;                 }                 else                 {                     time=TIME2+(time-TIME2)*RATE_T;                     total=time*H_WAGE;                     if(total<BREAK2)                         tax=TIME1*H_WAGE*RATE1+(time-TIME1)*H_WAGE*RATE2;                     else                         tax=TIME1*H_WAGE*RATE1+(BREAK2-BREAK1)*RATE2+(total-BREAK2)*RATE3;                 }                 net=total-tax;                 printf("Time is %.2f hours,total income is %.2f,tax is %.2f,net income is %.2f\n"                         ,time,total,tax,net);              }             else                 printf("Time cannot be negtive.\n") ;             printf("Enter time again or q to quit.\n");             H_WAGE=0;         }         if (H_WAGE == 0)             break;     }     printf("Done!\n");      return 0; } 供参考～

初学者要学的第一件事是 代码缩进写好 处理好这件事之前 不用讨论怎么评价代码 不入流

第一个if...else语句完全是多余的，switch语句就行了。

引用 1 楼 user-4 的回复:第一个if...else语句完全是多余的，switch语句就行了。多谢指教，我再修改一下

多谢指教 ，以后多注意


Question: c语言的问题  详细问题请点开看一下

嗯嗯 性质 1：是偶数； 性质 2：大于 4 且不大于 12。 小A 喜欢这两个性质同时成立的数字；Uim 喜欢这至少符合其中一种性质的数字；八尾勇喜欢刚好有符合其中一个性质的数字；正妹喜欢不符合这两个性质的数字。 就是这个问题 谢谢啊

把你的具体需求说一下，可以直接给你写一个可以实现的代码（用if else）  单从你的if ... else说明上来看是可以的，需要加大括号。大括号里的if else是一个整体，对于大括号外面的来讲


Question: gcc如何仅链接用到的函数，使程序体积尽量减小？

引用 6 楼 六道佩恩 的回复:话说你这些是在哪里看到的？ 呵呵，以前做个相似的

GCC链接操作以section作为最小的处理单元，一个section中可以包含很多个function，而一个section中只要有一个function被引用，该section就会被加入链接，最终生成可执行文件。  换句话说就是，在缺省情况下，某个.c程序中的所有function，实际上都会编译成同一个section。那么，只要你的代码中用到这个.c生成的.o的其中任何一个function，系统就会将这整个section进行链接。这就导致，我们在引用外部静态库时，不管你是引用其中一个函数，还是引用全部的函数，你最终编译链接出来的可执行文件都一样大，系统并不会自动根据你所引用的函数个数的多少而动态的调整链接方式。  如果静态库是你自己生成的，采用两个步骤即可： 编译时：使用"-ffunction-sections"和"-fdata-sections"将每个function/data创建为一个sections，sections名与function/data名保持一致。 链接时：采用"-Wl, -gc-sections"，告诉系统去掉那些没用用到的section，则链接器ld不会链接未使用的函数，从而减小可执行文件大小。  如果静态库不是你自己生成的，试试--strip-all(貌似-gc-sections与--gc-sections都可以) gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections -Wl,--strip-all

引用 5 楼 Intel0011 的回复:gcc -Os -fdata-sections -ffunction-sections test.c -o test.exe -Wl,-gc-sections -Wl,-strip-all or gcc -Os -fdata-sections -ffunction-sections -Wl,-gc-sections -Wl,-strip-all test.c -o test.exe 太牛了你！话说你这些是在哪里看到的？

引用 2 楼 user-2 的回复:--gc-sections，gc前面是两个-，不过不一定能小多少，你ls比较一下 不识别这个参数呀。。。。。 我的gcc是Windows上的（mingw）

忘说了，前提是静态库


Question: free函数

free需要和malloc/realloc成对出现，free是针对对上空间的释放，对于没在堆上申请空间的地址是不能释放的，否则可能会出现多错误～

引用 3 楼 肥牛肉^*^ 的回复：[quote=引用 2 楼 user-5的回复:]malloc <-> free 一定是成对使用的。 Sequence st没有使用malloc，是放在栈上的，不需要自行去free 至于说结构体中包含了指针。那得看这个指针是怎么用的。 如果没有malloc空间，不需要free。 那让结构体里面的指针指向一个指针变量这样可以释放吗，就是int *p   int**a=p可以free（st）吗[/quote]数组和数组元素是两码事 数组不用free，数组元素如果是指针类型，并且申请了内存，就要释放数组元素，也就是释放free(st.a[i])是可以的

引用 3 楼 肥牛肉^*^ 的回复:那让结构体里面的指针指向一个指针变量这样可以释放吗，就是int *p   int**a=p可以free（st）吗 你对成对使用这个词是怎么理解的

free 只针对堆地址，并不是所有的指针都需要free

引用 2 楼 user-5的回复:malloc <-> free 一定是成对使用的。 Sequence st没有使用malloc，是放在栈上的，不需要自行去free 至于说结构体中包含了指针。那得看这个指针是怎么用的。 如果没有malloc空间，不需要free。 那让结构体里面的指针指向一个指针变量这样可以释放吗，就是int *p   int**a=p可以free（st）吗

没有动态分配就不用free


Question: 关于多维指针的使用

感谢大佬们  我明白了

C99支持动态数组 Vs出错是因为他对c99标准不完全支持

引用 楼主 盛祖吕 的回复:问题如下： 1.题解使用的c语言是标准c吗？为什么能用变量初始化数组长度 2.triangle是二维指针，是怎么能够进行triangle[i][j]操作？vs是不能运行的，原因在于编译器不知道*triangle的数组长度有多大，没办法找到triangle[i][j]，而如下操作是可以的，创建了一个一维指针数组，每一个一维指针都指向一块独立的内存空间  int** cache = (int**)malloc(sizeof(int*) * triangleSize); for (int i = 0; i < triangleSize; i++) { 	cache[i] = (int*)malloc(sizeof(int) * triangleColSize[i]); }  3.针对问题2中的问题，类似于本题的情况，如何才能优雅的实现对一个多维数组使用数组下标来操作。 	cache[0][0] = triangle_p[0][0];		//此处运行崩溃 1、这个是符合C99标准的语法，用变量初始化数组长度且是局部作用域的数组称为变长数组 2、triangle是二维指针，是怎么能够进行triangle[i][j]操作？这个是二维数组的基本操作，triangle[i]是一维指针，triangle[i][j]就是元素了 3、明显你只对cache的二维分配了空间，没有对triangle_p的二维分配空间就访问当然出错

引用 5 楼 盛祖吕 的回复:[quote=引用 3 楼 qybao 的回复:]LS都说了，补充一下 2 【triangle是二维指针，是怎么能够进行triangle[i][j]操作？vs是不能运行的，原因在于编译器不知道*triangle的数组长度有多大，没办法找到triangle[i][j]】，如果是这样，你的代码 if (1 == triangleSize)         return triangle[0][0]; //为什么就可以操作？i=0,j=0  所以问题不在于编译器知不知道长度有多少，这个长度是你自己保证的，如果长度没能保证，编译器只会数组越界进行非法操作。所以这些参数的指针的有效性以及数组长度是你自己去保证的，因为编译器不知道运行时就传入什么参数，所以只要你语法对，就可以编译。  3 你的cache[I]都知道malloc分配内存，为何就没有想到triangle_p[i]没分配内存？所以triangle_p[0][0];是非法的。 不好意思贴错代码了 我之所以会说编译器不知道多少是因为如下例子： int a[2][2] = { {0,1}, {2,3} }; int **b = a; printf("%d\n", b[1][0]); 这样子运行的时候会崩溃，因为编译器不知道b[0]-b[1]间具体有多大的内存空间，所以必须显式的指定指针的宽度所以得写成以下这样才能正确运行 int a[2][2] = { {0,1}, {2,3} }; int (*b)[2] = a; printf("%d\n", b[1][0]); 那么问题来了   我的这个题目传入的参数数组的宽度不是定值，也就是说指定指针宽度得是个变值，而vs里又要求指针宽度不能是变量，这就很矛盾了，例如下面这样编译就会报错 int c = 2; int (*b)[c] = a;[/quote]  你没明白我的意思。我上面也说了，编译器不管长度，你不保证长度它就越界非法访问内存，所以这个参数传入是你自己保证的。 人家的题目又没有说main函数会给minimumTotal函数传入一个等长的二维数组（为了回答还去看了一下题目，下次直接贴题目不要链接），你怎么就自以为人家传入函数的参数是等长二维数组呢？ 比如  void printDoublePointer(int **p, int row, int *col) { //谁规定这里的p是等长的二维数组？p本身就是个不等长数组，1维长度row控制，2维长度col控制，很正常     int i, j;     for(i=0; i<row; i++) {         for (j=0; j<col[i]; j++) {             printf("%d ", p[i][j]); //这里的I，j是靠你保证的，你传入的参数不对，自然就会造成非法访问         }         printf("\n");     } }  int main() {     int n=5, i, j;     int **p = (int**)malloc(sizeof(int*)*n);     int *col = (int*)malloc(sizeof(int)*n);     for (i=0; i<n; i++) {         col[i] = i+1;         p[i] = (int*)malloc(sizeof(int)*col[i]);         for (j=0; j<col[i]; j++) {             p[i][j] = j+1;         }     }     printDoublePointer(p, n, col); //人家main函数这样传参数不行吗？谁规定一定用等长二维数组     free(col);     for (i=0; i<n; i++) {         free(p[i]);     }     free(p);     return 0; }

引用 8 楼 user-4 的回复:数组不是指针  你用二级指针指向二维数组是错误的行为  属于对指针和数组理解错误 所以oj在调用我的函数进行传参的时候传入的是一个指针数组，而不是直接将一个二维数组传入喽 这样看起来就说的过去了

数组不是指针  你用二级指针指向二维数组是错误的行为  属于对指针和数组理解错误

引用 5 楼 盛祖吕 的回复:我之所以会说编译器不知道多少是因为如下例子： int a[2][2] = { {0,1}, {2,3} }; int **b = a; printf("%d\n", b[1][0]); 这样子运行的时候会崩溃，因为编译器不知道b[0]-b[1]间具体有多大的内存空间 这个崩溃和你说的内容毫无关系 假设 int* 和 int 都是 4个字节 假设 数组a地址是1000 b[1] 就是 *(b+1) b是1000  b+1是1004 1004是 a[0][1]的地址 b[1][0] 相当于 *(int*)a[0][1] 把a[0][1]这个int内容当成地址 并解引用 导致崩溃

if (1 == triangleSize)         return triangle[0][0]; //为什么就可以操作？i=0,j=0 这句话没报错是因为用例没运行到

引用 3 楼 qybao 的回复:LS都说了，补充一下 2 【triangle是二维指针，是怎么能够进行triangle[i][j]操作？vs是不能运行的，原因在于编译器不知道*triangle的数组长度有多大，没办法找到triangle[i][j]】，如果是这样，你的代码 if (1 == triangleSize)         return triangle[0][0]; //为什么就可以操作？i=0,j=0  所以问题不在于编译器知不知道长度有多少，这个长度是你自己保证的，如果长度没能保证，编译器只会数组越界进行非法操作。所以这些参数的指针的有效性以及数组长度是你自己去保证的，因为编译器不知道运行时就传入什么参数，所以只要你语法对，就可以编译。  3 你的cache[I]都知道malloc分配内存，为何就没有想到triangle_p[i]没分配内存？所以triangle_p[0][0];是非法的。 不好意思贴错代码了 我之所以会说编译器不知道多少是因为如下例子： int a[2][2] = { {0,1}, {2,3} }; int **b = a; printf("%d\n", b[1][0]); 这样子运行的时候会崩溃，因为编译器不知道b[0]-b[1]间具体有多大的内存空间，所以必须显式的指定指针的宽度所以得写成以下这样才能正确运行 int a[2][2] = { {0,1}, {2,3} }; int (*b)[2] = a; printf("%d\n", b[1][0]); 那么问题来了   我的这个题目传入的参数数组的宽度不是定值，也就是说指定指针宽度得是个变值，而vs里又要求指针宽度不能是变量，这就很矛盾了，例如下面这样编译就会报错 int c = 2; int (*b)[c] = a;

不好意思贴错代码了 上面的是我调试的代码，实际没有triangle_p这个指针  int minimumTotal(int** triangle, int triangleSize, int* triangleColSize) {     int** cache = (int**)malloc(sizeof(int*) * triangleSize);     int res = 99999999999;     if (1 == triangleSize)         return triangle[0][0];     else if (!triangleSize)         return -1;     for (int i = 0; i < triangleSize; i++)     {         cache[i] = (int*)malloc(sizeof(int) * triangleColSize[i]);         memset(cache[i], 0, sizeof(int) * triangleColSize[i]);       }     cache[0][0] = triangle[0][0];        //此处运行崩溃     for (int i = 1; i < triangleSize; i++)     {         for (int j = 0; j < triangleColSize[i]; j++)         {             if (0 == j)             {                 cache[i][0] = cache[i - 1][0] + triangle_p[i][0];             }             else             {                 cache[i][j] = MIN(cache[i - 1][j], cache[i - 1][j - 1]) + triangle_p[i][j];             }         }     }     for (int i = 0; i < triangleColSize[triangleSize - 1]; i++)     {         res = MIN(res, cache[triangleSize - 1][i]);     }     return res; }