Question: 关于在单链表中查找元素的位置的问题

多谢各位指点

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

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

知道为什么了  C语言不能比较两个结构体

我的意思是为什么会这么报错啊？我不太懂要怎么改……

报错信息都给了你还想问什么. 书上写的只是伪代码吧..或者只是示意.要根据实际情况修改.

memcmp

提示说的很清楚了，结构体不能直接==比较，除非你重载过，你可以写一个比较的函数，自己去进行比较


Question: 两个头文件 和一个.c 文件 加在一个.c文件（main2-2）中 出现很多问题

c1.h部分 我输入复制错了 是下面的  /* c1.h (程序名) */  #include<string.h>  #include<ctype.h>  #include<malloc.h> /* malloc()等 */  #include<limits.h> /* INT_MAX等 */  #include<stdio.h> /* EOF(=^Z或F6),NULL */  #include<stdlib.h> /* atoi() */  #include<io.h> /* eof() */  #include<math.h> /* floor(),ceil(),abs() */  #include<process.h> /* exit() */  /* 函数结果状态代码 */  #define TRUE 1  #define FALSE 0  #define OK 1  #define ERROR 0  #define INFEASIBLE -1  /* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */  typedef int Status; /* Status是函数的类型,其值是函数结果状态代码，如OK等 */  typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */


Question: loop和坐标： 各位大神，帮帮忙！小弟感激不尽！！谢谢。

if (sqrt((x-(-2.0))*(x-(-2.0))+(y-1.0)*(y-1.0))<10e-5) break;//A坐标(-2.000000, 1.000000),当（x，y）和A坐标相差距离是10^-5 的时候停止loop


Question: c语言矩阵相乘在二维数组传入参数时遇到了一些问题

多谢，看来需要再补下基础啦

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

二维数组传参： http://www.cnblogs.com/wuyuegb2312/archive/2013/06/14/3135277.html

引用 4 楼 qq_29027865 的回复://备忘录递归  #include <stdio.h>    const int L = 7;   int LookupChain(int i,int j,int **m,int **s,int *p);   int MemoizedMatrixChain(int n,int **m,int **s,int *p);      void Traceback(int i,int j,int **s);//构造最优解      int main()   {       int p[L]={30,35,15,5,10,20,25};          int **s = new int *[L];       int **m = new int *[L];       for(int i=0;i<L;i++)         {             s[i] = new int[L];           m[i] = new int[L];       }        printf("矩阵的最少计算次数为:%d\n",MemoizedMatrixChain(6,m,s,p));   	printf("矩阵最优计算次序为:\n"); 	Traceback(1,6,s);       return 0;   }    //矩阵初始化操作   int MemoizedMatrixChain(int n,int **m,int **s,int *p)   {       for(int i=1; i<=n; i++)       {           for(int j=1; j<=n; j++)           {               m[i][j]=0;           }       }       return LookupChain(1,n,m,s,p);   }    //m数组内存放矩阵链的行列信息   //m[i-1]和m[i]分别为第i个矩阵的行和列（i = 1、2、3...） int LookupChain(int i,int j,int **m,int **s,int *p)   {       if(m[i][j]>0)       {           return m[i][j];       }       if(i==j)       {           return 0;       }       int u = LookupChain(i,i,m,s,p) + LookupChain(i+1,j,m,s,p)+p[i-1]*p[i]*p[j];       s[i][j]=i;       for(int k=i+1; k<j; k++)       {           int t = LookupChain(i,k,m,s,p) + LookupChain(k+1,j,m,s,p) + p[i-1]*p[k]*p[j];           if(t<u)           {               u=t;               s[i][j] = k;           }       }       m[i][j] = u;       return u;   }      void Traceback(int i,int j,int **s)   {       if(i==j) return;       Traceback(i,s[i][j],s);       Traceback(s[i][j]+1,j,s);       printf("Multiply A %d,%d\n",i,s[i][j]); 	printf("and A %d,%d\n",(s[i][j]+1),j);   }   在这里代码中为什么用**s就行了呢,请大神帮助下  多看基础，**s是一个二级指针，你声明的是动态的二维数组。

另外第一个的计算结果还是没有出来哈

已经解决了,想问一下，**S指的是什么意思呢

void Traceback(int i,int j,int **s)    改成：  void Traceback(int i,int j,int s[100][100])

欢迎大家帮忙调试一下


Question: 关于指针的问题，请大神回答下

引用 5 楼 qq_36140737的回复:定义一个char p试试多少啊？ 哎，忽略上面的回答吧。 我作为一个新手，只是想表达下个人看法。 首先，c语言里面，你随便拿来一个变量p，然后来找这个p里面的地址指向，是不是哪里出了问题？再者，连p自己都不知道自己是哪里的，它怎么来指定一个地址给你？(p是虚拟) 你把p换成a,b,c也一个道理。 当然，我作为个小白。我认为，你可以想出其它的方法来解决你的疑惑。 至于指针这东西嘛，本来就没有指针。只是拿来用于形象的表达。 楼上的系统提示不错，给个赞。

定义一个char p试试多少啊？

引用 2 楼 qq423399099 的回复:windows里常见的内存填充数据含义 * 0xABABABAB : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory * 0xABADCAFE : A startup to this value to initialize all free memory to catch errant pointers * 0xBAADF00D : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory * 0xBADCAB1E : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger * 0xBEEFCACE : Used by Microsoft .NET as a magic number in resource files * 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory * 0xCDCDCDCD : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory * 0xDEADDEAD : A Microsoft Windows STOP Error code used when the user manually initiates the crash * 0xFDFDFDFD : Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory * 0xFEEEFEEE : Used by Microsoft's HeapFree() to mark freed heap memory  其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

只要知道这个地址不可用就行了，研究具体值没有意义

*p未被初始化，其存储的值是随机值。在定义指针变量后，系统分配的只是指针本身的.内存(指针)，并没未分配存储数据的内存(指针的值)。就好比，上面说的，定义一个变量，变量单元未定义值前可能有随机值(垃圾值)，在被赋值以后才会记录赋予的值。(我是小白，我找的答案。)

int p[5]; 	 	printf("%p  %xd",&p,p); 	printf("\n%p   %xd",&p[1],p[1]);

试试这个，虽然，不知道能不能帮你。

存放之前栈上留下的值  VC在调试时会将未初始的栈内存用0xcc填充，未初始的堆内存用0xcd填充   这些都是无意义的值，就是为了方便你调试的，实际上如果工具不给你初始化，就是一个随机值


Question: 求大牛指教

你判断if(i>=6){  但你的i并不是输入字符串的长度，而是循环后的值（20）  你应该用strlen得到输入的长度   #include<stdio.h> void main(){ 	char c[20]; 	int i; 	int a,b,h,d; 	int len; 	a=0; 	b=0; 	h=0; 	d=0; 	scanf("%s",c); 	len = strlen(c); 	for(i=0;i<len;i++){ 		if((c[i]>'A'&&c[i]<'Z')||c[i]<'0'||(c[i]>'9'&&c[i]<'A')||(c[i]>'Z'&&c[i]<'a')||c[i]>'z') 			a=1; 		if(c[i]>='0'&&c[i]<='9') 			d=1; 		if(c[i]>='A'&&c[i]<='Z') 			b=1; 		if(c[i]>='a'&&c[i]<='z') 			h=1; 		if(c[i]=='\0') 			break; 	} 	if(len>=6){ 		if(a==1&&b==1&&h==1&&d==1) 			printf("very strong"); 		else 			if(a==0&&b==1&&h==1&&d==1) 				printf("strong"); 			else 				if(a==0&&b==0&&h==1&&d==1) 					printf("normal"); 				else 					if(a==0&&b==0&&h==0&&d==1) 						printf("weak"); 	} 	if(len<6) 		printf("wrong"); }


Question: vc6.0编写2016日历，只用for与while，无报错，无法正常运行。

要分清函数调用和函数声明

#include<stdio.h> #define K 7 void months(int month); int main() { 	int point,p; 	printf("这是2016年的日历，请输入月份：");  	p = scanf("%d",&point); 	while((p+(point<1)+(point>12)) == 1){ 		printf("周一\t周二\t周三\t周四\t周五\t周六\t周日\n"); 		months(point); 		p = scanf("%d",&point); 	}  	return 0; } //---------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------- void months(int month) { 	int n; 	// 	int day = 31; 	int x2,x4,x6,x9,x11; 	// 	int kong=4; 	int a,b; 	// 	//表格赋值 	int i,date[42],term; 	for(i=0;i<42;i++) 		date[i]=i+1; 	//ok 	// //以下是 天数 对应各月----------------------------------------------------------------------------------------------- 	for(x9=(month==9),x4=(month==4),x6=(month==6),x11=(month==11),n=x4+x6+x9+x11;n != 0;n=0) 		day = 30; 	for(x2=month;x2==2;x2++) 		day = 29;     //ok     // //以下是 空位数 对应各月,,fuck busy !   ---------------------------------------------------------------------------------- 	for(a=(month==2),b=(month==8);a+b == 1;a++) 		kong=0; 	for(a=(month==9),b=(month==12);a+b == 1;a++) 		kong=3; 	for(a=(month==11),b=(month==3);a+b == 1;a++) 		kong=1; 	for(a=(month==6);a == 1;a++) 		kong=2; 	for(a=(month==10);a == 1;a++) 		kong=5; 	for(a=(month==5);a == 1;a++) 		kong=6; 	//ok 	// //下面打印正二八经的月表格--------------------------------------------------------------------------------------------------- 	for(i=0;i<kong;i++) 		printf("\t"); 	for(i=0,term=K-kong-1;i<day;i++,term--){ 		printf("%d\t",date[i]); 		while(term==0){ 			printf("\n"); 			term=K;} 	} 	printf("\n\n时光荏苒，好好珍惜！\n\n\n\n退出按q"); //okZ // } 谢谢啦！ 终于好了

main函数中：  void months(month);  改成  months(month);


Question: linux下如何用C语言编程判断某端口是否被占用

引用 4 楼 qq_15311337 的回复:谢谢各位，已解决。 咋解决 的啊？

bool srvPortIsUsed(int port) {     std::strstream srm;     srm << "lsof -i :" << port << " >netstat.txt";     system(srm.str());     std::ifstream in("netstat.txt");     std::string line;     std::getline(in,line);     std::getline(in,line);     if(!line.empty())     {         line.find_first_of(' ');         line = line.substr(line.find_first_of(' ')+1);         line = line.substr(0,line.find_first_of(' '));         std::string sr = "kill -9 " + line;         system(sr.c_str());     }   }

谢谢各位，已解决。

system("netstat -na >netstat.txt"); //然后读文件netstat.txt的内容

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h>  #define MAXLINE 80  int main(void) { 	struct sockaddr_in servaddr; 	int sockfd,i,serverport,ret; 	sockfd = socket(AF_INET, SOCK_STREAM, 0);  	bzero(&servaddr, sizeof(servaddr)); 	servaddr.sin_family = AF_INET; 	inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);         for(i = 0;i < 65535;i++) 	{            servaddr.sin_port = htons(i); 	   ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));            if(EISCONN == ret)            {                  printf("端口 %d被占用",i);            } 	  else            {                close(sockfd);            }         } 	return 0; }

int port = 8888; int fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr); if(bind(fd, (struct sockaddr *)(&addr), sizeof(sockaddr_in)) < 0) {     printf("port %d has been used.\n", port); } close(fd);


Question: 如何从被调函数结束所有流程，但又使程序不退出

引用 9 楼 u010165006 的回复:抛出异常，会调整函数调用栈，到捕获它的主调函数。  抛出异常，可以调整函数调用栈，到捕获它的主调函数（的主调函数）继续运行，如果没有在抛出异常的函数内捕获的话。

抛出异常，会调整函数调用栈，到捕获它的主调函数。

引用 5 楼 mmm325400的回复:@huang19950308 那样的意思就是吧被调用函数直接写到函数中吗。既然把他写成了函数肯定是要多次调用，或者多种情况下都要调用。这样会徒增非常多的重复代码 1.3楼说的都挺不错啊

真的很多层的,而且在底层还需要做一些上层的结束的工作,那只能说明你的程序结构有问题.

仅供参考：#include <iostream> using namespace std; struct MyStruct {     int Nodedata;     MyStruct *pLeft;     MyStruct *pRight; } s1,s2,s3,s4,s5,s6,s7,s8; void ashow(MyStruct * p) {     if (p != nullptr) {         ashow(p->pLeft);         ashow(p->pRight);         cout << p->Nodedata << endl;         if (p->Nodedata == 4) {             throw 1;//退出递归.直接返回.         }     } } int main() {     MyStruct *pRoot;//根      pRoot = &s1;     s1.Nodedata = 1;     s2.Nodedata = 2;     s3.Nodedata = 3;     s4.Nodedata = 4;     s5.Nodedata = 5;     s6.Nodedata = 6;     s7.Nodedata = 7;     s8.Nodedata = 8;      s1.pLeft = &s2;     s1.pRight = &s3;      s2.pLeft = &s4;     s2.pRight = &s5;      s3.pLeft = &s6;     s3.pRight = &s7;     try {         ashow(pRoot);     } catch (int err) {         cout<<"catch err "<<err<<endl;     }     return 0; } //4 //catch err 1 //  再供参考：#include <stdio.h> #include <setjmp.h> jmp_buf mark; int i=0; void c() {     printf( "c in\n");     if (1==i%2) longjmp( mark, i );     printf( "c out\n"); } void b() {     printf( "b in\n");     c();     printf( "b out\n"); } void a() {     printf( "a in\n");     b();     printf( "a out\n"); } void main( void ) {    int jmpret;    jmpret = setjmp( mark );    printf( "Start %d\n",jmpret);    if( jmpret == 0 ) {        printf( "First\n");        a();        i++;        a();    } else {        printf( "Second\n");    } } //Start 0 //First //a in //b in //c in //c out //b out //a out //a in //b in //c in //Start 1 //Second //

switch语句再加一个循环语句就可实现

用一个switch语句就可以实现

能写个简单例子吗？

可以抛出一个异常，然后在希望退到的那个函数里捕获这个异常


Question: 为什么我收到的数据多了那么多FFFFFFFF

#include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; }

我擦嘞，结贴这么快

问题在 %.2x上，点号加2表示打印浮点数，保留小数点后两位，整数部分不限制，这时候来个char数据，如果最高位为1，以浮点数表示，则为负数，就出现了FFFFFFFF的现象

引用 4 楼 user-4 的回复: printf("%02X ", static_cast<unsigned char>(revData[i])); 可以了 谢谢

说明数据的二进制表示都是1，可能是无效数据，或者结束数据

引用 1 楼 user-4 的回复:因为revData[xxx]是cha却被按照%x显示(16进制格式化的int), 先转换成unsigned char 我在显示之前强制类型转换成(unsigned char)  revData[255]试了一下，还是和之前一样  很多FFFFFF


Question: 分享点资源（代码、技术点）

论坛分和下载分可以互换。

赞一下

这个printf结果?，自己顶顶 void test_1() { char idx; u32 n = 0x03020100; char w[8] = "abcdefg";  idx = n; w[++idx] = idx + '0'; w[++idx] = --idx - 1;  printf("%d\n", idx); printf("%c\n", w[idx]); printf("%s\n", w + idx); }

还有个人机对战的五子棋，喜欢的可以看看 http://download.csdn.net/detail/qixing1115/3569086


Question: 中缀表达式转化为后缀表达式

引用 3 楼 xinye1230 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];  这是什么啊？？[/quote] 你错误地使用了scanf("%c",&c);

天下难事必做于易,天下大事必做于细。

引用 5 楼 zhao4zhong1 的回复:[quote=引用 3 楼 xinye1230 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];  这是什么啊？？[/quote] 你错误地使用了scanf("%c",&c);[/quote] 嗯，好的，谢谢，你提醒的对，我找到错误了。我把出栈时返回的值写错了，应该是*e=*--（s->top）而我写成了*--（s->base）.

引用 2 楼 user-2 的回复:Push函数中，如果relloc后，s->top可能已经失效，s->stacksize也会发生变化 我没有看懂你说的，什么意思啊？

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


Question: 关于printf的一些问题

%x的问题吧,它默认本来就是输出32位整数

引用 15 楼 paschen 的回复:%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 14 楼 xgywd 的回复:] [quote=引用 13 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 11 楼 xgywd 的回复:] [quote=引用 7 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0  [/quote]  你会改诉参数是按值传递的，是复制进去的[/quote] 小端字节序 0x12345678在内存中是 78 56 34 12 在内存中的分布是 0xee在007.  0x12345678在008   006         007     008      009    010    011    012     ??         ee        78        56      34      12     ?? 所以想不通啊,%x一下复制过去4字节,那里会有0呢? [/quote]  只复制了一个字节过去，复制时会进行类型转换，正如以下是一样的：  char a = '3'; unsigned b = a;[/quote] 我还没想通,能详细下吗,   引用 15 楼 paschen 的回复:%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 14 楼 xgywd 的回复:] [quote=引用 13 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 11 楼 xgywd 的回复:] [quote=引用 7 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0  [/quote]  你会改诉参数是按值传递的，是复制进去的[/quote] 小端字节序 0x12345678在内存中是 78 56 34 12 在内存中的分布是 0xee在007.  0x12345678在008   006         007     008      009    010    011    012     ??         ee        78        56      34      12     ?? 所以想不通啊,%x一下复制过去4字节,那里会有0呢? [/quote]  只复制了一个字节过去，复制时会进行类型转换，正如以下是一样的：  char a = '3'; unsigned b = a;[/quote] 您说的这个我知道,也理解,对于入栈出栈调用规则我也知道,不定参也写过.但还是不理解,只是因为*(p1+1)与*(p1-1),两个表达式得出来的结果,在类型上并无区别,长度上也无区别,但是被push进堆栈之后,却形成了两个极端,于是我查了一些资料,关于push,发现32位系统的push有两样的形势,一种push 另一种是push bye .用push bye的时候,压入堆栈4个字节数据,除了原来的一字节还把其它位都用F来补齐,而push,却是用0来补齐,难道是因为这种原因,如果能详细解释一下真的是太感谢了

基本上是想通了,原来是有关于类型转换赋值的原因. 在有符号转为无符号类型时.特别是"短有符类型"转为"长无符类型"时. 所有不足的位,都会被其原来所具有的符号位添满. 换句话说,它原来代表符号的位置如果是1,被添满空位的就是1. 如果符号位置是0,被添满空位的就是0; 例如  在这个程序中有符 char i=0xef; 它的符号位是1. 当有一个无符型变量接收它的值时. 这个无符型变量除了数据所占的位.其它位都会被它的符号位补齐.  后来我把0xef定义成无符型, 输出结果是: ef 没有被1补齐,看来这种情况只存在有符与无符转换的时候. 最后,我把有符型的符号位变0.让i=0xf; 输出结果为: f 看来真的如猜测一样

引用 19 楼 xgywd 的回复:[quote=引用 18 楼 lzhui1987 的回复:] %x的问题吧,它默认本来就是输出32位整数 是的啊,它是32位的,但是为什么类型一样,长度一样的两个参数会有两种不同的输出结果呢.[/quote] 我在８楼说的，你没做吗。那我告诉你一个秘密，大于0x7f的char转unsigned会补１，　其余的补０

引用 18 楼 lzhui1987 的回复:%x的问题吧,它默认本来就是输出32位整数 是的啊,它是32位的,但是为什么类型一样,长度一样的两个参数会有两种不同的输出结果呢.

赵四解决实际问题好不好

%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  引用 14 楼 xgywd 的回复:[quote=引用 13 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 11 楼 xgywd 的回复:] [quote=引用 7 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0  [/quote]  你会改诉参数是按值传递的，是复制进去的[/quote] 小端字节序 0x12345678在内存中是 78 56 34 12 在内存中的分布是 0xee在007.  0x12345678在008   006         007     008      009    010    011    012     ??         ee        78        56      34      12     ?? 所以想不通啊,%x一下复制过去4字节,那里会有0呢? [/quote]  只复制了一个字节过去，复制时会进行类型转换，正如以下是一样的：  char a = '3'; unsigned b = a;

引用 13 楼 paschen 的回复:%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  [quote=引用 11 楼 xgywd 的回复:] [quote=引用 7 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0  [/quote]  你会改诉参数是按值传递的，是复制进去的[/quote] 小端字节序 0x12345678在内存中是 78 56 34 12 在内存中的分布是 0xee在007.  0x12345678在008   006         007     008      009    010    011    012     ??         ee        78        56      34      12     ?? 所以想不通啊,%x一下复制过去4字节,那里会有0呢?

%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在  引用 11 楼 xgywd 的回复:[quote=引用 7 楼 paschen 的回复:] %x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0  [/quote]  你会改诉参数是按值传递的，是复制进去的

%x 需要的 unsigned int ，不是 char

引用 7 楼 paschen 的回复:%x输出的本来就是32位的，而且是按无符号的，也就是正数  *(p1+1) 之所以只显示了两个数字是因为前面6个数字都为0  *(p1-1) 结果刚好是一个负数，而%x按无符号输出的，转换成在无符号数结果就成了那样  *(p1+1) 前后都不是0

引用 6 楼 xgywd 的回复:赵四老师,你又来刷分~请好好解惑好不好~ 在C的层面讨论指针总是有隔靴搔痒的感觉。 我已经不下几万次强调如何脱掉靴子和袜子瘙痒了，必要时还得擦药膏。

把  int c = 0x12345678;     char d = 0xee; 换成 int c = 0xfedcba90; char d = 0x12; 再试试就明白了

赵四老师,你又来刷分~请好好解惑好不好~

引用 2 楼 ipqtjmqj 的回复:char *p1 = &c; 这句编译时会有个警告：initialization from incompatible pointer type 是的虽然类型不同,但它们都是32位无符整形,指针的赋值并没有丢失数据,只是把指针的类型给转换成了char型,用char型指向了这个数据,取出的也应该是一个8bit数据.但是在传递给printf的时候却是让我迷糊了.

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

引用 1 楼 ipqtjmqj 的回复:字节对齐而补了１ 按我的理解*(p1+1)与*(p1-1) d 在计算完表达式之后的结果并无不同,都是取出来一个8bit数据,然后传递给printf函数.但是结果却是完全不同,我的理解竟然有误,这是为什么呢,能详细的给我解释一下吗?


Question: 我想问一个小问题

楼主学C语言不看书吗？

后面是C库函数，用于输出

前三个是用于定义一个变量的数据类型，分别对应整型，浮点型，字符型

前3个是一种数据类型的关键字，分别表示整型、浮点型、字符类型 第4个是一个库函数，用于输出   同意同意

c语言中int,fioat,char,printf分别表示什么。 int,fioat,char分别是数据类型,分别是整型，浮点型，字符型（但其实也是个数值，不过这个数值可以以多种方式显示，比如16进制数值0x41，10进制数值65，纯字符'A'） printf是库函数，需要包含头文件<cstdio>

int,fioat,char表示三种基本的数据类型。 int是整型数据;如:int a  则a的值只能是整型;如a=3; float是浮点型数据;如:float a   则a的值只能是浮点型数据;如a=3.50; char是字符型;如:char a  则a的值只能是字符型;如a='a'  printf是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。

前3个是数据类型 最后一个是函数名称


Question: 刚学数据结构的菜鸟，望有大神能帮我指出并改正这个代码

你这个一大堆错误。 1.e=q->data;少*号 2.DeleteList函数里NODE *p, *q; int j = 0; q = head;应该是NODE *p, *q; int j = 0; p = head; 3.DispList函数里p=p->data;应该是p=p->next; 4.CreateList函数里for (i = n; i>0; n--)应该是for (i = n; i>0; i--) 5.CreateList函数这样写也不行，你想在函数里改变head的指向必须传二级指针或者一级指针的引用（你的创建链表就是有问题的，后面的操作就肯定不会正确了） PS：建议去网上参考下别人的代码

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

我对楼主也是服了，这么烂的代码自己多检查调试几遍也就是行了，还贴的论坛！

谢谢指教，本身就对指针不大理解

DispList(&La) 后面少了分号  DeleteList函数中e=q->data;  e的类型是int*，而赋值的是int


Question: error C2065 未声明的标识符。 已经引入头文件为什么还是未声明？

VS2013测试通过，建议完全重编下试试

谢谢指正!Bug我都修改了。但是还是老情况 Node *head; head = creat(); 会提示head未声明的标识符，Node此类型用作表达式非法。 是VS2010的问题吗？ 修正以后的代码： #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct vector{ 	int x; 	int y; }vec;  typedef struct node{ 	vec a; 	struct node *next; }Node;  Node *creat(); void DestoryStack(Node *head); int StackEmpty(Node *head); int StackLenth(Node *head); int GetTop(Node *head, vec *b); void Push(Node *head, int a, int b); void Pop(Node *head);  Node *creat(){ 	Node *head = NULL; 	head = (Node *)malloc(sizeof(Node)); 	if (head == NULL){ 		printf("fail to creat"); 	    return NULL; 	} 	head -> next = NULL; 	return head; }  void DestoryStack(Node *head){ 	if (head){ 		Node *tail, *pnew = NULL; 		if (head ->next) 			tail = head ->next; 		free(head); 		while (tail ->next){  			pnew = tail ->next; 			free(tail); 		} 		free(pnew); 	} }  int StackEmpty(Node *head){ 	if(head->next){ 		return 1; 	} 	return 0; }  int StackLenth(Node *head){ 	int num; 	Node *tail = NULL; 	if(head)num=1; 	else return 0; 	tail = head; 	if(tail->next){ 		tail = tail->next; 		num++; 	} 	return num; }  int GetTop(Node *head, vec *b){ 	Node *tail = NULL; 	tail = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = tail->next; 		} 		b= &tail->a; 		return 1; 	} 	return 0; }  void Push(Node *head, int a, int b){     Node *tail, *pnew = NULL; 	tail = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = tail->next; 		} 		tail->next=(Node *)malloc(sizeof(Node)); 		pnew = tail->next; 		pnew->next = NULL; 		pnew->a.x = a; 		pnew->a.y = b; 	} }  void Pop(Node *head){ 	Node *tail, *last = NULL; 	tail = head; 	last = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = last; 			last = last->next; 		} 		free(last); 		tail->next =NULL; 	} }

if (head = NULL){  改成   if (head == NULL){   GetTop 不是所有路径都有返回  extern Node *creat(){  写成  Node *creat(){  吧

我这没问题, 不过bug太多了，  严重性	代码	说明	项目	文件	行	禁止显示状态 警告	C4709	逗号运算符在数组索引表达式内	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\main.c	11	 警告	C4709	逗号运算符在数组索引表达式内	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\main.c	16	 警告	C4709	逗号运算符在数组索引表达式内	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\main.c	21	 警告	C4709	逗号运算符在数组索引表达式内	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\main.c	26	 警告	C4706	条件表达式内的赋值	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	26	 错误	C4703	使用了可能未初始化的本地指针变量“tail”	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	40	 错误	C4703	使用了可能未初始化的本地指针变量“pnew”	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	44	 警告	C4701	使用了可能未初始化的局部变量“tail”	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	40	 警告	C4701	使用了可能未初始化的局部变量“pnew”	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	44	 警告	C4715	“GetTop”: 不是所有的控件路径都返回值	DDT1	c:\users\administrator\documents\visual studio 15\projects\project1\ddt1\linkedstack.h	77

#include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct vector{ 	int x; 	int y; }vec;  typedef struct node{ 	vec a; 	struct node *next; }Node;  extern Node *creat(); void DestoryStack(Node *head); int StackEmpty(Node *head); int StackLenth(Node *head); struct vector GetTop(Node *head); void Push(Node *head, int a, int b); void Pop(Node *head);  extern Node *creat(){ 	Node *head; 	head = (Node *)malloc(sizeof(Node)); 	if (head = NULL){ 		printf("fail to creat"); 	    return NULL; 	} 	head -> next = NULL; 	return head; }  void DestoryStack(Node *head){ 	if (head){ 		Node *tail, *pnew; 		if (head ->next) 			tail = head ->next; 		free(head); 		while (tail ->next){  			pnew = tail ->next; 			free(tail); 		} 		free(pnew); 	} }  int StackEmpty(Node *head){ 	if(head->next){ 		return 1; 	} 	return 0; }  int StackLenth(Node *head){ 	int num; 	Node *tail; 	if(head)num=1; 	else return 0; 	tail = head; 	if(tail->next){ 		tail = tail->next; 		num++; 	} 	return num; }  struct vector GetTop(Node *head){ 	Node *tail; 	tail = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = tail->next; 		} 		return tail->a; 	} }  void Push(Node *head, int a, int b){     Node *tail, *pnew; 	tail = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = tail->next; 		} 		tail->next=(Node *)malloc(sizeof(Node)); 		pnew = tail->next; 		pnew->next = NULL; 		pnew->a.x = a; 		pnew->a.y = b; 	} }  void Pop(Node *head){ 	Node *tail, *last; 	tail = head; 	last = head; 	if(!StackEmpty(head)){ 		if(head->next){ 			tail = last; 			last = last->next; 		} 		free(last); 		tail->next =NULL; 	} } 这是头文件。麻烦帮忙看看！！


Question: C语言基础

引用 4 楼 paschen 的回复:没有 34% 这种用法  %只有取余的意思  用于字符串可以作为printf  scanf 的参数类型指定 除非后缀表达式

34%不对，应该写3%4，%取余，然后就是scanf 和printf中，

1.模运算，即求余数。 表达式 a % b 就是计算 a 除以 b 得出的余数。 例如: 4 % 3 的结果是 1 2.转义符，比如在scanf()和printf()中的输入参数常出现带有%的表示参数类型的变量，如%d,%f等。

%除了取余还有输入输出时的格式说明符的作用，如：scanf("%d,a)这个%就是格式说明符，%d就是以十进制的格式输 34%应该是不对的吧，一般都是a%b这种格式取余吧

好像没有这种写法


谢谢，大家。

第二个是C99标准之前，第一个是从C99开始  看你使用的是哪个标准  http://en.cppreference.com/w/c/io/fopen

3指man section 3 3p指man section 3 posix  两个fopen的差异如一楼所说，restrict是C99的新关键字，可以指导编译器做优化。 如果不理解这个关键字，你可以认为它不存在，两个fopen就是一样的，不影响逻辑使用。

FILE *fopen( const char *filename, const char *mode );(until C99) FILE *fopen( const char *restrict filename, const char *restrict mode );(since C99)


Question: 怎么查看C语言的一个头文件里都有什么函数

引用 2 楼 qq423399099 的回复:直接右键打开文档？ 双击打开文档应该也行。

在VS安装目录，比如我的： F:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include 目录里直接用记事本打开stdio.h 不过头文件不好看

直接右键打开文档？

1）选中这个文件引用Alt+G跳转到文件查看 2）MSDN查看 3）一些C语言网站查看

可以在这里查：http://en.cppreference.com/w/Main_Page


Question: 动态库 地址无关代码PIC

引用 9 楼 paschen的回复:[quote=引用 2 楼 wsx199397 的回复:] [quote=引用 1 楼 paschen的回复:]因为A、B 和 C、D 的代码有重叠部分，你的p3程序同一个地址上只能放一个，否则你的指针去取这个地址取到的是哪个动态库 那么p1,p2为什么能正常运行?比如说B和C有代码重叠p2要访问c，为什么p2不会访问已经加载到内存的B呢?[/quote]  B和C有重叠无所谓，P2只依赖C和D，不会去加载B[/quote] 谢谢指教。能不能看看我上面理解的对不对。如果对的话很多问题自然就解决了。

引用 10 楼 mLee79的回复:PIC 代码就重定位项少一点, 加载起来方便点而已, M$Win 的DLL不是PIC代码, 不照样跑的好好的么...  各个进程地址空间是隔离的,  缺省指定的 DLL 基址被占用就换个地呗, 做下重定位就是了, 只是修改过后的页在不同进程间就不是共享的了...  在 x86 这种寄存器少的可怜还不能用ip做基址寄存器的破机器上, 生成 PIC代码时还得用本来就很少了的寄存器保存GOT表基址, 太浪费了些...  不过如果要手工写个 elf/pe loader 啥的, 用PIC代码倒是方便多了... 谢谢指教啊。但是能不能看看我上面理解的对不对呀

引用 1 楼 paschen的回复:因为A、B 和 C、D 的代码有重叠部分，你的p3程序同一个地址上只能放一个，否则你的指针去取这个地址取到的是哪个动态库 那么p1,p2为什么能正常运行?比如说B和C有代码重叠p2要访问c，为什么p2不会访问已经加载到内存的B呢?

引用 2 楼 wsx199397 的回复:[quote=引用 1 楼 paschen的回复:]因为A、B 和 C、D 的代码有重叠部分，你的p3程序同一个地址上只能放一个，否则你的指针去取这个地址取到的是哪个动态库 那么p1,p2为什么能正常运行?比如说B和C有代码重叠p2要访问c，为什么p2不会访问已经加载到内存的B呢?[/quote]  B和C有重叠无所谓，P2只依赖C和D，不会去加载B

总而言之，汇编语言的功底不到一定程度，讨论这个问题都是在浪费时间。

引用 4 楼 zhao4zhong1 的回复:The Intel 64 and IA-32 Architectures Software Developer's Manual 赵老师看看我这样理解的对不对哈。如果不采用PIC，那么共享模块的地址在编译期就确定了。这里的地址是虚拟地址。 假设B的虚拟地址是2-8，C的虚拟地址是4-10。对应p1来说访问地址5访问的是模块B而不是C是因为p1并没有用到模块C，所以C不会映射到进程p1的虚拟地址空间中，所以不会产生二义性。

引用 1 楼 paschen 的回复:因为A、B 和 C、D 的代码有重叠部分，你的p3程序同一个地址上只能放一个，否则你的指针去取这个地址取到的是哪个动态库 版主看看我这样理解的对不对哈。如果不采用PIC，那么共享模块的地址在编译期就确定了。这里的地址是虚拟地址。 假设B的虚拟地址是2-8，C的虚拟地址是4-10。对应p1来说访问地址5访问的是模块B而不是C是因为p1并没有用到模块C，所以C不会映射到进程p1的虚拟地址空间中，所以不会产生二义性。

引用 4 楼 zhao4zhong1 的回复:The Intel 64 and IA-32 Architectures Software Developer's Manual赵老师能不能给个具体点的指点啊，最近就是在看编译链接装载部分。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……


Question: 调用lib失败 fatal error LNK1113: invalid machine type

如果LNK错误直接是在LNK所提供的lib和dll时，跟厂商确认是否为For PC还是ARM。 如果是报在其他lib上，贴出详细点的

会用dumpbin吗？ 找厂商要调用例子。

软件给出的二次开发的文件都在这里。两个头文件，一个模板，还有一个库。模板里面把调用的函数格式都给我写好了，我自己也用dependency查看过了。 我不知道药怎么查看这个库，在网上查了很久，大抵都是说是动态库有几种什么的。这个要怎么看？我是用的C++6.0编的Win32 DLL，什么样的库我才能调用呢？


Question: 初学者想写一个关于C的积分系统，涉及读取存储文件数据，目前仅仅实现积分的储存清除，求大神看看数据为何错乱

引用 3 楼 LeoThanos的回复:谢谢大神。。刚试了一下   remove那一行有错   注释掉之后ok，但为什么这里要加remove error: cannot convert 'FILE* {aka _iobuf*}' to 'const char*' for argument '1' to 'int remove(const char*)'| 最开始需要给文件一个0，问题就解决了

引用 3 楼 LeoThanos的回复:谢谢大神。。刚试了一下   remove那一行有错   注释掉之后ok，但为什么这里要加remove error: cannot convert 'FILE* {aka _iobuf*}' to 'const char*' for argument '1' to 'int remove(const char*)'| 如果没有remove，你的数据怎么保存

1.你的fopen的打开模式不对，这里可以用a+ 2.你查看积分的时候，应该用fscanf将存在文件里的数字读出来 3.你积分清零的时候，应该将文件给清空，而不仅仅是将grade变成0  #include<stdio.h> int main(){ 	FILE *fp; 	int grade = 0; 	fp = fopen("1.txt", "a+"); 	if (fp == NULL)                                                   //第一次打开无数据定义grade为0 	{ 		printf("无数据存储！\n"); 		grade = 0; 	} 	printf("                        ******************************\n"); 	printf("                        *------欢迎进击的程序员------*\n"); 	printf("                        ******************************\n"); 	printf("1.存入积分 2.查看积分 3.积分清零\n"); 	int i; 	scanf("%d", &i); 	if (i == 1){ 		printf("请输入要存取的积分！\n"); 		int j; 		scanf("%d", &j); 		grade = grade + j; 		fprintf(fp, "%d\n", grade); 	} 	else if (i == 2){ 		fscanf(fp, "%d", &grade); 		printf("%d\n", grade); 	} 	else if (i == 3){ 		fclose(fp); 		fopen("1.txt", "w+"); 		grade = 0; 		printf("积分已清%d\n", grade); 	} 	else{ 		printf("输入错误！\n"); 	} 	fclose(fp); 	return 0; }

#include<stdio.h> int main() { 	FILE *fp; 	int grade; 	int x; 	fp = fopen("1.txt", "r+"); 	if (fp == NULL)					//第一次打开无数据定义grade为0 	{ 		printf("无数据存储！\n"); 		grade = 0; 	} 	printf("                        ******************************\n"); 	printf("                        *------欢迎进击的程序员------*\n"); 	printf("                        ******************************\n"); 	printf("1.存入积分 2.查看积分 3.积分清零\n"); 	int i; 	fscanf(fp, "%d", &grade); 	 	scanf("%d", &i); 	if (i == 1) { 		printf("请输入要存取的积分！\n"); 		int j; 		scanf("%d", &j); 		grade = grade + j; 		remove(fp); 		fp = fopen("1.txt", "w+"); 		fprintf(fp, "%d", grade); 	} 	else if(i == 2) { 		printf("%d\n", grade); 	} 	else if(i == 3) { 		grade = 0; 		printf("积分已清%d\n", grade); 		fprintf(fp, "%d", grade); 	} 	else { 		printf("输入错误！\n"); 	} 	fclose(fp); 	return 0; }


Question: sqrt使用在不同数据类型上的效率问题

你得对比两种重载形式的汇编代码

http://en.cppreference.com/w/cpp/numeric/math/sqrt  A set of overloads or a function template accepting an argument of any integral type. Equivalent to 2) (the argument is cast to double).


Question: 求CentOS linux C 下 DES 加密 带 KEY 和IV 的

给分结贴?


Question: 通过输入文件地址来读取文件内容的程序，出现的问题是所声明的数组大小要跟输入的文件名大小一致，否则就会报错

引用 4 楼 paschen 的回复:[quote=引用 3 楼 u013232195 的回复:] [quote=引用 1 楼 paschen 的回复:] 你的输入小于19就行，要算上最后的'\0' 老哥，不行啊。只能输入刚好19个字符（实际输入18个字符，算上自动加的\0)才能读取文本，少和多都不行。。。。[/quote]  输入没问题，只是会多接收到\n，导致打开文件失败  换用scanf函数，或者将\n 去除：  #include<stdio.h> int main() { 	FILE*fp; 	char ch, filename[19];//这里的19如果大于我输入的文件名就会报错，必须刚好 	errno_t err; 	printf("Please input file's name:\n"); 	fgets(filename, sizeof(filename), stdin); 	filename[strlen(filename)-1] = '\0'; 	err = fopen_s(&fp, filename, "r"); 	if (err != 0) 	{ 		printf("The file %s was not opened\n", filename); 	} 	while ((ch = getc(fp)) != EOF)  		putchar(ch);  	fclose(fp); 	return 0; }[/quote]多谢多谢，又学到了！

引用 2 楼 qq423399099 的回复:fgets会把回车符也读进来的，所以只有当刚好等于19你才不会出错，改成scanf_s好了  #include<stdio.h> int main() { 	FILE*fp; 	char ch, filename[19];//这里的19如果大于我输入的文件名就会报错，必须刚好 	errno_t err; 	printf("Please input file's name:\n"); 	scanf_s("%s", filename, 19); 	err = fopen_s(&fp, filename, "r"); 	if (err != 0) 	{ 		printf("The file %s was not opened\n", filename); 	} 	while ((ch = getc(fp)) != EOF) 		putchar(ch); 	fclose(fp); 	return 0; } 多谢老哥啊，本来也想到是不是多读取了些什么，可是没想到什么测试的办法，书看少了。

引用 3 楼 u013232195 的回复:[quote=引用 1 楼 paschen 的回复:] 你的输入小于19就行，要算上最后的'\0' 老哥，不行啊。只能输入刚好19个字符（实际输入18个字符，算上自动加的\0)才能读取文本，少和多都不行。。。。[/quote]  输入没问题，只是会多接收到\n，导致打开文件失败  换用scanf函数，或者将\n 去除：  #include<stdio.h> int main() { 	FILE*fp; 	char ch, filename[19];//这里的19如果大于我输入的文件名就会报错，必须刚好 	errno_t err; 	printf("Please input file's name:\n"); 	fgets(filename, sizeof(filename), stdin); 	filename[strlen(filename)-1] = '\0'; 	err = fopen_s(&fp, filename, "r"); 	if (err != 0) 	{ 		printf("The file %s was not opened\n", filename); 	} 	while ((ch = getc(fp)) != EOF)  		putchar(ch);  	fclose(fp); 	return 0; }

引用 1 楼 paschen 的回复:你的输入小于19就行，要算上最后的'\0' 老哥，不行啊。只能输入刚好19个字符（实际输入18个字符，算上自动加的\0)才能读取文本，少和多都不行。。。。

你的输入小于19就行，要算上最后的'\0'


Question: 进位什么意思？不太理解。

你能理解十进制的逢十进一么？

进制，代表每一位可容纳的（最大值-1），当到达最大值时，无法容纳，往前进一位；如十进制中，每一位最大只能容纳到（10 - 1）= 9， 当再往上加时，需往前进一位，编程10。  对比到实际生活中，可以想象成算盘或其他，以算盘为例，下半部分每个珠子代表1，4之前可以容纳，而一旦要表示5及以上，就需要借助上半部，相当于五进制。而你看到算盘计算值时， 值 = 上半部的珠子*5的1次方 + 下半部的珠子*5的0次方，以此类推

十进制，满十进一.二进制，满二进一

不知道这样做是不是正确

引用 11 楼 u014444402 的回复:[quote=引用 8 楼 yzjxue 的回复:] [quote=引用 4 楼 u014444402 的回复:] 为了10分. 3进制么,不能出现超过3的数字.比如3,4,5,6...就跟二进制不能出现2,3,4...一样. 所以3进制的话.就是 0 1 2    10 11 12 20 21 22  到这里要到3了..二位已经不能表示了.所以要进到3位 100 101 102  刚才又看了小老师的教材，说进制 的任意进制表示任意三个字符， 不特指0  1  2   那个如果把这几个换成 任意字符   H   D   F   的话下面三进制更糊涂。头晕[/quote] 咱转行学点别的吧.[/quote] 中肯

难得糊涂...

引用 8 楼 yzjxue 的回复:[quote=引用 4 楼 u014444402 的回复:] 为了10分. 3进制么,不能出现超过3的数字.比如3,4,5,6...就跟二进制不能出现2,3,4...一样. 所以3进制的话.就是 0 1 2    10 11 12 20 21 22  到这里要到3了..二位已经不能表示了.所以要进到3位 100 101 102  刚才又看了小老师的教材，说进制 的任意进制表示任意三个字符， 不特指0  1  2   那个如果把这几个换成 任意字符   H   D   F   的话下面三进制更糊涂。头晕[/quote] 咱转行学点别的吧.

引用 6 楼 ForestDB 的回复:你能理解十进制的逢十进一么？  没有理解

引用 7 楼 paschen 的回复:你小学学的加法运算，当大于等于10时需要往前面一位多加上1，这就是进位，其他进制同理  非常感谢，一下没有悟通 小学加法会计算，可运用到这来就头晕。

引用 4 楼 u014444402 的回复:为了10分. 3进制么,不能出现超过3的数字.比如3,4,5,6...就跟二进制不能出现2,3,4...一样. 所以3进制的话.就是 0 1 2    10 11 12 20 21 22  到这里要到3了..二位已经不能表示了.所以要进到3位 100 101 102  刚才又看了小老师的教材，说进制 的任意进制表示任意三个字符， 不特指0  1  2   那个如果把这几个换成 任意字符   H   D   F   的话下面三进制更糊涂。头晕


Question: 一个文件描述符，能否判断这个文件已经打开

引用 8 楼 shihengzhen101 的回复:[quote=引用 4 楼 qazaq408 的回复:] [quote=引用 2 楼 shihengzhen101 的回复:] 什么文件描述符 是fstream还是FILE*  int F; F = open("/home/dv/zz.txt",O_REONLY|O_CREATE|O_TRUN);   用这种方式打开结果得到文件描述符F,当然这代码文件是打开的，现在我的麻烦事，假如就这样一个文件描述符，作为参数传入函数，在函数内如何判断这个文件是否处于打开状态，要求不适用fcntl()函数[/quote] 我感觉这个不容易办到吧，他就是一个指针，里面又不包含状态信息，把任意一个变量的地址传给他都是有效的，况且把一个已经关闭的文件指针传给你也是检测不出来的，如果不进行文件操作，是不太可能知道这个指针是否有效的，只能做简单的判断，比如是不是空指针[/quote]  文件描述符是个int值，并不是个指针。你把文件指针和文件操作符搞混了。（这也能搞混－ －几天没睡觉了？）

参考Linux源代码相关片断？

什么文件描述符 是fstream还是FILE*

有人么

引用 4 楼 qazaq408 的回复:[quote=引用 2 楼 shihengzhen101 的回复:] 什么文件描述符 是fstream还是FILE*  int F; F = open("/home/dv/zz.txt",O_REONLY|O_CREATE|O_TRUN);   用这种方式打开结果得到文件描述符F,当然这代码文件是打开的，现在我的麻烦事，假如就这样一个文件描述符，作为参数传入函数，在函数内如何判断这个文件是否处于打开状态，要求不适用fcntl()函数[/quote] 我感觉这个不容易办到吧，他就是一个指针，里面又不包含状态信息，把任意一个变量的地址传给他都是有效的，况且把一个已经关闭的文件指针传给你也是检测不出来的，如果不进行文件操作，是不太可能知道这个指针是否有效的，只能做简单的判断，比如是不是空指针

参考Linux命令lsof的源代码？

引用 3 楼 zhao4zhong1 的回复:参考Linux源代码相关片断？ 楼上的楼上，打错。。。。

引用 3 楼 zhao4zhong1 的回复:参考Linux源代码相关片断？ 楼下帮忙看些，谢谢

引用 2 楼 shihengzhen101 的回复:什么文件描述符 是fstream还是FILE*  int F; F = open("/home/dv/zz.txt",O_REONLY|O_CREATE|O_TRUN);   用这种方式打开结果得到文件描述符F,当然这代码文件是打开的，现在我的麻烦事，假如就这样一个文件描述符，作为参数传入函数，在函数内如何判断这个文件是否处于打开状态，要求不适用fcntl()函数


Question: strcpy对结构体的指针类成员操作

你的Student *st_3; 没有分配内存  你可以直接创建一个对象：  Student st_3;  而不是一个指针

指针必须要分配空间后才能使用，否则指向的是未知区域（野指针），你尝试向未知区域进行写操作会出现异常  # include <stdio.h> # include <string.h> #include <stdlib.h>  struct Student { 	char name[130]; 	int score; 	Student *next; };  int main() {  	Student *st_3 = (Student *)malloc(sizeof(Student));  	strcpy(st_3->name, "jay"); 	printf("第三个学生的名字是:%s\n", st_3->name);  	return 0; }

引用 1 楼 qq_29025081 的回复:运行有问题 语法没问题Student *st_3;  //野指针，定义了一个指针但没有指向有效的对象 如果定义一个结构体对象Student st_3; 就没有问题

运行有问题 语法没问题


Question: ioctl调用失败

man ioctl


Question: c语言 实现bmp转pdf 问题

引用 2 楼 u010808402 的回复:代码没细看，不过Jpeg和Bmp对图片像素点的编码方式并不相同，简单替换buffer应该会有问题。 你可以试着通过mspaint或者其他工具将bmp先转换成jpeg然后测试下本段代码是否可行。  如可行，则只需做BMP移植，如不可行，则需换别的代码。 引用 3 楼 zhao4zhong1 的回复:使用GDI+将bmp转jpg再调用jpeg2pdf  有嵌入式适合的bmp转jpeg算法吗？ 这块我同事写了一个 转一副240*200的bmp 到jpeg要花1s多时间 受不了

将BMP转jpg的方式是可行的 ， 本段代码对jpeg 没问题。  不过我们的设备里面做转换的时候效率不高  我再试试  谢谢

嵌入式有GDI+吗？

STATUS Jpeg2PDF_AddJpeg(PJPEG2PDF pPDF, UINT32 imgW, UINT32 imgH, UINT32 fileSize, UINT8 *pJpeg, UINT8 isColor, PageOrientation pageOrientation, 						double dpiX, double dpiY, ScaleMethod scale, bool cropHeight, bool cropWidth) { 	STATUS result = ERROR; 	PJPEG2PDF_NODE pNode; 	double imgAspect, newImgW, newImgH;  	if(pPDF) { 		if(pPDF->nodeCount >= MAX_PDF_PAGES) { 			logMsg("Add JPEG into PDF Skipped. Reason: Reached Max Page Number (%d) in single PDF.\n", MAX_PDF_PAGES,2,3,4,5,6); 			return result; 		}  		pNode = (PJPEG2PDF_NODE)malloc(sizeof(JPEG2PDF_NODE)); 		if(pNode) { 			UINT32 nChars, currentImageObject; 			UINT8 *pFormat, lenStr[256]; 			pNode->JpegW = imgW; 			pNode->JpegH = imgH; 			pNode->JpegSize = fileSize; 			pNode->pJpeg = (UINT8 *)malloc(pNode->JpegSize); 			pNode->pNext = NULL; 			 			if(pNode->pJpeg != NULL) { 				bool jpegPortrait, pagePortrait; 				double pageWidth, pageHeight; // accounting for page orientation, in PDF units (pixels at PDF_DOT_PER_INCH dpi) 				double maxImgWidth, maxImgHeight; // actual values accounting for page orientation, in PDF units 				double jpegWidth, jpegHeight; // jpeg dimensions (accounting for dpiX, dpiY, PDF_DOT_PER_INCH), in PDF units 				Fit fit;  				memcpy(pNode->pJpeg, pJpeg, pNode->JpegSize); 				 				/* Image Object */ 				Jpeg2PDF_SetXREF(pPDF, INDEX_USE_PPDF, pPDF->currentOffSet, 'n'); 				currentImageObject = pPDF->pdfObj;   				pPDF->currentOffSet += sprintf(pNode->preFormat, "\n%d 0 obj\n<</Subtype/Image/Length 670/Width 248/Height 200/BitsPerComponent 1/ColorSpace/DeviceGray/Filter/JBIG2Decode/Interpolate true/Decode[ 1 0]>>stream\n", 					pPDF->pdfObj, ((isColor)? "DeviceRGB" : "DeviceGray"), pNode->JpegW, pNode->JpegH, pNode->JpegSize); 				 				pPDF->currentOffSet += pNode->JpegSize; 				 				pFormat = pNode->pstFormat; 				nChars = sprintf(pFormat, "\nendstream\nendobj\n"); 				pPDF->currentOffSet += nChars;	pFormat += nChars; 				pPDF->pdfObj++;  				/* determine scale of the image keeping aspect ratio */ 				jpegWidth=((double)pNode->JpegW)*PDF_DOT_PER_INCH/dpiX; 				jpegHeight=((double)pNode->JpegH)*PDF_DOT_PER_INCH/dpiY; 				imgAspect=jpegWidth/jpegHeight; 				if(JPEG2PDF_DEBUG) logMsg("imgAspect = %f %d %d\n", imgAspect, pNode->JpegW, pNode->JpegH, 3,4,5,6);  				// Determine page orientation: 				jpegPortrait=(jpegWidth <= jpegHeight); 				if(pageOrientation==PageOrientationAuto){ 					if(scale==ScaleNone && jpegWidth<=pPDF->maxImgW && jpegHeight<=pPDF->maxImgH){	// image already fits into available area, don't rotate the page 						pagePortrait=true;															// assuming portrait orientation the most convenient for most users 					}else{ 						pagePortrait=jpegPortrait; 						if((pPDF->maxImgW < pPDF->maxImgH) ^ (pPDF->pageW < pPDF->pageH)){ // very rare case: page orientation is opposite to available area orientation (it's possible with differently sized margins) 							pagePortrait=!pagePortrait; 						} 					} 				}else{ 					pagePortrait=(pageOrientation==Portrait) ? true : false; 				} 				maxImgWidth=pagePortrait ? pPDF->maxImgW : pPDF->maxImgH; 				maxImgHeight=pagePortrait ? pPDF->maxImgH : pPDF->maxImgW;  				// Determine scaling method: 				if(scale==ScaleFit || (scale==ScaleReduce && (jpegWidth>maxImgWidth || jpegHeight>maxImgHeight))){ // fit jpeg to available area 					if(maxImgWidth/maxImgHeight > imgAspect){ // available area aspect is wider than jpeg aspect 						fit=FitHeight; 					}else{ // jpeg aspect is wider than available area aspect 						fit=FitWidth; 					} 				}else if(scale==ScaleFitWidth || (scale==ScaleReduceWidth && jpegWidth>maxImgWidth)){ 					fit=FitWidth; 				}else if(scale==ScaleFitHeight || (scale==ScaleReduceHeight && jpegHeight>maxImgHeight)){ 					fit=FitHeight; 				}else{ // don't fit, keep original dpi 					fit=FitNone; 				}  				// Scale image: 				if(fit==FitWidth){ 					newImgW=maxImgWidth; 					newImgH=maxImgWidth/imgAspect; 				}else if(fit==FitHeight){ 					newImgW=maxImgHeight*imgAspect; 					newImgH=maxImgHeight; 				}else{//fit==FitNone 					newImgW=jpegWidth; 					newImgH=jpegHeight; 				}  				// Set paper size from image size (possibly fitted/reduced to specific paper size) or properly rotate the page: 				pageWidth=cropWidth ? (newImgW+pPDF->margin) : (pagePortrait ? pPDF->pageW : pPDF->pageH); 				pageHeight=cropHeight ? (newImgH+pPDF->margin) : (pagePortrait ? pPDF->pageH : pPDF->pageW); 				 				/* Page Object */ 				Jpeg2PDF_SetXREF(pPDF, INDEX_USE_PPDF, pPDF->currentOffSet, 'n'); 				pNode->PageObj = pPDF->pdfObj; 				nChars = sprintf(pFormat, "%d 0 obj\n<</Type/Page/Parent 1 0 R/MediaBox[0 0 %.2f %.2f]/Contents %d 0 R/Resources %d 0 R>>\nendobj\n", 						pPDF->pdfObj, pageWidth, pageHeight, pPDF->pdfObj+1, pPDF->pdfObj + 3); 				pPDF->currentOffSet += nChars;	pFormat += nChars; 				pPDF->pdfObj++; 				 				/* Contents Object in Page Object */ 				Jpeg2PDF_SetXREF(pPDF, INDEX_USE_PPDF, pPDF->currentOffSet, 'n'); 				sprintf(lenStr, "q\n1 0 0 1 %.2f %.2f cm\n%.2f 0 0 %.2f 0 0 cm\n/I%d Do\nQ\n", 						(pageWidth-newImgW)/2, (pageHeight-newImgH)/2, newImgW , newImgH  , pPDF->imgObj); // center image 				nChars = sprintf(pFormat, "%d 0 obj\n<</Length %d 0 R>>stream\n%sendstream\nendobj\n", 						pPDF->pdfObj, pPDF->pdfObj+1, lenStr); 				pPDF->currentOffSet += nChars;	pFormat += nChars; 				pPDF->pdfObj++;  				/* Length Object in Contents Object */ 				Jpeg2PDF_SetXREF(pPDF, INDEX_USE_PPDF, pPDF->currentOffSet, 'n'); 				nChars = sprintf(pFormat, "%d 0 obj\n%ld\nendobj\n", pPDF->pdfObj, strlen(lenStr)); 				pPDF->currentOffSet += nChars;	pFormat += nChars; 				pPDF->pdfObj++; 				 				/* Resources Object in Page Object */ 				Jpeg2PDF_SetXREF(pPDF, INDEX_USE_PPDF, pPDF->currentOffSet, 'n'); 				nChars = sprintf(pFormat, "%d 0 obj\n<</ProcSet[/PDF/%s]/XObject<</I%d %d 0 R>>>>\nendobj\n", 								pPDF->pdfObj, ((isColor)? "ImageC" : "ImageB"), pPDF->imgObj, currentImageObject); 				pPDF->currentOffSet += nChars;	pFormat += nChars; 				pPDF->pdfObj++; 				 				pPDF->imgObj++;  				/* Update the Link List */ 				pPDF->nodeCount++; 				if(1 == pPDF->nodeCount) { 					pPDF->pFirstNode = pNode; 				} else { 					pPDF->pLastNode->pNext = pNode; 				}  				pPDF->pLastNode = pNode;  				result = OK; 			} /* pNode->pJpeg allocated OK */ 		} /* pNode is valid */ 	} /* pPDF is valid */  	return result; }  目前直接把这个函数的jpeg buf用bmp buf替换 生成的pdf看不到图


Question: 用单链表删除文本文档的第一个数据失败，其他删除不了

上面是原代码，看了半天还是不懂该改哪里

#include <stdio.h> #include <stdlib.h> #include <string.h> void insert(); void show(struct stu *head); void save(struct stu *head); struct stu *read(); void add(struct stu *head); void search(struct stu *head); void del(struct stu *head); int count(struct stu *head); struct stu *BubbleSort(struct stu *head);/  struct stu{ 	long num;     char name[10]; 	char course[10]; 	int score; 	int term; 	struct stu *next; };  //输入参数:链表head //返回值:NULL void add(struct stu *head) { 	long num;//学生学号 	char name[20];//学生姓名 	char course[20];//课程 	int score=-1;//成绩 	int term=0;//学期 	struct stu *ptr,*p; 	//ptr=NULL; 	for(ptr=head;ptr->next;ptr=ptr->next) 	{ 		// 	} 	 	 		printf("\n下面开始输入学生信息：\n"); 		printf("请输入学生学号:\n"); 		scanf("%ld",&num); 		printf("请输入学生姓名：\n"); 		scanf("%s",name); 		printf("请输入科目:\n"); 		scanf("%s",course); 		//printf("请输入成绩:\n"); 		//scanf("%d",&score); 		while(score==-1) 		{ 			printf("请输入分数(0—100):\n"); 			scanf("%d",&score); 			if(score>100||score<-1) 			{ 				printf("分数范围必须在0和100之间！\n"); 				score=-1; 			} 		} 		while(term==0) 		{ 			printf("请输入学期(1—8):\n"); 			scanf("%d",&term); 			if(term>8||term<0) 			{ 				printf("学期范围必须在1和8之间！\n"); 				term=0; 			} 		}  		p=(struct stu *) malloc(sizeof(struct stu)); 		p->num=num; 		p->score=score; 		p->term=term; 		strcpy(p->name,name); 		strcpy(p->course,course); 		p->next=NULL; 		ptr->next=p; 		//printf("%ld",ptr->num); 		printf(" 学生数据输入成功！\n"); 		getchar(); 		getchar(); 	 } //查找代码 void search(struct stu *head) { 	int choice,t,score; 	choice=t=0;//t是同特征的个数 	long num; 	char name[10],cpname[10]; 	struct stu *ptr; 	ptr=NULL; 	printf("\n请选择查询方式:\n"); 	printf("\n 1.按学号：\n\n"); 	printf("\n 2.按姓名：\n\n"); 	printf("\n 3.按成绩：\n\n"); 	printf("\n 4.返回主菜单：\n\n"); 	 	while(choice==0) 	{ 		printf("\n输入数字选择查询方式:"); 		scanf("%d",&choice); 		if(choice==1) 		{ 			printf("\n输入您要查询学生的学号:"); 			scanf("%ld",&num); 			printf("\n"); 			for(ptr=head;ptr;ptr=ptr->next) 			{ 				if(ptr->num==num) 				{ 					printf("****学号：%ld，姓名：%s，科目：%s，分数：%d，学期：%d\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term); 					t++; 				} 			} 			if(t==0) 			{ 				printf("\n**不存在学号为：%ld的学生！",num); 				 			} 			else 			{ 				printf("\n**以上是学号为：%ld的学生记录，共%d条！\n",num,t);  			} 			break; 			 		} 		else if(choice==2) 		{ 			printf("\n输入您要查询学生的姓名:"); 			scanf("%s",name); 			printf("\n"); 			for(ptr=head;ptr;ptr=ptr->next) 			{ 				strcpy(cpname,ptr->name); 				if(strcmp(cpname,name)==0) 				{ 					printf("****学号：%ld，姓名：%s，科目：%s，分数：%d，学期：%d\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term); 					t++; 				} 			} 			if(t==0) 			{ 				printf("\n**不存在姓名为：%s的学生！",name); 				 			} 			else 			{ 				printf("\n**以上是姓名为：%s的学生记录，共%d条！\n",name,t);  			} 			break; 		} 		else if(choice==3) 		{ 			printf("\n输入您要查询学生的分数:"); 			scanf("%d",&score); 			printf("\n"); 			for(ptr=head;ptr;ptr=ptr->next) 			{ 				 				if(score==ptr->score) 				{ 					printf("****学号：%ld，姓名：%s，科目：%s，分数：%d，学期：%d\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term); 					t++; 				} 			} 			if(t==0) 			{ 				printf("\n**不存在分数为：%d的学生！",score); 				 			} 			else 			{ 				printf("\n**以上是分数为：%d的学生记录，共%d条！\n",score,t);  			} 			break; 		} 		else if(choice==4) 		{ 			break; 		} 		else  		{  			choice=0; 			printf("\n注意：输入错误，只能输入1、2 或 3 ！\n"); 		} 	} 	printf("\n按回车键回到主菜单...\n"); 	getchar(); 	getchar(); 	 }  void del(stu *head) { 	struct stu *ptr,*pre,*pnext; 	ptr=pre=pnext=NULL; 	int choice,num; 	int t=0; 	if (head == NULL) 	{ 		printf("无学生记录！\n"); 	    return; 	} 	printf("\n请输入要删除的学生的学号："); 	scanf("%d",&num); 	for(ptr=head;ptr;ptr=ptr->next) 	{ 		  		if(ptr->next==NULL) 		{ 			if(ptr->num==num) 			{ 				pre->next=NULL; 				t++; 			} 			break; 			 		} 		pnext=ptr->next; 		pre=ptr; 		if(pnext->num-1==num){ 			pre->next=pnext->next; 			pre=pnext; 			free(pnext); 			printf("\n删除成功！\n"); 			break; 			t++; 		} 		 	}  	printf("\n按回车键回到主菜单...\n"); 	getchar(); 	getchar(); } struct stu *BubbleSort(struct stu *head) { 	int choice=0; 	struct stu *endpt; /*控制循环比较*/ 	struct stu *p; /*临时指针变量*/ 	struct stu *p1;  	struct stu *p2; 	endpt=p=p1=p2=NULL;  	p1 = (struct stu *)malloc(sizeof(struct stu));//分配结点空间 	p1->next = head; /*增加一个节点，放在第一个节点的前面，主要是为了便于比较。因为第一个节点没有前驱，不能交换地址。*/ 	head = p1; /*让head指向p1节点，排序完成后，我们再把p1节点释放掉*/  	printf("\n请选择排序字段："); 	printf("\n1.按学号排序"); 	printf("\n2.按分数排序"); 	while(choice==0) 	{ 		printf("\n请输入1或2："); 		scanf("%d",&choice); 		if(choice==1) 		{ 			for(endpt=NULL; endpt!=head; endpt=p) 			{ 				for(p=p1=head; p1->next->next!=endpt; p1=p1->next) 				{ 				   if (p1->next->num > p1->next->next->num) 					p2 = p1->next->next; 					p1->next->next = p2->next; 					p2->next = p1->next;  					p1->next = p2;  					p = p1->next->next;  				} 			} 			printf("\n***按学号排序成功！\n"); 			break;	 		} 		if(choice==2) 		{ 			for (endpt=NULL; endpt!=head; endpt=p)  			{ 				for (p=p1=head; p1->next->next!=endpt; p1=p1->next) 				{ 					if (p1->next->score > p1->next->next->score ) 				   { 					p2 = p1->next->next;  					p1->next->next = p2->next;  					p2->next = p1->next; 					p1->next = p2; 					p = p1->next->next;  				   } 				} 			} 			printf("\n***按分数排序成功！"); 			break; 		}   	} 	 	  	p1 = head; 	head = head->next; 	free(p1); /*释放p1*/ 	p1 = NULL;  	printf("\n***排序后...！"); 	show(head);  	return head; }   int count(struct stu *head) { 	int choice,count,bad,good; 	choice=count=bad=good=0;//选择 	struct stu *ptr; 	char sort; 	ptr=NULL; 	printf("不及格记录如下：",count); 	printf("\n"); 	printf("★★★学号     *姓名*     课程  分数  学期★★★\n");//输出格式 	for(ptr=head;ptr;ptr=ptr->next) 	{ 		count++; 		if(ptr->score<60) 		{ 			bad++; 			printf("*%10ld%10s%10s%5d%5d        *\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term); 		} 	} 	printf("☆———————————————————————————★\n"); 	printf("\n"); 	printf("***有%d条不及格记录\n",bad); 	printf("***共有%d条记录...\n",count);  	printf("\n优秀记录如下：\n",count); 	printf("**★**学号     *姓名*     课程  分数  学期**★**\n");//输出格式 	for(ptr=head;ptr;ptr=ptr->next) 	{ 		count++; 		if(ptr->score>80) 		{ 			good++; 			printf("*%10ld%10s%10s%5d%5d        *\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term); 		} 	} 	printf("★———————————————————————————☆\n"); 	printf("\n"); 	printf("有%d条优秀记录\n",good); 	getchar();  	printf("\n*是否对分数进行冒泡排序？输入Y/n 进行排序...\n"); 	scanf("%c",&sort); 	if(sort=='y'||sort=='Y') 	{ 		BubbleSort(head); 		/*for(int i=0;i<count-1;i++) 		{ 			for(int j=count-1;j>i;--j) 			{ 			} 		}*/  		return 1; 		 	} 	else 	{ 		printf("\n您选择不进行冒泡排序。"); 		return 0; 	}  	 }  void show(struct stu *head) { 	struct stu *ptr=NULL; 	if(head==NULL) 	{ 		printf("\n 没有记录 \n"); 		return; 	} 	printf("\n所有记录如下：\n"); 	printf("\n"); 	printf("\n******学号     *姓名*     课程  分数  学期********\n");//输出格式 	for(ptr=head;ptr;ptr=ptr->next){ 		printf("%10ld%10s%10s%5d%5d\n",ptr->num,ptr->name,ptr->course,ptr->score,ptr->term);//显示一条信息 	} 	//	fscanf(fp,"%ld%s%s%d%d",&num,name,course,&score,&term); 	  }   //返回值：链表的head //功能描述：将student.txt文件中的学生信息逐条读出到链表 struct stu *read() { 	struct stu *head,*p,*tail; 	//tail=(struct stu *) malloc(sizeof(struct stu)); 	head=tail=NULL; 	long num;//学生学号 	char name[10];//学生姓名 	char course[10];//课程 	int score;//成绩 	int term;//学期  	FILE *fp;//文件指针	 	//以只读方式打开student.txt文件 	if(NULL==(fp=fopen("student.txt","r"))){  		printf("没有任何记录!\n"); 		return NULL; 	} 	fscanf(fp,"%ld%s%s%d%d",&num,name,course,&score,&term);//读取学生的信息  	while(!feof(fp)){ 		 		p=(struct stu *) malloc(sizeof(struct stu)); 		p->num=num; 		strcpy(p->name,name); 		strcpy(p->course,course); 		p->score=score; 		p->term=term; 		p->next=NULL; 		//printf("%ld\n",p->num); 		if(head==NULL) 		{ 			head=p; 		} 		else 		{ 			tail->next=p; 		} 		tail=p; 		fscanf(fp,"%ld%s%s%d%d",&num,name,course,&score,&term);//读取学生的信息  	} 	//关闭文件 	if(fclose(fp)){  		printf("File close error!\n"); 		exit(0); 	}     return head; }  //输入参数：NULL //返回值：链表的head //功能描述：将链表的学生信息保存到student.txt文件中 void save(struct stu *head) { 	struct stu *p; 	p=NULL; 	FILE *fp;//文件指针  	//打开student.txt文件 	if(NULL==(fp=fopen("student.txt","w"))){ 		 		//如果打开文件失败，就成了一个空指针 		printf("File student.txt open error!\n"); 		exit(0); 	} 	else 	{ 		for(p=head;p;p=p->next) 		{ 			fprintf(fp,"%10ld%10s%10s%5d%5d\n",p->num,p->name,p->course,p->score,p->term);//将信息写入文件 		} 	} 	//关闭文件 	if(fclose(fp)){  		printf("File close error!\n"); 		exit(0); 	}  } //主函数！ int main(){  	int choice=0;//选择功能 	int sort=0;//选择是否保存排序结果 	struct stu *head=read(); 	//显示主页面 	printf("★———————————————————————————★\n"); 	printf("                        学生成绩管理系统                \n\n"); 	printf("                  学号姓名：1200370221廖祖昌            \n\n"); 	printf("                     日期：2016年10月8日                \n\n"); 	printf("          ☆一一一一一一一一一一一一--一一一一一☆      \n\n"); 	//显示功能页面 	while(-1!=choice){  		printf("★——————————————————————————★\n"); 		printf("★—☆          欢迎进入学生成绩管理系统          ☆—★\n"); 		printf("★——————————————————————————★\n\n"); 		printf("                    1:输入数据                   \n\n"); 		printf("                    2:显示数据                   \n\n"); 		printf("                    3:删除数据                   \n\n"); 		printf("                    4:查询数据                   \n\n"); 		printf("                    5:统计与排序                 \n\n"); 		printf("                    -1:退出系统                  \n\n"); 	    printf("                请输入以上数字选择操作:          \n");//功能提示 		scanf(" %d",&choice);//choice接受用户选择的功能 		switch(choice){ 	    //数据输入(增加一个学生的信息) 		case 1: 			add(head); 			save(head); 			break; 		//显示所有记录 		case 2: 			show(head); 			printf("\n按回车键回到主菜单...\n"); 			getchar(); 			getchar(); 			break; 			//显示删除后的页面 		case 3: 			show(head); 			del(head); 			save(head); 			break; 			//执行查找功能 		case 4: 			search(head); 			break; 			//执行排序与统计功能 		case 5: 			sort=count(head); 			if(sort==1) 			{ 				save(head); 			} 			head=read(); 			printf("\n按回车键回到主菜单...\n"); 			getchar(); 			getchar(); 			break; 	    //退出软件 		case -1: 			save(head); 			printf("\n\n☆—★           谢谢使用学生成绩管理系统         ★—☆\n\n"); 			break; 		//错误输入 	    default: 			printf("\n错误输入，请重新输入数字选择功能!\n"); 			break; 		} 	} 	return 0; }

引用 14 楼 qq_33446306 的回复:[quote=引用 13 楼 qq_33446306 的回复:] [quote=引用 12 楼 qq423399099 的回复:] 1.声明改一下，改成：void del(struct stu **head); 2.调用改成:del(&head);  这样就直接显示无学生记录 了[/quote]      啊 ，  可以了， 是 删除函数前面有个ptr=  没改，改了之后就好了，不过变成 最后一个删不了了，    而且点删除操作后不提示删除成功 得自己去看才会发现[/quote]    上面操作是只把ptr删掉，pre = pnext = NULL;语句还在，之后这行代码注释掉后就没问题了

引用 13 楼 qq_33446306 的回复:[quote=引用 12 楼 qq423399099 的回复:] 1.声明改一下，改成：void del(struct stu **head); 2.调用改成:del(&head);  这样就直接显示无学生记录 了[/quote]    啊 ，  可以了， 是 删除函数前面有个ptr=pre = pnext = NULL;  没改，改了之后就好了，不过变成 最后一个删不了了，    而且点删除操作后不提示删除成功 得自己去看才会发现

引用 12 楼 qq423399099 的回复:1.声明改一下，改成：void del(struct stu **head); 2.调用改成:del(&head);  这样就直接显示无学生记录 了

引用 10 楼 qq423399099 的回复:不是让你改成这样if(pnext->num-1==num)，这样不对的。 你这个链表是不带头结点的，所以一旦你输入的num等于第一个结点，你是删除不掉的（除非传二级指针） 有几个方法： 1.链表改成带头结点的 2.参数传二级指针或者一级指针的引用 3.del改成带返回值的，重新返回head 下面这样试试：  void del(stu **head) { 	struct stu *ptr = *head, *pre, *pnext; 	ptr = pre = pnext = NULL; 	int choice, num; 	int t = 0; 	if (ptr == NULL) 	{ 		printf("无学生记录！\n"); 		return; 	} 	printf("\n请输入要删除的学生的学号："); 	scanf("%d", &num); 	if (ptr->num == num){ 		*head = ptr->next; 		free(ptr); 	} 	else{ 		for (; ptr; ptr = ptr->next) 		{  			if (ptr->next == NULL) 			{ 				if (ptr->num == num) 				{ 					pre->next = NULL; 					t++; 				} 				break;  			} 			pnext = ptr->next; 			pre = ptr; 			if (pnext->num == num){ 				pre->next = pnext->next; 				pre = pnext; 				free(pnext); 				printf("\n删除成功！\n"); 				break; 				t++; 			}  		} 	}  	printf("\n按回车键回到主菜单...\n"); 	getchar(); 	getchar(); }   运行之后出现这两个错误

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

单步跟踪程序运行，观察每一步变化，分析原因

其他可以删除  就是第一排数据删除不了  标题打错

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。http://bbs.csdn.net/topics/391975224

求大神解答，O(∩_∩)O谢谢

楼主没贴全代码（如果第一个元素删不掉说明楼主的链表是不带头结点的） 那么意味着其实和num比较是从第二个结点开始的，因为你比较的是if (next->num == num) 而第一次for循环的时候，next指向的是第二个结点，而不是第一个结点（所以第一个结点永远无法比较到）


Question: 安装microsoft visual C++2008出现以下问题

我是64位的系统啊……


Question: K&R的这个例子看的有些晕乎

else配对的是第二个if, 等价于     if (n > 0) {         if (a > b) {             z = a;         }         else {             z = b;         }     }