Question: c语言宏定义与文件包含改写c代码

引用 3 楼 qq423399099 的回复:将vol_ball,vol_cylind，vol_cone这三个函数放到一个单独的cpp文件里 总共需要三个文件： [1]myfun.h  #ifndef MYFUN_H #define MYFUN_H  #include<stdio.h>  #define PI 3.1415926  double vol_ball(); double vol_cylind(); double vol_cone();  #endif  [2]myfun.cpp  #include "myfun.h" double vol_ball() { 	double r; 	printf("请输入球的半径："); 	scanf("%lf",&r); 	return (4.0/3.0*PI*r*r*r); } /* 计算圆柱体积*/ double vol_cylind() { 	double r,h; 	printf("请输入圆柱的底圆半径和高："); 	scanf("%lf%lf",&r,&h); 	return (PI*r*r*h); } /* 计算圆锥体积*/ double vol_cone() { 	double r,h; 	printf("请输入圆锥的底圆半径和高："); 	scanf("%lf%lf",&r,&h); 	return (PI*r*r*h/3.0); }  [3]main.cpp  #include"myfun.h"  void main() { 	int choice; 	do 	{  		printf("       ====功能选项====\n"); 		printf("       1--计算球体体积 \n"); 		printf("       2--计算圆柱体积 \n"); 		printf("       3--计算圆锥体积 \n"); 		printf("       0--退        出  \n"); 		printf("请选择:  "); 		scanf("%d",&choice); 		switch(choice) 		{ 		case 1:  			printf("球体积为：%.2f\n",vol_ball()); 			break; 		case 2: 			printf("圆柱体积：%.2f\n",vol_cylind()); 			break; 		case 3: 			printf("圆锥体积：%.2f\n",vol_cone()); 			break; 		case 0: 			break; 		} 	}while(choice!=0); 	printf("谢谢使用! \n"); }   谢谢指教我去试试

/* 该程序功能包括3个计算圆形体体积的函数*/ #include "stdio.h" #include "math.h" main() { 	int choice; 	do 	{  	printf("       ====功能选项====\n");     printf("       1--计算球体体积 \n");     printf("       2--计算圆柱体积 \n"); 	printf("       3--计算圆锥体积 \n");     printf("       0--退        出  \n"); 	printf("请选择:  ");     scanf("%d",&choice);     switch(choice) 	{ 	case 1:  		printf("球体积为：%.2f\n",vol_ball()); 		break; 	case 2: 		printf("圆柱体积：%.2f\n",vol_cylind()); 		break; 	case 3: 		printf("圆锥体积：%.2f\n",vol_cone()); 		break; 	case 0: 		break; 	} 	}while(choice!=0); 	printf("谢谢使用! \n"); } #include "stdio.h" #define PI 3.1415926 double vol_ball() { 	double r; 	printf("请输入球的半径："); 	scanf("%lf",&r); 	return (4.0/3.0*PI*r*r*r); } #include "stdio.h" #define PI 3.1415926 double vol_cone() { 	double r,h; 	printf("请输入圆锥的底圆半径和高："); 	scanf("%lf%lf",&r,&h); 	return (PI*r*r*h/3.0); } #include "stdio.h" #define PI 3.1415926 double vol_cylind() { 	double r,h; 	printf("请输入圆柱的底圆半径和高："); 	scanf("%lf%lf",&r,&h); 	return (PI*r*r*h); }  我分成几个文件之后    程序运行之后算的体积不管输入任何半径值体积结果都是0。。。这是怎么回事

宏定义是不是让你们把π的值用宏来定义，比如 #define PAI (3.1415926) 文件包含的意思是不是将那几个计算函数放到另外的.c里面，并写一个.h，然后main单独写到一个.c里面，然后main去调用那几个.c里面的函数执行 我猜可能是这样

就是对你数据类型，重新定义一个新的类型（这样就实现一改全改，不用重复做很多事情）另外对你函数里面最终结果（面积，体积）用一个符号表示这个公式就好了。 文件包含，还在学习


Question: idea算法源码调试不成功，求大神啊！！！！

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

不懂啊！赵老师！在哪儿改啊！我是解密文件的时候到fopen那一步就卡主了

出错时中断下来，通过调用堆栈、变量窗口等观察分析原因 如果是代码逻辑有问题，建议单步跟踪程序运行分析原因


Question: 一个数学问题 · · ·

搜“四叉树”？

引用 2 楼 zhao4zhong1 的回复:计算几何大牛:http://www.codeproject.com/KB/recipes/Wykobi.aspx 赵四老师，感觉还是不太懂。。

在百度图片搜“四叉树”对应的链接。 你用鼠标左键多点几次感兴趣的图片，就会来到该图片所在的网页。 没准其中哪个就是论述如何使用四叉树实现二维碰撞检测的文章哟。

引用 9 楼 zhao4zhong1 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 u010202481 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 搜“四叉树”？  有人给我一个提示，叫“扫描线算法”····我可能需要研究下这个了。。[/quote] 这个远不如“四叉树”，相信我。[/quote] http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1464770068443_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E5%9B%9B%E5%8F%89%E6%A0%91[/quote]  我在碰撞检测中用了“扫描线算法”，感觉还是稍微有点慢，但是勉强可以。。但是这个计算临界边，就不知道效率怎么样了。。还有喔，这是什么链接喔。。

引用 8 楼 zhao4zhong1 的回复:[quote=引用 7 楼 u010202481 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 搜“四叉树”？  有人给我一个提示，叫“扫描线算法”····我可能需要研究下这个了。。[/quote] 这个远不如“四叉树”，相信我。[/quote] http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1464770068443_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E5%9B%9B%E5%8F%89%E6%A0%91

引用 7 楼 u010202481 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 搜“四叉树”？  有人给我一个提示，叫“扫描线算法”····我可能需要研究下这个了。。[/quote] 这个远不如“四叉树”，相信我。

引用 6 楼 zhao4zhong1 的回复:搜“四叉树”？  有人给我一个提示，叫“扫描线算法”····我可能需要研究下这个了。。

引用 2 楼 zhao4zhong1 的回复:计算几何大牛:http://www.codeproject.com/KB/recipes/Wykobi.aspx  谢谢赵4老师~很有用。

引用 1 楼 user-2 的回复:每个多边形，以他的中心，表示 在中心左右某个范围内的计算，其他不计算 这可以先用　Ｘ,Y 坐标分别排序 谢谢你的回答喔，我试了这种方式，感觉针对图形比较多的情况，还是有点慢，甚至有的好几分钟。我再想想看，谢谢你~


Question: 关于字符串数组的问题，求帮助！！！

引用 5 楼 paschen 的回复:[quote=引用 4 楼 edenluck 的回复:] [quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 edenluck 的回复:] [quote=引用 1 楼 user-2 的回复:] lithdata[i].sand中sand本身也是一个数组？如果是的话，那么p应该定义为二重指针，这样p[i]才是一个指针，才能将sand直接赋值给p[i]sand是这样的char sand【256】，是我在结构体里面定义的。 那应该怎么定义呢？二重指针是 char**p;p[i] = lithdata[i].sand;这样吗？[/quote]  char**p后要为每个指针分配内存，然后再让指针指向数据[/quote] 能写下代码给我参考下吗？新手不会啊[/quote]  p=(char**)malloc(n*sizeof(char*));  //n是你指针的数量[/quote]十分感谢！！！

引用 4 楼 edenluck 的回复:[quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 edenluck 的回复:] [quote=引用 1 楼 user-2 的回复:] lithdata[i].sand中sand本身也是一个数组？如果是的话，那么p应该定义为二重指针，这样p[i]才是一个指针，才能将sand直接赋值给p[i]sand是这样的char sand【256】，是我在结构体里面定义的。 那应该怎么定义呢？二重指针是 char**p;p[i] = lithdata[i].sand;这样吗？[/quote]  char**p后要为每个指针分配内存，然后再让指针指向数据[/quote] 能写下代码给我参考下吗？新手不会啊[/quote]  p=(char**)malloc(n*sizeof(char*));  //n是你指针的数量

引用 2 楼 edenluck 的回复:[quote=引用 1 楼 user-2 的回复:] lithdata[i].sand中sand本身也是一个数组？如果是的话，那么p应该定义为二重指针，这样p[i]才是一个指针，才能将sand直接赋值给p[i]sand是这样的char sand【256】，是我在结构体里面定义的。 那应该怎么定义呢？二重指针是 char**p;p[i] = lithdata[i].sand;这样吗？[/quote]  char**p后要为每个指针分配内存，然后再让指针指向数据

引用 3 楼 paschen 的回复:[quote=引用 2 楼 edenluck 的回复:] [quote=引用 1 楼 user-2 的回复:] lithdata[i].sand中sand本身也是一个数组？如果是的话，那么p应该定义为二重指针，这样p[i]才是一个指针，才能将sand直接赋值给p[i]sand是这样的char sand【256】，是我在结构体里面定义的。 那应该怎么定义呢？二重指针是 char**p;p[i] = lithdata[i].sand;这样吗？[/quote]  char**p后要为每个指针分配内存，然后再让指针指向数据[/quote] 能写下代码给我参考下吗？新手不会啊

引用 1 楼 user-2 的回复:lithdata[i].sand中sand本身也是一个数组？如果是的话，那么p应该定义为二重指针，这样p[i]才是一个指针，才能将sand直接赋值给p[i]sand是这样的char sand【256】，是我在结构体里面定义的。 那应该怎么定义呢？二重指针是 char**p;p[i] = lithdata[i].sand;这样吗？


Question: char *str与*str的区别

char *str=NULL; 是在声明变量，并初始化为NULL，变量类型是char*类型， 这里*是代表是指针类型  *str=NULL  这里的*解引指针，也就是说让指针提向的值赋值为NULL  两处的*不是同一个意思

有请赵老湿，在这个问题上，我同意赵老湿的汇编说法。

引用 3 楼 ghx287524027 的回复:首先，char str[100]={0};初始化只是将str[0]初始化了，其余元素并没有初始化。另外，在C语言中，NULL是宏定义的空指针，虽然其值在某种意义上是零，但它是指针类型，所以*str=NULL;在类型上是不一致的，所以会报错，正确的应该是str=NULL;  你啥地方见过给数组赋值NULL这种用法？c++里面有么？ 千万不要不确定的情况下误导人  实际测试一下就知道 char test[20]; test = NULL; 编译结果：error: incompatible types when assigning to type ‘char[20]’ from type ‘void *’  在c里面，数组初始化，一般来说就是示例中的赋值0，或者memset为0，从来不可能出现NULL的用法，NULL一般只能给指针赋值，如 char *test = NULL;或者 char *test;test = NULL; 楼主对指针还是不太明白，需要再去看看教材。*test表明的是test指向的内容了，那么如果执行 *test = NULL;那么会给你一个警告，warning: assignment makes integer from pointer without a cast，test是指针，NULL是指针，而*test指的是内容 比如   int x = 12; int *p; p = NULL; *p = 12; p = &x;  自己装个编译环境，对不明白的代码进行直接编译运行测试，对警告和错误进行分析，可以找到问题的原因。

引用 3 楼 ghx287524027 的回复:首先，char str[100]={0};初始化只是将str[0]初始化了，其余元素并没有初始化。另外，在C语言中，NULL是宏定义的空指针，虽然其值在某种意义上是零，但它是指针类型，所以*str=NULL;在类型上是不一致的，所以会报错，正确的应该是str=NULL;  char str[100] = {0}; 会将 str 的全部元素初始化为 0 。  数组不是指针，不能被赋值，给数组赋值（str = NULL） 是错误的。

char str[100]={0}; 这是在栈上分配了100个char内存，所以可以往这里面写东西 //char *str=NULL; 这个就一个指针，没分配内存，试图往它指向的内存写东西自然就挂了

谢谢楼上各位的解答，小弟受教了。

NULL是指针类型

char str[100]; *str=NULL; 等价于 char str[100]; str[0]=NULL;  C++中, NULL一般就是0，这句一般合法，C中NULL一般是 (void*)0，这就不行了， 怎能将指针付给char类型的数据呢


Question: c语言写停车场管理系统，计算停车时间运行结果比实际值大0.01，求大神解答！急！谢谢！（代码在下边儿）

浮点数一般是有误差的。想要准确表示，就全用整数

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


Question: 大神看看这个拆分英文名的代码，为什么可以输出字母序号呀，什么原理

因为a-z的ascii码是顺序排列的，a-'a' 、 b-'a' 就是在获得他们距离字母a的距离，也就是序号

因为 小写字母a~z,大写字母 A~Z 在 ASCII是顺序编码的


Question: 求助啊  不知道哪里错了

引用 2 楼 xigua1102 的回复:是基础没学好还是怎么的，乱写的么 仔细看看代码  void stationinit(carstation s) 这个参数是什么，s.top=0; 看你里面怎么用的  定义一个 carstation fhh;这样定义，fhh已经有存储空间了， Arrive(carstation *s) 里面，你又去申请空间，是个什么鬼    初学者。。 懂了！  谢谢

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

void stationinit(carstation s)  改成  void stationinit(carstation &s)


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

顶一下  露个脸。。

散分是怎么个意思

顶一下，正在学习这方面的知识

我前几天听了赵老师的课 感觉用工具来分析更能理解程序的内部运行 我是程序小白 完全是爱好 把学习程序当成打麻将一样的娱乐 没指望学得多好 就是别人说话听得懂就行

平时没时间.只有等上传完了再看.

老师，还只自学到函数这一章，可否听课？

欢迎来评价： http://edu.csdn.net/course/comment/2344

那我就报名了！老师收下我的膝盖。

引用 51 楼 qcx1221 的回复:老师，还只自学到函数这一章，可否听课？ 听了总没坏处，我觉得。

顶一顶。。。

不明觉厉。。。

刚看了一遍第一次课的录像。 里面既没萝莉，也没大叔！

引用 43 楼 user-15 的回复:蹭点分，赵老师记得及时结贴.......... 怎么也得等到课讲完以后再结贴吧。

已经报名第二期了！！！

刚看到这个帖子，先把（1）看下，再来看（2）…… 看了视频才知道赵老师的大名……

蹭点分，赵老师记得及时结贴..........


Question: 二叉树的中序非递归遍历

感谢各位    问题已搞定

引用 2 楼 user-3 的回复:把 if(p!=NULL)｛。。。｝ 替换成 if(p==NULL)printf(" "); else { 。。。 }  能不能说清楚点 怎么改啊

@user-3 @小灸舞    感谢回答      不过我想知道有没有以空格来代替空树的非递归遍历方法  谢谢

#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }   typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }   void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;       setlocale(LC_ALL,"chs");     CreateBiTree(T);       printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");       return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //   ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G   单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

CBEGDFA 这个是它的中序遍历结果


Question: 求用C语言编写的爱心

#include <conio.h> #include <stdlib.h> int main() {  system("chcp 437 >NUL&cls");  cprintf("%c",3);  getch();  return 0; }

引用 4 楼 pkuzhx的回复:赵老师太坏了 ？？？？？？？？？？？？？？？？

赵老师太坏了

#include <conio.h> #include <stdlib.h> int main() {  system("chcp 437");  cprintf("%c",3);  getch(); }


Question: 怎么修改？

strcpy_s 比strcpy要多一个参数，用来确定缓冲区的大小  参看：https://msdn.microsoft.com/zh-cn/library/td1esda9.aspx

strcpy_s(qwords[i], SIZE, temp);

或者直接用2个参数的用法 两个参数时： errno_t strcpy_s( char (&strDestination)[size], const char *strSource ); // C++ on

strcpy_s的用法是：  errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );  第2个参数才是size.

函数参数写反了 看定义 errno_t strcpy_s(char *strDestination,size_t numberOfElements,const char *strSource);


Question: 一个纯C程序，在vc里面运行正常，但gcc下面变异后执行总是提示段错误

1、打开core：ulimit -c unlimited 2、gdb core

呃，不说了，GDB吧

你VC下是debug版？

gdb调试一下，看段错误出现在哪里～

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

通常都是内存错误。vc的debug内存会有一些空间用来debug,访问越界也不会死掉。gcc没有，访问越界就死掉了。

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

为什么不用gdb dump一下看看呢。 先设置 ulimit -c unlimited  然后用gdb [exec file] [core file]


Question: 请教一个C语言问题！

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

scanf如果输入成功有一个返回值，输入错误也会有一个返回值，可以定义int a=scanf(。。。)查看返回值。

～是按位取反，scanf对返回值的操作； EOF是-1，按位取反就是0了；

关键你要弄懂scanf返回值的意思，表示的成功接收到的数目，如果失败，返回的是EOF，也就是0xFFFFFFFF，这个值取反以后就是0  参看：http://en.cppreference.com/w/c/io/fscanf

引用 4楼列子汤问 的回复:scanf的返回值是 输入变量的个数。 如果输入了a和b那么就返回2. ~scanf()，就是没有得到正确输入 总体上就是，如果有正确输入，就退出循环，如果没有正确输入，就执行循环，一直取值。明白了 谢谢！

引用 3楼shabby0104 的回复:scanf这个函数是有返回值的，返回时参数的个数。 ~是按位取反 while后面括号里只要非0就会一直循环，除非break 这句话的意思的是只要有输入就会一直循环下去谢谢！

引用 1楼小灸舞 的回复:scanf的返回值是接收到的变量值的个数 而~是位运算，取反能在解释清楚点吗谢谢！

scanf的返回值是接收到的变量值的个数 而~是位运算，取反


Question: C语言的一段代码请大神解释一下

x几乎为0吧，怎可能大于 limit呢，所以while条件为假呀，不会执行循环体的

#include <limits.h> 头文件  然后是在VS里面运行

为什么我设置监视之后 这个n无论怎样值都是0啊


Question: C语言有time人控件吗

boost库。里面有time库

如果sleep不可用，那就在主线程的循环里面加个static变量，保存上一次开始的时间，获取当前时间，相减的值超过倒计时间，则触发，并且将变量重置为当前时间。  如果有多线程，在其它线程写个死循环做这个操作。 如果是单片机，就要考虑计数触为器之类的。  c语言没有timer控件，这些东西都应该是操作系统提供的。和语言无关。

再供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h>     #include <process.h>     #define  MYVOID             void #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define ARRSIZE(x) (sizeof(x)/sizeof(x[0])) #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; char logstr[16000]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;       if (NULL==pszFmt||0==pszFmt[0]) return;     if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }             flog=fopen(logfilename1,"a");             if (NULL==flog) return;         }         fclose(flog);     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int No_Loop=0; MYVOID testThread(void *pcn) {     int n,i;      n=(int)pcn;     i=0;     while (1) {         sleep_ms(1000);         Log("in testThread %d:i==%ds\n",n,++i);         if (i>=5) No_Loop=1;     } } int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL);     pthread_t threads[1];     int threadsN;     int rc; #endif     Log("=========BEGIN==================\n"); #ifdef WIN32     _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif     i=0;     while (1) {         sleep_ms(100);         Log("in main:i==%d\n",++i);         if (No_Loop==1) break;//     }     Log("=========END====================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //2012-06-14 16:27:21.500 =========BEGIN================== //2012-06-14 16:27:21.609 in main:i==1 //2012-06-14 16:27:21.718 in main:i==2 //2012-06-14 16:27:21.828 in main:i==3 //2012-06-14 16:27:21.937 in main:i==4 //2012-06-14 16:27:22.046 in main:i==5 //2012-06-14 16:27:22.156 in main:i==6 //2012-06-14 16:27:22.265 in main:i==7 //2012-06-14 16:27:22.375 in main:i==8 //2012-06-14 16:27:22.484 in main:i==9 //2012-06-14 16:27:22.500 in testThread 1:i==1s //2012-06-14 16:27:22.593 in main:i==10 //2012-06-14 16:27:22.703 in main:i==11 //2012-06-14 16:27:22.812 in main:i==12 //2012-06-14 16:27:22.921 in main:i==13 //2012-06-14 16:27:23.031 in main:i==14 //2012-06-14 16:27:23.140 in main:i==15 //2012-06-14 16:27:23.250 in main:i==16 //2012-06-14 16:27:23.359 in main:i==17 //2012-06-14 16:27:23.468 in main:i==18 //2012-06-14 16:27:23.500 in testThread 1:i==2s //2012-06-14 16:27:23.578 in main:i==19 //2012-06-14 16:27:23.687 in main:i==20 //2012-06-14 16:27:23.796 in main:i==21 //2012-06-14 16:27:23.906 in main:i==22 //2012-06-14 16:27:24.015 in main:i==23 //2012-06-14 16:27:24.125 in main:i==24 //2012-06-14 16:27:24.234 in main:i==25 //2012-06-14 16:27:24.343 in main:i==26 //2012-06-14 16:27:24.453 in main:i==27 //2012-06-14 16:27:24.500 in testThread 1:i==3s //2012-06-14 16:27:24.562 in main:i==28 //2012-06-14 16:27:24.671 in main:i==29 //2012-06-14 16:27:24.781 in main:i==30 //2012-06-14 16:27:24.890 in main:i==31 //2012-06-14 16:27:25.000 in main:i==32 //2012-06-14 16:27:25.109 in main:i==33 //2012-06-14 16:27:25.218 in main:i==34 //2012-06-14 16:27:25.328 in main:i==35 //2012-06-14 16:27:25.437 in main:i==36 //2012-06-14 16:27:25.500 in testThread 1:i==4s //2012-06-14 16:27:25.546 in main:i==37 //2012-06-14 16:27:25.656 in main:i==38 //2012-06-14 16:27:25.765 in main:i==39 //2012-06-14 16:27:25.875 in main:i==40 //2012-06-14 16:27:25.984 in main:i==41 //2012-06-14 16:27:26.093 in main:i==42 //2012-06-14 16:27:26.203 in main:i==43 //2012-06-14 16:27:26.312 in main:i==44 //2012-06-14 16:27:26.421 in main:i==45 //2012-06-14 16:27:26.500 in testThread 1:i==5s //2012-06-14 16:27:26.531 in main:i==46 //2012-06-14 16:27:26.531 =========END====================

仅供参考：#pragma comment(lib,"user32") #include <stdio.h> #include <time.h> #include <sys/timeb.h> #include <windows.h> char datestr[16]; char timestr[16]; char mss[4]; void log(char *s) {     struct tm *now;     struct timeb tb;      ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,s); } VOID CALLBACK myTimerProc1(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc1\n"); } VOID CALLBACK myTimerProc2(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc2\n"); } int main() {     int i;     MSG msg;      SetTimer(NULL,0,1000,myTimerProc1);     SetTimer(NULL,0,2000,myTimerProc2);     for (i=0;i<20;i++) {         Sleep(500);         log("In main\n");         if (GetMessage(&msg,NULL,0,0)) {             TranslateMessage(&msg);             DispatchMessage(&msg);         }      }     return 0; } //2012-07-26 17:29:06.375 In main //2012-07-26 17:29:06.875 In myTimerProc1 //2012-07-26 17:29:07.375 In main //2012-07-26 17:29:07.875 In myTimerProc2 //2012-07-26 17:29:08.375 In main //2012-07-26 17:29:08.375 In myTimerProc1 //2012-07-26 17:29:08.875 In main //2012-07-26 17:29:08.875 In myTimerProc1 //2012-07-26 17:29:09.375 In main //2012-07-26 17:29:09.890 In myTimerProc2 //2012-07-26 17:29:10.390 In main //2012-07-26 17:29:10.390 In myTimerProc1 //2012-07-26 17:29:10.890 In main //2012-07-26 17:29:10.890 In myTimerProc1 //2012-07-26 17:29:11.390 In main //2012-07-26 17:29:11.890 In myTimerProc2 //2012-07-26 17:29:12.390 In main //2012-07-26 17:29:12.390 In myTimerProc1 //2012-07-26 17:29:12.890 In main //2012-07-26 17:29:12.890 In myTimerProc1 //2012-07-26 17:29:13.390 In main //2012-07-26 17:29:13.890 In myTimerProc2 //2012-07-26 17:29:14.390 In main //2012-07-26 17:29:14.390 In myTimerProc1 //2012-07-26 17:29:14.890 In main //2012-07-26 17:29:14.890 In myTimerProc1 //2012-07-26 17:29:15.390 In main //2012-07-26 17:29:15.890 In myTimerProc2 //2012-07-26 17:29:16.390 In main //2012-07-26 17:29:16.390 In myTimerProc1 //2012-07-26 17:29:16.890 In main //2012-07-26 17:29:16.890 In myTimerProc1 //2012-07-26 17:29:17.390 In main //2012-07-26 17:29:17.890 In myTimerProc2 //2012-07-26 17:29:18.390 In main //2012-07-26 17:29:18.390 In myTimerProc1 //2012-07-26 17:29:18.890 In main //2012-07-26 17:29:18.890 In myTimerProc1 //2012-07-26 17:29:19.390 In main //2012-07-26 17:29:19.890 In myTimerProc2

windows下用settimer api函数,linux用信号


Question: 求助!vs2010编写C语言时出现错误.

引用 2 楼 小灸舞的回复:楼主你少了个p=吧  #include <stdio.h> #include <memory.h> #include<string.h> #include <malloc.h> #include <stdlib.h> void main(){ 	struct stu{ 		int num; 		char *name; 		char sex; 		float scorce; 	} *p;   	p = (struct stu*) malloc(sizeof(struct stu)); 	p->num =100; 	p->name="xuNiu"; 	p->sex='n'; 	p->scorce=45.3; 	printf("name=%c\nnumber=%d\n",p->name,p->num); 	printf("sex=%c\nscore=%f\n",p->sex,p->scorce); 	free(p);   }  嗯，刚才没找出来，谢谢了！

引用 1 楼 user-2的回复:p = (struct stu*) malloc(sizeof(struct stu));  p->num =100;  p->name="xuNiu"; 不好意思，这么简单错误没看出来，谢谢了！


Question: 为什么改这里sizeof（buf-1）会是输出三个字符

谢谢大神们.

我建议你这辈子不用sizeof，丝毫不会妨碍你成为IT大神。

你这个写法相当于是buf数组下标为-1的地址。 楼主sizeof(buf-1)就知道是4，被当作了指针，所以输出了3个字符 数组下标为-1的地址对于数组来说是越界访问了，但是这个地址是有意义的  这个地址就是所申请的数组存储空间的首地址的向前偏移一个单位(也就是偏移一个当前数组类型所对应的字节数)所对应的地址。  这个地址由于没有跟着数组空间一起初始化， 所以其中的数据是不一定的， 如果是正在被系统或者其他APP使用中的地址空间，那么可以被访问，其中的数据的意义取决于被系统或者其他APP所写入的数据，但是访问后，有可能会引起系统或者其他APP异常。 如果是没有被使用的地址，那么就是一个野地址，那么其中的数据是随机的，无意义的

sizeof(buf)是求数组的大小是1024. buf-1时buf退化为char*，所以sizeof(buf-1)是救char*指针的大小是4，或许是留1位终止符，所以只能显示3个字符了吧. 你是想sizeof(buf)-1吧。


Question: KMP算法问题

引用 6 楼 u010370871 的回复:距离上次手写这个算法过去已经很久了帮我看下嘛，找不出来错误。。。

距离上次手写这个算法过去已经很久了

第二个函数应该是错的，但是代码贴的让人看不下去，如果你还是找不到bug，就对比一下模板http://blog.csdn.net/huatian5/article/details/51307735

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

单步跟踪程序运行过程来分析原因

kmp http://blog.csdn.net/zhangxiangdavaid/article/details/35569257

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


Question: 一个关于Windows日志提取的代码，求怎么修改

引用 6 楼 luciferisnotsatan 的回复:除了ofstream这个用于输出的流外，其它都是C的代码。改成C，只要把相关地方改成fopen，fwrite就行了。如果不会，请去复习下C语言  大神，现在和没学过没啥区别了，能不能教我改成直接可以运行的形式，现在毕设就差这个程序了。。。

引用 6 楼 luciferisnotsatan 的回复:除了ofstream这个用于输出的流外，其它都是C的代码。改成C，只要把相关地方改成fopen，fwrite就行了。如果不会，请去复习下C语言谢谢我试一下

Event Logging Functions The following functions are used with event logging.        BackupEventLog   ClearEventLog   CloseEventLog   DeregisterEventSource   GetNumberOfEventLogRecords   GetOldestEventLogRecord   NotifyChangeEventLog   OpenBackupEventLog   OpenEventLog   ReadEventLog   RegisterEventSource   ReportEvent

不太会用。。请问有这种读取日志的C语言代码吗

这个软件似乎有命令行接口。

引用 楼主 baidu_35012751 的回复:是在一篇论文上看到的，本人小白不会在VC6.0下实现，求大神帮忙改改~~ 这个软件倒是有，只是想 搞清楚怎么在VC6.0下实现这段代码~

这个软件倒是有，只是想 搞清楚怎么在VC6.0下实现这段代码~


Question: 求助，为什么运行没有结果

#include<stdio.h>  void main() { 	int i=1,j=0; 	printf("以下的数据能同时被2，3，7整除：\n"); 	while(i<=1000) 	{ 		if(i%(2*3*7)==0) 		{printf("%d\n",i); 		   j++;	} 		   i++; 	} 	printf("%d",j); }

因为当不满足if的时候，i不会递增，下次依然不满足    #include<stdio.h> void main() { 	int i=1,j=0; 	printf("以下数据能同时被2,3,7整除:\n"); 	while(i<=1000) 	{ 		if(i%(2*3*7)==0) 			printf("%d",i),j++,i++; 		else 			i++; 	} 	printf("共有%d个",j); }

因为i++放在if语句里，只有当i%（2*3*7）==0时才自增，否则i永远为1，而1%（2*3*7）始终为1，if结果始终为假，所以i始终没有自增。

#include <stdio.h> #include<stdio.h>  void main()  {  int i=1,j=0;  printf("以下数据能同时被2,3,7整除:\n");  while(i<=1000)  { 	 if(i%(2*3*7)==0){ 		printf("%5d",i),j++; 	 } 	 i++;  }  printf("共有%d个",j);  }   i++不应该在if语句中

#include<stdio.h> void main() { int i=1,j=0; printf("以下数据能同时被2,3,7整除:\n"); while(i<=1000) { if(i%(2*3*7)==0) {   printf("%d\n",i);    j++; }   i++; } printf("共有%d个",j); } 注意一下执行顺序就好了

问题解决了吗?


Question: 关于大顶堆的疑问

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？

楼主的理解是正确的。题目自己都矛盾呢，从其说明里面看，下标 i 是要 >=1 的，后面写实现的时候，又把 [0] 用了。

文字说明中，下标编号，不是C 语言的这种从0开始的 然而，程序是用C,C++ 编码实现的，下标是从0开始的。 大概是这样吧，有点不够严谨了


Question: 关于localtime(&timep)取时间计算的问题求帮助解决

http://en.cppreference.com/w/c/chrono/localtime  里面说到了：1) pointer to a static internal tm object on success, or null pointer otherwise. The structure may be shared between gmtime, localtime, and ctime and may be overwritten on each invocation.  就是你下一次获取时间会改变共享的那个变量值  解决办法可以返回tm，而不是指针：  tm TIME() { 	time_t timep; 	struct tm *p; 	time(&timep); 	p=localtime(&timep); 	return p; } tm tim1; tm tim2; 先取tim1=TIME(); 再取tim2=TIME();

如果单纯求两个时间差，不需要localtime，time(&tm1) - time(&tm2); 如果要获取开始时间和结束时间，建议用struct tm变量，而不是用指针；

因为你保存的是获取时间的指针，再下车过去时间后会更新指针指向的内容，因此你必须每次都保存时间值而不是指向它的指针


Question: 为什么会终止程序！求解啊

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

你这是数组越界导致的，程序退出的时候会报异常 你把int a[3][4];改为int a[4][4];就行

老老实实这样写试下 a[i][j]

一堆星号，内存溢出啦。

写那一堆星号就是故意想出错


Question: 请各位大神指点迷经!!!!

分隔符会进入缓冲区。 忽略掉的空格、回车和tab会从缓冲区消失  scanf("%c%d",&b,&num3);这句，你输入a 5然后回车 a和5之间的空格会从缓冲区被匹配走而消失，而回车符是不会的（还留在输入缓冲区）

因为%c不能自动跳过输入缓冲区中之前遗留的一个或多个连续的空白字符（\n,\t,空格） %1s可以。

引用 2 楼 zhao4zhong1 的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; //老师你改成这样看不懂啊，你定义整形数据变量，从键盘输入字符，变量能接收到吗？？？

老师好，请问为什么要这么改啊？ //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];


Question: 求解一个C语言题

你还是自己看看书查查资料写一个吧，我以前也是伸手党，但是发现伸手党的日子不好过，还是靠自己来的踏实和舒心，加油吧


Question: 求大神帮忙

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

指针操作完全不对  #include <stdio.h> #include <string.h> #include <stdlib.h>  typedef struct node { 	int a[10]; 	int length; }SeqList, *PSeqList;  void Delete(PSeqList PL, int x, int y) { 	int i, j=0;  	for(i=0; i< PL->length; i++) 	{ 		if (PL->a[i]>x && PL->a[i]<y)  		{ 			j++; //			printf("found match a[%d]=%d, j=%d\n", i, PL->a[i], j); 		} 		else 		{ 			int count = PL->length-i-1; //printf("count=%d\n", count); 			PL->length--; 			if (count > 0) { 				memmove(&PL->a[i], &PL->a[i+1], sizeof(int)*count); 				i--; 			} 		} 	} }  int main(void) { 	int k; 	PSeqList PL; 	int a[10] = {2,4,3,67,35,89,233,23232,2332,23323};  	 	PL=(PSeqList)malloc(sizeof(SeqList)); 	memcpy(PL->a, a, sizeof(a)); 	PL->length = 10; 	 	Delete(PL, PL->a[0], PL->a[3]); 	 	for(k = 0; k < PL->length; k++) 	{ 		printf("%d  ",PL->a[k]); 	} }


Question: 为什么打印不出来呢

引用 2 楼 qq_34973450 的回复:[quote=引用 1 楼 赵4老师的回复:]for(i=7;i>=1;i--) 抱歉，一时脑子断片[/quote] 脑子断片的时候，放下手头的代码，去腐败一下。

引用 1 楼 赵4老师的回复:for(i=7;i>=1;i--) 抱歉，一时脑子断片


Question: 关于MIB结构体的问题，请大家赐教

引用 3 楼 asdger 的回复:下面有比较详细的解释： http://blog.sina.com.cn/s/blog_615ec1630101kq1s.html  不是结构体转换，是指针类型转换

引用 1 楼 user-1 的回复:指针类型转换 和普通的数据类型转换一样吗？

指针类型转换


Question: 自己写的图片浏览器怎么实现右键点击启动并打开一张图片？

搜“Shell Extension”

引用 1 楼 u010165006 的回复:如果是C语言： int main(int argc,char *argv[]) 可以得到参数argv[1]，就是要打开的那个文件名。  MFC不清楚，C++ Builder会知道。  int APIENTRY WinMain(HINSTANCE hInstance, 		HINSTANCE hPrevInstance, 		LPSTR     lpCmdLine, 		int       nCmdShow) 第三个参数就是..居然忘了 直接把图片拖过去可以，但按照图上面选 不行..


Question: 一道关于大顶堆的C语言题目

hello，顶一个。。。。

hello，顶一个


Question: c指针作为地址使用

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

引用 4 楼 自信男孩的回复:在32位系统里，指针变量都是占4个字节；但是不同的指针类型，其指向的内存区域大小一样；比如，char类型的指针，在对其引用时，读取到的数值是一个字节的大小；若是int类型的指针变量，在对其引用时，读取道德数值是4个字节的大小；结构体指针，读取的是结构体大小的区域； 在32位系统里，指针变量都是占4个字节；但是不同的指针类型，其指向的内存区域大小一样；比如，char类型的指针，在对其引用时，读取到的数值是一个字节的大小；若是int类型的指针变量，在对其引用时，读取道德数值是4个字节的大小；结构体指针，读取的是结构体大小的区域；<br />  不好意思，没明白您的意思，既然指向的内存区域大小一样，为什么char类型是一个字节，int又是4个字节呢？谢谢！

是不是可以这样理解，指针所指向的类型比如说char类型的，系统会将这个指针指向该类型，并将这一个字节之后的内存空间留给其它变量。如果指向int类型（假设为2个字节），系统会将指针指向的地址的2个字节留给该指针，其后的空间留给其它变量。 或者说指针变量有些类似数组有长度（隐含的），这个隐含的长度就是指针的类型（char，int等），而指针变量的值将是其首地址。 不知道这样理解对不对？ 谢谢大家！

不管什么指针，在x86平台，都占用4byte. 所以指针的类型只是给编码的人阅读理解的。 其本质上都是一个32位长度的ulong. 无论什么类型的指针变量，在内存中本质上都是一样的，都是一个整数值的地址值；而这个不同的类型仅仅是向系统说明该变量在内存中占据字节的数目，如：字符型的指针变量在内存中占据一个字节、一个整形的指针变量在内存中占据四个字节等等。

sizeof(BYTE*), 就会发现不止1，指针本身占的空间和指向的类型无关，是和硬件本身有关的数据


Question: 请教C语言数据结构中的问题

引用 3 楼 user-1 的回复:简单地说，就是看着前面！  typedef struct { int data; struct node *next;  解析器解析到这里的时候，还不知道struct node是啥，因为前面没有申明。哦哦，懂了

引用 1 楼 user-1 的回复:typedef struct node { int data; struct node *next; }node;  试试没问题了，谢谢啊，但这是什么原因呢


Question: 在字符串中查找检索多个关键词（子串）比较好的方法

这是在做全文检索么..

谈及字符串的匹配问题的话，就不得不说字符串里面的算法了，当然本人还不熟练。 可以像楼主说的一一进行匹配，但是这种方法太麻烦，时间复杂度还高，优化后的KMP算法和ac自动机和后缀数组都很好用，当然这些算法不是很简单的。如果楼主不是搞算法的，建议稍微接触一下KMP算法就好了，这种方法毕竟使用简单点。

每次查找时不要都从头查找，必要时记录strstr返回值，从上一次查找到的位置继续查找

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


Question: 注释到只剩下main.c的return 0;还是报错,不把头文件移除就不行请问要怎么解决

引用 4 楼 qq423399099 的回复:如果用的是ide的话重新创建工程试试 还是不行呢... 试过重置默认,调过toolchain executable的,  引用 10 楼 zhao4zhong1 的回复:项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 并不是这个问题呢

已经解决了 是因为我在工程头文件的option处点了link和complie 不管怎样,感谢各位的回答

项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项

附加包含目录错误。我猜

引用 5 楼 zhao4zhong1 的回复:附加包含目录错误。我猜 错误显示为 -------------- Build: Debug in queue (compiler: GNU GCC Compiler)---------------  gcc.exe  -o bin\Debug\queue.exe C:\Users\DEREK\Desktop\duilie\bigline.h.gch obj\Debug\C\Users\DEREK\Desktop\duilie\budaitou.o obj\Debug\C\Users\DEREK\Desktop\duilie\daitou.o obj\Debug\C\Users\DEREK\Desktop\duilie\main.o obj\Debug\C\Users\DEREK\Desktop\duilie\port.o obj\Debug\C\Users\DEREK\Desktop\duilie\xunhuan.o    C:\Users\DEREK\Desktop\duilie\bigline.h.gch: file not recognized: File format not recognized collect2.exe: error: ld returned 1 exit status Process terminated with status 1 (0 minute(s), 0 second(s)) 0 error(s), 0 warning(s) (0 minute(s), 0 second(s)) 是您说的路径问题吗?

如果用的是ide的话重新创建工程试试

把编译命令贴出来或者代码贴出来

这是什么文件夹不存在的意思？查看代码是否有写错路径

代码比较长不方便贴出来,注释了依然出错可能不是代码本身的问题? 现在Bulid 上的错误是把注释去掉之后的结果 好像是路径方面的问题,不大熟悉,请大家继续指点

更换ide版本之后点击构建,在build message处不报错 但是在Bulid log 处显示以下错误   -------------- Build: Debug in queue (compiler: GNU GCC Compiler)---------------  gcc.exe  -o bin\Debug\queue.exe C:\Users\DEREK\Desktop\duilie\bigline.h.gch obj\Debug\C\Users\DEREK\Desktop\duilie\budaitou.o obj\Debug\C\Users\DEREK\Desktop\duilie\daitou.o obj\Debug\C\Users\DEREK\Desktop\duilie\main.o obj\Debug\C\Users\DEREK\Desktop\duilie\port.o obj\Debug\C\Users\DEREK\Desktop\duilie\xunhuan.o    C:\Users\DEREK\Desktop\duilie\bigline.h.gch: file not recognized: File format not recognized collect2.exe: error: ld returned 1 exit status Process terminated with status 1 (0 minute(s), 0 second(s)) 0 error(s), 0 warning(s) (0 minute(s), 0 second(s))


Question: 用VC创建二叉树，感觉思路和代码都是对的，为什么总实现不了

创建二叉树有问题,死循环  int CreateBiTree(BiTree &T) { 	char ch; 	ch = getchar(); 	fflush(stdin);/////////////////////del enter in stdin buff, only work in VC 	if(ch==' ') { 		T = NULL; 		return 0; /////////////////////need a end 	} 	else { 		if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) exit(0); 		T->data = ch; 		if (CreateBiTree(T->lchild) == 0) { //check end 			T->rchild = NULL; 			return 0; 		} 		if (CreateBiTree(T->rchild) == 0) { //check end 			return 0; 		}  	} 	 	return 1; }


Question: 请指导一个c语言题，谢谢

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> //isalpha   const int N = 21;  int main(void)  { 	 char num[N]; 	 gets(num); 	  	 int a = strlen(num); 	 if (a < 1) { 	 	printf("error\n"); 	 	return -1; 	 } 	 for (int b = 0; b < a; b++) // not a-1 	 { 	 	if (!isalpha(num[b])) { //not a-z or A-Z 	 		printf("error\n"); 	 		return -1; 		 } 	 	num[b] = num[b] + 4; 	 } 	 puts(num); 	  	 //pause 	 getchar();  }

懂了，谢谢

上面的两处{return -1}没怎么懂


Question: 为什么我运行程序之后会停止工作？是溢出了吗？

引用 12 楼 zhao4zhong1 的回复:在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 十分感谢，你的回答对我很有帮助，之前只是拿C语言做一些数值计算类的，现在还需要继续学习。

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

加几个输出语句排查一下程序是在哪块停止的

引用 4 楼 sds428 的回复:我也是新手，学习中，呵呵，不知道可否，malloc，或，new，那东西在堆中吧，可以搞的很大的，或，全局的呢，具体我也不清楚了，共同学习 我再试试

引用 6 楼 wenpinglaoyao 的回复:楼主，我不明白您的程序代码是怎么通过编译的。比如，在第36行的代码【double  C[numx][numy][numz];】这块，在栈上声明一个数组时，数组的大小应该是编译期就能确定的啊，但您代码里面的numx等明显不是常量啊，怎么可能编译通过呢？ 这样子在vc上的确编译不通过，但是在codeblocks上是可以编译通过的。

引用 5 楼 user-6 的回复:出错时点中断，通过调用堆栈、变量窗口等观察分析出错原因，必要时单步跟踪程序运行，特别注意检查是否越界 好，我再试试

double  C[numx][numy][numz];中8*100*100*100是不是有点大了，是约8M空间吗？（呵呵，不太清楚，是不是这样计算的）如是的话，局部变量申请这大，运行时，肯定过不了吧

引用 1 楼 sds428 的回复:刚放入vc6下跑了下，把类似于double  C[numx][numy][numz];这些改为double  C[100][100][100];等，就可以编译通过，但运行也会崩的，但把100改为10，20000改为20，就可以运行通过了， 谢谢，但是我需要的最小值就是100和20000，小一点的数值，我跑起来也会通过，那么这种情况是算溢出了吗？需要怎么改？我用的codeblocks,电脑win10 vc6不能运行。


Question: c语言文件输入输出问题，acm上一直通不过，求大神解答

不知道原题,按照你的思路搞得,你的描述有问题

引用 1 楼 lgbxyz 的回复: #include <ctype.h> #include <stdio.h> #include <string.h> #include <stdlib.h>  #define SIZE 100  void input(char * str,FILE * fp); char *sort( const char *str1,const char * str2);  int main(void) {     char *str1, *str2, *str3;     FILE *fp;          str1 = (char *)malloc(SIZE * sizeof(char));     str2 = (char *)malloc(SIZE * sizeof(char));  	//create file A      if((fp=fopen("A", "w"))!=NULL) {         input(str1, fp);         fclose(fp);    }//not close NULL        //create file B     if((fp=fopen("B", "w"))!=NULL) {        input(str2, fp);        fclose(fp);    }     	str3 = sort(str1, str2);     //整理  	if((fp=fopen("C","w"))!=NULL) { 		fputs(str3, fp);        //写入到C文件 		fclose(fp);   }     if((fp=fopen("A", "r"))!=NULL) {      	fgets(str1,SIZE, fp);   //从A中读取     	fclose(fp);     }     if((fp=fopen("B","r"))!=NULL) {         fgets(str2,SIZE,fp);    //从B中读取        	fclose(fp); 	} 	     if((fp=fopen("C","r"))!=NULL) {         fgets(str3,SIZE,fp);    //从C中读取        	fclose(fp);     }          printf("the content of file A:");   //显示    	puts(str1);free(str1); //////////////////////free string     printf("the content of file B:");     puts(str2);free(str2);//////////////////////free string     printf("the content of file C:");     puts(str3);free(str3);//////////////////////free string //    free(fp);  ///////////////////////////////do not free file desc     return 0; } void input(char * str,FILE * fp) { 	gets(str);  	fputs(str, fp); } char *sort(const char *str1, const char * str2) {     char * str3, temp;     int i,j,min;     str3 = (char *)malloc((strlen(str1) + strlen(str2) + 1));     str3 = strcpy(str3,str1);     str3 = strcat(str3,str2);          min = strlen(str3);     for(i = 0; i < min-1; i++) //bubble sort     {     	for (j = i+1; j < min; j++)      	{     		if (str3[i] > str3[j])     		{     			temp = str3[i];     			str3[i] = str3[j];     			str3[j] = temp; 			} 		} 	}     return str3; }      按照你的修改提交之后还是错误的

打开或关闭文件的if语句要加{} #include <ctype.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 100 void input(char * str,FILE * fp); char * sort( const char *str1,const char * str2); int main() {     char * str1,*str2,*str3;     FILE * fp;     str1=(char *)malloc(SIZE*sizeof(char));     str2=(char *)malloc(SIZE*sizeof(char));     if((fp=fopen("A.txt","w"))!=NULL){         input(str1,fp);     //读取第一行并写入到A文件         fclose(fp); 	}     if((fp=fopen("B.txt","w"))!=NULL){        input(str2,fp);        //读取第二行并写入到B文件        fclose(fp); 	}     str3=sort(str1,str2);     //整理     if((fp=fopen("C.txt","w"))!=NULL){        fputs(str3,fp);        //写入到C文件        fclose(fp); 	}    if((fp=fopen("A.txt","r"))!=NULL){         fgets(str1,SIZE,fp);   //从A中读取         fclose(fp); 	}     if((fp=fopen("B.txt","r"))!=NULL){         fgets(str2,SIZE,fp);    //从B中读取         fclose(fp); 	}     if((fp=fopen("C","r"))!=NULL){         fgets(str3,SIZE,fp);    //从C中读取         fclose(fp); 	}     printf("the content of file A:");   //显示     puts(str1);     printf("the content of file B:");     puts(str2);     printf("the content of file C:");     puts(str3);     free(fp);     return 0; } void input(char * str,FILE * fp) {       gets(str);     fputs(str,fp); } char * sort(const char *str1,const char * str2) {     char * str3,temp;     int i,j,min;     str3=(char *)malloc((strlen(str1)+strlen(str2)+1)*sizeof(char));     str3=strcpy(str3,str1);     str3=strcat(str3,str2);     for(i=0;i<strlen(str3);i++)     {         min=i;         for(j=i+1;j<strlen(str3);j++)         {            if(str3[min]>str3[j])             min=j;         }         temp=str3[i];         str3[i]=str3[min];         str3[min]=temp;     }     return str3; }


Question: C文件处理时出了个小BUG求帮忙！

多谢各位！已经解决！（文件问题）！

1   #include <stdio.h>                                                                                1 #include <ctype.h>     2 #include <string.h>     3       4 void  capitalization(FILE *p);     5       6 int main(void)     7 {     8     FILE *fp = fopen("1.txt", "r");     9     if (NULL == fp) {    10     |   fprintf(stderr, "Open %s Error", "1.txt");    11     |   return -1;    12     }    13     capitalization(fp);    14     return 0;    15 }    16      17      18      19      20 void  capitalization(FILE *p)    21 {    22     int i;    23     char array[100] = { 0 };    24     char str[100] = { 0 };    25      26     while (!feof(p))    27     {    28     |   fgets(array, sizeof(array), p); >> 29     |   for (i = 0; i < strlen(array); i++)    30     |   {    31     |   |   if ((isalpha(array[i])))    32     |   |   {    33     |   |   |   str[i] = toupper(array[i]);    34     |   |   }    35     |   else    36     |   {    37     |   |   str[i] = array[i];    38     |   }    39     }    40     printf("%s", str);    41     }    42 }   在Linux下测试了一下你的代码，没发现问题；我打开的文件里的数据要么是26个英文字符，要么是数字；可以将字母小写变大写，其他不变； 建议楼主查看一下要打开的文件；

点重试——中断，断下后通过调用堆栈、变量窗口观察分析原因

其实我也遇到过这个问题，可能是微软库的bug吧。isalpha((unsigned char)array[i])  应该就可以了。应该是你传入的字符有非ASCII字符，所以超过了127。由于MS的实现char是signed的。所以就整形提升以后就成了负数了。


Question: 一维数组与二维数组指针的区别

谢谢回复，你的推倒很精彩

int (*p)[3]=n;  这句话是定义了一个数组指针，并且将这个二维数组的首地址赋给指针，如果p+1就代表这个指针指向二维数组第二行的首地址，printf（“%d\n”,*p),为什么输出的是数组地址呢printf("%d\n",**p);才是输出的地址中的内容呢？，，，指针p是指向一个数组，如果一个*就是取出数组第一行首地址，再加一个*就是取出内容。   而一位数组中printf("%d\n",*pn);输出的确实地址中的内容？，，，因为pn是一个指向一维数组的指针，所以pn和n差不多，只不过n是一个常量指针，不能改变指向，但是pn可以改变指向，a[1]-----*(a+1)  两者一样，数组形式只不过是编译器做了优化

理解和讨论之前请先学会如何观察！  //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

二维数组： *p=*(p+0)=p[0]=&p[0][0] p[i][j]=*(p[i]+j)=*(*(p+i)+j)  两边取地址： &p[i][j]=p[i]+j=*(p+i)+j  如 j==0： &p[i][0]=p[i]=*(p+i)    如i==0： &p[0][0]=p[0]=*p     两边取地址：&&p[0][0]=&p[0]=p                                两边解引用：p[0][0]=*p[0]=**p

引用 3 楼 youxirenjia90 的回复:谢谢回复，还有个问题是数组的值比如{1,2,3,4}的值是什么，是地址么  不是地址，而是数组元素的值

如果数组{1,2,3,4}的值是地址的话，那么他的值即数组的地址，又因为数组的地址等于数组的首地址，所以该数组的值即是元素1的地址？是这样么，请问？

谢谢回复，还有个问题是数组的值比如{1,2,3,4}的值是什么，是地址么

因为p是指向数组的指针 *p是数组 **p才是数组中元素的值

二维数组指针的名字是这个指针的首地址，所以*p 是指针存的内容也就是数组的地址。应该用*（p［i］）


Question: 词频统计  从文件中读取几行英文句子按字典序统计词频   结果跑出来总有段错误   望大神指点！

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

感谢各位！问题我已经找到了，是一开始的#define MAXSIZE 太小了    line[]那个要开大一点，不过速度太慢   还需要找优化的方法

引用 3 楼 wangyaninglm 的回复:[quote=引用 2 楼 V_ermouth 的回复:] 我单步调试可以调试到最后的return 0，然后再走一步就会报错  那是不是那里申请了空间，没有释放？[/quote] 整个程序申请的空间并没有临时用来存储的，都是在最后的链表中啊

查看cpu窗口 然而我还看不懂汇编    请教大神是哪里错了QAQ

在调试下运行，出错时可以断下来，通过调用堆栈、变量窗口等观察分析出错原因

引用 2 楼 V_ermouth 的回复:我单步调试可以调试到最后的return 0，然后再走一步就会报错  那是不是那里申请了空间，没有释放？

我单步调试可以调试到最后的return 0，然后再走一步就会报错

单步调试 ，找到报错的代码，分析代码


Question: 求助：二维数组（已经生成并且知道行数但不知道每一列的列数）怎么冒泡排序？

问题已经解决啦 for (i=0;_word[i][0]!='\0';i++); 	num=i;//num是单词个数 	for (i=0;i<num-1;i++){ 		for (j=0;j<num-i-1;j++){ 			if (strcmp(_word[j],_word[j+1])>0){ 						strcpy (temp,_word[j]); 						strcpy (_word[j],_word[j+1]); 						strcpy (_word[j+1],temp); 			} 		} 	} 前面有char temp[20]={0}; 不管怎么样还是谢谢你！

新手学C，遇到相似的问题，学习一下


Question: 灵异事件，求真相。。。

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。 void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

字符串以\0结尾，如果找不到\0，就会一直去解析这个字符串，导致出现一些乱码

数组没有初始化，导致printf和strlen结果错误  #include<stdio.h> #include<string.h>  const char Stop = '#'; const char Symbol_1 = '.'; const char Symbol_2 = '!'; const int MaxLen = 100;  int main(void) {   char chs[MaxLen] = {0};///////////  need init, otherwise printf chs will not work correct   int Letter; ///////////////////////// getchar return int not char   int Counts = 0;   int Times = 0;      printf("Please Input Words To Test:\n");   while ((Letter = getchar()) != Stop)   {     if (Letter == Symbol_1)     {       chs[Counts] = Symbol_2;       ++Counts;       ++Times;     }     else if(Letter == Symbol_2)     {         chs[Counts++] = Symbol_2;         chs[Counts++] = Symbol_2;         ++Times;      }      else if ((Letter == EOF) || (Letter == '\n')) //////////////////////in case the wrong input      {//parse input done      	break;      } 	 else      {         chs[Counts] = Letter;         ++Counts;      }   }   printf("%d Times\n",Times);   printf("%s\n",chs);   //<----Õâ¸öºÜÆæÝâ ---------------------->see line 10   int Len = strlen(chs);    //<---ÎÊÌâ³öÔÚÕâ3ÐÐ´úÂëÀï   for(int i = 0 ; i < Len+1 ; ++i)     printf("%c ",chs[i]);  return 0; }

引用 3 楼 user-5 的回复:这里面有两个重点： 1. c语言的字符串是要依靠结束符'\0'来判断字符串的结尾 2. 局部变量如果不明确的初始化，它可能是任何值。可能是0，也可能不是0。1楼的memset就是一种初始化。  另一个问题：Counts不断增加的过程中每次都要判断是否超过了MaxLen，否则数组越界了很麻烦的。 其实我好奇的不是这个。。  我最好奇的是为什么我下面加了那3行（就是注释掉的），为什么上面的那句printf()会受到影响。。。

在printf输出前面加上这个，chs[Counts] = '\0';

大概是因为字符串结束符。 两个办法： 1. 在while之前memset(chs, 0, sizeof(chs)); 2. 在while之后chs[Counts] = '\0';

我擦。。输出最后没的2个火星字符csdn都显示不出来。。


Question: 求解释（无法得到答案）

zdgys（）和zdgxs（）函数中没有参数abcd的事啊，怎么可能会有结果呢~

为毛每次给分都是给分与总分不符，，，，

1   #include <stdio.h>                                                                                1        2 int greatest_common_divisor(int a, int b)   3 {      4     int common = b % a;   5     while (common != 0) {   6     |   b = a;   7     |   a = common;   8     |   common = b % a;   9     }  10     return a;  11 }     12       13       14 int main(void)  15 {     16     int n1, n2;  17     int common1, common2;    18     scanf("%d %d",&n1,&n2);  19     if (n1 > n2)  20     |   common1 = greatest_common_divisor(n2, n1);  21     else  22     |   common1 = greatest_common_divisor(n1, n2);  23     printf("Greatest Common Divisor is %d, between %d and %d\n", common1, n1, n2);  24     common2 = n1 * n2 / common1;      25     printf("Least Common Multiple is %d, between %d and %d\n", common2, n1, n2);  26 }   e, f, g, h都是什么做什么，随机变量，结果都不知道做什么的；

最大公约数使用辗转相除法获取，最小公倍数可以通过两数相乘除于最小最大公约数；

在你的基础上改的，其实efgh变量是多余的，直接用abcd就可以 long zdgys (int a,int b) {     int i,e = a,f = b;     for(i=e%f; i!=0;)     {         e=f;         f=i;         i=e%f;     }      return f; } long zxgbs (int c,int d) {     int j,g=c,h=d;     for (j=g;; j++)         if (j%g==0&&j%h==0)     break;     return j; }

google"辗转相除法"呗…… 祝楼主好运


Question: （long long *） double*  指针 int 数组 之间的疑问

引用 2 楼 zhangkaiy1220 的回复:*((long long*)DataBuffer + 12) = 12;  运行结果 DataBuffer[24] = 0;  DataBuffer[25] =12  而  *((double*)DataBuffer + 12)     = 12; 的运行结果是  DataBuffer[24] = 0;  DataBuffer[25] =1076363264  比较疑惑  没问题啊，没懂你疑惑在哪，你希望的值是多少

用%a格式输出试试

12 的 double 在内存中占据 8 个字节。这八个字节是 0x4028000000000000 分成两个 4 字节的 int 就是 0:1076363264

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

有什么问题，楼主去网上搜索浮点数在内存中的表示形式，他与整数表示方式不一样，不是你让一个double类型变量等于12，内存中存储的就是12的二进制


Question: 老手请给点小白鼠点建议哪里错了（C语言程序）

指针直接复制的字符串是不能做任何修改的！  用吧char *s改成char s[ ] 就可以！

谢谢各位!!!!!!!!

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

不好意思我没说清楚我就想把字符串倒置！！！

1   #include <stdio.h>                                                                                1 #include <string.h>     2          3 int main()     4 {        5     char s[] ="hello world";     6     size_t max = strlen(s) - 1;    //最后一个字符串结束标识\0     7     int min = 0; >>  8     while(max > min)     9     {    10     |   char temp = s[min];    11     |   s[min] = s[max];    12     |   s[max] = temp;    13     |   min++;    14     |   max--;    15     }    16     printf("%s\n", s);    17     return 0;    18 }

char *s="hello world"; s指向的字符串是常量，不可写，可以如下编写：      char s[]="hello world"; 另外，从题意看是将字符串逆序，因此max应该为      int max = strlen(s) - 1;

你用char * 声明的字符串常量 是会声明在常量区中的，所以不能修改。 建议用char 数组保存一个字符串试试

常量区的字符串一般不允许进行写操作

用数组保存你的字符串，才能修改。char s[]="hello world";

char *s="hello world"; 这里s是指向的是常量区的字符串，修改会导致出错  之所以不用写成const char* s 完全因为历史原因下的特殊规定

不要修改字符串字面量，这个和 1 = 2一样愚蠢


Question: c语言fget读空行，读取到的是什么？

引用 4 楼 lqbk1 的回复:虽然说上这里问能得到正确答案…… 但答案远没有楼主自己敲代码测试一下来得快.... 嗯哪 编了个小程序，最后发现读取空行得到的第一个字符是‘\r’

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

如果读的是空行，那么返回的字符串是"\n"，fgets会把回车符读到缓存里（在Linux下读到是"\n"，在window下读到应该是"\r\n"，因为两种系统下换行符不一样吧）；

fgetc还是fgets？ fgets和fgetc都不会去掉换行符的，所以读空行的话，会得到"\n"。

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

C语言没有fget

如果有那一行，只是那一行是空，读到的是 “” ,读取失败返回才是NULL  http://en.cppreference.com/w/c/io/fgets


Question: 两个结构体 怎么 将其中一个结构体部分 位元素 付给 另一个结构体

直接按名赋值就是了 再说，同一结构体类型，可以直接赋值


Question: 字符串拼接函数关于'\0'的问题

引用 2 楼 qq423399099 的回复:看楼主你的输入的长度了，fgets会读入回车符的 假如你第一次输入了one,那么string_1里面存的是one\n\0  (一共有4个字符加一个\0) 第二次输入two,那么string_2里面存的是two\n\0  (一共有4个字符加一个\0) strcat之后变成了one\ntwo\n\0 (一共8个字符加一个\0)刚好越界一个字符 +++ '\0'即0；fgets读完一行，在缓存里数据的最后两个字符即\n\0

确实拼接后第一个数组是放不下的。。。


Question: 谁能发现下面程序错误，怎么改？

paschen  和vcgaoshou 正解，高手真多，膜拜一下！

int main() { 	wchar_t texts[2][25][80]; 	wchar_t (*p_old)[25][80] = &texts[0]; 	wchar_t (*p_new)[25][80] = &texts[1]; 	wchar_t (*tmp)[80]  = &p_new[24][0];   	if (memcmp(tmp,p_new[24],sizeof(wchar_t)*80) == 0) 	{ 		//do something  	}  	return 0; }

或者   int main() { 	wchar_t texts[2][25][80]; 	wchar_t (*p_old)[25][80] = &texts[0]; 	wchar_t (*p_new)[25][80] = &texts[1]; 	wchar_t (*tmp)[80]  = &(*p_new)[24];   	if (memcmp(tmp,(*p_new)[24],sizeof(wchar_t)*80) == 0) 	{ 		//do something  	}  	return 0; }

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

由定义wchar_t texts[2][25][80];可知，texts数组只有2个元素，分别是texts[0],texts[1], wchar_t (*p_new)[25][80] = &texts[1];表明p_new指向了texts的第二个元素texts[1]。  (*tmp)[80]表示tmp是一个行指针，指向有80个元素的一维数组。 现在wchar_t tmp=p_new[24];即 wchar_t tmp=*(p_new+24)，表示tmp指向texts数组的第26个元素texts[25 ] 而texts[2][25][80]只有2个元素texts[0],texts[1]，所以无法通过tmp指针访问到texts的区域。

1   #include <stdio.h>                                                                                1 #include <stdlib.h>                                                  2 #include <memory.h>                                                  3             4 //typedef short wchar_t;                                             5             6 int main(void)                                                       7 {           8     wchar_t texts[2][25][80] = {    //the length of array is 2       9     |   { //the length of the array is 25                           10     |   |   {'h', 'o'},    //The length of the array is 80          11     |   |   {'w', 'o'},                                             12     |   |   {'b', 'e'},                                             13     |   |   {'b', 'e'},                                             14     |   |   {'b', 'e'},                                             15     |   |   {'b', 'e'},                                             16     |   |   {'b', 'e'},                                             17     |   |   {'b', 'e'},                                             18     |   |   {'b', 'e'},                                             19     |   |   {'b', 'e'},                                             20     |   |   {'b', 'e'},                                             21     |   |   {'b', 'e'},                                             22     |   },                                                          23     |   {                                                           24     |   |   {'h', 'o'},                                             25     |   |   {'w', 'o'},                                             26     |   |   {'b', 'e'}                                              27     |   }                                                           28     };  >> 29     wchar_t (*p_old)[25][80] = &texts[0];                           30     wchar_t (*p_new)[25][80] = &texts[1];    //or texts+1           31     wchar_t (*tmp)[80]  = p_new[0];    //tmp is two dimensional array, or wchar_t (*tmp)[80] = p_new[1];    32     //wchar_t (*tmp)[80]  = p_new[24];   //p_new is out of bounds    33            34     if (memcmp(tmp,p_new[24],sizeof(wchar_t)*80) == 0)    35     {      36     | //do something                                                37     }      38            39     return 0;                                                       40 }   个人理解，tmp是一个二维数组，只是比普通二维数组特殊一点，其行数是80，所以，p_new[24]赋值tmp是越界的，只能是p_new[0]或者p_new[1]赋值给tmp

wchar_t texts[2][25][80];   wchar_t (*p_old[25])[80];    wchar_t (*p_new[25])[80];    p_new[24] = &texts[1][24];   wchar_t (*tmp)[80] = p_new[24];

第一次的回答错了，跟初始化没有关系，而是指针类型错误，导致了访问越界 确实不太容易发现

没有初始化吗？没用过wchar哎，，，

wchar_t texts[2][25][80] = {0};


建议自己手动算几步，才能熟悉递归调用方式，

递归函数，最好的理解方式就是单步跟踪程序运行，一步步查看程序流程及变量变化情况

递归其实就是“一个函数的自调用” 在这个“自调用”的过程中，必须要有一个变化的“参数”，当这个“参数”达到你的期望值的时候，终止该“自调用”过程


Question: c 语言指针

引用 13 楼 zhao4zhong1 的回复:[quote=引用 11 楼 tthawk 的回复:]  nt main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值  /*这个可能称为指针数组更为贴切*/  一段代码，要想便于维护，他的可读性比编程的技巧可能更重要。对于在调试的过程中去分析地址，这个是个很好的思路。谢谢！！！ http://bbs.csdn.net/topics/380157851[/quote]  更正  char (*  x000   )[5];//返回值  /*这个可能称为指针数组更为贴切*/===>指向二维数组的指针。 2、跑题了。但是还是要给赵老师

引用 12 楼 fefe82 的回复:这是未定义行为，程序有权给出任何结果。( gcc 在某些编译选项下会给 warning ，甚至 error 直接拒绝编译）  你说的是在标准c中没有定义那一个，能不能在详细一点点。多谢！！这个，感觉距离我想要寻找的答案更近了！！！

引用 11 楼 tthawk 的回复: nt main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值  /*这个可能称为指针数组更为贴切*/  一段代码，要想便于维护，他的可读性比编程的技巧可能更重要。对于在调试的过程中去分析地址，这个是个很好的思路。谢谢！！！ http://bbs.csdn.net/topics/380157851

仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

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

对于指针，是有差异的。比如指向int的指针、指向char的指针、指向结构体的指针等等。。。 在程序运行的过程中，不同类型的指针是能够被识别出来的。 这种识别的机制是什么，这个我不清楚。所以，在开始的那段小程序中的运行结果我就不明白。   请各位大神赐教，感谢两位网友的发言。

指针是变量，当然可以++。即便是char * p，这个p仍然可以++。 我不明白的是int * p，为什么能够表示char ** pt这个指向指针的指针变量。而不会出错。 如题目所示，如果将int *p 改为 char *p,那么程序运行就报错。

你都说是地址了，当然用int了，当然其他整形也可以，用指针的移动来实行，用char不能++吧

为啥code你的字符都成为白色的了。

char **cp; //指向指针的指针变量 int *p         //指向int类型的指针 /* 我们可以说cp变量中存放的是数组name的某个数组元素的内存单元的地址，而p存放的是int数据内存单元的地址。 如下： */ int **pp; int *p int a=10; p=&a; pp=&p;   printf("%d %d %d\n",**pp,*p,a); //这个输出的都是10.   // 虽然sizeof(p)=4,这也只能说明指针变量用4个Byte来存放数据。 // 还是没有弄明白？？？？<img src="https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/32.gif" alt="">

C语言中指针都是4个字节，没有本质区别，可以随意转换。     p=name+3; // 指针隐式转换成int*，将name+3所在的地址解释为一个指向int型变量的指针     printf("%s\n",*p);//指针以字符串形式解释。其实此时又将指针解释为指向一个字符串。  你试试  printf("%d\n",*p);  看看会发生什么，就知道了。


Question: mjpg-streamer如何支持多摄像头

请问树莓派可以外挂USB Hub HAT 实现外加6x USB CAMERA 吗

已经做到了，请问你现在还在做这个吗


Question: linux C 错误 :segmentation fault(core dumped)

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

出错时断下来，通过调用堆栈、变量窗口等观察分析原因

36 行，head是随机值，使用head->next 就是访问了非法地址


Question: 数据结构链表和串的初始化问题

将函数参数名起得和调用它时传的实参的变量名一样也没用。而且还造成概念混淆。

单步调试可以发现 idxlist->item[0].bnolist 已经是NULL了，取idxlist->item[0].bnolist->next导致崩溃

Initlist(idxlist->item[ct].bnolist);这样的传参方式（一级指针）是没有用的，在Initlist函数里操作的只是一个指针的拷贝 改成传二级指针或者一级指针的引用  #include<stdio.h> #include<stdlib.h> #include<string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define MAXKEYNUM 2500 //引索表的最大容量-- #define MAXLINELEN 500 //数目串的最大长度 缓冲区长度-- #define MAXWORDNUM 10 //词表的最大容量-- #define MAXWORDLEN 100//关键词的最大容量-- typedef int Status; typedef struct{     char *ch;     int length; }Hstring; typedef struct{     char *item[MAXWORDNUM];     int last; }Wordlisttype; //词表类型  typedef int Elemtype;  typedef struct Lnode{     Elemtype data[3];     struct Lnode *next; }Lnode,*Link,*Linklist;//*号放在前边  typedef struct{     Hstring key;//关键词     Linklist bnolist;//存放书号索引的链表 }Idextermtype;//索引项类型  typedef struct {     Idextermtype item[MAXKEYNUM+1];     int last; }Idexlisttype;  Idexlisttype idxlist;  void Initidxlist(Idexlisttype *idxlist); void Init_Hstring(Hstring *wd); Status Initlist(Linklist *L); int main() {     Initidxlist(&idxlist);     return 0; } Status Initlist(Linklist *L) {     int ct;     if(!(*L = (Link)malloc(sizeof(Lnode))))         return OVERFLOW;     for(ct=0;ct<3;ct++)         if(!((*L)->data[ct] = (int)malloc(sizeof(int))))             return OVERFLOW;     (*L)->next = NULL;     return OK; }//initlist; void Init_Hstring(Hstring *wd) {     int ct;     wd->ch = (char *)malloc(MAXWORDLEN*sizeof(char));     for(ct=0;ct<MAXWORDLEN;ct++){         wd->ch[ct] = '\0';     }     wd->length = 0; } void Initidxlist(Idexlisttype *idxlist) {     int ct;     for(ct=0;ct<MAXKEYNUM;ct++){         Init_Hstring(&(idxlist->item[ct].key));         Initlist(&idxlist->item[ct].bnolist);     }     printf("????????????\n");     if(idxlist->item[0].bnolist->next==NULL)//--------------------------------这里有问题         printf("????????????\n");     idxlist->last = 0; }

printf("????????????\n");     if(idxlist.item[0].bnolist->next==NULL)         printf("????????????\n");     idxlist.last = 0;


Question: 二叉查找树的删除疑问

好的，现在大概搞清楚了，谢谢各位

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

因为这个是递归调用的，当最后一次调用的时候找到了需要删除的结点后，你应该返回的是替换它的结点的地址 假设它的上一级是T->Right = Delete(T->Element,T->Right);   你的Delete(T->Element,T->Right);  是不是只需要返回替换它的节点的地址，然后这个删除节点的父节点就是上一级的这个T T->Right = 新的替换节点的地址  PS：表达的不是太好，楼主可以在纸上演算一下，或者单步调试一步步看结果


Question: 求教：RSA加密算法，大数求余，急！！！

我用的是二进制求模指数但是数字太大了貌似就做不出来  for (i = 1;i <= filesize;++i) { //这里是转字符为整形保存为数组的，其实我觉得没必要 inside_ol[i] = inside_ol1[i - 1]; inside_ol[i] = inside_ol[i]; inside_ol2[i] = RSA_encrypt(inside_ol + i, e); int transform(int b, int *a) //这里是解密的时候的模指运算模块，加密的时候也是这个。 { int t, temp = -1; while (b>0) { t = b % 2; ++temp; a[temp] = t; b = b / 2; } return temp; } int RSA_encrypt(char *inside_ol, int b) { int a = *inside_ol; int x = 0, back = 1, k, i, s[1000]; k = transform(b, s); for (i = k;i >= 0;i--) { x = 2 * x; back = (back*back) % n; if (s[i] == 1) { x++; back = (back*a) % n; } } return back; } 我也是最近在研究这个，学校比赛打算做个用这个加密文件内容的小程序出来

我就喜欢重复制造木头轮子：#include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }

有各种现成的加密库，如freeLIP、Crypto++、微软的Crypto API等，也有一些现成的大数运算库，如Miracl

公司做项目需要用RSA，之前没弄过，要求是128位加密，所以需要用到256位对128位求余，openssl用在STM32中方便吗

RSA 至少的得 1024 位起,  256 位算啥事情啊.  编译个 openssl 上去就是了,  又不麻烦.   要快就编译个  gmp 上去.  自己写简单点就像 openssl 样试商, 性能不行, 不过代码好读.   高级点就像 gmp 弄个 FFT  的上去.    现在不都流行 ECC 了么, 弄 RSA 干嘛...


Question: 请教linux下socket编程中send()函数如何强制其将数据发出去？

都是做异步网络发送： https://github.com/owenliang/simple_kit/tree/master/simple_io

SEND Section: Linux Programmer's Manual (2) Updated: 2004-07-01  --------------------------------------------------------------------------------    NAME send, sendto, sendmsg - send a message on a socket    SYNOPSIS #include <sys/types.h>  #include <sys/socket.h>  ssize_t send(int s, const void *buf, size_t len, int flags);  ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);  ssize_t sendmsg(int s, const struct msghdr *msg, int flags);     DESCRIPTION The system calls send, sendto, and sendmsg are used to transmit a message to another socket.  The send call may be used only when the socket is in a connected state (so that the intended recipient is known). The only difference between send and write is the presence of flags. With zero flags parameter, send is equivalent to write. Also, send(s,buf,len) is equivalent to sendto(s,buf,len,NULL,0).   The parameter s is the file descriptor of the sending socket.   If sendto is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) socket, the parameters to and tolen are ignored (and the error EISCONN may be returned when they are not NULL and 0), and the error ENOTCONN is returned when the socket was not actually connected. Otherwise, the address of the target is given by to with tolen specifying its size. For sendmsg, the address of the target is given by msg.msg_name, with msg.msg_namelen specifying its size.   For send and sendto, the message is found in buf and has length len. For sendmsg, the message is pointed to by the elements of the array msg.msg_iov. The sendmsg call also allows sending ancillary data (also known as control information).   If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.   No indication of failure to deliver is implicit in a send. Locally detected errors are indicated by a return value of -1.   When the message does not fit into the send buffer of the socket, send normally blocks, unless the socket has been placed in non-blocking I/O mode. In non-blocking mode it would return EAGAIN in this case. The select(2) call may be used to determine when it is possible to send more data.   The flags parameter is the bitwise OR of zero or more of the following flags.   MSG_OOB  Sends out-of-band data on sockets that support this notion (e.g. of type SOCK_STREAM); the underlying protocol must also support out-of-band data.  MSG_EOR  Terminates a record (when this notion is supported, as for sockets of type SOCK_SEQPACKET).  MSG_DONTROUTE  Don't use a gateway to send out the packet, only send to hosts on directly connected networks. This is usually used only by diagnostic or routing programs. This is only defined for protocol families that route; packet sockets don't.  MSG_DONTWAIT  Enables non-blocking operation; if the operation would block, EAGAIN is returned (this can also be enabled using the O_NONBLOCK with the F_SETFL fcntl(2)).  MSG_NOSIGNAL  Requests not to send SIGPIPE on errors on stream oriented sockets when the other end breaks the connection. The EPIPE error is still returned.  MSG_CONFIRM (Linux 2.3+ only)  Tell the link layer that forward progress happened: you got a successful reply from the other side. If the link layer doesn't get this it'll regularly reprobe the neighbour (e.g. via a unicast ARP). Only valid on SOCK_DGRAM and SOCK_RAW sockets and currently only implemented for IPv4 and IPv6. See arp(7) for details.  MSG_MORE (Since Linux 2.4.4)  The caller has more data to send. This flag is used with TCP sockets to obtain the same effect as the TCP_CORK socket option (see tcp(7)), with the difference that this flag can be set on a per-call basis. Since Linux 2.6, this flag is also supported for UDP sockets, and informs the kernel to package all of the data sent in calls with this flag set into a single datagram which is only transmitted when a call is performed that does not specify this flag.  The definition of the msghdr structure follows. See recv(2) and below for an exact description of its fields.    struct msghdr {     void         * msg_name;     /* optional address */     socklen_t    msg_namelen;    /* size of address */     struct iovec * msg_iov;      /* scatter/gather array */     size_t       msg_iovlen;     /* # elements in msg_iov */     void         * msg_control;  /* ancillary data, see below */     socklen_t    msg_controllen; /* ancillary data buffer len */     int          msg_flags;      /* flags on received message */ };   You may send control information using the msg_control and msg_controllen members. The maximum control buffer length the kernel can process is limited per socket by the net.core.optmem_max sysctl; see socket(7).     RETURN VALUE On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.    ERRORS These are some standard errors generated by the socket layer. Additional errors may be generated and returned from the underlying protocol modules; see their respective manual pages.  EACCES  (For Unix domain sockets, which are identified by pathname) Write permission is denied on the destination socket file, or search permission is denied for one of the directories the path prefix. (See path_resolution(2).)  EAGAIN or EWOULDBLOCK  The socket is marked non-blocking and the requested operation would block.  EBADF  An invalid descriptor was specified.  ECONNRESET  Connection reset by peer.  EDESTADDRREQ  The socket is not connection-mode, and no peer address is set.  EFAULT  An invalid user space address was specified for a parameter.  EINTR  A signal occurred before any data was transmitted.  EINVAL  Invalid argument passed.  EISCONN  The connection-mode socket was connected already but a recipient was specified. (Now either this error is returned, or the recipient specification is ignored.)  EMSGSIZE  The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible.  ENOBUFS  The output queue for a network interface was full. This generally indicates that the interface has stopped sending, but may be caused by transient congestion. (Normally, this does not occur in Linux. Packets are just silently dropped when a device queue overflows.)  ENOMEM  No memory available.  ENOTCONN  The socket is not connected, and no target has been given.  ENOTSOCK  The argument s is not a socket.  EOPNOTSUPP  Some bit in the flags argument is inappropriate for the socket type.  EPIPE  The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.     CONFORMING TO 4.4BSD, SVr4, POSIX 1003.1-2001. These function calls appeared in 4.2BSD.  POSIX only describes the MSG_OOB and MSG_EOR flags. The MSG_CONFIRM flag is a Linux extension.     NOTE The prototypes given above follow the Single Unix Specification, as glibc2 also does; the flags argument was `int' in BSD 4.*, but `unsigned int' in libc4 and libc5; the len argument was `int' in BSD 4.* and libc4, but `size_t' in libc5; the tolen argument was `int' in BSD 4.* and libc4 and libc5. See also accept(2).    BUGS Linux may return EPIPE instead of ENOTCONN.    SEE ALSO fcntl(2), getsockopt(2), recv(2), select(2), sendfile(2), socket(2), write(2), ip(7), socket(7), tcp(7), udp(7)  --------------------------------------------------------------------------------

网卡的发送需要排队的吧，使用send，是用户区的，从网卡上发出去是内核做的；应该没有办法使用send将数据立即发送到网络上，因为你不能直接操作网卡；

引用 1 楼 a991556 的回复:强制发送？没听说过 socket应该有个缓冲区吧，应该就是刷新缓冲区的意思

有个No Delay设置，会立马发送，具体可以网上自己搜一下。

强制发送？没听说过


Question: 大神求救！第一次用C-Free5.0 小白 为什么老是被调试程序不是可执行程序。

程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。 程序员的常识之二：写程序之前，关闭UAC、防火墙、杀毒软件、以管理员身份运行、……

我按照教程来的，并没有什么用，好像，总感觉保存路径不对

先保证创建工程是否正确： 参考：http://jingyan.baidu.com/article/f3e34a128204a8f5eb653597.html

window下编程用VS、Dev-C++， 不要用一些不知名的软件，用的人少。


Question: 谁帮我看看这个指针排序要这么写为什么错误啊！

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

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

比大小 如果存在函数调用实参和形参间传参，最好不要用 交换指针的方法， 传参是单向的，运行结果会有问题

路过，学习了，感觉数组内的值可以改吧，但数组名，表示数组的首地址，似乎不能改吧，本人也在学习中！

数组是不能被修改的

数组交换值，只能拷贝，不可能通过交换行指针的值，除非是指针数组。   #include <stdio.h> #include <stdlib.h> #include <string.h>  #define K (3) #define L (100)   void ASCorder(char (*str)[L],int n)  {  	int i, j;  	char tmp[L];  	 	for (i = 0; i < n-1; i++) { 		 		for (j = i + 1; j < n; j++) { 			if (strcmp(str[i], str[j]) > 0) { 				memcpy(tmp, str[i], L); 				memcpy(str[i], str[j], L); 				memcpy(str[j], tmp, L);			 			} 		} 		 	}  }  int main(void) { 	int i = 0;     char str[K][L] = {"789", "456", "123"};          ASCorder(str, K);          for (i = 0; i < K; i++) {     	printf("%s\n", str[i]); 	} 	     system("pause");     return 0; }


Question: ECHILD 什么情况下会出现？

这个网上好多解析好的资料 http://blog.csdn.net/taolinke/article/details/8057335

引用 1 楼 lgbxyz 的回复: #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <errno.h>   int main(void) {     int ret; 	//ignore the SIGCHLD signal     signal(SIGCHLD, SIG_IGN);      //During execution of the command, SIGCHLD will be blocked     ret = system("echo Hello");     if (ret < 0) {         perror("system failed");         return -1;     }     return 0; }    我在看 linux system这个函数的代码， 不少文章提到过， system 可能有 EHILD 出现，  能再解释一下原因吗？   什么原因导致的？