Question: 数据结构用C语言，建立单链表并求表长

厉害，尤其是赵四老师，顶帖！

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

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

建立的时候就出错了  q->Next=L->Next; L->Next=q; 你新建的q一直都是放在L->Next下，所以不管怎么增加，你表长不会改变吧  修改了下，没测试过  List Read() { 	int m; 	LNode *q, *p; 	List L=(List)malloc(sizeof(LNode)); 	L->Next=NULL; 	p = L; 	 	while((scanf("%d", &m))!='-1') { 		q=(LNode*)malloc(sizeof(LNode)); 		q->Data=m; 		q->Next=NULL; 		p->Next=q; 		p = p->Next; 	} 	return L; }

#include <stdio.h> #include <stdlib.h>  typedef int ElementType; typedef struct LNode *PtrToLNode;  struct LNode {     ElementType Data;     PtrToLNode Next; };  typedef PtrToLNode List;  List Read() {     int m;     List q;     List L = (List)malloc(sizeof(struct LNode));     L->Next = NULL;     while((scanf("%d", &m)) != -1 && m != -1) {    /* replace '-1' with -1, then add condition when exit from while*/         q = (List)malloc(sizeof(struct LNode));         q->Data = m;         q->Next = L->Next;         L->Next = q;     }     return L; }  int Length(List L) {     int j = 0;     List p;     p = L->Next;     while(p) {         p = p->Next;         j++;     }     return j; }  int main() {     List L = Read();     printf("%d\n", Length(L));     return 0; } 修改了一下，求长度的逻辑没问题，C语言对于结构体名不能单独使用吧，需要加struct关键字，或者typedef一下； 另外，我改过的程序，循环输入，输出-1就会退出输入，然后计算长度。


Question: 关于外部文件中结构体内嵌后外部声明报错，及二级指针问题

int main() {         /*struct*/ mysql_pool mysql; //你定义变量不需要再用struct描述了         return 0; }  问题二： 我在test.h文件中使用了mysqlclient库的api  所以要用到msyql的头文件 为什么不能把头文件写在test.c中  而在test.c(test.h?)中加入的头文件可以直接在main.c中使用  你在main #include "test.h“了，那么main中也包含了test.h中包含的头文件 test.c作为一个编译单元，对main是不可见的

问题1：需要你把定义的头文件test.h加到需要用到这两个结构体的源文件里； 问题2：应该是可以用的，在main.c中建议也引入api的头文件（如果在main.c中有用到api的函数接口）；  另外，test.h的头文件里#ifndef _MYSQL_H_ #define _MYSQL_H_ 这两行不好和mysql.h里的一样。避免出错，建议头文件名是什么，头文件里的避免重复包含的这两句宏也是用头文件的名字。 比如test.h头文件，建议宏是这样定义： #ifndef _TEST_H_ #define _TEST_H_ ... #endif


Question: 帮忙解答一道题谢谢！！！

非常感谢各位热心的解答

for (i; search[i] != '\0';++i) 这里应该是判断string是否到达\0，而不是search

我真的没看懂你的逻辑，没看出你代码有查找子串的点 总的来说你可以有以下思路  循环被查找字符串 如果某个字符匹配查找串的第一个字符，那么判断后续的字符是否相同 相同就返回这个索引 否则查找下一个被查找串的字符，直至结束，如果都没有就返回-1  以下是我写的一个版本  int findstring(char string[], char search[]) {     int idx1 = 0, idx2, idx3;     if (!string) //如果被查找串为NULL，返回-1         return -1;     if (!search || !search[0]) //如果查找串没有数据，返回0         return 0;      for (; string[idx1]; idx1++)     {         idx2 = idx1;         idx3 = 0;         // 如果被查找串的idx1位置的字符跟search首字符相同，就继续判断后续         // 直到字符串结束或者某个对应字符不相同         while (string[idx2] && search[idx3] && !(string[idx2] - search[idx3]))             idx2++, idx3++;         if (!search[idx3]) //如果search串判断到最后'\0'的位置，意味着它是string的子串             return idx1;     }      return -1; }  int main() {     int pos1 = findstring("xxssssddxs", "sddx");     int pos2 = findstring("xxssssddxs", "sdxs");     int pos3 = findstring("xxssssddxs", "s");     int pos4 = findstring("xxssssddxs", 0);     int pos5 = findstring(0, "xxs");     int pos6 = findstring("xx", "");     int pos7 = findstring("", "");      return 0; }

引用 2 楼 ifyykp 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] #include <stdio.h> #include <string.h>   int findString(char *string, char *search); int find_string(char *src, char *subsrc); int main(void) {     char *src = "helloworld";     char *subsrc = "rld";      printf("pos = %d\n", findString(src, subsrc));     printf("pos = %d\n", find_string(src, subsrc));     return 0; }  int findString(char *string, char *search) {     int i;      for (i = 0; i < strlen(string); i++) {         if (strncmp(string+i, search, strlen(search)) == 0)             return i;     }      /* Can't find it!*/     return -1; }  int find_string(char *src, char *subsrc) {     int i, j, pos;      for (i = 0; i < strlen(src); i++) {         pos = i;         for (j = 0; j < strlen(subsrc); j++) {             if (src[pos++] != subsrc[j])                 break;         }         if (j >= strlen(subsrc))             return i;     }     /*Can't find it*/     return -1; } 两种方法，一个是调用字符串库函数，一个自定义。当然还有其他方法来实现，可以动手写写。  能写下没指针自定义的吗？你这里应该用了指针对吧？ [/quote]他只是用指针传递了一下地址。取值还是用的数组

引用 2 楼 ifyykp 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] #include <stdio.h> #include <string.h>   int findString(char *string, char *search); int find_string(char *src, char *subsrc); int main(void) {     char *src = "helloworld";     char *subsrc = "rld";      printf("pos = %d\n", findString(src, subsrc));     printf("pos = %d\n", find_string(src, subsrc));     return 0; }  int findString(char *string, char *search) {     int i;      for (i = 0; i < strlen(string); i++) {         if (strncmp(string+i, search, strlen(search)) == 0)             return i;     }      /* Can't find it!*/     return -1; }  int find_string(char *src, char *subsrc) {     int i, j, pos;      for (i = 0; i < strlen(src); i++) {         pos = i;         for (j = 0; j < strlen(subsrc); j++) {             if (src[pos++] != subsrc[j])                 break;         }         if (j >= strlen(subsrc))             return i;     }     /*Can't find it*/     return -1; } 两种方法，一个是调用字符串库函数，一个自定义。当然还有其他方法来实现，可以动手写写。  能写下没指针自定义的吗？你这里应该用了指针对吧？ [/quote] 可以，直接将指针换成数组即可。int find_string(char src[], char subsrc[]) 比如上面的定义，函数体不用做任何修改； 其实写成数组形式还是指针形式，最终编译器都会认为是指针形式，与其让编译器翻译一遍，不如直接用指针。

引用 1 楼 cfjtaishan 的回复:#include <stdio.h> #include <string.h>   int findString(char *string, char *search); int find_string(char *src, char *subsrc); int main(void) {     char *src = "helloworld";     char *subsrc = "rld";      printf("pos = %d\n", findString(src, subsrc));     printf("pos = %d\n", find_string(src, subsrc));     return 0; }  int findString(char *string, char *search) {     int i;      for (i = 0; i < strlen(string); i++) {         if (strncmp(string+i, search, strlen(search)) == 0)             return i;     }      /* Can't find it!*/     return -1; }  int find_string(char *src, char *subsrc) {     int i, j, pos;      for (i = 0; i < strlen(src); i++) {         pos = i;         for (j = 0; j < strlen(subsrc); j++) {             if (src[pos++] != subsrc[j])                 break;         }         if (j >= strlen(subsrc))             return i;     }     /*Can't find it*/     return -1; } 两种方法，一个是调用字符串库函数，一个自定义。当然还有其他方法来实现，可以动手写写。  能写下没指针自定义的吗？你这里应该用了指针对吧？


Question: 大神帮忙看看，主要问题错在什么地方

谢谢！

#include <stdio.h> #include <stdlib.h> #include <time.h>  void game(); int main(void) {     game();     return 0; }  void game() {      system("cls");     int gamer;  // 玩家出拳     int computer;  // 电脑出拳     int result;  // 比赛结果     int i = 1;      // 为了避免玩一次游戏就退出程序，可以将代码放在循环中     while (i){         printf("1:剪刀\n2:石头\n3:布\n0:不玩了\n");         printf("请输入你要出的拳头：\n");         scanf("%d", &gamer);         switch (gamer) {             case 1:                 gamer = 4;                 break;             case 2:                 gamer = 7;                 break;             case 3:                 gamer = 10;                 break;             case 0:                 {                     system("cls");                     //menu();                 }                 break;         }         srand((unsigned)time(NULL));  // 随机数种子         computer = rand() % 3;  // 产生随机数并取余，得到电脑出拳         result = gamer + computer;  // gamer 为 char 类型，数学运算时要强制转换类型          printf("电脑出了: ");         switch (computer)         {             case 0:printf("剪刀\n");break; //4    1             case 1:printf("石头\n");break; //7  2             case 2:printf("布\n");break;   //10 3         }         printf("你出了");         switch (gamer)         {             case 4:                 printf("剪刀\n");                 break;             case 7:                 printf("石头\n");                 break;             case 10:                 printf("布\n");                 break;         }         if (result == 6||result == 7||result == 11)             printf("你赢了!\n");         else if (result == 5 || result == 9 || result == 10)             printf("电脑赢了!\n");         else             printf("平手\n");         system("pause>nul&&cls");  // 暂停并清屏     } } 代码里i 没有初始化，其他没什么问题；除非赋值gamer为0，否则不会进入switch中case 0里的


Question: 九度oj 1100 一直wa，实在找不出错在哪，求大神指教（dijkstra算法）

百度搜相关关键字。

自己顶，求不沉

好的，我再发一个

建议： 1. 将代码细分，可以根据功能分成不同函数处理。把所有的操作写在一起，容易分不清逻辑； 2. 建议放到C++专栏里


Question: 用迭代法算x的n次方的代码

#include <stdio.h>  int power(int x, int n) {   int i;   int result = 1;   if(n < 0){   	printf("指数必须大于0！\n");     return -1;   }   for(i=0; i<n; i++){   	result *= x;   }   return result;   } int main() {   printf("%d\n", power(2,3)); 	return 0; }

#include <stdio.h>  unsigned int get_power(int num, int n);  int main(void) {     int num, index;     printf("Please input two numbers: ");     scanf("%d%d", &num, &index);      printf("%d ^ %d = %u\n", num, index, get_power(num, index));      return 0; }  unsigned int get_power(int num, int n) {     int i;     unsigned int power = 1;      for (i = 0; i < n; i++) {         power *= num;     }      return power; }


Question: 打印沙漏

等差数列应用——控制台输出沙漏


Question: 单链表的实现中出现error: expected ';', ',' or ')' before '&' token的错误

引用 2 楼 cfjtaishan 的回复:注意你的coding style. 谢谢！

注意你的coding style.

出现这样的错误，原因是C语言里不支持引用，这是C++才会有的语法功能；建议是用*； 你的代码除了这些error，以外，还有很多。建议你自己一一修改了。以下是改过的： #include <stdio.h> #include <stdlib.h>  typedef int ElemType;  typedef struct LNode{     ElemType data;//数据域     struct LNode *next; //指针域 }LNode, *LinkList;  //初始化线性表 void Init_LinkList(LinkList *L) {     *L = (LinkList)malloc(sizeof(LNode));     (*L)->next = NULL; }  //取元素 int GetElem_LinkList(LinkList *L, int i, ElemType *e) {     int j;     LinkList p;      //L是带头结点的链表的头指针，以e返回第i个元素     p = (*L)->next;//p指向第一个节点     j = 1;//j为记数量     while (p && j < 1) {//顺时针向后查找,直到p指向第i个元素         p = p->next;         ++j;     }     if(!p||j>i){//如果p不存在         return 0;     }     else{         *e = p->data;         return 1;     } }  //插入数组元素 int Insert_LinkList(LinkList *L, int i, ElemType e) {     int j;     LinkList p, s;      p = (*L)->next;     j = 0;     while (p && j < i-1) {         p = p->next;         ++j;     }     if (!p || j > i-1){//插入位置非法         return 0;     } else {         s=(LinkList)malloc(sizeof(LNode));         s->data = e;         s->next = p->next;         p->next = s;          return 1;     } }  //删除元素 int Delete_LinkList(LinkList *L, int i, ElemType *e) {     int j;     LinkList p, q;      p = (*L)->next;     j = 1;     while (p && j < i - 1) {         p = p->next;         ++j;     }     if (!p || j > i - 1) {         return 0;     } else {         q=p->next;         p->next = q->next;         *e = q->data;         free(q);         return 1;     } } //建立线性表 //头插法： void CreatLinkList(LinkList *L, int n) {     int i;     LinkList p;      L=(LinkList *)malloc(sizeof(LinkList));     //创建头结点     (*L)->next=NULL;     for(i = n; i > 0; i--) {         p = (LinkList)malloc(sizeof(LNode));         scanf("%d", &p->data);         p->next = (*L)->next;         (*L)->next = p;     } }  //线性表的合并 void Merge_L(LinkList La, LinkList Lb, LinkList *Lc) {     LinkList pa, pb, pc;      //按值排序的单链表La,Lb,归并为Lc后也按值排序     pa = La->next;     pb = Lb->next;     *Lc = pc = La;//初始化      while (pa&&pb) {//将pa,pa结点按大小依次插入c中         if(pa->data <= pb->data){             pc->next = pa;             pc = pa;             pa = pa->next;         }else{             pc->next = pb;             pc = pb;             pb = pb->next;         }         pc -> next =pa?pa:pb;//插入剩余值         free(Lb);     } }


Question: 利用getchar()实现输入多个字符串

可以最多输入n个字符串，while循环读入字符串，for循环控制读入字符串的个数。 while()每次读入到‘\n’时就会结束一个字符串的读入，进而i++； for()循环一直到i=n时不满足i<n，结束循环。

循环而已，每次输入一个字符，然后换个位置，继续输入

首先n标识for循环可以执行几次，每一次都是将字符放在字符数组a[i]中，每次回车后，退出while的循环，并且对此次的输入结尾加上字符串结束标记'\0'

for (int i = 0; i<n; i++) {         j = 0;  //输入一行，回车键。这个是一行的结束标志，把前面的字符存入一个数组中，结束内循环 //继续读取下一行的字符         while ((c = getchar()) != '\n') {             a[i][j++] = c;         }         a[i][j] = '\0';     }


Question: do-while循环的问题

引用 3 楼 qq_18888869 的回复:不会是死循环，每次除以10都会减少一位，直到为零。  谢谢您

引用 4 楼 paschen 的回复:这是整数除法，不是浮点数除法，如9/10就等于0  谢谢您

引用 1 楼 jianwen0529 的回复:n是整数呀，跟字符串有啥关系  n = n / 10 int 除以 int 最后还是int，结果是整数  11 / 10 = 1; // 两个整形数相除结果取整 10 / 10 = 1; 9 / 10 = 0; // 两个整形数相除结果取整  谢谢您

这是整数除法，不是浮点数除法，如9/10就等于0

不会是死循环，每次除以10都会减少一位，直到为零。

不会死循环，因为每次n对10除之后，会把商赋值给n。比如101，101 /10， n = 10, 下次，n = 1,在下次，n = 0退出循环


Question: 关于shell排序算法的一些不懂的地方求大神讲解

各种排序算法动画演示http://www.webhek.com/misc/comparison-sort/

引用 3 楼 qq_34574208 的回复:你先去看看什么是树，什么是堆 void shellsort(int v[],int n) 这个数组实际上是实现了一棵树，你先去看看吧，现在讲了也没用。 谢谢

引用 1 楼 user-3 的回复:http://baike.baidu.com/link?url=vMyMF52wGGd9wanrBQkXSM3tIhrOEteDEys_rvHqHUwpj3PuwDsls3eC_eO6QagJd-sNE-fv2VQoMSWP7WWAkeEB3nrzWvNMugV_TJpxFGO  大神，百度百科如果能给我解决，我就不会来这里问了，不知道具体是怎么实现这一过程是我的困惑


Question: 只有我觉得数据结构与算法分析c语言描述翻译的很烂吗

百度搜相关关键字。

宏定义替换，这什么兼容？

你说的这个我知道，但是不清楚这和兼容性有什么关系

宏定义，等价替换~

引用 2 楼 m0_37590480 的回复:你说的这个我知道，但是不清楚这和兼容性有什么关系 宏定义可以提高兼容性，比如在嵌入式开发中，不同的平台CPU的位数可能不同，那么相同int类型，指针表示的值的范围和内存地址长度也不一样；通过宏定义可以做到兼容；即不同的平台使用宏去匹配。


Question: 大神来帮看看

if(i==3)     //这里i=1它也运行  在if语句里面 你如果写i=1 那就代表赋值语句了，就相当于if(true) i=1 和i==1 是有区别的 楼主注意一下 =是赋值 ==是判断两个数是否相等 相等则返回true 否则返回false

请问一下，楼主写这代码是想做什么呢？ 你只给代码也不知道你要的是什么呀

我用的是do...while，我去了“；”后报错啊。

#include<stdio.h>  int xn(int *x,int *m);  int main() {     int n=10, i;     int nx[10], *p, *z;      for(i = 0; i < n; i++)     {         nx[i] = i + 1;         printf("%3d", nx[i]);     }     printf("\n");     p = nx;     z = &nx[i-1];   /* replace i with i-1, i has overflowed.*/      printf("%5d\n", xn(p, z));     return 0; } int xn(int *x, int *m) {     int i = 1, j, y;     int *a;      a = x;     for(j = 0; x != m; x++)     {         j++;     }     x = a;     do     {         if(i == 3)         {             y = *x;             *x = 0;             j--;             i = 0;             printf("i = %d, *x = %d\n", i, *x);         }         else         {             i++;             x++;             if(x > m)                 x=a;             while(*x == 0)    /*del ;*/             {                 x++;             }             printf("+++i = %d, *x = %d\n", i, *x);         }     } while(j != 1);      printf("\n");     return *x; } 不是i为1的语句体里执行了，而是i确实等于了3才执行了。 另外，提出2点问题： 1. main函数里，z = &xn[i]其实数据已经越界了，因为i 的下标范围是0～9,经过循环后i是10了，所以越界； 2. xn函数里有while(*x == 0);去掉后面的分号； 最后提一点，注意coding style.

if(i==3)     //这里i=1它也运行  i = 1 跟 i == 1 可是不同的噢


Question: 文件和输出设备的关系

输出设备你可以看成是文件，使用createfile可以打开设备，readfile和writefile可以对设备进行读写。

在Linux下，一切都是文件。设备也是文件；不同的文件都有自己描述符，区分不同文件就是使用文件描述； 你的问题里，输出设备是指终端输出或者是显示器吧；显示器是标准输出设备，也是又对应的文件描述符； 0，1，2分别表示：标准输入（键盘等），标准输出（显示器等），标准错误输出（也一般是指显示器）


Question: 虽然很不好意思。。但是还是要把代码贴上来/（C语言实现数据结构的Arraylist）

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }

#include <stdio.h> #include <stdlib.h> #include <assert.h>  typedef int elem_type;  typedef struct poly_key {     elem_type ratio;     elem_type power; }poly_obj, *poly_handle;  typedef struct poly_node {     poly_obj poly;     struct poly_node *next; }polynomial_obj, *polynomial_handle;  typedef int (*pfunc)(poly_obj, poly_obj);   static polynomial_handle create_node(void) {     polynomial_handle pnew;      pnew = (polynomial_handle)malloc(sizeof(polynomial_obj));     if (!pnew) {         fprintf(stderr, "malloc error!\n");         return NULL;     }     pnew->poly.ratio = 0;     pnew->poly.power = 0;     pnew->next = NULL;      return pnew; }  /* Create a polynomial */ void create_polynomial_link(polynomial_handle *phead) {     polynomial_handle p, q;      while (1) {         p = create_node();         printf("Please input two numbers(ratio and power): ");         scanf("%d%d", &p->poly.ratio, &p->poly.power);         if (p->poly.ratio == 0)    /* if ratio is equal zero, then break from while.*/             break;         if (!(*phead)) {             *phead = p;             q = *phead;             continue;         }         q->next = p;         q = p;     }     free(p); }   void show_polynomial_link(polynomial_handle phead) {     polynomial_handle pcur;      pcur = phead;     while (pcur) {         printf("%dx^%d ", pcur->poly.ratio, pcur->poly.power);         pcur = pcur->next;     }     putchar(10); }  int get_length_polynomial(polynomial_handle phead) {     int cnt = 0;     polynomial_handle pcur = phead;      while (pcur) {         cnt++;         pcur = pcur->next;     }      return cnt; }  /* flag: 0: compare by ratio, 1: compare by power*/ static int check_cond(polynomial_handle pnode, int val, int flag) {     assert(pnode);      if (flag)         return (pnode->poly.power == val);     else         return (pnode->poly.ratio == val); }   void delete_polynomail(polynomial_handle *phead, int val, int flag) {     polynomial_handle pcur, prev;      pcur = prev = *phead;     while (pcur) {         if (check_cond(pcur, val, flag)) {             if (pcur == *phead) {                 *phead = (*phead)->next;                 free(pcur);                 pcur = *phead;                 continue;             }             prev->next = pcur->next;             free(pcur);             pcur = prev->next;         } else {             prev = pcur;             pcur = pcur->next;         }     } }  static int compare_as_ratio(poly_obj a, poly_obj b) {     return (a.ratio - b.ratio); }  static int compare_as_power(poly_obj a, poly_obj b) {     return (a.power - b.power); }  void bubble_asc_sort(polynomial_handle phead, pfunc cmp) {     polynomial_handle p, q;     poly_obj tmp;      for (p = phead; p; p = p->next)         for (q = phead; q->next; q = q->next)             if (cmp(q->poly, q->next->poly) > 0) {                 tmp = q->poly;                 q->poly = q->next->poly;                 q->next->poly = tmp;             } }  /* insert node before phead */ void insert_polynomail_node(polynomial_handle *phead, poly_obj param) {     polynomial_handle pnew;      pnew = create_node();      pnew->poly = param;      pnew->next = *phead;     *phead = pnew; }  void destroy_polynomail_link(polynomial_handle phead) {     polynomial_handle pcur, prev;      pcur = phead;      while (pcur) {         prev = pcur->next;         free(pcur);         pcur = prev;     } }  int main(void) {     int len, flag, val;     polynomial_handle phead = NULL;     poly_obj poly;      create_polynomial_link(&phead);     show_polynomial_link(phead);      printf("Add one term(ratio, power):  ");     scanf("%d%d", &poly.ratio, &poly.power);     insert_polynomail_node(&phead, poly);     printf("After insert: \n");     show_polynomial_link(phead);      len = get_length_polynomial(phead);     printf("The term of polynomial is %d\n", len);       bubble_asc_sort(phead, compare_as_ratio);     printf("After sort as ratio: \n");     show_polynomial_link(phead);      bubble_asc_sort(phead, compare_as_power);     printf("After sort as power: \n");     show_polynomial_link(phead);      printf("Del terms, del ratio or power(0, 1): ");     scanf("%d", &flag);     printf("Please input a number: ");     scanf("%d", &val);      delete_polynomail(&phead, val, flag);     printf("After delete: \n");     show_polynomial_link(phead);      destroy_polynomail_link(phead);     return 0; }   链表表示多项式，如有问题可以继续讨论～加油吧～

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

看到一句要提高难度，看过你的代码，我还是建议不要提高难度了。 1.代码没有条理性，函数定义后面加数字这是一个不好的定义方式，每个函数都有自己的独立功能，如果功能相近不建议写两个，在进行细分。 2. 函数返回值和接收返回值的类型不匹配，这个在编译阶段就会提出警告甚至是错误；建议，先把警告和错误去掉； 3. 函数的结束方式：1）正常退出，就是所有语句都执行完毕；2）执行逻辑错误，比如malloc失败，exit退出；3）return返回退出；若return了，那么直接从该函数里退出了，自然后面的语句就不会执行了，但是程序里把很多关键的语句放在return后面执行； 4. 注释太多，注释多不如把代码写的通俗易懂，就是在定义变量，函数的时候能够做到见名知义，这样就不需要写那么多注释了，如果真要写那么多，建议你写成文档，用于代码说明； 5. 结构体可以直接赋值的，在排序中看到你的结构体交换数据还是先将结构体元素拷贝，然后在每个元素交换；如果一个结构体有50多个成员，那怎么交换两个结构体的值？ 6.个人建议，代码不一定要写完了所有功能再编译，而是一个功能写完，编译运行没问题在进行下一个功能；当然，需要在写之前先做好设计；如果一下子写完，再一下子出了很多error或警告，处理起来可能就会比较麻烦。当然，如果自己的能力达到一定程度了，可以考虑。但是即使这样，我还是建议一点一点的实现，步步为营，稳打稳进。 以上都是个人见解，如有说的重的，请包涵～

都是编译的小问题，我总结下：  1： 函数使用前，必须能看到它的声明，但是你有些函数使用的时候都看不见声明，虽然在后面有定义 解决方法：把函数的定义放在前面，或者在最开始处声明函数，在后面定义  2：实参和返回值，跟函数的形参和返回值不匹配报错，例如 //main char judge; int choice;  judge=create_poly(&poly1,&poly2); 返回值要求char *，你却给了个char； 参数要求multinomial_add *，你却传了个 multinomial_add **  3：使用未定义的东西 //main case 3:judge = Funcdetele_poly_oly_1(poly1); printf("%s\n", judge);  break; case 4:judge = Funcdetele_poly_oly_2(poly2); printf("%s\n", judge);  break;  红色部分在程序之中根本找不到它们的声明或者定义，那么它们是什么？  4：其他的一些小问题 return之后你还有其他语句，那些语句永远不会被执行，你留着有什么用


Question: 刚学c语言的小白

把printf("%d\n", a+b) 改成 printf("\n%d\n", a+b) 试试

我也是来学习的。

输入两个整数，随便用啥间隔。 仅供参考：#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>  #define MAX_PAIR 10 int main() {     int a[MAX_PAIR], b[MAX_PAIR];     int i, n = 0;     //Ctrl + Z 结束输入     while (scanf("%d%d", &a[n], &b[n]) == 2)     {         n++;     }     for (i = 0; i < n; i++)     {         printf("%d\n", a[i] + b[i]);     }     return 0; }

那你继续输入，2  5， 4  6等等；这样就可以多次输出了。每次也是新的一行。


Question: 帮我看看这段程序错在哪儿了，改了一处还是不行

写得太糟糕了。重写一个吧，没有改的必要。

什么错误，编译错误还是运行错误？ 错误提示是什么？


Question: 帮我看看这段程序错在哪儿了

你应该发在嵌入式设计的版块中去的

引用 5 楼 m0_37163288 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] //#include<reg52.h> #include<string.h>  //#define jingzhen 11059200UL 王老师叫我在那个烧录工具STC-ISP中有个波特率计算器，可以直接生成串口初始化的函数的代码 typedef  unsigned char uchar; sbit JDQ1=P1^1; uchar zifuchuan[] = "Lost humanity"; volatile uchar sending; uchar *pd;  void delay(uchar i) {     uchar j,k;     for(j=i;j>0;j++)         for(k=90;k>0;k--); }  void init_serialcom(void) {     SCON = 0x50;  //8位数据,可变波特率     AUXR |= 0x40;  //定时器1时钟为Fosc,即1T     AUXR &= 0xFE;  //串口1选择定时器1为波特率发生器     TMOD &= 0x0F;  //设定定时器1为16位自动重装方式     TL1 = 0x70;  //设定定时初值     TH1 = 0xFF;  //设定定时初值     ET1 = 0;  //禁止定时器1中断     TR1 = 1;  //启动定时器1 }  void recieve(void) {     *pd=SBUF;     sending=1;     while(sending); } void recievec(void) {     while((*pd)!='\0')     {         recieve();         pd++;     } }  void fasongzifuchuan(void) //interrupt 4 {     EA=0;     if(RI)  //收到数据     {         RI=0; //清中断请求     }     else  //发送完一字节数据     {         TI=0;         sending=0; //清正在发送标志     }     uchar* c1="Lost humanity";     uchar* c2="Lost";      if(!strcmp(pd,c1))     {         JDQ1=0;      }     else if(!strcmp(pd,c2))     {         JDQ1=1;      }     else;      EA=1; }  int main() {     init_serialcom();     while(1)     {         delay(200);         recievec();     }     return 0; }  数据类型别名，建议使用typedef，使用宏定义不是不可以，但是最好加上括号；注意，宏定义是等价替换，并且如果不加括号，uchar就是unsigned #define uchar (unsigned char) 个人建议，类型别名不建议使用宏定义，建议使用typedef,宏定义一般用于定义常量，头文件等等  改成#define uchar (unsigned char)还是不行 求助[/quote] 为啥不用typedef呢？

引用 1 楼 cfjtaishan 的回复://#include<reg52.h> #include<string.h>  //#define jingzhen 11059200UL 王老师叫我在那个烧录工具STC-ISP中有个波特率计算器，可以直接生成串口初始化的函数的代码 typedef  unsigned char uchar; sbit JDQ1=P1^1; uchar zifuchuan[] = "Lost humanity"; volatile uchar sending; uchar *pd;  void delay(uchar i) {     uchar j,k;     for(j=i;j>0;j++)         for(k=90;k>0;k--); }  void init_serialcom(void) {     SCON = 0x50;  //8位数据,可变波特率     AUXR |= 0x40;  //定时器1时钟为Fosc,即1T     AUXR &= 0xFE;  //串口1选择定时器1为波特率发生器     TMOD &= 0x0F;  //设定定时器1为16位自动重装方式     TL1 = 0x70;  //设定定时初值     TH1 = 0xFF;  //设定定时初值     ET1 = 0;  //禁止定时器1中断     TR1 = 1;  //启动定时器1 }  void recieve(void) {     *pd=SBUF;     sending=1;     while(sending); } void recievec(void) {     while((*pd)!='\0')     {         recieve();         pd++;     } }  void fasongzifuchuan(void) //interrupt 4 {     EA=0;     if(RI)  //收到数据     {         RI=0; //清中断请求     }     else  //发送完一字节数据     {         TI=0;         sending=0; //清正在发送标志     }     uchar* c1="Lost humanity";     uchar* c2="Lost";      if(!strcmp(pd,c1))     {         JDQ1=0;      }     else if(!strcmp(pd,c2))     {         JDQ1=1;      }     else;      EA=1; }  int main() {     init_serialcom();     while(1)     {         delay(200);         recievec();     }     return 0; }  数据类型别名，建议使用typedef，使用宏定义不是不可以，但是最好加上括号；注意，宏定义是等价替换，并且如果不加括号，uchar就是unsigned #define uchar (unsigned char) 个人建议，类型别名不建议使用宏定义，建议使用typedef,宏定义一般用于定义常量，头文件等等  改成#define uchar (unsigned char)还是不行 求助

引用 2 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。  已收藏，谢谢分享

C 语言， 变量需要定义在第一个执行语句之前


Question: 为什么使用GCC4.7.2用以下代码提交会报错

主函数要用结构体名表示类型的时候，前面还要加个struct 。多谢各位大佬，此贴终结。

引用 2 楼 cfjtaishan 的回复:#include<stdio.h> #include<stdlib.h> struct Info{     double n;     int j;     int k; }; int main() {     int a, i, j, b;      scanf("%d", &a);     struct Info *H=(struct Info *)malloc(a * sizeof(struct Info));     for(i = 0; i < a; i++)         scanf("%lf%d%d", &H[i].n, &H[i].j, &H[i].k);      scanf("%d", &b);     int *c = (int *)malloc(b * sizeof(int));     for(i = 0; i < b; i++)         scanf("%d", &c[i]);     for(i = 0; i < a; i++) {         for(j = 0; j < b; j++) {             if(H[i].k == c[j])                 printf("%0.lf %d\n", H[i].n, H[i].j);         }     }     return 0; } 对于结构体，C语言不支持只用结构体名来表示类型的，前面需要加struct，除非用typedef；  谢谢，编译成功了。

引用 1 楼 user-2 的回复:报什么错也不说一下

报什么错也不说一下


Question: 一个简单的C语言题求大神解答

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


Question: 结构体和结构体指针

因为你的结构体指针并没有指向一个有效的对象

指针是野指针，没有分配空间，没有分配空间的野指针，然后在对野指针进行读写操作，很容易出现段错误； 要想一样，定义指针之后要malloc空间。


Question: c 怎么读取一个不断增加的文件

我这个是linux下的啊

_sopen, _wsopen Open a file for sharing.  int _sopen( const char *filename, int oflag, int shflag [, int pmode ] );  int _wsopen( const wchar_t *filename, int oflag, int shflag [, int pmode ] );  Routine Required Header Optional Headers Compatibility  _sopen <io.h> <fcntl.h>, <sys/types.h>, <sys/stat.h>, <share.h> Win 95, Win NT  _wsopen <io.h> or <wchar.h> <fcntl.h>, <sys/types.h>, <sys/stat.h>, <share.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a file handle for the opened file. A return value of –1 indicates an error, in which case errno is set to one of the following values:  EACCES  Given path is a directory, or file is read-only, but an open-for-writing operation was attempted.  EEXIST  _O_CREAT and _O_EXCL flags were specified, but filename already exists.  EINVAL  Invalid oflag or shflag argument.  EMFILE  No more file handles available.  ENOENT  File or path not found.  Parameters  filename  Filename  oflag  Type of operations allowed  shflag  Type of sharing allowed  pmode  Permission setting  Remarks  The _sopen function opens the file specified by filename and prepares the file for shared reading or writing, as defined by oflag and shflag. _wsopen is a wide-character version of _sopen; the filename argument to _wsopen is a wide-character string. _wsopen and _sopen behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tsopen _sopen _sopen _wsopen    The integer expression oflag is formed by combining one or more of the following manifest constants, defined in the file FCNTL.H. When two or more constants form the argument oflag, they are combined with the bitwise-OR operator ( | ).  _O_APPEND  Repositions file pointer to end of file before every write operation.  _O_BINARY  Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)  _O_CREAT  Creates and opens new file for writing. Has no effect if file specified by filename exists. The pmode argument is required when _O_CREAT is specified.  _O_CREAT | _O_SHORT_LIVED  Create file as temporary and if possible do not flush to disk. The pmode argument is required when _O_CREAT is specified.  _O_CREAT | _O_TEMPORARY  Create file as temporary; file is deleted when last file handle is closed. The pmode argument is required when _O_CREAT is specified.   _O_CREAT | _O_EXCL  Returns error value if file specified by filename exists. Applies only when used with _O_CREAT.  _O_NOINHERIT  Prevents creation of a shared file handle.  _O_RANDOM  Specifies primarily random access from disk.  _O_RDONLY  Opens file for reading only; cannot be specified with _O_RDWR or _O_WRONLY.  _O_RDWR  Opens file for both reading and writing; cannot be specified with _O_RDONLY or _O_WRONLY.  _O_SEQUENTIAL  Specifies primarily sequential access from disk  _O_TEXT  Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)  _O_TRUNC  Opens file and truncates it to zero length; the file must have write permission. You cannot specify this flag with _O_RDONLY. _O_TRUNC used with _O_CREAT opens an existing file or creates a new file.  Warning   The _O_TRUNC flag destroys the contents of the specified file.  _O_WRONLY  Opens file for writing only; cannot be specified with _O_RDONLY or _O_RDWR.  To specify the file access mode, you must specify either _O_RDONLY, _O_RDWR, or _O_WRONLY. There is no default value for the access mode.  The argument shflag is a constant expression consisting of one of the following manifest constants, defined in SHARE.H.  _SH_DENYRW  Denies read and write access to file  _SH_DENYWR  Denies write access to file  _SH_DENYRD  Denies read access to file  _SH_DENYNO  Permits read and write access  The pmode argument is required only when you specify _O_CREAT. If the file does not exist, pmode specifies the file’s permission settings, which are set when the new file is closed the first time. Otherwise pmode is ignored. pmode is an integer expression that contains one or both of the manifest constants _S_IWRITE and _S_IREAD, defined in SYS\STAT.H. When both constants are given, they are combined with the bitwise-OR operator. The meaning of pmode is as follows:  _S_IWRITE  Writing permitted  _S_IREAD  Reading permitted  _S_IREAD | _S_IWRITE  Reading and writing permitted  If write permission is not given, the file is read-only. Under Windows NT and Windows 95, all files are readable; it is not possible to give write-only permission. Thus the modes _S_IWRITE and _S_IREAD | _S_IWRITE are equivalent.  _sopen applies the current file-permission mask to pmode before setting the permissions (see _umask).  Example  /* LOCKING.C: This program opens a file with sharing. It locks  * some bytes before reading them, then unlocks them. Note that the  * program works correctly only if the file exists.  */  #include <io.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/locking.h> #include <share.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h>  void main( void ) {    int  fh, numread;    char buffer[40];     /* Quit if can't open file or system doesn't      * support sharing.      */    fh = _sopen( "locking.c", _O_RDWR, _SH_DENYNO,                   _S_IREAD | _S_IWRITE );    if( fh == -1 )       exit( 1 );     /* Lock some bytes and read them. Then unlock. */    if( _locking( fh, LK_NBLCK, 30L ) != -1 )    {       printf( "No one can change these bytes while I'm reading them\n" );       numread = _read( fh, buffer, 30 );       printf( "%d bytes read: %.30s\n", numread, buffer );       lseek( fh, 0L, SEEK_SET );      _locking( fh, LK_UNLCK, 30L );       printf( "Now I'm done. Do what you will with them\n" );    }    else       perror( "Locking failed\n" );     _close( fh ); }   Output  No one can change these bytes while I'm reading them 30 bytes read: /* LOCKING.C: This program ope Now I'm done. Do what you will with them   Low-level I/O Routines  See Also   _close, _creat, fopen, _fsopen, _open

OPEN Section: Linux Programmer's Manual (2) Updated: 2004-12-08  --------------------------------------------------------------------------------    NAME open, creat - open and possibly create a file or device    SYNOPSIS #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>  int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode);     DESCRIPTION The open() system call is used to convert a pathname into a file descriptor (a small, non-negative integer for use in subsequent I/O as with read(2), write(2), etc.). When the call is successful, the file descriptor returned will be the lowest file descriptor not currently open for the process. This call creates a new open file, not shared with any other process. (But shared open files may arise via the fork(2) system call.) The new file descriptor is set to remain open across exec functions (see fcntl(2)). The file offset is set to the beginning of the file.  The parameter flags is one of O_RDONLY, O_WRONLY or O_RDWR which request opening the file read-only, write-only or read/write, respectively, bitwise-or'd with zero or more of the following:   O_APPEND  The file is opened in append mode. Before each write(), the file pointer is positioned at the end of the file, as if with lseek(). O_APPEND may lead to corrupted files on NFS file systems if more than one process appends data to a file at once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition.  O_ASYNC  Generate a signal (SIGIO by default, but this can be changed via fcntl(2)) when input or output becomes possible on this file descriptor. This feature is only available for terminals, pseudo-terminals, and sockets. See fcntl(2) for further details.  O_CREAT  If the file does not exist it will be created. The owner (user ID) of the file is set to the effective user ID of the process. The group ownership (group ID) is set either to the effective group ID of the process or to the group ID of the parent directory (depending on filesystem type and mount options, and the mode of the parent directory, see, e.g., the mount options bsdgroups and sysvgroups of the ext2 filesystem, as described in mount(8)).  O_DIRECT  Try to minimize cache effects of the I/O to and from this file. In general this will degrade performance, but it is useful in special situations, such as when applications do their own caching. File I/O is done directly to/from user space buffers. The I/O is synchronous, i.e., at the completion of the read(2) or write(2) system call, data is guaranteed to have been transferred. Under Linux 2.4 transfer sizes, and the alignment of user buffer and file offset must all be multiples of the logical block size of the file system. Under Linux 2.6 alignment to 512-byte boundaries suffices.  A semantically similar interface for block devices is described in raw(8).  O_DIRECTORY  If pathname is not a directory, cause the open to fail. This flag is Linux-specific, and was added in kernel version 2.1.126, to avoid denial-of-service problems if opendir(3) is called on a FIFO or tape device, but should not be used outside of the implementation of opendir.  O_EXCL  When used with O_CREAT, if the file already exists it is an error and the open() will fail. In this context, a symbolic link exists, regardless of where its points to. O_EXCL is broken on NFS file systems, programs which rely on it for performing locking tasks will contain a race condition. The solution for performing atomic file locking using a lockfile is to create a unique file on the same file system (e.g., incorporating hostname and pid), use link(2) to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its link count has increased to 2, in which case the lock is also successful.  O_LARGEFILE  (LFS) Allow files whose sizes cannot be represented in an off_t (but can be represented in an off64_t) to be opened.  O_NOATIME  (Since Linux 2.6.8) Do not update the file last access time when the file is read(2). This flag is intended for use by indexing or backup programs, where its use can significantly reduce the amount of disk activity. This flag may not be effective on all filesystems. One example is NFS, where the server maintains the access time.  O_NOCTTY  If pathname refers to a terminal device - see tty(4) - it will not become the process's controlling terminal even if the process does not have one.  O_NOFOLLOW  If pathname is a symbolic link, then the open fails. This is a FreeBSD extension, which was added to Linux in version 2.1.126. Symbolic links in earlier components of the pathname will still be followed. The headers from glibc 2.0.100 and later include a definition of this flag; kernels before 2.1.126 will ignore it if used.  O_NONBLOCK or O_NDELAY  When possible, the file is opened in non-blocking mode. Neither the open() nor any subsequent operations on the file descriptor which is returned will cause the calling process to wait. For the handling of FIFOs (named pipes), see also fifo(4). This mode need not have any effect on files other than FIFOs.  O_SYNC  The file is opened for synchronous I/O. Any write()s on the resulting file descriptor will block the calling process until the data has been physically written to the underlying hardware. See RESTRICTIONS below, though.  O_TRUNC  If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is ignored. Otherwise the effect of O_TRUNC is unspecified.  Some of these optional flags can be altered using fcntl() after the file has been opened.   The argument mode specifies the permissions to use in case a new file is created. It is modified by the process's umask in the usual way: the permissions of the created file are (mode & ~umask). Note that this mode only applies to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.   The following symbolic constants are provided for mode:   S_IRWXU  00700 user (file owner) has read, write and execute permission  S_IRUSR (S_IREAD)  00400 user has read permission  S_IWUSR (S_IWRITE)  00200 user has write permission  S_IXUSR (S_IEXEC)  00100 user has execute permission  S_IRWXG  00070 group has read, write and execute permission  S_IRGRP  00040 group has read permission  S_IWGRP  00020 group has write permission  S_IXGRP  00010 group has execute permission  S_IRWXO  00007 others have read, write and execute permission  S_IROTH  00004 others have read permission  S_IWOTH  00002 others have write permisson  S_IXOTH  00001 others have execute permission  mode must be specified when O_CREAT is in the flags, and is ignored otherwise.   creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC.     RETURN VALUE open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropriately). Note that open() can open device special files, but creat() cannot create them - use mknod(2) instead.  On NFS file systems with UID mapping enabled, open may return a file descriptor but e.g. read(2) requests are denied with EACCES. This is because the client performs open by checking the permissions, but UID mapping is performed by the server upon read and write requests.   If the file is newly created, its atime, ctime, mtime fields are set to the current time, and so are the ctime and mtime fields of the parent directory. Otherwise, if the file is modified because of the O_TRUNC flag, its ctime and mtime fields are set to the current time.


Question: 求助，报指针错误问题

引用 1 楼 cyfcsd 的回复:好像没有指针错误，但那个jobs[i]是一个结构体，不能直接用%s输出的，得改一下，用循环或者一个函数输出吧  Job  jobs[]={ 	{1,"法师","biubiubiu专家"}, 	{2,"刺客","千年刺杀专家"}, 	{3,"战士","我的肉提别厚"}, 	{4,"机甲师","靠机甲吃饭"}, 	{5,"射手","打哪知哪"}, };        这里我用for(j=0;j<5;j++) { 	printf("%s\n",jobs[j]); } 想输出这样的效果不行么：程序在我输入后，就报内存错误了 1,"法师","biubiubiu专家" 2,"刺客","千年刺杀专家" 3,"战士","我的肉提别厚" 4,"机甲师","靠机甲吃饭" 5,"射手","打哪知哪"

引用 5 楼 cfjtaishan 的回复:#include<stdio.h> #include<stdlib.h>  typedef struct _job {     int id;     char * name;     char * desc; }Job;  typedef struct _ability {     int id;     char * name;     char * intro; }Ability;  typedef struct _pubTime {     int year;     int month;     int day; }PubTime;  typedef struct _hero {     int id;     char * name;     char sex;     Job job;     double hp;     double speed;     Ability abillity[5];     PubTime pubTime; }Hero;  void InputHero();  Hero heros[5]; Job  jobs[]={     {1,"法师","biubiubiu专家"},     {2,"刺客","刺杀专家"},     {3,"战士","我的肉提别厚"},     {4,"机甲师","靠机甲吃饭"},     {5,"射手","射得准"}, };  void InputHero() {     int i,j;     for(i=0;i<5;i++)     {         int jobchoice;         printf("第%d位英雄的信息：\n",i+1);         heros[i].id = i+1;         printf("英雄名称为：");         heros[i].name = (char*)malloc(50);         scanf("%s",heros[i].name);         getchar();/* add getchar() here */         printf("英雄性别为：");         scanf("%c",&heros[i].sex);         fflush(stdin);           for(j = 0; j < 5; j++)         {             printf("%s\n",jobs[j].name); /* error, jobs[j].name*/         }         printf("请选择职业：(1-5之间的整数)");         scanf("%d", &jobchoice);         heros[i].job = jobs[jobchoice - 1];         printf("%s当前职业为：《%s》\n",heros[i].name, heros[i].job.name); /* error job.name*/     } }  int main(int argc, char *argv[]) {     InputHero();      return 0; } 有几处错误和不合理的地方，现已修改，可以测试一下，试试！  问题解决，感谢！

引用 3 楼 qq_37837743 的回复:[quote=引用 1 楼 cyfcsd 的回复:] 好像没有指针错误，但那个jobs[i]是一个结构体，不能直接用%s输出的，得改一下，用循环或者一个函数输出吧  Job  jobs[]={ 	{1,"法师","biubiubiu专家"}, 	{2,"刺客","千年刺杀专家"}, 	{3,"战士","我的肉提别厚"}, 	{4,"机甲师","靠机甲吃饭"}, 	{5,"射手","打哪知哪"}, };        这里我用for(j=0;j<5;j++) { 	printf("%s\n",jobs[j]); } 想输出这样的效果不行么：程序在我输入后，就报内存错误了 1,"法师","biubiubiu专家" 2,"刺客","千年刺杀专家" 3,"战士","我的肉提别厚" 4,"机甲师","靠机甲吃饭" 5,"射手","打哪知哪"[/quote] #include<stdio.h> #include<stdlib.h> typedef struct _job {     int id;     char * name;     char * desc; }Job; typedef struct _ability {     int id;     char * name;     char * intro; }Ability; typedef struct _pubTime {     int year;     int month;     int day; }PubTime; typedef struct _hero {     int id;     char * name;     char sex;     Job job;     double hp;     double speed;     Ability abillity[5];     PubTime pubTime; }Hero; void InputHero(); Hero heros[5]; Job  jobs[]={     {1,"法师","biubiubiu专家"},     {2,"刺客","刺杀专家"},     {3,"战士","我的肉提别厚"},     {4,"机甲师","靠机甲吃饭"},     {5,"射手","射得准"}, }; void InputHero() {     int i,j;     for(i=0;i<5;i++)     {         int jobchoice;         printf("第%d位英雄的信息：\n",i+1);         heros[i].id = i+1;         printf("英雄名称为：");         heros[i].name = (char*)malloc(50);         scanf("%s",heros[i].name);         printf("英雄性别为：");         scanf("%c",&heros[i].sex);         fflush(stdin);                  for(j=0;j<5;j++)         {             printf("%d %s %s\n",jobs[i].id, jobs[i].name, jobs[i].desc);         }         printf("请选择职业：(1-5之间的整数)");         scanf("%d",&jobchoice);         heros[i].job = jobs[jobchoice - 1];         printf("%s当前职业为：《%s》\n",heros[i].name,heros[i].job.name);     } }  int main() { InputHero();  return 0; }

下面两个name少写了。 for(j=0;j<5;j++)  {         printf("%s\n",jobs[j].name);  } printf("请选择职业：(1-5之间的整数)"); scanf("%d",&jobchoice); heros[i].job = jobs[jobchoice - 1].name;


Question: c 语言小白求助

哦哦，好的，谢谢

因为你输入完a以后按了一个回车键，这个回车键被ch接收了，你可以在scanf("%d",&a);后面加一句getchar();来接收那个回车，这样就正常了，但注意只能按一个回车 如有问题欢迎继续追问，没问题请及时结贴，谢谢


Question: 求教各位大虾！！关于两次free（） 没有出错问题

参考Linux源代码中free和malloc的实现。

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

@wizard_tiger 可是释放了这个指针意思是这个指针变量p里面存的地址还是之前的，但是这个指针已经和那块区域没有了联系，没有访问权了，可是大虾你看我后面定义在堆上的例子，，还可以打印出指针所指空间的值   是我哪里理解错了吗

只是释放了指针的位置，表示这个位置可以使用，在没有再次使用前还是原数值。未定义行为。

以上程序我申请了堆上的空间，然后将字符串拷贝在堆上的空间了，那么释放的时候应该也是释放的堆上的空间吧？ 但是两次释放仍然没有出错的现象，难道还是释放的栈上的空间？？  望大虾指点一番

还有个疑问就是，有位大虾说：其实请不清空指针所指的空间内容要看编译器，但是指针已经没有对它的使用权了，但是我实验了一下在不将指针=NULL，此时指针仍保留当初地址的时候，仍然可以访问做指向的区域，两次free也可以运行？？？？？？

大虾就是大虾  厉害  哈哈  你说的那个指针指向了栈中的内存言之有理！！！我想这样写应该就对了：

第一次free和第二次free都没有将开始申请的空间释放掉，因为在堆上申请的空间存放在指针p变量里，但是后来你将栈上空间a赋值给了p，即指针变量p的值被覆盖了。所以，开始申请的空间找不回来，也释放不了，除非退出程序，系统自动释放； free两次没有出错，因为其释放的都不是堆上的空间，上面已有解释； 所以，free没有效果，那么*p是可以正常输出的，因为*p输出的就是变量a的值，a在栈上，生命周期是main函数退出，其周期结束。

第一个问题，free必须释放堆内存使用的，你让p=&a的时候，p指向的那块儿堆内存已经泄露了，再也找不回来了，所以这么写是错的，然后现在p指向的是栈内存了，对栈指针调用free应该有个警告 但不存在释放两次会出错的问题 第二个也是一样，也存在内存泄漏问题，还有就是是堆上的内存，释放以后再引用也是未定义行为，就是结果不可预测，所以不要这么用就对了


Question: 帮忙看看为什么会出现这样的运行结果

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

#include <stdio.h>  int main (void) {     char number[50],rank;     float grade;      printf("输入学号：");     scanf("%s",number);     getchar();   //add getchar() here     printf("输入成绩等级：");     scanf("%c",&rank);     printf("输入入学平均成绩：");     scanf("%f",&grade);     printf("学号=%s\n"             "成绩等级=%c\n"             "入学平均成绩=%f",number,rank,grade);     return 0; } 建议，将rank变量输出，看一下接收了什么数据，然后分析一下； 更深入的了解，可以查一下输入缓存问题

scanf()作单字符输入时规定只接收一个字符，但它却把回车符也作为字符对待，第二个scanf会接收回车符，所以不会让你去输入！ 解决办法：scanf(" %c",&rank);%号前面空一格！ 或者： #include "stdafx.h" #include<stdio.h> int main (void) {     char number[50],rank;     float grade;     printf("输入学号：");     scanf("%s",number); 	fflush(stdin);     printf("输入成绩等级：");     scanf("%c",&rank);     printf("输入入学平均成绩：");	     scanf("%f",&grade);     printf("学号=%s\n"     "成绩等级=%c\n"     "入学平均成绩=%f",number,rank,grade);     return 0; }

回忆了一下之前看过的资料，我好像自己明白了。。。


Question: 图片预处理

熟悉MATLAB的调试手法。

老师，您好。我是在MATLAB环境下进行运行，对图像利用中值滤波预处理，但是在帧差时获得效果不佳，我觉得是预处理的问题，请问老师该如何解决

建议楼主先编译链接调试OpenCV自带的相关例子代码。


Question: windows 网络事件  内核事件 WSAWaitForMultipleEvents  WaitForMultipleObjects

《Windows核心编程》


Question: while循环中无执行语句的情况

引用 1 楼 cyfcsd 的回复:s[i++] = t[j++]这一句本身就会将t中的内容复制到s里，然后再去判断，这是写程序的一个小技巧 谢谢了


Question: linux中如何将动态链接库嵌入到可执行程序中一起发布

自己写脚本啊，直接使用LD_LIBRARY_PATH变量添加你的路径，然后将这条信息写入/etc/profile或者/etc/bash.bashrc下，安装时就实调用脚本。

要么全部用静态库； 要么全部用动态库。 不要混用！

I do not why to answer you.

引用 4 楼 luoziluojun 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 luoziluojun 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] 动态库是运行时加载，动态库有自己的加载路径；运行时会从固定路径加载； 即需要把动态库放到固定路径下； 比如linux的/lib/目录下也可以在链接的时候指定运行时动态库位置,有没有办法把动态库包含进可执行文件呢[/quote] 包含到可执行文件里，那就是静态库了。[/quote]并不是静态库,静态库调用之后就不在需要,我的意思是在程序运行的时候还是去调用动态库.只是动态库包含在可执行文件中,比如目标文件为1M 动态库文件为2M, 生成一个3M的可执行文件可以直接运行[/quote] 怕是做不到呀～

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 luoziluojun 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] 动态库是运行时加载，动态库有自己的加载路径；运行时会从固定路径加载； 即需要把动态库放到固定路径下； 比如linux的/lib/目录下也可以在链接的时候指定运行时动态库位置,有没有办法把动态库包含进可执行文件呢[/quote] 包含到可执行文件里，那就是静态库了。[/quote]并不是静态库,静态库调用之后就不在需要,我的意思是在程序运行的时候还是去调用动态库.只是动态库包含在可执行文件中,比如目标文件为1M 动态库文件为2M, 生成一个3M的可执行文件可以直接运行

引用 2 楼 luoziluojun 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 动态库是运行时加载，动态库有自己的加载路径；运行时会从固定路径加载； 即需要把动态库放到固定路径下； 比如linux的/lib/目录下也可以在链接的时候指定运行时动态库位置,有没有办法把动态库包含进可执行文件呢[/quote] 包含到可执行文件里，那就是静态库了。

引用 1 楼 cfjtaishan 的回复:动态库是运行时加载，动态库有自己的加载路径；运行时会从固定路径加载； 即需要把动态库放到固定路径下； 比如linux的/lib/目录下也可以在链接的时候指定运行时动态库位置,有没有办法把动态库包含进可执行文件呢


Question: 为什么我用MATLAB和C语言计算图像信噪比PSRN结果不一样

有人说是数据类型的问题。我测试图片为bmp格式的。

你把中间的变量都输出一下，对比对比不就知道了吗


Question: 帮我看下这个程序

引用 4 楼 pupilkk 的回复:[quote=引用 3楼自信男孩 的回复:]建议你把ptr和food的地址打印出来，在while之前；如下形式： printf("ptr = %p, food = %p\n", ptr, food); 另外，建议对于这样的问题，验证性的，自己敲一下，编译运行一下～然后再去分析结果；对于库函数或者系统函数，去分析其用法和返回值。把地址看成一个整型，比较它们的前后关系吗[/quote] 对于32位的CPU，地址是unsigned int类型的，地址是可以比较的，因为其都大小，相对于0地址的偏移不同；

引用 3楼自信男孩 的回复:建议你把ptr和food的地址打印出来，在while之前；如下形式： printf("ptr = %p, food = %p\n", ptr, food); 另外，建议对于这样的问题，验证性的，自己敲一下，编译运行一下～然后再去分析结果；对于库函数或者系统函数，去分析其用法和返回值。把地址看成一个整型，比较它们的前后关系吗

strlen函数有统计的长度是忽略了'\0'字符的长度的，比如存这个字符串“CHINA”进去实际上存的占了6个字节，而strlen函数统计会忽略‘\0’，所以是长度是5  第二个问题则是运算符运算的优先级问题，按照--ptr >= food ，实际是这样计算（--ptr）>=food，先括号在外面，这里具体就是ptr先自减1然后在拿ptr和food比较

连打字也懒得动的懒癌患者建议趁早改行。


Question: C语言中可以调用C++编写的动态库吗（DLL），如果可以，应该如何操作？谢谢各位大神了！

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！


Question: bitblt画图，怎样擦除上一次画的图

擦除上一次的内容  就是把上一次的内容，还原成上上一次的内容，  所以，如果有缓存上上一次的内容，则直接替换就可以  如果没有缓存，则需要重画一遍：  比如你画了一条直线，白色的，a到b，而画之前a-b之间是红色的，  你想擦除这条直线，  就是在a-b之间，用红色，再画一遍

dc = BeginPaint(hwnd, &ps);  dc2 = CreateCompatibleDC(dc); SelectObject(dc2, hbmp[14]); GetObject(hbmp[14], sizeof(BITMAP), &bit); //x = 0; //y = 6; po.x = (43 + (x * 69)); po.y = (41 + (y * 69));  //  wsprintf(str, TEXT("x:%d  y:%d"), po.x, po.y); //	MessageBox(NULL, str, TEXT("1"), 0); kuang(dc2, po); if (j == 0) { MoveToEx(dc2, 0, 0, NULL); LineTo(dc2, 100, 100); j++; } BitBlt(dc, 0, 0, bit.bmWidth, bit.bmHeight, dc2, 0, 0, SRCCOPY);


Question: 老是显示停止工作

#include<stdio.h> #include<malloc.h> #include<string.h>  typedef struct integ {     int data;     struct integ *prior;     struct integ *pnext; }stu, *pstu;  pstu create() {     struct integ *phead, *ptail, *pnew;     int i, n, a;      phead = (pstu)malloc(sizeof(stu));     ptail = phead;     phead->pnext = NULL; /* should init head's next node.*/     ptail->prior = phead;      printf("输入节点个数：\n");     scanf("%d",&n);      for (i = 0; i < n; i++) {         printf("第%d个节点的数值：",i+1);         scanf("%d", &a);          pnew = (pstu)malloc(sizeof(stu));         pnew->data = a;         pnew->pnext = NULL;         pnew->prior = ptail;         ptail->pnext = pnew;         ptail = pnew;     }     return phead; }  void show(stu *phead) {     pstu p = phead->pnext;     while (p) {         printf("%d ", p->data);         p = p->pnext;     }     printf("\n"); }    pstu search(stu *h, int c) {     stu *p;      p = h->pnext;     //y = p->data; /* type conflict */      while (p) {         if (p->data == c)             return p;           p = p->pnext;     }     printf("没有找到相同的数据\n");     return NULL;    /* if can't find it, then return NULL */ }  void del(stu *p) {     if (!p)    /* if not existed, then return */         return;      pstu a, b;     a = p->prior;     b = p->pnext;     a->pnext = b;     if (b)    /* if p is last node, b is NULL */         b->prior = a;     free(p); }  void destroy_dlink(pstu head) {     pstu p = head, q;      while (p) {         q = p->pnext;         free(p);         p = q;     } }  int main() {     int a;     pstu q;      pstu phead = NULL;     phead = create();     show(phead);      printf("请输入需要删除的数字\n");     scanf("%d",&a);     q = search(phead, a);      del(q);     show(phead);     destroy_dlink(phead);     return 0; } 改了几处我感觉不合适或者有问题的地方，修改的地方都加了注释； 建议几点：1）既然使用了typedef，建议就使用typedef之后的名字；2）注意代码风格； 另外，加了一个释放整个链表的函数。

要学会自己调试程序  修改两个函数，修改后代码为  pstu search(stu *h, int c){     pstu p = h->pnext;     while (p != NULL){         if (p->data - c == 0){             return p;         }         else{             p = p->pnext;         }     }     printf("没有找到相同的数据\n");      return NULL; } void del(stu *p){     if (!p)         return;      stu *a, *b;     a = p->prior;     b = p->pnext;      a->pnext = b;     if (b) //b删除元素的下一个元素，判断是否存在         b->prior = a;          free(p); }


Question: 大神帮忙看看一看是哪里的问题~

引用 2 楼 Billd_ 的回复:引用 1 楼 cyfcsd 的回复:你是要干什么求出100~200之间的素数 把k的定义移到第一个for循环里面，要不它一直在加，还有你可以看看别人求素数的程序，可以有很多优化的 如有问题欢迎继续追问，没问题请及时结贴，谢谢

#include<stdio.h> #include <stdlib.h>  void main() {     int i, n = 0, j, k = 0;      printf("100~200间所有素数为：\n");     for (j = 100;j <= 200;j++)     {         for (i = 2; i <= j - 1; i++)         {             if (j%i==0)                 k = k + 1;         }         if (k == 0)         {             printf("%d ", j);             n = n + 1;         }         if (n % 10 == 0)             printf("\n");         k = 0;    /* reinit 0*/     }     system("pause"); }  k没有重新初始化为0，建议把k变量改成flag，这样代码可读性会加1分。

引用 1 楼 cyfcsd 的回复:你是要干什么求出100~200之间的素数

你是要干什么


Question: 在图的邻接表中查找指定节点

你说的第y个是从0开始还是从1开始，要是从1开始那就改为j<y-1，要是从0开始就是你的邻接表没有建好

不行，还是一样中断了

j <= y改成j<y试试


Question: 程序的一部分

执行的时候  you received 105.90 105.900000 11.000000 说明函数返回时w值变了不知道怎么回事

什么问题？

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


Question: 环状序列（UVa1584）  刘汝佳《算法竞赛入门经典2》p52，为什么要设置变量T？

引用 4 楼 csdn_mr_l 的回复:引用 3 楼 cfjtaishan 的回复:T是执行次数，就是处理几个字符串；可以将main函数改成下面的形式，另外加上一条退出条件判断就好～也就是说和输入输出格式有关吧，谢谢了。 没关系，和退出的方式有关系；比如T输入的数据是3，那么你输入三个字符串之后，会自动退出循环；

引用 1 楼 user-2 的回复:里面应该描述了输入是啥格式的。  你们这两个哪个能正确读入输入呢？两种方法读的东西是不一样的。你的意思是这与输入格式有关？我没找到这个例题的输入输出格式，新手见谅


Question: 帮忙看看是哪里有问题

仅供参考：#include <afxdisp.h> #include <stdio.h> #include <stdlib.h> int main(int argc, TCHAR* argv[]) {     COleDateTime t;     COleDateTimeSpan ts;     CString s,fmt;     int nYear;     int nMonth;     int nDay;     int nHour;     int nMin;     int nSec;     int lDays;     int nHours;     int nMins;     int nSecs;     int i,N;     // initialize MFC and print and error on failure     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {         printf("Fatal Error: MFC initialization failed\n");         return 1;     }     if (argc<13) {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 2;     }     if (stricmp(argv[12],"SQL")==0) fmt="%Y-%m-%d %H:%M:%S";     else if (stricmp(argv[12],"YYYY")==0) fmt="%Y%m%d %H%M%S";     else if (stricmp(argv[12],"YY")==0) fmt="%y%m%d %H%M%S";     else {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 3;     }     nYear =atoi(argv[ 1]);     nMonth=atoi(argv[ 2]);     nDay  =atoi(argv[ 3]);     nHour =atoi(argv[ 4]);     nMin  =atoi(argv[ 5]);     nSec  =atoi(argv[ 6]);     lDays =atoi(argv[ 7]);     nHours=atoi(argv[ 8]);     nMins =atoi(argv[ 9]);     nSecs =atoi(argv[10]);     N     =atoi(argv[11]);     if (N<=0) {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 4;     }     t=COleDateTime( nYear, nMonth, nDay, nHour, nMin, nSec);     ts=COleDateTimeSpan( lDays, nHours, nMins, nSecs );     for (i=1;i<=N;i++) {         s=t.Format(fmt);         printf("%08d %s\n",i,s);         t=t+ts;     }     return 0; }

重新看了下  知道问题在哪了  date_judge(b).day 这里错误，书上的公式没给正确  导致n_value计算出的数据不对。  谢谢热心的各位

抱歉 忘记说了  这是计算两个日期间的天数  但是我输入2004 8 8  和2005 2 22后 所计算出来的天数不对

不清楚问题是什么

都不知道你要干什么，你的代码能过编译器，哪里知道你的问题出在哪里呢？ 难道因为我是新手？大神都能看懂？有潜规则？


Question: 文件指针

#include<stdio.h> #include<stdlib.h>   int main(int argc,char *argv[]) {     char in[10];     FILE *pf1,*pf2;       printf("enter in file:");     if((pf1=fopen(argv[1],"rb"))==NULL) /*去掉""*/     {         printf("cant open %s",argv[1]);         exit(1);     }     fgets(in,10,pf1);     if((pf2=fopen(argv[2],"wb"))==NULL) /*去掉""*/     {         printf("cant open %s",argv[2]);         exit(1);     }     fputs(in,pf2);     return 0; } argv[1]和argv[2]本身就是字符串指针，所以不需要再加双引号，并且，即使不是字符串指针，加了双引号也不会称为字符串。

路径不对，试试用绝对路径

我已经找到错误啦 pf1=fopen("argv[1]","rb")  argv[1]不应该用双引号引起来。


Question: 嵌入式系统内存分配的若干问题

代码烧录在ROM里没错，但是程序运行时，是不是需要加载到RAM里面才能运行呀？没听说过直接在ROM里面跑程序的

代码可以烧到ROM中，变量才需要RAM

感谢大侠的解答。关于1-3点的解答和我设想的是一致的。 关于第四点：深入一点讨论，在最初的内存规划时，系统应该是设定了几块固定好的区域分别用来作为存储代码段、静态和全局变量段、堆栈段的。而系统在上电运行时，代码必须拷贝到内存中并且使指针指向代码的第一条指令，程序才可以正确运行。 如果是被注释的代码，有可能由于链接的关系，最终不会被放入内存，这个没问题。但是...真正要运行的代码段毫无疑问是要放入内存的，所以，严格意义上来说，精简代码，然后手动缩小代码空间，是可以节约运行时内存的，当然了，这是我想当然，仅仅是推断，我自己没有这么做过。 恳请各位有经验的人士来不吝赐教。

1. 程序能够编译通过并正常运行的情况下，（尤其是大的数组赋值时）为什么会篡改其他的全局变量？ 答：应该是嵌入式的内存不足，申请大的空间，导致变量空间重叠； 2. 程序能够通过编译，运行时为什么会触发写到ROM的保护？ 答：编译通过，只是用来检查语法，简单的逻辑问题，不会检查申请空间过大的问题，编译器也不会去做这些事情； 3. 被注释掉的代码会占用系统运行时内存吗？（考虑后续开发的兼容性，代码段比较大，有许多扩展模式） 答：被注释掉的代码，在编译时就不会进入目标文件和可执行程序里，所以也不会占用内存； 4. 节省代码段的长度可以提高内存使用率吗？ 答：代码段长度与内存使用率没关系，建议申请大内存时，要小心，根据需要来，如果数据用不了那么大的空间，反而会降低内存使用率； 嵌入式对内存的使用是宝贵的，所以在定义数据结构时就应该注意

按自己的理解答复下，请参考： 1. 程序能够编译通过并正常运行的情况下，（尤其是大的数组赋值时）为什么会篡改其他的全局变量？ ——数组应该是全局的，可能是数组越界，检查下下标 2. 程序能够通过编译，运行时为什么会触发写到ROM的保护？ ——运行和编译没关系，触发到写rom保护可能是使用了非法指针（指向保护内存） 3. 被注释掉的代码会占用系统运行时内存吗？（考虑后续开发的兼容性，代码段比较大，有许多扩展模式） ——注释掉无影响 4. 节省代码段的长度可以提高内存使用率吗？ ——不可以，或者说意义非常有限，程序使用的内存与其大小无关（不考虑程序本身占用的内存）


Question: C#里的“~”键如何检测被按下！求指教！

好吧，新来的不懂

请移驾C#论坛。


Question: 0x775598C1 (ntdll.dll) (ConsoleApplication4.exe 中)处有未经处理的异常: 0xC0000374: 堆已损坏。 (

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

下断点跟吧 堆已损坏大多是由于越界操作引起的


Question: 循环问题？

引用 8 楼 w1610scanf 的回复:[quote=引用 7 楼 lilimite 的回复:] scanf(" %c",&a);还可以在%前面加一个空格 这是什么原理？[/quote] 变量类型的问题，char型是一个字节的，每次输入之后敲的回车ASCII码会缓存，下次scanf的时候就输入回车键了，加个空格就相当于是回车了。

引用 7 楼 lilimite 的回复:scanf(" %c",&a);还可以在%前面加一个空格 这是什么原理？

scanf("%c",&a);前面增加fflush(stdin);清空缓冲区，程序就没问题了，如下：  #include "stdafx.h"  #include<stdlib.h> #include<stdio.h> #include<math.h>  int main() { //下面进行简单的加减乘除算法。 while(1) {  printf("请输入你要进行的算法，加法请输入+，减法请输入-，乘法请输入*，除法请输入/\n"); char a; int b,c,d;     fflush(stdin);     scanf("%c",&a); 	 switch(a)    { case('+'):printf("请输入要相加的两个整数\n"); scanf("%d %d",&b,&c); d=b+c; printf("%d+%d=%d\n",b,c,d); break;  case('-'):printf("请输入要相减的两个整数\n"); scanf("%d %d",&b,&c); d=b-c; printf("%d-%d=%d\n",b,c,d); break;  case('*'):printf("请输入要相乘的两个整数\n"); scanf("%d %d",&b,&c); d=b*c; printf("%d*%d=%d\n",b,c,d); break;  case('/'):printf("请输入要相除的两个整数\n"); scanf("%d %d",&b,&c); d=b/c; printf("%d/%d=%d\n",b,c,d); break;  case('\r'):printf("\n");  default:printf("我只会加减乘除啊，不要难为小学生\n"); break; } }   }

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

scanf(" %c",&a);还可以在%前面加一个空格

请参考以下文章  使用Qt和Interpreter设计模式开发计算器（附源码）

那请问一下，如何做到像计算器那样，可以不限计算的个数呢？

#include<stdio.h> #include<math.h>  int main() {     //下面进行简单的加减乘除算法。     while(1)     {          printf("请输入你要进行的算法，加法请输入+，减法请输入-，乘法请输入*，除法请输入/\n");         char a;         int b,c,d;         scanf("%c", &a);         switch(a)         {             case('+'):                 printf("请输入要相加的两个整数\n");                 scanf("%d %d",&b,&c);                 d=b+c;                 printf("%d+%d=%d\n",b,c,d);                 break;              case('-'):                 printf("请输入要相减的两个整数\n");                 scanf("%d %d",&b,&c);                 d=b-c;                 printf("%d-%d=%d\n",b,c,d);                 break;              case('*'):                 printf("请输入要相乘的两个整数\n");                 scanf("%d %d",&b,&c);                 d=b*c;                 printf("%d*%d=%d\n",b,c,d);                 break;              case('/'):                 printf("请输入要相除的两个整数\n");                 scanf("%d %d",&b,&c);                 d=b/c;                 printf("%d/%d=%d\n",b,c,d);                 break;              case('\r'):                 printf("\n");                 break;              default:                 printf("我只会加减乘除啊，不要难为小学生\n");                 break;         }         getchar();    /*add to  recv '\n' (linux)*/     }  }  加一句getchar(); 原因是输入整数之后会有回车留在输入缓冲区里

scanf("%c",&a);  改为：   while((a=getchar()) == '\n'){  }


Question: 求助帖,求看看是哪个位置问题

引用 2 楼 paschen 的回复:scanf("%d\n", &sec); 去掉后面的\n  否则它是不会立即显示的，要等再接收到一个非（空格、制表符、回车）的输入scanf语句才结束 感谢了

引用 1 楼 jianwen0529 的回复:把两个地方的 scanf("%d\n", &sec); 修改为 scanf("%d", &sec);  感谢了


Question: 求大佬帮忙，我实在看不出来，Dev C++   VC6.0    Code Blocks

引用 3 楼 cfjtaishan 的回复:主要是两点： 1. 在C语言里变量和函数都是遵循先声明后使用的原则；如果函数定义在main之前，则不需声明； 2. 声明时，也要注意，不建议声明在main函数里，这种声明陋习建议改掉；同时，声明时需要带上参数的类型，对于参数的名字可以不写； 注意一下代码风格。代码逻辑方面的问题也一并修改了，请查阅上面的代码。万分感谢，膜拜工程师们

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

引用 4 楼 cfjtaishan 的回复:这个不需要清回车，它不会影响后面的输入；  感谢指正。

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

引用 1 楼 jianwen0529 的回复: int main(){     //struct student *create();     //struct student *pdelete();     //void pint();     struct student *create(int n);     struct student *pdelete(struct student *head, int grade);     void print(struct student *head);    // 其他代码 }  for (i = 1; i < n; i++){         pnew = (struct student *)malloc(sizeof(struct student));         //scanf("%s %f ", pnew->name, &pnew->score);         scanf("%s %f", pnew->name, &pnew->score); //%f后面不要空格         fflush(stdin);//刷新下，把输入时候的回车键给清除掉          ptail->next = pnew;         ptail = pnew;     }  这个不需要清回车，它不会影响后面的输入；

#include <stdio.h> #include <stdlib.h>  struct student {     char name [10];     float score ;     struct student *next ; };  /* Function statement */ struct student *create (int n ); void print (struct student *head ); struct student *pdelete(struct student *head, int grade);  int main () {     struct student *head;     int n;     printf("Input the number of nodes:\n");     scanf("%d", &n);     head = create(n);     printf("Output all nodes:\n");     print(head);      head = pdelete(head, 60);     printf("Output fail-nodes:\n");     print(head);      return 0; }  struct student *create (int n) {     struct student  *head,*pnew ,*ptail;;     int i ;     pnew =(struct student *) malloc (sizeof (struct student ));     scanf ("%s%f",pnew ->name ,&pnew ->score);     head = ptail = pnew;     for (i=1;i<n;i++){         pnew =(struct student *)malloc (sizeof (struct student ));         scanf ("%s%f",pnew->name ,&pnew ->score);         ptail ->next =pnew ;         ptail =pnew ;     }     ptail ->next =NULL;     return head; }  void print (struct student *head ) {     struct student *p=head ;     while (p!=NULL){         printf ("%s %.1f\n", p->name, p->score);         p=p->next;     } }  struct student *pdelete(struct student *head, int grade) {     struct student *p,*pold;      if (!head) {         fprintf(stderr, "Link is empty!\n");         return NULL;     }     while (head && head->score >= grade) {         p = head;         head = head->next;         free(p);     }     if (!head) {         fprintf(stderr, "Link is empty!\n");         return NULL;     }     pold = head;     p = head->next;     while (p){         if (p->score >= grade){             pold->next = p->next;             free(p);             p = pold->next;         } else {             p = p->next;             pold = pold->next;         }     }      return head; }     以上是第一个程序修改的结果，建议你注意下代码风格。


Question: 关于aqrt()函数

printf("%d\n",(int)sqrt(i));//这样结果不正确  sqrt返回的是double，double跟%d不匹配的


Question: main函数的参数

int main(int argc, char* argv[]) { 	for (int i = 0; i < argc; i++) 	{ 		std::cout << argv[i] << std::endl; 	}  	return 0; }   生成一个1.exe  在控制台执行1.exe  如下图

#include <stdio.h>  int main(int argc, char *argv[]) {     int i;      for (i = 0; i < argc; i++)         puts(argv[1]);     return 0; } 把上面的程序编译一下，生成一个可执行程序，比如a.out; 然后如下执行（在终端上执行）./a.out hello world,然后看一下输出结果。

首先，你的参数列表写错了，应该是 int argc, char *argv[]   传进来的参数都是char*类型 那么你就需要根据char*转换成你需要的类型，诸如int double等 参考 atoi atof 等函数  argv[0] 保存的是执行程序的路径，所以参数是从argv[1]开始的   #include <stdio.h> #include <stdlib.h> // 执行程序的时候，附加一个int类型的参数，那么程序会打印改值 int main(int argc, char *argv[]) {     int n = 0;     if (argc > 1)     {         n = atoi(argv[1]);     }      printf("%d", n);     return 0; }


Question: 为什么a[3] 等价于 *(a+3)     a不是第一个数组的地址吗，怎么能直接加3？

Pointer Arithmetic Additive operations involving a pointer and an integer give meaningful results only if the pointer operand addresses an array member and the integer value produces an offset within the bounds of the same array. When the integer value is converted to an address offset, the compiler assumes that only memory positions of the same size lie between the original address and the address plus the offset.  This assumption is valid for array members. By definition, an array is a series of values of the same type; its elements reside in contiguous memory locations. However, storage for any types except array elements is not guaranteed to be filled by the same type of identifiers. That is, blanks can appear between memory positions, even positions of the same type. Therefore, the results of adding to or subtracting from the addresses of any values but array elements are undefined.  Similarly, when two pointer values are subtracted, the conversion assumes that only values of the same type, with no blanks, lie between the addresses given by the operands.

这里a+3表示的是地址向后移了3个

这个甲鱼的臀部——规定，一个地址值加减一个数表示移动到相应个数的位置，具体位置视你指向的对象的类型

不是地址加了3，而是地址偏移了sizeof(a[0])个字节。数组名a是数组的首地址，a[3]是指从首地址向后偏移3  * sizeof(a[0])个字节的地址里取出其中的数值。*(a+3)也是这个意思，只是后一种表达的更形象。 另，若a是int类型数据，基于a向后偏移了：3 * sizeof(int)

楼主你要理解一下数据类型的概念，数据都是有类型的，一个int变量和一个double变量都加3，虽然效果看起来都是多了3，但里面的二进制变化规则是不同的，所以运算符的运算过程要根据它作用的数据类型来决定 当一个指针类型的变量加上一个整数n时，它实际加的是n*siezof(指针所指对象的类型)

A[B] *(A+B) *(B+A) B[A] //以上四行等价  "abc"[1] *("abc"+1) *(1+"abc") 1["abc"] //以上四行等价  A[0] *(A) 0[A] //以上三行等价

引用a不是第一个数组的地址吗 你并没有告诉我们 a 是啊 ...  ========================== 指针可以和整数做加减法。建议去看一下书。

楼主这个问题还是看书比较清楚，参考以下任一本相关章节： 《深入理解C指针》 《C语言点滴》 C和指针

地址 +- 一个整数，得出来的还是地址 表示移动了几步，步长是该指针的基本类型的大小  int p[10]; (a+3) == a[3] == a的地址值 + 3 * sizeof(int)


Question: 关于调用函数求数组和和平均数的问题（内含指针）

引用 4 楼 qq_37120435 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] #include <stdio.h>   #define MAX_LEN 3 void avg_sum(double a[],int n,double *avg,double *sum);  int main() {     double a[MAX_LEN], av, su;     int i;      for (i = 0; i < MAX_LEN; i++)         scanf("%lf", &a[i]);      avg_sum(a, MAX_LEN, &av, &su);      printf("ave = %.2lf, sum = %.2lf\n", av, su);      return 0; } void avg_sum(double a[], int n, double *avg,double *sum) {     int i;     *sum = 0.0;      for(i = 0; i < n; i++)         *sum += a[i];     *avg = *sum/n; } 第一点，C语言不支持可变数组，n是一个随机值，可能是很大导致数组申请的超过栈的大小（猜的）； 第二点，double使用%lf格式输入，因为%lf与%f大小不一样，你可以试一下，用%f格式输入（较小的值），最后的结果都是0.000，因为输入的数据都变成了double的小数部分，但是输出时一般都是输出小数点后6位，输入的数值又小，不到输出的精度，所以都是0了。 那么怎么样才能输入可变数组呢？我也不知道会输入多少个，没办法给n一个准确的值[/quote] C语言不支持，所以没办法，但是可以通过malloc，每次你要求多少个即n是多少就可以申请相应的空间。

引用 3 楼 cfjtaishan 的回复:#include <stdio.h>   #define MAX_LEN 3 void avg_sum(double a[],int n,double *avg,double *sum);  int main() {     double a[MAX_LEN], av, su;     int i;      for (i = 0; i < MAX_LEN; i++)         scanf("%lf", &a[i]);      avg_sum(a, MAX_LEN, &av, &su);      printf("ave = %.2lf, sum = %.2lf\n", av, su);      return 0; } void avg_sum(double a[], int n, double *avg,double *sum) {     int i;     *sum = 0.0;      for(i = 0; i < n; i++)         *sum += a[i];     *avg = *sum/n; } 第一点，C语言不支持可变数组，n是一个随机值，可能是很大导致数组申请的超过栈的大小（猜的）； 第二点，double使用%lf格式输入，因为%lf与%f大小不一样，你可以试一下，用%f格式输入（较小的值），最后的结果都是0.000，因为输入的数据都变成了double的小数部分，但是输出时一般都是输出小数点后6位，输入的数值又小，不到输出的精度，所以都是0了。 那么怎么样才能输入可变数组呢？我也不知道会输入多少个，没办法给n一个准确的值

定义a[n]的时候，n为随机值吧

scanf("%lf",&a[i]); // double类型使用 %lf 格式


Question: IntelliSense:  无法打开 源 文件 "X11/Xlib.h"

在网上查 有人说要用gcc for Win编译 可不知道如何做

需要装这个X11库，却不知道从哪里来

系统好像不带着两个文件

Xlib.h Xutil.h  你要先找到这两个文件，然后放在C++的include路径中，或者include时指定绝对路径

百度搜相关关键字。

这两个头文件不是 linux 系统的嘛？


Question: 斐波那契数列取余问题

余数相加再取余=原数相加取余

[quote=引用 1 楼 自信男孩 的回复:] “如果计算出n之后对10007取余会导致越界，如果对每次的运算都取余10007，就永远不会数值越界；即类似：(1+1+2+3+5+8+13)%10，和1%10+1%10+2%10+3%10+5%10+ 8%10+13%10结果应该是一样的”这个不对，应该是余数相加之后再取余才对，（1%10+1%10+2%10+3%10+5%10+ 8%10+13%10）%10才对

如果计算出n之后对10007取余会导致越界，如果对每次的运算都取余10007，就永远不会数值越界；即类似：(1+1+2+3+5+8+13)%10，和1%10+1%10+2%10+3%10+5%10+ 8%10+13%10结果应该是一样的。所以，可以如下实现吧： #include <stdio.h>  #define     KEY     10007  int main(void) {     int n, tmp, reminder;     int i;     int last = 1 % KEY;     int sum = 2 % KEY;      scanf("%d", &n);     if (n == 1 || n == 2) {         printf("1\n");     } else if (n == 3) {         printf("2\n");     } else {         for (i = 3; i < n; ++i)         {             tmp = sum % KEY;             sum = (sum + last) % KEY;             last = tmp % KEY;         }         printf("循环求出斐波那契序列值:%d\n", sum);     }     reminder = sum % KEY;     printf("reminder = %d\n", reminder);     return 0; } 有问题可以继续沟通～


Question: 哪位大神看下我这个问题怎么解决

thank you，我忽略了最重要的问题

main函数的名称写错了 main不是mian（面）