Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: 关于去除字符串的空格符的一个问题

回复:
user: user-1
content: 1.strncpy(newstr,str+j,ncount);这句有问题，应该是strncpy(newstr,str+i,ncount);才对 2.newstr[ncount]='\0'这句就是在新字符串的末尾补上'\0'，不补'\0'的话输出的时候可能越界崩溃 PS：i是从前往后遍历，第一个不是空格的下标位置，而j是从后往前第一个不是空格的下标位置  #include<stdio.h> #include<string.h> #include <ctype.h> int trimSpace(char *str,char *newstr) { 	char *p=str; 	int ncount=0; 	int i,j=0;   	if(str==NULL||newstr==NULL) 	{ 		return -1; 	} 	i=0; 	j=strlen(p)-1; 	while(isspace(p[i])&&p[i]!='\0') 	{ 		i++; 	} 	while(isspace(p[j])&&p[j]!='\0') 	{ 		j--; 	}  	ncount=j-i+1; 	strncpy(newstr,str+i,ncount); 	newstr[ncount]='\0'; }  void main() { 	char *a = "  sfdsf  "; 	char buffer[32] = {0}; 	trimSpace(a, buffer); 	printf("%s\n", buffer); }  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

user: user-2
content: 1、+j 表示从开头第j个字符那里开始复制 2、字符串以\0结尾

user: user-0
content: 哦哦哦，原来如此。谢谢谢谢。太棒了

user: user-1
content: strlen是不计算'\0'的长度，主要是因为数组下标是从0开始的，所以它要-1

user: user-0
content: 哦，那意思是前面的strlen（p）-1也不是\0吗？他不是要减去\0的长度吗。我有点糊涂了。

user: user-1
content: 当然不是'\0' 以我给的例子为例，i和j的值是2和6，加1以后才是5（主要是因为j提前了一位，因为它是指向最后一个非空格的下标）

user: user-0
content: 他不是ncount=j-i+1吗，这个+1难道不是\0吗？那他这个+1是什么意思
user-0 提问: 初涉socket疑问：linux c 的 client 使用connect直接返回问题

回复:
user: user-0
content: 引用 1 楼 wysk1 的回复:最近也刚学，说下我自己的理解，服务端启动后，accept阻塞，并不断检查listen指向的消息队列接收客户端的消息，客户端connect请求连接服务器，listen侦听到该消息，把请求放入队列，向客户端返回连接成功消息  但我现在的问题是服务器端启动后，并没有通过accept阻塞，这个时候客户端调用connect应该客户端会阻塞才对，但是客户端未阻塞，成功返回，并且client fd可以正常使用。这个现象我不知道是正常还是异常=_=

user: user-1
content: 最近也刚学，说下我自己的理解，服务端启动后，accept阻塞，并不断检查listen指向的消息队列接收客户端的消息，客户端connect请求连接服务器，listen侦听到该消息，把请求放入队列，向客户端返回连接成功消息

user: user-0
content: 引用 3 楼 Loydia 的回复:可以这样理解：listen后内部会维护一个连接队列，当有连接进来就会push到这个队列中。accept只是从连接队列中pop一个连接，如果为连接队列为空且为阻塞模式，函数将一直等待到有连接进来。如果为非阻塞，函数将会返回错误并设置要求重试的错误代码。 非常感谢！

user: user-2
content: 可以这样理解：listen后内部会维护一个连接队列，当有连接进来就会push到这个队列中。accept只是从连接队列中pop一个连接，如果为连接队列为空且为阻塞模式，函数将一直等待到有连接进来。如果为非阻塞，函数将会返回错误并设置要求重试的错误代码。
user-0 提问: C语言初学者求助

回复:
user: user-1
content: #include<stdio.h> #include<stdlib.h> int suanqian(int,int); main(){ start:	int i,a,b,c,need,put,rest; int price[10]={1,2,2,3,4,6,6,6,6,6}; char*name[10]={"怡宝","可乐","雪碧","酸奶","橙汁","咖啡","红牛","脉动","芬达","奶茶",};  for(i=0;i<10;i++){ printf("%d.%s",i+1,name[i]);printf("   %d元\n",price[i]); }  bianhao:printf("请输入物品的编号"); scanf("%d",&a); if(a>10){ printf("输入有误，请重新输入\n"); goto bianhao; } system("CLS");printf("您选择了%s",name[a-1]); printf("\n请输入物品的数量"); scanf("%d",&b);  need=suanqian(b,price[i-1]); printf("所需费用%d元",need); buzu:printf("请投币"); scanf("%d",&put); if(put==need) {printf("谢谢惠顾");} else if(put<need) {printf("支付余额不足,退回%d元\n",put);goto buzu;} else if(put>need){ rest=put-need;     printf("找回零钱%d元,谢谢惠顾",rest);} printf("继续消费请输入0,结束消费请输入1"); scanf("%d",&c);if(c==0){system("CLS");goto start;} return 0;}  int suanqian(int x,int y){ int z; z=x*y; return z; }  你没必要再在主函数主函数中写一遍，suanqian():函数 goto 这个用法不利于代码的规范，一般不用

user: user-2
content: 函数里面不能定义另一个函数，把他拿到main的外边去

user: user-0
content: 引用 楼主 L_h_l_d 的回复:#include<stdio.h> #include<stdlib.h> int suanqian(int,int); main(){ start:	int i,a,b,c,need,put,rest; int price[10]={1,2,2,3,4,6,6,6,6,6}; char*name[10]={"怡宝","可乐","雪碧","酸奶","橙汁","咖啡","红牛","脉动","芬达","奶茶"};  for(i=0;i<10;i++){ printf("%d.%s",i+1,name[i]);printf("   %d元\n",price[i]); }  bianhao:printf("请输入物品的编号"); scanf("%d",&a); if(a>10){ printf("输入有误，请重新输入\n"); goto bianhao; } system("CLS");printf("您选择了%s",name[a-1]); printf("\n请输入物品的数量"); scanf("%d",&b); int suanqian(int x,int y){ 	int z; 	z=x*a; 	return z; } need=suanqian(b,price[i-1]); printf("所需费用%d元",need); buzu:printf("请投币"); scanf("%d",&put); if(put==need) {printf("谢谢惠顾");} else if(put<need) {printf("支付余额不足,退回%d元\n",put);goto buzu;} else if(put>need){ 	rest=put-need;     printf("找回零钱%d元,谢谢惠顾",rest);} printf("继续消费请输入0,结束消费请输入1"); scanf("%d",&c);if(c==0){system("CLS");goto start;} return 0;}  int suanqian(int x,int y){ 	int z; 	z=x*a; 	return z; 这里总提示我函数定义非法为什么啊。。。我不会改。。。有劳各位大神。。。    怎么弄成模块化设计啊。。。尴尬。。。求助各位大神。。。

user: user-3
content: 1.不是深层嵌套一般不推荐使用goto 2.suanqian函数里z=x*a;应该是z=x*y;吧 3.别在函数里定义函数  #include<stdio.h> #include<stdlib.h> int suanqian(int,int); int main(){ start:	int i,a,b,c,need,put,rest; 	int price[10]={1,2,2,3,4,6,6,6,6,6}; 	char*name[10]={"怡宝","可乐","雪碧","酸奶","橙汁","咖啡","红牛","脉动","芬达","奶茶"};  	for(i=0;i<10;i++){ 		printf("%d.%s",i+1,name[i]);printf("   %d元\n",price[i]); 	}  bianhao:printf("请输入物品的编号"); 	scanf("%d",&a); 	if(a>10){ 		printf("输入有误，请重新输入\n"); 		goto bianhao; 	} 	system("CLS");printf("您选择了%s",name[a-1]); 	printf("\n请输入物品的数量"); 	scanf("%d",&b); 	need=suanqian(b,price[i-1]); 	printf("所需费用%d元",need); buzu:printf("请投币"); 	scanf("%d",&put); 	if(put==need) 	{printf("谢谢惠顾");} 	else if(put<need) 	{ 		printf("支付余额不足,退回%d元\n",put);goto buzu; 	} 	else if(put>need){ 		rest=put-need; 		printf("找回零钱%d元,谢谢惠顾",rest); 	} 	printf("继续消费请输入0,结束消费请输入1"); 	scanf("%d",&c);if(c==0){system("CLS");goto start;} 	return 0; }  int suanqian(int x,int y){ 	int z; 	z=x*y; 	return z; }
user-0 提问: fread读不到文件数据

回复:
user: user-0
content: 谢谢各位前辈，和赵四老师的解答。 我用winhex查看了保存的二进制文件。字节是对的。说明文件完整保存了。 我也断点调试了，发现并没有读取到。因为我把问题想得太复杂了，忽略了一个基础问题：重新运行窗口，然后直接加载二进制文件的数据。  for(i=0;i<ij;i++)     {         if(fread(&stu[i],sizeof(stu),1,read_FILE)!=1)         {             printf("读取失败!\n");             exit(1);         }               } ij这个变量的值要么随机，要么为0.导致了循环失败. 于是： 我改成了 while(fread(&stu[i],sizeof(stu),1,read_FILE)==1) { //计次变量递增 }  再调用show函数，发现已经完整读取所有的数据。

user: user-1
content: 怎么写就怎么读，单步跟踪程序，判断判断每一步读到什么，分析原因

user: user-2
content: if(fread(&stu[i],sizeof(stu[i]),1,read_FILE)!=1) 这么读，原则上没什么问题，但最好和你写入的方式保持一致。 第一步先确认录入和打印都能正常运行，录入之后马上把数据打出来看看对不对。 第二步确认写文件是否正确，找个二进制编辑器打开文件看看。

user: user-2
content: 这两行的意图显然不一致         for(save_count=0;save_count<ix;save_count++)         if((fwrite(&stu,sizeof(stu),1,save_FILE))!=1)

user: user-0
content: 补充一下，调试加载的结果是这样。完全打印不出来

user: user-3
content: fwrite(&stu,sizeof(stu),1,save_FILE))!=1不应该是fwrite(&stu[save_count],sizeof(stu),1,save_FILE))!=1吗

user: user-4
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了
user-0 提问: C语言，关于MISRA规范，有几个告警很不明白，请大家帮忙啊

回复:
user: user-0
content: 引用 1 楼 user-1 的回复:http://blog.csdn.net/pony_maggie/article/details/5270335  个人感觉其实是错在这里了： uint8 i = 0U; 要改成： unit8 i = (uint8) 0U;  这个本地试了下，确实不行。对i取地址的时候，i的值应该是不影响这个操作的。

user: user-1
content: http://blog.csdn.net/pony_maggie/article/details/5270335  个人感觉其实是错在这里了： uint8 i = 0U; 要改成： unit8 i = (uint8) 0U;
user-0 提问: 学预处理数学库遇到的问题

回复:
user: user-0
content: 不是很明白，在这个代码里具体应该怎么处理呢？

user: user-1
content: 函数要前向声明, 没声明的返回类型默认为int

user: user-2
content: 1.rect_to_plar需要前置声明 2. result = rect_to_polar(input);应该是 result = rect_to_plar(input);你多了一个o  #include<stdio.h> #include<math.h>   #define RAD_TO_DEG (180/(4*atan(1.0)))   typedef struct polar_v {     double magnitude;     double angle; }POLAR_V;   typedef struct rect_v {     double x;     double y; }RECT_V;  POLAR_V rect_to_plar(RECT_V rv); int main(void) {     RECT_V input;     POLAR_V result;       puts("Enter x,y coordinates;enter q to quit: ");     while (scanf("%lf %lf", &input.x, &input.y) == 2)     {         result = rect_to_plar(input);         printf("magnitude =%0.2f, angle =%0.2f\n",             result.magnitude, result.angle);     }     puts("Bye!");       return 0; }   POLAR_V rect_to_plar(RECT_V rv) {     POLAR_V pv;       pv.magnitude = sqrt(rv.x * rv.x + rv.y * rv.y);     if (pv.magnitude == 0)     {         pv.angle = 0.0;       }     else     {         pv.angle = RAD_TO_DEG*atan2(double(rv.y), rv.x);     }     return pv; }
user-0 提问: 《C和指针》中关于指针与下标的问题

回复:
user: user-1
content: int array[10],  说明数组元素为整形。 取得a的值，并把它与整形的长度（也就是4）相乘，就是根据下标a，乘以4（整形量所占内存的字节数），所得结果就是下标变量相对数组起始位置的偏移，也就是array[a]所对应的“变量地址”（当然要加上数组基址）   int array[10], a; for(a = 0; a < 10; a += 1)      array[a] = 0;   为了对下标表达式求值，编译器在程序中插入指令，取得a的值，并把它与整形的长度（也就是4）相乘。这个乘法需要花费一定的时间和空间。   int array[10], *ap; for(ap = array; ap < array + 10; ap++)      *ap = 0;	  ap++中，++其实就是在ap当前指针所指的位置处，加上一个ap所指元素的类型的长度，这里就是int,即4。也就是1必须与整形的长度（也就是4）相乘，然后再与指针相加。     从这里，貌似两个循环都进行了乘法，好像没有什么差异。可是，你注意到没有2个循环其实是有很大的不同的。不同在哪里呢？？？    仔细看，会发现数组下标中的a每次的值是不同的，每次a都会与长度4进行相乘，即进行了10次乘法。    再看看指针，你会发现ap++时，是1与长度4进行相乘，再与指针相加。每次执行乘法时，其实就是1*4。这个乘法只在编译时进行了一次运算。程序执行的时候，就没有进行乘法运算，只是简单的将4与指针相加而已。         指针比下标更有效率的一个典型。你会发现在这个场合中 -- 当你在数组中1次1步（或某个固定的数字）地移动时，与固定数字相乘的运算在编译时完成，所以运行时所需的指令就少一些。在绝大多数机器上，程序竟会更小一些、更快一些。

user: user-2
content: 请忽略以上的叙述。（可以忽略以上有关效率的所有文字）  随着 CPU 、体系结构 与 编译器的发展，以上说法的正确性在随时发生着变化。
user-0 提问: 循环队列，运行不出结果，求大神赐教

回复:
user: user-0
content: 非常非常非常感谢，我再好好看看。

user: user-1
content: 你如果不接受返回值，而是通过函数内给指针分配空间必须要传二级指针或者一级指针的引用（因为它修改了指针的指向） 如果是修改指针所指向的区域的值那么传一级指针。 就比如你这个题，如果你传一级指针，仅仅表示main函数里的qu和init_queue的形参que指向了同一块内存（都指向了NULL） 而main函数里的qu和init_queue的形参que两者并不是同一个指针,所以你给que分配空间，修改它的指向是影响不到main函数的qu的

user: user-0
content: 非常感谢，我在看二叉树时也看到有二级指针，但始终不是很明白，大神能否详细讲解一下为什么非要用二级指针才能分配空间，或者给指个学习方向？

user: user-1
content: 三个问题： 1.你想通过init_queue给main函数的qu初始化分配空间，必须传二级指针或者一级指针的引用才行 （传一级指针是没有用的，操作的只是他的一个副本而已） 2.没有给int *arr分配空间 3.main函数内while (!isempty_queue(qu))应该是while (isempty_queue(qu))  /* @filename list.h */  #include<stdlib.h> #include<malloc.h> #include<stdio.h> typedef struct queue { 	int *arr; 	size_t cap; 	size_t front; 	size_t rear; 	size_t size; }QUEUE;  void init_queue(QUEUE ** que, size_t cap) { 	*que = (QUEUE*)malloc(cap*sizeof(int)); 	(*que)->arr = (int *)malloc(cap*sizeof(int)); 	(*que)->cap = cap; 	(*que)->front = 0; 	(*que)->rear = 0; 	(*que)->size = 0; } void destroy_queue(QUEUE *que) { 	free(que->arr); 	que->arr = NULL; 	que->cap = 0; 	que->front = 0; 	que->rear = 0; 	que->size = 0; } int  pop_queue(QUEUE *que) { 	if (que->front >= que->cap) 	{ 		que->front = 0; 	} 	que->size--; 	return que->arr[que->front++]; } void push_queue(QUEUE *que, int data) { 	if (que->rear >= que->cap)//下标越界 		que->rear = 0; 	que->arr[que->rear++] = data;//数据放进队尾，队尾后移 	que->size++;//个数加1 }  int  isfull_queue(QUEUE *que) { 	if ((que->size) ==( que->cap)) 		return 1; 	else 		return -1; } int isempty_queue(QUEUE *que) { 	if (que->size == 0) 		return 0; 	else 		return -1; } int getsize_queue(QUEUE *que) { 	return que->size; } void show_front(QUEUE *que) { 	if (que->front >= que->cap) 		que->front = 0; 	printf("%d\n", que->arr[que->front]); }    int main() { 	QUEUE * qu=NULL; 	init_queue(&qu, 5); 	int i; 	for (i = 0; i<5; i++) 	{ 		if (isfull_queue(qu)) 			push_queue(qu,i); 	} 	printf("size%d\n", getsize_queue(qu)); 	while (isempty_queue(qu)) 	{ 		printf("%d\n", pop_queue(qu)); 	} 	destroy_queue(qu); 	getchar(); 	return 0; }   单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。
user-0 提问: 如何提取多个txt中的数据

回复:
user: user-0
content: 好的，谢谢老师，我的问题解决了

user: user-1
content: #include <stdio.h> double d[8]; FILE *f; char fn[32]; int i, j, r; int main() { 	for (r = 1; r <= 4; r++) {//第r行 		for (j = 1; j <= 8; j++) {//第j个文件 			sprintf(fn, "D://stress%d.txt", j); 			f = fopen(fn, "r"); 			if (f) { 				for (i = 0; i<r - 1; i++) fscanf(f, "%*lf");//跳过前r-1个数 				fscanf(f, "%lf", &d[j - 1]);//读取第r个数到d[j-1]中 				fclose(f); 			} 		} 		for (i = 0; i<8; i++) printf("%15.6lf ", d[i]);//显示第r行的100个数 		printf("\n");//换行间隔 	} 	return 0; }

user: user-0
content: 改成了double后精度问题解决了，非常感谢！

user: user-2
content: 引用 2 楼 zuiai214 的回复:谢谢老师的指导！对于整型数据的输入，也就是我的例子可以完美解答。 但是由于我是从其他软件导出txt的结果，实际数据与我的例子还是有些不同，我导出的实际结果如下  可以看出每行txt数据前有空格，而且空格的个数并不固定，另外我的数据是浮点型的。在这种情况下我经过简单修改输出的结果为  可以看出我导入的数据小数点后被略去了。想再向老师询问问题产生的原因与解决方法。我的程序如下，麻烦老师了。 #include <stdio.h> float d[8]; FILE *f; char fn[32]; int i, j, r; int main() { 	for (r = 1; r <= 4; r++) {//第r行 		for (j = 1; j <= 8; j++) {//第j个文件 			sprintf(fn, "D://stress%d.txt", j); 			f = fopen(fn, "r"); 			if (f) { 				for (i = 0; i<r - 1; i++) fscanf(f, "%*f");//跳过前r-1个数 				fscanf(f, "%f", &d[j - 1]);//读取第r个数到d[j-1]中 				fclose(f); 			} 		} 		for (i = 0; i<8; i++) printf("%f ", d[i]);//显示第r行的100个数 		printf("\n");//换行间隔 	} 	return 0; } 这个应该是float的精度问题，你换成double应该就能过了，具体原因自己搜一下吧，长篇大论的。建议不要用fscanf/scanf来输入float。 另外，看一楼说法，我觉得用二维数组把数据全读出来之后进行处理比较方便，你这样打开关闭文件，还要跳来跳去的很容易出错。

user: user-0
content: 谢谢老师的指导！对于整型数据的输入，也就是我的例子可以完美解答。 但是由于我是从其他软件导出txt的结果，实际数据与我的例子还是有些不同，我导出的实际结果如下  可以看出每行txt数据前有空格，而且空格的个数并不固定，另外我的数据是浮点型的。在这种情况下我经过简单修改输出的结果为  可以看出我导入的数据小数点后被略去了。想再向老师询问问题产生的原因与解决方法。我的程序如下，麻烦老师了。 #include <stdio.h> float d[8]; FILE *f; char fn[32]; int i, j, r; int main() { 	for (r = 1; r <= 4; r++) {//第r行 		for (j = 1; j <= 8; j++) {//第j个文件 			sprintf(fn, "D://stress%d.txt", j); 			f = fopen(fn, "r"); 			if (f) { 				for (i = 0; i<r - 1; i++) fscanf(f, "%*f");//跳过前r-1个数 				fscanf(f, "%f", &d[j - 1]);//读取第r个数到d[j-1]中 				fclose(f); 			} 		} 		for (i = 0; i<8; i++) printf("%f ", d[i]);//显示第r行的100个数 		printf("\n");//换行间隔 	} 	return 0; }

user: user-1
content: //有一百个txt文件，按顺序deta1，deta2...deta100命名， //每个txt中有一列数据，现在我想要提取顺序提取每个txt中对应行的数据。 //例如：我提取所有txt中第一行的数据，保存到一个C语言的一维数组中，然后进行处理。 //再提取每个txt中第二行，第三行，以此类推。 #include <stdio.h> int d[100]; FILE *f; char fn[32]; int i,j,r; int main() {     for (r=1;r<=4;r++) {//第r行         for (j=1;j<=100;j++) {//第j个文件             sprintf(fn,"deta%d.txt",j);             f=fopen(fn,"r");             if (f) {                 for (i=0;i<r-1;i++) fscanf(f,"%*d");//跳过前r-1个数                 fscanf(f,"%d",&d[j-1]);//读取第r个数到d[j-1]中                 fclose(f);             }         }         for (i=0;i<100;i++) printf("%d ",d[i]);//显示第r行的100个数         printf("\n");//换行间隔     }     return 0; }
user-0 提问: c语言写的LRU页面置换算法，求大神帮忙修改语法错误

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

user: user-0
content: 对了，渣渣我用的还是c++6.0，谢谢大神指导
user-0 提问: c语言编程问题求助

回复:
user: user-1
content: if(p=NULL) 实际上是： p=NULL; if (p!=NULL)   这个一直为假。

user: user-0
content: 非常感谢,我用的VS2010,在编译时并没有报错,按照你的方法确实是成功了 不过还有一个问题,if(p = NULL)这种方式写确实有问题,可为啥能执行else, 并打印出了内存分配成功呢?

user: user-1
content: printf("%p\n",p);  //打印地址 if(p = NULL) { printf("内存分配失败\n"); }  改成 if(p==NULL)  这个是有警告的。
user-0 提问: 求救，模块化编程参数问题

回复:
user: user-1
content: 引用 4 楼 qq_35371144 的回复:谢谢   刚开始不会这些  第一次写  尝试着像3楼一样写代码，代码的书写格式是很重要的。

user: user-2
content: 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。

user: user-0
content: 谢谢   刚开始不会这些  第一次写

user: user-3
content: //我这程序为什么最后输入密码一直不正确 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<conio.h>  void cubao(int a[], int *key){    //函数申明有什么返回值 	int i = 0, j; 	static int k = 0;         //这里k你想表示已用的柜子数量，但k是局部变量，每次进来都初始化为0，之后就回收了，所以应该设为静态局部变量    	int c, e, f;                       	srand(time(0)); 	a[i] = rand() % 50 + 1; 	k++; 	for (j = 0; j<i; j++)          //原因同上，i每次进来都初始化为0 所以这个for根本不会执行 	{ 		if (a[i] == a[j]) 		{ 			i--; 		} 	} 	if (k <= 50)                    	{ 		srand(time(0));               		c = rand() % 65537 + 0; 		srand(time(0)); 		e = (a[i] + 10); 		f = e * 100000;               		*key = f + c;                //key=f+c 主要问题在这里，这里的key只是进来这个cubao函数后为它额外分配的一个地址，你改变的是这个函数里面的key而不是main里的key，要改变一个变量值要利用指针 		printf("箱号是%d\n密码是%d\n", a[i], *key); 	} 	else 		printf("柜子已满\n"); } void qubao(int* key){             //同理这里也应该传key的指针进来比较 	int psw; 	printf("请输入密码:\n");          	scanf("%d", &psw); 	if (psw == *key) 		printf("请取走物品\n"); 	else 		printf("欢迎下次光临\n"); } int main(){ 	int n; 	int a[50];                        //设有50个柜子 	int key=0; 	while (1) 	{ 		printf("欢迎使用\n"); 		printf("存请按0\n"); 		printf("取请按1\n"); 		scanf("%d", &n); 		if (n == 0) 		{ 			cubao(a, &key); 		} 		else if (n == 1) 		{ 			qubao(&key); 		} 		else 		{ 			break; 		} 	} 	return 0; } 测试已经通过，新手对指针以及局部变量的问题不熟练，多看资料，不会的时候一步一步调试

user: user-0
content: 还是不行哎      不知道怎么处理了

user: user-4
content: int key = 0;可以吗
user-0 提问: 分别统计字母 数字 空格和其他的个数

回复:
user: user-1
content: 将 if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) 写成这样 if(('a'<=c&&c<='z')||('A'<=c&&c<='Z')) 是不是可读性更好更不易出错呢？

user: user-2
content: 出不来是因为循环条件的问题，当没有遇到空字符时，循环是不会停下来的，键盘上输的都是有字符的，所以程序一直在等待输入，停不下来，所以出不来。你可以改成别的不能显示的ASCII字符当作停止条件，例如’\t‘(水平制表符)、'\n'(换行符)。   引用 1 楼 qq423399099 的回复:两个错误： 1.while((c=getchar())!='\0')应该是while((c=getchar())!='\n') 2.if(c>='a'&&c<='z'||c>='A'&&c<='Z')应该是if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))  #include<stdio.h> int main() { 	char c; 	int m=0,n=0,k=0,q=0; 	printf("请输入一串字符\n"); 	while((c=getchar())!='\n') 	{ 		if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) 			m++; 		else 			if(c>='0'&&c<='9') 				n++; 			else 				if(c==' ') 					k++; 				else 					q++; 	} 	printf("%d %d %d %d\n",m,n,k,q); 	return 0; }  if(c>='a'&&c<='z'||c>='A'&&c<='Z')这条语句没有错误，>=、<=的优先级大于&&，&&的优先级大于||

user: user-0
content: 引用 1 楼 qq423399099 的回复:两个错误： 1.while((c=getchar())!='\0')应该是while((c=getchar())!='\n') 2.if(c>='a'&&c<='z'||c>='A'&&c<='Z')应该是if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))  #include<stdio.h> int main() { 	char c; 	int m=0,n=0,k=0,q=0; 	printf("请输入一串字符\n"); 	while((c=getchar())!='\n') 	{ 		if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) 			m++; 		else 			if(c>='0'&&c<='9') 				n++; 			else 				if(c==' ') 					k++; 				else 					q++; 	} 	printf("%d %d %d %d\n",m,n,k,q); 	return 0; }   版主为什么(c=getchar())!='\n'不是'\0'’呢？

user: user-3
content: 两个错误： 1.while((c=getchar())!='\0')应该是while((c=getchar())!='\n') 2.if(c>='a'&&c<='z'||c>='A'&&c<='Z')应该是if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))  #include<stdio.h> int main() { 	char c; 	int m=0,n=0,k=0,q=0; 	printf("请输入一串字符\n"); 	while((c=getchar())!='\n') 	{ 		if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) 			m++; 		else 			if(c>='0'&&c<='9') 				n++; 			else 				if(c==' ') 					k++; 				else 					q++; 	} 	printf("%d %d %d %d\n",m,n,k,q); 	return 0; }
user-0 提问: 关于交换节点的问题

回复:
user: user-1
content: http://edu.csdn.net/huiyiCourse/detail/158

user: user-2
content: _DEBUG_ASSERT_可以不要 VAR_FILL_VALUE表示一定不正确的下标，指针版本改为NULL

user: user-2
content: 对于双向链表，交换位置最高需要写入6个指针，交换值需要写入3倍值长度的字节 所以当你的元素大于8字节的时候，交换位置更好  	void swap (INDEX index1 ,INDEX index2) { 		_DEBUG_ASSERT_ (index1 != VAR_FILL_VALUE && index2 != VAR_FILL_VALUE) ; 		if (mList[index2].next == index1) 			_SWAP_ (index1 ,index2) ; 		if (mList[index1].next == index2) { 			(mList[index1].prev != VAR_FILL_VALUE ? mList[mList[index1].prev].next : mFirst) = index2 ; 			(mList[index2].next != VAR_FILL_VALUE ? mList[mList[index2].next].prev : mLast) = index1 ; 			mList[index1].next = mList[index2].next ; 			mList[index2].prev = mList[index1].prev ; 			mList[index1].prev = index2 ; 			mList[index2].next = index1 ; 		} else { 			(mList[index1].prev != VAR_FILL_VALUE ? mList[mList[index1].prev].next : mFirst) = index2 ; 			(mList[index2].prev != VAR_FILL_VALUE ? mList[mList[index2].prev].next : mFirst) = index1 ; 			(mList[index1].next != VAR_FILL_VALUE ? mList[mList[index1].next].prev : mLast) = index2 ; 			(mList[index2].next != VAR_FILL_VALUE ? mList[mList[index2].next].prev : mLast) = index1 ; 			_SWAP_ (mList[index1].prev ,mList[index2].prev) ; 			_SWAP_ (mList[index1].next ,mList[index2].next) ; 		} 	}  如果你是要用指针的话，比如mList[index1].prev改成pointer1->prev就行了
user-0 提问: c语言&a[1]-&a[0]=1?a是整型数组

回复:
user: user-1
content: 标准就这么规定的  同理，一个int*指针+1移动的距离是4而不是1

user: user-2
content: Pointer Arithmetic Additive operations involving a pointer and an integer give meaningful results only if the pointer operand addresses an array member and the integer value produces an offset within the bounds of the same array. When the integer value is converted to an address offset, the compiler assumes that only memory positions of the same size lie between the original address and the address plus the offset.  This assumption is valid for array members. By definition, an array is a series of values of the same type; its elements reside in contiguous memory locations. However, storage for any types except array elements is not guaranteed to be filled by the same type of identifiers. That is, blanks can appear between memory positions, even positions of the same type. Therefore, the results of adding to or subtracting from the addresses of any values but array elements are undefined.  Similarly, when two pointer values are subtracted, the conversion assumes that only values of the same type, with no blanks, lie between the addresses given by the operands.

user: user-3
content: 引用 1楼小灸舞 的回复:因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的，标准中有这样一段话： When two pointers to members of the same array object are subtracted, the difference is divided by the size of a member. The result represents the difference of the subscripts of the two array members.  翻译过来就是：当同一个数组的两个成员的指针相减时，其差值为：地址值的差，再除以一个数组成员的size。这个结果代表了两个指针对应元素的下标之差。涨知识

user: user-4
content: 不管什么数组这个结果固定为1

user: user-0
content: 引用 1 楼 小灸舞的回复:因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的，标准中有这样一段话： When two pointers to members of the same array object are subtracted, the difference is divided by the size of a member. The result represents the difference of the subscripts of the two array members.  翻译过来就是：当同一个数组的两个成员的指针相减时，其差值为：地址值的差，再除以一个数组成员的size。这个结果代表了两个指针对应元素的下标之差。 原来如此。讲得很好，我懂了

user: user-5
content: 因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的，标准中有这样一段话： When two pointers to members of the same array object are subtracted, the difference is divided by the size of a member. The result represents the difference of the subscripts of the two array members.  翻译过来就是：当同一个数组的两个成员的指针相减时，其差值为：地址值的差，再除以一个数组成员的size。这个结果代表了两个指针对应元素的下标之差。
user-0 提问: 关于EasyX中一些函数不能使用的问题

回复:
user: user-1
content: winbgi不错。收藏待用。

user: user-2
content: 在2011年版之后被删了http://www.easyx.cn/downloads/View.aspx?id=5 解决办法,下载2010年版http://www.suxiazai.com/tuwenchuli/tuxianguanli/11385.html#download 或使用winbgi,http://csci.biola.edu/csci105/using_winbgi.html

user: user-0
content: 引用 3 楼 ipqtjmqj 的回复:在2011年版之后被删了http://www.easyx.cn/downloads/View.aspx?id=5 解决办法,下载2010年版http://www.suxiazai.com/tuwenchuli/tuxianguanli/11385.html#download 或使用winbgi,http://csci.biola.edu/csci105/using_winbgi.html  谢谢你的回答！很有帮助！

user: user-3
content: 谷歌搜索了下,原来EasyX是个图形库,在帮助里搜索setviewport还真没找到这个函数

user: user-0
user-0 提问: 如何用C语言输出一个超级长的小数到TXT文本中？

回复:
user: user-1
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

user: user-0
content: 还有就是 我现在用fprintf把一个char变量写入到文本中，发现它竟然占用了5个字节，char不是只占用一个字节的吗？ fprintf(ofp,"%c",sym[j]);   sym[j]是一个char数组 将这个字符数组输出后，我删掉一个字符，发现整个文本减少了5个字节，不过继续删的话每次减少1个字节，这是什么原因？

user: user-0
content: 引用 3 楼 sprawling 的回复:按数据结构存也可以啊，够简单吧。 虽然稍微查了一下，但还是不太懂你说的什么意思，能详细说一下吗？

user: user-0
content: 引用 4 楼 paschen 的回复:用字符串来存储这个“超级长”的小数 这样的话占用的字节数就是字符串长度吧，和我用数组效果一样

user: user-2
content: 用字符串来存储这个“超级长”的小数

user: user-3
content: 按数据结构存也可以啊，够简单吧。

user: user-0
content: 请问你说的是用fwrite吗？如果是，只能说占的字节数更多了。。。

user: user-4
content: 按字节写不就行了吗？
user-0 提问: 2*3矩阵转置

回复:
user: user-0
content: 谢谢版主  真好  我的问题解决了

user: user-1
content: 1.申请的数组应当是 int a[3][3];否则会越界 2.输出的时候应该是输出3行2列，而不是2行3列  #include<stdio.h> int main() {     void sort(int x[][3],int n);     int a[3][3];     int i,j;     printf("请输入一个2*3矩阵\n");     for(i=0;i<2;i++)         for(j=0;j<3;j++)             scanf("%d",&a[i][j]);         sort(a,2);         for(i=0;i<3;i++)         {             for(j=0;j<2;j++)                 printf("%d ",a[i][j]);             printf("\n");         } } void sort(int x[][3],int n) {     int i,j,t;     for(i=0;i<n;i++)         for(j=0;j<3;j++)             if(i<j)             {                 t=x[i][j];                 x[i][j]=x[j][i];                 x[j][i]=t;             } }
user-0 提问: 稀疏矩阵转化成三元组写入速度文件太慢了，怎么优化？

回复:
user: user-1
content: 在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快 写类似。

user: user-0
content: fseek的原因，怎么弄？

user: user-0
content: 请无视注释..
user-0 提问: 发起多个非阻塞connect，然后用epoll来监听它们，怎样判断连接的状态

回复:
user: user-1
content: 感觉楼主可以参考下这篇博客 http://www.cnblogs.com/yuxingfirst/archive/2013/03/08/2950281.html 作者提到  “使用非阻塞 connect 需要注意的问题是： 1. 很可能 调用 connect 时会立即建立连接（比如，客户端和服务端在同一台机子上），必须处理这种情况。 2. Posix 定义了两条与 select 和 非阻塞 connect 相关的规定： 1）连接成功建立时，socket 描述字变为可写。（连接建立时，写缓冲区空闲，所以可写） 2）连接建立失败时，socket 描述字既可读又可写。 （由于有未决的错误，从而可读又可写） 不过我同时用epoll也做了实验(connect一个无效端口，errno=110, errmsg=connect refused)，当连接失败的时候，会触发epoll的EPOLLERR与EPOLLIN，不会触发EPOLLOUT。 当用select检测连接时，socket既可读又可写，只能在可读的集合通过getsockopt获取错误码。 当用epoll检测连接时，socket既可读又可写，只能在EPOLLERR中通过getsockopt获取错误码。”  关于非阻塞connect时判断套接字是否连接成功，《unix网络编程卷1》中提到：   我觉得可以在epollin 中通过调用read来判断。
user-0 提问: 被代码虐成狗了，求救啊啊啊

回复:
user: user-0
content: 引用 1 楼 小灸舞的回复:undefined reference都是只有函数声明而找不到函数实现 检查你的附加包含目录和附加依赖项 看描述，没定义那个结构体的话是可以编译过的。不知道怎么跟那个结构体有冲突，在开源项目做开发的。。

user: user-0
content: 引用 1 楼 小灸舞的回复:undefined reference都是只有函数声明而找不到函数实现 检查你的附加包含目录和附加依赖项 看描述，没定义那个结构体的话是可以编译过的。不知道怎么跟那个结构体有冲突，在开源项目做开发的。。

user: user-1
content: undefined reference都是只有函数声明而找不到函数实现 检查你的附加包含目录和附加依赖项

user: user-2
content: 看不清你的图片，如果没定义没问题那问题就在你定义的这个结构体是否重名了等等，检查一下
user-0 提问: c语言程序问题

回复:
user: user-1
content: long fun (long s) { 	long lResult = 0, lANum, lNumCount = 0; 	char arNumber[128] = {0};  	while(s > 0) 	{ 		lANum = s % 10;		// 取得末尾一位数 		s /= 10;			// 删掉末尾一位数  		if ( lANum % 2 == 0)// 判断是偶数 		{ 			arNumber[lNumCount] = lANum;	// 记录一位符合条件的数 			lNumCount++; 		} 	}  	// 利用数组构建新数字 	while(lNumCount > 0) 	{ 		lNumCount--; 		lResult = lResult * 10 + arNumber[lNumCount]; 	}  	return lResult;    直接拿走

user: user-2
content: int func(int s) { 	int tmp = 0; 	int t = 0; 	int count = 0; 	while(s > 0) 	{ 		tmp = s % 10; 		if((tmp % 2) == 0){ 			if(count == 0) 				t = tmp; 			else{ 				tmp *= pow(10,count); 				t += tmp; 			} 			count++; 		} 		s /=10; 	} 	return t; }

user: user-2
content: int func(int s) {      /*********begin************/ 	int tmp = 0; 	int t = 0; 	int count = 0; 	while(s > 0) 	{ 		tmp = s % 10; 		if((tmp % 2) == 0){ 			if(count == 0) 				t = tmp; 			else{ 				tmp *= pow(10,count); 				t += tmp; 			} 			count++; 		} 		s /=10; 	} 	return t;         /******************end*****************/ }

user: user-3
content: 参考：  #include<stdio.h> long fun (long s)  { 	long sl=10, t; 	s /= 10;  	t = s % 10;  	while(s> 0) 	{  		s = s/100; 		t = t+s%10*sl ; 		sl = sl * 10; 	} 	return t; } void main()      { 	long s,m; 	//void TestFunc(); 	printf("\nPlease enter s:"); 	scanf("%ld", &s);      	m=fun(s); 	printf("The result is: %ld\n", m); 	//TestFunc(); }

user: user-4
content: long fun (long s) { 	/*********Begin**********/ 	long t = 0; 	long k = 1; 	while (s >= 10) 	{ 		s /= 10; 		t += s % 10 * k; 		k *= 10; 		s /= 10; 	} 	return t; 	/**********  End  **********/ }

user: user-5
content: 如果单纯取偶数位的数字,也可以先转成字符串； sprintf或者snprintf, 然后按照字符串下标依次取出对应的数值；
user-0 提问: 调不对 啊，关于吸收输入后的回车键

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

user: user-2
content: scanf("%d",&n)  后面不需要用getchar

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

user: user-4
content: 我给个建议，用switch 和case，这样好一点 结构也清晰，你的思路没有错！估计一点小错误 调试一下就估计OK了！

user: user-4
content: 我给个建议，用switch 和case，这样好一点 结构也清晰，你的思路没有错！估计一点小错误 调试一下就估计OK了！
user-0 提问: 为什么用fread读取二进制文件数据前面能正常显示后面就全是0

回复:
user: user-1
content: 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

user: user-1
content: 引用 8 楼 sds428 的回复:学习，学习，赵4老师的讲解太好了

user: user-2
content: 学习，学习，赵4老师的讲解太好了

user: user-3
content: 多维数组，很容易忽略  栈溢出的情况，因为每一维都很小 但是乘积很大  建议略微大一点的多维数组， 采用动态分配和全局变量这两种方式处理 以免，跟直觉发生冲突

user: user-4
content: 1、数组太大应该用动态分配内存  2、单步跟踪程序运行很容易找到问题原因

user: user-0
content: 引用 3 楼 qq423399099 的回复:你的int x[2800][2500];会导致栈溢出 2800*2500*4/1024/1024=26.7M我把后面数据的类型弄错了， short 弄成int了,现在解决了，谢谢~

user: user-5
content: 你的int x[2800][2500];会导致栈溢出 2800*2500*4/1024/1024=26.7M

user: user-0
content: 这样可以吗...

user: user-0
content: int x[2800][2500]; fseek(fp2, 1028L, SEEK_SET); 	fread(x, sizeof(int), 1, fp2); 	for (int row = 0; row < 2800; row++) 	{ 		for (int col =0; col < 2500; col++) 		{ 			if (x[row][col]) { 				cout << x[row][col]; 			} 			 		} 		cout << endl; 	}
user-0 提问: 指针++的问题。

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

user: user-2
content: 0012ff4c是变量a地址对吧。  对  b=b+1000000，是否告诉指针继续移动40万个字节？  是  那么005004c储存着什么东西呢？ 不知道  此时再来一句*b=20;，应该是在005004c写入20。我试了，出错，但没出现电脑死机等问题啊，不是说指针在错误位置写入不合适东西会很严重嘛？ 这种情况是否出错一种不确定行为，但每个程序的内存空间都是独自的，并不会影响到其他程序，只可能造成该程序崩溃  若是b=b+1，应该是指针移动4个字节对吧？那也到达其它程序的地盘了吧，怎么就没出错？ 同上，地址空间都是虚拟独立的，你程序不会写到其他进程内，除非你使用专门API，至于没出错，上面也说了，是一t  引用 5 楼 qq_16774199 的回复:[quote=引用 4 楼 paschen 的回复:]  能否简单介绍如何看到0050048c储存的信息？ 假如把内存中一段信息取出来分析，不就能看出它属于哪个程序，修改信息不就能控制程序。我知道实际没那么简单，但是不是这个理？就是帮我理一下思路，加深对电脑的了解。谢谢。[/quote]  你先去理解进程空间虚拟内存，我都没明白你说的0050048c是什么内存，你的程序可以有一个0050048c，别的程序也可以有一个0050048c，他们并不是同一个0050048c

user: user-3
content: 楼主了解一下进程、虚拟内存地址空间。

user: user-0
content: 引用 4 楼 paschen 的回复:  能否简单介绍如何看到0050048c储存的信息？ 假如把内存中一段信息取出来分析，不就能看出它属于哪个程序，修改信息不就能控制程序。我知道实际没那么简单，但是不是这个理？就是帮我理一下思路，加深对电脑的了解。谢谢。

user: user-4
content: 分段机制让每个程序都处在不同的段,各程序之间一般无法直接通信.应用程序特权级为3(最低),而系统级程序都是属于0(最高),特权级低的访问特权级高的会导致处理器异常.

user: user-2
content: 0012ff4c是变量a地址对吧。  对  b=b+1000000，是否告诉指针继续移动40万个字节？  是  那么005004c储存着什么东西呢？ 不知道  此时再来一句*b=20;，应该是在005004c写入20。我试了，出错，但没出现电脑死机等问题啊，不是说指针在错误位置写入不合适东西会很严重嘛？ 这种情况是否出错一种不确定行为，但每个程序的内存空间都是独自的，并不会影响到其他程序，只可能造成该程序崩溃  若是b=b+1，应该是指针移动4个字节对吧？那也到达其它程序的地盘了吧，怎么就没出错？ 同上，地址空间都是虚拟独立的，你程序不会写到其他进程内，除非你使用专门API，至于没出错，上面也说了，是一种不确定行为

user: user-5
content: 0012ff4c是变量a地址对吧。 对，是a的地址 b=b+1000000，是否告诉指针继续移动40万个字节？ 应该是400万吧，呵呵 那么005004c储存着什么东西呢？ 400万个字节约等于4M，八成已经超出你的栈区了，到达其他区了，里面存的东西是未知的 此时再来一句*b=20;，应该是在005004c写入20。我试了，出错，但没出现电脑死机等问题啊，不是说指针在错误位置写入不合适东西会很严重嘛？ 电脑死机太严重了，它说的严重还不至于到那个程度 若是b=b+1，应该是指针移动4个字节对吧？那也到达其它程序的地盘了吧，怎么就没出错？ b+1应该还没有到其他程序地盘，还在你当前的工作栈内，这部分内存现在没有任何保护，你可以随便写，这也是C语言的缺点吧

user: user-6
content: 如果写入保护内存，抱歉，会报错，而不是死机之类的 因为写，读，执行 都会可能产生异常 如果读写保护内存，那么就是异常处理就是回报错误 如果读写的内存，有权读写，那么内存在真实内存中，会直接读写 不在，会产生缺页中断，然后，操作系统执行页面调度，完成后继续执行 这回就可以正确执行了 总之，没那么容易死机啥的了 当年死机，是因为 Win98这类的操作系统不稳定

user: user-7
content: 电脑死机。。。 你太高估你写的这个程序了。 005004c这种都是虚拟内存。 严重的后果是指程序崩溃（这还不严重？）

user: user-8
content: 005004c并非是你自己开的内存，自然不能随你写。肯定出错了，报不报出来就不知道了
user-0 提问: 问题是：为什么单词you会出现在结果中？我用了一个循环来判断它啊？

回复:
user: user-0
content: 不是添加，是把上一行的m=0移到括号外面来。

user: user-1
content: #include <stdio.h>  2   #include <ctype.h>                                                                                                                                                                                          1 #include <string.h>   2     3 char WORD[10][10]={"you","for","your","on","no","if","the","in","to","all"};   4 char xx[][50]={"you are a student.,","He am NOT a  student."};   5     6 int maxline=2;        7     8 void DelWord()        9 {  10     int i,j,k,m,len,s,t;  11     char ww[20], yy[20], line[80];  12       13     for(i=0;i<maxline;i++)  14     {  15     |   m = 0;       16     |   line[0] = 0;  17     |   len = strlen(xx[i]);  18     |   for(j = 0; j <= len; j++)  19     |   |   if(isalpha(xx[i][j]))  20     |   |   |   ww[m++] = xx[i][j];  21     |   |   else  22     |   |   {  23     |   |   |   ww[m] = 0;  24     |   |   |   if(m) {   25     |   |   |   |   for(k=0;k<10;k++)  26     |   |   |   |   |   if(strcmp(ww,WORD[k]) == 0)  27     |   |   |   |   |   |   break;  28     |   |   |   |   if(k >= 10)  29     |   |   |   |   {  30     |   |   |   |   |   //puts(ww);  31     |   |   |   |   |   s=0;  32     |   |   |   |   |   for(t=m-1;t>=0;t--)  33     |   |   |   |   |   |   yy[s++]=ww[t];  34     |   |   |   |   |   yy[s]=0;  35     |   |   |   |   |   strcat(line,yy);  36     |   |   |   |   |   m=0;  37     |   |   |   |   }     38     |   |   |   |   m = 0;    //add this sentence  39     |   |   |   }    40     |   |   }     41     |   strcpy(xx[i],line);  42     }     43 }     44 int main(void)       45 {  46     int i;           47     DelWord();       48       49     for(i=0;i<maxline;i++)  50     |   printf("%s\n",xx[i]);  51       52     return 0;        53 }

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

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

user: user-0
content: 引用 1 楼 user-3 的回复:好长啊，自己调试一下吧。  是只是 you 么，其它的那个单词有好用的么，如果其它的也没有好用的就要考虑语法问题了。  如果只是you 就要看看you有啥特殊的了，除了是第一个没看出有啥特殊的。  建议在  if(strcmpi(ww,WORD[k])==0) break; 位置，把比较用的两个字符串打印出来看看是不是你想要的，就应该能找到问题了。 其它的都ok，break这条语句是不区分大小写判断是否有一样的单词，如果有，则不连接到line数组中，相当于删除该单词。

user: user-3
content: 好长啊，自己调试一下吧。  是只是 you 么，其它的那个单词有好用的么，如果其它的也没有好用的就要考虑语法问题了。  如果只是you 就要看看you有啥特殊的了，除了是第一个没看出有啥特殊的。  建议在  if(strcmpi(ww,WORD[k])==0) break; 位置，把比较用的两个字符串打印出来看看是不是你想要的，就应该能找到问题了。
user-0 提问: 如何学习C语言编程

回复:
user: user-1
content: 我感觉就跟着一本经典的书籍学习，边学理论，边敲代码，做做习题，感觉是真的会很乏味，有空去网上搜搜有趣的应用调节一下吧。。。

user: user-2
content: 不是搞嵌入式,不要学C语言了.学其它的吧.

user: user-3
content: 程序错了，用搜索引擎搜索错误码。  你碰到的错误，在网上基本都能找到对应的案例。  一个好的学习方法就是看别人的经典代码，认真理解，在此基础上修改，做出自己的东西。

user: user-4
content: C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817

user: user-5
content: 基础语法是必须的，否则看别人简单代码都有疑惑的，从别人简单片段理解，接着理解网络上的能运行的代码，弄到自己电脑跑跑，能跑起来的，就尝试添加打印信息如printf来理解程序运行到哪一步的结果，为什么会变成这样。一步一步来，

user: user-6
content: 我学C的过程是，一边看"21天学通C++"一边做上面的部分习题(当然我没学C++) --> http://c-faq.com/ --> 翻阅 stackoverflow "highest voted c questions" --> leetcode oj --> 翻阅 C99 标准草案 --> 翻阅 c99 rationale

user: user-7
content: 语言只是一门工具，关键在于实践，还是多打代码吧！

user: user-8
content: 我觉得还是多练习吧，普通人用砖砌墙都砌不直，师傅可以用砖盖房子，都是有个过程，只不过现在的人都比较急功近利，忽视了很多东西而已（比如练武功要蹲马步。。） 用直观的数据，有的学生大学四年的代码量不超过一千行，有的牛人可以达到几万行，那最后的水平是肯定的。 书上主要是为了教学，除非是专门案例的书，一般都只是介绍技术点和核心代码。完整实用的程序网络上也有很多，不过一般都是基于某些API或者框架。

user: user-9
content: 对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

user: user-10
content: 这个得需要多练习了；对于语法错误,多次遇到就知道哪儿出错了,就是"久病成医"； 练习先从简单程序开始,一点一点的学习复杂的程序； 平时也可以遇到问题多百度,自己去查错误问题； 总之,不能懒,不能退缩, 遇到问题解决问题~
user-0 提问: Debug的时候 return *p一步出现30xC0000005: 读取位置 0x00000000 时发生访问冲突

回复:
user: user-1
content: 你对NULL指针进行了操作 稍微调试了下发现Add函数要返回的时候，此时p3已经是NULL了，你还*p3就出现异常了 同时你的Compare里面也不对else {if(a=b)是什么鬼，多了个{少了个=  Windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 Linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。
user-0 提问: 蔡勒公式有问题

回复:
user: user-0
content: 计算某一天星期几的几个公式 蔡勒公式：W = ([C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1) mod 7． 吉姆拉尔森公式：W =((Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+[13*(M+1)/5 ]+d) mod 7． 蔡农公式：W = (C%4*5+Y+Y/4+(13*M+8)/5+D)%7

user: user-1
content: y=year;改成ty=year;试试  #include<stdio.h> int main() {     int year,month,day,ty,m,y,c,d,weeks;     scanf("%d%d%d",&year,&month,&day);     ty=year;     m=month;     if(m<3)     {         m=12+m;         ty--;     }     y=ty%100;     c=ty/100;     d=day;     weeks=(y+y/4+c/4-2*c+(26*(m+1))/10+d-1)%7;     printf("%d\n",weeks); }

user: user-0
content: 蔡勒公式 公式中的符号含义如下： w：星期（计算所得的数值对应的星期：0-星期日；1-星期一；2-星期二；3-星期三；4-星期四；5-星期五；6-星期六）[1] c：年份前两位数 y：年份后两位数 m：月（m的取值范围为3至14，即在蔡勒公式中，某年的1、2月要看作上一年的13、14月来计算，比如2003年1月1日要看作2002年的13月1日来计算） d：日 [　]：称作高斯符号，代表向下取整，即，取不大于原数的最大整数。 mod：同余（这里代表括号里的答案除以7后的余数）
user-0 提问: 初学指针疑问，为什么不用普通变量储存地址，要专门发明指针变量来储存呢？

回复:
user: user-0
content: 引用 12 楼 贫僧博企的回复:3楼说得对啊. 看样子,LZ没学过汇编啊. 我没学过，但是从下往上学会不会太久太难。

user: user-1
content: 它们不都是“变量”么？

user: user-2
content: 3楼说得对啊. 看样子,LZ没学过汇编啊.

user: user-3
content: 引用 楼主 qq_16774199 的回复:初学指针疑问，为什么不用普通变量储存地址，要专门发明指针变量来储存呢？  在某些方面用起来方便吧， 其实指针存的也是数字，也有个别人，用来和数字间转来转去， 不过很少见。  就像有了刀子，还发明了锯子一样吧。（不知道刀子和锯子是哪个在先）

user: user-4
content: 引用 9 楼 DelphiGuy 的回复:如果指针扩展到1024位，那么必然会有相应的整数类型，诸如int1024之类的，就像现在指针64位，但是__int64、long long出现得比64位指针还早。 那还真不一定。

user: user-5
content: 如果指针扩展到1024位，那么必然会有相应的整数类型，诸如int1024之类的，就像现在指针64位，但是__int64、long long出现得比64位指针还早。

user: user-4
content: 引用 7 楼 DelphiGuy 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 万一将来CPU的寻址范围达到2^1024……  这个应该没有可能，超过2^64的可能性都很小，可观测宇宙范围内的基本粒子总数大约是10^80级别，也就是2^265多一点，所以2^512已经超过所需了。 [/quote] 我的意思是到那时任何一个普通变量都存不下一个指针值了。

user: user-5
content: 引用 4 楼 zhao4zhong1 的回复:万一将来CPU的寻址范围达到2^1024……  这个应该没有可能，超过2^64的可能性都很小，可观测宇宙范围内的基本粒子总数大约是10^80级别，也就是2^265多一点，所以2^512已经超过所需了。

user: user-6
content: 指针就是普通变量

user: user-7
content: 因为32位的cpu，不知对不对，哈哈 32/8 = 4字节。  现在都有64位了，所以有长指针了。

user: user-4
content: 万一将来CPU的寻址范围达到2^1024……

user: user-8
content: 因为指令集里面有一种间接寻址的方式，抽象出来就是指针了

user: user-9
content: 普通变量存储不了地址，比如你定义一个变量给他赋值一个看起来像地址的数据 const int a = 0x000000c0； 这时a只是等于这么一个十六进制的值，你无法操作0x000000c0这个地址的内存（当然，即使是指针，如果这么定义，你们无法修改这个地址中的数据） 另外，最主要的，指针可以从堆上动态申请内存

user: user-5
content: 指针也是基本类型，和char、int之类的一样。
user-0 提问: 请教，指针无非就储存个地址，为什么还要指定类型？

回复:
user: user-1
content: 没用类型，那->符号怎么用？ 指针++怎么计算？

user: user-2
content: ++ptr内存到底加多少, array[4]难道是指偏移4个字节？

user: user-3
content: 引用 楼主 qq_16774199 的回复:请教，指针无非就储存个地址，为什么还要指定类型？ 方便程序员啊，也方便编译器做检查。提前发现错误。

user: user-4
content: 我是这样理解的，指针确定这个数据的起点，而这个数据多大，占几个字节，以什么方式读取，这都是数据类型来决定的

user: user-5
content: 强类型的语言， 编译器可以在编译期间检查程序有效性。 跟弱类型语言比较下。

user: user-5
content: 类型就是内存结构， 指针的值规定了起点， 类型规定了大小和组分。

user: user-6
content: 自己判断啥类型！！！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-7
content: 你不定义类型怎么区分这块内存存的是什么类型的数据？

user: user-8
content: 你买个房还要分户型呢？

user: user-9
content: 不指定类型，那我要以哪种方式解析出这个地址对应的值呢？

user: user-10
content: 这个。。。微机原理学了吗？简单的说，请思考16位程序、32位程序、64位程序的区别。。。
user-0 提问: 小弟 初学C语言 有一题不明 还望大神提点

回复:
user: user-1
content: 从楼主的描述来看，ratingCounters[11]刚好处在number的位置，ratingCounters[11] = 0;等价于number=0 这样就可以解释调换顺序的区别了。

user: user-1
content: 数组越界。 int ratingCounters[11];//用来存储每个分数的个数 这个数组的合法范围是0~10，而不是1~11 所以， for (i = 1; i <= 11; ++i) 应该是 for (i = 0; i < 11; ++i)

user: user-0
content: 引用 3 楼 qq423399099 的回复:眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  谢啦

user: user-0
content: 引用 1 楼 brookmill 的回复:数组越界。 int ratingCounters[11];//用来存储每个分数的个数 这个数组的合法范围是0~10，而不是1~11 所以， for (i = 1; i <= 11; ++i) 应该是 for (i = 0; i < 11; ++i)   感谢大神  确实是因为越界了

user: user-2
content: 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。
user-0 提问: 请教关于EOF的一个问题

回复:
user: user-1
content: cin读入标准输入，直到遇到文件结束符结束符，而在Windows中CTRL+Z相当于文件结束符EOF windows认为，如果缓冲中还有其它内容，ctrl+z不表示输入结束，仅代表当前行输入结束，只在单独一个ctrl+z的时候才表示输入结束。

user: user-2
content: <Enter>,<Ctrl+Z>,<Enter>

user: user-1
content: windows认为，如果缓冲中还有其它内容，ctrl+z不表示输入结束，仅代表当前行输入结束，只在单独一个ctrl+z的时候才表示输入结束。

user: user-0
content: 引用 4 楼 qq423399099 的回复:因为它没有读到EOF当然不会跳出循环。 你要输入一行就跳出循环应该写成while((c = getchar()) != '\n') windows下要输入CTRL+Z才相当于结束符EOF  我输入的是'a'+EOF+'\n'，为啥没有读到呢？

user: user-1
content: 因为它没有读到EOF当然不会跳出循环。 你要输入一行就跳出循环应该写成while((c = getchar()) != '\n') windows下要输入CTRL+Z才相当于结束符EOF

user: user-0
content: 引用 2 楼 qq423399099 的回复:cin读入标准输入，直到遇到文件结束符结束符，而在Windows中CTRL+Z相当于文件结束符EOF windows认为，如果缓冲中还有其它内容，ctrl+z不表示输入结束，仅代表当前行输入结束，只在单独一个ctrl+z的时候才表示输入结束。  那我请问缓冲中还有其他内容时，while((c = getchar()) != EOF)到底为什么变成等待输入的状态？ 不该是此时跳出循环么？
user-0 提问: 关于C语言海龟图问题

回复:
user: user-1
content: 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

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

user: user-0
content: 谢谢赵老师和版主大人的悉心教诲，因为自学C语言，一开始就没有养成一个好习惯去自己调试程序，真的谢谢你们能够抽出时间来告诉我怎么学习C语言
user-0 提问: 各位大大帮帮忙，关于fwrite函数

回复:
user: user-1
content: 可以试试在系统下跑一跑会不会无故退出,如果不会,应该是目标运行环境的问题；

user: user-2
content: 1楼的fclose放错位置了，应该在if的大括号里面。 还可以试试先写第3个文件再写前两个。 既然SaveInitData、SaveSlideData、SaveCtrlData这些都是连续的，为什么不一次写300字节呢？不过这也没什么本质区别。

user: user-0
content: 本来是2万多字节一次性写入的，结果会退出，后来改成现在这样分开写入，还是退出 真是没辙了

user: user-0
content: 引用 2 楼 brookmill 的回复:其它看不出什么问题了。延时、fflush应该都没什么关系。 再就是那些自定义的数组和结构，使用是否正确，只有你自己知道了。 嗯我再检查检查，是一个比较大的数组两万多字节， 类似这样的 U8 SaveData[26302]; U8 *SaveInitData=SaveData; U8 *SaveSlideData=SaveData+100; U8 *SaveCtrlData=SaveData+200; ......

user: user-3
content: 硬盘上有坏道。我再猜。

user: user-3
content: 磁盘空间满。我猜。

user: user-0
content: 引用 2 楼 brookmill的回复:其它看不出什么问题了。延时、fflush应该都没什么关系。 再就是那些自定义的数组和结构，使用是否正确，只有你自己知道了。 跟数组没关系，随便新建一个100字节的数组，重复保存保存263次，也会死，保存少点，比如64次就没事， for(i=0;i<263;i++)     fwrite(aaa,1,100,fp);

user: user-0
content: 引用 6 楼 brookmill的回复:1楼的fclose放错位置了，应该在if的大括号里面。 还可以试试先写第3个文件再写前两个。 既然SaveInitData、SaveSlideData、SaveCtrlData这些都是连续的，为什么不一次写300字节呢？不过这也没什么本质区别。 只保存一次没问题，随便哪个文件都没事

user: user-0
content: 我已经放弃了。现在是分成几个比较小的文件分开保存，目前一切正常。谢谢大家帮忙。

user: user-3
content: 写入速度限制的话，你多次写之间得加适当的延时。

user: user-0
content: 也就是说，程序应该没问题了。 存储设备是64M的DOC电子盘，写入速度据说很慢500K/S,不知道有没有关系。 因为在两台设备上都有问题，应该不是空间和坏道的问题

user: user-0
content: 引用 1 楼 brookmill 的回复:1. 是FILE * 还是 File * 2. 同样的代码复制好几遍的时候，就可以考虑写个函数了，比如 fp = fopen("par1.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);  fp = fopen("par2.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);  fp = fopen("par3.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);  是FILE，代码是手敲的，公司的项目，没法拷贝

user: user-2
content: 其它看不出什么问题了。延时、fflush应该都没什么关系。 再就是那些自定义的数组和结构，使用是否正确，只有你自己知道了。

user: user-2
content: 1. 是FILE * 还是 File * 2. 同样的代码复制好几遍的时候，就可以考虑写个函数了，比如 fp = fopen("par1.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);  fp = fopen("par2.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);  fp = fopen("par3.dat", "wb"); if(fp != NULL) {     save(fp); } fclose(fp);
user-0 提问: 有没有大牛 帮我解决这两个程序题  小弟感激不尽

回复:
user: user-1
content: #include"stdio.h" #include"stdlib.h" #include"string.h" int main(){ 	int i,n,len,j=0,j1=0,flag; 	char buf[50] = { 0 };//存放输入的字符串 	char s[123] = { 0 };//a到z是97到122    s这个数组每个位置代表着一个字母，里面的值表示这个字母出现的次数 	char buf_puts[50] = { 0 }; 	printf("输入字符串\n"); 	scanf("%s", buf); 	printf("输入字符出现次数\n"); 	scanf("%d", &n); 	len = strlen(buf); 	for (i = 0; i < len; i++){ 		s[buf[i]]++;  //每个字母出现的次数都存起来 	} 	for (i = 0; i < len; i++){ 		if (s[buf[i]] == n){   //找出次数与n相同的 			flag = 0; 			for (j1 = 0; j1 < j;j1++){                  				if (buf_puts[j1] == buf[i]){       //buf_puts是已经输出过的字符，flag置1表示此字符已经输出过一次 					flag = 1; 					break; 				} 			} 			if (flag == 0){ 				printf("%c", buf[i]); 				buf_puts[j++] = buf[i]; 			} 		} 	}  	return 0; } 上一个有点问题 这个已调试通过

user: user-1
content: #include"stdio.h" #include"stdlib.h" #include"string.h" int main(){ 	int i,n,len,j=0,j1=0,flag; 	char buf[50] = { 0 };//存放输入的字符串 	char s[123] = { 0 };//a到z是97到122    s这个数组每个位置代表着一个字母，里面的值表示这个字母出现的次数 	char buf_puts[50] = { 0 }; 	printf("输入字符串\n"); 	scanf("%s", buf); 	printf("输入字符出现次数\n"); 	scanf("%d", &n); 	len = strlen(buf); 	for (i = 0; i < len; i++){ 		s[buf[i]]++;  //每个字母出现的次数都存起来 	} 	for (i = 0; i < len; i++){ 		if (s[buf[i]] == n){   //找出次数与n相同的 			flag = 0; 			for (j1 = 0; j1 < j;j1++){                  				if (buf_puts[j++] == buf[i]){       //buf_puts是已经输出过的字符，flag置1表示此字符已经输出过一次 					flag = 1; 					break; 				} 			} 			if (flag == 0){ 				printf("%c", buf[i]); 				buf_puts[j++] = buf[i]; 			} 		} 	}  	return 0; } 第一题 因为会重复输出的问题略微繁琐了  可自行研究

user: user-2
content: 仅供参考：#include <stdio.h> #include <string.h> char s1[]="delete"; char s2[]="select"; unsigned char n[256]={0}; char r[257]; int i,L,o=0; void main() {     L=strlen(s1); for (i=0;i<L;i++) if (!n[(unsigned int)s1[i]]) n[(unsigned int)s1[i]]=++o;     L=strlen(s2); for (i=0;i<L;i++) if (!n[(unsigned int)s2[i]]) n[(unsigned int)s2[i]]=++o;     L=0;     for (o=1;o<=256;o++) {         for (i=0;i<256;i++) {             if (o==n[i]) {                 r[L++]=i;                 break;             }         }         if (i>=256) break;     }     r[L]=0;     printf("[%s]\n",r); } //[deltsc]
user-0 提问: 这个延时程序看了很久都没弄懂到底延时时间是多少，求大神指点。

回复:
user: user-1
content: 要看晶振了,通过晶振计算出执行一条指令需要的时间； 不过,这样的延时是不准确的,不如使用中断来做的精确

user: user-2
content: n*5000的量纲不是时间。

user: user-0
content: 那我可以认为延时时间是n*5000吗？

user: user-2
content: 使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。

user: user-3
content: 具体事件多少未知，反正是n * 5000次循环。

user: user-0
content: 难到这个延时函数是错的？？

user: user-4
content: 未知 .... 与太多东西相关了 ...  ================== 开了优化，可能没有任何延迟。整个函数都可能被完全优化掉。

user: user-0
content: 我用的晶振是12M的，是用在单片机上面的。但是我没弄懂这个延时函数，所代表的延时时间。

user: user-3
content: 既然是单片机，拿你可以读它的计时器计数，类似PC上8253/8254的计数器0，在两次计数之间调用delay，然后根据计数差值和晶振频率就可以算出时间。

user: user-5
content: 延时有忙延时，和定时器延时两种方案 忙延时就是循环 需要跟汇编关联，确定每个指令执行多少周期 一共执行多少指令 然后延时 定时器延时，PC上，在多线程，多进程环境下，用的多点 嵌入式，也可自行处理， 或者采用实时操作系统，定时器来延时 定时器延时，基本不占用CPU。而是倚靠定时器硬件的定时中断，到达延时的目的

user: user-6
content: 这跟指令周期有关（跟CPU速度相关：架构、流水线、频率、Cache等有关），单片机上可能有用，一般不这么用吧。

user: user-7
content: 这是嵌入式里面的程序吗？

user: user-8
content: 这个函数的延时时间需要你自己仿真。外部晶振不一样，延时时间是不同的！
user-0 提问: c如何实现包含字串的查找功能

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

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

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

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

user: user-1
content: 处理中文请使用wchar_t、wcsstr、L"中文"

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