Question: 循环队列的操作

几个问题： 1.EnQueue函数里while(e!=-1){scanf("%d",&e);}这个写法是什么鬼？你这样写使得e不是-1就没法出循环 如果是一次输入一个元素的话应该改成用if判断，如果要一次输入多个元素的话，改成while,但不是你那样写的 2.putQueue里的while(Q->front!=Q->rear)改成while(i!=Q->rear)   #include<stdio.h> #include <malloc.h> #define MAXQSIZE 10 typedef struct { 	int *base; 	int front; 	int rear; }SqQueue;  int InitQueue(SqQueue *Q)//构造空队列 { 	Q->base=(int *)malloc(MAXQSIZE*sizeof(int)); 	if(!Q->base) 		printf("存储分配失败。"); 	Q->front=Q->rear=0; 	return 1; }  int QueueLength(SqQueue *Q)//返回队列长队 { 	return (Q->rear-Q->front+MAXQSIZE)%MAXQSIZE; }  int EnQueue(SqQueue *Q)//插入新元素e { 	int e; 	if((Q->rear+1)%MAXQSIZE==Q->front) 	{ 		printf("队列满"); 		return 0; 	} 	else 		printf("请输入要插入的数:"); 	scanf("%d",&e); 	if(e!=-1) 	{ 		Q->base[Q->rear]=e; 		Q->rear=(Q->rear+1)%MAXQSIZE; 	} 	 	return 1;  }  int DeQueue(SqQueue *Q)//若队列不为空，则删除Q的队头元素 { 	int e; 	if(Q->front==Q->rear) 	{ 		printf("队列为空\n"); 		return 0; 	} 	e=Q->base[Q->front]; 	printf("删除的数为%2d\n",e); 	Q->front=(Q->front+1)%MAXQSIZE; 	return 1;  }  void putQueue(SqQueue *Q) {  	int i=Q->front; 	if(Q->front==Q->rear) 		printf("队列为空\n"); 	while(i!=Q->rear) 	{ 		printf("%2d\n",Q->base[i]); 		i=(i+1)%MAXQSIZE; 	} }  int main() { 	SqQueue Q; 	int i = 0; 	InitQueue(&Q);  	while(i!=-1) 	{ 		scanf("%d",&i); 		switch(i) 		{ 		case 0:EnQueue(&Q); break; 		case 1:DeQueue(&Q); break; 		case 2:putQueue(&Q); break; 		case 3:QueueLength(&Q); break; 		default : break;  		} 	} 	return 0; }  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

不要依赖调试器输出复杂数据结构！而要将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”： //不带表头结点的循环双向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next;     struct NODE *prev; } *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;         q->prev=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             q->prev=p;             p=q;         }     }     p->next=head;     head->prev=p;      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      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;             q->prev=head->prev;             head->prev->next=q;             head->prev=q;             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;                 q->prev=p;                 p->next->prev=q;                 p->next=q;                 break;             }         }         p=p->next;         if (p==head) break;     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      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;             head->prev=q->prev;             q->prev->next=head;             if (q==head) head=NULL;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 p->next=q->next;                 q->next->prev=p;                 free(q);                 break;             }         }         p=p->next;         if (p==head) break;     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      printf("从小到大排序:");//从小到大排序     for (p=head;p!=NULL;) {         p1=p->prev;         for (q=p->next,q1=p;q!=NULL;) {             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;                  //或者                  //交换prev和next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         head->prev=p1;                         p1->next=q;                         p->next=q->next;                         p->prev=q;                         q->next->prev=p;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         head->prev=p1;                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         p->next->prev=p;                         p->prev=q1;                         q->next->prev=p;                         q->next=p2;                         p2->prev=q;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         p->prev=q;                         q->next->prev=p;                         q->next=p;                         q->prev=p1;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         p->prev=q->prev;                         q->next->prev=p;                         q->next=p2;                         q->prev=p1;                         p2->prev=q;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个循环双向链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d(=)",s->data); //                  if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;} //                  s=s->next; //                  if (s==head) { //                      printf(" Loop\n"); //                      break; //                  } //              } //              printf("head,p,q:%02d %02d %02d\n",head->data,p->data,q->data); //              getchar();             }             q1=q;q=q->next;             if (q==head) break;         }         p=p->next;         if (p->next==head) break;     }      //输出整个循环双向链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         n++;         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         while (1) {             q=p->prev;p->prev=p->next;p->next=q;             p=p->next;             if (p==head) break;         }     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      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;             break;         }         p=p->next;         if (p==head) break;     }     head=q->next;      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;         if (p==head) {             break;         }     }      return 0; } //创建10个节点的循环双向链表:12(=)46(=)31(=)63(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //将值为5的结点插入到循环双向链表的第3个结点前:12(=)46(=)05(=)31(=)63(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //删除第5个节点:12(=)46(=)05(=)31(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //从小到大排序:02(=)05(=)12(=)25(=)31(=)39(=)46(=)68(=)91(=)92(=) Loop //将整个链表逆序:92(=)91(=)68(=)46(=)39(=)31(=)25(=)12(=)05(=)02(=) Loop //将循环双向链表中前4个结点和后6个结点进行互换:39(=)31(=)25(=)12(=)05(=)02(=)92(=)91(=)68(=)46(=) Loop //


Question: c如何实现包含字串的查找功能

引用 3 楼 shorttailbird 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 处理中文请使用wchar_t、wcsstr、L"中文" 能具体讲讲它们的优势吗？而且我现在只能用标准库函数或者自制函数[/quote] 这些在windows下都是标准库函数。

// string::find #include <iostream> #include <string> using namespace std; int main() {     wstring ws1,ws2;      wcin.imbue(locale("chs"));     wcout.imbue(locale("chs"));      getline(wcin,ws1);     getline(wcin,ws2);      wstring::size_type found = ws1.find(ws2);     if (found!=string::npos)         wcout << L"第一次'" << ws2 << L"'出现在'"<< ws1 <<"'的位置:" << found << endl;     else         wcout << L"在'"<< ws1 << L"'中找不到'" << ws2 << L"'!" << endl;      return 0; } //输入： //a中文123汉字 //汉 //输出： //第一次'汉'出现在'a中文123汉字':6 //  //输入： //a中文123汉字 //形 //输出： //在'a中文123汉字'中找不到'形'! //

// string::find #include <iostream> #include <string> using namespace std; int main() {     wstring ws1,ws2;      wcin.imbue(locale("chs"));     wcout.imbue(locale("chs"));      getline(wcin,ws1);     getline(wcin,ws2);      wstring::size_type found = ws1.find(ws2);     if (found!=string::npos)         wcout << L"第一次'" << ws2 << L"'出现在'"<< ws1 <<"'的位置:" << found << endl;     else         wcout << L"在'"<< ws1 << L"'中找不到'" << ws2 << L"'!" << endl;      return 0; } //输入： //a中文123汉字 //汉 //输出： //第一次'汉'出现在'a中文123汉字':6 //  //输入： //a中文123汉字 //形 //在'a中文123汉字'中找不到'形'! //输出： //

引用 2 楼 zhao4zhong1 的回复:处理中文请使用wchar_t、wcsstr、L"中文" 能具体讲讲它们的优势吗？而且我现在只能用标准库函数或者自制函数

但是我担心一个问题，就是中文的存储是拆开的，我不了解这个函数的原理，会不会把前一个中文字符的后半和后一个中文字符的前半合起来这段当成目标字符。当然这种情况概率极低，如果字符串够长的话也不会出现这种bug。


Question: 请问有没有一种效率很高的从一堆有重复字符串出现的字符串数组中记录下每个字符串重复出现的次数的算法？

c语言的实现思路 以所有可能出现的字符串做一个索引咯，每碰到一个字符串，找到对应的字符串并计数+1

字典树(trie tree)

hash也可以，但索引项为字符串的hash table自己构造比较困难 可以考虑直接采用标准库里的map容器，它是用红黑树实现的，效率应该和hash有一拼

std::unordered_map ？可以测试一下，效率不够了再试其它的吧……

用二叉树，记录就可以了 或者用hash table


Question: 请教各位一个问题

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

引用 2 楼 user-2 的回复:假设输入5 3 ， 在程序运行的时候，，经过3个递归，K的值已经变为1，但之后我看K的值会跳变为2，请问这是为什么 =》 不知道你是怎么看的，递归吗，执行完了最内侧的，就要执行倒数第二的了，是不是在执行倒数第2时看到的K为2啊，如果是的话就应该这样啊。   为什么执行最内侧完 要执行倒数第2的呢？

#include <stdio.h> #include <stdlib.h> #define MAXN 100 int a[MAXN]= {0}; int counts=0; void  combine(int m,int k) {     printf("*****%d,%d\n\n",m,k);     int i,j;     for (i=m; i>=k; i--)     {         a[k]=i;         if (k>1)         {             printf("[[[[[[[%d,%d\n\n",m,k);             combine(i-1,k-1);          }         else         {             counts++;             for (j=a[0]; j>0; j--)             {                 printf("%2d ",a[j]);             }             printf("\n");         }     } } int main() {     int m,n;     printf("Please input m:");     scanf("%d",&m);     printf("Please input n:");     scanf("%d",&n);     counts=0;     a[0]=n;     combine(m,n);     printf("All kinds is:%d\n",counts);     return 0; }     就是为什么输入5, 3 后    三个递归后 m和k已经变为3,1   为什么k会加1变为2 还能进行递归

不太清楚你的问题是什么， 随便说说我看到的内容， 下面函数是没有返回值的也没有对m和k的更改权限，所以第1次调用的" for (i=m; i>=k; i--)" 一定要i<k才会退出，假设第一次m = 10 , k =5 那么 i 一定会经历 10~5的变化后，最外层经过5次循环才会退出。 void  combine(int m,int k)

引用 4 楼 qq_35319548 的回复:[quote=引用 2 楼 user-2 的回复:]  假设输入5 3 ， 在程序运行的时候，，经过3个递归，K的值已经变为1，但之后我看K的值会跳变为2，请问这是为什么 =》 不知道你是怎么看的，递归吗，执行完了最内侧的，就要执行倒数第二的了，是不是在执行倒数第2时看到的K为2啊，如果是的话就应该这样啊。   为什么执行最内侧完 要执行倒数第2的呢？ [/quote]  7楼回答的就是这个问题。不太好回答你这个问题，不知道应该怎么讲才容易明白。 其实你打印出来的内容就是执行的过程。 假设有下面两个函数： funA() { A1; A2; funB(); A3; A4; }  funB() { B1; B2; B3; B4; }  其实和下面一个函数是一样的，B执行完了就会走A3,A4. funA() { A1; A2; B1; B2; B3; B4; A3; A4; } 你把上面例子的B想象成A,就变成下面的样子，就是两次的递归了。 funA() { A1; A2; A1; A2; A3; A4 A3; A4; } 下面是3次的递归，展开时就像这个样子。 funA() { A1; A2; A1; A2; A1; A2; A3; A4 A3; A4 A3; A4; }

谢谢 谢谢  懂了

感觉楼主没有很好的理解递归。 递归就是某个函数直接或间接地调用了自身，这种调用方式叫做递归调用。 但凡是递归的函数，一定会在某一个地方存在能够返回上一层函数的代码。 函数自己在一层层的往深度调用自己，然后一层层的往回返。


Question: 一个可能是动态存储及链表的问题

1.creat拼错了，应该是create 2.你create函数里的island *i = malloc(sizeof(island));应该是island *i = (island *)malloc(sizeof(island));

两个name重名？


Question: 关于指针数组的一个问题。求解答

*p1=192; p1+=1;*p1=168; p1+=1;*p1=6; p1+=1;*p1=252;

你给p1赋值的时候用的不对，每次+=1就行了  #include<stdio.h> void ip2s(int n) { 	unsigned char *p = (unsigned char *)&n; 	printf("%u.%u.%u.%u\n", *p, *(p + 1), *(p + 2), *(p + 3));   } int main() { 	int ip=0; 	unsigned char *p1=(unsigned char *)&ip;  	int a=0x12345678; 	char*p=(char *)&a; 	p++; 	printf("%x\n",a);  	//"192.168.6.252"  	*p1=192;  	p1+=1; 	*p1=168; 	 	p1+=1; 	*p1=6;  	p1+=1; 	*p1=252;  	printf("ip=%d\n",ip);  	ip2s(ip);  	return 0;  }


Question: TCP客户端与服务器通信，非阻塞模式，程序填空，运行服务器闪退？求改错

这题面本身就不是什么好东西，对于tcp的socket来说就是误人子弟。。。

个人意见：用填空题考程序理解能力纯属脑残！

#由Windows版移至C语言


Question: 求大神帮忙做这个题目

引用 6 楼 情月的回复:问题已经被解答了，不过还是提几个建议： 1、提问的时候最好能把code排版下。这样方便别人查看和阅读。3楼的仁兄的code看过去就舒服点了。  2、然后看了你的code， 建议阅读下林锐《高质量c/c++编程指南》。对你会有帮助的。 大一小白刚学c语言没多久。目前还在努力中。谢谢你的建议，表示会去研究那边书的。

引用 4楼我是你的主体 的回复:[quote=引用 1 楼 小灸舞的回复:]1.你的fun函数写的有问题，k=1应该是k=2，k<n-1应该是k<=n-1 2.main函数里printf的应该是i，而不是k  #include<stdio.h> int fun(int n) { 	int k,r; 	for(k=2;k<=n-1;k++) 	{ 		r=n%k; 	if(r==0) 		break; 	} 	if(k==n) 		return 1; 	else 		return 0; } void main() {  	int i,j,k,sum; 	for(i=1;i<=1000;i++) 	{  		k=i; 		sum=0; 		while(k) 		{ 			j=k%10; 			if(fun(j)==0)break; 			sum+=j; 			k/=10; 		} 		if(fun(sum)&&k==0) 			printf("%d\n",i); 	}  }  谢谢大神我看了好久都没有反应过来。[/quote]解决了的话记得及时结帖

引用 1 楼 小灸舞的回复:1.你的fun函数写的有问题，k=1应该是k=2，k<n-1应该是k<=n-1 2.main函数里printf的应该是i，而不是k  #include<stdio.h> int fun(int n) { 	int k,r; 	for(k=2;k<=n-1;k++) 	{ 		r=n%k; 	if(r==0) 		break; 	} 	if(k==n) 		return 1; 	else 		return 0; } void main() {  	int i,j,k,sum; 	for(i=1;i<=1000;i++) 	{  		k=i; 		sum=0; 		while(k) 		{ 			j=k%10; 			if(fun(j)==0)break; 			sum+=j; 			k/=10; 		} 		if(fun(sum)&&k==0) 			printf("%d\n",i); 	}  }  谢谢大神我看了好久都没有反应过来。

已知某一整数,求各位数字均为素数,而且各位数字之和也为素数 什么意思，是不是  已知某一整数, 判断 它的 各位数字是否均为素数,而且各位数字之和也为素数？


Question: c语言 ip地址如何手动输入

请问 这个问题你是怎么改的呀 error C2664: 'inet_addr' : cannot convert parameter 1 from 'char (*)[32]' to 'const char *'

大神，怎样把分给你啊？是不是用结贴啊

大神，谢谢啊，我经过几次修改，没问题了，我成功了

谢谢你哦，不过有个错误：error C2664: 'inet_addr' : cannot convert parameter 1 from 'char (*)[32]' to 'const char *' inet_addr里面好像是const char* 类型，我改了一下，还是不对

scanf("%31s", &ip);

string q;   //这是什么鬼？C++里面的std::string？  char ip;    //char表达不了一个IP地址，不管是v4还是v6  ip=scanf("%s",&q); // scanf的返回值不是输入的内容（IP地址字符串）！成功读入的项数或EOF  sockaddr_in addrSrv;   addrSrv.sin_addr.S_un.S_addr = inet_addr(&ip); //&ip类型确实是char*，但不是以'\0'结尾的C字符串！！  稍微改下：  char ip[32] = "";  struct sockaddr_in addrSrv;    if (scanf("%s", &ip) != 1) {       printf("input error!\n");  }   memset(&addrSrv, 0, sizeof(addrSrv));   addrSrv.sin_family = AF_INET;   addrSrv.sin_addr.s_addr = inet_addr(&ip);  addrSrv.sin_port = htons(6000);

connect连接服务器时候失败的


Question: c语  将若干字符串按字母顺序小到大输出

引用 5 楼 qq423399099 的回复: 这样子不行？不知道楼主究竟想达到什么效果  恩 对  是我弄错了

这样子不行？不知道楼主究竟想达到什么效果

引用 3 楼 zhao4zhong1 的回复:#include<stdio.h> #include<string.h> void mysort(int *p,int n); void myprintf(char *name[],int n); void myscanf(char *name[],int n); int main() {     char *str[][];     int n;     myscanf(name,n);     mysort(name,n);     myprintf(name,n);  } void myscanf(char *name[],int n) {     int i;     for(i=0;i<n;i++)         scanf("%s",name[i]); } void mysort(char *name[],int n) {     char *temp;     int i,j;     for(i=0;i<n-1;i++)         for(j=i+1;j<n;j++)             if(strcmp(name[i],name[j])>0)             {                 temp=name[i];                 name[i]=name[j];                 name[j]=temp;             } } void myprintf(char *name[],int n) {     int i;     for(i=0;i<n;i++)         printf("%s\n",name[i]); }  还是不对啊  我也不知道怎么改？？

先输入一个数，指定一共有几个字符串 然后依次输入要排序的字符串(指针数组的每个指针都要malloc空间才行)

#include<stdio.h> #include<string.h> #include<stdlib.h> int main() { 	void sort(char *name[],int n); 	void myprintf(char *name[],int n); 	void std(char *name[],int n); 	char *name[32]; 	int n; 	scanf("%d", &n); 	std(name,n); 	sort(name,n); 	myprintf(name,n);  } void std(char *name[],int n) { 	int i; 	for(i=0;i<n;i++) 	{ 		name[i] = (char *)malloc(32); 		scanf("%s",name[i]); 	}  } void sort(char *name[],int n) { 	char *temp; 	int i,j; 	for(i=0;i<n-1;i++) 		for(j=i+1;j<n;j++) 			if(strcmp(name[i],name[j])>0) 			{ 				temp=name[i]; 				name[i]=name[j]; 				name[j]=temp; 			} } void myprintf(char *name[],int n) { 	int i; 	for(i=0;i<n;i++) 		printf("%s\n",name[i]); }


Question: 'getcher' undefined; assuming extern returning int这个怎么解决？

还有好多别的小错误。。。

萌新看错了，谢了

getcher 不是getchar 吗？


Question: 调用以下头文件的时候会出错，大概说是重定义了。求大声帮我找出原因和解决办法

是单片机程序，但是我包含了STC.H也是这样呢

这是单片机程序？应该是没有包含寄存器定义头文件，比如<reg51.h>之类的。

如果你的P0~P4是定义在别的文件中的话那么使用EXTERN 声明变量 如果不是的话，那么在当前文件中定义一下P0~P4

该头文件中，如 sbit     pb_GPIO0         = P1^6;   sbit     pb_GPIO1         = P4^2; sbit     pb_GPIO11        = P1^0; sbit     pb_GPIO12        = P1^1;  sbit     pb_GPIO5         = P1^2; sbit     pb_GPIO14        = P1^3;  sbit     pb_GPIO6         = P1^4; sbit     pb_GPIO9         = P0^0;	  这几个如何在使用它的文件里面定义？ 或者怎样可以调用帖子里面那个头文件，我一调用就会出错

不是重定义，而是没定义。 undefined identifier是常见的keil编译错误 引发这一错误的原因是你使用的变量没有被定义 常见的处理手段是对你使用到的变量进行变量定义 另外一种常见的错误就是大小写导致的 如你定义的是unsigned char num； 在使用的时候，写成了NUM，也会出现同样的错误。


Question: 刚开始看书自学C 看到for循环就碰到问题了求解

引用 3 楼 talkdream 的回复:[quote=引用 楼主 boy9178 的回复:] for循环求平均数  为什么会跳过里面的if检查输入一个数后就变这样了 输入数字后你又输入了回车，回车被下个scanf 取走了. 你在下面scanf 的%c 前面加一个空格就好了。这个空格有去除回车的作用 scanf(" %c",&answer);[/quote]  试了下果然是这个原因，谢谢！

自己查找一下错误原因，没那么难：for (;;) {     int ret;     int ans;     ////////////////////////////////////     /////// 此处代码略去     ////////////////////////////////////     ret = scanf("%c",&answer);     printf( "scanf: %d\n"             "answer: %c\n",             ret,             answer             );     ans = tolower(answer);     printf( "tolower: %c\n",             ans             );     if (ans == 'n')     {         break;     } }

你先geichar 一下 在  scanf   建议 scanf  写成getchar       一般获取 字符   需要 获取2次  第一次获取的是缓存里的回车 第二次才可以拿到  想要的字符  所以写两次getchar

引用 楼主 boy9178 的回复:for循环求平均数  为什么会跳过里面的if检查输入一个数后就变这样了 输入数字后你又输入了回车，回车被下个scanf 取走了. 你在下面scanf 的%c 前面加一个空格就好了。这个空格有去除回车的作用 scanf(" %c",&answer);

好吧，，不是这个原因，无视我我再看看

第16排，n要大写，'N' n和N在编码器中数值是不相等的  ------------------------------------------------ 我也是新手，握爪~一起加油~


Question: strtok函数问题，无法正确识别EOF

我再上一次代码吧： #include <stdio.h> #include <stdlib.h> #include <string.h>   int sum=0;/*信息条目总数*/   typedef struct{ char number[6];/*索书号*/ char bookname[30];/*书名*/ char author[40];/*作者及译者*/ char keyword[40];/*关键字*/ char zhongtu[10];/*中图法分类号*/ char ISBN[25];/*ISBN*/ char press[30];/*出版社*/ char pubdate[10];/*出版日期*/ char times[3];/*印刷版次*/ char appendix[30];/*配给*/ char info[50];/*备注*/    }book;  book data[200];/*结构数组用于保存全部书目信息*/  int main(void) {  int i;  char temp[274]={0};   FILE* load; load=fopen("library.txt","r"); if(load==NULL){  puts("lib didn't read properly");  exit(1);  }   	while(1){ 	memset(temp,0,274); 	fgets(temp,274,load); 	if(feof(load)) break;/*在读入最后一行后，feof才做有效检验*/      strcpy(data[i].number,strtok(temp,","));   /*数据加载*/  	strcpy(data[i].bookname,strtok(NULL,",")); 	strcpy(data[i].author,strtok(NULL,",")); 	strcpy(data[i].keyword,strtok(NULL,",")); 	strcpy(data[i].zhongtu,strtok(NULL,",")); 	strcpy(data[i].ISBN,strtok(NULL,",")); 	strcpy(data[i].press,strtok(NULL,",")); 	strcpy(data[i].pubdate,strtok(NULL,",")); 	strcpy(data[i].times,strtok(NULL,",")); 	strcpy(data[i].appendix,strtok(NULL,",")); 	strcpy(data[i].info,strtok(NULL,"\n"));          printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",data[i].number,data[i].bookname,data[i].author,data[i].keyword,data[i].zhongtu,\ 	data[i].ISBN,data[i].press,data[i].pubdate,data[i].times,data[i].appendix,data[i].info);      	i++;      sum++;/*数据加载 获得总条数*/ 	} 	 fclose(load); 	  return 0; } /*main函数*/

这个eof搞死我了  我在实际使用的时候，又产生了eof 提前结束的情况。也测试不出来原因，就正常的结束了，大神再看看吧？  代码跟上面的没有本质区别，我就上一下文件吧。估计还是文件出的问题。  1-1-05,GMAT词汇精选,俞敏洪(编著),英语-词汇-研究生,H313,978-7-80080-549-3,群言出版社,2006.1,8,光盘一张,  1-2-01,人间失格,太宰治(著)高詹灿(译),自传体-小说-日本,I313,978-7-201-07970-7,天津人民出版社,2013.3,5, ,人间失格即丧失人的资格 2-3-15,photoshop CS5 从入门到精通,新视角文化行(编著),图形软件-photoshop,TP391,978-7-115-23837-5,人民邮电出版社,2010.12,1,DVD两张,  4-1-10,中外著名枪械鉴赏图鉴,李大光(编著),手枪-世界-普及读物,E922,978-7-224-09475-6,西泠出版社,2012.1,1, ,美丽的过时 3-5-20,普通话水平测试实施纲要,国家语言文字工作委员会(编著),普通话-水平考试-自学,H102,978-7-100-03996-3,商务印书馆,2004.1,19,一张光盘,根据教育部发布《普通话水平测试管理规定制作本大纲》  莫名其妙在第四个读完之后，读第五个的时候就认为是eof了？而且data[i].number 明明值等于1-1-05,printf出来却等于1-1-05GMAT词汇精选 好奇怪啊。真的懵比，我就是照着上午的程序抄的，规模大了一点，不知道为什么又出错了。

看看这篇：http://blog.csdn.net/ysdaniel/article/details/7954668

还是想询问一下 空行并不算末尾对吧，不然正常的段落间的空行就无法判断了对吧？没想到竟然是这种地方的问题。

非常感谢，顺便问一下memset(temp,0,200)是说把temp数组的两百个元素初值都设定为0的意思吧。

引用 11 楼 qq423399099 的回复: 版主果然厉害，是多了一个空行？多了一个空行咋了？空行影响EOF吗？

我猜是你的a.txt最后多了一个空行，删掉空行试试。 或者改成下面这样：判断一下读到的字符数，如果是0的话就跳出  #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct{ char number[10]; char text[40]; char author[40]; char code[10];  }book; book data[20];  int main(void) { int i=0; char temp[200]={0}; FILE *in;  in=fopen("a.txt","r"); if(in==NULL){ printf("not open file."); exit(1); }   while(!feof(in)){	 	memset(temp, 0, 200);     fgets(temp,200,in); 	if(strlen(temp) == 0) 		break;     strcpy(data[i].number,strtok(temp,","));     strcpy(data[i].text,strtok(NULL,","));     strcpy(data[i].author,strtok(NULL,","));     strcpy(data[i].code,strtok(NULL,"\n"));     	     printf("%s\t%s\t%s\t%s\n",data[i].number,data[i].text,data[i].author,data[i].code);     i++; }        fclose(in);    return 0;	  }

引用 3 楼 qq423399099 的回复:楼主顺便贴下文件吧 其实我就是想写一个能读以逗号为分隔符的函数，越搞问题越多。。

测试了一下，按照ForestDB 还是不行。并不能测出EOF。  我观察之后是这样的，在我fgets我目标行之后，它还会再fgets一次，获得的数据是   所以我想到的大概是这么一个结构：  while(1) { fgets(temp,200,in); while(){  strcpy(data[i].number,strtok(temp,",")); strcpy(data[i].text,strtok(NULL,","));  strcpy(data[i].author,strtok(NULL,","));  strcpy(data[i].code,strtok(NULL,"\n"));  printf("%s\t%s\t%s\t%s\n",data[i].number,data[i].text,data[i].author,data[i].code);   i++; } break; }  现在因为我还是不太了解这个函数，所以不知道内层的while填写一个什么条件（我知道写什么，但不知道格式）。填写一个条件，让strtok的返回值等于null的时候，就终止（因为最后一次fgets的第一个值就是\n，如果判断能以\n作为分隔符，那么这个strtok的返回值就能是null，如果满足这个条件就停止就行了）。我觉得我离问题问题解决就差一点，可惜我基本功不牢。

另外文件中有中文，所以要注意编码中可能有\x0，所以要选对的API和注意编码问题。

引用 4 楼 ForestDB 的回复:while(!feof(in)){     fgets(temp,200,in);  把这一小段逻辑改成： while (1) {     fgets(temp, 200, in);     if (feof(in))         break; 或者直接是 while (fgets(temp, 200, in)) { 试试。  原因就是fgets读完文件最后一行后，并未到达文件结尾（可以假想EOF还为读到），这时去测试feof为假； 然后fgets再去读，才知道文件结束（读到EOF），这时feof测试才为真。我现在的想法已经很接近这个了！我马上试试。我另外把我测试遇到的问题再反馈一下。

a.txt吗？ 1-1-05,GMAT词汇精选,俞敏洪(编著),英语-词汇-研究生 1-2-01,人间失格,太宰治(著)高詹灿(译),自传体-小说-日本 2-3-15,photoshop CS5 从入门到精通,新视角文化行(编著),图形软件-photoshop 4-1-10,中外著名枪械鉴赏图鉴,李大光(编著),手枪-世界-普及读物 3-5-20,普通话水平测试实施纲要,国家语言文字工作委员会(编著),普通话-水平考试-自学

楼主顺便贴下文件吧

有谁看了这篇文章能明白我改怎么改吗？学生一枚，确实需要帮助呀  http://blog.csdn.net/liuintermilan/article/details/6283705


Question: 用CreateProcess打开某个应用程序，要怎么才能在这个应用程序的线程关闭后作出处理？

引用 1 楼 列子汤问的回复:这样不行吗  WaitForSingleObject( pi.hProcess, INFINITE );  pi.hProcess是子进程的Handle.  不是窗口的句柄。 试过了，不知怎么回事，程序关闭后一直没有返回，不知是不是我写错了。

引用 2 楼 zghmvp 的回复:[quote=引用 1 楼 列子汤问的回复:]这样不行吗  WaitForSingleObject( pi.hProcess, INFINITE );  pi.hProcess是子进程的Handle.  不是窗口的句柄。 试过了，不知怎么回事，程序关闭后一直没有返回，不知是不是我写错了。[/quote]  检查程序关闭后，程序的进程是否还在后台没有结束

引用 3 楼 user-2的回复:[quote=引用 2 楼 zghmvp 的回复:] [quote=引用 1 楼 列子汤问的回复:]这样不行吗  WaitForSingleObject( pi.hProcess, INFINITE );  pi.hProcess是子进程的Handle.  不是窗口的句柄。 试过了，不知怎么回事，程序关闭后一直没有返回，不知是不是我写错了。[/quote]  检查程序关闭后，程序的进程是否还在后台没有结束[/quote] 解决了，感谢。。。。


Question: 如何用变量初始化静态局部变量

引用 2 楼 brookmill 的回复:int func() { 	static int flag = 0;     static int x;     static int y = 10; 	if (!flag) 	{ 		x = rand(); 		flag = 1; 	}   这个有线程安全问题，别这么写。

c++之所以能够这么干是有它的道理的,明白crt0.s的桩程序吗?这个就是Linux中调用main函数的一段代码。为什么我要提这个,我要开始啰嗦了，为什么c++编译器这么难做,举个列子c++有一个东西,这个叫做全局类,这个类有个构造函数,这个构造函数优先于main函数。原有的crt0.s的桩程序就不能再满足c++程序,所以后面拆分了很多，名字我不细举了。那现在为啥c++允许你static int x = rand(); 原因就如上面所说的,你的random在main函数之前跑这是可以的,但是换成c就不可以了。还有一点细节就是,未初始化的静态变量处于bss段中,其值都是0

活人不会被尿憋死。

C里面不允许啊， 当然C++是可以的。

把x拿出来，作为全局变量吧。


Question: 在C语言编程中一直遇到的一个语法报错问题

先重新生成工程试试。 还不行的话代码和错误都截个图发上来。

引用 1 楼 qq423399099 的回复:把power10函数里的变量定义放到最前面  #include <stdio.h>  void test(); int power10(int n);   int power10(int n) { 	int i; 	int value = 10; 	if (n == 0) 		return 1; 	 	for (i = 1; i < n; i++) 	{ 		value *= 10; 	} 	return value; } void test() { 	printf("test\n"); } int main() { 	printf("%d\n",power10(3)); 	return 0; }  我已经放到最前面了啊。但是没用啊


Question: 一个新手关于指针的问题。

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

1. VS 不是 C 编译器，它是一个 C++ 编译环境。VS 对 C 的支持也就到了 2015 才好了一些。 2. 不是所有非法的东西编译器都会报错。使用非法的程序产生的任何后果都需要程序员自己负责。

C++下将通不过，C编译器类型转换时可能不做过多检查，所以可以将const int[]转换为int* 而C++下pd = ar;这一步会出错

简单说说： 编译器都会越来越智能 C语言来说： const int和 int 是两种不同的类型 这点一定要弄清楚。  从 const int 转换到 int 就会警告 这是C语言的规定

.cpp文件中这是一个错误，.c文件中这是一个警告。但都不能视而不见。建议把所有警告都当成错误。

你重建工程试试看。  除非强制性的做类型转换。  pd = (int *) ar;

我用的也是Visual Studio 10 ， 显示的结果是编译出错。  1error C2440: “=”: 无法从“const int [10]”转换为“int *”

你难道看不到警告？或者选择性忽视？编译通过也不证明一切都正确。


Question: 小白求助，无法读取内存

链表的操作，把每一步都在纸上画出来，更容易理解。 楼主也可以搜一些“删除链表结点”的示例代码作为参考

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

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

引用 6 楼 brookmill 的回复:假定链表a->b->c。如果要删除b，第一步是a->next=c，第二步才是free(b) 你的代码里少了第一步，链表就断了。 这里如果就输入1的话，head没有移动指向第一个结点，那head->next就是指向第二个节点，head = head->pNext;不是把head直接指向第二个结点了吗，那第一个节点不是被删除了吗？为什么会连接不上呢？

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

引用 4 楼 user-4 的回复:引用 3 楼 Never_Setttle 的回复:[quote=引用 1 楼 user-4 的回复:] 传入参数Head不正确（指向未初始化内存空间）。那应该怎么改，找了一天都没弄明白，其他的函数也是这样传入的但是没有错啊  你在函数开头加断点，断下后，看参数Head是不是正确，F10单步，每走一步看head的值，是不是一直都是正确的值。[/quote] 一直到Treaverse_book(Head);才出现上图中的无法读取内存的问题

引用 3 楼 Never_Setttle 的回复:引用 1 楼 user-4 的回复:传入参数Head不正确（指向未初始化内存空间）。那应该怎么改，找了一天都没弄明白，其他的函数也是这样传入的但是没有错啊  你在函数开头加断点，断下后，看参数Head是不是正确，F10单步，每走一步看head的值，是不是一直都是正确的值。

那应该怎么改，找了一天都没弄明白，其他的函数也是这样传入的但是没有错啊

传入参数Head不正确（指向未初始化内存空间）。


Question: 这道题做了一段时间发现自己做不出来，就来求助各位了

#include <stdlib.h> #include <stdio.h> #include <string.h>  char *fun(const char *src, const int len, int n) {     char *dest = (char *)malloc(sizeof(char) * len);     int i = 0, j = 0, k = 0;     //扫描前导有多少个*     for(i = 0; i < len; i ++)     {         if(src[i] == '*')         {             k ++;         }         else         {             break;         }     }     //前导小于n填*，之后填字符串内容     for(j = 0; j < len && i < len; j ++)     {         if(j < k && j < n)         {             dest[j] = '*';         }         else         {             dest[j] = src[i];             i ++;         }     }     return dest; }  int main(int argc, char* argv[]) {     char *tmp = "********************ssss***sssfff*****ffffff****";     char *dest = fun(tmp, strlen(tmp), 10);     printf("%s\n", dest);     free(dest);     return 0; }

#include <stdlib.h> #include <stdio.h> #include <string.h>  char *fun(const char *src, const int len, int n) { 	int i = 0, j = 0, k = 0; 	//扫描前导有多少个* 	for (i = 0; i < len; i++) 	{ 		if (src[i] == '*') 		{ 			k++; 		} 		else 		{ 			break; 		} 	} 	if (k > n) 	{ 		//若前导*的个数k 大于给定的n，则字符串的长度为:len-(k-n) 		int num = len - k + n + 1; 		char *dest = (char *)malloc(sizeof(char)* num);	 		for (i = 0; i < n; i++) 			dest[i] = '*'; 		for (i = n; i < num - 1; i++) 			dest[i] = src[i + k - n]; 		dest[num] = '\0'; 		return dest; 	} 	else 	{ 		char *dest = (char *)malloc(sizeof(char)* (len+1)); 		for (i = 0; i < len; i++) 			dest[i] = src[i]; 		dest[len] = '\0'; 		return dest; 	} }  int main(int argc, char* argv[]) { 	char *tmp = "**s"; 	char *dest = fun(tmp, strlen(tmp), 3); 	printf("%s\n", dest); 	free(dest); 	return 0; }

仅供参考：//有字符串 //1_22_333,,4444__55555,_666666 //需要解析为 //1 //22 //333 //_ //4444 //55555 //666666 #include <stdio.h> char s[]="1_22_333,,4444__55555,_666666"; char c,*p,*p1; int st; void main() {     st=0;     p=s;     while (1) {         c=*p;         if (0==c) {             switch (st) {             case 1:printf("_\n");    break;             case 2:printf("%s\n",p1);break;             }             break;//         }         switch (st) {         case 0:                  if ('_'==c) {                            st=0;}             else if (','==c) {                            st=1;}             else             {p1=p;                       st=2;}         break;         case 1:                  if ('_'==c) {                            st=1;}             else if (','==c) {printf("_\n");              st=1;}             else             {p1=p;                       st=2;}         break;         case 2:                  if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}             else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}             else             {                            st=2;}         break;         }         p++;     } } //1 //22 //333 //_ //4444 //55555 //666666

这个要看你在啥环境下了，标准C只能一点一点的比较，然后复制。 要是可以用字符串函数库，可以用字符串的的拷贝，链接等做一做。

void fun (char str[], int n) { 	int num; 	int len = strlen (str); 	//找到从哪个下标开始不是* 	for (int i = 0; i < len; i++) 	{ 		if(str[i] != '*') 		{ 			num = i; 		} 	} 	int count; 	//进行删除操作 	if (num >= n) 	{ 		for (int i = n, count = num; count <= len; i++,count++) 		{ 			str[i] = str[count]; 		} 	} } 上面那个是错的   删除哪有点问题

void fun (char str[], int n) { 	int num; 	int len = strlen (str); 	//找到从哪个下标开始不是* 	for (int i = 0; i < len; i++) 	{ 		if(str[i] != '*') 		{ 			num = i; 		} 	} 	int count; 	//进行删除操作 	if (num >= n) 	{ 		for (int i = n, count = num; i <= count; i++,count--) 		{ 			str[i] = str[count]; 		} 	} }


Question: strcmp有宽字符版本吗？或者有没有可代替的函数？

String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

wcscmp  http://en.cppreference.com/w/c/string/wide/wcscmp  另外可以使用_tcscmp，这样在unicode下等于wcscmp，多字节下等于strcmp

标准 C 就是： #include <stdio.h> #include <stdlib.h> #include <string.h> #include <tchar.h> _tcscmp - strcmp (ANSI) / wcscmp (Unicode) 好处是跨平台。  Windows 平台 API 有很多： int lstrcmp(const TCHAR *lpStr1, const TCHAR *lpStr2); int lstrcmpi(const TCHAR *lpStr1, const TCHAR *lpStr2); int StrCmpC(const TCHAR *lpStr1, const TCHAR *lpStr2); int StrCmpN(const TCHAR *lpStr1, const TCHAR *lpStr2, int cch); int StrCmpNI(const TCHAR *lpStr1, const TCHAR *lpStr2, int cch); BOOL StrIsIntlEqual(BOOL bCaseSens, const TCHAR *lpStr1, const TCHAR *lpStr2, int cch); BOOL IntlStrEqWorker(BOOL bCaseSens, const TCHAR *lpStr1, const TCHAR *lpStr2, int cch);  每个都分为 A 和 W 版本。如： #include <windows.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") const char str1[] = "ABC" const char str2[] = "abc" const WCHAR wstr1[] = L"ABC"; const WCHAR wstr2[] = L"abc" printf("%d\n", lstrcmpA(str1, str2)); printf("%d\n", lstrcmpW(wstr1, wstr2)); printf("%d\n", lstrcmpiA(str1, str2)); printf("%d\n", lstrcmpiW(wstr1, wstr2)); printf("%d\n", lstrcmpA(str1, str2)); printf("%d\n", lstrcmpW(wstr1, wstr2)); printf("%d\n", StrIsIntlEqualA(TRUE, str1, str2, 1024)); printf("%d\n", StrIsIntlEqualA(FALSE, str1, str2, 1024)); printf("%d\n", StrIsIntlEqualW(TRUE, wstr1, wstr2, 1024)); printf("%d\n", StrIsIntlEqualW(FALSE, wstr1, wstr2, 1024));


Question: 关于C语言字符串的问题

仅供参考：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

引用 5 楼 lunat 的回复:     printf("sendBuf size:%d\n", 4 + strlen(&sendBuf[4]));     printf("sendBuf:%s \n", &sendBuf[4]);  或者，打印unsigned char： int i;  for (i = 0; i < 4 + msglen; ++i) {     printf("%02hhX ", sendBuf[i]); }  建议：把数据包封装一下，类似： typedef struct message_s {     int length;     char str[2000]; } message_t;  void message_dump(const message_t * msg) {     printf("length=%d, str=\"%s\"\n", msg->length, msg->str); }  void message_fill(message_t * msg, const char * str) {     strncpy(msg->str, str, sizeof(msg->str) - 1);     msg->str[sizeof(msg->str) - 1] = '\0';     msg->length = strlen(msg->str); }    谢谢，明天试试

引用 1 楼 lunat 的回复:little_endian(msglen, &sendBuf[0]); 第二个参数类型是unsigned char *，这个函数是把一个整数（msglen）放在sendBuf缓冲区中。  sendBuf不表示一个以\0结尾的C风格字符串！ 对sendBuf执行strlen(sendBuf)是错误的。strlen只能对以\0结尾的C风格字符串操作。 后面printf %s想打印出sendBuf，也是错误的。  主要是我需要发送sendbuf，send（）需要知道长度，strlen不行的话，是不是需要用sizeof（）

引用 1 楼 lunat 的回复:little_endian(msglen, &sendBuf[0]); 第二个参数类型是unsigned char *，这个函数是把一个整数（msglen）放在sendBuf缓冲区中。  sendBuf不表示一个以\0结尾的C风格字符串！ 对sendBuf执行strlen(sendBuf)是错误的。strlen只能对以\0结尾的C风格字符串操作。 后面printf %s想打印出sendBuf，也是错误的。  谢谢。 之前尝试过sendbuf是unsigned char 然后执行  little_endian(msglen, &sendBuf[0]);  memcpy(&sendBuf[4], msg, msglen);     可是服务端说数据有问题，所以想打印出来看看到底是怎么回事，改成char为了打印方便。。。看来不对。  那这两句拼串的过程有什么问题么，如果是unsigned char ？ 如果想看unsigned char 数据，不用printf的话，怎么输出呢。 谢谢。

楼上正解.  little_endian(msglen, &sendBuf[0]); //改为:  little_endian(1684234849, &sendBuf[0]); 试试.


Question: 为什么两次输入的都是一样的，但数出来却多了个‘？’

仅供参考：#include <conio.h> #include <stdio.h> char pw[40]; int i,ch; FILE *f; void main() {     cprintf("\r\nPassword:");     i=0;pw[i]=0;     while (1) {         ch=getch();         if (ch==13 || i>=39) break;         switch (ch) {         case 27:             cprintf("\rPassword: %40s"," ");             cprintf("\rPassword: ");             i=0;pw[i]=0;             break;         case 8:             if (i>0) {                 i--;                 pw[i]=0;                 cprintf("\b \b");             }             break;         default:             pw[i]=ch;             i++;             pw[i]=0;             cprintf("*");             break;         }     }     cprintf("\r\n");     f=fopen("password.txt","w");     fprintf(f,"%s\n",pw);     fclose(f); }

因为   你输入  123456 的时候在数组里 存的是123456  当你在输入 abcd的时候那么数组就会自动的把abcd覆盖到1234里  但是 5和6 是没有覆盖的所以还是会显示出来,所以当你再次使用数组的时候要 memset 一下

你给一部分代码没法帮你调试  你自己单步跟踪程序运行，哪里多出一个什么来很容易就可以发现，然后分析原因

楼主 在声明 pass2的时候，没有初始化。  pass2 = {0};  就可以了。

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


Question: 请问如何把加法改为减法？

我能问问为什么这样修改吗。。。 {              pb->data.coef = -pb->data.coef;             pc->next=pb;pc=pb;pb=pb->next;         }这什么意思。。。

#include<stdio.h> #include<stdlib.h> #include<math.h> //多项式链表结点类型定义 typedef struct { 	float coef;  //系数 	int expn;  //指数 }DataType; typedef struct node { 	DataType data; 	struct node *next; }ListNode,*LinkList; int q;  //定义一全局量 int LocateNode(LinkList L,DataType e) { //查找定位算法 	ListNode *p=L->next; 	q=0;  //记录结点位置序号 	while(p&&e.expn<p->data.expn) 	{ p=p->next; 	q++; 	} 	//printf("%f,%d\n",e.coef,e.expn); 	if(p==NULL||e.expn!=p->data.expn) 		return 0; //查找失败 	else 		return 1; } //有序链表结点的插入 LinkList InsertNode(LinkList L,DataType e) {  //在有序表中插入一个结点，仍保持表的有序性 	ListNode *s,*p; 	int i=0;p=L; 	while(p->next&&i<q) 	{ p=p->next; 	i++; 	}//查找插入位置 	s=(ListNode *)malloc(sizeof(ListNode)); 	s->data.coef=e.coef; 	s->data.expn=e.expn; 	s->next=p->next; 	p->next=s; 	return L; } //多项式链表的建立 LinkList CreatPolyn(int n) { 	LinkList pa; 	int i; 	DataType e; 	pa=(ListNode *)malloc(sizeof(ListNode));//生成链表头结点 	pa->next=NULL; 	for(i=1;i<=n;i++) 	{ 		scanf("%f,%d",&e.coef,&e.expn); 		if(!LocateNode(pa,e))  //当前链表中不存在该指数项 			pa=InsertNode(pa,e); 	} 	return pa; } //多项式链表的输出 void printList(LinkList L) { 	ListNode *p; 	p=L->next; 	while(p) 	{ 		printf("%c %fx^%d",(p->data.coef>0 ? '+' : ' '),p->data.coef,p->data.expn); 		p=p->next; 	} 	printf("\n"); } //多项式两遍的相加 LinkList AddPolyn(LinkList La,LinkList Lb) {  //两个有序链表La和Lb表示多项式相加 	ListNode *pa,*pb,*pc,*s; 	LinkList Lc; 	float sum; 	pa=La->next;pb=Lb->next;  //pa和pb分别指向两个链表的开始结点 	Lc=pc=La;  //用La的头结点作为Lc的头结点 	while(pa&&pb){ 		if(pa->data.expn>pb->data.expn){ 			pc->next=pa;pc=pa;pa=pa->next; 		} 		else if(pa->data.expn<pb->data.expn) 		{  			pc->next=pb;pc=pb;pb=pb->next; 		} 		else { 			sum=pa->data.coef+pb->data.coef; 			if(fabs(sum)>1e-6){ //系数和不为零 				pa->data.coef=sum; 				pc->next=pa;pc=pa;pa=pa->next; 				s=pb;pb=pb->next;free(s); 			} 			else { 				s=pa;pa=pa->next;free(s); 				s=pb;pb=pb->next;free(s); 			} 		} 	} 	pc->next=pa?pa:pb;  //插入链表剩余部分 	free(Lb);   //释放Lb的头结点 	return Lc; }  //多项式两遍的相加 LinkList SubPolyn(LinkList La,LinkList Lb) {  //两个有序链表La和Lb表示多项式相加 	ListNode *pa,*pb,*pc,*s; 	LinkList Lc; 	float sum; 	pa=La->next;pb=Lb->next;  //pa和pb分别指向两个链表的开始结点 	Lc=pc=La;  //用La的头结点作为Lc的头结点 	while(pa&&pb){ 		if(pa->data.expn>pb->data.expn){ 			pc->next=pa;pc=pa;pa=pa->next; 		} 		else if(pa->data.expn<pb->data.expn) 		{  			pb->data.coef = -pb->data.coef; 			pc->next=pb;pc=pb;pb=pb->next; 		} 		else { 			sum=pa->data.coef-pb->data.coef; 			if(fabs(sum)>1e-6){ //系数和不为零 				pa->data.coef=sum; 				pc->next=pa;pc=pa;pa=pa->next; 				s=pb;pb=pb->next;free(s); 			} 			else { 				s=pa;pa=pa->next;free(s); 				s=pb;pb=pb->next;free(s); 			} 		} 	} 	s = pb; 	while(s) 	{ 		s->data.coef = -s->data.coef; 		s = s->next; 	} 	pc->next=pa?pa:pb;  //插入链表剩余部分 	free(Lb);   //释放Lb的头结点 	return Lc; }  //主控函数 void main() {   	LinkList La,Lb,Lc; 	int n; 	printf("输入第一个多项式的项数:  "); 	scanf("%d",&n); 	printf("输入第一个多项式的每一项的系数,指数:  \n"); 	La=CreatPolyn(n); 	printf("第一个多项式为:  "); 	printList(La); 	printf("输入第二个多项式的项数:  "); 	scanf("%d",&n); 	printf("输入第二个多项式的每一项的系数,指数:  \n"); 	Lb=CreatPolyn(n); 	printf("第二个多项式为:  "); 	printList(Lb); 	//Lc=AddPolyn(La,Lb); 	//printf("\n相加后的和多项式为:  "); 	Lc=SubPolyn(La,Lb); 	printf("\n相减后的和多项式为:  "); 	printList(Lc); }


Question: linux下怎么用c语言实现动态调用函数

EXAMPLE Load the math library, and print the cosine of 2.0:  #include <stdio.h> #include <dlfcn.h>  int main(int argc, char **argv) {     void *handle;     double (*cosine)(double);     char *error;      handle = dlopen ("libm.so", RTLD_LAZY);     if (!handle) {         fprintf (stderr, "%s\n", dlerror());         exit(1);     }      dlerror();    /* Clear any existing error */     *(void **) (&cosine) = dlsym(handle, "cos");     if ((error = dlerror()) != NULL)  {         fprintf (stderr, "%s\n", error);         exit(1);     }      printf ("%f\n", (*cosine)(2.0));     dlclose(handle);     return 0; }  If this program were in a file named "foo.c", you would build the program with the following command:   gcc -rdynamic -o foo foo.c -ldl   Libraries exporting _init() and _fini() will want to be compiled as follows, using bar.c as the example name:   gcc -shared -nostartfiles -o bar bar.c

引用 2 楼 Saleayas 的回复:假如你的共享库的名字叫 libSoName，并且导出 Func 函数。 这个 Func 函数对于不同的共享库就是不同的功能。  那么你的 main 函数传入 SoName。 那么使用 dlopen 打开这个共享库。 呼叫共享库的导出函数 Func 就可以了。  以后需要使用其他的功能，创建一个共享库，比如名字叫 libSoNameNew。 同样导出函数 Func 。实现自己的功能。 main 函数传入参数 SoNameNew 就可以了。  当然你需要手动把新建的共享库放入指定的目录。 你这个是什么环境下呢，我的环境是linux下纯c语言，没有 dlopen

引用 3 楼 Rewen 的回复:楼主可以参考一下设计模式里面的command模式。 linux下的c好像不行吧

赵老师的方法是可行的，就是对dlopen和dlsym的应用 不过一般而言，在Linux下，感觉还是写一个脚本，比如 shell 脚本或者 perl 脚本，这样比较容易实现， c++只是静态语言，而shell 和perl 是动态语言

switch(n) {  case 1:func1(); break; case 2:func2(); break; ... }

楼主可以参考一下设计模式里面的command模式。

少的话挨着比较，多的话就用hash查找，找到后调用对应函数.... 应该算是基础吧.....


Question: 初学者关于  指针  的一些问题！！！

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

首先你要知道 地址是什么。 指针是什么。 然后 指针变量 是什么。 指针变量存的是什么。 * 和 & 运算符的作用在不同的语句里面作用是什么。 有不同意见欢迎指正。

你的p是指针变量，直接printf ("p = %d\n", p); 当然输出的是地址了 只有解引用后（*）才能输出指针所指向的值 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！


Question: 编写程序，统计1-100，阿拉伯数字“5”出现的次数

引用 5 楼 baijiaheizhiganmao 的回复:[quote=引用 4 楼 qq423399099 的回复:] [quote=引用 3 楼 cqh963852 的回复:] [quote=引用 2 楼 baijiaheizhiganmao 的回复:] 5 15 25 35 45 55 65 75 85 95  -- 观察后发现,数子小于10的,可以判断他是否等于5 假如是就是5 数字>10 的可以模10 余下为5的就是有数字5 正解。[/quote] 50~59呢[/quote] 说的很对! 侧漏了![/quote]

引用 4 楼 qq423399099 的回复:[quote=引用 3 楼 cqh963852 的回复:] [quote=引用 2 楼 baijiaheizhiganmao 的回复:] 5 15 25 35 45 55 65 75 85 95  -- 观察后发现,数子小于10的,可以判断他是否等于5 假如是就是5 数字>10 的可以模10 余下为5的就是有数字5 正解。[/quote] 50~59呢[/quote] 说的很对! 侧漏了!

引用 3 楼 cqh963852 的回复:[quote=引用 2 楼 baijiaheizhiganmao 的回复:] 5 15 25 35 45 55 65 75 85 95  -- 观察后发现,数子小于10的,可以判断他是否等于5 假如是就是5 数字>10 的可以模10 余下为5的就是有数字5 正解。[/quote] 50~59呢

引用 2 楼 baijiaheizhiganmao 的回复:5 15 25 35 45 55 65 75 85 95  -- 观察后发现,数子小于10的,可以判断他是否等于5 假如是就是5 数字>10 的可以模10 余下为5的就是有数字5 正解。

5 15 25 35 45 55 65 75 85 95  -- 观察后发现,数子小于10的,可以判断他是否等于5 假如是就是5 数字>10 的可以模10 余下为5的就是有数字5  #include <iostream> using namespace std; int main() { 	int count = 0;				//计算器 	for(int i= 1;i<=100;i++) 	{ 		if(i<10 && i == 5) 			count++; 		else 		{ 			if(i%10 == 5) 				count ++; 		} 	} 	cout<<count<<endl; 	return 0; }

#include <stdlib.h> #include <stdio.h> #include <math.h> void  main() { 	int x=0; 	for(int i=1;i<=100;i++) 	{ 		int a=i%10; 		int b=i/10%10; 		if(a==5) 			x++; 		if(b==5) 			x++;  	} 	printf("%d",x); 	system("pause"); }


Question: 求大神指导，putchar和scanf的问题

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];

标红的能读到运算符这个应该好理解吧？ 标绿的之所以读不到，是因为你输入a,b对应的数字后，输入缓冲区有遗留的回车符，会直接被getchar()给读走 用scanf %c或者getchar读之前，最好都加一句fflush(stdin)清空输入缓冲区

前面一个char ch=getchar();是红色，后面一个char ch=getchar();是绿色，由于输入错误，颜色未显示


Question: open串口设备 20秒才返回

引用 10 楼 abc3240660 的回复:实际情况是 有其他进程close另一个串口设备时，tty_lock迟迟不释放  导致我open时，一直在等待 原来如比！

Linux好就好在是开源的。

引用 5 楼 zhao4zhong1 的回复:还有可能是不是串口之前已经被另一个进程或僵尸进程打开了。 现在基本可以定位到tty_open中的tty_lock导致了这么久的等待，还得继续分析

引用 6 楼 zhao4zhong1 的回复:会不会是串口通讯的对端的处理有问题。 或串口线缆太长，误码率超高。 …… 这种时候，需要“怀疑一切，打击一切”的心态。  我打开的是USB接口的4G模块生成的ttyUSB，没有线缆  你说的 引用 5 楼 zhao4zhong1 的回复:还有可能是不是串口之前已经被另一个进程或僵尸进程打开了。 正常的时候我试过，生成的串口设备是可以被多次打开的  所以好奇怪。。。

还有可能是不是串口之前已经被另一个进程或僵尸进程打开了。

引用 3 楼 zhao4zhong1 的回复:没准当时cpu被另一个进程或线程占用了。 倒也想过这个问题，但是10多秒才返回，这时间也忒长了。。。

没准当时cpu被另一个进程或线程占用了。

引用 1 楼 Rewen 的回复:是不是调用了fcntl函数？ 没有调用这个函数啊，我现在的测试程序 就只有open和close  在内核中添加了一些打印信息发现应用层调用open后，有时过了10多秒内核中的sys_open才调用

是不是调用了fcntl函数？


Question: 一元多项式的运算

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


Question: #C语言#起泡排序法的总结

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

楼主有兴趣建议把各种排序算法都实现一下，再进行一下比较

还有时间复杂度分析

版主，我这里blog登陆不了。所以发到这里。这里可以发PM你么？

是呢，放到这里你结贴咋搞啊

你这个可以发博客


Question: 请教一个算法问题。。。

引用 6 楼 FancyMouse 的回复:一个数x有N位，因为第一项至少是1，所以x>=10^(N-1)。因为高于N位的数码都是0，所以x<=9*10^(N-1)+9*10^(N-2)+...+9<10^N 10^(N-1)<=x<10^N 两边取log10 N-1<=log10(x)<N多谢耐心解答！

引用 4 楼 user-4 的回复:1)乘积化和： lg(a*b) = lg(a)+lg(b) 2)位数和对数的关系， 对于一个大于0 的数 x 常用对数的整数部分加一，就是位数 假设 lg(x) =n+lg(t)  //1<=t <10 则有 x= t  *10^n 也就数有 n+1位数  lg（1)=0 lg（2）=0.3010 lg(10)=1  3）常用对数 lg C语言中, 用库函数  log10表示 常用对数lg就是以10为底数的对数多谢耐心解答！

仅供参考：#include<stdio.h> #define N 1000    //要计算的N long s[N]={1,1},n=N,t=2,a=1,b=0; int main()//雨中飞燕之作 {     for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)         s[a]=(b+=s[a]*t)%10000,b/=10000;     for(printf("%d",s[*s]);--*s>0;) printf("%04d",s[*s]);     return 0; }

对于一个大于1 的数 x 当整数部分为负值的时候，表示这个是小于1 就变成计算小数位数了

引用 2 楼 user-4 的回复:数学上是没问题的 唯一有问题的，是精度问题  因为 n^ ( log( n,x)) =x;  所以 log(n，x) 的整数部分就是 x的位数 (x>0), 如果位数为负值 ，则该数字小于1  成绩的对数，等于对数和，所以这个加法没问题，可以求出位数，如果能够计算出并且精确度可控 那么这么做就可以了，不然会有误差 我就是想知道数学上这个怎么解释？解释为什么可以以取对数的方法来求它的位数？

scanf("%d",&m);       sum=0;       for(i=1;i<=m;i++)       {           sum=sum+log10((double)i);           }       printf("%d\n",(int)sum+1);


Question: C语言编的程序编译没有错误，运行时出现unhandled exception in xx.exe 0xC000005:Access Violation

引用 1 楼 lianshaohua 的回复:运行完这个函数后你做了什么操作？ channel函数：  void channel(dcomplex *ricianSeq, dcomplex *signalSeq, double sigma) {      dcomplex temp;     double nc, ns;     for(int i = 0; i < SYMBOLLEN; i++)     {         ricianSeq[i] = rician_distribution();         ComplexGauss(sigma, &nc, &ns);         temp = cMult(ricianSeq[i], signalSeq[i]);         signalSeq[i].re = temp.re + nc;         signalSeq[i].im = temp.im + ns;     } }

把修改后的signalSeq作为参数被channel函数调用； void channel(dcomplex *ricianSeq, dcomplex *signalSeq, double sigma)；

运行完这个函数后你做了什么操作？

引用 6 楼 qq423399099 的回复:眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 单步，设断点都尝试过了，还是没有找到问题所在for(int i = 0; i < SYMBOLLEN; i++)     {         randSeq[i] = rand() % ConstellationSize;         for(label = 0, m = 0; m < MODULATION_TYPE; m++)             label = (label<<1) + (int)encoded_bit[(i+1)*MODULATION_TYPE-m-1];         label = label ^ randSeq[i];         int index = m_pSignalMapper[label];          signalSeq[i] = m_pSignal[index];     } 执行完这个循环后程序里吗就出现 call stack 中提示：NTDLL! 775315ee()， 然后汇编跳到：775315EE   add     esp, 4

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


Question: C文件读写问题

先rb，如果不成功(说明没有创建)，再wb

第一次文件不存在，需要建立文件，rb+要出错

rb+

是在VC++6.0版本之下编写的


Question: 大神帮忙看下，为什么下面的方法不行？？

b指向的是垃圾区域，尝试写入会出现异常。 ps:下面那个程序'\0'也写错了

b是个野指针，没有分配空间。


Question: 怎么用C语言猜由电脑随机产生的一个四位数，输出你猜对了这个数中的哪几个数字，谢谢

怎么猜法，比大小？

#include <stdlib.h> #include <stdio.h> #include <math.h> void  main() { 	while(1){ 		printf("已经生成随机数，请输入猜测数据，4位数"); 		int x=rand() % 10000; 		int y; 		while(1){ 			int right_number=0; 			scanf("%d",&y); 			if(y%10==x%10) 				right_number++; 			if(y/10%10==x/10%10) 				right_number++; 			if(y/100%10==x/100%10) 				right_number++; 			if(y/1000%10==x/1000%10) 				right_number++; 			if(right_number==4) 			{ 				printf("恭喜，猜对了%d",x); 				getchar(); 				printf("重新生成随机数"); 				break; 			} 			printf("输入正确数字数目%d",right_number); 			system("pause"); 		} 		 	} 	 }


Question: 跪求：联合体中包涵结构体结构体中包涵位域的东东 整蒙了

理解和讨论之前请先学会如何观察！

引用 11 楼 u010165006 的回复:[quote=引用 5 楼 wsm19841205 的回复:]    [quote=引用 3 楼 u010165006 的回复:] unsigned int word;  // word是成员  恩，这个我知道的哈，以下是飞思卡尔单片机的底层，也有这个  byte Byte;就是不知道下面的值uvflag.Bit.flag3=1; uvflag.Bit.flag11=1;要变化 这个uvflag.word会跟着变化吗 /*** INTCR - Interrupt Control Register; 0x0000001E ***/ typedef union {   byte Byte;   struct {     byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte IRQEN       :1;                                       /* External IRQ Enable */     byte IRQE        :1;                                       /* IRQ Select Edge Sensitive Only */   } Bits; } INTCRSTR; extern volatile INTCRSTR _INTCR @(REG_BASE + 0x0000001EUL); #define INTCR                           _INTCR.Byte #define INTCR_IRQEN                     _INTCR.Bits.IRQEN #define INTCR_IRQE                      _INTCR.Bits.IRQE  #define INTCR_IRQEN_MASK                64U #define INTCR_IRQE_MASK                 128U[/quote]   uvflag.Bit.flag11=1;要变化 这个uvflag.word会跟着变化吗 —————————————— union里面各个成员是共享（映射）同一块内存（低两个字节二者是重叠的，高两个字节只属于word成员）[/quote] 我大概知道了，Word和结构体都是union的成员变量，共用内存，所占内存取最大者，Word和结构体所占空间一样大，都是2个字节，其中一个变化另外一个也变化？（低两个字节二者是重叠的，高两个字节只属于word成员）这句是什么意思呀？ typedef union{ unsigned int Word; struct { unsigned int  flag0:1; unsigned int  flag1:1; unsigned int  flag2:1; unsigned int  flag3:1; unsigned int  flag4:1; unsigned int  flag5:1; unsigned int  flag6:1; unsigned int  flag7:1; unsigned int  flag8:1; unsigned int  flag9:1;	 unsigned int  flag10:1; unsigned int  flag11:1; unsigned int  flag12:1; unsigned int  flag13:1; unsigned int  flag14:1; unsigned int  flag15:1;	 }Bit; }UVFLAG;

引用 14 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)  多谢多谢你的例子，很清晰

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

引用 18 楼 wsm19841205 的回复:[quote=引用 17 楼 u010165006 的回复:] word成员是unsigned int类型不是4个字节吗？你的是什么硬件平台，多少位的？ 是飞思卡尔16位的单片机哈[/quote] 那是2个字节

理解和讨论之前请先学会如何观察！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

引用 17 楼 u010165006 的回复:word成员是unsigned int类型不是4个字节吗？你的是什么硬件平台，多少位的？ 是飞思卡尔16位的单片机哈

引用 2 楼 wsm19841205 的回复:[quote=引用 1 楼 lm_whales 的回复:] 这事坑人牌的，代码 定义了一个类型(别名)word ， 和 union 的一个成员 word  颇有混淆是非的嫌疑 那这句uvflag.word就不起什么作用了吧？是吗[/quote] 起作用。  这种代码只能蒙自己 蒙不了编译器 编译器能清晰的分辨出这两个标志符 只是你自己可能分辨不了，研究几回， 可能就懵了 不知道他们谁是谁了

关于位段，，，，位顺序由 实现定义  例如 typedef unsigned char uchar; union{ uchar uc; struct { uchar  b0:1; uchar  b1:1; uchar  b2:1; uchar  b3:1; uchar  b4:1; uchar  b5:1; uchar  b6:1; uchar  b7:1;  }pos;  struct { uchar  b7:1; uchar  b6:1; uchar  b5:1; uchar  b4:1; uchar  b3:1; uchar  b2:1; uchar  b1:1; uchar  b0:1;  }rev; }flag;  flag.uc=0; flag.pos.b0=1;===> flag.uc =0x80,或者 0x01 不同实现，结果不同 flag.uc=0; flag.rev.b0=1;===> flag.uc =0x01,或者 0x80 不同实现，结果不同  这个联合体的情况大抵如此 不过，你这里，定义类型，和变量名相同， 虽然是允许的，确实是坑人的 同一个标志符，有两种不同的含义 他们的心理距离是0 我们从心理上，不倾向于分辨他们 这是跟自己作对的做法

引用 5 楼 wsm19841205 的回复:[quote=引用 3 楼 u010165006 的回复:] unsigned int word;  // word是成员  恩，这个我知道的哈，以下是飞思卡尔单片机的底层，也有这个  byte Byte;就是不知道下面的值uvflag.Bit.flag3=1; uvflag.Bit.flag11=1;要变化 这个uvflag.word会跟着变化吗 /*** INTCR - Interrupt Control Register; 0x0000001E ***/ typedef union {   byte Byte;   struct {     byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte IRQEN       :1;                                       /* External IRQ Enable */     byte IRQE        :1;                                       /* IRQ Select Edge Sensitive Only */   } Bits; } INTCRSTR; extern volatile INTCRSTR _INTCR @(REG_BASE + 0x0000001EUL); #define INTCR                           _INTCR.Byte #define INTCR_IRQEN                     _INTCR.Bits.IRQEN #define INTCR_IRQE                      _INTCR.Bits.IRQE  #define INTCR_IRQEN_MASK                64U #define INTCR_IRQE_MASK                 128U[/quote]   uvflag.Bit.flag11=1;要变化 这个uvflag.word会跟着变化吗 —————————————— union里面各个成员是共享（映射）同一块内存（低两个字节二者是重叠的，高两个字节只属于word成员）

引用 9 楼 user-4 的回复:[quote=引用 8 楼 wsm19841205 的回复:] [quote=引用 7 楼 user-4 的回复:] typedef unsigned int word;  unsigned int word;  这两句确实有问题，但不是语法问题，我猜作者的意思是： typedef unsigned int word; ... word word;  有关位域： https://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx https://msdn.microsoft.com/en-us/library/yszfawxh.aspx http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm 谢谢哈， 这个是底层里的开头大写的Word的定义   #if defined(__CHAR_IS_16BIT__)   typedef  unsigned char      Word;   typedef    signed char      sWord; #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__)   typedef  unsigned short     Word;   typedef    signed short     sWord; #elif defined(__INT_IS_16BIT__)   typedef  unsigned int       Word;   typedef    signed int       sWord;  小写的定义是typedef unsigned int word;  我写的这个unsigned int word;应该有点问题 正确的是word Word;  这个word flag1:1; word flag2:1; word flag3:1; word flag4:1; word flag5:1; word flag6:1; word flag7:1; word flag8:1; word flag9:1; word flag10:1; word flag11:1; word flag12:1; word flag13:1; word flag14:1; word flag15:1;	 里面的小写没问题。 这样能说的通吗？[/quote]  语法上没问题，但是系统底层定义一个Word是unsigned char，然后自己定义一个word是unsigned int，这样可能存在误导。 [/quote]  引用 9 楼 user-4 的回复:[quote=引用 8 楼 wsm19841205 的回复:] [quote=引用 7 楼 user-4 的回复:] typedef unsigned int word;  unsigned int word;  这两句确实有问题，但不是语法问题，我猜作者的意思是： typedef unsigned int word; ... word word;  有关位域： https://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx https://msdn.microsoft.com/en-us/library/yszfawxh.aspx http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm 谢谢哈， 这个是底层里的开头大写的Word的定义   #if defined(__CHAR_IS_16BIT__)   typedef  unsigned char      Word;   typedef    signed char      sWord; #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__)   typedef  unsigned short     Word;   typedef    signed short     sWord; #elif defined(__INT_IS_16BIT__)   typedef  unsigned int       Word;   typedef    signed int       sWord;  小写的定义是typedef unsigned int word;  我写的这个unsigned int word;应该有点问题 正确的是word Word;  这个word flag1:1; word flag2:1; word flag3:1; word flag4:1; word flag5:1; word flag6:1; word flag7:1; word flag8:1; word flag9:1; word flag10:1; word flag11:1; word flag12:1; word flag13:1; word flag14:1; word flag15:1;	 里面的小写没问题。 这样能说的通吗？[/quote]  语法上没问题，但是系统底层定义一个Word是unsigned char，然后自己定义一个word是unsigned int，这样可能存在误导。 [/quote]  引用 9 楼 user-4 的回复:[quote=引用 8 楼 wsm19841205 的回复:] [quote=引用 7 楼 user-4 的回复:] typedef unsigned int word;  unsigned int word;  这两句确实有问题，但不是语法问题，我猜作者的意思是： typedef unsigned int word; ... word word;  有关位域： https://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx https://msdn.microsoft.com/en-us/library/yszfawxh.aspx http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm 谢谢哈， 这个是底层里的开头大写的Word的定义   #if defined(__CHAR_IS_16BIT__)   typedef  unsigned char      Word;   typedef    signed char      sWord; #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__)   typedef  unsigned short     Word;   typedef    signed short     sWord; #elif defined(__INT_IS_16BIT__)   typedef  unsigned int       Word;   typedef    signed int       sWord;  小写的定义是typedef unsigned int word;  我写的这个unsigned int word;应该有点问题 正确的是word Word;  这个word flag1:1; word flag2:1; word flag3:1; word flag4:1; word flag5:1; word flag6:1; word flag7:1; word flag8:1; word flag9:1; word flag10:1; word flag11:1; word flag12:1; word flag13:1; word flag14:1; word flag15:1;	 里面的小写没问题。 这样能说的通吗？[/quote]  语法上没问题，但是系统底层定义一个Word是unsigned char，然后自己定义一个word是unsigned int，这样可能存在误导。 [/quote]  恩，我再看看哈，欧洲杯看吗？马上开始啦，西班牙 VS2016 捷克 哈哈

引用 8 楼 wsm19841205 的回复:[quote=引用 7 楼 user-4 的回复:] typedef unsigned int word;  unsigned int word;  这两句确实有问题，但不是语法问题，我猜作者的意思是： typedef unsigned int word; ... word word;  有关位域： https://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx https://msdn.microsoft.com/en-us/library/yszfawxh.aspx http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm 谢谢哈， 这个是底层里的开头大写的Word的定义   #if defined(__CHAR_IS_16BIT__)   typedef  unsigned char      Word;   typedef    signed char      sWord; #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__)   typedef  unsigned short     Word;   typedef    signed short     sWord; #elif defined(__INT_IS_16BIT__)   typedef  unsigned int       Word;   typedef    signed int       sWord;  小写的定义是typedef unsigned int word;  我写的这个unsigned int word;应该有点问题 正确的是word Word;  这个word flag1:1; word flag2:1; word flag3:1; word flag4:1; word flag5:1; word flag6:1; word flag7:1; word flag8:1; word flag9:1; word flag10:1; word flag11:1; word flag12:1; word flag13:1; word flag14:1; word flag15:1;	 里面的小写没问题。 这样能说的通吗？[/quote]  语法上没问题，但是系统底层定义一个Word是unsigned char，然后自己定义一个word是unsigned int，这样可能存在误导。

引用 7 楼 user-4 的回复:typedef unsigned int word;  unsigned int word;  这两句确实有问题，但不是语法问题，我猜作者的意思是： typedef unsigned int word; ... word word;  有关位域： https://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx https://msdn.microsoft.com/en-us/library/yszfawxh.aspx http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm 谢谢哈， 这个是底层里的开头大写的Word的定义   #if defined(__CHAR_IS_16BIT__)   typedef  unsigned char      Word;   typedef    signed char      sWord; #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__)   typedef  unsigned short     Word;   typedef    signed short     sWord; #elif defined(__INT_IS_16BIT__)   typedef  unsigned int       Word;   typedef    signed int       sWord;  小写的定义是typedef unsigned int word;  我写的这个unsigned int word;应该有点问题 正确的是word Word;  这个word flag1:1; word flag2:1; word flag3:1; word flag4:1; word flag5:1; word flag6:1; word flag7:1; word flag8:1; word flag9:1; word flag10:1; word flag11:1; word flag12:1; word flag13:1; word flag14:1; word flag15:1;	 里面的小写没问题。 这样能说的通吗？

引用 4 楼 u010165006 的回复:[quote=引用 2 楼 wsm19841205 的回复:] [quote=引用 1 楼 lm_whales 的回复:] 这事坑人牌的，代码 定义了一个类型(别名)word ， 和 union 的一个成员 word  颇有混淆是非的嫌疑 那这句uvflag.word就不起什么作用了吧？是吗[/quote]  UVFLAG这个union最长就是unsigned int word 成员 4个字节，Bit这个结构体成员只有2个字节。 uvflag.Bit.flag3=1; uvflag.word的值是多少呀？ 个人觉得应该是8（二进制第4位为1） [/quote]

引用 3 楼 u010165006 的回复:unsigned int word;  // word是成员  恩，这个我知道的哈，以下是飞思卡尔单片机的底层，也有这个  byte Byte;就是不知道下面的值uvflag.Bit.flag3=1; uvflag.Bit.flag11=1;要变化 这个uvflag.word会跟着变化吗 /*** INTCR - Interrupt Control Register; 0x0000001E ***/ typedef union {   byte Byte;   struct {     byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte             :1;      byte IRQEN       :1;                                       /* External IRQ Enable */     byte IRQE        :1;                                       /* IRQ Select Edge Sensitive Only */   } Bits; } INTCRSTR; extern volatile INTCRSTR _INTCR @(REG_BASE + 0x0000001EUL); #define INTCR                           _INTCR.Byte #define INTCR_IRQEN                     _INTCR.Bits.IRQEN #define INTCR_IRQE                      _INTCR.Bits.IRQE  #define INTCR_IRQEN_MASK                64U #define INTCR_IRQE_MASK                 128U

引用 2 楼 wsm19841205 的回复:[quote=引用 1 楼 lm_whales 的回复:] 这事坑人牌的，代码 定义了一个类型(别名)word ， 和 union 的一个成员 word  颇有混淆是非的嫌疑 那这句uvflag.word就不起什么作用了吧？是吗[/quote]  UVFLAG这个union最长就是unsigned int word 成员 4个字节，Bit这个结构体成员只有2个字节。 uvflag.Bit.flag3=1; uvflag.word的值是多少呀？ 个人觉得应该是8（二进制第4位为1）


Question: 输入错误格式的内容，编译器怎么处理？

如果输入了非法数据，键盘缓冲区就可能还有残余信息。 当使用scanf函数时，如果遇到一些匪夷所思的问题，在scanf函数后正确使用fflush(stdin);，清空输入缓冲区，可以解决很多问题。

引用 1 楼 u010165006 的回复:运行期，不是编译器的问题了 要看scanf这个函数具体怎么实现了  如果scanf函数是你编写的，如果输入错误，你默认给个0或者0xffff也是随你的，不过当然要符合常理。

运行期，不是编译器的问题了 要看scanf这个函数具体怎么实现了


Question: c strlen问题

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

字符串之类的，要留个位置哦，让系统放入\0的吧，否则如何使用操作，因为找不到尾巴啦

char s3[6] = { 'I', 'S', 'O', 'C', '+', '+' };你这样写，使得s3这个数组没有'\0'结尾 那执行strlen的时候就是看脸了，返回一个什么值都有可能

strlen碰到0才算结束…… 你的字符串中没有0，所以会越界查找，直接有找到0为止。

已经超出数据范围，结果不确定 char s3[7] = { 'I', 'S', 'O', 'C', '+', '+' };


Question: Modbus TCP 源码

libmodbus http://libmodbus.org/2016/libmodbus-v3-1-4/


DESCRIPTION        inet_aton() converts the Internet host address cp from  the  IPv4  num-        bers-and-dots  notation  into  binary  form (in network byte order) and        stores it in the structure that inp  points  to.  所以inet指internet，a指address（不正规的说法ascii），即"192.168.0.1"这样的字符串格式的地址（人可读）； n指number/numeric，即0xC0A80001这样数字格式的地址（机器可读）。

inet_ntoa The Windows Sockets inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format.  char FAR * inet_ntoa (   struct in_addr in   );   Parameters in  [in] A structure that represents an Internet host address.  Remarks The inet_ntoa function takes an Internet address structure specified by the in parameter and returns an ASCII string representing the address in ".'' (dot) notation as in "a.b.c.d''. The string returned by inet_ntoa resides in memory that is allocated by Windows Sockets. The application should not make any assumptions about the way in which the memory is allocated. The data is guaranteed to be valid until the next Windows Sockets function call within the same thread, but no longer. Therefore, the data should be copied before another Windows Sockets call is made.  Return Values If no error occurs, inet_ntoa returns a char pointer to a static buffer containing the text address in standard ".'' notation. Otherwise, it returns NULL.   QuickInfo   Windows NT: Yes   Windows: Yes   Windows CE: Use version 1.0 and later.   Header: Declared in winsock2.h.   Import Library: Link with ws2_32.lib.  See Also inet_addr


Question: 求教这个程序的运行过程，为什么s=1,结果会输出65

是先打印出6后程序没有停下来，又进入了下一个case又打印了一个5，所以你看到的是65了吧

引用 7 楼 小灸舞的回复:解决了记得结帖 貌似手机上找不到这个功能啊

解决了记得结帖

引用 4 楼 小灸舞的回复:建议楼主再去看下switch....case case只是个标签，表示跳转到那里开始执行，如果没有break,它会一直往后面执行  你输入一个小于0的数就能跳出while循环了 谢谢指教，已解决，我忽略后面有个break可以跳出循环

对于switch（i）语句，根据i的值进入对应的case语句中，如果执行完该case之后的语句没有遇到break，则会按顺序继续运行下面的case语句，依次类推，直到遇到break或者运行到最后一行case才会退出。        至于while（）怎么退出……只要满足while（）括号里的条件，程序就会一直运行的，通过scanf("%d",&s);来改变s的值，如果你输入的s小于0，不满足while（）的条件，程序就会推出while了。        这些都是基础，不会的时候多看基本概念。

引用 1 楼 小灸舞的回复:因为你输入1，会进入case 1的分支，然后输出6 因为没有break,会继续执行case 2，然后输出5，然后break; 执行到scanf("%d",&s);等待输入 而且这个while循环该怎么跳出

引用 1 楼 小灸舞的回复:因为你输入1，会进入case 1的分支，然后输出6 因为没有break,会继续执行case 2，然后输出5，然后break; 执行到scanf("%d",&s);等待输入 但是s=1啊，case后面是2不应该执行后面的语句吧


Question: C语言读取PLC数据

为什么只读到第一个的值呢,D500的,其他读出来的都是错误的

Short data[5]; int i; lRet = object.ReadDeviceBlock2("d500",5,&data[0]); for (i=0;i<5;i++) printf("%04hx ",data[i]);


Question: 求教vs里pow等重载函数的问题,谢谢谢谢!

引用 24 楼 akirya 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] 看来vs里面的智能提示功能不区分C和C++ 区分的，基于语义解析出来的。[/quote] 那为什么还会出现19楼的现象？

引用 21 楼 zhao4zhong1 的回复:看来vs里面的智能提示功能不区分C和C++ 区分的，基于语义解析出来的。

依赖智能提示的码农当不了码村长。

引用 27 楼 akirya 的回复:[quote=引用 25 楼 zhao4zhong1 的回复:] [quote=引用 24 楼 akirya 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] 看来vs里面的智能提示功能不区分C和C++ 区分的，基于语义解析出来的。[/quote] 那为什么还会出现19楼的现象？[/quote] 还是没设置成C编译器啊。[/quote] 我在VS2010里面没找到设置的地方。

引用 25 楼 zhao4zhong1 的回复:[quote=引用 24 楼 akirya 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] 看来vs里面的智能提示功能不区分C和C++ 区分的，基于语义解析出来的。[/quote] 那为什么还会出现19楼的现象？[/quote] 还是没设置成C编译器啊。

VS 对 C 的支持，直到 VS2015 才好了一些。

引用 16 楼 tkk13 的回复:[quote=引用 15 楼 akirya 的回复:] [quote=引用 11 楼 tkk13 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 8 楼 tkk13 的回复:] 是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++[/quote] 这个我改过了,不过效果是什么?  我输入pow(还是跳出6个函数类型让我选.[/quote] 用__cplusplus检测时候是C++  至于提示,可能智能提示的问题。[/quote] 用__cplusplus检测的时候还是有error红色下划线.配置改了还是这样,扩展名也是.c了.[/quote] 呃，那就不清楚你的问题在哪里了。

试试： 将整个代码用 extern "C" { ... ... } 括住

看来vs里面的智能提示功能不区分C和C++

引用 18 楼 akirya 的回复:[quote=引用 16 楼 tkk13 的回复:] [quote=引用 15 楼 akirya 的回复:] [quote=引用 11 楼 tkk13 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 8 楼 tkk13 的回复:] 是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++[/quote] 这个我改过了,不过效果是什么?  我输入pow(还是跳出6个函数类型让我选.[/quote] 用__cplusplus检测时候是C++  至于提示,可能智能提示的问题。[/quote] 用__cplusplus检测的时候还是有error红色下划线.配置改了还是这样,扩展名也是.c了.[/quote] 呃，那就不清楚你的问题在哪里了。[/quote] 好吧,谢谢!

引用 17 楼 zhao4zhong1 的回复:试试： 将整个代码用 extern "C" { ... ... } 括住 括住了,"但pow("依旧出来6个选项, #if defined(__cplusplus) #error "CPP" #endif error下面也还是有红色波浪线.

引用 8 楼 tkk13 的回复:是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++

引用 15 楼 akirya 的回复:[quote=引用 11 楼 tkk13 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 8 楼 tkk13 的回复:] 是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++[/quote] 这个我改过了,不过效果是什么?  我输入pow(还是跳出6个函数类型让我选.[/quote] 用__cplusplus检测时候是C++  至于提示,可能智能提示的问题。[/quote] 用__cplusplus检测的时候还是有error红色下划线.配置改了还是这样,扩展名也是.c了.

引用 11 楼 tkk13 的回复:[quote=引用 9 楼 akirya 的回复:] [quote=引用 8 楼 tkk13 的回复:] 是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++[/quote] 这个我改过了,不过效果是什么?  我输入pow(还是跳出6个函数类型让我选.[/quote] 用__cplusplus检测时候是C++  至于提示,可能智能提示的问题。

引用 13 楼 zhao4zhong1 的回复:源代码扩展名由cpp改为c？ 可是解决方案栏目下源文件的名字已经是以.c为结尾了

源代码扩展名由cpp改为c？

引用 10 楼 user-4 的回复:在C里面，pow是double类型参数 另外有powf，powl对应float与long double参版本  http://en.cppreference.com/w/c/numeric/math/pow 恩,正确的C环境下pow本来应该只有1中函数类型可以选,可是我用visual编写的时候它会弹出多个pow类型让我选择. 也就是说我的编辑环境是c++环境, 我是想换成专门c的环境

引用 9 楼 akirya 的回复:[quote=引用 8 楼 tkk13 的回复:] 是error 编译选项在哪里?没找到 菜单->项目->属性->C/C++ -> 高级 -> 编译为 ->  TC是C代码 TP是C++[/quote] 这个我改过了,不过效果是什么?  我输入pow(还是跳出6个函数类型让我选.


Question: C语言问题，好累啊找不出错

所有问题均已排除，但是否能得到正确的预期结果，还有待运行检验 #include<stdio.h> #include<string.h> #include<stdlib.h> #define length 5  struct employee {     char employeeid[10];    //职工号     char name[10];            //姓名     char sex[10];            //性别     int age;                //年龄     float basesalary;        //基本工资     float postWage;            //岗位工资     float totalwages;        //总工资 }; typedef struct employee EMPLOYEE;  //1.显示菜单 void displayMenu() {     printf("\n++++++++++++++++++++++++++++++++++++++++++++++\n");     printf("+                职工工资管理系统              +\n");     printf("+                   1.输入信息                 +\n");     printf("+                   2.输出信息                 +\n");     printf("+                   3.查询信息                 +\n");     printf("+                   4.修改信息                 +\n");     printf("+                   5.排序                     +\n");     printf("+                    6.保存到文件               +\n");     printf("+                   7.从文件读                 +\n");     printf("+                   8.退出程序                 +\n");     printf("+                                              +\n");     printf("\n++++++++++++++++++++++++++++++++++++++++++++++\n"); }  //2.登陆函数，验证口令 int login(char password[]) {     int flag;     static char key[10]="123";     if(strcmp(password,key)==0)     {         flag=1;     }     else     {         flag=0;     }     return flag; }  void unique(EMPLOYEE *employee,int leng,char employeeid[]) {     int i=0;     printf("请输入职工的职工号(以0结束)：");     scanf("%s",employee[i].employeeid);     for(i=1; i<leng ;i++)     {         while(gets(employeeid)!=0)         {             strcpy((employee+i)->employeeid, employeeid);             if((employee+i-1)->employeeid==(employee+i)->employeeid)             {                 printf("已有该职工。请重新输入");                 gets(employeeid);                 continue;             }             break;         }     } }  //5.输入信息到结构体数组中 void inputInfo(EMPLOYEE *employee,int leng) {     int i;     printf("请输入职工信息：");     for(i=0; i<leng ;i++)     {         scanf("%s %s %d %f %f %f", (employee+i)->name, (employee+i)->sex, &(employee+i)->age,             &(employee+i)->basesalary, &(employee+i)->postWage, &(employee+i)->totalwages);     } }  //6.输出结构体数组中的数据 void outputInfo(EMPLOYEE *employee, int leng) {     printf("输出职工信息：");     for(int i=0; i<leng ;i++)     {         printf("%s %s %s %d %f %f %f", (employee+i)->employeeid, (employee+i)->name, (employee+i)->sex, (employee+i)->age,             (employee+i)->basesalary, (employee+i)->postWage, (employee+i)->totalwages);     } }  //7.按职工号查询结构体数组中的数据 void queryInfo(EMPLOYEE employee[], int leng, char employeeid[]) {     int flag=0;     printf("请输入需要查询的职工的职工号：");     gets(employeeid);     for(int i=0; i<=leng ;i++)     {         if(strcmp(employeeid, employee[i].employeeid)==0)         {             flag=1;             break;         }     }     if(flag=1)     {         printf("%s %s %s %d %f %f %f", employee[i].employeeid, employee[i].name, employee[i].sex, employee[i].age,             employee[i].basesalary, employee[i].postWage, employee[i].totalwages);     }     else     {         printf("not found.");     } }  //8.按总工资降序对结构体数组中的职工信息进行排序 void sortScore(EMPLOYEE employee[], int leng) {     int i, j;     EMPLOYEE temp;     for(i=0; i<leng ;i++)         for(j=0; j<leng-j ;j++)             if(employee[j].totalwages > employee[i+1].totalwages)             {                 temp=employee[j];                 employee[j]=employee[j+1];                 employee[j+1]=temp;             } } /* //9.保存结构体数组中的数据到文件 void writeToFile(EMPLOYEE employee[], int length) {}*/  //10.修改信息 void ModifyOne(EMPLOYEE *employee) {     int i;     printf("请输入需修改信息的职工的职工号：\n");     scanf("%d", &i);     printf("请继续输入修改后的信息:\n");     scanf("%s %s %d %f %f %f", (employee+i-1)->name, (employee+i-1)->sex, &(employee+i-1)->age,             &(employee+i-1)->basesalary, &(employee+i-1)->postWage, &(employee+i-1)->totalwages); }  //主程序 void main() {     int i, flag, chos;     char password[10];     char employeeid[10];     EMPLOYEE *employee;      for(i=0;i<=3;i++)     {         printf("请输入登录口令：");         gets(password);         flag=login(password);         if(flag==1)         {             printf("登录成功。");             displayMenu();                                //显示菜单             printf("请选择你需要使用的功能：");             scanf("%d", &chos);             switch(chos)             {                 case 1:unique(employee, length, employeeid);inputInfo(employee,length);break;                 case 2:outputInfo(employee, length);break;                 case 3:queryInfo(employee, length, employeeid);break;                 case 4:ModifyOne(employee);break;                 case 5:sortScore(employee, length);break;                 case 6:                 case 7:                 case 8:break;break;                 default:printf("输入错误。");             }          }         else if(flag==0)         {             printf("输入错误，请重新输入。");             if(i==3)             {                 printf("输入出错三次，退出系统。");                 break;             }             continue;         }     } }

void unique(EMPLOYEE *employee, int length, char employeeid[])中 length,与#define length 5中length同名

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

引用 3 楼 paschen 的回复:另外：  void unique(EMPLOYEE *employee, int length, char employeeid[])   这里的length换一个名字吧，因为你已经在上面#define length 5  把length定义成宏的名字了 不只这里，所有以length作为形参的函数，都要把形参length换一下

void unique(EMPLOYEE *employee, int length, char employeeid[]) 函数中，  strcpy(employee+i)->employeeid, employeeid);   改成：  strcpy((employee+i)->employeeid, employeeid);

//4.验证输入职工的唯一性中的  strcpy(employee+i)->employeeid, employeeid); 少一个括号

把错误拿去一搜就行，一般常见的问题都能找到答案。

引用 6 楼 qq_33271984 的回复:好多这种类似的错误比如 warning C4013: 'outputInfo' undefined; assuming extern returning int 是怎么回事啊，还有 error 2143:syntax error:missing';'before'type'. 求大神详解，急需 第一个问题好理解，就是表面的意思。但是第二个问题就比较复杂了，能引起这个问题的直接原因有很多，但是归根结底和编译有关系，如果你知道你的代码在机器中是怎么编译的话，就很容易理解为什么提示缺少分号了。比如你代码中length的问题

引用 6 楼 qq_33271984 的回复:好多这种类似的错误比如 warning C4013: 'outputInfo' undefined; assuming extern returning int 是怎么回事啊，还有 error 2143:syntax error:missing';'before'type'. 求大神详解，急需 第1句的意思是某个变量没定义, 则编译器默认它在外部文件中定义, 并默认是int型. 第2句的意思是少了分号


Question: 散分＋快来报名“C语言指针与汇编内存地址（三、四）”公开课

这个要认真学习，关于指针与内存！

学习，并且来支持一下。

学习了。

引用 53 楼 sprint06 的回复:哈哈哈，新人来报道啊，刚刚听了老师的课，还不错的感觉哦 理解和讨论之前请先学会如何观察！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

学习

哈哈哈，新人来报道啊，刚刚听了老师的课，还不错的感觉哦

学习

支持赵老师！

引用 47 楼 liuyiqi5145 的回复:支持赵老师！ 来自00:20:27的支持我是应该感动还是应该悲哀呢？  or

点个赞

感快报名啊米娜桑

好久没有写过C的代码了。 学习了。

支持赵老师.

引用 41 楼 user-17 的回复:赵老师的课坚决支持，赵老师，我爱你！！ 在CSDN是禁止搞基的。

赵老师的课坚决支持，赵老师，我爱你！！


Question: GDI 全屏如何改成窗体

来源保密。

引用 4 楼 zhao4zhong1 的回复:  老赵这个是中文版的MSDN里的？

窗口宽度包括两边框，高度也包括两边框（其它标题栏、菜单栏要看创建的窗口样式有没有）

引用 1 楼 u010165006 的回复:ScreenW=GetSystemMetrics(SM_CXSCREEN); ScreenH=GetSystemMetrics(SM_CYSCREEN);   width=GetSystemMetrics(SM_CXSCREEN); //屏幕宽度改成你需要的窗口宽度（客户区宽度+两边沿） height=GetSystemMetrics(SM_CYSCREEN);  //屏幕高度改成你需要的窗口高度（客户区高度+标题栏+菜单栏+边沿） hWnd=CreateWindow( "BasicApp", "Basic Applicaton", WS_POPUP|WS_MAXIMIZE, 0,0, width,height, NULL,NULL, hCurrentInst,NULL);  WS_POPUP|WS_MAXIMIZE  可以改成  WS_OVERLAPPEDWINDOW ，窗口样式参数很多，具体要查MSDN

width=GetSystemMetrics(SM_CXSCREEN)/2; height=GetSystemMetrics(SM_CYSCREEN)/2;


Question: 一道编程题

引用 5 楼 xw3527858 的回复:百度考试碰到这道题了，以下是我写的代码，可惜提交的时候页面抽风，代码不完整。。。 #include <iostream> using namespace std; void GetTheNext1(int**& gird,int n,int m,int rows,int columns) { 	gird[n][m] = 0; 	if ((n+1)<rows&&gird[n+1][m]==1) 	{ 		GetTheNext1(gird,n+1,m,rows,columns); 	} 	if ((n-1)>=0&&gird[n-1][m]==1) 	{ 		GetTheNext1(gird,n-1,m,rows,columns); 	} 	if ((m+1)<columns&&gird[n][m+1]==1) 	{ 		GetTheNext1(gird,n,m+1,rows,columns); 	} 	if ((m-1)>=0&&gird[n][m-1]==1) 	{ 		GetTheNext1(gird,n,m-1,rows,columns); 	} } int GetTheNubmer(int** grid,int n,int m) { 	int rows = n; 	int	columns = m; 	int theNumbers=0; 	for(int i = 0;i<n;i++) 	{ 		for (int j=0;j<m;j++) 		{ 			if (grid[i][j] == 1) 			{ 				GetTheNext1(grid,i,j,rows,columns); 				theNumbers++; 			} 		} 	}  	return theNumbers; } 具体思想是，每找到一个1，房子数+1，然后将这个1上下左右的1全置为0（此处递归），所以要把传数组的引用

这个你做出来了么？

你还记得测试用例？

引用 1 楼 user-4 的回复:这不是四连通区域提取吗？ 能帮忙写一下，或者找源代码吗

这不是四连通区域提取吗？


Question: coad = C, 动态开辟二维数组的方法有多少种

会这一种就行：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //