Question: C语言将会推出历史的舞台吗？

引用 45 楼 zhao4zhong1 的回复:[quote=引用 39 楼 luciferisnotsatan 的回复:] [quote=引用 38 楼 DelphiGuy 的回复:] 赵老师是绝对不会退出CSDn的舞台滴。  来了几年，活跃用户除了赵老师，都换了好几波了。[/quote] 天下武功，最厉害的莫过于活的比你长。[/quote]  神龟虽寿,犹有竟时。

引用 39 楼 luciferisnotsatan 的回复:[quote=引用 38 楼 DelphiGuy 的回复:] 赵老师是绝对不会退出CSDn的舞台滴。  来了几年，活跃用户除了赵老师，都换了好几波了。[/quote] 天下武功，最厉害的莫过于活的比你长。

周围没人用C不代表C不在周围。 LZ多虑了。

引用 36 楼 m13286282 的回复:可是我发现周围的人没有一个用c的 往底层走走看看？就像楼上说的那样，给上层世界打造一个很好的编程环境——代表就是Unix/Linux！包括嵌入式开发，驱动开发也是以C为战场的！

还有大批大批一心扑在 C 上的人，楼主你的圈子不是计算机世界的全部，大家都在干着不同的事 用汇编、C 的人在辛勤的打造着你用来学习编程的世界，有兴趣你要进去看看

想多了，底层硬件还是得靠C

除非计算机又推出什么新架构思想，否则..不会

引用 38 楼 DelphiGuy 的回复:赵老师是绝对不会退出CSDn的舞台滴。  来了几年，活跃用户除了赵老师，都换了好几波了。

赵老师是绝对不会退出CSDn的舞台滴。

可是我发现周围的人没有一个用c的

引用 36 楼 m13286282 的回复:可是我发现周围的人没有一个用c的 你换个地方（比如华为公司）再发现一下。

C语言退不退出历史舞台没什么意思>  关键能否解决问题.

我也觉得楼主多虑了

那也不是退出，只是使用会变少，底层越来越完善，只需小部分的人维护

晕死，C要退出的话，那得先操作系统退出，操作系统是C写的，系统API也是C，各语言底层都用C，

lz想多了。。。

21,25楼++ 尤其21楼，在下觉得他道出了本质 目前个人看，还没有语言能够超越lisp。好多高级语言都是在模仿lisp的一些特性，而从未超越！ 楼主要坚信，几十年风雨依旧不倒，自有它不倒的原因！既然几十年都过来了，那为什么会在这个时候能够瞬间倒下？显然是不可能的！此外，越底层越抽象，越抽象越精悍，越精悍越强大！这就是计算机的哲学：简单就是美！

引用 30 楼 wwwwpppp628 的回复:不论什么语言，都是一堆规则而已。这个世界上，还没有一套规则能对所有问题适用。凡是最后都得落实到具体的任务身上，我想应该没人愿意用java去写驱动，用C去写UI。 象Quake3这样的UI还得用C写。


Question: 谁能说一下循环左移和循环右移

移位运算都是无符数才移位啊

循环移位只跟带不带C标志位有关系。 《The Intel 64 and IA-32 Architectures Software Developer's Manual》

循环移位跟最高位符号位没关系。

0111 0111 1110 1110 1101 1101 1011 1011 0111 0111

你都说是循环了，左移时，最低位被最高位补充，右移时，最高位被最低位补充。  要不然怎么循环？


Question: char array[5] = “csdn”;中，“csdn”储存的位置？

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

3楼正解

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

看定义位置， 非静态数组 定义在函数内部的，很可能有两个位置保存这个数据。 其一在常量区（静态数据区）这个是程序员无法访问的。 其二在函数运行时候，初始化数组时，复制到数组内部。（早期C，函数内部的非静态数组，不能初始化）  对于全局变量，包括 各种静态变量，C语言，在数组内部，储存用于初始化数组的常量数据。 这是编译好就确定的，一般来说，程序装载到内存，就完成了数组的初始化。  C++ 则有可能会尽可能这么处理， 但是由于C++有构造函数，所以有些可能要延迟到程序运行时才初始化 而C++ 函数内部的静态数组，可能会在函数第一次运行时候，才会初始化。  总之，在数组内部空间储存常量，至于会不会有其他辅助空间，编译器会根据需要处理。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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对应的汇编并单步执行观察相应内存和寄存器变化。）  《Windows PE权威指南》

函数外就为全局变量 在函数中就在栈中

引用 1 楼 xiaohuh421 的回复:char array[5]  保存在这个数组中.  const char *p = "CSDN"   //保存在常量区 char p[] = "CSDN";  //保存在数组p中, 也就是在栈中.  数组大小会根据初始化串的大小自动分配栈空间. char p[5] = "CSDN"  //同上.+1


Question: C语言中的指针操作

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

先看一个类似的例子： void f(int i) {   i = 2; // 这个改动不会修改main里面的n } int main() {   int n = 1;   f(n);   printf("%d\n", n); // n还是1 } 要通过函数f来修改main里面的n，就是1楼和2楼的两个办法： void f(int *i) {   *i = 2; } 或者 int f() {   return 2; } 在这里，指针和普通变量其实是一样的，只不过就是要用二级指针。

你的输入字符时的格式有问题吧，用getchar不是很好吗

引用 楼主 Vanquish_self 的回复:最近还是做二叉树啊栈啊的操作 经常发现当程序涉及指针地址操作的时候，在执行的时候就会弹出提示框，无法按正常运行。 下面是程序段： void CreateBinTree(TriNode *T){ 	char c; 	scanf(&c);  	if(c==' '){ 	   T=NULL;          } 	else if(c!=' ') 	{ 		if(!(T=(TriNode*)malloc(sizeof(TriNode)))) exit(0); 		T->data=c; 		CreateBinTree(T->lchild); 		CreateBinTree(T->rchild); 	}  } main代码段没有给出来   但是经过debug已经发现问题就出现在函数类型（main函数就是一个输入） 第二段 返回指针变量 TriNode* CreateBinTree(TriNode *T){ 	char c; 	scanf(&c);  	if(c==' '){ 	   T=NULL;          } 	else if(c!=' ') 	{ 		if(!(T=(TriNode*)malloc(sizeof(TriNode)))) exit(0); 		T->data=c; 		CreateBinTree(T->lchild); 		CreateBinTree(T->rchild); 	} 	return T; }  改成这样以后编译依旧没有错，可是执行就会出现下面的提示   求大牛解救解救小白       其实之前在sacnf输入的时候也会出现这样的问题，那是因为忘记在变量之前打地址符了。我猜测这里还是因为地址操作的原因，但是不知道怎么修改，或者说不知道本质错误。 用的工具是DEV-C++  TriNode* CreateBinTree() {     TriNode* T;     char c;      //scanf(&c);      scanf("%c", &c);      if (c == '\n') {         T = NULL;     } else {         if (!(T = (TriNode *)malloc(sizeof(TriNode)))) {             exit(0);         }         T->data = c;         T->lchild = CreateBinTree();         T->rchild = CreateBinTree();     }          return T; }

或者这样也可以： void CreateBinTree(TriNode **T){ char c; scanf(&c);  if(c==' '){    *T=NULL;          } else if(c!=' ') { if(!(*T=(TriNode*)malloc(sizeof(TriNode)))) exit(0); (*T)->data=c; CreateBinTree(&(*T)->lchild); CreateBinTree(&(*T)->rchild); } }

TriNode* CreateBinTree(){ char c; TriNode *T; scanf(&c);  if(c==' '){    T=NULL;          } else if(c!=' ') { if(!(T=(TriNode*)malloc(sizeof(TriNode)))) exit(0); T->data=c; T->lchild = CreateBinTree(); T->rchild = CreateBinTree(); } return T; }


Question: 如何更高效率的显示第1500个数呢？省略前面1-1499个数。

引用 2 楼 bagademosuki 的回复:void main()    {   int cnt;   for (int i=1,j=1;j<=1500;i++)     {        if (POW(i))        {          j++;        }     }  printf("第1500个=%d\n",i);    } 你既然只要第1500个，前面就不要输出就好了 帅爆了 比我的快！

算法效率低下 #include "stdafx.h" #include <stdio.h> #include<stdlib.h> #include<iostream> #include<vector> using namespace std;  int min3(int a,int b,int c) { 	int tmp=(a<b?a:b); 	return (tmp<c?tmp:c); } int main() { 	vector<int> uglyNum; 	uglyNum.push_back(1);  //初始只有1在数组中 	int t2=0,t3=0,t5=0; //每个因子开始相乘的下标位置 	int i,j,k; 	while(uglyNum.size()!=1500) 	{ 		int m2,m3,m5;  //保存每个因子得到的值 		for(i=t2;i<uglyNum.size();i++) 			if(2*uglyNum[i]>uglyNum.back()) 			{ 				m2=2*uglyNum[i]; 				break; 			} 			for(j=t3;j<uglyNum.size();j++) 				if(3*uglyNum[j]>uglyNum.back()) 				{ 					m3=3*uglyNum[j]; 					break; 				} 				for(k=t5;k<uglyNum.size();k++) 					if(5*uglyNum[k]>uglyNum.back()) 					{ 						m5=5*uglyNum[k]; 						break; 					} 					int tmp = min3(m2,m3,m5); 					uglyNum.push_back(tmp); 					if(tmp==m2) 						t2=i+1;  //下标位置进行更新 					if(tmp==m3) 						t3=j+1; 					if(tmp==m5) 						t5=k+1; 	} 	for(int i=0;i<uglyNum.size();i++) 		 printf("第%d个=%d\n",i+1,uglyNum[i]); 		cout<<endl; 	system("pause"); 	return 0; }

引用 3 楼 brookmill 的回复:当然不是printf的问题，printf再慢，也只不过执行1500次而已，浪费不了多少时间。 关键还是算法的效率太低了。我运行楼主的代码要20多秒，而高效的解法(包括1500个printf)也就几毫秒。 这是个经典题目，叫“丑数”，也常见于面试，随便一搜就能找到大量的解法和代码。 基本的思路和求质数的筛法类似，不要浪费大量时间判断每个数是不是符合要求，而是反过来直接生成符合要求的数。 #include <stdio.h> int results[2048]; int main() {   int idx2 = 1;   int idx3 = 1;   int idx5 = 1;   results[1] = 1;   for (int i=2; i<=1500; i++)   {     int result2 = 2 * results[idx2];     int result3 = 3 * results[idx3];     int result5 = 5 * results[idx5];     results[i] = (result2 < result3) ? result2 : result3;     if (results[i] > result5) {       results[i] = result5;     }     printf("第%d个=%d\n", i, results[i]);     while (2 * results[idx2] <= results[i]) idx2++;     while (3 * results[idx3] <= results[i]) idx3++;     while (5 * results[idx5] <= results[i]) idx5++;   }  return 0; }+1，逆向思维好

是的printf是个很低效的语句，涉及到外设的语句效率都不会高到那里去


Question: C语言

谢谢大家的指导 ，问题解决了！初学习C语言，多多指教!

三楼好人一个，直接给出这么详细的代码了。 给颁个CSDN好人奖

# include <stdio.h> # include <malloc.h> # include <stdlib.h>  typedef struct Node  //链式栈 {         int data;         struct Node *pNext; }NODE, *PNODE;  void initStack(PNODE);               //初始化栈 void pushStack(PNODE, int);      //圧栈操作 bool popStack(PNODE, int*);     //出栈操作，出栈元素存放在d bool is_empty(PNODE);             //判断栈是否为空  int main() {         int N;   //要转化的十进制数         int k;   //转化成的进制数         int d;   //出栈元素存放在d         printf("请输入要转化的十进制数: ");         scanf("%d", &N);         printf("请输入要转的数制: ");         scanf("%d", &k);          NODE S;         initStack(&S);           while(N>0)         {                 pushStack(&S, N%k);                 N = N/k;         }         while(!is_empty(&S))         {                 popStack(&S, &d);                 printf("%d ", d);         }          return 0; } void initStack(PNODE S) {        // S = (PNODE)malloc(sizeof(NODE));//注释掉这句          if(NULL == S)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         S->pNext = NULL;  } void pushStack(PNODE S, int val) {         PNODE pNew = (PNODE)malloc(sizeof(NODE));         if(NULL == pNew)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         pNew->data = val;         pNew->pNext = S->pNext;         S->pNext = pNew; } bool is_empty(PNODE S) {         if(NULL == S->pNext )                 return true;         else                 return false; }  bool popStack(PNODE S, int *pVal) {         if( is_empty(S) )                 return false;         else         {                 PNODE p = S->pNext;                 *pVal = p->data;                 S->pNext = p->pNext;                 free(p);                 return true;         } }

主要是你需要知道为什么要这样改，再讨论吧~~~

# include <stdio.h> # include <malloc.h> # include <stdlib.h>   typedef struct Node  //链式栈 {         int data;         struct Node *pNext; }NODE, *PNODE;   void initStack(PNODE);               //初始化栈 void pushStack(PNODE, int);      //圧栈操作 bool popStack(PNODE, int*);     //出栈操作，出栈元素存放在d bool is_empty(PNODE);             //判断栈是否为空   int main() {         int N;   //要转化的十进制数         int k;   //转化成的进制数         int d;   //出栈元素存放在d         printf("请输入要转化的十进制数: ");         scanf("%d", &N);         printf("请输入要转的数制: ");         scanf("%d", &k);           NODE S;    //这儿是一个结构体变量（不是指针哦），在initStack里你用的malloc哦。所以，这儿应该用指针。        //PNODE S = NULL；试试这样会不会运行呢         initStack(&S);             while(N>0)         {                 pushStack(S, N%k);                 N = N/k;         }         while(！is_empty(S))         {                 popStack(S, &d);                 printf("%d ", d);         }           return 0; } void initStack(PNODE *S)    //这儿 {         *S = (PNODE)malloc(sizeof(NODE));         if(NULL == *S)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         *S->pNext = NULL;   } void pushStack(PNODE S, int val) {         PNODE pNew = (PNODE)malloc(sizeof(NODE));         if(NULL == pNew)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         pNew->data = val;         pNew->pNext = S->pNext;         S->pNext = pNew; } bool is_empty(PNODE S) {         if(NULL == S->pNext)                 return true;         else                 return false; }   bool popStack(PNODE S, int *pVal) {         if( is_empty(S) )                 return false;         else         {                 PNODE p = S->pNext;                 *pVal = p->data;                 S->pNext = p->pNext;                 free(p);                 return true;         } } 抱歉还需要改。我是欠考虑~~~

# include <stdio.h> # include <malloc.h> # include <stdlib.h>  typedef struct Node  //链式栈 {         int data;         struct Node *pNext; }NODE, *PNODE;  void initStack(PNODE);               //初始化栈 void pushStack(PNODE, int);      //圧栈操作 bool popStack(PNODE, int*);     //出栈操作，出栈元素存放在d bool is_empty(PNODE);             //判断栈是否为空  int main() {         int N;   //要转化的十进制数         int k;   //转化成的进制数         int d;   //出栈元素存放在d         printf("请输入要转化的十进制数: ");         scanf("%d", &N);         printf("请输入要转的数制: ");         scanf("%d", &k);          NODE S;    //这儿是一个结构体变量（不是指针哦），在initStack里你用的malloc哦。所以，这儿应该用指针。        //PNODE S = NULL；试试这样会不会运行呢         initStack(&S);           while(N>0)         {                 pushStack(&S, N%k);                 N = N/k;         }         while(！is_empty(&S))         {                 popStack(&S, &d);                 printf("%d ", d);         }          return 0; } void initStack(PNODE S) {         S = (PNODE)malloc(sizeof(NODE));         if(NULL == S)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         S->pNext = NULL;  } void pushStack(PNODE S, int val) {         PNODE pNew = (PNODE)malloc(sizeof(NODE));         if(NULL == pNew)         {                 printf("动态内存分配失败!\n");                 exit(-1);         }         pNew->data = val;         pNew->pNext = S->pNext;         S->pNext = pNew; } bool is_empty(PNODE S) {         if(NULL == S->pNext)                 return true;         else                 return false; }  bool popStack(PNODE S, int *pVal) {         if( is_empty(S) )                 return false;         else         {                 PNODE p = S->pNext;                 *pVal = p->data;                 S->pNext = p->pNext;                 free(p);                 return true;         } }   入栈，出栈和判断栈是否为空都没有问题，问题应该出在initstack上。 如果按照我说的改还有问题，那再联系我，我们再沟通分析一下。

调试吧！要学会解决问题，而不是遇到问题就上论坛问！


Question: C单链表

//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             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=5;                 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) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     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-> //

引用 2 楼 cfjtaishan 的回复:对于初学链表，建议在写对应操作函数时，可以考虑在草稿纸上画一画，搞清节点指针的指向。 你这个好像没写demo测试程序哦，自己写个测试一下吧。对不对，只有测试了才能知道。 有写测试了也通过了，希望大家给点优化的指点

仅供参考 http://yun.baidu.com/s/17yIcQ

//楼主是否想创建len个节点呢？尝试一下这样： NODE *CreateLink(int len) {       if (0 == len)           return NULL;      NODE *phead = *cur = *tmp = NULL;      for (i = 0; i < len; i++) {          if (NULL == phead) {              phead = InitNode(i);              cur = phead;           }          else          {               tmp = InitNode(i);               cur->next = tmp;               cur = tmp;          }      }      return phead; }  NODE *InitNode(int val) {       NODE *p = (NODE *)malloc(sizeof(NODE));       if (NULL == p) {               fprintf(stderr, "malloc error\n");               exit(EXIT_FAILURE);       }       p->data = val;        p->next = NULL; }  NODE *CreateLink( int len ){     NODE *head,*current,*temp;//头节点指针，当前指针,创建指针     if( len == 0 ) return NULL;//长度为零，返回空指针     head = (NODE *)malloc( sizeof (NODE));     head->data = 0;     head->next = NULL;     if( len == 1 ) return head;//长度为1，返回头节点     current = head;//当前指针指向头节点     for( int i =1; i < len; i++ ){          temp = (NODE *)malloc( sizeof (NODE));//分配内存,并将当前指针的next指向内存         temp->data = i;         temp->next = NULL;         current->next = temp;//表示将current所指向的节点的next指向temp         current = temp;//表示将current指针移向新生成的节点temp     }     return head; }


Question: typedef的用法

引用 10 楼 u013163178 的回复:create是一个指针，他指向一个函数void * function(void) 谢谢你哈，能不能帮忙解决这个问题啊 http://bbs.csdn.net/topics/390920981

引用 7 楼 FightForProgrammer 的回复:typedef void * (*create)(void);  声明一个叫做create类型的指针，这个指针是一个函数指针，这个指针指向一个无参数、返回void*的函数。  详细内容可以参考函数指针、typedef 谢谢你哈，能不能帮忙解决这个问题啊 http://bbs.csdn.net/topics/390920981

引用 8 楼 my_live_123 的回复:定义一个类型别名 这句代码定义一个函数指针类型void * (*)(void)的别名create 需要定义这样的函数指针的时候，直接 create fun; //fun的类型void * (*)(void) 谢谢你哈，能不能帮忙解决这个问题啊 http://bbs.csdn.net/topics/390920981

void * (*create)(void); 就是定义一个函数指针void*是这个函数的返回类型，别的没有什么了。

引用 3 楼 falcomavin 的回复:这个typedef给这个函数指针定义了一个别名，你以后可以直接创建该函数指针，比如 create c；//c就是上面那种类型的函数指针 http://bbs.csdn.net/topics/390920981

引用 2 楼 user-7 的回复:[quote=引用 楼主 wangqing008 的回复:] typedef void * (*create)(void);  [/img] 确实是个函数指针呀。 和这个很类似的。       #include <signal.h>       void (*signal(int sig, void (*func)(int)))(int);       or in FreeBSD's equivalent but easier to read typedef'd version:       typedef void (*sig_t) (int);       sig_t      signal(int sig, sig_t func); [/quote] 可以帮忙看看这个吗？漏写了 一个函数，最近看源码看到的，不懂 http://bbs.csdn.net/topics/390920981

前边也是函数指针啊 http://zhidao.baidu.com/link?url=nkdC3naJiN-dWjTOr5eADJSE08JCrerLwJAB5q33KFftJD_vWBtheVyShI-2-zsvlC5jDKZ7UO0A8DF_qmrh_K

引用 楼主 wangqing008 的回复:typedef void * (*create)(void);  [/img] 确实是个函数指针呀。 和这个很类似的。       #include <signal.h>       void (*signal(int sig, void (*func)(int)))(int);       or in FreeBSD's equivalent but easier to read typedef'd version:       typedef void (*sig_t) (int);       sig_t      signal(int sig, sig_t func);


Question: malloc函数在什么情况下会直接出现段错误而不是返回NULL

不用看肯定其他地方越界。光看这代码肯定啥都看不出来。

你加下malloc分配失败判断吧，会不会是分配失败又去free导致的错误呢？

#include <stdio.h> #include <malloc.h> #include <stdlib.h> void main(void) { 	char **list; 	list = (char**)malloc(200 * sizeof(char*));     if(list == NULL) { 		perror("mem error\n"); 		exit(1); 	}  }  VC6.0没有发现问题 你把你的运行崩后的提示截个图

以下是用valgrind运行的结果，不知道有没有参考价值，valgrind我其实不太会用 本来应该更新到顶楼但不知怎么显示我没有权限，就加在这里了 valgrind --tool=memcheck --leak-check=full ./x 10gs_ligand.mol2  ==15439== Memcheck, a memory error detector ==15439== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==15439== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==15439== Command: ./x 10gs_ligand.mol2 ==15439==  ==15439== Invalid write of size 8 ==15439==    at 0x4C2F793: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15439==    by 0x402A41: identify (id.c:149) ==15439==    by 0x401A26: target (read_mol2.c:95) ==15439==    by 0x400FB4: main (main.c:15) ==15439==  Address 0x591f208 is 0 bytes after a block of size 168 alloc'd ==15439==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15439==    by 0x402911: identify (id.c:141) ==15439==    by 0x401A26: target (read_mol2.c:95) ==15439==    by 0x400FB4: main (main.c:15) ==15439==  ok n_pt: 21 key_num: 210 --15439-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting --15439-- si_code=80;  Faulting address: 0x0;  sp: 0x802b9ddd0  valgrind: the 'impossible' happened:    Killed by fatal signal ==15439==    at 0x3805CF06: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) ==15439==    by 0x380216D4: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) ==15439==    by 0x380218A2: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) ==15439==    by 0x3809DC03: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) ==15439==    by 0x380AC87C: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)  sched status:   running_tid=1  Thread 1: status = VgTs_Runnable ==15439==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15439==    by 0x40689C: key (key.c:44) ==15439==    by 0x40742D: distscore (distscore.c:165) ==15439==    by 0x400FD0: main (main.c:18)

引用 10 楼 lovesmiles 的回复:[quote=引用 8 楼 bagademosuki 的回复:] [quote=引用 5 楼 lovesmiles 的回复:] 没看出这个malloc用法有什么问题，我更倾向于你的程序有其它的问题。  单独建一个程序测试这个用法看看。 我试了，把这个程序稍加修改单独运行没有问题。 我想问下这样怎么办。。。[/quote]  信息量太少了，你已经引导我们向你设想的问题方向去了。如果问题不出在malloc上面，你把malloc的代码贴出来我们也分析不出原因。[/quote] sorry...如果把全部代码贴出来的话，确实是挺多了，而且还需要很多输入文件，量很大，我觉得不是很合适。 另一方面，这个问题可能真的和之前有关，但他仍是在调用一个简单的malloc时出的错，从这里入手大概可以解决吧。。。我把valgrind的信息贴上来好了

引用 8 楼 bagademosuki 的回复:[quote=引用 5 楼 lovesmiles 的回复:] 没看出这个malloc用法有什么问题，我更倾向于你的程序有其它的问题。  单独建一个程序测试这个用法看看。 我试了，把这个程序稍加修改单独运行没有问题。 我想问下这样怎么办。。。[/quote]  信息量太少了，你已经引导我们向你设想的问题方向去了。如果问题不出在malloc上面，你把malloc的代码贴出来我们也分析不出原因。

引用 6 楼 mymtom 的回复:板子上跑的程序？ 不是，写来在PC上做计算的。

引用 5 楼 lovesmiles 的回复:没看出这个malloc用法有什么问题，我更倾向于你的程序有其它的问题。  单独建一个程序测试这个用法看看。 我试了，把这个程序稍加修改单独运行没有问题。 我想问下这样怎么办。。。

引用 4 楼 r_Jimy 的回复:你的编译环境是怎么样的，可能动态空间的分配确实受到了限制 另外，你将malloc返回的地址强转成二级指针没问题吗？ 我是UBUNTU 14.04 Linux guxiaoPC 3.8.0-32-generic #47-Ubuntu icc version 13.1.1 (gcc version 4.7.0 compatibility) 其它地方也有这种转换好像没有问题，void理论上应该可以随便转的吧

板子上跑的程序？

引用 1 楼 user-7 的回复:不至于，因为你分配的空间又不大。。。。  你可以把你的错误信息贴出来看看 n_pt: 21 key_num: 210 Segmentation fault (core dumped) 上面一行是这几行之前的输出，没有问题 下面就是报错，除了说是段错误没有什么有价值的信息了

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

不至于，因为你分配的空间又不大。。。。  你可以把你的错误信息贴出来看看


Question: 关于c语言用function算完美数会输出两个一样结果的问题

已经明白怎么改了，谢谢各位帮助www

引用 5 楼 r_Jimy 的回复:引用 4 楼 Nintenxu 的回复:[quote=引用 3 楼 r_Jimy 的回复:] while(x<=limit)问题不在这里吧...我改了之后出来一大堆东西..... 不好意思理解错了，专业点要改PerNum的算法，不专业的判断下重复值吧[/quote]唔...我想尝试改下PerNum算法，根据第一个人回复也大概知道问题在哪可是还是不太会改Orz

引用 4 楼 Nintenxu 的回复:引用 3 楼 r_Jimy 的回复:while(x<=limit)问题不在这里吧...我改了之后出来一大堆东西..... 不好意思理解错了，专业点要改PerNum的算法，不专业的判断下重复值吧

while(x<=limit)

引用 1 楼 user-2 的回复:你把printf("%d\n",PerNum(x));改成printf("%d %d\n",x,PerNum(x));你就知道为什么了。 顺便目测下一个33550336会输出6次。唔...大概明白怎么回事了，可还是不太清楚怎么改，在下面m=m*2后面加上x++也没用啊...


Question: C语言字符串与函数调用的问题，求大神解答！

*实参定义成*str，虽然编译通过，但是打不出来。用str[100]就可以了  *str 只定义了一个指针，没有定义空间。 str[100]则分配了100个char空间。  这是c的基本知识，你还是先把书看完再说吧。

引用 1 楼 u013163178 的回复:我草，你这。。。。。你知道,下面两语句的区别吗 char str[100]; char *str; 什么，不知道，那就去看看书吧，太基础了+1

char *str;仅仅是定义了一个字符指针而已，而且没有指向有效的内存空间（这是关键）。char str[100]; 则是定义了一个长度为1000的字符数组，数组名就指向数组的首地址（一个有效的内存空间）


Question: 指针作为函数参数的调用疑问

所以你传任何指针地址进去都是正确的 但是使用的时候，必须转化成你要的指针类型 不然无法解释那段内存中的数据 以及数据格式

不算 void *表示任意类型的指针，不能解释说明指针类型以及内存大小 使用的时候必须转回来

指针的长度都是一样的。在一些严格的编译器可能会提出类型不符，需要显式转换二个指针。但大部份编译器都会通过的。

就是为了可以进行强制转化而写成void*,只要你保证传进去和接收的类型一致就可以在函数内部进行强制转化而没有问题。

楼上正解，另说明下： const void *data类型的参数在函数内部只能传值，不能修改指向的内容，所以AvlNode指针结点传到该函数内，这个结点的内容不会改变

const void *data void*可以表示一切类型的指针。你只要在函数中转换回来就ok了


Question: 求指点const使用问题

我用的vs2005，试验了下，会提示  error C2659: “=”: 作为左操作数

楼上解释const有点不对 const所修饰的物体 表示该物体是不可变的 不可以修改的 并不是常量 ， 而且const带有类型检测功能，编译时 比如  const char comp_c='@'; 表示变量comp_c的值永远为'@'，不可以修改 去除掉const则改变值可以修改 虽然意思都是不变的 常量一般说是 1 2 3 “12zzx”等

把const去掉就行。const是常量，不能更改。

引用 3 楼 skyabc 的回复:make_move=(board,x,y,player_c);   /* 错误代码位置，cannot convert `const   这段要把=去掉吧  然后我也试了编译了下，可以运行的啊 这位朋友解说的正确，小小的错误纠结了我好久啊，错误提示强一点的编译器有没有推荐啊


Question: 一个小程序带来的思考

为什么不参考bsearch函数的源代码呢？

逻辑修改了一下 给了 0 1 3 6 7这几个测试用例，没问题了

#include "stdafx.h" #include <stdio.h> int binary_search(int a[],int left,int right,int number) { 	if (left>right) 	{ 		return -1; 	} 	else if (left == right) 	{ 		if (a[left]==number) 		{ 			return left; 		}  		else 		{ 			return -1; 		} 	} 	else 	{ 		int mid=left + (right -left)/2; 		if (a[mid] == number) 		{ 			return mid; 		} 		else if(a[mid]>number){ 			return binary_search(a,left,mid,number); 		} 		else{ 			return binary_search(a,mid+1,right,number); 		}	 	}  	return 0; } int main(int argc,char *argv[]) { 	int sortedarray[]={1,2,3,4,5,6}; 	int number,i; 	int len=sizeof(sortedarray)/sizeof(sortedarray[0]); 	printf("请输入你想查找的数字:\n"); 	scanf("%d",&number); 	i=binary_search(sortedarray,0,len-1,number); 	printf("%d,\n",i);  	getchar(); 	getchar(); }

今天发现上面的代码有个bug,  else(array[mid] < key) 应为else if,不好意思。

这个二分查找写得不严谨。 1、应该为while(left <= right)  ，整个程序把left = right的情形忘记了，事实上，题主的疑惑就是这个导致的，试想当left = right时，根据程序，可知直接到了return 0。 2、if(a[mid]>number){ return binary_search(a,left,mid,number); }，这里的右边界应该为mid + 1, mid的情形已经讨论过了，造成重复。  我徒手写了个标准写法(非递归、升序): //非递归，升序，返回索引 --by Yaoxin_ int binarysearch(int *array, int length, int key) { 	if(!array) 	{ 		return -1; 	} 	int left = 0; 	int right = length -1; 	int mid; 	 	while(left <= right) 	{ 		mid = left + (right - left)/2; 		if(array[mid] > key) 		{ 			left = mid + 1; 		} 		else(array[mid] < key) 		{ 			right = mid - 1; 		} 		else 		{ 			return mid; 		} 	} 	 	return -1; }

已解决，谢谢你

二分法是基本功，网上有很多样例代码，建议楼主找来学习一下。

if (left > right)  return; // 这里也有问题，建议改成 return -1; 试试输入0或者10看看什么结果

改成while (left<=right)试试


Question: 操作系统中的独木桥问题，用c语言写代码

引用 1 楼 Yaoxin_ 的回复:P（int sem） { 	sem +-= 1; } V(int sem) { 	sem -= 1; }  楼主不是已经贴出了伪码么？ 想着能不能用C写代码，不是伪代码


Question: 如何调用VM——API

说想用它们的产品，让他们技术支持工程师给解释下

查看vm的官方文档

就是运行程序然后虚拟机自动运行或者关闭

用C语言来实现。。。打错了


Question: 菜鸟求教一个问题，本人学过c但没深入，现在在公司发展不理想，想学习代码编写

修改相关注册表项。我猜。

禁止识别U盘 把USB口通过注册表屏蔽可以做到

驱动标识，我猜

为啥不直接问他

工控机用的xp操作系统，在usb驱动上加标志？不懂。我不是学计算机的，很多东西没接触过。呵呵

看工控机用的什么操作系统，或者是不带操作系统，要禁止和启动U盘可在USB驱动上加个标志来控制


Question: C语言遇到一个奇怪的访存错误

分配了160 * 8192字节的内存 却访问50*8192*4的位置，明显越界

1楼解释是对的

引用 1 楼 jerry_dqh 的回复:cb8s+50*8192 你打印这个地址就知道，实际偏移的字节数是 50*8192*sizeof(float),  有道理，谢谢


Question: 怎么设置visual studio 2010 代码模板

引用 2 楼 ForestDB 的回复:这个应该是VC中的定制project，搜搜MSDN吧。 感觉这样好麻烦,有没有简单的方法,网上有导出模板,而我的10版显示无法导出模板, 最后我使用了编辑功能里面的将文件作为文本插入.

这个应该是VC中的定制project，搜搜MSDN吧。

新建一个helloworld的控制台工程就行了。并不是什么模板


Question: C如何打开对应程序的对应文件

CSDN如何回复对应楼主的对应帖子？

~~~ 好迷糊的 问题

引用 4 楼 zhao4zhong1 的回复:CSDN如何回复对应楼主的对应帖子？ 这也能得分？！

引用 1 楼 u012421456 的回复:什么对应文件啊 说错了，你知道C程序怎么调用vm_api 不

什么对应文件啊


Question: 新手求救，不晓得哪里错了。呜呜~~~

问题解决~~~~

#include <stdio.h> #include <stdlib.h> //首先你在函数中返回了局部变量 //这段内存在函数结束有可能被释放掉，数据虽然读到了 //但是数据不一定是正确的 //然后 函数统计有误 //你通过指针这样判断 //是无法正确找到结束位置 void main() { 	int a[50]; 	int n; 	printf("请输入学生数目，且数目<=50\n"); 	scanf("%d",&n); 	if (n>50) 	{ 		printf("学生数目有误！大于50\n"); 		return ; 	} 	printf("请输入%d个学生的成绩\n", n);  	for(int i=0; i<n;i++) 	{ 		scanf("%d", &a[i]); 	} 	int inum1 = 0,inum2 = 0; 	double dAvg1 = 0.0,dAvg2 = 0.0; 	int dwSUM1 = 0; 	int dwSUM2 = 0; 	for (int i=0; i<n;i++) 	{ 		if (a[i]>= 60) //jige 		{ 			inum1++; 			dwSUM1 = dwSUM1 + a[i]; 		} 		else //bujige 		{ 			inum2++; 			dwSUM2 = dwSUM2 + a[i]; 		} 	} 	if (inum1 > 0) 	{ 		dAvg1 = dwSUM1/inum1; 	}  	if (inum2 > 0) 	{ 		dAvg2 = dwSUM2/inum2; 	} 	printf("及格人数：%d ,%d个人平均成绩：%.1f\n", inum1, inum1, dAvg1); 	printf("不及格人数：%d,%d个人平均成绩：%.1f\n",inum2, inum2,dAvg2);   	system("pause"); }

你这个代码完全是错误的

引用 10 楼 qq_16912257 的回复:[quote=引用 6 楼 xwuno1 的回复:] scanf_s("%d", &a[i], sizeof(int));  少了个 & 号 printf_s("Pass:%d,%.1f", flag1, sum1 / flag1, sizeof(int), sizeof(float));格式控制符数目和你需要输出的数目不匹配 printf_s("Fail:%d,%.1f", flag2, sum2 / flag2, sizeof(int), sizeof(float)); 那么，这个sum1/flag1的位数是多少啊，应该怎么表示？？不是sizeof（float）么？[/quote]  你前面的控制符是两个，但是你后面却输出四个数值，肯定有问题。 假定你:%d,%.1f对应的是 flag1, sum1 / flag1，则输出后面两个sizeof需要再添加两个%d， printf_s("Pass:%d,%.1f, %d, %d", flag1, sum1 / flag1, sizeof(int), sizeof(float));

#include <stdio.h> #include <stdlib.h> //还可以全局变量，或者new 堆  void init(int a[], int n) { 	printf("请输入%d个学生的成绩\n", n); 	for(int i=0; i<n;i++) 	{ 		scanf("%d", &a[i]); 	}  } void jige(int a[], int n) { 	int inum1 = 0; 	double dAvg1 = 0.0; 	int dwSUM1 = 0; 	for (int i=0; i<n;i++) 	{ 		if (a[i]>= 60) //jige 		{ 			inum1++; 			dwSUM1 = dwSUM1 + a[i]; 		} 	} 	if (inum1 > 0) 	{ 		dAvg1 = dwSUM1/inum1; 	} 	printf("及格人数：%d ,%d个人平均成绩：%.1f\n", inum1, inum1, dAvg1); } void bujige(int a[], int n) { 	int inum2 = 0; 	double dAvg2 = 0.0;	 	int dwSUM2 = 0; 	for (int i=0; i<n;i++) 	{ 		if (a[i]< 60) //jige 		{		 			inum2++; 			dwSUM2 = dwSUM2 + a[i]; 		} 	}  	if (inum2 > 0) 	{ 		dAvg2 = dwSUM2/inum2; 	} 	printf("不及格人数：%d,%d个人平均成绩：%.1f\n",inum2, inum2,dAvg2);  } void main() { 	int a[50]; 	int n; 	printf("请输入学生数目，且数目<=50\n"); 	scanf("%d",&n); 	if (n>50) 	{ 		printf("学生数目有误！大于50\n"); 		return ; 	} 	init(a,n); 	jige(a,n); 	bujige(a,n); 	system("pause"); }

引用 15 楼 zhouxiaofeng1021 的回复:问题解决~~~~ 恩恩，这个我会的。不过老师让都在函数中实现。。我就在尝试不把输入写到main怎么实现。看来没有必要。谢谢啦

路过

在线等大神、、

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

引用 6 楼 xwuno1 的回复:scanf_s("%d", &a[i], sizeof(int));  少了个 & 号 printf_s("Pass:%d,%.1f", flag1, sum1 / flag1, sizeof(int), sizeof(float));格式控制符数目和你需要输出的数目不匹配 printf_s("Fail:%d,%.1f", flag2, sum2 / flag2, sizeof(int), sizeof(float)); 那么，这个sum1/flag1的位数是多少啊，应该怎么表示？？不是sizeof（float）么？

引用 1 楼 qq_16912257 的回复: 输入时好好地，然后输入完毕就显示 0x0F3BE541 (msvcr120d.dll) (Project2.exe 中)处有未经处理的异常:  0xC0000005:  写入位置 0xCCCCCCCC 时发生访问冲突。那么

你debug调试一下，立马能找到错误

for (i = 0; i < x; i++)  {  scanf_s("%d", a[i], sizeof(int));  //错了  }


Question: 避免野指针问题，请大神赐教

应该在free(p[i]); 之后 ， p[i]=0  以及free(p); 之后 p=0  但是出现这个断点应该不是因为这个原因啊 除非这个函数被你连续调用2次

引用 1 楼 jerry_dqh 的回复:将*p = null注释掉并不表示没有问题，问题隐藏得更深了。  所以呢？为什么会出现断点报错呢？

将*p = null注释掉并不表示没有问题，问题隐藏得更深了。


Question: 求助 局部变量的问题

引用 4 楼 q328965539 的回复:[quote=引用 楼主 q328965539 的回复:] int* size() { 	int a[3]={1,2,3}; 	return a; } int main() { 	int* p=size(); 	cout<<*p<<endl; 	return 0; } 为什么还是能输出1，在size()函数中的内存部分，不是已经随着该函数的结束而销毁了吗？ 求助是不是编译器自动优化了？  确实是这样的~ ，请问这个函数调用的时候，栈顶指针以及一些寄存器的存取情况可以简绍下么 或者推荐下好文章[/quote] 推荐你读两本书： 《程序员的自我修养》和《老码识途》

引用 楼主 q328965539 的回复:int* size() { 	int a[3]={1,2,3}; 	return a; } int main() { 	int* p=size(); 	cout<<*p<<endl; 	return 0; } 为什么还是能输出1，在size()函数中的内存部分，不是已经随着该函数的结束而销毁了吗？ 求助是不是编译器自动优化了？  确实是这样的~ ，请问这个函数调用的时候，栈顶指针以及一些寄存器的存取情况可以简绍下么 或者推荐下好文章

引用 楼主 q328965539 的回复:int* size() { 	int a[3]={1,2,3}; 	return a; } int main() { 	int* p=size(); 	cout<<*p<<endl; 	return 0; } 为什么还是能输出1，在size()函数中的内存部分，不是已经随着该函数的结束而销毁了吗？ 求助是不是编译器自动优化了？ 虽然随着函数的结束而销毁了，但是内存中保存的值并没有被清空。但是不能保证一定是1。

引用 1 楼 wangzuxi 的回复:[quote=引用 楼主 q328965539 的回复:] int* size() { 	int a[3]={1,2,3}; 	return a; } int main() { 	int* p=size(); 	cout<<*p<<endl; 	return 0; } 为什么还是能输出1，在size()函数中的内存部分，不是已经随着该函数的结束而销毁了吗？ 求助是不是编译器自动优化了？ a是在size函数的栈中，调用size函数返回后，只是改变栈顶指针，而不是真正的销毁a的内存，如果调用size()函数之后接着调用其他函数的话，其他函数就会覆盖size函数的栈。[/quote] 你可以试试正面这段代码：   int* size() {     int a[3]={1,2,3};     return a; }  void test() {     int b[3] = {11, 22, 33}; }  int main() {     int* p = size();     cout << *p <<endl;     test();     cout << *p <<endl;     return 0; }  第一行输出1，第二行输出11.

引用 楼主 q328965539 的回复:int* size() { 	int a[3]={1,2,3}; 	return a; } int main() { 	int* p=size(); 	cout<<*p<<endl; 	return 0; } 为什么还是能输出1，在size()函数中的内存部分，不是已经随着该函数的结束而销毁了吗？ 求助是不是编译器自动优化了？ a是在size函数的栈中，调用size函数返回后，只是改变栈顶指针，而不是真正的销毁a的内存，如果调用size()函数之后接着调用其他函数的话，其他函数就会覆盖size函数的栈。


Question: 图片取模问题

引用 18 楼 zhao4zhong1 的回复:r = (color & 0xFF0000) >> 16; 和 r = (color & 0xFF0000u) >> 16; 不是一回事！参考： #include <stdio.h> unsigned char ui;   signed char si; char main() {     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui>>1;     si=si>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed char)ui)>>1;     si=((unsigned char)si)>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("==============\n");      ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui<<1;     si=si<<1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned char)0x80u;     si=(  signed char)0x80;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed char)ui)<<1;     si=((unsigned char)si)<<1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      return 0; } //ui=128 //si=-128 //ui=64 //si=-64 //-------------- //ui=128 //si=-128 //ui=192 //si=64 //============== //ui=128 //si=-128 //ui=0 //si=0 //-------------- //ui=128 //si=-128 //ui=0 //si=0  C Integer Constants An “integer constant” is a decimal (base 10), octal (base 8), or hexadecimal (base 16) number that represents an integral value. Use integer constants to represent integer values that cannot be changed.  Syntax  integer-constant :  decimal-constant integer-suffix opt octal-constant integer-suffix opt hexadecimal-constant integer-suffix opt  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffix opt long-suffix unsigned-suffix opt   unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  Integer constants are positive unless they are preceded by a minus sign (–). The minus sign is interpreted as the unary arithmetic negation operator. (See Unary Arithmetic Operators in Chapter 4 for information about this operator.)  If an integer constant begins with the letters 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal.   The following lines are equivalent:  0x1C   /* = Hexadecimal representation for decimal 28 */ 034    /* = Octal representation for decimal 28 */  No white-space characters can separate the digits of an integer constant. These examples show valid decimal, octal, and hexadecimal constants.   /* Decimal Constants */ 10 132 32179  /* Octal Constants */ 012 0204 076663  /* Hexadecimal Constants */ 0xa or 0xA 0x84 0x7dB3 or 0X7DB3 多谢赵老师解疑答惑，我已经解决了，祝你每天生活愉快（这大段代码和颜色有关系么？）

引用 15 楼 gqjjqg 的回复:我不太理解你哪里不明白。  我没有取模软件，搜了一下，取模是指取字模吗？  字模之类的，freeType 可以满足你的各种需求。 看你提供的代码，仅仅是颜色格式上的转换而已，完全可以自己按需求写。  刚刚我已经搞定了，就你最有耐心，分全都给你了

引用 15 楼 gqjjqg 的回复:我不太理解你哪里不明白。  我没有取模软件，搜了一下，取模是指取字模吗？  字模之类的，freeType 可以满足你的各种需求。 看你提供的代码，仅仅是颜色格式上的转换而已，完全可以自己按需求写。 取模还指图片取模，freeType也不错

引用 14 楼 liaocao2010 的回复:话说，@gqjjqg，您有好的取模软件么  我不太理解你哪里不明白。  我没有取模软件，搜了一下，取模是指取字模吗？  字模之类的，freeType 可以满足你的各种需求。 看你提供的代码，仅仅是颜色格式上的转换而已，完全可以自己按需求写。

话说，@gqjjqg，您有好的取模软件么

引用 12 楼 gqjjqg 的回复:分析红色不显示的问题，先要知道输入的color 是RGB888?还是RGBA8888，亦或者是其他各种格式。 目测代码要求输入的是RGB888或者BGR888。你输入16bit的数值，果断就出问题。  修复的办法很简单，输入值改成RGB888的格式就行了。  不是很明白RGB888是什么意思，我现在能确定的是0xf800是红色，0x07e0是绿色，0x001f是蓝色，也就是565  也不知道是不是我的取模软件有问题，直接显示颜色就行，用图片取模生成的数组颜色就是不正，现在也不是缺少红色了，我修改后，发现图片中的颜色能把蓝色显示成绿色，单独显示蓝色又没问题

引用 10 楼 liaocao2010 的回复:[quote=引用 9 楼 gqjjqg 的回复:] 1.有没有能生成18bit的图片取模软件？    我没发现有这样的软件，RGB 666 每个通道 6bit，目测要自己写，代码不算复杂。  2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS，懂！ 但是用0x0000-0xffff表示是怎么个原理，请不吝赐我 0x000-0xffff 只是存储的范围，5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。  我很喜欢你解答的风格，我忘记了问一个关键的问题，“显示不了红色是为什么？” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;[/quote]  引用 10 楼 liaocao2010 的回复:[quote=引用 9 楼 gqjjqg 的回复:] 1.有没有能生成18bit的图片取模软件？    我没发现有这样的软件，RGB 666 每个通道 6bit，目测要自己写，代码不算复杂。  2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS，懂！ 但是用0x0000-0xffff表示是怎么个原理，请不吝赐我 0x000-0xffff 只是存储的范围，5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。  我很喜欢你解答的风格，我忘记了问一个关键的问题，“显示不了红色是为什么？” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;[/quote]  分析红色不显示的问题，先要知道输入的color 是RGB888?还是RGBA8888，亦或者是其他各种格式。 目测代码要求输入的是RGB888或者BGR888。你输入16bit的数值，果断就出问题。  修复的办法很简单，输入值改成RGB888的格式就行了。

参考 Image Magick CXImage

引用 5 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; unsigned int n; int c; //------------------------------------------------------- void main(int argc,char *argv[]) {     if (argc<3) {         cprintf("Bin2Hex srcfile desfile");         return;     }     if ((fi=fopen(argv[1],"rb"))==NULL) {         cprintf("Can not find file %s",argv[1]);         return;     }     if ((fo=fopen(argv[2],"w"))==NULL) {         fclose(fi);         cprintf("Can not create file %s",argv[2]);         return;     }     n=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         n++;         if (1==n)        fprintf(fo,  "0x%02X",c);         else {             if (1==n%16) fprintf(fo,"\n0x%02X",c);             else         fprintf(fo, ",0x%02X",c);         }     }     fcloseall();     cprintf("OK to Bin2Hex %u bytes.",n); }   赵老师，您能详细说说图片取模生成16bit的c数组应该怎么写RBG的函数才能不失真么，万分感谢了

引用 2 楼 lovesmiles 的回复:那里有18bit的东西？只有2的n次方的bit。18bit不轮不类，你一般的软件生成不了这样的bmp。  0x000000-0xFFFFFF是三字节，一个颜色通道点一字节。 0x0000-0xffff是二字节，二个颜色通道占10bit，一个颜色通道点6bit。  你的程序输入是32位的数据，你就要用32位的图片，用其它图片格式没有用的    我也觉得18bit的好奇怪，偏偏代码以前的记录里有，这个软件里也有选项，就是生成不了  那0x000000-0xFFFFFF是不是要生成24bit的c数组啊，貌似我的datasheet里面是说18bit是mcu的一种接口模式  32位的图片能通过ps生成，那么用什么软件能取模生成相应的c数组文件呢

引用 1 楼 user-4 的回复:ILI9341Write8bitData((current_color >> 16) & 0xFF);                     ILI9341Write8bitData((current_color >> 8) & 0xFF);                     ILI9341Write8bitData(current_color & 0xFF); 这个有问题啊， 按你前面的那个函数来说， rgb应该是分别5bit，6bit，5bit 所以应该是                      ILI9341Write8bitData((current_color >> 11) & 0xFF);                     ILI9341Write8bitData((current_color <<5>>11) & 0xFF);                     ILI9341Write8bitData(current_color <<11>>11& 0xFF);  5、6、5不就是16bit么，这个不就是直接使用 ILI9341Write8bitData((current_color >> 8) & 0xFF); ILI9341Write8bitData(current_color & 0xFF);  这两条代码就好了么，write8bitdata一次就是写8位数据啊，我把这代码拷贝到工程里去运行，显示不了哦  感谢您的回复，祝你每天生活愉快！^_^

引用 8 楼 zhao4zhong1 的回复:http://www.baidu.com/s?wd=18%E4%BD%8DRGB&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_sug3=4&rsv_sug=0&rsv_sug1=4&rsv_sug4=110&inputT=7828  赵老师，能否稍微爆发一下您的小宇宙， 这段代码到底要咋改 u32 shift_picture(u32 color) {     u32 r,g,b;     u32 out_color = 0;       r = (color & 0xFF0000) >> 16;//16位的数组文件在这里的结果只会是0,也就是丢掉红色的原因所在     g = (color & 0x00FF00) >> 8;     b = color & 0x0000FF;       switch(u8_LCDPixelFormat)//这里是图片显示格式，主函数里手动赋值为5或6都可以     {         case 3: // 12-bit         {             r = r >> 4;             g = g >> 4;             b = b >> 4;             out_color = (r << 8) | (g << 4) | b;             break;         }         case 5: // 16-bit         {             r = r >> 3;             g = g >> 2;             b = b >> 3;             out_color = (r << 11) | (g << 5) | b;             break;         }         case 6: // 18-bit         {             out_color = color & 0xFCFCFC;             break;         }     }     return out_color; }

引用 9 楼 gqjjqg 的回复:1.有没有能生成18bit的图片取模软件？    我没发现有这样的软件，RGB 666 每个通道 6bit，目测要自己写，代码不算复杂。  2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS，懂！ 但是用0x0000-0xffff表示是怎么个原理，请不吝赐我 0x000-0xffff 只是存储的范围，5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。  我很喜欢你解答的风格，我忘记了问一个关键的问题，“显示不了红色是为什么？” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;


Question: 疑问，关于函数地址的赋值

结贴了，谢谢各位！

或者typedef int(*FUNC1)(int a); typedef int(*FUNC2)(int*, int*, int*);

函数是指针类型的。  FUNC1 *p = NULL;


Question: 请大家帮帮忙，结构体数组成员做参数的函数调用问题！

再请问大家，不用类，仅用结构体指针能否行？ 怎样做？

呵呵，先谢谢！dev-c++，编译通过了，哈哈，厉害，五体投地！

结构体变量在通常情况下使用和普通变量int float是一样的 除非结构体中含有类似指针类型，情况就有变 在C++中，结构体和class基本上是通用，他们的区别仅仅是默认访问修饰符不一样而已 所以可以参考类的使用

float max_s(struct Data_my * pm1, int m, int n, float Data_my::*which_mem /* 定义成员指针 */) {         .... 	pm1->*which_mem; // 取成员值         .... }  ... 	max_s(m1, 1, 1, &Data_my::a);  // 调用时传指针的方法 	max_s(m1, 1, 1, &Data_my::b); ...


Question: 用中点画法画出一条直线，编译后出现error C2078: too many initializers

引用 8 楼 programming_hard4me 的回复:[quote=引用 3 楼 zhaowech 的回复:] [quote=引用 2 楼 zhaowech 的回复:] 用这段代码试试： #include<graphics.h> #include<conio.h>   //在这里多加了一句，否则函数会提示未声明 int Myfunc(int x0,int y0,int x1,int y1);   void main() {     initgraph(640,480);     int Myfunc(5,8,9,11);     getch();     closegraph(); }   int Myfunc(int x0,int y0,int x1,int y1) {     int a,b,delta1,delta2,d,x,y;     a=y0-y1;     b=x1-x0;     d=2*a+b;     delta1=2*(a+b);     delta2=2*a;     x=x0; y=y0;     putpixel(x,y,RED);     while(x<x1)     {         if(d<0)         {             x++;y++;d+=delta1;}         else          {             x++; d+=delta2;}         putpixel(x,y,RED);     } }

引用 11 楼 programming_hard4me 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] http://www.easyx.cn 我有安装EasyX，我的错误是 too many initializers ，怎么解决这个问题？我还没有看出来为什么会出这个错[/quote]  int Myfunc(5,8,9,11);去掉int就可以运行

蓝色删掉 #include<graphics.h> #include<conio.h>   //在这里多加了一句，否则函数会提示未声明 int Myfunc(int x0,int y0,int x1,int y1);   void main() {     initgraph(640,480);     int Myfunc(5,8,9,11);     getch();     closegraph(); }   int Myfunc(int x0,int y0,int x1,int y1) {     int a,b,delta1,delta2,d,x,y;     a=y0-y1;     b=x1-x0;     d=2*a+b;     delta1=2*(a+b);     delta2=2*a;     x=x0; y=y0;     putpixel(x,y,RED);     while(x<x1)     {         if(d<0)         {             x++;y++;d+=delta1;}         else          {             x++; d+=delta2;}         putpixel(x,y,RED);     } }

引用 10 楼 zhao4zhong1 的回复:http://www.easyx.cn 我有安装EasyX，我的错误是 too many initializers ，怎么解决这个问题？我还没有看出来为什么会出这个错

引用 5 楼 zhouxiaofeng1021 的回复:VS2008提示无法找到 错误	1	fatal error C1083: 无法打开包括文件:“graphics.h”: No such file or directory	e:\mfc 学习\练习\练习\11\11\11.cpp	4 找不到头文件，是因为没有安装EasyX，所以找不到graphics这个库

引用 3 楼 zhaowech 的回复:[quote=引用 2 楼 zhaowech 的回复:] #include<graphics.h> #include<conio.h>  //在这里多加了一句，否则函数会提示未声明 int Myfunc(int x0,int y0,int x1,int y1);  void main() { 	initgraph(640,480); 	int Myfunc(5,8,9,11); 	getch(); 	closegraph(); }  int Myfunc(int x0,int y0,int x1,int y1) { 	int a,b,delta1,delta2,d,x,y; 	a=y0-y1; 	b=x1-x0; 	d=2*a+b; 	delta1=2*(a+b); 	delta2=2*a; 	x=x0; y=y0; 	putpixel(x,y,RED); 	while(x<x1) 	{ 		if(d<0) 		{ 			x++;y++;d+=delta1;} 		else  		{ 			x++; d+=delta2;} 		putpixel(x,y,RED); 	} } 你用的这个函数和头文件中的函数名字重名，尝试下上面的代码吧 纠正main中的错误代码，不能运行就是烦[/quote] 我用的是Visual C++6.0 你说的那个函数重名，是指MidPointLine吗？ 还有，你说的”纠正main中的错误代码，不能运行就是烦“是什么意思，求指教

找不到头文件，是因为没有安装EasyX，所以找不到graphics这个库

引用 2 楼 zhaowech 的回复:#include<graphics.h> #include<conio.h>  //在这里多加了一句，否则函数会提示未声明 int Myfunc(int x0,int y0,int x1,int y1);  void main() { 	initgraph(640,480); 	int Myfunc(5,8,9,11); 	getch(); 	closegraph(); }  int Myfunc(int x0,int y0,int x1,int y1) { 	int a,b,delta1,delta2,d,x,y; 	a=y0-y1; 	b=x1-x0; 	d=2*a+b; 	delta1=2*(a+b); 	delta2=2*a; 	x=x0; y=y0; 	putpixel(x,y,RED); 	while(x<x1) 	{ 		if(d<0) 		{ 			x++;y++;d+=delta1;} 		else  		{ 			x++; d+=delta2;} 		putpixel(x,y,RED); 	} } 你用的这个函数和头文件中的函数名字重名，尝试下上面的代码吧 纠正main中的错误代码，不能运行就是烦

#include<graphics.h> #include<conio.h>  //在这里多加了一句，否则函数会提示未声明 int Myfunc(int x0,int y0,int x1,int y1);  void main() { 	initgraph(640,480); 	int MidPointLine(5,8,9,11); 	getch(); 	closegraph(); }  int Myfunc(int x0,int y0,int x1,int y1) { 	int a,b,delta1,delta2,d,x,y; 	a=y0-y1; 	b=x1-x0; 	d=2*a+b; 	delta1=2*(a+b); 	delta2=2*a; 	x=x0; y=y0; 	putpixel(x,y,RED); 	while(x<x1) 	{ 		if(d<0) 		{ 			x++;y++;d+=delta1;} 		else  		{ 			x++; d+=delta2;} 		putpixel(x,y,RED); 	} } 你用的这个函数和头文件中的函数名字重名，尝试下上面的代码吧

你用的是tc？我用vs2005，提示找不到头文件


Question: C语言，有没有引用类型？

c是C文件的扩展名 cc是C++文件的扩展名 C用gcc编译 C++用g++编译 C没有引用 C++有引用  另外数据结构中，都是伪代码，可是坑爹的作者都不指出来，或者作者有指出来，坑爹的LZ都不仔细看。

C语言没有引用，国内的教课书就是按照vc6.0来编的，所以在编程的时候，其实都是写的c++程序，大家都误以为有引用。比如说李春葆的数据结构里面就用到了引用，坑死人，我大一的时候看书上代码，看不懂，后来才发现被坑了，毁人不倦啊。

引用C语言里面没有引用这个东西可以用指针c++才有这个呢 帅哥 这样？！  http://www.baike.com/wiki/《小孩好黑》

"习惯其它语言(特别是 Fortran 语言)的程序员可能会对 C 语言的函数参数传递方式感到 陌生。在 C 语言中,所有函数参数都是“通过值”传递的。也就是说,传递给被调用函数的 参数值存放在临时变量中,而不是存放在原来的变量中。这与其它某些语言是不同的,比如, Fortran 等语言是“通过引用调用” ,Pascal 则采用 var 参数的方式,在这些语言中,被调用的 函数必须访问原始参数,而不是访问参数的本地副本。 最主要的区别在于,在 C 语言中,被调用函数不能直接修改主调函数中变量的值,而只 能修改其私有的临时副本的值。 传值调用的利大于弊。在被调用函数中,参数可以看作是便于初始化的局部变量,因此 额外使用的变量更少。这样程序可以更紧凑简洁。" ——K&R  答案：C没有引用！C它爹说的，不是我说的

C语言里面没有引用这个东西 可以用指针 c++才有这个呢 帅哥

“引用”（reference）是c++的一种新的变量类型

引用 1 楼 user-8 的回复:C里没有引用，C++才有。 +1 C用指针可实现C++引用的功能

C里没有引用，C++才有。


Question: 新手求助

谢谢各位大神的帮助

视频可以看郝斌翁恺的，软件，VS2010及以上版本，dev c++、cfree等都可以

环境还是用VS2008吧 C预言的话 c plus那本经典书籍吧 学这个主要是敲代码 看代码 学得快 做项目

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

单纯学语言可以看《c primer》,VC++的话建议不要用vc6.0了太老了，很多东西和现有标准不一致，甚至在现在看来都是错的，可以用vs2005,2008等


Question: 如何输出一个自定义行列的矩阵？

我感觉我好蠢啊。诸位的我连简单的都看不懂。下面还是别回复了。我得抽个时间好好看看！

#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 //

把a[m][n]定义放在mn信息采集后。现在C99标准已经支持这种特性喽！gcc支持 示例：  #include <stdio.h>  int main(int argc, char *argv[]) { 	int m, n; 	scanf("%d %d", &m, &n);  	int a[m][n];  	a[1][2] = 10; 	printf("%d\n", a[1][2]);  	return 0; }

已经调试通过

#include "stdafx.h"  #include<stdio.h> #include <malloc.h>  #include<stdio.h> int main() { 	int m,n;  	printf("please input m and n:\n"); 	scanf("%d %d",&m,&n); 	int i, j; 	int *a = (int*)malloc(sizeof(int) * n*m);  	printf("please input a:\n"); 	for (i = 0; i < m; i++) 	{ 		for (j = 0; j < n; j++) 		{ 			scanf("%d", &a[i*m+j]); 		} 	} 	printf("the array is :\n"); 	for (i = 0; i < m; i++) 	{ 		for (j = 0; j < n; j++) 		{ 			printf("%5d", a[i*m+j]); 		} 		printf("\n"); 	} 	delete[] a; 	getchar();//读取缓冲区遗留的换行符0xA,不会暂停程序 	getchar();//暂停程序 }

这里开始如何声明m.n啊。  跑程序的时候它说我    未定义标示符。  我的目的是求两个任列任行的两个矩阵相乘。  望好心人解答。自学很是艰难啊。


Question: C语言数组内存分配与赋值问题

32位，用户可用3G空间，省着点用！

如果用到 32 位的库就没法了，除非你找到那个库的 64 位版本。  不使用 64 位的情况下，要么就分段处理数据，不要一起全放内存里面; 要么使用 AWE（http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa366527(v=vs.85).aspx） 来让程序使用超过 4G 的内存

系统有限制的的 尤其是内存方面 32位的系统中一个进程操作的内存的上线是2G 64位的上线是4G

刚试了下，改成x64，问题又出现了，因为程序调用了一个CLAPACK库，是32位的，所以不兼容，怎么解决呢

VC2005 都可以创建 64 位的程序了。解决方法之一就是把你的程序改成 64 位的

貌似vs2010只有win32位吧，不太懂，那我现在需要怎么解决这一问题呢

你的程序是 32 位的还是 64 位的？ 32 位的进程的内存地址范围只有 4G， 自己可用的还不到 2G， 和实际的物理内存多大无关。


Question: 【求助】关于#define的高级用法

对号入座，有什么不懂的？## 拼接标识符

引用 1 楼 zhao4zhong1 的回复:编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E 好的，我试试，谢谢！

看不懂define的内容就预编译一下看看，赵老师经常说的那啥？

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E


Question: 新手写了一个简单程序 不知道怎么一运行就出问题

我是新手 如何给分啊。。。

快点给他分啊，栈溢出

神马问题啊。调试吧！

引用 5 楼 u013174702 的回复:太厉害了 解决了。。这就是传说中的栈溢出(stackoverflow)，希望印象深刻。

引用 3 楼 sundq12 的回复:a[1000][1000]申请太大的数组，导致栈溢出了，改小一点，或者修改栈的空间大小正解无误！

数组太大。一般用动态数组，申请堆内存

太厉害了 解决了。。

我现在去试试去

调试了  到 int a[1000][1000];这就中断了


Question: 直接插入排序用不带头结点的单向链表实现

引用 2 楼 zhao4zhong1 的回复://不带表头结点的单向链表 #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=5;             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=5;                 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) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> // 谢谢老师，有些地方还没理清楚，我自己多看看吧。


Question: 结构体指针变量互换

你在分配空间的时候，len还没有初始化，肯定会出错的。

int len; //len是个随机值，+-0都有可能，导致malloc不一定成功，因为你的len信息还没有采集，你就分配内存喽     struct student * pst = malloc(sizeof(struct student) * len); //《-bug     int i,j;     struct student t;               printf("请输入学生数：");     scanf("%d",&len);  补丁：  int len;     struct student * pst ；     int i,j;     struct student t;               printf("请输入学生数：");     scanf("%d",&len);     pst = malloc(sizeof(struct student) * len);     if(!pst)          exit(EXIT_FAILURE);


Question: 求助：简单程序。结尾出现大量乱码

Debug模式吧，“烫”是GBK编码的0xCCCC 而每一个0xCC都对应着int 3号中断，用来激活调试器的 也就是说，如果你错误的访问后面的数据时，会自动弹出来询问你是否需要Debug的对话框  参考： http://wenku.baidu.com/link?url=pAuYuX5St9TWCyV1vFbF_QpZIhIUTViCx9i0Fn-sDXRgleDQZxrFIDF9YqnyC_L73AmGGzgGFwEDF6N4O3W6memnufIcA4vzAIq-bPiQjsO  下次再看到【烫】，第一反应就是数组越界了……

对的，字符数组需要‘\0’结尾 定义完数组后，可以调用memset(a，0,200)初始化数组，将所有元素置为0。

没有字符串结束标志 '\0', 你看下面的程序 #include <stdio.h> #include<string.h> int main(void) { 	// your code goes here 	char a[100]; 	a[0] = 'f'; 	a[1] = 'd'; 	a[2] = '\0';//注释掉这句试试 	printf("%s\n",a); 	return 0; }

循环后数组a结尾没加'\0'.


Question: 新手关于结构数组排序的提问

，谢谢了，没看到，打漏了...

其他的没有细看，这个是明显的错误呀 else if (pr[i].hour = pr[i-1].hour) ===> else if (pr[i].hour == pr[i-1].hour)

我描述的问题是下面的代码出现的： （交换结构里的每个成员） while (answer4 == 'y')             {                 printf ("Please choose the standard(time(t) or rating(r)):\n");                 getchar ();                 scanf ("%c", &std );                 if (std == 't')                 {                     for (i = 1; i < num1; i++)                     {                         if (pr[i].hour < pr[i-1].hour)                             {                                 strcpy(pr[i-1].name,temp1);                                 temp2 = pr[i-1].rating;                                 temp3 = pr[i-1].hour;                                 temp4 = pr[i-1].minute;                                  strcpy(pr[i].name,pr[i-1].name);                                 pr[i-1].rating = pr[i].rating;                                 pr[i-1].hour = pr[i].hour;                                 pr[i-1].minute = pr[i].minute;                                  strcpy(temp1,pr[i].name);                                 pr[i].rating = temp2;                                 pr[i].hour = temp3;                                 pr[i].minute = temp4;                              }  这个是直接交换结构指针：  while (answer4 == 'y')             {                 printf ("Please choose the standard(time(t) or rating(r)):\n");                 getchar ();                 scanf ("%c", &std );                 if (std == 't')                 {                     for (i = 1; i < num1; i++)                     {                         if (pr[i].hour > pr[i-1].hour)                             ;                              else if (pr[i].hour < pr[i-1].hour)                              {                                 temp = pr[i-1];                                 pr[i-1] = pr[i];                                 pr[i] = temp;                              }

程序可以运行，就是交换结构数据的时候，结构的第一个数据都变成了第一个结构的数据了。（他们原来是不一样的。只是排序，但运行时，其他结构的第一个数据都变成了第一个结构的第一个数据了）

＜1000个元素，冒泡排序 ＜100000个元素，qsort函数 ＜10000000个元素，放数据库中，建索引，（B+树排序） ≥10000000个元素，没用到过。

楼主是要研究排序算法吗？

char name [CSIZE];这个是怎么回事啊

仅供参考： //学号 姓名 电话 成绩 //01 XXX 182XXXXXXXX 88 #include <stdio.h> #include <string.h> #define MAXS 10000 struct ST {     int XH;     char XM[11];     char DH[13];     int CJ; } st[MAXS],t; int n,i,j; char ln[80]; FILE *f; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     i=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         if (4!=sscanf(ln,"%d%10s%12s%d",&st[i].XH,st[i].XM,st[i].DH,&st[i].CJ)) {             st[i].XH=0;             strcpy(st[i].XM,"Unknown");             strcpy(st[i].DH,"Unknown");             st[i].CJ=0;             printf("line %d format error:%s!\n",i+1,ln);         }         i++;         if (i>=MAXS) {             printf(">%d lines Ignored.\n",MAXS);             break;         }     }     fclose(f);     n=i;     for (i=0;i<n-1;i++) {         for (j=i+1;j<n;j++) {             if (st[i].CJ<st[j].CJ) {t=st[i];st[i]=st[j];st[j]=t}         }     }     for (i=0;i<n;i++) {         printf("%5d%10s%12s%4d\n",st[i].XH,st[i].XM,st[i].DH,st[i].CJ);     }     return 0; }

百度一下撒 排序算法一大堆呢 代码有点长 也不知道你要我们帮你解答什么 是代码写的问题 还是逻辑有问题 还是算法有问题 还是运行时报错等等

可以使用qsort，只会冒泡的路过


Question: 有关内联汇编的问题 , 调用C函数Release版本奔溃了! ?

引用 2 楼 passion_wu128 的回复:这很好解决啊，你按你的参数调用sprintf函数，然后调试，在汇编窗口就能看到正确的汇编码了。（最好在release下看，debug下没有优化，有很多冗余的指令） 对比之后 , release C的导入函数 第一个跳转就有问题 , 直接到程序领空的空内存去了.

引用 1 楼 lovesmiles 的回复:sprintf是变长参数的函数  变长参数的入栈似乎有点不一样 应该不是参数问题 , 那为什么在Debug模式下没问题 ?

引用 2 楼 passion_wu128 的回复:这很好解决啊，你按你的参数调用sprintf函数，然后调试，在汇编窗口就能看到正确的汇编码了。（最好在release下看，debug下没有优化，有很多冗余的指令） 这个我知道, 关键怎么解决啊

sprintf是变长参数的函数  变长参数的入栈似乎有点不一样


Question: 关于输入类型的练习    求改错~~~

楼主的代码有两个问题： 1. 第一次运行到while(n != 0)的时候，没有给n赋值，所以n可能是任何值，有可能是0。给n随便赋值一个非0值可以解决这个问题。 2. 输入0的时候，也会执行一次循环并输出0(A)。在scanf("%d",&n);后面加一行if (n==0) break;可以解决这个问题。

#include <stdio.h>  int main() { 	int i, n, m, sum;  	while(scanf("%d", &n), n){ 		sum = 0; 		for(i = 0; i< n; ++i){ 			scanf("%d", &m); 			sum += m; 		} 	printf("%d\n", sum); 	} 	return 0; }

while(scanf("%d",&n) == 1 && n != 0) {  for(i = 1,A = 0;i <= n;i++) { scanf("%d",&a); A += a; } printf("%d\n",A); }


Question: 求解答：没有与这些操作数匹配的 "[]" 运算符

一楼最后一行写错了，应该是 void SortIntegerArray (plinfo a[]) { a[j] ... }  其实直接改成 void SortIntegerArray (plinfo g[]) 这样没准也能通过编译而且正确运行，但是不要这么做。同名的全局变量和函数参数看着太乱

plinfo g[10000000]; SortIntegerArray函数里面出现了两个g，他们是不同的变量。一个是全局变量plinfo g[]，另一个是函数参数plinfo g 编译器会把它解释为函数参数，不是数组，所以就不能用[] 有两个解决办法： 1. 函数不要参数，直接用全局变量 plinfo g[10000000]; void SortIntegerArray () { g[j] ... } 2. 函数的参数改个名字，不要和全局变量冲突 plinfo g[10000000]; void SortIntegerArray (plinfo a) { a[j] ... }


Question: c初学者又来新问题咯

11.2.2  gets（）函数 gets（）（代表 get string） 函数对于交互式程序非常方便。它从系统的标准输入设备（通常是键盘）获得一个字符串。因为字符串没有预定的长度，所以 gets（）需要知道输入何时结束。解决办法是读字符串直到遇到一个换行字符（\n），按回车键可以产生这个字符。它读取行符之前（不包括换行符）的所有字符，在这些字符后添加一个空字符（\0），然后把这个字符串交给调用它的程序。它将读取换行符并将其丢弃，这样下一次读取会在新的一行开始。 出自C Primer Plus (fifth eidtion)

gets应该会把换行符读进去，你调试一下看看


Question: 新手求助，找不到问题啊

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

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

#include "car1.h"

太粗心了 ，问题已解决 谢谢各位！

#include car1.h

#unclude car1.h

你的头文件名字是不是写错了，到底是Car1.h 还是Car.h?

CharPtr的定义呢


Question: 多线程服务器，求大神改错

引用 2 楼 user-2 的回复:加一个信号处理，处理Ctrl +D 信号，信号处理里刷新所有流再退出 同意

加一个信号处理，处理Ctrl +D 信号，信号处理里刷新所有流再退出

请大神帮帮忙啊


Question: 请教，用字符串做参数和用字符数组做参数有何不同

“ssssssss”本身被保存在文字常量区域，str[20] = "sssssssss"被保存在栈空间中。当作为参数的时候str可以通过地址找到整个字符串，而"ssssssss"在你的C语言程序中没有标识，所以编译器本身是找不到的，因此需要直接将整个字符串压入栈中（如果优化的话还可能也是将str指针入栈，因为它们的内容相同）。知道这个就够了。无论是gcc编译器还是vs编译器都有自己处理C语言规定的方式，具体方式我们不得而知，而且编译器本身将C转换为指令的时候，存在很多的优化，背着编程人员作了很多事情。所以我觉得楼主理解到它们保存在什么地方就够了。个人意见，仅供参考！

不是直接把整个串压栈吧？能给提供个截图吗？ 据说C语言从不会直接操纵整个字符串的，无论你使用数组还是常量字符串，都是只使用它的首地址的。 是不是LZ看错了？

c语言啊  纯概念问题 有点记不清了  我大概给你说下  你知道对于c语言来说，有五种存储空间吧  这五种具体的名字我记不清了  总之里面有一种是专门存放字符串常量的 就像你写的“sssss”  所以如果你直接显示“ssssss” 那么就会直接把这个字符串拿来  这就是为什么你看到压栈的是整个字符串 而如果是通过str而拿到字符串的话，那么首先，str是一个普通的数组  或者说 它就是个普通的数据  所以自然是压它入栈了  然后才是通过它找到对应的字符串  我想你是忽视了这里的存储空间的不同才有的这个问题   只要你知道，str和“sssss”不在同一种存储空间里  你应该就明白了吧～  原谅我忘了具体的概念名词～～自己上网查查吧

我觉得，不论使用字符串还是字符数组，进栈的都是地址引用，不会直接操作堆上的实际存储值。

谢谢楼上几位的回答啊，经过查看，发现字符串常量是被储存在.rodata区域的


Question: 编程挑战--小女孩问题 代码求解，不知怎么不符合要求

#include<stdio.h> void main(){     unsigned long int n;     while (scanf_s("%d", &n) != EOF){         if (n % 8 == 1)             printf("%d\n", 1);         else if (n % 8 == 5)             printf("%d\n", 5);         else if (n % 8 == 3 || n % 8 == 7)             printf("%d\n", 3);         else if (n % 8 == 4 || n % 8 == 6)             printf("%d\n",4);         else printf("%d\n",2);     } }

unsigned long int n; 	while (scanf_s("%d", &n) != EOF) 	{ 		if (1<=n && n<=5)printf("%d\n", n); 		else 		{ 			unsigned long int m=(n-5)%8; 			switch (m) 			{ 				case 0:printf("%d\n", 5);break; 				case 1:case 7:printf("%d\n", 4);break; 				case 2:case 6:printf("%d\n", 3);break; 				case 3:case 5:printf("%d\n", 2);break; 				case 4:printf("%d\n", 1);break; 			} 		} 	}

一个小女孩正在用左手手指数数，从1数到n。她从拇指算作1开始数起，然后，食指为2，中指为3，无名指为4，小指为5。接下来调转方向，无名指算作6，中指为7，食指为8，大拇指为9，如此反复。问最后会停在那个手指上？用编号1、2、3、4、5依次表示大拇指、食指、中指、无名指、小指。 输入格式： 输入多组数据。每组数据占一行，只包含一个整数n(1<=n<=1000000000)。 输出格式： 每组数据占一行，只包含一个介于1和5之间的整数，表示最后停留的手指。

我贴错了  我发上去的就是没有_s的

把  while (scanf_s("%d", &n) != EOF){ 上面这行代码中的 scanf_s 换成 scanf  就可以了

你把题目条件发上来看看


Question: 串口长时间工作出现问题

引用 3 楼 u010384159 的回复:谢谢赵4老师，我修改了程序，现在句柄数变化不大，但系统缓存以每秒加4的速度增加，这也是内存泄露吗？？ 多半是。

不应该啊，贴点关键的句柄代码看看

检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！


Question: socket编程，看些什么书？

引用 11 楼 Daffodiles 的回复:各位：    9楼问题？ tcp/ip是协议， socket是编程接口， 这个两个基本都通用。

各位：    9楼问题？

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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语言开发IOS后台，看这三本书合适么？ 看完了，能开发什么类型应用？

各位：   9楼问题？

linux高性能服务器编程

引用 5 楼 Daffodiles 的回复:[quote=引用] 网络编程1，2卷  TCP/IP协议详解 卷1  2，3楼：   这三本书，有些像天书，怎办呢？[/quote]  引用 5 楼 Daffodiles 的回复:[quote=引用] 网络编程1，2卷  TCP/IP协议详解 卷1  2，3楼：   这三本书，有些像天书，怎办呢？[/quote] 一遍一遍看，一遍一遍实践

C APUE UNP1,2       TCP/IP  1

引用网络编程1，2卷  TCP/IP协议详解 卷1  2，3楼：   这三本书，有些像天书，怎办呢？

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

TCP/IP协议详解 卷1 ，这个必须要看一下

网络编程1，2卷

TCP/IP


Question: switch case里在case中加入函数,返回值给了谁?

不明白， 你把函数返回值给 result，它还能跑到别的地方去？ 觉得你还是上代码比较好

引用计算接果然后返回该结果 返回哪里？

感觉楼主的话情况较多，不妨上代码

既然结果是给result， 为何要return ?  直接  赋值不就行？    或者你的计算是在另外函数进行？  那么把函数的结果return 再赋值给result

C语言是面向过程的语言，既然面向过程，他的牛逼之处在于使用了各种函数，LZ可把返回值放在任何函数中，先需要的位置调用这个函数，没有必要非得放在main函数里，当然c语言规定正常情况下，从main函数开始，从main函数结束

如果switch在main里,是不是在case里不能使用return给数赋值?

引用 2 楼 u013326283 的回复:我在main中定义一个int result来村结果.return 应该返回给result;结果没给他怎么可能用return给result在main里赋值呢


Question: C语言问题~

引用 2 楼 relaxisland 的回复:1 你想访问 整数的某个位的的时候 比如一个班有 32个同学， 你不是用32个int，而是用一个int去表示各个同学考试是否几个，可以用如下方式设定获取的第N位同学的状态 score & 1<<n  2 变量的地址的长度是32位 或64位，地址的长度不影响变量的长度， 影响的可访问的地址的范围，也可以说存储变量的内存的数量  就比如 门牌号码的位数， 不影响 房子的大小， 但是影响可以标识的 房子的个数 三位数的门牌，只能访问999个房子，   3 这个基本不用操心，操作系统会根据当前的编码弄好的吧   o

1、一般情况下用的不多，就像goto几乎只在switch或多重循环时才可能用到 2、一楼的例子不错 3、网易MOOC翁恺的，或者郝斌的，都比较基础 4、自己动手，丰衣足食，多动手试试，要是出现你认为奇怪的现象，先谷歌百度，不明白可以来论坛问

1按需要的的时候才做运算，比如x*2，这样的运算，左移一位就可以了。x/2，同样右移一位就行了。 2指针保存的是地址，所有变量的地址都是4字节。就像你家的门牌号，所有门牌号都一只占一个小格子，你邻居家50平方的房子，你家的面积是200平方米，所以会担心你家的门牌号和邻居一样大，就无法表示你家吗？地址和实际的住房是两个概念。  3不知道有什么好视频，看书是最好的吧 4你运算一下不就知道了吗？


Question: malloc分配内存失败

引用 4 楼 user-1 的回复:[quote=引用 3 楼 whustyle 的回复:] [quote=引用 2 楼 user-1 的回复:] [quote=引用 1 楼 user-1 的回复:] 内存是按int[m][n]大小申请的，不要强制转换为double [m][n], 两者并不兼容。  由此可能引起越界访问，个种问题都可能发生。 [/quote]  我的程序需要大量地动态创建int 型和double型矩阵，那有什么好的方法没呢？[/quote] 你需要double [m][n],就申请 double[m][n], 不要申请 int[m][n][/quote] 好的，谢谢

引用 3 楼 whustyle 的回复:[quote=引用 2 楼 user-1 的回复:] [quote=引用 1 楼 user-1 的回复:] 内存是按int[m][n]大小申请的，不要强制转换为double [m][n], 两者并不兼容。  由此可能引起越界访问，个种问题都可能发生。 [/quote]  我的程序需要大量地动态创建int 型和double型矩阵，那有什么好的方法没呢？[/quote] 你需要double [m][n],就申请 double[m][n], 不要申请 int[m][n]

引用 2 楼 user-1 的回复:[quote=引用 1 楼 user-1 的回复:] 内存是按int[m][n]大小申请的，不要强制转换为double [m][n], 两者并不兼容。  由此可能引起越界访问，个种问题都可能发生。 [/quote]  我的程序需要大量地动态创建int 型和double型矩阵，那有什么好的方法没呢？

引用 1 楼 user-1 的回复:内存是按int[m][n]大小申请的，不要强制转换为double [m][n], 两者并不兼容。  由此可能引起越界访问，个种问题都可能发生。


Question: 函数调用运行出错

楼上正解。。。。

返回的地址，为啥要=两边都加*呢，楼上正解

*g=*find_int(c,a,b); 这一句，把*号去掉  g=find_int(c,a,b);


Question: linux下多线程，只对共享资源进行读取，不写，会造成问题么？

加锁就是应为怕其他线程在你读取数据的过程中，修改数据。 既然不写，那就不加锁了。

引用 5 楼 zhao4zhong1 的回复:早晚会写的。我预测  类似于启动的配置数据，把很多函数地址注册进去，然后，很多线程根据消息号会去到改地址

在博物馆，你只是看，但还要保安干嘛

只读不写不用加锁，读的数据不会发生改变，每个线程读的都是同样内容

共享资源如果没有任何进程写入，完全不要需要加锁，注意是共享内存完全没有人写入

只读不写不加锁没问题

不需要加锁！

早晚会写的。我预测

我也感觉不写的话,不用加锁? 等大神来解释~

感觉不会出问题啊


Question: 条件编译程序，错误，求教。

引用 3 楼 s_a_n_ 的回复:很显然第一个代码段是因为B30和A30都未定义，也就是说把VANTILATOR_TYPE定义成了空，而B30和A30都同样是空，所以两个#if都成立，因此两段代码都编译了。 谢谢啦

#define A #define B #define C  #ifdefine A  #elseif B  #else  #endif

引用 1 楼 relaxisland 的回复:你不是自己解决问题了吗 我一般用第二种 windebug的预编译条件就是这样的吧+1


Question: 求两个极大数字的乘积没为什么这段程序在位数很大时便无法输出了?位数低的时候明明没问题的。。。

引用a=(char*)malloc(sizeof(N));     b=(char*)malloc(sizeof(N));     c=(char*)malloc(sizeof(2*N)); 其中“ sizeof(N) ”错了；改为“ N ”，即：(char*)malloc(N)； sizeof(N)=4，是整形的大小..... ps:a,b,c,没有释放内存（虽然不会造成问题）。

楼主试哪个数时没有输出结果？除了楼上说的，scanf中间最好加上空格

太感谢了，就是sizeof（N）那里出的问题。


Question: 我用vc++6.0 写查IP地址的程序为什么只能查txt里的前面一点

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

看到这么多fseek, 就感觉有哪里不对了.  你应该一个地方读取后, 再处理.  (如果文本不大的话).  fseek(fp,-1l,1);  这里的用法不知道是否对了, 每次都移动到  第三个参数的 1 是SEEK_CUR,  第二个参数-1, 表示前移一个.  又没看到移动到文本末尾的操作,  已经晕了.  自己下个断点, F10单步跟踪程序吧.

代码格式太混乱 建议一个功能一个功能封装成函数 然后单步调 很快就找到问题所在

支持单步调试

代码太长，而且格式相当难看，不忍心看啊 不过还是看到了一个错误： while(a=fgetc(fp)!='\n') ==> while((a=fgetc(fp))!='\n') 赋值的优先级最低


Question: 菜鸟写的输入年月日求星期。

COleDateTime::GetDayOfWeek int GetDayOfWeek( ) const;  Return Value  The day of the week represented by the value of this COleDateTime object.  Remarks  Call this member function to get the day of the month represented by this date/time value. The COleDateTime class handles dates from 1 January 100 – 31 December 9999.

记得是 《编程珠玑》 还是《代码之美》里有一个非常简短的算星期几的代码，但忘了怎么写的了

引用 1 楼 user-4 的回复:一个常用的办法是用数组代替switch int days = { 0, 31, 59, 90, ... }； daysum += days[month]; if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) daysum++;+1

#include<stdio.h>   // 自定义函数。 void week();                     // 星期 // 自定义变量。 int year, month, day;           // 年月日 int weeksum, calendarsum, animalsum; // 计算结果，星期，农历，生肖。 int main()  { 	printf("###输入年月日，格式为：年,月,日###\n"); 	scanf("%d,%d,%d", &year, &month, &day); // 输入年月日。 	week(); 	return 0; } void week()  { 	int yearsum, leapsum, aleapsum, daysum; 	yearsum = year - 1;//计算输入日期跟公元一年相差几年。 	aleapsum = yearsum / 4;//计算经过了几个闰年。 	leapsum = yearsum - aleapsum;//计算经过了几个平年。 	daysum = aleapsum * 366 + leapsum * 365;//计算经过的天数。 	switch (month)  	{ 		  case 1:daysum += 0;break; 		  case 2:daysum += 31;break; 		  case 3: 			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) 				daysum += 60; 			else  				daysum += 59; 			break; 		  case 4:daysum += 90;break; 		  case 5:daysum += 120;break; 		  case 6:daysum += 151;break; 		  case 7:daysum += 181;break; 		  case 8:daysum += 212;break; 		  case 9:daysum += 243;break; 		  case 10:daysum += 273;break; 		  case 11:daysum += 304;break; 		  case 12:daysum += 334;break; 	} 		//经过的天数%7等于星期。 	weeksum = (daysum + day - 1) % 7; 	printf("你输入的日期为：星期%d\n", weeksum);   }  改了下可读性

对于用户的任何输入，要判断他是否合法，比如是否输入了13月32日之类的。不能因为用户的非法输入导致数组越界等问题。 如果用switch，应该有default，处理用户输入13月的情况。 if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 这里最好加上括号，看着明确一点，而且不会出现优先级的问题。


Question: c初学者的一个问题的疑惑

我看不懂你的，自己写的选择排序 /*************************************************************************     > File Name: selecsort.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月01日 星期六 22时17分24秒  ************************************************************************/  #include<stdio.h>  //交换值 void swap(int *a, int *b) { 	int tmp; 	tmp = *a; 	*a = *b; 	*b = tmp; }  //排序 void sort(int *arr, int len) { 	for(int i = 0; i < len - 1; ++i) 	{ 		for(int j = i+1; j < len; ++j) 		{ 			if(arr[i] > arr[j]) 				swap(&arr[i], &arr[j]); 		} 	} }   int main() { 	int arry[10]; 	for(int i = 0; i < 10; ++i) 		scanf("%d",&arry[i]); 	sort(arry, 10); 	for(int i = 0; i < 10; ++i) 		printf("%d\n",arry[i]);  	return 0; }

引用 7 楼 addsspu 的回复://选择排序 #include<stdio.h> int main (void){ 	int i,j,f,t,k,a[10],temp; 	for(i=0;i<10;i++) 		scanf("%d",&a[i]); 	for(j=0;j<9;j++){ 		temp=j;//标记位置 		for(k=j+1;k<10;k++){ 			if(a[temp]>a[k]){ 				temp=k;//更新位置 			} 		} 		t=a[j]; 		a[j]=a[temp]; 		a[temp]=t;//对换数据 	} 	for(f=0;f<10;f++) 		printf("%d\t",a[f]); 	return 0; }  恩恩，我想问我的程序哪里不太正确？？

引用 5 楼 u013163178 的回复:加油啊，你的代码的思想不错 /*************************************************************************     > File Name: fibonacci.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月01日 星期六 19时37分56秒  ************************************************************************/  #include<stdio.h> int fib(int n) { 	if( n == 0 || n ==1) 		return 1; 	else 		return fib(n-1) + fib(n-2); }  int main() { 	int n = 10; 	printf("%d\n",fib(n)); 	return 0; }  恩，您编的很简洁，很漂亮，向您学习，我会努力的，对了，刚才我在编简单选择法排序的时候出了点问题，您能帮忙解释一下吗？ #include<stdio.h> int main (void) { 	int i,j,f,t,k,a[10]; 	for(i=0;i<10;i++) 	scanf("%d",&a[i]); 	for(j=0;j<9;j++) 	{ 		for(k=j+1;k<10;k++) 		{ 			if(a[j]>a[k]) 			{t=a[j];a[j+1]=a[j];a[j+1]=t;} 			  		} 	} 	for(f=0;f<10;f++)     printf("%d",a[f]); 	return 0; }

引用 2 楼 u012421456 的回复:# include <stdio.h>  int main() {     int i,n,fib[12];     fib[0]=1;     fib[1]=1;     for(i=2;i<12;i++)///////////////////这个问题，，，楼主需要认真啊     {         fib[i]=fib[i-1]+fib[i-2];     }     for(n=0;n<13;n++)         printf("%4d",fib[n]);/////////////////让输出之间有间隙              return 0; }  恩，发现错误了，感谢感谢，以后一定要认真

引用 1 楼 shenimenyilian 的回复:#include<stdio.h> main() { int i,n,fib[12]; fib[0]=1;fib[1]=1; for(i=2;1<12;i++)//应该是i<12不是1<12 { fib[i]=fib[i-1]+fib[i-2]; } for(n=0;n<13;n++) printf("%d",fib[n]); return 0;      } 发现了发现了 非常感谢！！看来我还需努力啊！


Question: 内存不够用的问题怎么解决？？

引用 6 楼 whustyle 的回复:[quote=引用 4 楼 zxh707wk 的回复:] 优化数据结构，优化算法  老实说，我这样的算法确实蠢了点，目前还想不出有什么巧妙地设计数据结构和算法，来节省一点内存，我还有待学习[/quote]淡定。。。

引用 4 楼 zxh707wk 的回复:优化数据结构，优化算法  老实说，我这样的算法确实蠢了点，目前还想不出有什么巧妙地设计数据结构和算法，来节省一点内存，我还有待学习

引用 3 楼 bbs2241 的回复: double** E_inv = CreateMatrix(nBand,nBand);     E_inv = MatrixInverse(Ground_Cov,nBand);  内存泄露，改成  double** E_inv = MatrixInverse(Ground_Cov,nBand);  这个E_inv也得释放。其他的没细看  一语惊醒梦中人呐，按照您这样一改，100万次循环不要一分钟就顺利算完了。非常的感谢

优化数据结构，优化算法

引用 1 楼 user-3 的回复:double** E_inv = CreateMatrix(nBand,nBand);     E_inv = MatrixInverse(Ground_Cov,nBand);   目测这里内存泄露 我把这里面的拿出来给你看吧，看不出来哪里泄露啊，求继续指点 //创建一个m行n列的double型矩阵 double** CreateMatrix(int m, int n) { 	double** Matrix; 	int i;     Matrix = (double **) malloc(sizeof(double *) * m);     for(i = 0; i < m; i++)     {             Matrix[i] = (double *) malloc(sizeof(double) * n);     }     return Matrix; }  //矩阵的求逆 double** MatrixInverse(double **A,int M)  { 	int i,j,k; 	double** A_inv = CreateMatrix(M,M); 	double** AE = CreateMatrix(M,2*M); 	for (i=0;i<M;i++) 	{ 		memset(A_inv[i],0,sizeof(double)*M); 		memset(AE[i],0,sizeof(double)*2*M); 	} 	for(i=0;i<M;i++)     {         for(j=0;j<M;j++)         {             AE[i][j]=A[i][j];         }     } 	for(i=0;i<M;i++)     {         for(j=M;j<2*M;j++)         {             if(i==(j-M))             {                 AE[i][j]=1;             }             else             {                 AE[i][j]=0;             }         }     } 	/*****************求逆模块***********************/     for(i=0;i<M;i++)     {         if(AE[i][i]==0)         {             for(k=i;k<M;k++)             {                 if(AE[k][k]!=0)                 {                     for(int j=0;j<2*M;j++)                     {                         double temp;                         temp=AE[i][j];                         AE[i][j]=AE[k][j];                         AE[k][j]=temp;                     }                     break;                 }             }             if(k==M)             {                 printf("该矩阵不可逆！\n");             }         }         for(j=2*M-1;j>=i;j--)         {             AE[i][j]/=AE[i][i];         }         for(k=0;k<M;k++)         {             if(k!=i)             {                 double temp=AE[k][i];                 for(j=0;j<2*M;j++)                 {                     AE[k][j]-=temp*AE[i][j];                 }             }         }     }     /*****************获取逆矩阵***********************/ 	 for(i=0;i<M;i++)     {         for(j=M;j<2*M;j++)         {             A_inv[i][j-M]=AE[i][j];         }     } 	 for (i=0;i<M;i++) 	 { 		 free(AE[i]); 		 AE[i] = NULL; 	 } 	 free(AE); 	 AE = NULL; 	 return A_inv; }


Question: 刚接触函数，调用求解

label1：     z = pd();         ge = z%10;         shi = (z/10)%10;         bai = (z/100)%10;         qian = (z/1000)%10;         wan = (z/10000)%10;         js(ge,shi,bai,qian,wan); goto label1;

使用while循环，如果条件不满足直接退出

while (1) {         z = pd();         ge = z%10;         shi = (z/10)%10;         bai = (z/100)%10;         qian = (z/1000)%10;         wan = (z/10000)%10;         js(ge,shi,bai,qian,wan);         getch();         printf("\n");     } 加一个循环即可，注意的是要设定好结束循环的条件


Question: 好奇吗？

引用 2 楼 dbzhang800 的回复:你是说变长数组么？  不好奇， C99标准 允许这种写法。GCC在C99之前也支持这种写法。+1，c99标准

引用 2 楼 dbzhang800 的回复:你是说变长数组么？  不好奇， C99标准 允许这种写法。GCC在C99之前也支持这种写法。 那么问题来了，数组n到底是在堆上还是在栈上呢

gcc下也可以通过。。。


Question: CFree调试，如何查看整个数组内容？

引用 3 楼 ForestDB 的回复:其实我倒是觉得logger（printf）比debugger要好。 英雄所见略同： //带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*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;     }      //将单链表中前 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; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

楼主 这个或许能帮到你

引用 3 楼 ForestDB 的回复:其实我倒是觉得logger（printf）比debugger要好。产品级这样好，如果平时调试学习用，还是debugger好

其实我倒是觉得logger（printf）比debugger要好。

求助一下。

CFree调试不太清楚，用DEV是可以的


Question: 有大约1万个文件，给你10个文件夹，把这1万个文件放到文件夹里，要求：这10个文件夹的大小基本相同。

文件大小不能差太多，否则任何算法都没有办法: 比如一个差大文件(100G), 其他文件加起来不到1MB

引用 4 楼 bjym1987 的回复:引用 3 楼 mujiok2003 的回复:最简单办法： 把文件按大小排好序,  第x个文件放入 x % / 10个文件夹中。 这方法 10文件夹 大小不是基本相同的，这样应该是递增的. 恩。 变一下就好了.  for(i = 0 ; i < file_number;) {   for(int j = 0; j < 10 &&  i < file_number;  ++j, ++i)   {      put file[i] to folder[j];   }     for(int j = 0; j < 10 &&  i < file_number;  ++j, ++i)   {      put file[i] to folder[9-j];   } }

这个应该是一个等份背包问题吧： 1、先得到1w个文件总的大小 T -> 每个目录分得 t=T/10(大概) 2、根据 t 的值来遍历每个文件，寻到累计和接近 t 的时候把这些文件归入一个目录里面（动态规划） 3、把已经加入到目录里面的文件从总的文件列表中去除 4、重复2-3步骤 直至总的文件列表为空  难点是接近值的确定，比如 t=10 ，那累计和达到9、9.1、...、10.1、...等是否达到要求。  个人觉得采用方差的方式应该更精确一点，10份目录的每个目录大小，与 t 进行方差计算，得出最小的就是最理想的平均分配方案又有一个问题就是如何分配10份目录的文件数，最笨也是最简单实现的就是穷举。。。  能力有限只能想到这么多

你这不是要 读取每个文件大小，然后算下10等分值，然后按要求移过去就可以了吧

我的想法： 如果不考虑细节和特殊情况的话：先读取每个文件大小后做累加得到总和后处于10得到一个平均值，得到平均值后就在读取一遍所有文件和文件大小并进行文件的复制还要计算你复制到每个文件夹下的文件总和大小并判断是否超出平均值.


Question: C语言地址问题

引用 11 楼 b_j_m 的回复:你举的例子与你提的问题没有关系吧，你的举例，说的仅仅是数据的存储与变量地址间的关系。这跟变量地址的长度有什么联系呢？如果你对表达式int p=789; 不理解，那么应该认识什么是类型，什么是变量，什么是值。p变量这里声明为int类型，那么p变量这里被赋值为789. p是变量的名称，或者理解为一个被命名的地址，这个地址开始，用int类型的操作赋值，int类型如果是4个字节的宽度，那么这些字节存储的就是789的二进制值表示。数据一般按类型操作，所以变量的长度与他的类型有关。  是的，正是要说没有联系！各种号的长度和变量的存储空间没有联系！长度和总量有关系！相当数学中的取值范围——域！其实lz的问题得牵涉到计算机体系和组成——地址线的宽度决定地址的长度！

内存是连续的，但不同类型的变量，所占的大小不同。 int32为4个字节。足以放下你那个789.下一个地址就不知道存的啥了

p的地址存的变量是789， 1245052+1是下一个地址，变量值未知

一个整数只有一个地址，p没有地址，p只是一个符号。p所代表的变量才有地址。c语言中地址+1无意义，指针+1才有意义，因为地址是没有类型的，指针具有类型。

参见1楼。。

楼上已经说的很清楚了 1245052+1 这个是无意义的  应该这样 1245052+1*sizeof(int)  这样才是8的地址

1 变量地址一般就是所谓的指针了，这个长度和系统编译器有关，32位机器的编译器一般是4个字节； 2 p的地址是1245052的话，p+1的地址不是在地址的数值上+1，而是加上这个指针的类型（比如这个就是int型指针）大小，也就是相当于加上了sizeof(int)

引用 13 楼 u012421456 的回复:[quote=引用 12 楼 zxh707wk 的回复:] +1.... 你经常+1、围观啊[/quote]+2，围观

789被存放到了为p所分配的内存空间中，通过访问变量名来访问该数据，一个int所占空间已经足够存储，楼主可以好好看看一楼的话

引用 12 楼 zxh707wk 的回复:+1.... 你经常+1、围观啊

举个例子不吧：车牌号和车的大小有关系嘛？没有！门牌号和房子大小有关系嘛？没有！图书索引号和书本厚度有关系嘛？没有！身份证id和人帅不帅有关系嘛？没有！妹纸的深度和你的。。。什么呢？你懂得！车牌号，门牌号，索引号，身份证号，就是地址。车，房子，书本，人，就理解成变量得了！

还有789转换成二进制后存储在存储器中，int型在32位机器上有32位，从低到高存储789的二进制位，高位没有补0，并不是说7和a地址相同，反而存储7这个位应该在高位字节上。

这也太二吧，32位下，int 类型占有4个字节，但是，表示一个变量的地址，用的是变量对应地址的最低位节吧，每个字节都有编号，四个字节的编号是连续的，好比，int a，a的地址是0x00000001，那么这个变量的四个字节的地址从低位到高位依次是 0x00000001，0x00000002，0x00000003,0x00000004，变量的每个字节都有地址，但是表示变量a地址用的是最低位的 0x00000001这个地址。

一楼正解。。。


Question: 关于include的一个困惑

既然函数是库中的，你调用该函数的文件必须要做该函数的申明（库文件都是伴随有.h文件的，不然你咋知道这个库有哪些函数，函数原型是什么。这里把申明该函数的.h文件include到你文件中）。然后，将该函数所在文件加入到你的工程中（有的是.o文件，有的是dll文件等等，怎么添加看你的编译器而定）。  有的库是以源码形式提供的，这个你应该知道怎么搞。

a.c和main.c是不同的编译单元。 编译器编译的时候，是先编译每一个编译单元，生成各个单元的链接文件（即a.o main.o），再用链接器链接成可执行文件。  a.c编译成a.o时，当然找不到func1的定义拉。

引用 10 楼 e08610318 的回复:[quote=引用 9 楼 s_a_n_ 的回复:] 编译的时候只需要有函数的声明就可以调用该函数，编译成功。 连接的时候需要找到该函数的定义，就是具体调用的什么东东要知道。 你没有添加定义的时候只有声明因此只能编译通过的，连接的时候找不到函数定义。 举个例子，老大让你找一个叫小明的人帮你忙，可是你只知道他的名字（函数声明）却不知道他在哪里（函数定义，即函数体的起始位置），你怎么让他帮你的忙呢  能否调用一个函数与函数在哪个文件中定义无关。 在哪个文件中定义，只是影响了声明函数的方式。  总结一下：凡是你调用到的函数，都必须有明确的定义。如果你没有定义一个函数，那么就不能调用它。  你的意思是，只要一个文件包含了需要调用的函数的声明，那么该函数的定义放在哪都没关系？[/quote] 对，不过有一点需要说明的是，被调用的函数定义必须存在（通常放在同一个工程下参与编译即可）。 放在某个.c源文件中经过编译生成目标代码也可以，使用动态/静态链接库也可以。

应该是链接错误吧

引用 9 楼 s_a_n_ 的回复:编译的时候只需要有函数的声明就可以调用该函数，编译成功。 连接的时候需要找到该函数的定义，就是具体调用的什么东东要知道。 你没有添加定义的时候只有声明因此只能编译通过的，连接的时候找不到函数定义。 举个例子，老大让你找一个叫小明的人帮你忙，可是你只知道他的名字（函数声明）却不知道他在哪里（函数定义，即函数体的起始位置），你怎么让他帮你的忙呢  能否调用一个函数与函数在哪个文件中定义无关。 在哪个文件中定义，只是影响了声明函数的方式。  总结一下：凡是你调用到的函数，都必须有明确的定义。如果你没有定义一个函数，那么就不能调用它。  你的意思是，只要一个文件包含了需要调用的函数的声明，那么该函数的定义放在哪都没关系？

引用 3 楼 e08610318 的回复:[quote=引用 1 楼 wangzuxi 的回复:] [quote=引用 楼主 e08610318 的回复:] 描述：          config.h文件声明了一个全局函数func1，且只包含了一个类型定义的H文件，main.c只包含config.h，此外工程中包含了文件a.c，但是没有用到a.c的函数，但a.c要用到全局函数func1，此时编译出错，告知找不到func1的定义，然后在main.c定义了func1函数，编译通过。这是怎么回事？  引用：这是我在使用CMSIS固件库时遇到的问题，此时func1对应void check_failed(uint8_t *file, uint32_t line)。 a.c用到了func1，但func1没有定义，当然出错，之后你在main.c中定义了func1，在编译a.c编译器在main.o中找到了func1的定义，所以能编译通过。[/quote] 这个我也知道，能从文件包含的一些机制来回答该问题吗？比如说编译器在编译过程中它的依赖关系是怎么建立的？主要是这个做法不是通用做法，一下子我就反应不过来了。[/quote] 推荐你看看这篇文章： http://codemacro.com/2014/09/15/inside-static-library/

引用 2 楼 JiangWenjie2014 的回复:那就把a.c从工程中移除啊，否则的话，a.c需要使用func1，那么在链接阶段函数func1必须是有定义的。  这个治标不治本的，以后要用到呢？所以我事先在工程中加入了该文件。

引用 1 楼 wangzuxi 的回复:[quote=引用 楼主 e08610318 的回复:] 描述：          config.h文件声明了一个全局函数func1，且只包含了一个类型定义的H文件，main.c只包含config.h，此外工程中包含了文件a.c，但是没有用到a.c的函数，但a.c要用到全局函数func1，此时编译出错，告知找不到func1的定义，然后在main.c定义了func1函数，编译通过。这是怎么回事？  引用：这是我在使用CMSIS固件库时遇到的问题，此时func1对应void check_failed(uint8_t *file, uint32_t line)。 a.c用到了func1，但func1没有定义，当然出错，之后你在main.c中定义了func1，在编译a.c编译器在main.o中找到了func1的定义，所以能编译通过。[/quote] 这个我也知道，能从文件包含的一些机制来回答该问题吗？比如说编译器在编译过程中它的依赖关系是怎么建立的？主要是这个做法不是通用做法，一下子我就反应不过来了。

引用 楼主 e08610318 的回复:描述：          config.h文件声明了一个全局函数func1，且只包含了一个类型定义的H文件，main.c只包含config.h，此外工程中包含了文件a.c，但是没有用到a.c的函数，但a.c要用到全局函数func1，此时编译出错，告知找不到func1的定义，然后在main.c定义了func1函数，编译通过。这是怎么回事？  引用：这是我在使用CMSIS固件库时遇到的问题，此时func1对应void check_failed(uint8_t *file, uint32_t line)。 a.c用到了func1，但func1没有定义，当然出错，之后你在main.c中定义了func1，在编译a.c编译器在main.o中找到了func1的定义，所以能编译通过。

在a.c中加入extern void check_failed(uint8_t *file, uint32_t line)或者包含config.h头文件

include实际就是代码替换，把include文件里所有的内容copy过来。  --------万恶的分割线-------------------------------------------------------------  编译阶段：     1.  include和宏替换。     2.  把所有声明的函数解释成编译器能识别的函数别。(有可能是fdff@check_failed，这样看起来很乱的函数名，也有可能是汇编码)。     3.  把所有的代码，所有的函数调用，全部关联到函数定义的地方。(如果没有找到，此时就会报错)。  以上是我的粗浅的理解。。。。

a.c也包含 config.h啊


Question: 这个代码运行有问题 麻烦学长们看看

#include <stdio.h>  void main(){ 	int a[6]; 	int *p=a,i; 	printf("input the array:\n"); 	for(i=0;i<6;i++)scanf("%d",p+i); 	printf("\n"); 	for(i=0;i<6;i++)printf("%8d",*(p+i));  	void sort(int *p, int n); 	sort(p,6); 	printf("the new sort is:\n"); 	for(i=0;i<6;i++) 		printf("%8d",*(p+i)); 	printf("\n");	 }  void sort(int *p, int n){ 	int *i,*j,k,t=0; 	i=p; 	for(;i<p+n-1;i++){ 		for(k=1;k<p+n-i;k++){//这里写错了，会导致i+k越界,写成k<p+n-i 			if(*i<*(i+k)){//这里会越界！！！！！ 				t=*i; 				*i=*(i+k); 				*(i+k)=t; 			} 		}	 	} }


Question: if语句对程序运行时间的影响

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

引用 6 楼 hitxingkong 的回复:引用 4 楼 my_live_123 的回复:每条if语句都会翻译成相应的跳转指令！其实包括循环语句，最终也是转换成了类似if的跳转指令！跳转指令相对与其他指令要慢，因此if条件执行的次数越多，就越影响效率！有些编译器会有针对性的优化工作！建议楼主反汇编瞅瞅！函数是否有返回值对运行时间会有影响吗 返回值不影响效率，只是将某个值放到一个寄存器中，一般是eax！类似与: mov value eax.在函数返回后，有主调函数从寄存器中拿取返回值！

第一个快 第二个慢

#include<stdio.h> #include<stdlib.h> #include<windows.h>  int main() { 	long test=1000000000; 	long i=0; 	int  flag =0; 	DWORD result1, result2; 	DWORD dwStartTicks, dwEndTicks;  	dwStartTicks=GetTickCount(); 	for(i=0;i<test;i++) 	{ 		; 	} 	dwEndTicks=GetTickCount();  	// 计算时长 	if (dwEndTicks < dwStartTicks) 	{ 		result2 = (0xFFFFFFFF - dwStartTicks + dwEndTicks + 1); 	} 	else 	{ 		result2 = (dwEndTicks - dwStartTicks)+1; 	}  	printf("result2= %d\n",result2);  	dwStartTicks=GetTickCount(); 	for(i=0;i<test;i++) 	{ 		; 		if(i != test) 			flag = ~flag; 	} 	dwEndTicks=GetTickCount(); 	// 计算时长 	if (dwEndTicks < dwStartTicks) 	{ 		result1 = (0xFFFFFFFF - dwStartTicks + dwEndTicks + 1); 	} 	else 	{ 		result1 = (dwEndTicks - dwStartTicks)+1; 	}  	printf("result1 = %d\n",result1); 	getchar(); }

SYNOPSIS      #include <time.h>       clock_t      clock(void);  DESCRIPTION      The clock() function determines the amount of processor time used since      the invocation of the calling process, measured in CLOCKS_PER_SECs of a      second.

针对两种情况写个程序， 不要在代码中计算时间， 使用linux time命令,多测几次再统计结果。

引用 2 楼 user-6 的回复:好好写代码，1和2分分清楚，你程序里先2再1，下面数据先1再2，换谁都不会信任你这个数据结果的。认真重写代码，科学重测数据，再来看有没有什么问题。 在虚拟机里写的，忘了返回值，gcc编译也能通过，加了返回值带if语句的循环运行时间就更长。返回值怎么影响这个呢


Question: 不包含stdio.h头文件，如何读写文件

单独使用一个 C 文件，使用 stdio.h. 她们仅仅是定义。

引用 2 楼 sunmaxwell 的回复:[quote=引用 1 楼 JiangWenjie2014 的回复:] 那就用系统提供的文件操作啊，windows(Windows.h)有CreateFile，ReadFile；linux(fcntl.h, unistd.h)有open，read，write，close。Windows下的CreateFile、ReadFile函数都是C++函数，我想问的是C语言哈，这个标准是针对C语言的，所以很困惑~Linux这些函数好像是针对C语言的，在Linux系统下开发得少了一点。  Syntax C++ HANDLE WINAPI CreateFile(   __in      LPCTSTR lpFileName,   __in      DWORD dwDesiredAccess,   __in      DWORD dwShareMode,   __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,   __in      DWORD dwCreationDisposition,   __in      DWORD dwFlagsAndAttributes,   __in_opt  HANDLE hTemplateFile );[/quote] 这明明是C函数，你怎么说是C++函数呢？

Low-level I/O These functions invoke the operating system directly for lower-level operation than that provided by stream I/O. Low-level input and output calls do not buffer or format data.  Low-level routines can access the standard streams opened at program startup using the following predefined handles:  Stream Handle  stdin 0  stdout 1  stderr 2    Low-level I/O routines set the errno global variable when an error occurs. You must include STDIO.H when you use low-level functions only if your program requires a constant that is defined in STDIO.H, such as the end-of-file indicator (EOF).  Low-Level I/O Functions  Function Use  _close Close file  _commit Flush file to disk  _creat, _wcreat Create file  _dup Return next available file handle for given file  _dup2 Create second handle for given file  _eof Test for end of file  _lseek, _lseeki64 Reposition file pointer to given location  _open, _wopen Open file  _read Read data from file  _sopen, _wsopen Open file for file sharing  _tell, _telli64 Get current file-pointer position  _umask Set file-permission mask  _write Write data to file    _dup and _dup2 are typically used to associate the predefined file handles with different files.

引用 1 楼 JiangWenjie2014 的回复:那就用系统提供的文件操作啊，windows(Windows.h)有CreateFile，ReadFile；linux(fcntl.h, unistd.h)有open，read，write，close。Windows下的CreateFile、ReadFile函数都是C++函数，我想问的是C语言哈，这个标准是针对C语言的，所以很困惑~Linux这些函数好像是针对C语言的，在Linux系统下开发得少了一点。  Syntax C++ HANDLE WINAPI CreateFile(   __in      LPCTSTR lpFileName,   __in      DWORD dwDesiredAccess,   __in      DWORD dwShareMode,   __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,   __in      DWORD dwCreationDisposition,   __in      DWORD dwFlagsAndAttributes,   __in_opt  HANDLE hTemplateFile );

所以我的第一个回复就是告诉，使用一个单独的 C 文件。

引用 10 楼 Saleayas 的回复:MISRA 标准是针对想汽车控制系统，这类嵌入式的，永远运行，安全至上的软件。 你在这类嵌入式中使用 fopen 是不标准的。 您可以参考9楼的回答哈~谢谢您这么热心地回答~~

而且，我觉得如果是你使用 Windows 操作系统，这个标准就没有意义了。 因为这个标准是针对嵌入式的。  因为在 Windows 编程中，使用的库都是可能有动态内存分配的。

引用 9 楼 s_a_n_ 的回复:那个标准不是说的很清楚吗？ 就是说，标准本身是假定你没有stdio.h中规定的i/o需求的。而现在你有读写文件的需求，因此，需要你的嵌入式系统支持你读写文件这类操作。对于标准情况而言，这类操作可能包含大量为定义的行为，因此，至于如何使用，只有从你的系统本身那里找答案。 ps：提示一下，怎么读写文件要看你的文件系统接口，如果你的系统里根本没有文件系统，那么就不能读写文件。  您说得还是蛮有道理的，谢谢您的回答

在二进制代码中， C++ 生成的 和 C 没有区别。 所有 C++ 的代码，都可以以 C 的方式写出来。 所以不管 CreateFile 时候是有 C 语言写的，结果都是一样的。  在 MSDN 文档中，C++ 这个标签包含了 C，因为这个 文档是给 vS 用的。 和这个标签平齐的不是 C，而是 C#、JavaScript、F# 和 VB 这些语言。

引用 8 楼 dbzhang800 的回复:[quote=引用 6 楼 sunmaxwell 的回复:] 额。。。不至于吧？这是MSDN的官方解释，C++代码~~你可以自己动手查下~  你不妨把你看到的官方解释贴出来。 这个说法，其他人估计还真查不出来。 [/quote]

引用 6 楼 sunmaxwell 的回复:额。。。不至于吧？这是MSDN的官方解释，C++代码~~你可以自己动手查下~  你不妨把你看到的官方解释贴出来。 这个说法，其他人估计还真查不出来。

引用 5 楼 Saleayas 的回复:单独使用一个 C 文件，使用 stdio.h. 她们仅仅是定义。 您好，谢谢您的回答。MISRA C 2004标准不允许使用stdio.h啊，所以另外包含一个也无济于事的哈~~

引用 4 楼 dbzhang800 的回复:[quote=引用 2 楼 sunmaxwell 的回复:] [quote=引用 1 楼 JiangWenjie2014 的回复:] 那就用系统提供的文件操作啊，windows(Windows.h)有CreateFile，ReadFile；linux(fcntl.h, unistd.h)有open，read，write，close。Windows下的CreateFile、ReadFile函数都是C++函数，我想问的是C语言哈，这个标准是针对C语言的，所以很困惑~Linux这些函数好像是针对C语言的，在Linux系统下开发得少了一点。  Syntax C++ HANDLE WINAPI CreateFile(   __in      LPCTSTR lpFileName,   __in      DWORD dwDesiredAccess,   __in      DWORD dwShareMode,   __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,   __in      DWORD dwCreationDisposition,   __in      DWORD dwFlagsAndAttributes,   __in_opt  HANDLE hTemplateFile );[/quote] 这明明是C函数，你怎么说是C++函数呢？[/quote] 额。。。不至于吧？这是MSDN的官方解释，C++代码~~你可以自己动手查下~


Question: 一个字符串复制函数  调试时出现”Unhandled exception 0xC0000005;Access Violation“，是怎么回事

参见1楼，没有分配内存

嗯，char *d = dest;//参数备份 那它的值是啥啊

引用 5 楼 s_a_n_ 的回复:[quote=引用 4 楼 xad707348125 的回复:] [quote=引用 3 楼 bjym1987 的回复:] 参见1楼，没有分配内存 我赋值了，不就是让d指向dest的内存空间吗？还有再分配空间？？ 指针那边都忘了，求科普？[/quote] 你的dest也没有分配空间啊。你main函数里char *d;只是申请了一个指针，但没有分配空间直接就用了。 至于怎么给指针分配空间，太基础了，看书学比较靠谱一些。[/quote] 嗯，，我知道错那了。。改过来了。。。谢谢。。太基础了呀。。。

引用 4 楼 xad707348125 的回复:[quote=引用 3 楼 bjym1987 的回复:] 参见1楼，没有分配内存 我赋值了，不就是让d指向dest的内存空间吗？还有再分配空间？？ 指针那边都忘了，求科普？[/quote] 你的dest也没有分配空间啊。你main函数里char *d;只是申请了一个指针，但没有分配空间直接就用了。 至于怎么给指针分配空间，太基础了，看书学比较靠谱一些。

引用 3 楼 bjym1987 的回复:参见1楼，没有分配内存 我赋值了，不就是让d指向dest的内存空间吗？还有再分配空间？？ 指针那边都忘了，求科普？

char *d;没有分配空间给它


Question: 一个选择题，不明白，求解

明白了  谢谢大家   可惜分不多

楼主这个也想不明白吗？ FA调用FB，若FB出现在FA之后，FA调用FB时，不认识FB，所以报错，需要把FB的原型放到FA的前边

要想彻底明白，请参考gcc源代码相关片断。

还不是很明白

C语言的编译是顺序编译 记住就好了

首先是FA  调用 FB  所以 如果FB是在FA之前则可以直接使用 但是如果我的FA出现在FB之前，如果此前FB没有声明， 则无法找到FB的相关信息。无法编译通过 顾选择D

为什么C错了 而D对了

引用 14 楼 u012421456 的回复:[quote=引用 12 楼 zxh707wk 的回复:] +1.... 经常的+1、围观回复？？？[/quote]yes

脑筋急转弯  好好想想选项C    D

引用 12 楼 zxh707wk 的回复:+1.... 经常的+1、围观回复？？？

额。。。。。。。

编译是有顺序的，所以 FA 跟FB  肯定有编译顺序，如果 FA 调用FB， 若FB在FA前定义，那么不用声明，直接调用即可，因为FB是在FA之前已经通过编译的。若 FB在FA之后，那么就需要先声明FB，不然FA调用FB的时候编译器不知道谁是FB……  所以如果FA调用FB的话 选D 反之，如果FB调用FA的话 选C

这是函数定义和函数声明区分 “函数定义可以以任意次序出现在一个源文件或多个源文件中,但同一函数不能分割存放在多个文件中。如果源程序分散在多个文件中,那么,在编译和加载时,就需要做更多的工作,但这是操作系统的原因,并不是语言的属性决定的。”-K&R 注:函数定义的自由先决条件是有函数声明在先  由于C是强类型语言，任何变量在使用之前都必须告知编译器它的类型，函数不例外！而且在使用时候要做类型检查！函数调用属于表达式的范畴，当归约识别出是函数调用时，就要从符号表中获取此函数的信息，以匹配和检查参数的传递，确保参数合法性从而保证函数的正确使用！——这些都是编译器的工作！  目前C编译器都是LL实现，从左到右，从先到后语法解析源程序，因此先出现的标识（变量名，函数名）先进入符号表，如果一个函数FB未定义又没有声明，那么它就不会出现在符号表当中，而此时若有函数FA调用FB，只会报错函数FB未定义，也就是调用非法，因为FB根本不存在符号表中，找不到它任何信息，报错！如果只声明FB而没有定义FB，然后FA调用FB，编译能通过，但链接就会出错喽！也就是符号表中已经有它的信息，函数调用语法归约和类型检测能够顺利进行，编译能通过，但是链接时就找不到FB的地址了，没有定义嘛！  ls上hacker给出了另外一种告知方式，它是正确可执行的。依据C文法，函数声明和变量声明最终都到declaration-list，无论是全局的还是局部的，只要是合法的声明，相关符号属性都会放入符号表！但是本质不一样，放在函数内，它是局部声明，在函数局部符号表内，而不是全局符号表。放在函数外，则是在全局符号表内。虽然表面效果一样，但是机理还是有区分的。提醒这一点吧，并无它意！ 下面代码可以验证它的作用域   #include <stdio.h>   int FA(void) { 	int x, y; 	double FB(int x, int y);  	x = 1; 	y = 2; 	printf("%f\n", FB(x, y));  	return 0; }  int FC(void) {     int x, y;      x = 1;     y = 2;     printf("%f\n", FB(x, y));//gcc编译报错,上面FB声明只在局部符号表内      return 0; }  double FB(int x, int y) {     return (x + y) / 2.0; }  int main(int argc, char *argv[]) {     FA();     FC();     return 0; }    gcc编译信息  declaration.c:23:20: error: incompatible implicit declaration of function ‘FB’      printf("%f\n", FB(x, y));                     ^ declaration.c:8:9: note: previous implicit declaration of ‘FB’ was here   double FB(int x, int y);          ^ declaration.c:23:5: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]      printf("%f\n", FB(x, y));      ^

FA调用FB，所有在声明或定义FB时，都不用管FA有没有声明，FA根本影响不到FB，所以C错的

D也不对呀！ 虽然从实践上D的说法是没错的，但是并不是必须  #include <stdio.h>  int FA(void) {     int x, y;     double FB(int x, int y);      x = 1;     y = 2;     printf("%f\n", FB(x, y));      return 0; }  double FB(int x, int y) {     return (x + y) / 2.0; }  int main(int argc, char *argv[]) {      FA();     return 0; }

调用前必须先声明啊，因为FA要调用FB所以FB在FA之前必须声明啊


Question: 求救error C2106: '=' : left operand must be l-value

引用 2 楼 xpdavis 的回复:如果name是数组的话，应该这样： strcpy(G->vertices[h].name, data[v[d]].name);   的确是这个问题，感激不尽

name成员变量是什么类型，估计是数组吧， 改成 strcpy( G->vertices[h].name, data[v[d]].name );

你至少G和data的定义要给出来啊