去年一滴相思泪，今日方才到嘴边。

今日结贴结贴!

//提取出IP地址即char buf0[]="192.168.0.253"中的数字“192168000253”保存在char buf1[]中，再转为C0A800FD，以16进制保存在char buf2[]中 //printf("%s",buf2);   输出结果：C0A800FD #include <stdio.h> char buf0[]="192.168.0.253"; char buf1[13]; char buf2[9]; int v[4]; int main() {     sscanf(buf0,"%d.%d.%d.%d",&v[0],&v[1],&v[2],&v[3]);     sprintf(buf1,"%03d%03d%03d%03d",v[0],v[1],v[2],v[3]);     printf("buf1:[%s]\n",buf1);     sprintf(buf2,"%02X%02X%02X%02X",v[0],v[1],v[2],v[3]);     printf("buf2:[%s]\n",buf2);     return 0; } //buf1:[192168000253] //buf2:[C0A800FD] //

@user-3 ：大神，那个buf2中保存的是16进制的数据，不是字符串"C0A800FD"啊，以16进制的形式输出，	char buf3[]={0xc0,0xa8,0x00,0xfd}; printf("\n buf3[0]=%02x",(unsigned char)buf3[0]);  输出结果：buf3[0]=c0 酱紫的  sprintf(buf2,"%02X%02X%02X%02X",a[0],a[1],a[2],a[3]); printf("\n buf2[0]=%02x",buf2[0]); 输出结果：buf2[0]=43; 两者不一样？

@user-3 :谢谢你啦，我知道了！

@user-3 :第14行和第15行代码有什么用捏？

#include <stdlib.h>  void split_ip_address(char* address,int* output) { 	char* s=(char*)address; 	char* ss=nullptr; 	int n=0; 	while (n<4&&(ss=strchr(s,'.'))!=nullptr) 	{ 		*ss=0; 		output[n++]=atoi(s); 		s=ss+1; 	} 	if (n<4&&*s) 		output[n]=atoi(s); }  int main() { 	char buf0[]="192.168.0.253"; 	int a[4]; 	split_ip_address(buf0,a);  	char buf1[16],buf2[16]; 	sprintf_s(buf1,"%d%d%d%d",a[0],a[1],a[2],a[3]); 	sprintf_s(buf2,"%02X%02X%02X%02X",a[0],a[1],a[2],a[3]);  	printf("buf1=%s\n",buf1); 	printf("buf2=%s\n",buf2);  	return 0; }


Question: 求助。。链表的建立  自己不知道错在哪

仅供参考：//不带表头结点的单向链表 #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 楼 qq423399099 的回复:楼上已经解决了大部分问题,还有个输入的问题 既然在主函数里已经输入过数据了，在create函数里就没必要再输入了（删掉create函数里的scanf）  #include<stdio.h> #include<stdlib.h>   struct linklist *create(int a[],int n); void Print(struct linklist *phead);    struct linklist     //创建结构体； {     int data;     struct linklist *next; };   int main()   {     int a[6];     int n=0,i;     struct linklist *p;     printf("请输入数组的元素：");     for(i=0;i<6;i++){         ++n;         scanf("%d",&a[i]);     }      p=create(a,n);  //调用建立单向链表的函数；     Print(p);    //调用输出函数；     return 0; }   struct linklist *create(int a[],int n){     int i,count=0;     struct linklist *phead=NULL,*pend,*pnew;     pnew=pend=(struct linklist*)calloc(1,sizeof(struct linklist));     pnew->data=a[0];     pnew->next=NULL;     pend=pnew;     phead=pnew;     for(i=1;i<n;i++){         pnew=(struct linklist*)calloc(1,sizeof(struct linklist));         pnew->next=NULL;         pend->next=pnew;         pend=pnew;         pnew->data=a[i];     }     pnew->next=NULL;     //free(pnew);     return phead; }   void Print(struct linklist *phead){     struct linklist *temp;     temp=phead;     printf("用链表输出的数组是：");     while(temp!=NULL){         printf("%d ",temp->data);         temp=temp->next;     } }   确实对他这样重复输入感到迷惑，不知道是想做什么~

主要有这么几个问题： 第一，如果函数定义在调用函数之后，那么需要事先进行声明； 第二，在create的for循环之中，要先进行malloc然后再进行操作，原来的代码顺序有点混乱；并且最后不能进行free操作，否则，最后一次malloc的空间将被释放，也就无法输出里面的内容；（free针对的是内存而不是指针） 第三，malloc只是进行申请内存，而并不初始化，所以建议使用calloc或者malloc之后进行memset；   #include<stdio.h> #include<stdlib.h>  struct linklist *create(int a[],int n); void Print(struct linklist *phead);   struct linklist     //创建结构体； {     int data;     struct linklist *next; };  int main()   { 	int a[6]; 	int n=0,i; 	struct linklist *p; 	printf("请输入数组的元素："); 	for(i=0;i<6;i++){ 		++n; 		scanf("%d",&a[i]); 	}  	p=create(a,n);  //调用建立单向链表的函数； 	Print(p);    //调用输出函数； 	return 0; }  struct linklist *create(int a[],int n){ 	int i,count=0; 	struct linklist *phead=NULL,*pend,*pnew; 	pnew=pend=(struct linklist*)calloc(1,sizeof(struct linklist)); 	scanf("%d",&a[0]); 	pnew->data=a[0]; 	pnew->next=NULL; 	pend=pnew; 	phead=pnew; 	for(i=1;i<n;i++){ 		pnew=(struct linklist*)calloc(1,sizeof(struct linklist)); 		pnew->next=NULL; 		pend->next=pnew; 		pend=pnew; 		scanf("%d",&a[i]); 		pnew->data=a[i]; 	} 	pnew->next=NULL; 	//free(pnew); 	return phead; }  void Print(struct linklist *phead){ 	struct linklist *temp;     temp=phead; 	printf("用链表输出的数组是："); 	while(temp!=NULL){ 		printf("%d ",temp->data); 		temp=temp->next; 	} }

引用 7 楼 user-6 的回复:#include<stdio.h> #include<stdlib.h>   struct linklist     //创建结构体； {      int data;      struct linklist *next; }; struct linklist *create(int a[],int n)	 { 	int i,count=0; 	struct linklist *phead=NULL,*pend,*pnew; 	phead=(struct linklist*)malloc(sizeof(struct linklist)); //	scanf("%d",&a[0]); //	pnew->data=a[0]; //	pnew->next=NULL; //	pend=pnew; //	phead=pnew; 	phead->next =NULL; 	pend=phead; 	for(i=0;i<n;i++)  	{ 		pnew=(struct linklist*)malloc(sizeof(struct linklist)); 		pnew->data=a[i]; 		pnew->next=NULL; 		pend->next=pnew; 		pend=pnew; 	} 	return phead; }  void Print(struct linklist *phead) { 	struct linklist *temp=phead->next ; 	printf("用链表输出的数组是："); 	while(temp!=NULL) 	{ 		printf("%d ",temp->data); 		temp=temp->next; 	} 	printf("\n"); }     void dele(struct linklist *phead){ 	struct linklist *p; 	while(phead->next!=NULL){ 		p=phead->next; 		phead=p->next; 		free(p); 	} }   int main()   { 	int a[6]; 	int i; 	struct linklist *p; 	printf("请输入数组的元素："); 	for(i=0;i<6;i++) 	{ 		scanf("%d",&a[i]); 	} 	p=create(a,i);     //调用建立单向链表的函数； 	Print(p);    //调用输出函数； 	dele(p); 	free(p); 	return 0; }  前辈，为什么用p=create(a,i)而不是我原来函数中的p=create(a,n)？  i在循环之后不是等于5吗，而n=6,。i=5调用到create函数以后就是进行i<5的循环  这样不应该少输入一个数了吗？

引用 1 楼 GOT01 的回复:在C/C++里面，函授要先定义再调用，在main中使用了尚未定义的create和Print函数是不对的。 你说的对，也不全然是这样，这种情况下，有些编译器会搞猜测 猜测的结果固然是不准确的，所以不可信，还有的是，他前面的结构体定义，少了个分号

[quote=引用 4 楼 qq423399099 的回复:] 楼上已经解决了大部分问题,还有个输入的问题 既然在主函数里已经输入过数据了，在create函数里就没必要再输入了（删掉create函数里的scanf）  还想问问前辈，单向链表的建立   头插法是什么原理？搜百度出来的PPT没看明白，  我知道我用的是尾插法  感觉尾插法很好理解。。

[quote=引用 4 楼 qq423399099 的回复:] 楼上已经解决了大部分问题,还有个输入的问题 既然在主函数里已经输入过数据了，在create函数里就没必要再输入了（删掉create函数里的scanf）  谢谢~昨天码的时候有点乱。。 都没想到这

[quote=引用 3 楼 ghx287524027 的回复:] 主要有这么几个问题： 第一，如果函数定义在调用函数之后，那么需要事先进行声明； 第二，在create的for循环之中，要先进行malloc然后再进行操作，原来的代码顺序有点混乱；并且最后不能进行free操作，否则，最后一次malloc的空间将被释放，也就无法输出里面的内容；（free针对的是内存而不是指针） 第三，malloc只是进行申请内存，而并不初始化，所以建议使用calloc或者malloc之后进行memset；  明白了，谢谢解答~   我想问一下是不是每次pnew想要指向一个新的数据时，就要先用一次malloc函数？  malloc以后怎么初始化呢。。

结构体的定义后面少了个分号。结构体后声明函数，就可以编译运行了。 struct linklist     //创建结构体； { 	int data; 	struct linklist *next; };  // 声明函数定义 struct linklist *create(int a[],int n); void Print(struct linklist *phead);


Question: 关于for循环变量的声明问题

引用 1 楼 ghx287524027 的回复:如果你是C语言编译,在for中是不能定义变量的,C++编译器可以,在for中的变量作用域在for代码块内,外部的j被隐藏.j在for中声明时被赋值,是一次性的,for的循环体不包含赋值语句. VC6中好像这种写法有BUG,for中的变量具有函数的生命周期.之后的版本解决了这个问题. 不是说不允许，要看你用的那种标准编译的，如果是 C89是不允许的 C99是可以这样做的 以上是 变量作用域的问题，就近原则用。所以外面的sum没有加上去

在for循环里不用再次定义sum,i，直接赋值即可。

引用 3 楼 paschen 的回复:你循环中的sum与外面的sum是两个不同的变量，因为你循环中的sum是在for(int sum=10,i=3;i<10;++i)新定义的，把int删除掉应该就可以了 正解。

作用域，重复定义覆盖掉了外边的sum

循环可能执行了（没做优化） 也可能没执行（优化了，根本没有生成循环的任何代码） 然而循环中的定义的变量只在循环语句中有效。 即作用域为for的小括号和循环语句（无大括号时候）或者语句组（有大括号时候）  PS：  循环语句，if 语句 也是一个作用域 其中定义的变量只在相应的循环 或者if语句内部有效

在for循环的括号内声明变量，编译器会分配一块新的内存，这是一个全新的局部变量，而且只在循环内有效。for循环在这里相当于一个大括号（语句块）内一个局部变量。跳出循环，这个变量就没用了。但是，你在for循环声明的那个和sum和i 是在另一块内存里面，他们不在一个房间，即使他们的名字都一样，但是互不影响。对于int sum,int i;这种声明变量的方式是不允许的，不符合语法规范的。无论是在循环内还是循环外。

引用 7 楼 jeroy 的回复:#include <stdio.h> int main(void) { 	for(int sum=10,int i=1;i<=10;++i) 	{ 	sum+=i; 	printf("\n第一个数字是%d是%d是\n",sum,i); 	} 	return 0; }  这样写也会报错，是不是不能在for循环里声明2个变量的？ for(int sum=10,i=3;i<10;++i) 这么写就是i和sum都是重新定义的,覆盖了外面的,所以i和sum都是0;

在for中重复定义了sum，去掉sum前的int就对了


Question: C语言 十六进制转化为十进制？

#include<stdio.h> long fun(char *s); int main() {  	long m; 	char s[50]; 	scanf("%s",s); 	m=fun(s); 	printf("%ld\n",m); 	return 0; } long fun(char *s) { 	int i,t; 	long sum=0; 	for(i=0;s[i];i++) 	{ 		if(s[i]<='9') 			t=s[i]-'0'; 		else 			t=s[i]-'a'+10; 		sum=sum*16+t; 	} 	return sum; }

谢谢你们，我的问题已经解决了，谢谢版主

引用 5 楼 xinye1230 的回复:我是初学者   不知道什么是char*    能不能帮忙该个不带*的？、  因为他们是完全不同的类型，一个是指针，一个不是

引用 7 楼 xinye1230 的回复:[quote=引用 6 楼 qq423399099 的回复:] [quote=引用 5 楼 xinye1230 的回复:] 我是初学者   不知道什么是char*    能不能帮忙该个不带*的？、 数组学过没？[/quote] 数组 函数都学了。[/quote] 指针没学？ 把long fun(char *s)改成long fun(char s[])就行

引用 6 楼 qq423399099 的回复:[quote=引用 5 楼 xinye1230 的回复:] 我是初学者   不知道什么是char*    能不能帮忙该个不带*的？、 数组学过没？[/quote] 数组 函数都学了。

引用 5 楼 xinye1230 的回复:我是初学者   不知道什么是char*    能不能帮忙该个不带*的？、 数组学过没？

我是初学者   不知道什么是char*    能不能帮忙该个不带*的？、

仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

long fun(char s)   参数不是char，应该是char*


Question: c语言  输入一串字符将最长的单词输出，用函数写

[quote=引用 1 楼 qq423399099 的回复:] 参考：  #include<stdio.h> #include<string.h> int main() {  	int tonji(char s[]); 	char str[100]; 	printf("请输入一串字符"); 	gets(str); 	tonji(str); 	return 0; }  int tonji(char s[]) { 	int i,flag=1,point,place=0,length=0,len=0; 	strcat(s, " "); 	for(i=0;s[i]!='\0';i++) 	{ 		if(s[i]!=' ') 		{  			if(flag) 			{ 				point=i;flag=0;   			} 			else 				len++;        		} 		else 		{ 			flag=1; 			if(len>length)         			{ 				length=len; 				place=point;      				len=0;     			} 		} 	} 	for(i=place;s[i]!=' ';i++) 		printf("%c",s[i]); 	return 0; }  初学者前来报到！版主你这个我在  vs 2013 pro  版运行了一下，gets（），strcat( )现在都不用了， 改用gets_s() 和strcat_s(）替代了。还有测试得不到想要的结果，不是每次都能输出最长单词，且无法同时 输出相同的最长单词，这个问题我想了一上午，看了很多帖子，终于解决。想跟大家分享下我的喜悦，请多指教 [code=c] #include<stdio.h> #include<memory.h> void main() { 	char str[40] = { 0 }; 	int t_number[40] = { 0 }, longest[40] = { 0 };    //   t_number表示最长单词的末字母序号， 									                //     longest表示最长字母的长度 	gets_s(str, 40); 	int i, t = 0, l = 0, k = 1;                       //t 末字母序号，l 最长长度，k最长相同单词个数 	for (i = 0; str[i] != '\0'; i++) 	{ 		if (str[i] != ' ')  //   ' '   (空格） 		{ 			if (str[i - 1] == ' '&&i - 1 != 0) l = 0 ;   //单词首字母，将之前的长度置0  			l++; 			if (str[i + 1] == ' ' || str[i + 1] == '\0')//在进入空格或结束字符之前进行判断，可以避免最后一个 			                                           //字符不是空格就漏掉最后那个单词 			{ 				t = i; 				if (l > longest[0]) 				{ 					memset(longest, 0, sizeof(longest)); 					memset(t_number, 0, sizeof(t_number));  //数组清零，当出现唯一的最长的单词时将之前保存的数据作废 					longest[0] = l; 					t_number[0] = t;                        //将唯一的最长单词存放在第一位，后来的相同长度的单词 			                                               //（长度和末字母序号）依次往后存放 					k = 1;  				} 				else if (l == longest[0])                    //可能会有相同长度的不同单词都是最长的都要输出 				{ 					longest[k] = l; 					t_number[k] = t; 					k++; 				} 			} 		} 	} 	for (int j = 0; j <k; j++)     //k表示最长单词的个数 	{ 		for (i = t_number[j] + 1 - longest[j]; i <= t_number[j]; i++)  //知道最长单词的的长度和末字母序号， 			                                                          //那其首字母序号可求 			printf("%c", str[i]);                      //用循环挨个输出指定位置的字符，组合起来就是最长的单词 		printf("\n"); 	} }

版主果然速度

引用 9 楼 qq423399099 的回复:[quote=引用 8 楼 xinye1230 的回复:] 哦、、 回帖最好引用一下。。。这样别人会有提示，不然并不一定看的到 问题解决了的话记得结贴[/quote]  哦  好吧，我知道了

引用 8 楼 xinye1230 的回复:哦、、 回帖最好引用一下。。。这样别人会有提示，不然并不一定看的到 问题解决了的话记得结贴

哦、、

引用 6 楼 xinye1230 的回复:版主，那为什么是双引号，不是单引号啊？ because strcat需要两个参数是char *类型的，不是char

版主，那为什么是双引号，不是单引号啊？

引用 4 楼 xinye1230 的回复:stract(s," ")； 是什么意思啊？ 往你输入的字符串后面拼接上一个空格，否则的话最后一个单词不会进入else分支，就不会参加比较了

stract(s," ")； 是什么意思啊？

zifu 函数需要的参数是char，但你提供的是字符数组


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

else if(PIN[j]=='1')和else if(PIN[j]=='o')里  PIN[j]都写成PIN[k]了吧 最下面的else分支也不对吧？多循环了一次吧？ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  #include<stdio.h> #include<string.h> #include<math.h>   int main(){     char Team[20],PIN[20],store[20][40];     int n,N,flag,i,j,k;     int len1,len2;       while(scanf("%d",&n)!=EOF){         N=0;         for(i=0;i<n;i++){             flag=0;             scanf("%s%s",&Team,&PIN);             len1=strlen(Team);             len2=strlen(PIN);             for(j=0;j<len2;j++){                 if(PIN[j]=='0'){                     PIN[j]='%';                     flag=1;}                 else if(PIN[j]=='1'){                     PIN[j]='@';                     flag=1;}                 else if(PIN[j]=='o'){                     PIN[j]='O';                     flag=1;}                 else if(PIN[j]=='l'){                     PIN[j]='L';                     flag=1;}             }             if(flag==1){                 for(k=0;k<len1;k++) store[N][k]=Team[k];                 store[N][k]=' ';                 for(k=0;k<len2;k++) store[N][k+len1]=PIN[k];                 store[N][len1+len2]='\n';                 N++;             }         }         if(N==0)printf("There is %d account and no account is modified\n",n);         else {             printf("%d\n",N);             for(i=0;i<N;i++){                 for(j=0;j<len1+len2+1;j++){                     printf("%c",store[i][j]);                 }                 printf("\n");             }         }     }     return 0; }


Question: c++

#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string> #include<cstring> #include<sstream> #include<iomanip> using namespace std; int main() { 	int N; 	cin>>N; 	for(int i = 0; i < N; i++) { 		double M; 		cin>>M; 		if(M-(int)M == 0) { 			cout.unsetf(ios::fixed); 			cout<<M<<endl; 		} 		else { 		cout<<setiosflags(ios_base::fixed)<<setprecision(2)<<M<<endl;	 		} 		cout<<setiosflags(ios_base::fixed)<<setprecision(6)<<M<<endl; 	} }

c++	         cout.setf(ios::fixed); 	cout.precision(2); 	cout << 123.000000 << endl;


Question: linux  capability编译报错

我的也是 你是少安装包了。这是我的libcap-devel-2.16-5.5.el6.x86_64 你可以yum安装 yum install libcap-devel

在〈sys/capability.h〉里

如果是 configure生成的makefile 在configure的时候带上 CFLAGS=“-g -O2 -Wall”等 把原先的-Wformat -Werror都去掉 如果是子目录里的，修改config.status文件重新成成libtool来编译。 我是编译其他开源软件遇到时的解决方案希望对你有用。


Question: Ctrl+z 和程序中的EOF是对应的吗？为什么我写这个程序结束不了

ch 应为 int  否则不能保证正确性

while((ch=getchar())!=EOF)  你跟一下代码看看ch读出来的值是多少，是不是跟EOF的值一致不就知道了吗？ 不过控制台程序一般我都用回车来结束输入，判定一下等于'\n'就行了。

Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter


Question: 为什么输出的d会乱了？求大神解答

请检查scanf的返回值。

你两处getchar()得到的都是上一次输入留下的换行符

读%c之前最好都清空一下输入缓冲区fflush(stdin);  #include<stdio.h> void main() { 	double a,d; 	int b; 	char c; 	scanf("%lf",&a); 	scanf("%d",&b); 	fflush(stdin); 	c=getchar(); 	scanf("%lf",&d); 	printf("%c %d %.2f %.2f \n",c,b,a,d); }

fflush用于标准输入行为是未定义的

#include<stdio.h> void main() { 	double a,d; 	int b; 	char c; 	scanf("%lf",&a); 	scanf("%d",&b); 	getchar();//空读前面的回车符 	c=getchar(); 	scanf("%lf",&d); 	printf("%c %d %.2f %.2f \n",c,b,a,d); }

scanf的时候缓冲区末尾会存有回车，所以会影响c即getchar的结果，在输入c之前要进行清空缓冲区操作。  #include<stdio.h> void main() { double a,d; int b; char c; scanf("%lf",&a); scanf("%d",&b); getchar(); c=getchar(); scanf("%lf",&d); printf("%c %d %.2f %.2f \n",c,b,a,d); }


Question: [疑惑]关于memset对结构体清零

引用 7 楼 andyxu111 的回复:自己解决疑惑了！  1.在不使用microLib库的情况下         在keil的编译环境下，memset是四字节进行清零操作的。汇编代码中关键的一步是：         STM r0!,{r2-r3,r2,lr}  方括号中的四个寄存器的值均为0，如果r0（即代表结构体的初始地址），因为是4字节赋值，如果r0并不是4字节对齐的话，就会直接死机；所以当我们在定义数组的时候，如果指定四字节对齐，就不会死机、  2.在使用microLIb之后       通过查看汇编代码，发现此时对memset的实现是单字节进行的，因此不存在字节对齐问题。故程序能正常运行。  从上面的一点来看，microLib虽然减小了代码大小，但是因为没有字节对齐，一次赋值一个字节肯定比一次赋值四个字节来的慢，这也算是一个   时间（性能）换空间的例子吧赞一个

仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("AD sizeof %d\n", sizeof(AD));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("A1 sizeof %d\n", sizeof(A1));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("A2 sizeof %d\n", sizeof(A2));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("A4 sizeof %d\n", sizeof(A4));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("A8 sizeof %d\n", sizeof(A8));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("A16 sizeof %d\n", sizeof(A16));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //

引用 4 楼 DelphiGuy 的回复:但他说的是“偶尔会死机”，并不是数组没有32位对齐就导致死机。所以我觉得这不是memset要求目标地址4字节对齐造成的，应该没有这种限制。而是struct _RIP_MSG这个结构编译器是做了对齐处理的，你把它放在非对齐地址上，生成的代码访问成员可能错位了，这本身也不会造成死机，而是在数据处理部分出现问题。   我程序是运行到 memset这句的时候死机的，而且为了找原因，我就抠出了帖子中的那几句话，并未做其他任何的数据处理。  后来我发现，KEIL下有一个 microLib，勾选了的话，不管对不对齐都可以运行。     因此，我的问题就变成了，死机到底是如何造成的？我在研究下，应该是跟编译器的编译选项有关系，我去研究下microLib

印象中VS的memset的实现是不需要4字节对齐的  也可能某些系统上memset使用特殊的实现，要求数据必须对齐。

因为 每种CPU对对齐的处理不同吧  有的能正确处理对其问题，有的不能 有的可以设置对其处理模式  Keil 可 以开发各种CPU的程序， 大体上说，这可能不是开发环境的问题 也不排除Keil 有Bug；对某种CPU处理不完善 不过，个人感觉这是正常情况，不是Bug 但是，鉴于本人对Keil 了解不很深刻，这个结论未必正确 如果是Bug可以告知 Keil的开发者，想必他们会乐意解决这个问题的 。。。。。。。。。 PS： 很多人用的keil 是盗版的，不知道有没有问题 不知道你的 keil 是什么情况

要不要4字节对齐，好像和开发环境，执行环境有关


Question: c语言问题 求大神解决

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

是啊，按版主说的自己学学调试吧，况且根据你的描述，也根本不知道是什么问题

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

运行出错时点中断，然后通过调用堆栈、变量监视等窗口观察分析原因


Question: c语言问题，求大神解决

对，自己尝试着调试，这比会写代码更重要

运行出错时点中断，然后通过调用堆栈、变量监视等窗口观察分析原因


Question: C语言通过ODBC连接access数据库总是不成功，求各位大神帮解决，谢谢

在64位Windows下： 64位exe和dll在目录c:\windows\system32目录下； 32位exe和dll在目录c:\windows\syswow64目录下； 所以要注意：     在win64位系统下注册32位ocx或dll需要将32位ocx或dll拷贝到c:\windows\syswow64\目录下。     且注册要用c:\windows\syswow64\regsvr32 xxxxxxx.ocx或dll     在win64位系统下设置32位程序使用的数据库别名要用c:\windows\syswow64\cliconfg.exe     在win64位系统下设置32位程序使用的系统DSN要用c:\windows\syswow64\odbcad32.exe

最后我自己解决了，不过调用的是sql server数据库，不是access数据库。 步骤： 1. 把数据库放到系统DSN中； 2. 写程序； 3. 将项目属性中的“字符集”改为“未设置”（一定要改，否则返回值始终是-1），如下图所示。  附上我写的代码（其实是复制别人的） #include   <windows.h>    #include <sqlext.h> //这个应该是必须的, 链结时需要odbc32.lib #include <stdio.h> #include <stdlib.h>   void main() {  	SQLHENV     henv; 	SQLHDBC     hdbc; 	SQLHSTMT    hstmt; 	SQLRETURN   retcode;  	/*Allocate environment handle */ 	retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  	if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 		/* Set the ODBC version environment attribute */ 		retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);  		if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 			/* Allocate connection handle */ 			retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  			if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 				/* Set login timeout to 5 seconds. */ 				SQLSetConnectAttr(hdbc, /*(void*)*/SQL_LOGIN_TIMEOUT, (void*)5, 0);  				/* Connect to data source */ 				retcode =SQLConnect(hdbc, (SQLCHAR*) "Wall_PRF", SQL_NTS,(SQLCHAR*) "ABCD", SQL_NTS,(SQLCHAR*) "123456789", SQL_NTS);  				if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){ 					/* Allocate statement handle */ 					retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 					printf("Connect Wall_PRF database success!\n");           					retcode = SQLPrepare(hstmt, (SQLCHAR*)"select * from Wall_PRF where ID=1", SQL_NTS); //准备sql查询  					retcode = SQLExecute(hstmt); //执行SQL命令  					SQLINTEGER cbsatid = SQL_NTS;  					while (SQLFetch(hstmt) != SQL_NO_DATA_FOUND) //循环从结果集中取每一行数据 					{ 						SQLINTEGER id; 						SQLDOUBLE PRF0; 						SQLDOUBLE PRF1; 						SQLCHAR Weight_Type[42];  						SQLGetData(hstmt, 1, SQL_C_LONG, &id, sizeof(SQLINTEGER), &cbsatid); 						SQLGetData(hstmt, 2, SQL_C_DOUBLE, &PRF0, sizeof(SQLINTEGER), &cbsatid); 						SQLGetData(hstmt, 3, SQL_C_DOUBLE, &PRF1, sizeof(SQLINTEGER), &cbsatid); 						SQLGetData(hstmt, 26, SQL_C_CHAR, Weight_Type, 10, &cbsatid);  						printf("id is:%ld, PRF[0] is :%lf, PRF[1] is :%lf, Weight_Type is:%s\n", id, PRF0,PRF1, Weight_Type); //打印取得的值} 					}  					if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 						/* Process data */  						SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 					} 					SQLDisconnect(hdbc); 				} 				SQLFreeHandle(SQL_HANDLE_DBC, hdbc); 			} 		} 		SQLFreeHandle(SQL_HANDLE_ENV, henv); 	}  	system("pause"); }


Question: 谁能形象的讲解一下宏定义的作用？

你和小伙伴约定，我喊 1，你就读：一行白鹭上青天 #define a abcdefg（也可以是很长一段代码一个函数） 同理宏就相当于你和编译器之间的约定，你告诉它 我写 a 就是后面那段内容。 okay，预编译的时候 它一看噢 a是这个 它就在这时候把所有的a都替换成了后面那个。

宏有两种 1）不带参数的宏       宏常量，以及其他各种宏表达式      这种宏 通常会直接替换掉      2）带参宏，可以当作函数用 这种宏，替换的时候，参数也相应的替换掉

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

代码替换，注意是代码级替换，不是变量的赋值。注意！注意！注意！ 通常用法： （1）常量代换，如#define  BTN_FILE  1    #define BTN_EDIT  2 （2）调试使用：#define DEBUG （3）.h文件头防止重复包含 等等

如果能形象地描述出来，那就不是宏定义了

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

宏定义分类：   （1）不带参数的宏定义   形式： #define 宏名 [宏体] 功能：可以实现用宏体代替宏名 使用实例： #define TRUE 1 作用：程序中多次使用TRUE，如果需要对TRUE的值进行修改，只需改动一处就可以了     （2）带参数的宏： #define 宏名 ( 参数表) [宏体]     宏定义作用：   （1）方便程序的修改   上面的#define TRUE 1就是一个实例   （2）提高程序的运行效率   宏定义的展开是在程序的预处理阶段完成的，无需运行时分配内存，能够部分实现函数的功能，却没有函数调用的压栈、弹栈开销，效率较高  （3）增强可读性   这点不言而喻，当我们看到类似PI这样的宏定义时，自然可以想到它对应的是圆周率常量   （4）字符串拼接    例如： #define CAT(a,b,c) a##b##c   main() {     printf("%d\n" CAT(1,2,3));     printf("%s\n", CAT('a', 'b', 'c'); }   程序的输出会是：   123 abc     （5）参数转化成字符串   示例：   #defind CAT(n) "abc"#n   main() {     printf("%s\n", CAT(15)); }   输出的结果会是 abc15   （6）用于程序调试跟踪 常见的用于调试的宏有，_ L I N E _，_ F I L E _，_ D A T E _，_ T I M E _，_ S T D C _ （7）实现可变宏 举例来说： #define PR(...) printf(_ _VA_ARGS_ _)

代码级别文本展开，改的是代码本身，很强大，所以不要乱用


Question: 我实在不知道自己的代码哪里错了  请指教

#include<stdio.h> #include "string.h"  struct {     int num;     char name[10];     char sex;     char job;     union     {         int class1;         char position[10];     }category; }person[4];  int main() {     int i, n;     n = 2;     for(i = 0; i < n; i++)     {         printf("请输入您的职业：");         scanf(" %c", &person[i].job);         if('t' == person[i].job)         {             printf("请输入老师学号：");             scanf(" %d", &person[i].num);             printf("请输入老师的姓名：");             scanf(" %s", person[i].name);             printf("请输入性别：");             scanf(" %c", &person[i].sex);              printf("++++debug++++\n");             printf("请输入老师的职务：");             scanf(" %s", person[i].category.position);         }         else if('s' == person[i].job)         {             printf("请输入学生学号：");             scanf(" %d", &person[i].num);             printf("请输入学生的姓名：");             scanf(" %s", &person[i].name[0]);             printf("请输入性别：");             scanf(" %c", &person[i].sex);             printf("请输入学生的班级：");             scanf(" %d", &person[i].category.class1);         }         else         {             printf("输入错误！\n");             return 0;         }     }      printf("\nnum\tname\tsex\tjob\tclass or position\n");     for(i = 0; i < n; i++)     {         printf("%d\t%s\t%c\t%c\t", person[i].num, person[i].name, person[i].sex, person[i].job);         if('s' == person[i].job)         {             printf("%d\n", person[i].category.class1);         }         else         {             printf("%s\n", person[i].category.position);         }     }     return 0; } 主要是scanf的格式化输入，看我的如：scanf(" %c", &person[i].sex);内的空格 运行后为： 请输入您的职业：t 请输入老师学号：1234 请输入老师的姓名：zhangsan 请输入性别：m ++++debug++++ 请输入老师的职务：shuxue 请输入您的职业：s 请输入学生学号：5678 请输入学生的姓名：lisi 请输入性别：h 请输入学生的班级：5  num     name    sex     job     class or position 1234    zhangsan        m       t       shuxue 5678    lisi    h       s       5 Press any key to continue

在使用scanf输入char的时候第一次会读取上一次滞留的回车，所以可以进行两次读取或者清空缓存。另外就是不能使用保留字class,其他的没什么问题，下面是正确的代码：  #include<stdio.h> #include "string.h"  struct {     int num;     char name[10];     char sex;     char job;     union     {         int myclass;         char position[10];     }category; }person[4];  int main() {     int i, n;     n = 4;     for(i = 0; i < n; i++)     {         printf("请输入您的职业：");         scanf("%c", &person[i].job);         if('t' == person[i].job)         {             printf("请输入老师学号：");             scanf("%d", &person[i].num);             printf("请输入老师的姓名：");             scanf("%s", person[i].name);             printf("请输入性别："); 			getchar();             scanf("%c", &person[i].sex);              printf("++++debug++++\n");             printf("请输入老师的职务：");             scanf("%s",person[i].category.position); 			getchar();         }         else if('s' == person[i].job)         {             printf("请输入学生学号：");             scanf("%d", &person[i].num);             printf("请输入学生的姓名：");             scanf("%s", &person[i].name[0]);             printf("请输入性别："); 			getchar();             scanf("%c", &person[i].sex);             printf("请输入学生的班级：");             scanf("%d", &person[i].category.myclass); 			getchar();         }         else         {             printf("输入错误！\n");             return 0;         } 		printf("\n");     }          printf("\nnum\tname\tsex\tjob\tclass or position\n");     for(i = 0; i < n; i++)     {         printf("%d\t%s\t%c\t%c\t", person[i].num, person[i].name, person[i].sex, person[i].job);         if('s' == person[i].job)         {             printf("%d\n", person[i].category.myclass);         }         else         {             printf("%s\n", person[i].category.position);         }     }     return 0; }

你想实现什么功能，出的错又是什么呢

虽然不知道你写的是什么，class是个关键字，你int真的好嘛。


Question: 【求】求高手告知这段程序哪出错了

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


Question: wireshark过滤规则的bug?

把&http加到第一种过滤条件

引用 10楼我是你的主体 的回复:[quote=引用 9 楼 user-1 的回复:] 默认wireshark勾选Edit->Preferences->protocols->TCP菜单的Allow sub dissector to reassemble TCP streams！！！ 如果不勾选：  厉害，我无意中发现firefox对tomcat首页处理的时候（我测试的环境是： tomcat+apache, fireforx， 网站就是tomcat自带的！！！）  抓的包， 然后去查看报文，发现第97个包说明了firefox搞了并行访问http服务器！！  这是现代浏览器的技术，可以让http请求并行！！！   我有一个新的问题（我就不开贴了，直接在这里请教吧），新问题是：  目前的网站有没有这种搭建的情景：  2台机器构建一个网站，其中部分资源在第2台机器上，  用户去访问该网站的时候，会做几个tcp连接（先抛开 浏览器的并行访问技术），  我本身不懂Web开发，可以说，这些场景都是我意淫出来的。   用户的机器会不会和 2台机器做不同的tcp连接？  还是说用户只和域名对应的ip的机器做tcp连接？     [/quote]这要看客户端和谁建立的tcp，这种情况具体我没有分析过，暂无法回答

引用 9 楼 user-1 的回复:默认wireshark勾选Edit->Preferences->protocols->TCP菜单的Allow sub dissector to reassemble TCP streams！！！ 如果不勾选：  厉害，我无意中发现firefox对tomcat首页处理的时候（我测试的环境是： tomcat+apache, fireforx， 网站就是tomcat自带的！！！）  抓的包， 然后去查看报文，发现第97个包说明了firefox搞了并行访问http服务器！！  这是现代浏览器的技术，可以让http请求并行！！！   我有一个新的问题（我就不开贴了，直接在这里请教吧），新问题是：  目前的网站有没有这种搭建的情景：  2台机器构建一个网站，其中部分资源在第2台机器上，  用户去访问该网站的时候，会做几个tcp连接（先抛开 浏览器的并行访问技术），  我本身不懂Web开发，可以说，这些场景都是我意淫出来的。   用户的机器会不会和 2台机器做不同的tcp连接？  还是说用户只和域名对应的ip的机器做tcp连接？

引用 7 楼 user-1 的回复:  好吧，可能wireshark的显示有点诡异， 不能“直接显示”出150封包来。  呵呵。  不管如何，非常感谢

引用 5 楼 u012879787 的回复:[quote=引用 3 楼 user-1 的回复:] [quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 user-1 的回复:] 把&http加到第一种过滤条件  为啥要加？   加了之后，我发现还是漏到某个http包。[/quote]漏掉的http是101机器和102机器之间的http报文吗？？？[/quote]   大神尝试的结果如何？  [/quote]是TCP segment of a reassembled PDU  这个TCP包吗？

引用 3 楼 user-1 的回复:[quote=引用 2 楼 u012879787 的回复:] [quote=引用 1 楼 user-1 的回复:] 把&http加到第一种过滤条件  为啥要加？   加了之后，我发现还是漏到某个http包。[/quote]漏掉的http是101机器和102机器之间的http报文吗？？？[/quote]   大神尝试的结果如何？

引用 1 楼 user-1 的回复:把&http加到第一种过滤条件   http://pan.baidu.com/s/1bpkHsUr  pcpa文件在这里  过滤条件 在只贴里，你试试就可。  注意 第 150 包， 我反正加上&&http后，第150个包（http)就会丢失！！！！

引用 2 楼 u012879787 的回复:[quote=引用 1 楼 user-1 的回复:] 把&http加到第一种过滤条件  为啥要加？   加了之后，我发现还是漏到某个http包。[/quote]漏掉的http是101机器和102机器之间的http报文吗？？？

引用 1 楼 user-1 的回复:把&http加到第一种过滤条件  为啥要加？   加了之后，我发现还是漏到某个http包。


Question: VS2015 c++找不到目标合适的SDK

先彻底卸载完全。 参考：http://tieba.baidu.com/p/3996550898 然后重新安装。

应该你安装的时候没有完整安装，重新彻底卸载了安装一下


Question: 不懂错在哪

你贴的代码有问题，输入3（1（，4），2（0，9））@不行

楼主哪里复制来的代码？ 错误一大坨。 稍微改了下  #include<stdio.h> #include<stdlib.h>  #define N 100 typedef struct binode{ 	char data; 	struct binode *lchild,*rchild; }bitree; bitree*p,*root; bitree* creatbt() { 	int flag=0; 	int top=-1; 	bitree *stack [N]; 	root=NULL; 	char ch; 	while(1) 	{ 		scanf("%c",&ch); 		switch(ch){ 		default: 			p=(bitree*)malloc(sizeof(bitree)); 			p->data=ch; 			p->lchild=NULL; 			p->rchild=NULL; 			if(root==NULL) 				root=p; 			else if (flag==1) 				stack[top]->lchild=p; 			else 				stack[top]->rchild=p; 		case '(':top++;stack[top]=p;flag=1;break; 		case ',':flag=2;break; 		case ')':top--;break; 		case'@':return(root);break; 		} 	} }  void preorder(bitree *root) { 	if(root!=NULL) 	{ 		printf("%c",root->data); 		preorder(root->lchild); 		preorder(root->rchild); 	} } int main() { 	int ah; 	bitree *creatbt(); 	void preorder(bitree *root); 	bitree *b; 	while(1) 	{ 		printf("输入选择："); 		scanf("%d",&ah); 		switch(ah){ 		case 1:b = creatbt();break; 		case 2:preorder(b);break; 		} 	}  }  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 从论坛上复制了一段C语言代码，，但是总是报错，，希望可以有人帮忙看一下

楼主的代码根本就不是实现   把几个Txt文件里><内容写入到另一个Txt文件里面  的功能啊。


Question: c语言 输入该年月日，求是第几天

为什么return 0报错

楼上两位都只改了一半。。。。。 1.for循环从1开始没关系，z = z + a[i];应该改成z = z + a[i-1]; 2.同时z的初值应该赋值为day  #include<stdio.h> int main() {     int riqi(int,int,int);     int year,month,day,c;     printf("请输入年月日");     scanf("%d %d %d",&year,&month,&day);     c=riqi(year,month,day);     printf("%d\n",c);     return 0; } int riqi(int year,int month,int day) {     int z=day;     int i;     int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};     for(i=1;i<month;i++)     {         z=z+a[i-1];     }     if((year%4==0&&year%100!=0||year%400==0)&&month>=3)         z=z+1;     return z; }

int z=0;改成int z=day;   #include<stdio.h> int main() { 	int riqi(int,int,int); 	int year,month,day,c; 	printf("请输入年月日"); 	scanf("%d %d %d",&year,&month,&day); 	c=riqi(year,month,day); 	printf("%d\n",c); 	return 0; } int riqi(int year,int month,int day) { 	int z=day; 	int i; 	int a[12]={31,28,31,30,31,30,31,31,30,31,30,31}; 	for(i=1;i<month;i++) 	{ 		z=z+a[i]; 	} 	if((year%4==0&&year%100!=0||year%400==0)&&month>=3) 		z=z+1; 	return z; }

数组下标从0开始，for循环中i的初值应该是0。

#include<stdio.h> int main() {     int riqi(int,int,int);     int year,month,day,c;     printf("请输入年月日");     scanf("%d %d %d",&year,&month,&day);     c=riqi(year,month,day);     printf("%d\n",c);     return 0; } int riqi(int year,int month,int day) {     int z=day;     int i;     int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};     for(i=1;i<month;i++)     {         z=z+a[i];     }     if((year%4==0&&year%100!=0||year%400==0)&&month>=3)         z=z+1;     return z; }   你们输入一个1999 2 1看一下  为什么是29天呢？

引用 5 楼 user-5 的回复:[quote=引用 3 楼 qq423399099 的回复:] 楼上两位都只改了一半。。。。。 1.for循环从1开始没关系，z = z + a[i];应该改成z = z + a[i-1]; 2.同时z的初值应该赋值为day  #include<stdio.h> int main() {     int riqi(int,int,int);     int year,month,day,c;     printf("请输入年月日");     scanf("%d %d %d",&year,&month,&day);     c=riqi(year,month,day);     printf("%d\n",c);     return 0; } int riqi(int year,int month,int day) {     int z=day;     int i;     int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};     for(i=1;i<month -1;i++)     {         z=z+a[i-1];     }     if((year%4==0&&year%100!=0||year%400==0)&&month>=3)         z=z+1;     return z; }   month 应该减1 [/quote] 你上面发上来的自己测试过吗？ 输出的是123，不觉得自己多算了一个月吗 要么for(i=1;i<month;i++) 或者for(i=0;i<month-1;i++)

引用 4 楼 user-5 的回复:数组下标不能乱来啊，应该从0开始  int riqi(int year, int month, int day) {     int i;     int z = day;     int a[12] =     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };     for (i = 0; i < month -1 ; i++)     {         if(i == 1) // 二月         {             if (((year % 4 == 0 && year % 100 != 0 )|| year % 400 == 0))                     z = z + 1;         }         z = z + a[i];     }     return z; }  void test_day_num() {     int riqi(int, int, int);     int year, month, day, c;     year = 2014 ;     month = 4 ;     day = 3;     c = riqi(year, month, day);     printf("%d\n", c); }  month 应该减1 就正确

引用 3 楼 qq423399099 的回复:楼上两位都只改了一半。。。。。 1.for循环从1开始没关系，z = z + a[i];应该改成z = z + a[i-1]; 2.同时z的初值应该赋值为day  #include<stdio.h> int main() {     int riqi(int,int,int);     int year,month,day,c;     printf("请输入年月日");     scanf("%d %d %d",&year,&month,&day);     c=riqi(year,month,day);     printf("%d\n",c);     return 0; } int riqi(int year,int month,int day) {     int z=day;     int i;     int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};     for(i=1;i<month -1;i++)     {         z=z+a[i-1];     }     if((year%4==0&&year%100!=0||year%400==0)&&month>=3)         z=z+1;     return z; }   month 应该减1

数组下标不能乱来啊，应该从0开始  int riqi(int year, int month, int day) {     int i;     int z = day;     int a[12] =     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };     for (i = 0; i < month; i++)     {         if(i == 1) // 二月         {             if (((year % 4 == 0 && year % 100 != 0 )|| year % 400 == 0))                     z = z + 1;         }         z = z + a[i];     }     return z; }  void test_day_num() {     int riqi(int, int, int);     int year, month, day, c;     year = 2014 ;     month = 4 ;     day = 3;     c = riqi(year, month, day);     printf("%d\n", c); }


Question: fd_set 是什么类型

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

结构体，建议查阅msdn

其实这是一个数组的宏定义，数组的类型是(unsigned) long型的(个人推测无符号)，占有128位，无论是32位的linux下，还是64位下，他都是128个字节（128*8位=1024位，也就是可以检测1024个任务，这也是select默认的个数，可以通过编译内核修改），但是由于不同位数的系统下long型的长度不同，所以导致数组的元素个数也是不同的。 参考：http://blog.csdn.net/xluren/article/details/8180753


Question: 求助：char指针和signed char指针 为何不能相互赋值

引用 9 楼 lm_whales 的回复:因为 ASCII编码只有 127 以内的128 个 所以，开始的时候，char类型，就不需要 128 以上的编码 因此，不很重视 他是有符号，还是无符号  如果是 一开始，就超过128 估计就固定下来了 由于开始没固定，后来标准里面就没表态 然后就成现在这个样子，由实现决定。  恩恩  理解了  谢谢

引用 6 楼 paschen 的回复:[quote=引用 4 楼 andyxu111 的回复:] [quote=引用 2 楼 user-3 的回复:] char到底解释为 无符号还是有符号取决于编译器 所以从语言角度来说，无法保证“signed char ”和“char”是同样的类型，也无法保证“signed char* ”和“char*”是同样的类型，语言层面上禁止这两类变量之间相互复制，很正常   	signed char var1; 	 char var2 = var1; 为什么不是指针的赋值就可以编译通过呢？[/quote]  因为这个符合隐式转换条件，但不同类型的指针不符合[/quote]   版主这么讲我就能说服自己了，谢谢

一般char默认是 signed char。但是由于系统实现及历史遗留原因 导致部分系统或者编译器使用unsigned char，所以在指针转换时需要进行强制转换

引用 4 楼 andyxu111 的回复:[quote=引用 2 楼 user-3 的回复:] char到底解释为 无符号还是有符号取决于编译器 所以从语言角度来说，无法保证“signed char ”和“char”是同样的类型，也无法保证“signed char* ”和“char*”是同样的类型，语言层面上禁止这两类变量之间相互复制，很正常   	signed char var1; 	 char var2 = var1; 为什么不是指针的赋值就可以编译通过呢？[/quote]  因为这个符合隐式转换条件，但不同类型的指针不符合

引用 3 楼 andyxu111 的回复:signed int *var1; 	 int *var2 = var1;这个是可以编译通过的   那也就说 本质上是因为 char 的特殊性才导致：  	signed char *var1; 	 char *var2 = var1;  这个编译不通过？  那是因为signed int 就是 int

引用 2 楼 user-3 的回复:char到底解释为 无符号还是有符号取决于编译器 所以从语言角度来说，无法保证“signed char ”和“char”是同样的类型，也无法保证“signed char* ”和“char*”是同样的类型，语言层面上禁止这两类变量之间相互复制，很正常   	signed char var1; 	 char var2 = var1; 为什么不是指针的赋值就可以编译通过呢？

除了void*指针，其他不同类型的指针是不能直接赋值的  你需要写成 char *var2 = (char *)var1;


Question: 最大公约数 最小公倍数问题，用函数写。

#include<stdio.h> int main() {     int yshu(int,int);     int bshu(int,int,int);     int a,b;     int m,n;     scanf("%d %d",&a,&b);     m=yshu(a,b);     n=bshu(a,b,m);     printf("%d\n",m);     printf("%d\n",n);     return 0; } int yshu(int a,int b) {     int c,t;     if(a<b)     {         t=a;         a=b;         b=t;     }      while(b!=0)     {         c=a%b;         a=b;         b=c;     }     return a; } int bshu(int a,int b,int m) {     return (a*b/m); }  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

你代码这里c应该改成t吧  		t=a; 		a=b; 		b=c;


Question: 崩溃了，完全不知道怎么回事？

a[10]=0；有问题 a[10]  相当于后面这个  *（a+10）对后面的内存解除引用是很危险的 不一定奔溃（你可以在int a[10]后面在加一个int i=0；试试。 看运气。

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

引用 5 楼 qq_25868549 的回复:[quote=引用 2 楼 paschen 的回复:] 删除a[10] = 0;这一句，其他没问题  大神，问下，他虽然a[10] = 0;，但printf并没有输出a[10]，为什么会崩溃呢？[/quote]  越界了

引用 5 楼 qq_25868549 的回复:[quote=引用 2 楼 paschen 的回复:] 删除a[10] = 0;这一句，其他没问题  大神，问下，他虽然a[10] = 0;，但printf并没有输出a[10]，为什么会崩溃呢？[/quote]  可以利用a[10] 进行寻址，但是却不能对其进行赋值操作。这是C比较特别的地方

引用 2 楼 paschen 的回复:删除a[10] = 0;这一句，其他没问题  大神，问下，他虽然a[10] = 0;，但printf并没有输出a[10]，为什么会崩溃呢？

int a[10];这样子的数组，一般可以操作的是a[0]到a[9]的，出现a[10]这样的东西，感觉都是违法的哦！

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

看楼主的程序是在做冒泡排序。数组a定义10个元素，下标是0-9，给a[10]赋值是不对的，会数组越界。 建议楼主可以把数组的大小定义成宏，这样这种小程序好扩展

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

删除a[10] = 0;这一句，其他没问题

#include<stdio.h>  int main() { 	int a[10]; 	int i,j,swap=0; 	/*a[10] = 0;//只有0-9是有效能用的下标，这里a[10]等于0是啥意思？直接删掉就能过*/ 	for (i = 0; i <= 9; i++) 	{  		printf("请输入a[%d]:", i); 		scanf("%d", &a[i]); 	} 	for (i = 8; i >=0; i--) 		for (j = 0; j <= i;j++) 		{ 			if (a[j] > a[j + 1]) 			{ 				swap=a[j]; 				a[j]=a[j+1]; 				a[j+1]=swap; 			}  		}  		for (i = 0; i <= 9; i++) 			printf("a[%d]=%d\n", i, a[i]); 		return 0;  }


Question: 求大神帮忙看下算法的错误

//不带表头结点的单向链表 #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-> //   单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

算法的错误暂时还看不明白，先解决你语法的错误，关于算法部分你还是提供一份文字说明吧 #include "stdio.h" #include "malloc.h"  //int maxzu(int x,int y); //再简单的函数也要入栈和出栈，如果功能太简单了就没有必要用函数了 #define maxzu(x,y) ((x)>(y)?x:y)  typedef struct node {     int a;     struct node *next; } linknode,*link;  link Creatlist() {     int num;     link H,r,p;	//分别保存链表的头、当前项和下一项     H=(link)malloc(sizeof(linknode));     r=H;     printf("please put the num:");     scanf("%d",&num);     while (num!=35)     {         p=(link)malloc(sizeof(linknode));         p->a =num;         r->next=p;         r=p;         printf("please put num:");         scanf("%d",&num);     }     r->next=NULL;     return H; }  link Adjmax(link H,int k)	//缺返回值 {     link p1,p2,p3;     p1=H;     int i=1,max[100]/*,maxfinal,nodefinal*/;     //int cachevalue[100];     //cachevalue[0]=0; 	//从前到尾只用了cachevalue[0]，炫富的节奏 	int cachevalue = 0;     max[0]=1;     for(int j=0; max[j]!=NULL; j++)	//此处用未初始化的max数组作为判断依据，不同编译器下表现不同 									//虽然NULL==0,但一般情况下NULL还是表示指针比较好，值用0     {          p1=p1->next;         p2=p1;	         for(/*i*/; i<=k; i++) //初始化为可选项         {             p3=p2;             cachevalue/*[0]*/+=p3->a;  //到底怎么相加的，太乱了吧             p2=p3->next;                      //p3->next==NULL时，下一轮循环就该报错了         }         max[j]=cachevalue/*[0]*/; 		//看也好久也没明白到底在干什么，你最好直接用文字描述你的需求吧     } 	//int m;     int m = max[0],n=0; 	//for(int f=1,m=max[0],n=0; f<10; f++) 	//int f=1,m=max[0],n=0; 等价于 int f=1; int m=max[0]; int n=0; 	//作用域仅限for循环内部，错误 	for(int f=1; f<10; f++)     {         if (maxzu(m,max[f])>m)         {             //m=maxzu(m,max[f]); 			m = max[f];	//maxzu(m,max[f])>m的情况下，maxzu(m,max[f])必定等于max[f]，还是炫富             n=f;         }     }     //printf("序号/n值/n",n+1,m); 	//格式化字符串，不知道你想表达什么，就按我的意思改了 	printf("序号%d值%d\n",n+1,m);  	return NULL;	//到底要返回什么我也不知道，先这样吧 } /* int maxzu(int x,int y) {     return(x>y? x:y); } */  void main() {     link L;     L=Creatlist();     int k;     printf("please put the k");     //scanf("%d",k); 	scanf("%d",&k);     //Adjmax(H,k); 	Adjmax(L,k); }

Adjmax(H,k);  这句H没有定义


Question: linux下为什么系统调用比库函数更占资源，库函数不是会调用系统调用吗？

引用 2 楼 tiyorn 的回复:可是库函数的实现不是通常也要通过调用系统调用吗？ 一般IO操作的库函数都需要系统调用 fopen fread之类的 但不需要系统调用的也很多啊 memcpy strcpy

可是库函数的实现不是通常也要通过调用系统调用吗？

库函数调用通常比行内展开的代码慢，因为它需要付出函数调用的开销。但系统调用比库函数调用还要慢很多，因为它需要把上下文环境切换到内核模式。


Question: 链表头指针的问题

静态变量作用范围在一个文件内，程序开始时分配空间，结束时释放空间，默认初始化为0，使用时可以改变其值。  静态变量或静态函数只有本文件内的代码才能访问它，它的名字在其它文件中不可见。  详见：http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777441.html

static变量仅作用于当前CPP文件

因为你声明的 head 是 static 的，所以它在不同的编译单元（b.c / c.c）中就是互相独立的，修改其中一个不会影响另一个。


Question: 讨论C语言中局部变量的存储地址

有没关系你要看生成的汇编代码

理解和讨论之前请先学会如何观察！  计算机组成原理→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执行停在该断点处的时候。  栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……  在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

http://open.163.com/movie/2008/1/J/K/M6SL23BRS_M6SL33KJK.html 请楼主先看第8课后半段，然后再看第10课，基本上能解释清楚你遇到的问题了……  如果有时间，建议整个课程看一遍.....

1）有一个理想的安排方式，即按照定义的先后和层次，安排位置，发布版，差不多会这样安排 2）编译器不必非得按照理想方式，安排，可以比较随意一点，灵活一点

要看增长方向只要再调用一层函数啊，同一层的编译器想怎么安排就这么安排啊


Question: 求高手指点！！！

以VC2010为例：  string.h对应文件： C:\Program Files\Microsoft Visual Studio 10.0\VC\include\string.h  string对应文件： C:\Program Files\Microsoft Visual Studio 10.0\VC\include\string  别拿豆包不当干粮，别拿没扩展名的头文件不当头文件。  请亲自用记事本打开这两个文件看看吧。

看完这个你就明白了：http://blog.csdn.net/kobesdu/article/details/38304523

string是c++字符串标准库类，string.h是c语言的字符串类 并不是毫无关系，string是根据c风格字符串创建的类 string.h在c++头文件写成cstring

用尖括号 #include <>： 一般用于包含标准的库头文件，编译器会去系统配置的库环境变量和者用户配置的路径去搜索，而不会在项目的当前目录去查找。 用双引号 #include ""： 一般用于包含用户自己编写的头文件，编译器会先在项目的当前目录查找，找不到后才会去系统配置的库环境变量和用户配置的路径去搜索。

string是C++的， "(引号)与<(尖括号)的不同是搜索头文件目录优先的问题


just try GCC

可以装，但兼容不好，实在装不上也可以用虚拟机装，但不建议用了，快20年的东西了  http://blog.csdn.net/cometnet/article/details/19551125

珍爱生命 远离vc6.0

win7以上就兼容不太好了，建议用vs，如果一定要vc6,还不如用虚拟机xp跑vc6


Question: C语言大循环嵌套问题

再回到第一个循环？递归不更好吗

嗯嗯。有道理，谢谢啦

while(1) {     if(条件1)     {         while(1)         {             if(条件2)             {                 break;             }         }     } }

while(1) 	{ 		if(...) 		{ 			while(...) 			{ 				if(...) 				{ 					break; 				} 			} 		} 	}


Question: 子进程多个socket

说说你的这个功能是用在什么地方的

觉得你的思路有点问题，正常一般做法都是这样的。  服务端每收到一个连接请求，就fork 一个进程，这样子进程和父进程都共享了 监听socket ，acceptsocket，  fork 之后，父进程close accept 到的socket ， 子进程close 监听socket ，这样，子进程 按照正常的socket 收发进行通信。  同理，如果你非要等到3个连接都来来再fork ，按照一个连接的情况处理也是一样的， fork 之后，一个一个socket 再通信，父进程不管子进程的socket .


Question: nginx, apache httpd等服务器的反向代理有什么优点？

自己up一下，up一下


Question: c++模板

Point类型是什么来的？

错误说得很明白了啊，你传进去的是Point的数组，而Point类型没有重载操比较作符( < 或 > )

修改过了还是报错 #include<iostream> using namespace std; template<typename T> int find_lower_bound(T seq[],int n,const T& value)  { 	int index=-1; 	T max; 	int you=0; 	for(int i=0;i<n;i++) 	{ 		if(seq[i]<value) 		{ 			you=1; 			index=i; 			max=seq[i]; 			break; 		} 	} 	if(you==0) 	{ 		return -1; 	} 	else 	{ 		for(int i=0;i<n;i++) 		{ 			if(seq[i]>max&&seq[i]<value) 			{ 				max=seq[i]; 				index=i; 			} 		}  	} 	return index; }

题目要求找 index ，而你的程序找的是值

#include<iostream> using namespace std; template<typename T> int find_lower_bound(T seq[],int n,const T& value)  { 	T max; 	int you=0; 	for(int i=0;i<n;i++) 	{ 		if(seq[i]<value) 		{ 			you=1; 			max=seq[i]; 			break; 		} 	} 	if(you==0) 	{ 		return -1; 	} 	else 	{ 		for(int i=0;i<n;i++) 		{ 			if(seq[i]>max&&seq[i]<value) 			{ 				max=seq[i]; 			} 		}  	} 	max=(int)max; 	return max; }

这是我写的代码和报的错，求错误的参考


Question: 问一个关于用PlaySound函数播放音乐的问题

SND_ASYNC 异步播放


Question: 二维数组旋转不借助临时工作数组

参考：  #include <stdio.h> #include <string.h> #include <stdlib.h>  void swap(int* a,int *b){ 	int t=*a; 	*a=*b; 	*b=t; }    void transp(int a[][3],int n){  	int i,j;  	for(i=0;i<n;i++) 		for(j=i+1;j<n;j++) 			swap(&a[i][j],&a[j][i]);  	for(i=0;i<n/2;i++) 		for(j=0;j<n;j++) 			swap(&a[i][j],&a[n-1-i][j]); }  int main(){  	int a[][3]={ 		{1,2,3}, 		{4,5,6}, 		{7,8,9} 	};  	int i,j;  	for(i=0;i<3;i++) 		for(j=0;j<3;j++) 		{ 			printf("%d\t",a[i][j]); 			if(2==j) printf("\n"); 		}  		printf("\n");  		transp(a,3);  		for(i=0;i<3;i++) 			for(j=0;j<3;j++) 			{ 				printf("%d\t",a[i][j]); 				if(2==j) printf("\n"); 			}  			return 0; }

先来个两步的 123 456 789 --->行交换 789 456 123 ----> 然后 37交换。68交换，24交换 三条主对角线的元素交换，位置 为 x+y=a 3,6,9 2,5,8 1,4,7  也可一步交换 只要找清楚规律即可


Question: 编写一个c程序，实现两个分数的加减法 。函数比较特别，求帮助,需要注释！

1)分子分母比较小，用整数存储，通分计算 2）分子分母很大，通分后 最大整数存储会溢出 直接用字符串做大整数加减乘除

仅供参考：  #include<stdio.h> #include<stdlib.h>  char *sr(char *strjs) { 	 long int a,b,c,d,i,x,y,z;     char op; 	sscanf(strjs, "%ld/%ld%c%ld/%ld", &b,&a,&op,&d,&c);      if(a==0||c==0)  	{ 		printf("分母为0输入错误!"); 		exit(0); 	}      if(op=='+'){y=b*c+d*a;x=a*c;}        /*运算结果均为y/x*/      if(op=='-'){y=b*c-d*a,x=a*c;}      if(op=='*'){y=b*d;x=a*c;}      if(op=='/'){y=b/c;x=a/d;}      z=x;      if(x>y) z=y;      i=z;      while(i>1)            /*y/x分子分母约去公因数*/     {         if(x%i==0&&y%i==0){x=x/i;y=y/i;continue;}         i--;      } 	char *res = (char *)malloc(32); 	sprintf(res, "%ld/%ld", y, x); 	return res; }  void main() { 	char str[32] = {0}; 	printf("请输入分数运算式:\n"); 	scanf("%s", str); 	char *jg = sr(str); 	printf("%s\n",jg);  }


Question: 理解不了，比如*curr, *head;可以帮忙注释一下吗解释一下重要语句的作用

如果这都需要解释的话，那么楼主不应该上论坛，而是应该找本数据结构的课本学习一下。 这样会事半功倍的，祝你好运^_^

#include<stdio.h> #include<stdlib.h>  //定义一个结构体 struct list1 { 	int val; 	struct list1 *next; //next指针指向后继结点 }; typedef struct list1 item; //定义别名 void main() { 	item *curr, *head;//定义两个指针，curr用来保存当前的结点，head保存头结点的地址 	int i; 	head = NULL;//将头指针置为NULL 	for (i = 1; i <= 10; i++)//循环10次 	{ 		curr = (item *)malloc(sizeof(item));//malloc一个结点 		curr->val = i;//赋值 		curr->next = head;//将当前malloc出来的结点的next指针指向head 		                 //i=1时，第一个结点的next指针指向NULL，i>1时，将新结点的next指向原来的头结点，在头部拼上新结点 		head = curr;//head指向新结点（因为是头插法，所以让head重新指回当前链表的第一个结点） 	} 	curr = head;//curr指向头结点以输出链表中的元素 	while (curr) 	{ 		printf("%d\t", curr->val); 		curr = curr->next; 	} 	getchar();//调试模式 };  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: vc++调试出来output.c

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

出错时中断下来观察分析原因  判断你出错在(a[k*G->dian+ik->infor->dian1])=+1;  此时ik的值 是NULL，具体情况楼主可单步跟踪程序运行以分析


Question: malloc与free问题

非常感谢各位大神的回答，已解决问题！！学习中，还有很多不懂~

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

让别人直接看你的代码不礼貌吧？啥子错误帖出来？这玩意基本是内存重复释放或空指针引用

目测最后一个节点没释放，直接 赋值为NULL

如楼上所说如果是free的时候崩溃，那么极有可能是越界破坏了堆空间导致free出错。 先单步调试找到出错的语句。 如果找不到，就贴上完整的代码。 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

很可能原因不是在free的时候，而是使用动态分配的内存时越界了，导致堆破坏，在释放内存时导致出错


Question: c头文件extern问题

对文件xyz来说编译是重复定义。 对于主程序，link的时候会link， x.c中： void Init_Language(void) { abort(); }

如果 其中一个文件不链接，编译器并不会报错

abort() 对于调试非常有用 这个函数的存在主要作用是调试程序

不是很懂，这样链接不会报错吗？

extern是C语言中声明和引用的作用，引用是因为改函数在其他地方定了了； absort是中断程序，用户在可能出错，或者参数异常的地方使用，这样可以方便定位问题；

如果包含 函数的.c 文件没有其他的引用符号。 那么如果链接的时候，你的自定义的函数将优先被链接。 不会引起符号冲突，除非 那个 .c 文件还有其他的符号被链接。  这样的效果就是，如果你没有自定义这个函数，那么将使用库的缺省函数。 否则就会使用你的自定义函数。（编译器的虚函数^_^)  而库的缺省函数就是直接 abort() 了。 这个函数直接退出整个程序。

引用 楼主 u013903890 的回复:例子如下： x.h中： extern void Init_Language(void);  x.c中： void Init_Language(void) { 	abort(); } 另一个文件xyz中： #include	"x.h" void Init_Language(void) { 	自定义实现细节； } 主程序： #include	"x.h" 调用Init_Language();   问题：主程序到底调用的那个函数？另外abort()的作用，查资料说中止进程，那是令当前进程退出吗，这样有什么实际意义和必要吗？ 1. 这个写法编译不过，会提示Init_Language重复定义 2. 函数名: abort 功  能: 异常终止一个进程 特 性：abort()函数通过发出一个SIGABRT信号终止程序的执行。 abort()函数不会清空缓冲区，也没有调用之前用atexit()函数注册的清理函数，属于异常退出。

引用 2 楼 qq_34891043 的回复:不是很懂，这样链接不会报错吗？ 这是别人源码的一部分，可以正常运行，我一开始还想成java的函数重写了-_-#

这个链接的时候肯定报错啊，重定义了 abort被调用时，程序将直接退出，任何对象的析构函数都不会调用 http://www.cplusplus.com/reference/cstdlib/abort/?kw=abort


Question: 删除操作无法执行，输入删除位置之后执行下一步，程序就停止运行了

好的，谢谢你啦

引用 8 楼 qq_30306457 的回复:是因为没有头结点接下来输出就不知道从哪里遍历了吗？所以一定要把头结点指向新的第一个结点吗？ 因为你的另外函数都是写成有头结点的，比如你的OutPutList函数，所以一定要在链表头部加上头结点

引用 6 楼 qq_30306457 的回复:你好，你的最后一步我不明白，我的指针s是移动的，移到最后一个位置时，把指针指向前面不可以吗？L不是头结点吗，没有移动啊？ 退出while的时候，r指向了最后一个结点（也就是逆序后的第一个结点），s已经是NULL 此时应该让头结点（L）指向新的第一个结点,所以是（L->next = r;）

改成这样：  void TransposeList(LinkList L) { 	LinkList r,s,t; 	r = NULL; 	s = L->next; 	while(s) 	{ 		t=s->next;//t指向s后面的那个元素 		s->next=r;//s指向前面的元素 		r=s;//移动指针 		s=t; 	} 	//s->next=r;//s指向最后一个元素时，s->next为空，但s还是指向前面。 	L->next = r; }

我还想问个问题，关于单链表转置的，我的逻辑没错吧？我觉得没错我编译没错，运行没结果。 TransposeList(LinkList L) { 	LinkList r,s,t; 	r=L; 	s=r->next; 	while(s->next) 	{ 		t=s->next;//t指向s后面的那个元素 		s->next=r;//s指向前面的元素 		r=s;//移动指针 		s=t; 	} 	s->next=r;//s指向最后一个元素时，s->next为空，但s还是指向前面。 }

引用 2 楼 qq_30306457 的回复:谢谢你啦，不过我还是个学生，还是个小白。 问题解决了，记得及时结贴

谢谢你啦，不过我还是个学生，还是个小白。

删除操作里，找到要删除的结点后，让它的上一个结点(s)指向待删除结点(r)的next指针指向的结点就行了 ps:你的删除和插入函数也不需要return  #include<stdio.h>  #include<stdlib.h>   typedef struct LNode  {   	int data;   	struct LNode *next;  }LNode,*LinkList;  LinkList L; void createList(int n)//构建链表 {      	LinkList s,r; 	int i; 	L=r=(LinkList)malloc(sizeof(LNode));  	//r->next=NULL; 	for(i=0;i<n;i++)  	{   		s=(LinkList)malloc(sizeof(LNode)); 		scanf("%d",&s->data); 		//s->next=r->next; //表头插入法 		//r->next=s;   		r->next=s;//表尾插入法 		r=s; 	}  	r->next=NULL; }  LinkList InsertList(LinkList L,int n)//单链表的插入 { 	LinkList s,r=L; 	int i,j; 	printf("请输入要插入的位置："); 	scanf("%d",&j); 	s=(LinkList)malloc(sizeof(LNode)); 	printf("请输入要插入的数："); 	scanf("%d",&(s->data)); 	if(j<1||j>n+1) 		printf("插入位置错误："); 	else 	{ 		for(i=0;i<j-1;i++) 			r=r->next; 		s->next=r->next; 		r->next=s;	 	} 	return L; }  LinkList DeleteList(LinkList L,int n)//单链表的删除 { 	LinkList s,r=L; 	int i,j,k; 	printf("请输入要删除的位置："); 	scanf("%d",&j); 	if(j<1||j>n+1) 		printf("要删除的位置越界："); 	else 	{ 		for(i=0;i<j;i++) 		{ 			s = r; 			r=r->next; 		} 		k=r->data; 		printf("删掉的数为%d",k);  		s->next = r->next; 		/* 		while(r) 		{ 			(r-1)->next=r->next;//被删元素之后的元素左移 		} 		*/ 		free(r); 		return L; 	} } void OutPutList(LinkList L)//输出链表 {   	LinkList p; 	p=(LinkList)malloc(sizeof(LNode));//删掉这句还是可以运行 	p=L->next; 	printf("表中值为:");   	while(p)  	{   		printf("%d ",p->data);  		p=p->next;  	}   	printf("\n");  }  int main()  {    	int len; 	printf("请输入表长："); 	scanf("%d",&len); 	printf("请输入："); 	createList(len); 	OutPutList(L); 	InsertList(L,len); 	OutPutList(L); 	DeleteList(L,len); 	OutPutList(L); 	return 0; }   崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 520，送给我的夫人

里面的每一个变量名，每个单词，都是有特殊的意思的，我把这些年的经历，都写进去了呢

。。。。拿来哄妹子不错

引用 9 楼 lmy121的回复:marry未定义呀 只是一个goto的标志，无需定义

没什么卵用呀。

marry未定义呀

引用 3 楼 paschen 的回复:  这里好像少了一个%c来输出 ！  printf("%c %c%c%c%c %c%c%c%c", five, two, zero, j, q, r, b, c, w);谢啦

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

没创意，楼主可以试试用I love you这些字符填充一颗心。

引用 6 楼 user-10 的回复:marry:     return 0; 这是说结婚就玩完的意思么？ 从此之后，她和他就过上了幸福生活……

marry:     return 0; 这是说结婚就玩完的意思么？


Question: 字符串

C最早设计时定义了“常量”字符串，可以在编译时做优化节省空间. 常量字符串编译时会将相同的值合并到一起。 而"a","ab","abc"显然不是相同的值

“a”“ab”“abc”是三个不同的常量字符串，分开存储。

%p是输出地址，printf("%p\n", "a");输出的是"a"这个常量字符串的地址  如果需要输出字符串的值，用%s  “a” “ab”  “abc” 是不同的常量，内存地址不相同的


Question: 关于linux进程创建函数fork

copy on write机制，前面是共享的，后面如果你不对变量做写操作它也是共享的。 自己搜下理解下这个机制。

引用 1 楼 x20121223 的回复:fork()是克隆出一份父进程的内容，会保留父进程的所有当前状态。所以输出一样的。 哦，明白了，是在执行之前就共享了变量，谢谢你啊


Question: 求前50个质数.要求确定一个数n是否是质数，用已求出的质数对n的整除性来确定.

引用 5楼ghx287524027 的回复:判断一个自然数是不是质数，可以用所有比它小的质数从小到大依次去除它，除到商比除数小，而且还有余数，它就是质数，否则不是质数。应该是比它平方根小的质数吧。

引用 7 楼 Justarte 的回复:[quote=引用 5 楼 ghx287524027 的回复:] 判断一个自然数是不是质数，可以用所有比它小的质数从小到大依次去除它，除到商比除数小，而且还有余数，它就是质数，否则不是质数。   没理解, 比如要判断13是不是质数, 那么用1,3,5,7,一次去除以13, 然后得到的商比13小, 且有余数,  [/quote]  原理其实和8楼说的差不多，只不过是除的次数少一点。比如对于19，比它小的质数有2,3,5,7,11,13,17.那么从小到大依次用2,3,5,7,11,13,17去除19.当用5去除19的时候，商为3，小于5，并且此时有余数。那么就可以判断19是质数了，不再需要用其余的数再去除19了。

是这样的：  n从2开始。这时n=2。 此时还没有确认哪个数是质数，因此“已求的质数”是个空集。用这个空集里的所有已求的质数（这时个数为0）对n（这时就是2）的整除性来确定2是不是质数。因此有0个已求的质数能整除2。也就是说没有一个已求的质数能整除2，因此2是质数。 此时“已求的质数”不是个空集，而是有一个成员“2”。“已求的质数”就是“2”。  然后判断下一个n，（=3）是不是质数。这时“已求的质数对n的整除性来确定”3是不是质数，意思就是用2对3的整除性来确定3是不是质数。由于2不能整除3，所以3是质数。 这时“已求的质数”就是“2”和“3”。  然后判断下一个n，就是4，是不是质数。“已求的质数对n的整除性来确定”4是不是质数，意思就是用2和3对4的整除性来确定3是不是质数。由于2能整除4，所以4不是质数。

引用 5 楼 ghx287524027 的回复:判断一个自然数是不是质数，可以用所有比它小的质数从小到大依次去除它，除到商比除数小，而且还有余数，它就是质数，否则不是质数。   没理解, 比如要判断13是不是质数, 那么用1,3,5,7,一次去除以13, 然后得到的商比13小, 且有余数,

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

引用 3 楼 Justarte 的回复:[quote=引用 1 楼 ghx287524027 的回复:] 求哪里的前50个质数？  应该是所有质数中的前50个[/quote]  那题目意思应该就是，先求出前50个质数，然后根据这50个数来对整数n的整除性作出分析，从而判断n是否也为质数。

引用 1 楼 ghx287524027 的回复:求哪里的前50个质数？  应该是所有质数中的前50个

筛选法吧。。。

求哪里的前50个质数？


Question: c语言指针问题

你把printf都放函数里

函数FindMax里的局部变量i和j，只在这个函数体内有效，出了这个函数体后，就自动被系统回收了。也就是说这个函数用完了之后，m,n指向的内存已经被回收了。

int FindMax(int score[3][4],int *m,int *n) { static int i,j;

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

这个代码运行起来有个错误的  Segmentation fault (core dumped) 不知道你这个为啥没报出来，可能跟编译，运行环境有关。  int *m=NULL; int *n=NULL;  这么写了之后mn两个指针没有分配空间 然后你在赋值那里写的 m=&i; n=&j 就是让m n指向了ij的内存，但是ij的内存在函数return之后，就释放掉了，这样mn指向就有问题 一般说来，指针在使用前需要用malloc分配一下内存，你可以对mn进行malloc，但是仅仅这样还是不行 mn分配内存之后，你赋值那里依然是把ij的地址给mn，在函数return之后，那个地址也不能用了，mn的值依然不正确 用malloc给mn分配内存后，在赋值那里写成 *m=i;*n=j;这样就对了，最后记得对malloc的指针进行malloc  不知道这么说对不对，楼上赵老师是专家

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

你在函数中修改指针的值并不会改变函数外的m，n，因为你函数传递参数是按值传递的，也就是说你函数中的m,n只是函数外m,n的一个复制后的值，你修改复制后的值是没有用的  第二，你函数中的 i，j在函数执行完就销毁了，就算你指针指向了它，可能他已经是无用的值了

如一楼所说，注意变量的作用域~

一楼说的对的。局部变量在函数结束就失效了。指向的地址自然也就没了


Question: 图的十字链表存储 程序指针问题

不兼容的指针类型赋值。


Question: 关于void*强制转换的问题

你这是对内存以不同的形式重新解释，而不是值转换。而且没必要搞个函数吧： int i = 10; printf("%f\n", i);              // 0.0 printf("%f\n", *(float *)&i);   // 0.0 (同上) printf("%f\n", (float)i);       // 10.0

浮点数格式 http://bbs.csdn.net/topics/390676437

如果int转float ，结果将是10.0f 但你的是int*转float*，是指针类型的转换，这将导致用float的格式去解释内存中的数据 而浮点数在内存中的存储形式与整数是不同的 参看：http://blog.csdn.net/richerg85/article/details/20456969

1#正解,IEEE标准定义了float的内存布局 参考 深入理解计算机系统 第二章 - 浮点型

引用 2 楼 dustpg 的回复:新手多用static_cast，禁止用C风格转换，少用reinterpret_cast 卧槽，还以为是C++，原来是C，C类型不安全，lz多多小心即可

10在内存中的存储： 0000 1010 0000 0000 0000 0000 0000 0000  浮点数在内存中的存储： http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html  用float去读该内存区域自然读不出来了


Question: 关于递归调用局部变量空间分配的问题

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

参数是一级指针，只能改变指针指向的区域的值（实参和形参都指向同一块内存，但两个指针本身是不同的） 只有传二级指针或者一级指针的引用才能改变指针本身的值（指针的指向）

原来如此，谢谢大神！

为什么不一样？函数调用的参数传递本质上是值传递 只有引用参数，才是地址传递 每次复制一份node  node 的值当然不会变化了


Question: 求一个能用二维离散傅里叶变换 c代码

网搜吧，很多的


Question: 关于rand（），一样的种子每次都产生不同的随机数……

建议使用<random>，效果优秀

应该是一样的。 基本上都是用系统时间做种子，不过这也是伪随机。

种子相同,每次调用rand()函数出来的随机数都是相同的，种子不同，rand()出来的随机就不会相同，一般种子多选用获取当前的时间，这样每次rand()的值都不会相同的

[root@localhost d]# ./a 1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421 [root@localhost d]# ./a 1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421  同样的种子得出同样的序列。 你的截图和我运行两次的结果对比，可以发现：你的第一个序列是不对的（可能代码不对或者不是相同的程序）。

srand(time(0)); 用时间来初始化种子


Question: 大神能帮我看一下，这个A*算法的程序是完全的吗？

https://github.com/dustpg/NoteFL/blob/master/GraduationProject/PathFinder/pfdAStar.cpp#L322 这是我的实现，让lz参考参考，注释很详细

A*算法这个绝对有非常成熟的库及各种相关优化算法。自己写太烧脑了，而且效率并不一定就高。


Question: 回文数

大数加法，用栈。。什么类型都不可以的

引用 3 楼 ghx287524027 的回复:[quote=引用 2 楼 jianjiu7 的回复:] [quote=引用 1 楼 ghx287524027 的回复:] 这个可以用  #include<stdio.h> long sum( long a){     int t=0,i=0;     long a1=0;     int c[25]={0};     while(a){         c[i]=a%10;         a/=10;         i++;     }        t=i;     for(i=0;i<t;i++)     a1=a1*10+c[i];        return a1; } int main(){     long a; 	long s[100]={0};     int ta,i;     while(scanf("%I64d",&a)!=EOF)     {         ta=0;         s[ta]=a;         while(a!=sum(a))         {                a+=sum(a); 			ta++;             s[ta]=a;         }         for(i=0;i<ta;i++)           printf("%I64d--->",s[i]); 		printf("%I64d",s[ta]);        }     return 0; }  不行，题目说明输入的数值不超过2^60，long不够吧[/quote] 你用的什么环境，在vc6.0中是不支持long long类型的[/quote]合工大oj    我在我的devc++上是可以的（我在想是不是输出时溢出了，我感觉我可能没理解那两个提示 1.输入的数据保证小于2^60 2.每组数据保证最多运算100次  （你觉的是数据的原因吗））

引用 2 楼 jianjiu7 的回复:[quote=引用 1 楼 ghx287524027 的回复:] 这个可以用  #include<stdio.h> long sum( long a){     int t=0,i=0;     long a1=0;     int c[25]={0};     while(a){         c[i]=a%10;         a/=10;         i++;     }        t=i;     for(i=0;i<t;i++)     a1=a1*10+c[i];        return a1; } int main(){     long a; 	long s[100]={0};     int ta,i;     while(scanf("%I64d",&a)!=EOF)     {         ta=0;         s[ta]=a;         while(a!=sum(a))         {                a+=sum(a); 			ta++;             s[ta]=a;         }         for(i=0;i<ta;i++)           printf("%I64d--->",s[i]); 		printf("%I64d",s[ta]);        }     return 0; }  不行，题目说明输入的数值不超过2^60，long不够吧[/quote] 你用的什么环境，在vc6.0中是不支持long long类型的

引用 1 楼 ghx287524027 的回复:这个可以用  #include<stdio.h> long sum( long a){     int t=0,i=0;     long a1=0;     int c[25]={0};     while(a){         c[i]=a%10;         a/=10;         i++;     }        t=i;     for(i=0;i<t;i++)     a1=a1*10+c[i];        return a1; } int main(){     long a; 	long s[100]={0};     int ta,i;     while(scanf("%I64d",&a)!=EOF)     {         ta=0;         s[ta]=a;         while(a!=sum(a))         {                a+=sum(a); 			ta++;             s[ta]=a;         }         for(i=0;i<ta;i++)           printf("%I64d--->",s[i]); 		printf("%I64d",s[ta]);        }     return 0; }  不行，题目说明输入的数值不超过2^60，long不够吧


Question: Debug Assertion Failed!

引用 12 楼 qq423399099 的回复:fopen打开文件成功，返回文件指针（赋值给fp），打开失败则返回NULL值； fopen_s打开文件成功返回0，失败返回非0。 太感谢了，我纠结了好久，vs2015里面的这些用法不是很理解，造成好多困扰

引用 9 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 没有弹出对话框，输入文件名之后，就直接退出来了

引用 7 楼 qq423399099 的回复:楼主贴一下控制台输入的截图 输入之后就闪退了

引用 6 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  请检查每个函数的返回值。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];  谢谢指教

楼主贴一下控制台输入的截图

引用 3 楼 qq423399099 的回复:楼主你的scanf_s("%s", filename);这句不对，读%c和%s的时候必须多传入一个参数指定读取的字符的长度 应该改成scanf_s("%s", filename, 10); 楼主可以单步调试或者在下面printf验证一下之前这样的用法是不是正确输入了文件名  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 额……又犯了这种错误，但是，改了之后，输入文件名之后就会自动退出，貌似无法创建文件

这个是例题，但是在vs2015，2013下就会出现这样的错误

为什么要用两次ch=getchar()呢？


Question: C语言读文件如何检测从一个位置读起，然后转存到另一个数组中，再创建一个文件写出

#include <stdio.h> #include <io.h> #include <stdlib.h> #include <malloc.h> #include <string.h> char *buf; long flen; FILE *f; int i; int main() {     f=fopen("in.dat","rb");     if (NULL==f) {         printf("Can not open file in.dat!\n");         return 1;     }     flen=_filelength(_fileno(f));     buf=(char *)malloc(flen);     if (NULL==buf) {         fclose(f);         printf("Can not malloc %d bytes!\n",flen);         return 1;     }     fread(buf,1,flen,f);     fclose(f);     for (i=0;i<flen-5;i++) if (0==memcmp(buf+i,"start",5)) break;     f=fopen("1.txt","wb");     fwrite(buf+i+5,1,flen-i-5,f);     fclose(f);     free(buf);     return 0; }

引用 2 楼 zhao4zhong1 的回复:char buf[2000]; FILE *f; int i; f=fopen(...,"rb"); fread(buf,1,2000,f); fclose(f); for (i=0;i<2000-5;i++) if (0==memcmp(buf+i,"start",5)) break; f=fopen("1.txt","wb"); fwrite(buf+i+5,1,2000-i-5,f); fclose(f);  还有就是想请教一下如何使用rb、wb去写。因为我最开始是读了fopen、fwrite的参数配置和指令，然后有尝试使用写，目前还在学习阶段，想看看您的书写方法，在这种实例中0.0

引用 2 楼 zhao4zhong1 的回复:char buf[2000]; FILE *f; int i; f=fopen(...,"rb"); fread(buf,1,2000,f); fclose(f); for (i=0;i<2000-5;i++) if (0==memcmp(buf+i,"start",5)) break; f=fopen("1.txt","wb"); fwrite(buf+i+5,1,2000-i-5,f); fclose(f);  sorry，没仔细看，看懂了~~~3Q

引用 2 楼 zhao4zhong1 的回复:char buf[2000]; FILE *f; int i; f=fopen(...,"rb"); fread(buf,1,2000,f); fclose(f); for (i=0;i<2000-5;i++) if (0==memcmp(buf+i,"start",5)) break; f=fopen("1.txt","wb"); fwrite(buf+i+5,1,2000-i-5,f); fclose(f);   那有多个文件，每个文件长度都不定，我是不是需要strlen(File)，然后File-乱码长-5呢0.0，这一段乱码长要如何减。。。不定长乱码。。。

使用ftell移动到需要读取的位置  参考：http://en.cppreference.com/w/c/io/ftell


Question: 求助

引用 4 楼 赵4老师的回复:将相关文件添加到项目、源文件中。 不会添加，第一次碰见，

将相关文件添加到项目、源文件中。

引用 1 楼 wang0635的回复:这个函数是哪里的 format(); 还有文件没传，太多了

有很对其他的文件，还没传，太多了

这个函数是哪里的 format();

我刚开始也是的这样的，好像是你上一次没运行完成或者终断了，而你又很快的运行了一次程序，这样导致上一次运行残留的和这一次运行的产生冲突了。方法：保存代码，退出软件，重新进入，打开项目程序

1.如果是自定义的文件，那么需要include头文件，并且将CPP文件添加到项目中 2.如果是别人提供给你的lib,那么也需要include头文件，添加包含目录，添加库目录，附加依赖项 PS：具体操作都可以百度到

引用 5 楼 paschen的回复:错误是因为链接时链接器没有找到format这个函数的实现部分，楼主这个函数是在哪定义的，是否导入了库文件 没导入，不知道怎么导入库函数


Question: 关于调用函数过程中被调用函数的问题

引用 4 楼 youxirenjia90 的回复:[quote=引用 2 楼 ghx287524027 的回复:] 值传递和引用传递的问题 你好，这两个有什么具体的区别么。对于值传递和引用传递？[/quote] 关于值传递和引用传递，百度上有很多，c/c++/java都可以，原理差不多

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

你函数中的参数只是实际参数的一个复制器，你交换的仅仅是两个复制品，而不是实际参数  用指针的话，指针是个复制器，但你可以修改指针指向的值

C 只有值传递 所以，需要改变的对象要传入地址。形参是指针，通过指针间接改变 ，传入地址中的数据（这是指针的功能）。 C++多了个引用参数 传入对象（名），即可匹配引用参数 引用参数可以修改传入的实参对象。（这就是别名的含义）

姑且这么标识一下  #include <stdio.h>  swap(int *p1,int *p2){ 	int temp;               	temp=*p1;                  	*p1=*p2; 	*p2=temp; } swap1(int x,int y){     	int temp; 	temp=x; 	x=y;  	y=temp; } swap2(int *p1,int*p2){ 	int *p; 	p=p1; 	p1=p2; 	p2=p; }  int main(){ 	int a,b; 	int *pointer_1; 	int *pointer_2; 	scanf("%d%d",&a,&b); 	pointer_1=&a; 	pointer_2=&b; 	if(a<b){ 		swap(pointer_1,pointer_2); 		swap1(*pointer_1,*pointer_2); 		swap2(pointer_1,pointer_2); 		printf("%d\n%d\n",a,b); 	} 	return 0; }    swap属于引用传递，可以达到交换a,b的目的，不必多说。 swap1属于值传递，虽然对x,y进行了交换，但跟a,b没关系，不会影响a,b的值。 swap2虽然也是引用传递，但是只是改变了指针的指向，a,b的实际值并没有改变

引用 2 楼 ghx287524027 的回复:值传递和引用传递的问题 你好，这两个有什么具体的区别么。对于值传递和引用传递？

值传递和引用传递的问题

这就是指针嘛，/*.........*/中的代码，说白了就是  a = 3; b = 4; swap( a, b );实际上就是swap( 3, 4 )   3和4都是数，怎么可能被交换呢？  换成指针就是 swap( 装3的盒子， 装4的盒子 ），在swap里面把盒子里面的东西互换一下。

能不能规范一下代码啊，看起来很痛苦的说~


Question: 三目运算中 (x>=y)?x:y中的等号加还是不加

算正确，参考答案仅供参考

效果一样，答案只是个参考 不过在这里面很少用=

int max = x < y ? y : x;  能使用 < 的地方，不要使用其他的。

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

在此处加不加等号是一样的

从功能上来说有没有等号都是可以的，效果一样


Question: 求指错，一运行就停止工作

1、ArrayInputTwoDem 这个对数组初始化时，循环少了一层，你这是二维数组 2、BubbleSortTwoDem 排序那里，for(k=0;k<N-j;k++)，j=0的时候，你看看你下面比较用的k+1,会出什么问题

ArrayInputTwoDem函数里，j没有初始化就使用了

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

ArrayInputTwoDem()函数中少了一层for循环


Question: 求指导以下程序怎么运行不出来

引用 1 楼 zhao4zhong1 的回复:while((ch=getchar())!='\n') 谢谢赵四老师解答，问题解决了

while((ch=getchar())!='\n')

while循环里面，把\n改为EOF试试

而且你看看你的位置，里面创建那个文件没

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

注意运算符优先级。 !=的优先级是大于=的。 http://www.jb51.net/article/37282.htm


Question: （新人贴）求助湖里的大神

for (i=1;i<=n-1;i++)         r[i]=66.1157/sqrt(1-pow(0.6*cos(k[i]),2)); //此时i的值为n即18     d[i]=((r[i+1]-r[i])/h[i+1]-(r[i]-r[i-1])/h[i])*6/(h[i]+h[i+1]);//越界！

请说明白点，没看出来哎，谢谢

能不能把括号补全


Question: 如何给已经定义好的结构体，重新增加几个（个数动态变化）变量，以便程序的其他地方给这几个变量赋值，

你就算加上也没有用，因为使用者不知道。  在很多使用，我们需要动态的使用一个数据结构。 此时需要使用一个标识来表示这个结构的额外数据。 使用 flag and union 来标识 数据。 在结构体开始定义一个 size 来表示这个结构数据的大小。 你可以看到 Windows API 很多传入和传出结构都是有 Size 的。 就是他的数据就像你这样的。  struct { int size; int flag; union { struct  {} _1; struct { } _2; } }

改不了~~~

realloc ？

在结构体中放个void *指针？ 有3个int的时候就转换成int *,并且分配3*sizeof(int)的空间 如果是double,那就转成double *

结构体不能动态修改

结构体的定义是在编译前，编译好的程序运行时全是二进制数据了

1）修改原来的代码 2）传递结构体指针并强制转换


Question: 我是初学者，主要是C语言指针数组的问题，求教各位。

学会做饭比把这顿吃饱更重要。

引用 4 楼 sjxzjw 的回复:不会栈，我不会调试  学会调试比解决问题更重要  http://jingyan.baidu.com/article/c910274bc7ed0acd371d2d78.html

引用 6 楼 sjxzjw 的回复:printf这个方法已经领悟了，但感觉对这个用处不大 这个方法很好用

引用 4 楼 sjxzjw 的回复:不会栈，我不会调试  告诉你一个最笨最简单的办法，每行之间加个打印 printf(""); 打印内容自己加，这样你就知道你的代码大概运行到哪里出问题的了  另外你贴出的代码的问题，printf("%s\n",*p[k]);; 字符串打印不能加*，printf("%s\n",p[k]);即可 至于这个功能如何实现，我觉得你不能去看别人写的，还是把你自己这段代码修改出来最好

不会栈，我不会调试

停止时点中断，然后通过调用堆栈、变量窗口等观察分析原因  建议；不要觉得是初学者就不自己思考，否则你无法进步

#include<stdio.h> #include<stdlib.h> #include<math.h> long sum( long a){     int t=0,i=0;     unsigned int a1=0;     unsigned int c[25]={0};     while(a){         c[i]=a%10;         a/=10;         i++;     }        t=i;     for(i=0;i<t;i++)     a1+=pow(c[i],t);        return a1; } int main(){     unsigned int a;     while(scanf("%u",&a)!=EOF)     { 		if(a==0){ 			break; 		}         if (a==sum(a)){ 			printf("YES "); 		}else{ 			printf("NO "); 		}              }     return 0; }

printf这个方法已经领悟了，但感觉对这个用处不大


Question: 请问如何在程序中隐藏硬编码字符串

比如在我这段代码生成的exe里面你就找不到abcdefg这个字符串： #include <stdio.h> const char* str="ａｂｃｄｅｆｇ"; char t[8]; int i; int main() {     for (i=0;i<7;i++) t[i]=*(unsigned char *)(str+1+i*2)-0xE1u+'a';     t[i]=0;     printf("[%s]\n",t);     return 0; }

在生成二进制文件后，代码中的硬编吗部分会被生成类似下面这样的一段数据。这样里面的信息很容易就被看到了。 我是想法是能不是让这段秘钥不出现在这个位置。如果分散再其它地方的话相信在一个很大的文件中取找并不是什么容易的事情   empty return str=%s text str=%s %2.2x get info start.... get_imsi get_imei get_mac get_device_id imsi imei mac device_id get_password_start 1 2 3 4 5 6 get_password_end pass_md5 json:%s  N9__gnu_cxx24__concurrence_lock_errorE  N9__gnu_cxx26__concurrence_unlock_errorE    __gnu_cxx::__concurrence_lock_error __gnu_cxx::__concurrence_unlock_error   std::bad_alloc  basic_string::at    basic_string::copy  basic_string::compare   basic_string::_S_create basic_string::erase basic_string::_M_replace_aux    basic_string::insert    basic_string::replace   basic_string::assign    basic_string::append    basic_string::resize    basic_string::_S_construct null not

引用 11 楼 hw80520997 的回复:[quote=引用 9 楼 akirya 的回复:] 通过自定义一个运算得到 key  昨天晚上我也想过这个。比如弄个字符串数组然后用下标来去。可是下标的key不又是硬编的了吗[/quote] 客户端要存key，那么必然有方法找到的。只不过是难易程度有区别。

引用 9 楼 akirya 的回复:通过自定义一个运算得到 key  昨天晚上我也想过这个。比如弄个字符串数组然后用下标来去。可是下标的key不又是硬编的了吗

引用 8 楼 zhao4zhong1 的回复:const char* str =“ａｂｃｄｅｆｇ”;//(^_^)  我想改的可是帖子没权限编辑  其实我想要的就是一段秘钥被硬编到二进制程序里不容易被人轻易找到肯破译

const char* str =“ａｂｃｄｅｆｇ”;//(^_^)

引用 1 楼 user-6 的回复:服务器加密，服务器返回字符串。  否则，请楼下的解释让lz不要陷入无尽的加密/解密中。 奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！

通过自定义一个运算得到 key

那你存储加了密的字符串，然后使用时自己解密，不过即使这样，别人仍然是有办法通过反汇编破解得到你的解密算法

希望大家能给一个解决方案。要是能让秘钥可以更新就更好了。但是需要一个完整周密在方案才能做到秘钥从服务器传输到客户端联给截获。而且客户端是手机。都是非登陆用户，还有如果要更新秘钥那秘钥在保存也是个问题

没事到“看雪论坛”逛逛。

引用 7 楼 zhao4zhong1 的回复:[quote=引用 1 楼 user-6 的回复:] 服务器加密，服务器返回字符串。  否则，请楼下的解释让lz不要陷入无尽的加密/解密中。 奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！ [/quote]  只要写个函数，得到字符串的过程弄复杂一些，很多人就不再试图跟踪了，当然了，对于赵老湿这种啥都看汇编，到处下断点，能找到最后结果的人就不值一哂了。

引用 2 楼 Saleayas 的回复:既然你密钥，那么就不可能让别人知道， 所以就算真的隐藏了，也没有用的。  我没太理解你的意思。不想让别人知道为什么隐藏没用呢

引用 1 楼 user-6 的回复:服务器加密，服务器返回字符串。  否则，请楼下的解释让lz不要陷入无尽的加密/解密中。  需求是这样的。客户端程序需要收集一些手机的本地信息然后加密传回服务器端。这个过程不希望被别人破译。一方面怕别人拿到这些信息。另一方面也怕别人了解算法和密钥后构造数据欺骗服务器

既然你密钥，那么就不可能让别人知道， 所以就算真的隐藏了，也没有用的。


Question: vc++6.0在debug时让指定可执行文件名是怎么回事

引用 3 楼 pkuzhx 的回复:这个老古董还有人在用啊 新手表示都在用

引用 9 楼 xian_wwq 的回复:lz的默认启动项目类型是dll，无法启动，切换到可执行的项目进行调试吧

lz的默认启动项目类型是dll，无法启动，切换到可执行的项目进行调试吧

老手也在用VC6。 特此证明。  引用 7 楼 jennyvenus 的回复:一直使用vc6 抱团取暖

一直使用vc6

老手也在用VC6。 特此证明。

这个老古董还有人在用啊

引用 3 楼 pkuzhx的回复:这个老古董还有人在用啊 不用这个用哪个，初学者不都是用这个嘛？

你这是dll工程？

这是截图


Question: mmap 共享内存方式在进程关闭能自动释放映射的内存么？

会

进程退出后是会自动释放共享内存区域的数据的


Question: C语言二维数组

你找到错了就最好，这种最好自己慢慢编译运行慢慢找问题

刚看完题目

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

帮结帖

我自己找到了~·

期待大神的到来~~·


Question: 有研究过代码相似度检测程序SIM吗？

好奇楼主用在什么产品上？汇编代码量很大吗

我的毕业论文也是这个，还没想法呢，哎，没看到哪篇文章讲的很清晰

至少现在没有。


Question: 编译错误 undefined reference to '__udivdi3'

有添加libgcc的编译链接。

引用 2 楼 maxwell11 的回复:是在windows下编译的，再者不确定我要在反编译中什么内容。 建议使用dumpbin命令查看.lib文件。

引用 5 楼 mLee79 的回复:这几个函数应该是 libgcc 的,  链接选项加上 -lgcc 就是了.. 如果完全不想引入 libgcc 就去gcc代码里把相应的几个几个源文件加进去...   楼主看看这个吧

Link + libm

是在windows下编译的，再者不确定我要在反编译中什么内容。

建议使用objdump命令查看.a文件。


Question: 关于fwrite函数如果字符数组没有被占满字符数组会整体复制到目标文件中包括哪些未初始化的这个问题怎么解决

“rb+”   When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.

谢谢，这个问题解决了，但是我又发现个问题，fopen()函数用“ab+”模式打开，居然只能在文件尾添加数据，但是我想通过fseek()定位修改文件内容，我该怎么办。百度了一下，好像没有能修改文件的模式

引用 4 楼 user-3 的回复:fread有返回读取到多少数据，你写入另外文件的时候按这个读取到的值写入具体的数据量 我也想过这个办法，但是如果从头开始读取的话我觉得太浪费时间，所以想把单词的总数存在文件的最I后四个字节里，在添加时在读取出总数再覆盖掉最后四个字节的数据，现在就是覆盖这里出问题了

fread的返回值

memset Sets buffers to a specified character.  void *memset( void *dest, int c, size_t count );  Routine Required Header Compatibility  memset <memory.h> or <string.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  memset returns the value of dest.  Parameters  dest  Pointer to destination  c  Character to set  count  Number of characters  Remarks  The memset function sets the first count bytes of dest to the character c.  Example  /* MEMSET.C: This program uses memset to  * set the first four bytes of buffer to "*".  */  #include <memory.h> #include <stdio.h>  void main( void ) {    char buffer[] = "This is a test of the memset function";     printf( "Before: %s\n", buffer );    memset( buffer, '*', 4 );    printf( "After:  %s\n", buffer ); }   Output  Before: This is a test of the memset function After:  **** is a test of the memset function   Buffer Manipulation Routines  See Also   _memccpy, memchr, memcmp, memcpy, _strnset

引用 1 楼 zhao4zhong1 的回复:先memset(buf,0,bufsize);  这个函数是什么功能，形参指得是什么？