Question: 【华为笔试题】程序发生段错误，可能是数组越界，堆栈溢出（比如，递归调用层数太多）

第一，首先需要注意数组的大小，如果用vector，就不需要在使用前约定范围了； 第二，需要注意最大值查找的范围，如果开始的位置>结束的位置，就会出错，这里需要加一个判断； 第三，多个case，可以输入多组测试用例； 如果这三点都可以解决，就没什么问题了。

U A B ID 为A 的成绩更新为 B 假设 A=3，B=6 U 3 6 的意思是 成绩为  1 2 3 4 5  ID 现在和成绩相等 更改后 变成 1 2 6 4 5 估计是你理解错了更改的意思了 假设用数组储存成绩 用ID-1表示下标 int scores[5];表示五个学生的成绩 U 3 6 就是  scores[3-1] =6; 这种题目，其实就相当于，做个 命令语言的解释器 U 3 6 命令 ：把第三个学生（ID=3 的学生）的成绩改为6 Q 1 5 命令 ：输出 ID从1 到 5 的学生中，的成绩最好学生的分数

引用 12 楼 Falleyes 的回复:你的代码水平，慢慢提高吧，多看看基础的东西。话说你是哪个省的，华为校招已经开始了啊？ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h>  int main(void){ 	int N, M, A, B; 	int* score; 	int i, max; 	char C;  	scanf("%d%d", &N, &M);  	score = (int*)malloc(sizeof(int)*N);  	for (i = 0; i < N; i++) 		scanf("%d", &score[i]);  	while (M--){ 		fflush(stdin); 		scanf("%c%d%d", &C, &A, &B); 		if (C == 'Q'){ 			max = score[A - 1]; 			for (i = A - 1; i < B; i++){ 				if (max < score[i + 1]) 					max = score[i + 1]; 			} 			printf("%d\n", max); 		} 		if (C == 'U') 			score[A - 1] = B; 	}  	free(score);  	return 0; } max = score[i + 1]这句数组越界，总算对了 #include <stdio.h> #include <stdlib.h> #include <string.h>   int main(void) {     char C;     int N, M, A, B;     int *score;     int i, max, temp;               while(scanf("%d%d", &N, &M) == 2)     {              	score = (int *)malloc(sizeof(int)*N); 	     	for (i = 0; i < N; i++)     	{         	scanf("%d", &score[i]);     	}             	while (M--)     	{     		scanf(" %c%d%d", &C, &A, &B);     	         	if (C == 'Q')     		{                         if (A > B)                 {                     temp = A;                     A = B;                     B = temp;                 }                 max = score[A-1];         	         		for (i = A; i < B; i++)         		{        	    		if (max < score[i])             		{             		max = score[i];	             		}         		}         		printf("%d\n", max);     		}     		if (C == 'U')     		{         		score[A-1] = B;     		}      	}         free(score);     }     return 0; }

引用 14 楼 lizi_stdio 的回复:[quote=引用 12 楼 Falleyes的回复:]你的代码水平，慢慢提高吧，多看看基础的东西。话说你是哪个省的，华为校招已经开始了啊？ 你这个只有1组数据。这题怎么提交？[/quote] 可以改成循环测试多组数据，我这个程序只提供基本的改正。 提交。。。我也不清楚楼主的是哪个区的，这已经开始笔试了。总之，我这边山东区还没有开始正式笔试。你投了简历的话就慢慢等吧

参考代码 /**************************************  *FILE    :C:\Users\Administrator\desktop\214\main.cpp  *PROJECT :NULL  *AUTHOR  :707wk  *CREATED :2015/9/5 10:01:36  *TEXT    :NULL  *EMAIL   :gtsoft_wk@foxmail.com  *CODE    :https://github.com/707wk  *LOGO    :                #########                                      ############                                    #############                                  ##  ###########                                ###  ###### #####                               ### #######   ####                             ###  ########## ####                           ####  ########### ####                        #####   ###########  #####                     ######   ### ########   #####                   #####   ###   ########   ######                ######   ###  ###########   ######             ######   #### ##############  ######           #######  ##################### #######          #######  ##############################        #######  ###### ################# #######       #######  ###### ###### #########   ######       #######    ##  ######   ######     ######       #######        ######    #####     #####         ######        #####     #####     ####           #####        ####      #####     ###             #####      ;###        ###      #                 ##       ####        ####                ***************************************/  #include <stdio.h>  #define N 30000 #define M 5000  int score[N];  int main() { 	int len=0; 	int operatenum=0; 	int A; 	int B; 	 	scanf("%d%d",&len,&operatenum); 	 	for(int i=0;i<len;i++) 	{ 		scanf("%d",score+i); 	} 	 	for(int i=0;i<operatenum;i++) 	{ 		char operate; 		getchar(); 		scanf("%c%d%d",&operate,&A,&B); 		if(operate=='Q') 		{ 			int maxindex=A-1; 			for(int j=A;j<B;j++) 			{ 				if(*(score+maxindex)<*(score+j))maxindex=j; 			} 			printf("%d\n",*(score+maxindex)); 		}	 		else 		{ 			score[A-1]=B; 		} 	} 	 	return 0; }

引用 15 楼 Falleyes的回复:[quote=引用 14 楼 lizi_stdio 的回复:] [quote=引用 12 楼 Falleyes的回复:]你的代码水平，慢慢提高吧，多看看基础的东西。话说你是哪个省的，华为校招已经开始了啊？ 你这个只有1组数据。这题怎么提交？[/quote] 可以改成循环测试多组数据，我这个程序只提供基本的改正。 提交。。。我也不清楚楼主的是哪个区的，这已经开始笔试了。总之，我这边山东区还没有开始正式笔试。你投了简历的话就慢慢等吧[/quote] 想提交看结果的，算了，我弄弄其他题目。这题在笔试里面只能算简单题。

引用 9 楼 lonely1206 的回复:我的代码，我用vim测试了下，一组数据情况下，输入数据不多是成功的，输入的数据多了，就发生段错误，不懂。。。#include <stdio.h> #include <stdlib.h> #include <string.h> int N, M, A, B; char C; int main(void) {          int score[N];     int i, max;               scanf("%d%d", &N, &M);  	     for (i = 0; i < N; i++)     {         scanf("%d", &score[i]);     }             while (M--)     {     	scanf(" %c%d%d", &C, &A, &B);     	         if (C == 'Q')     	{         	max = score[A-1];         	         	for (i = A; i < B; i++)         	{        	    	if (score[i-1] < score[i])             	{             	max = score[i];         		             	}         	}         	printf("%d\n", max);     	}     	if (C == 'U')     	{         	score[A-1] = B;     	}     }     return 0; } 你没有对N进行赋值，然后就声明int score[N]，这个数组大小的N，是依据环境决定的。之后你读取值赋值给N，但是score数组的大小没有改变啊。

我的程序提交运行的结果是：  答案错误:您提交的程序没有通过所有的测试用例  测试用例: 9 10 28 49 11 35 40 17 57 4 6 Q 9 9 U 9 79 Q 9 5 Q 4 8 U 2 27 U 8 40 U 4 77 U 7 71 U 4 44 U 8 51  对应输出应该为: 6 79 57

引用 7 楼 xiaoxuhao 的回复:你的代码里有多处错误，主要是： 1、int score[N];这样定义是不行的，编译器不知道怎么给score分配内存； 2、scanf("%c%d%d", &C, &A, &B);这一句存在吃回车问题，需要规避一下； 3、缺少用M来构造的外层for循环； 4、if (C == 'Q')分支中，数组下标和比较逻辑都有问题；  我把这些问题改了一下，在vs2010下调好了，请参考：  #include <stdio.h> #include <stdlib.h> #include <string.h>   int main(void) {     int N, M, A, B;     int score[10];     int i,j,max;     unsigned char C[2];           scanf("%d%d", &N, &M);        for (i = 0; i < N; i++)     {         scanf("%d", &score[i]);     }  	for(j = 0; j < M; j++) 	{  	    scanf("%1s%d%d",&C, &A, &B); 	   	    if (C[0] == 'Q') 	    { 	        max = score[A-1]; 	        for (i = A; i <= (B-1); i++) 	        { 	               if (score[i] > max) 	            { 	                max = score[i]; 	            } 	        } 	        printf("%d\n", max); 	    } 	    if (C[0] == 'U') 	    { 	        score[A-1] = B; 	    }  		printf("scores:");         for (i = 0; i < N; i++) 	    { 	        printf("%d ", score[i]); 	    }    		printf("\n");  	}      return 0; } 谢谢，后来我也改了一下，但还是不行，你这个也还是通不过。。。

引用 12 楼 Falleyes的回复:你的代码水平，慢慢提高吧，多看看基础的东西。话说你是哪个省的，华为校招已经开始了啊？ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h>  int main(void){ 	int N, M, A, B; 	int* score; 	int i, max; 	char C;  	scanf("%d%d", &N, &M);  	score = (int*)malloc(sizeof(int)*N);  	for (i = 0; i < N; i++) 		scanf("%d", &score[i]);  	while (M--){ 		fflush(stdin); 		scanf("%c%d%d", &C, &A, &B); 		if (C == 'Q'){ 			max = score[A - 1]; 			for (i = A - 1; i < B; i++){ 				if (max < score[i + 1]) 					max = score[i + 1]; 			} 			printf("%d\n", max); 		} 		if (C == 'U') 			score[A - 1] = B; 	}  	free(score);  	return 0; } 你这个只有1组数据。这题怎么提交？

楼主，请问在哪儿提交，能不能给我提交地址？我想试试。  或者楼主帮我跑一下3L的程序吧，应该可以过的。

引用 2 楼 zxh707wk 的回复:N没初始化。。。N是用户输入赋值的

引用 1 楼 Falleyes 的回复:他给你的例子，U 3 6将第3个学生的成绩改为第6个的成绩，但是他只有5个学生啊，你如果不判断越界的话，肯定会出错的。。。U 3 6是把第三个学生的成绩改为6，不是改为第6个的成绩

首先多组数据，你这个只能测试1组；而且你的操作明显只能操作一回，肯定错了。我的代码仍有错误，不知为啥 #include <stdio.h> int scr[30000]; int main(void){ 	int N,M; 	char C; 	int i,j,k,a,b; 	while(~scanf("%d%d",&N,&M)){ 		for(i=0;i<N;i++){ 			scanf("%d",&scr[i]); 		} 		for(i=0;i<M;i++){ 			scanf("%c%d%d",&C,&a,&b); 			if(C=='Q'){ 				k=a-1; 				for(j=k+1;j<b;j++){ 					if(scr[k]<scr[j]){ k=j;} 				} 				printf("%d\n",scr[k]); 			} 			else scr[a-1]=b; 		} 	} 	return 0;  }

输入成绩是时将学生1-N的成绩存到score数组中的1-N而不是1-N-1      huozhe,  for 循环中 A B 都减1  不然最后一个学生N的成绩score[N]会越界，或者说低底第N 个学生的成绩是score[N-1]

N没初始化。。。


Question: pat不满分不知道为什么  求助=。=  Basic Level 1007素数对猜想

#1有错。数组够大了。char不够。试改为int p[50000];

注意题中N的范围。LZ程序中的char p[50000]数组不够大,char类型也太小.试改为: static int p[100000];


Question: C语言 帮我看看哪里错了  在线求大神

修改如下：  #include <stdio.h> #include <math.h> int Discriminant(int a, int b, int c) { 	int sam; 	//sam = b ^ 2 - 4 * a*c;   //^是异或运算，下同 	sam = b * b - 4 * a*c; 	return sam; } float Boot1(int a, int b, int c) { 	float boot1; 	boot1 = (-b + sqrt(b * b - 4 * a*c)) / (2 * a); 	return boot1; } float Boot2(int a, int b, int c) { 	float boot2; 	boot2 = (-b - sqrt(b * b - 4 * a*c)) / (2 * a); 	return boot2; } int main() { 	int a, b, c; 	a = b = c = 0; 	float boot1, boot2; 	printf("请输入二次项系数（以回车结束）："); 	scanf("%d", &a); 	printf("请输入一次项系数（以回车结束）："); 	scanf("%d", &b); 	printf("请输入常数项（以回车结束）："); 	scanf("%d", &c); 	if (Discriminant(a, b, c) >= 0) 	{ 		boot1 = Boot1(a, b, c); 		boot2 = Boot2(a, b, c); 		printf("根1：%.2f\n", boot1); 		printf("根2：%.2f\n", boot2); 	} 	else 	{ 		printf("此函数无实数根！\n"); 	} 	return 0; }

函数重名了啊啊 啊 啊啊

函数名字写错了啊，楼主辛苦了～～

int main（）      2个 Boot1！


Question: 请教一个C语言指针问题

13行，p是NULL,，给*p赋值就是写0位置的内存，这个内存是不可以写的，所以非法操作内存，自然错误。

局部指针不能返回，函数退出后栈中的数据是无法掌控的：  #include <stdio.h> #include <stdlib.h> #include <time.h>  int arr[100];  void arry(void) {     int i;     srand(time(0));     for(i = 0; i < 10; i++) {         arr[i] = rand()%100 + 1;     } }  int main(void) {     int i;     arry();     for(i = 0; i < 10; i++) {         printf("%d\n", arr[i]);     } }

你具体想做什么？ 12行类型转换、13行返回一个局部变量都有问题。

老是发错 再来一次  #include <stdio.h> #include <stdlib.h> #include <time.h>  void arry(int arr[]){      int i;     srand(time(0));     for(i = 0; i < 10; i++){         arr[i] = rand()%100 + 1;     }  }  int main(void){     int i, arr[100];      arry(arr);     for(i = 0; i < 10; i++){              printf("%d ", arr[i]);     } }

#include <stdio.h> #include <stdlib.h> #include <time.h>  void arry(int arr[]){     //int *p = 0;     int i;//, arr[100];     srand(time(0));     for(i = 0; i < 10; i++){         arr[i] = rand()%100 + 1;     }     //*p =(int) &arr;   //  return &arr; }  int main(void){     int i, arr[100];     int arr2[100]     arry(arr);     for(i = 0; i < 10; i++){         arr2[i] = arry();         printf("%d,", arr2[i]);     } }

我也是新手 试着改一下 看看对不 #include <stdio.h> #include <stdlib.h> #include <time.h>  int arry(int arr[]){     //int *p = 0;     int i;//, arr[100];     srand(time(0));     for(i = 0; i < 10; i++){         arr[i] = rand()%100 + 1;     }     //*p =(int) &arr;     return &arr; }  int main(void){     int i, arr[100];     arry(arr);     for(i = 0; i < 10; i++){         //arr[i] = arry();         printf("%d,", arr[i]);     } }

你返回的是指针的指针，而且这个指针还是在栈里面。实在是奇怪。


Question: TDM-GCC生成的文件怎么优化？太大了

试试Code::Blocks（http://www.codeblocks.org）。


Question: 小白求助一个c中数组做函数参数的问题！！！急急急

int*a[].一般都不这么写，数组传递进去就自动退化成指针 了

引用 18 楼 jay183986697 的回复:[quote=引用 5 楼 q3733353520 的回复:] [quote=引用 3 楼 q3733353520 的回复:] [quote=引用 1 楼 jay183986697 的回复:] 写错了。。改动1出 函数参数是 int * a           .............. 改为int **a[/quote]  对于你函数的用法只能改为 int*a[4][/quote]改了，报错1 unresolved externals 执行 link.exe 时出错.[/quote] http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=ubuntuu_cb&wd=1%20unresolved%20externals%20%E6%89%A7%E8%A1%8C%20link.exe%20%E6%97%B6%E5%87%BA%E9%94%99&oq=link.exe%20%E6%97%B6%E5%87%BA%E9%94%99&rsv_pq=d2cc07de00101f81&rsv_t=64c3V2gyobYzwaNJjmIm0DTC0TXeUTDq8uqg%2F0y8Q7s2g4rrl8jzCyQ%2FgaqvdgadQA&rsv_enter=0&rsv_sug3=3&rsv_n=2&inputT=1030&rsv_sug4=13416

两位老师....

引用 13 楼 zhao4zhong1 的回复:[quote=引用 9 楼 zhangxiangDavaid 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 思考一下为什么没人将整个互联网内容当作函数参数传来传去呢？ 如何对这种进行描述呢？[/quote] 我的意思是说，对数组这种容量比较大的数据，就别参数传其内容了，最多传其对应的void *，甚至不传，直接使用全局变量共享。[/quote]  数组大吗？数组能有多大？ 如果不建议传递数组的内容，干脆也建议省掉strcpy之类的函数，毕竟复制也挺浪费时间的。

门外汉看不来

C++ 数组引用传递，可以整个传递数组，不过很不灵活，数组的元素数只能是固定的 要想传递任意数组，只能定义函数模板 C则只能传递指针，即使定义为传递数组，最终也会当成指针。 多维数组，数组元素也只是固定的 不过，可以通过传递一级指针，操作任何维数的，任何大小的数组。

写错了。。改动1出 函数参数是 int * a           ..............

引用 14 楼 zhangxiangDavaid 的回复:[quote=引用 13 楼 zhao4zhong1 的回复:] [quote=引用 9 楼 zhangxiangDavaid 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] 思考一下为什么没人将整个互联网内容当作函数参数传来传去呢？ 如何对这种进行描述呢？[/quote] 我的意思是说，对数组这种容量比较大的数据，就别参数传其内容了，最多传其对应的void *，甚至不传，直接使用全局变量共享。[/quote][/quote] 别急着点赞  C/C++ 根本不可能在函数参数中传递数组 只能传递指向数组的指针 这是在语法层就做的限制 zhao4说的东西没什么卵用

引用 9 楼 zhangxiangDavaid 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 思考一下为什么没人将整个互联网内容当作函数参数传来传去呢？ 如何对这种进行描述呢？[/quote] 我的意思是说，对数组这种容量比较大的数据，就别参数传其内容了，最多传其对应的void *，甚至不传，直接使用全局变量共享。

引用 11 楼 zhangxiangDavaid 的回复:哈哈，为何不能使用“强制类型转换”？ 原因1 字太多 (int*) 需要敲键盘6次  而用*只需要敲键盘1次  就算是[0] 也只是3次  原因2 不方便 你这里传入整个数组  看起来没什么  如果你想传入 76,-4,12,82 用(int*) 写起来自讨苦吃

引用 10 楼 lin5161678 的回复:[quote=引用 8 楼 zhangxiangDavaid 的回复:] 修改如下：  #include <stdio.h> #define M 4 int fun (int *a) {     int i, max; 	max = *a; 	for(i = 1; i < 2*M; i++) 	{ 		if(max < a[i]) 			max = a[i]; 	} 	return max; } int main( ) {   	int arr[2][M] = { 5,8,3,45,76,-4,12,82 }; 	printf("max=%d\n", fun((int*)arr)); 	getchar(); } //max=82 函数调用写错了  别用强制类型转换 用 *arr 或 arr[0][/quote] 哈哈，为何不能使用“强制类型转换”？

引用 5 楼 q3733353520 的回复:[quote=引用 3 楼 q3733353520 的回复:] [quote=引用 1 楼 jay183986697 的回复:] 写错了。。改动1出 函数参数是 int * a           .............. 改为int **a[/quote]  对于你函数的用法只能改为 int*a[4][/quote]改了，报错1 unresolved externals 执行 link.exe 时出错.

引用 2 楼 zsh0317 的回复:改动后函数fun返回的是地址，而改动前函数fun返回的是值。返回max=**a怎么是地址？？

引用 8 楼 zhangxiangDavaid 的回复:修改如下：  #include <stdio.h> #define M 4 int fun (int *a) {     int i, max; 	max = *a; 	for(i = 1; i < 2*M; i++) 	{ 		if(max < a[i]) 			max = a[i]; 	} 	return max; } int main( ) {   	int arr[2][M] = { 5,8,3,45,76,-4,12,82 }; 	printf("max=%d\n", fun((int*)arr)); 	getchar(); } //max=82 函数调用写错了  别用强制类型转换 用 *arr 或 arr[0]

引用 7 楼 zhao4zhong1 的回复:思考一下为什么没人将整个互联网内容当作函数参数传来传去呢？ 如何对这种进行描述呢？

思考一下为什么没人将整个互联网内容当作函数参数传来传去呢？

“数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”，而不是“指针的指针”： 实参                                                      所匹配的形参 数组的数组          char c[8][10];                 char (*)[10];          数组指针 改成 int fun(int (*a)[M])


Question: 新手求帮助，题目不复杂

引用 7 楼 ye736986237的回复:[quote=引用 6 楼 zh1599512 的回复:] 奇偶交叉，  i=0.  0%2=0为假 执行else. 输出`A`+0当然是A.    I=1执行。1+`a`=b.  入门提啊 坑爹啊，为什么下面是大写的B和C，误导我[/quote] 难道你没发现嘛?明显有错啊，

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

引用 6 楼 zh1599512 的回复:奇偶交叉，  i=0.  0%2=0为假 执行else. 输出`A`+0当然是A.    I=1执行。1+`a`=b.  入门提啊 坑爹啊，为什么下面是大写的B和C，误导我

引用 1 楼 cjqpker 的回复:C 这个题目就是考察ASCII表中a-z以及A-Z的分布，即使不知道这些字母的具体ASCII值，根据从小到大的顺序，也应该知道'a'+1='b'，'A'+1='B' 另外，观察一下ASCII表，就很清楚了 还是看不懂啊，能不能讲具体点，谢谢

好复杂，太费脑。这种题目我都是抛硬币填答案：抛两次即可得到答案。

嗯，怪不得，谢谢了

引用 1 楼 cjqpker 的回复:C 这个题目就是考察ASCII表中a-z以及A-Z的分布，即使不知道这些字母的具体ASCII值，根据从小到大的顺序，也应该知道'a'+1='b'，'A'+1='B' 另外，观察一下ASCII表，就很清楚了 搞反了，应该是B。


Question: 问一个移动宽带和电信宽带 应用程序通讯的问题，高手请进

大侠，能否详细指导一下？  那业务该从哪里着手解决呢？

路由器过滤掉了或少NAT穿透配置。

不知道C板的大侠有没有经验的？  或者，哪位告诉我， CSDN的哪个版本， 有这方面的经验的人比较多啊


Question: 基于arcgis对于校园gis的设计

跪求大神！！！！！！！！


Question: cgdb调试标准输入的问题

cgdb是不是开源的？

up 起来，有高手解决了吗？

搜索了一下，发现gdb tui模式也是如此。  看帖子： http://segmentfault.com/q/1010000000515825   有人会解决吗？


Question: c 指针下标问题 有点不太明白 请大家帮忙解释一下

修改如下：  #include <stdio.h> char *eatspace(char *d, char *s) { 	char *p = d; 	if(NULL == d || NULL == s) return d; 	while(*s) 	{ 		if(*s != ' ') *d++ = *s; 		s++; 	} 	*d = '\0'; 	return p; } char *leaveOneSpace(char *d, char *s) { 	char *p = d; 	if(NULL == d || NULL == s) return d; 	*d++ = *s++; 	while(*s) 	{ 		if(' ' == *(d - 1) && ' ' == *s) 			; 		else 			*d++ = *s; 		s++; 	} 	*d = '\0'; 	return p; } int main(void) { 	char s[] = "abc  def"; 	char d[20]; 	//printf("eatspace...\n"); 	//eatspace(d, s); 	//printf("s=%s\nd=%s\n", s, d); 	printf("leaveOneSpace...\n"); 	leaveOneSpace(d, s); 	printf("s=%s\nd=%s\n", s, d); 	return 0; }

1楼的回答是正确的

你要写成如下这样也是可以滴   void thkg(char *t ,char *p) {     while(*p != '\0')     {          if(*p !=' ' || *(p+1) != ' ')           {              *t++ = *p++;          }          else               p++;     }     *t='\0'; }

++p可以，p++不可以，两者都会改变p的值，但是之后的 *t++ = *p;会用到p的值。需要看程序需要不需要p的值改变

用p++的话, if(*p !=' ' || *(p++) != ' ') ||前后两个部分的是值判断是一样的，没有意义。 ++p可以用，只不过要对应修改，而且应该会比你现在这样效率更高

引用 7 楼 eddition512 的回复:[quote=引用 1 楼 掌心的呵护的回复:]++p和p++都会改变p的值，所以不用。 不好意思 手机屏幕太小点错了。 这里的 p++ 先执行附近的运算再自增 这个好理解 但++p 是先自增 在这条语句中 它们与 p+1 有什么区别[/quote]  如下三句： if(*p !=' ' || *(p+1) != ' ') //为什么 这里的 *(p+1)  不能用 *(++p) 或 *(p++) 呢？ 编译环境 gcc 4.7.1 {      *t++ = *p; } p++; 在if判断语句这一行，可以使用++p来替换，但p的值被改变了（p=p+1），需要将下面的两句赋值修改为之前p的值；或者将最后一句去掉（因为p已完成自增）， *t++ = *p修改为 *t++ = *（p-1）;

引用 1 楼 掌心的呵护的回复:++p和p++都会改变p的值，所以不用。 ++p和p++都会改变p的值，所以不用。[/quote] ++p和p++都会改变p的值，所以不用。[/quote] ++p和p++都会改变p的值，所以不用。[/quote] 不好意思 手机屏幕太小点错了。 这里的 p++ 先执行附近的运算再自增 这个好理解 但++p 是先自增 在这条语句中 它们与 p+1 有什么区别

++p和p++都会改变p的值，所以不用。


Question: 求解

引用 1 楼 赵4老师的回复:仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.   先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再 参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c n=4，k=-1是什么，不懂

可以用getchar()一个个字符读，就可以不用回车来将缓冲区数据送入变量中 函数调用时，先将调用处下一条执行命令压入栈中（以便函数执行完后接着执行下一条语句），在逐个将参数压入栈中

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。”

调试时按Alt+7键查看Call Stack即“调用堆栈”，里面从上到下列出了对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。


Question: 设计一个完整的C程序，实现对某班级学生某门课程的成绩汇总与统计（班级人数不固定，用链表实现）

每题写个函数就差不多了， 然后写个链表的数据结构： 定义链表，实现创建，插入，查找，删除，销毁

int main() {       printf("拒绝伸手党\n");       return 0; }

楼主你真厉害，这么大的题目，有谁给你解答啊

诸位大神帮我看看

99%的C/C++作业题在百度都能搜到。

赵4老师别逗我了


Question: 求解P++和P+1的区别

引用 2 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  赵老师，你到处拷贝这些话，都能拿高分。

这里用p++和p+1对于传入的参数值不同，前者就是p，而后者是p+1。 另外p++会对后续使用p带来影响。 这里的递归函数reverse01只需要p所指向的下一个地址即可，可写成p+1或者++p。但是++p改变了p值，反而后续输出则变得不正常。

p++传入的是p，之后才在自身加1，++p才是传入p+1

你这里的reverse(p++)是先reverse(p)，再p+1，而reverse(p+1)是先p+1,在传给函数


Question: vs2008： error lnk2005 already defined in main.obj

很明显，头文件中是不能定义变量的，你肯定这样做了

楼主，你是不是在结构体声明时定义了结构体对象 这样定义的对象是全局变量，当有多个源文件包含它时，会出现重复定义


Question: c语言 二维数组和指针 求教。

a+1是以一维数组为整体上的的运算，偏移量为一维的大小，即a+1，指向第二行 &a+1是以二维数组为整体上的运算，偏移量为二维的大小（如a[4][5]，则二维的大小为4*5*sizeof(int)） *a是以元素为整体上的运算，偏移量为元素的大小，*a+1表示下一元素的地址

引用 7 楼 sunday20060101的回复:int (*p)[5] = a; int *p；  对于以上的定义，p是个指针变量，注意是变量，是变量就有其存储的地址即&p;同时由于是指针变量，所以也就有*p的操作，也就是取出其所指向的内容；一句话：p是变量本身，&p是变量p所在的地址，*p则是其指向的值；  int a[4][5]; 这个语句则定义了一个数组a，a的值本身就是个地址，是数组的起始地址，是个常量（注意，是个常量），而不是变量；所以a、*a，&a的值是相同的都是数组的起始地址；这一点要和变量区分开； int (*p)[5] = a; int *p；  对于以上的定义，p是个指针变量，注意是变量，是变量就有其存储的地址即&p;同时由于是指针变量，所以也就有*p的操作，也就是取出其所指向的内容；一句话：p是变量本身，&p是变量p所在的地址，*p则是其指向的值；  int a[4][5]; 这个语句则定义了一个数组a，a的值本身就是个地址，是数组的起始地址，是个常量（注意，是个常量），而不是变量；所以a、*a，&a的值是相同的都是数组的起始地址；这一点要和变量区分开；[/quote] a+1.  &a+1.  *a+1值为什么不一样?

引用 3 楼 user-4的回复:a 是二维数组首地址 *a 与a[0]等价，   &a  不知道 &a是一个数组的地址

楼主，没必要纠结这个，对编程没有多大作用，只要记住，数组名并没有存储在内存空间中，在编译时，会将数组名转换成数组数据的首地址

楼主可以将*(a+1)转换成a[1]，可以将二维数组借助数组指针理解（不能等同，毕竟数组指针是一个指针，指针本身也要内存空间），a理解为第一行的地址，a+1为第二行的地址，*（a+1）为第二行第一元素的地址。

a 是二维数组首地址 *a 与a[0]等价，   &a  不知道

引用 1 楼 ant2012 的回复:静态数组，*a   &a  a这三个表示都是数组的首地址 这是编译机制的问题，不要用指针的方式去理解，楼主有兴趣可以看看这段代码的汇编代码，发现它们的汇编代码是一样的  也可以这么理解，a 是二维数组，由于静态二维数组物理结构是一维的，逻辑结构才是二维的，所以a是数组第一个元素的地址。*a 是第一行的第一个元素的地址，还是数组第一个元素的地址。&a是数组变量的地址，即数组的地址，即第一个元素的地址。  这个记住就行，不要用二级指针的模式去理解静态二维数组   额。。那这3个表达式的 +1后的 偏移不一样 怎么理解啊？


Question: RadASM编译出错问题

原来是我顺序搞错了。。。。搞定

怎么自动回复了。。。。  mov eax,004558C8h;地址 mov word ptr [eax],0E9B5040000h 加0是可以了 但有的jmp很长代码就又出错了 error A2084: constant value too large

前面加 0 就好了 EB14h ->  0EB14H


Question: 看一下这段程序 。

引用 2 楼 chenxue0821 的回复:没看懂 ，buf[(i*whl+j)*3+hdl] 这个不会越界么这个 表达式是。。。？

没看懂 ，buf[(i*whl+j)*3+hdl] 这个不会越界么

想让看什么？

[quote=引用 楼主 jk_101 的回复:] 	for(i=0;i<whl;i++) { pd[i]=(int*)malloc(whl*sizeof(int)); for(j=0;j<whl;j++) { pd[i][j]=buf[(i*whl+j)*3+hdl]; } 这个实在给pd[i][j]分配空间吗?


Question: 关于指针数组，求大神指导！

仅供参考：#include <stdio.h> double A[300][100]; double valuex[300]; double valuey[300]; int i; double fun00(double x,double y) {return x  +   y  ;}; double fun01(double x,double y) {return x*x+ 3*y  ;}; double fun02(double x,double y) {return x  + 2*y*x;}; //...  fun03(double x,double y) {return ...+...   ;}; //... //...  fun98(double x,double y) {return ...+...   ;}; double fun99(double x,double y) {return x/2+20*y  ;}; double (*funNN[100])(double,double)={     fun00,     fun01,     fun02, //  fun03, //  ... //  fun98,     fun99, }; int main() {     double x,y;     int f,FN;      for (i=0;i<300;i++) {         valuex[i]=(double)i;         valuey[i]=(double)i;     }     FN=3;     for (i=0;i<300;i++) {          x=valuex[i];          y=valuey[i];          for (f=0;f<FN;f++) A[i][f]=funNN[f](x,y);     }     for (i=0;i<3;i++) {         for (f=0;f<FN;f++) printf("%lg ",A[i][f]);         printf("\n");     }     return 0; } //0 0 0 //2 4 3 //4 10 10

指针数组，是一个数组，元素为指针类型，楼主的代码，每个元素为函数指针（即指向函数的指针），说白了，数组中每个元素存放的是某个函数的地址，在使用是时，只需要将某个同类型的函数的函数名给元素赋值，就可通过指针来调用函数

1， static void (* const fsbl_init_func_tbl[])(void) 定义了一个 无返回无参数的函数指针数组； 2， = {   fsbl_ram_init,   fsbl_hw_init, #ifdef BOOT_USES_DCACHE   boot_cache_mmu_init, #endif   NULL  }; 初始化这个函数指针数组 3，  for ( i = 0; fsbl_init_func_tbl[i] != NULL; i++ )   {     fsbl_init_func_tbl[i]();   } 遍历这个函数指针数组，并挨个调用一次


Question: 无法理解的代码

开始，运行，cmd，确定。

我认为六楼说的很有道理，跟我猜的差不多。但我天资愚笨，希望可以通俗的给我讲一下（有个例子最好）。九楼说的我用getchar（）试了，确实可以直接打开了，当我输入所需的数据后点击enter运行时又直接跳出来了（不运行）

对就是闪退。

不好意思我不会用cmd窗口。四楼说的我试了一下编译的时候他给出了这么一段话‘system' is not declared in this scope，好像是不能识别吧。可能我表述的不是太清楚吧，我再说一下我的问题！！我想知道为什么在我程序正确的情况下不能直接运行应用程序，只能通过打开源代码运行？？（我想听到原因、解释、思想……而不是方法、改变、其他途径打开……）。我编写的代码都是这样的情况。应该不是代码的问题。我是新手，有很多不懂，希望大家多多支持。谢谢。（想截个图给你们看看但是这图片一直显示在上传中）

如果是打开闪退的话，main结束前加getchar()或者system("pause")

如果是系统限制，杀毒软件拦截，防火墙什么的原因的话，报错信息就比较明显的

编译器生成的程序，并没有经过封装，所以并不是一个放到哪里都能用的程序

你编译完，编译器是知道你的程序所需要的库在哪里的，但是你直接运行程序时，需要系统知道你这个程序需要库在哪里，（一般默认是当前文件夹下），当然，所需库和程序不在同一文件夹的话系统就不知道了  所以，你把程序放到用到库的文件夹里的话，就可以了

在cmd窗口中输入以下命令： cd /d 你的exe文件所在盘符和目录 你的exe文件名.exe 如果还是不能运行你的exe文件，关闭UAC、防火墙、杀毒软件、……

我刚刚在网上又找了一下封装的知识并用到了我写的程序里，确实是这方面的问题。解决问题的答案就是在main函数结束之前加两个getchar（）；   然后就可以直接运行。exe文件了，很感谢大家的帮助（不管是有用的还是无用但有心的解答）。以后有不会的还请大家多多指教。

恩。好的，关于封装这一方面我不是太了解，有谁可以推荐一些书给我看看（最好是pdf格式的）

我试了你的程序，我这边能运行，拿到哪里都可以，，，

刚看到你这个图，感觉并没有什么需要封装的文件，把中文都换成英文试试

引用 16 楼 doublekill_ 的回复:请大家解答我的疑惑（就是我问什么你答什么而不是给我又引入到另一个情景中），请仔细看我的问题好吧。谢谢（例子就是像六楼那样回答，但是他讲的也不是太清晰，所以希望大家集思广益）。           打个比方，你调用了一个系统函数printf（只是打个比方），这个函数你是直接拿来用的，而它的代码就在库文件里面，你用了这个函数，就需要在运行时，能够找到这个库，确切说是能找到这些调用了的代码，让你的程序能够执行下去。         你用编译器去运行时，编译器帮你做好了找到这些库文件之类的工作，所以可以执行；但是当你直接运行exe时候，这时运行环境是win32控制台，它并不会像编译器做的那么多，它只会去它自己知道的地方去找文件，而没有找到的话，就不能运行了  真的不知道再怎么细说了，，  你想运行exe是要封装后才能做到，不明白的话也不用刻意去纠结，等你慢慢了解了就会了，非要做到，就去看看程序是怎么封装的吧

你确定scanf真的停下来等你了？用每一个函数之前先确定这个函数的用法。

另外，6楼应该是最不靠谱的回答了。

因为你建的是win32控制台项目

在主函数return前加 system("pause");试试


Question: 为什么GetMessage函数也可以调用窗口过程

那个是调用钩子函数吧，我记得 SetWindowHook 有一种方式就是在取消息的时候回调


Question: 关于 程序的段

window ,linux 段 寄存器，除了fs 都不再使用了 等于关闭了段模式 其实偶尔还会用的，不过用户（3级别代码）程序，不能够使用而已。 elf 中的段，只是操作系统，划分 代码数据等不同用途数据的一种方式，不再是 dos 时代的那种段了

CPU中的段选择子 和 PE或elf文件中的Section 不是一个概念。

当然不一样  不管是 Linux 还是 Windows，现在都是平坦内存模型。 cs, ds, ss 所指向的段选择子基址都是 0，size 都是 0xffffffff , 也就是说偏移的范围其实就是 0～4G 整个内存地址空间。偏移值就是地址的值。 Linux 和 Windows 都采用分页机制来管理内存，通过这种设置相当于绕过分段机制了，因为分段在 CPU 中没法关闭，必须使用。


Question: 求解利用多线程数组中查找一个数，出现未处理的异常？

应该是这里崩溃了  printf("\n\n%d,%p\n\n", *addrfind, addrfind);//打印地址，还有数据  原因可能是： if (*px == pstruct->num) { printf("%d\tfind\t%p\t%d\n", pstruct->bh, px, *px); *(pstruct->pflag) = 1;//改变标识，代表找到 *(pstruct->addr) = px; return; }  如果条件不成立，*(pstruct->addr) 还是NULL，即addrfind是NULL,这样*addrfind就会崩溃

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  多线程程序该加锁的地方一定要加锁。 调试多线程程序请使用支持多线程的日志功能。参考下面：//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; 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;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     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);             }         } else {             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} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             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]:'.');             }             Log("%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]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }


Question: winAPIoverRide怎么用

自己看联机帮助。看不懂在官方论坛或技术支持问。  英语也是一门计算机语言的说。

什么意思，用户要查看什么


Question: 求助，输入流怎么会读不进第一个字符？帮忙看看

引用 6 楼 qq_30446977 的回复:[quote=引用 4 楼 qq_30446977 的回复:] [quote=引用 1 楼 walkiz 的回复:] 这样写才对：  void eatspaces(void) {     char ch = 0;     while(isspace(ch = (char)getchar())){     }     ungetc(ch,stdin); }   这个是怎么运行的？是下面这样吗： 1.读取一个字符（是一次性输入一串字符回车结束）。2.如果第一个字符是空格，循环继续，读到非空格循环结束，3.将最后一个字符放回输入流。....这里后面的字符还要继续进行while循环吗？                                     2.如果第一个不是空白字符，循环结束。3.将最后一个字符放回输入流。...这里后面的字符还要继续进行while循环吗？    是这样运行的吗？ [/quote] 帮我看看我这样想对吗？如果像7楼上所说的，如果返回输入流，就结束了。 输入流中就没有空格了，那为什么主函数最后输出后是 有空格的呢？

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

字符放回输入流后eatspaces函数就结束了，不用继续while循环

引用 4 楼 qq_30446977 的回复:[quote=引用 1 楼 walkiz 的回复:] 这样写才对：  void eatspaces(void) {     char ch = 0;     while(isspace(ch = (char)getchar())){     }     ungetc(ch,stdin); }   这个是怎么运行的？是下面这样吗： 1.读取一个字符（是一次性输入一串字符回车结束）。2.如果第一个字符是空格，循环继续，读到非空格循环结束，3.将最后一个字符放回输入流。....这里后面的字符还要继续进行while循环吗？                                     2.如果第一个不是空白字符，循环结束。3.将最后一个字符放回输入流。...这里后面的字符还要继续进行while循环吗？    是这样运行的吗？ [/quote] 帮我看看我这样想对吗？

void eatspaces(void)  //测试输入是否是空白字符。  { char ch=0; while(isspace(ch=(char)getchar())) ungetc(ch,stdin);  //将不是空白字符返回输入流  }   输入空字符是会一直进入循环  void eatspaces(void) {     char ch = 0;     while(isspace(ch = (char)getchar())){     }     if(!isspace(ch = (char)getchar()))     ungetc(ch,stdin); } 这样排除返回空字符，应该就可以了

引用 1 楼 walkiz 的回复:这样写才对：  void eatspaces(void) {     char ch = 0;     while(isspace(ch = (char)getchar())){     }     ungetc(ch,stdin); }   这个是怎么运行的？是下面这样吗： 1.读取一个字符（是一次性输入一串字符回车结束）。2.如果第一个字符是空格，循环继续，读到非空格循环结束，3.将最后一个字符放回输入流。....这里后面的字符还要继续进行while循环吗？                                     2.如果第一个不是空白字符，循环结束。3.将最后一个字符放回输入流。...这里后面的字符还要继续进行while循环吗？    是这样运行的吗？

输入空格的时候你就死循环了  取一个是空格，放回去，再取就取到刚刚放回去那个，当然还是空格，然后再放回去，然后再取，还是放回去 ......  while 后面加 分号

引用 1 楼 walkiz 的回复:这样写才对：  void eatspaces(void) {     char ch = 0;     while(isspace(ch = (char)getchar())){     }     ungetc(ch,stdin); }   这个函数的作用是，去除空白字符。如果改成上面这样，那么就起不到这个作用了吧。我输入空格就会输出空格。


Question: Window编程闪屏, 换双缓冲就显示白屏问题,求教,谢谢

我刚上CSDN,分值不够,我选择了平均分,希望两位朋友别生气.

多谢上面两位朋友的回答,仔细的查看了一下, HDC 声明有错, Case 块 差 {} ,然后就是ReleaseDC出错,改正后就出来了, 在次感谢.

在WM_CREATE里面有多次ReleaseDC, 没看到getdc, 这个hdc怎么来的

请判断每个函数调用的返回值。必要时GetLastError


Question: 自学新手小白求助,编了个简单代码不知道哪里错了

引用 4 楼 赵4老师的回复:每行的后面都有'\n'，区别是在新的一段开头有空格，我觉得。 可是我程序里就是\n啊，有没有什么其他能表示段的方法呢，因为万一我英文文档每段前面没有空格呢？

每行的后面都有'\n'，区别是在新的一段开头有空格，我觉得。

引用 1 楼 D_CHRIS 的回复:这是程序 #include <stdio.h> #include <stdlib.h> void main() { 	FILE *fp1, *fp2; /*定义两个指向FILE类型结构体的指针变量*/ 	char filename1[50],filename2[50],ch;   	long paragraph;  	paragraph=0;  	printf("Enter file name \n"); 	scanf("%s", filename1); /*输入要进行统计的文件的路径及名称*/ 	if((fp1=fopen(filename1, "r"))==NULL)  	{ 		printf("cannot open file.\n"); 		exit(1); 	} 	printf ( "Enter file name for write data:\n"); 	scanf("%s",filename2); /*输入文件名即将统计结果放到那个文件中*/ 	if((fp2=fopen(filename2, "w"))==NULL) /*已可写方式要存放统计结果的文件*/ 	{ 		printf("cannot open file \n"); 		exit(1); 	} 	while((ch=fgetc(fp1))!=EOF) /*知道文件内容结束处停止while循环*/ 		ch=fgetc(fp1); 		if(ch=='\n')  			paragraph++;	 		fclose(fp1);  		fprintf(fp2,"paragraph:%ld \n", paragraph); /*将统计结果写入fp指向的磁盘文件中*/ 		 }  windows中的文件换行符是\r\n

\n 和 /n 不是一回事！  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: 关于二维指针和字符串的问题 求帮忙！！！！！！

仅供参考：#include <stdio.h> #include <string.h> char string[80]; char seps1[3]; char seps2[3]; char *token; char *zzstrtok (     char *string,     const char *control1,//连续出现时视为中间夹空token     const char *control2 //连续出现时视为中间无空token     ) {     unsigned char *str;     const unsigned char *ctrl1 = (const unsigned char *)control1;     const unsigned char *ctrl2 = (const unsigned char *)control2;     unsigned char map1[32],map2[32];     static char *nextoken;     static char flag=0;     unsigned char c;     int L;      memset(map1,0,32);     memset(map2,0,32);     do {         map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));     } while (*ctrl1++);     do {         map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));     } while (*ctrl2++);      if (string) {         if (control2[0]) {             L=strlen(string);             while (1) {                 c=string[L-1];                 if (map2[c >> 3] & (1 << (c & 7))) {                     L--;                     string[L]=0;                 } else break;             }         }         if (control1[0]) {             L=strlen(string);             c=string[L-1];             if (map1[c >> 3] & (1 << (c & 7))) {                 string[L]=control1[0];                 string[L+1]=0;             }         }         str=(unsigned char *)string;     }     else str=(unsigned char *)nextoken;      string=(char *)str;     while (1) {         if (0==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 string++;                 str++;             } else {                 flag=1;                 str++;             }         } else if (1==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=0;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=2;                 break;             } else str++;         } else {//2==flag             if (!*str) return NULL;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=(char *)str;                 flag=0;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=(char *)str;             } else {                 string=(char *)str;                 str++;                 flag=1;             }         }     }     nextoken=(char *)str;      if (string==(char *)str) return NULL;     else             return string; } void main() {    strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some  more tokens, ");    strcpy(seps1,",\n");strcpy(seps2," \t");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");    strcpy(seps1,"|");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"");strcpy(seps2,"|");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"|");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,a,,b,,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,,");    strcpy(seps1,",");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    } } // //[A      string          of ,,tokens // //and some  more tokens,] //Tokens: // <A>, <string>, <of>, <>, <tokens>, <>, <and>, <some>, <more>, <tokens>, <>, //[1234| LIYI|China | 010 |201110260000|OK] //Tokens: // <1234>, <LIYI>, <China>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <>, <010>, <201110260000>, <OK>, //[a] //Tokens: // <a>, //[a,b] //Tokens: // <a>, <b>, //[a,,b] //Tokens: // <a>, <>, <b>, //[,a] //Tokens: // <>, <a>, //[a,] //Tokens: // <a>, <>, //[,a,,b] //Tokens: // <>, <a>, <>, <b>, //[,,a,,b,,] //Tokens: // <>, <>, <a>, <>, <b>, <>, <>, //[,] //Tokens: // <>, <>, //[,,] //Tokens: // <>, <>, <>, //[,,,] //Tokens: // <>, <>, <>, <>,

数组是数组 指针是指针  别把数组当成指针  char arr[3][4]; char** p = arr; 是完全错误的

静态二维数组在数据储存上元素内存地址空间是连续的，其实就是一维数组，只不过逻辑结构是二维的，所以不能将二维数组传给二级指针。楼主可以将二维数组强制转换成一级指针传给一级指针，但这样的话，在子函数访问这个一级指针，只能通过长宽计算偏移量来访问  直接在形参中声明二维数组就行，char strs[][100]; 第一维长度可以忽略 还可以通过定义数组指针实现，char (*strs)[100];

主要问题是 我用二级指针当函数参数    用二维数组名当实参时   函数中的二级指针 却是空   或者读不出来

字符串拆分，可以参考以下的做法：  #include<stdio.h> #include<string.h>  int split_string(char* str, const char* delims, char** strs, int w) {     char* result = NULL;     int i = 0;      result = strtok(str, delims);     while(result != NULL){         strcpy((char*)((int)strs + i * w), result);         i++;         result = strtok(NULL, delims);     }      return i; }  int main(int argc, char* argv[]) {     char str[] = "abcdef,acccd,eeee,aaaa,e3eeeee,sssss";     char strs[10][100];     int n;     int i;      n = split_string(str, ",", (char**)strs, 100);     for(i = 0; i < n; i++){         printf("%s\n", strs[i]);     } }


Question: 关于remove()与rename()

不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！

引用 8 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; 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); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     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);             }         } else {             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 main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中 好像找到问题了！ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h>  int main() { 	char filename[30] = {"e:\\file.txt"}; 	char filename_tmp[30] = {"e:\\file_tmp.txt"}; 	FILE *fp = fopen(filename, "rb+"); 	if(NULL == fp) fp = fopen(filename, "wb+"); 	FILE *fp_t = fopen(filename_tmp, "wb+"); 	if(NULL == fp || NULL == fp_t){ 		perror("open"); 		return 1; 	}  	int i, a; 	// 把105 106 107 108 109写入文件file.txt 	for(i = 0; i < 5; i++){ 		a = i + 105; 		fwrite(&a, sizeof(int), 1, fp); 	} 	rewind(fp); //指针移到文件首 	int key = 2; 	// 把105 106 108 109写入文件file_tmp.txt 	while(fread(&a, sizeof(int), 1, fp) == 1){ 		if(key + 105 != a) 			fwrite(&a, sizeof(int), 1, fp_t); 	}  	fclose(fp);  	//之前已经打开过一次filename_tmp，在没有关闭它之前再次打开就出错了。。。 #if 1 //把1改为0就能正确 	fp_t = fopen(filename_tmp, "wb+"); 	if(NULL == fp_t){ 		perror("file_tmp"); 		return 1; 	} #endif 	fclose(fp_t); 	if(remove(filename)) perror("remove"); 	if(rename(filename_tmp, filename)) perror("rename");  	fp = fopen(filename, "rb+"); 	if(NULL == fp) return 1; 	while(fread(&a, sizeof(int), 1, fp) == 1){ 		printf("%d\n", a); 	} 	fclose(fp); 	if(remove(filename)) perror("remove"); 	return 0; }  /*  *像这样的代码(其实整个意思是要删掉文件里的某块信息)有时会出现 remove:permission denied rename:permission denied 这样的错误，有时又不会；就以为是关闭文件的时候需要点时间，就停了下，发现还是会出错~求教！  */  我在程序中某些地方需要强制退出函数，但并没有把替换文件关闭（如以上程序），导致下一次调用函数时再次打开一次替换文件，从而导致错误，改正之后运行良好（至少测试很多例子都没有出错）。但不知为什么打开两次就会出问题额；还有一点奇怪的是在我真正的程序里*fp_t是局部变量，就算没有关闭应该也没问题吧。。。

虽然还是没有解决问题，但还是感谢各位的帮忙。。。

引用 4 楼 zhao4zhong1 的回复:所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。然而您只是把问题重新描述了一遍。。。

引用 1 楼 user-4 的回复:临时文件的话为何不试试 FILE* file = tmpfile();其实不算是临时，是用同名文件替代之前的文件，把旧的删掉

用ferror查一下出错原因 错误代码： EROFS  欲写入的文件为只读文件。 EFAULT  参数filename 指针超出可存取内存空间。 ENAMETOOLONG  参数filename 太长。 ENOMEM  核心内存不足。 ELOOP  参数filename 有过多符号连接问题。 EIO I/O  存取错误。

引用 5 楼 q3733353520 的回复: system("mv src_filepath dst_filepath");   可以先直接mv，然后打开mv过来的，修改，关闭。 或者打开修改关闭后再mv

system("mv src_filepath dst_filepath");

临时文件的话为何不试试 FILE* file = tmpfile();


Question: C语言的字符串指针问题

首先你要明白你的s定义的是一级指针，而s作为数组的时候，s是一个地址，s表现为一级指针的地址，s➕1也是一个一级指针的地址，此时接受的变量需要是二级指针。二级指针对应一级指针的地址…………………分隔符，我也正在学习中，不知道该回答是否满意，如有错误请指正，谢谢

s是指针数组名 其值为s[0]的地址 s[0]是"abcfd"的起始地址，指向char型 所以s指向 "指向char型的指针"

我自己搞明白了。因为str本身就是一个地址，存放的是字符串首元素地址，也就是指向地址的地址，自然要用二级指针来指向。str存放的就是字符串welcome的地址，str+1存放的就是字符串to的地址，str+2存放的就是字符串chaozhou的地址。这里有个结论，str=&str[0]，也就是说字符串的地址就是字符串首元素地址的地址。谢谢各位的解答。

数组名对于编译器而言，是个不确定类型也不存在于运行时期的东西。对于声明语句：char str[] = "abcdefg";⒈它可以代表整个数组对象：计算 sizeof(str) 结果是整个数组大小 8 字节而不是指针大小。 ⒉它可以代表首个元素的地址：当你把 str 当作右值或者参数的时候，它被弱化为指针。 编译器实际上并不为 str 这个符号分配内存。不过通常我们把它视作是值不可改变指针常量。 如上面的 str 可以视为和声明语句「char * const p;」中等同的 p 的类型。  当你要声明一个变量指向该字符串，你需要：char *p1 = str;     // 指向首个元素 char *p2 = str + 1; // 指向第二个元素 char *p3 = &str[1]; // 与上一行等价char *s[] = { "abcfd", "fhd", "ghf" }; char **p = s + 1;上述例子中，我们将 char * 视作一种类型，使用 Windows SDK 定义的 PCHAR 代替：PCHAR s[] = { "abcfd", "fhd", "ghf" }; PCHAR *p1 = s;     // 指向首个元素 PCHAR *p2 = s + 1; // 指向第二个元素 PCHAR *p3 = &s[1]; // 与上一行等价可以看到形式上和上面并没有区别。


Question: 找出链表中的含有最大值得节点

struct list { int v; list *next;}; list *max_ele(list *head){     if(!head) return NULL;     list *ans=head;     for(head=head->next;head;head=head->next)         if(ans->v<head->v) ans =head;     return ans; }

百度搜一下就会有很多可以参考的~~~


Question: C语言编译警告

引用 5 楼 eseses455250704 的回复:[quote=引用 4 楼 useprlove 的回复:] 在函数定义的地方加，而不是调用的地方加： Link_t Test_new( ) {...}       加完了还是会报警告warning: assignment makes pointer from integer without a cast [enabled by default]      head = Test_new();           ^ [/quote] .h文件中，那个函数声明也要改成： Link_t Test_new(void);

引用 4 楼 useprlove 的回复:在函数定义的地方加，而不是调用的地方加： Link_t Test_new( ) {...}       加完了还是会报警告warning: assignment makes pointer from integer without a cast [enabled by default]      head = Test_new();           ^

引用 2 楼 eseses455250704 的回复:[quote=引用 1 楼 ant2012 的回复:] Test_new( )  好像没有返回类型 应该是Link_t Test_new( )    吧     加上之后 error: expected expression before ‘Link_t’                      head = Link_t Test_new(); [/quote] 回去看书吧

引用 1 楼 ant2012 的回复:Test_new( )  好像没有返回类型 应该是Link_t Test_new( )    吧     加上之后 error: expected expression before ‘Link_t’                      head = Link_t Test_new();


Question: 多线程问题

多线程协调问题。

#include <iostream> #include <windows.h> #include <process.h>  using namespace std;  const int thread_num = 2; //线程个数 const int ouput_count = 5; //重复输出次数  HANDLE thread[thread_num]; HANDLE semaphore[thread_num];  #define P(s) WaitForSingleObject(s,INFINITE) #define V(s) ReleaseSemaphore(s,1,NULL)  void print_thread(void *argv)  { 	HANDLE s_cur, s_next; 	char c = (char)argv;  	s_cur = semaphore[c - 'A']; 	s_next = semaphore[(c - 'A' + 1) % thread_num];  	for (int i = 0; i < ouput_count; i++) 	{ 		P(s_cur); 		cout << c; 		V(s_next); 	} }  int main() { 	for (int i = 0; i < thread_num; i++) 	{ 		semaphore[i]=CreateSemaphore(NULL, 0, 1, NULL); 	}  	V(semaphore[0]);  	for (int i = 0; i < thread_num;i++) 	{ 		thread[i] = (HANDLE)_beginthread(print_thread, 0, (void *)('A'+i)); 	}  	WaitForMultipleObjects(thread_num, thread, TRUE, INFINITE); 	 	cout << endl;  	system("pause");  	return 0; }

引用 2 楼 xihu1364 的回复: //伪码 event1,event2;  void threadA() {     WaitForSingleObject(event1);     printf("A");     SetEvent(event2); } void threadB() {     WaitForSingleObject(event2);     printf("B");     SetEvent(event1); }   再加上个计数器控制5次，就达到楼主要求了

4楼 + 1

A线程操作时，B线程等待信号。 A线程操作完，发送给B线程信号。 B线程操作时，A线程等待信号。 B线程操作完，发送给A线程信号。


Question: 图像处理算法

参考OpenCV源代码相关片断。

低通滤波器在图像处理中主要是去除图像中的高频成分，一般高频成分是细节信息，有时噪声相对较多。所以经过低通滤波后，图像会去除一定的噪声，但是会变模糊。


Question: C语言典型内存安排

这问题问的很深入啊，大致分为栈区、堆区、全局/静态/常量区、代码区，这里引用一个博文： http://blog.csdn.net/youoran/article/details/10990815

这个语言本身有个毛的关系。差评。


Question: 看一下简单递归问题  卡在递归，为什么一直学不会

自底向上 自顶向下

@赵4老师 回答的主要是递归函数的编程实现上，而非设计。要设计递归函数主要分两步： 1. 确定状态（即函数所要实现的功能）。在这题中，函数f要达到输入一个参数n，打印n层的那种图形。 2. 确定状态转移方程（即递归方程）。在这题中，要实现n层图形只要先打印n-1层，再把最后一层打印出来即可，即如下递归方程：f(n) = f(n-1), 然后打印 n个 '$'3. 确定初始状态（即递归出口或叫终止条件）。在这题中，是：f(0) = 不打印任何东西综上，代码如下：void f(int n){ 	if(!n)return; 	f(n-1); 	while(n--)putchar('$'); 	putchar('\n'); } int main(){ 	f(5); }

搞懂了函数调用的过程对学习递归应该有帮助。

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

递归的思路，挺好理解的。 楼主，你可以用数学公式理解 f(n)  = f(n-1) + n;   // n != 0 f(0) = 4;    // n == 0 要想得到f(n)的值，就得先得到f(n-1)的值，这样层层递归，直到n == 0，则返回4; 因此递归函数： int f(int n) { 	if(n == 0) 	{ 		return 4; 	} 	else 	{ 		return f(n-1) + n; 	} }  再如楼主你提供的例子：要想打印n行$首先得打印前n-1行$，然后再打印第n行，则递归函数如下： void f(int n) { 	if(n == 0) 	{ 		return; 	} 	else 	{ 		f(n - 1); 		for(int i = 0; i < n; i++) 		{ 			printf("$"); 		} 		printf("\n"); 	} }

代码简单清晰，多看几遍就会了：  #include <stdio.h>  void print_dollar(int n) {     static int count = 1;     int i;      for(i = 0; i < count; i++)     {         putchar('$');     }     putchar('\n');     count++;      if(n > 1)     {         print_dollar(n - 1);     } }  int main(int argc, char* argv[]) {     print_dollar(5);     return 0; }

我觉得递归就是函数的自身调用吧，当达到某个条件的时候跳出循环。


参考C/C++标准。

引用 2 楼 zhao4zhong1 的回复:*(__u16 **)y_buf += image_width<<i;  老师能解释一下么 谢谢

有时间的话，可以研究http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf  引用 4 楼 liuzijiang1123 的回复:[quote=引用 3 楼 walkiz 的回复:] 左值不能强制类型转换，你可以这样做：  __u16* y16_buf = (__u16*)y_buf; ... y16_buf += image_width << i;   感谢，请问原理是什么，我还不懂[/quote]

引用 3 楼 walkiz 的回复:左值不能强制类型转换，你可以这样做：  __u16* y16_buf = (__u16*)y_buf; ... y16_buf += image_width << i;   感谢，请问原理是什么，我还不懂

*(__u16 **)y_buf += image_width<<i;

多上传了一幅同样的图片，错误在这个图片上


Question: c语言用extern 引用结构的问题，本人新手望解答

可以不用头文件，但这样在你引用的文件内必须重新声明你extern变量的结构

谢谢各位，分已给，继续看书

引用 6 楼 u014513151 的回复:[quote=引用 4 楼 songe88 的回复:] 就是说我必须要用头文件把这两个文件联系起来是么，不用.h文件不可以么   用一个头文件是最好的，C++中的话可以用 #ifndef _HEADERNAME_H #define _HEADERNAME_H  ...//(头文件内容)  #endif 这个东西防止重复定义，但是最好还是避免隐患[/quote]   额，少打字了，是C/C++可以用这个防止重复定义，C和C++都可以，，，

引用 4 楼 songe88 的回复:就是说我必须要用头文件把这两个文件联系起来是么，不用.h文件不可以么   用一个头文件是最好的，C++中的话可以用 #ifndef _HEADERNAME_H #define _HEADERNAME_H  ...//(头文件内容)  #endif 这个东西防止重复定义，但是最好还是避免隐患

引用 4 楼 songe88 的回复:就是说我必须要用头文件把这两个文件联系起来是么，不用.h文件不可以么  用两个源文件，这样在编译时，两个源文件都会编译一次，就会造成全局变量的重复定义

就是说我必须要用头文件把这两个文件联系起来是么，不用.h文件不可以么

extern 表示声明一个全局变量，并不是定义一个全局变量 当涉及多个文件使用同一个全局变量时，一般在某个头文件中extern声明一个全局变量，在其中某个源文件（包含了那个头文件）中定义这个全局变量，其它源文件，只要引用那个头文件，就可以使用这个全局变量了  以上程序，years数组只应用于一个源文件中，不需要加extern，直接把声明放在头文件中，把定义放在源文件中。而且楼主，你第二个文件没有包含第一个文件，struct date会无法识别吧

头文件： #include <stdio.h> #include <stdlib.h>   struct date { char month[15]; char abbreviation[4]; int days; int month_num; };  extern struct date years[12];  A.cpp： #include "head.h"  struct date years[12] = { {"January","Jan",31,1}, {"February","Feb",28,2}, {"March","Mar",31,3}, {"April","Apr",30,4}, {"May","May",31,5}, {"June","Jun",30,6}, {"July","Jul",31,7}, {"August","Aug",31,8}, {"September","Sep",30,9}, {"October","Oct",31,10}, {"November","Nov",30,11}, {"December","Dec",31,12} };   B.cpp： #include "head.h"  int main(void) { 	int i; 	puts("Enter month you want\"1-12\"(non digital to quit)"); 	while (scanf("%d", &i) == 1) 	{ 		int k = 0; 		while (getchar() != '\n') 			continue; 		 		for (int m = 0; m < i; m++) 			k += years[m].days; 		 		printf("%d days\n", k); 		puts("Enter month you want\"1-12\"(non digital to quit)"); 	}  	system("pause"); 	return 0; }  extern用法是正确的，不能有重复定义，你没有弄错，但是，文件2并不知道文件1的结构，所以，他知道years是结构数组，但他并不知道这个结构是什么样子的


Question: 如何向stdin里写字符 用getchar能读到。

_ungetch Pushes back the last charcter read from the console.  int _ungetch( int c );  Routine Required Header Compatibility  _ungetch <conio.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  _ungetch returns the character c if it is successful. A return value of EOF indicates an error.  Parameter  c  Character to be pushed  Remarks  The _ungetch function pushes the character c back to the console, causing c to be the next character read by _getch or _getche. _ungetch fails if it is called more than once before the next read. The c argument may not be EOF.  Example  /* UNGETCH.C: In this program, a white-space delimited   * token is read from the keyboard. When the program   * encounters a delimiter, it uses _ungetch to replace   * the character in the keyboard buffer.  */  #include <conio.h> #include <ctype.h> #include <stdio.h>  void main( void ) {    char buffer[100];    int count = 0;    int ch;    ch = _getche();    while( isspace( ch ) )      /* Skip preceding white space. */       ch = _getche();    while( count < 99 )         /* Gather token. */    {       if( isspace( ch ) )      /* End of token. */          break;       buffer[count++] = (char)ch;       ch = _getche();    }    _ungetch( ch );            /* Put back delimiter. */    buffer[count] = '\0';      /* Null terminate the token. */    printf( "\ntoken = %s\n", buffer ); }   Output  White token = White   Console and Port I/O Routines  See Also   _cscanf, _getch

int ungetc(int c, FILE *stream); int ungetch(int c);

stdin 本身是不可以的，不过它有个缓冲区，可以把字符放回缓冲区 用 ungetc 就可以了

不可能的，stdin 标准输入代表的是键盘，stdout 标准输出代表的是屏幕（虽然可以对他们重定向），你不能往键盘写东西，也不能从屏幕读东西


Question: NULL 为什么不可以赋值

0 地址并非不能赋值，只是方法不对：// 这样当然可以： int p = 0; *(int *)p = 0x1234ABCD;// 这样岂不乱套了？ *(int *)0 = 0x1234ABCD;如果第二种可以赋值，也就意味着上面说的 3 = 5; 这种写法在 C 语言里也应该是有效的。

如果你在开发驱动就会发现，NULL 是可以写的。

操作系统内存管理中应该有答案。

参考Linux源代码中内存管理相关源代码片断。

12楼正解 NULL是常量，不是变量，不能作为左值，只能作为右值~ 很基础的知识，再多看点书~

当NULL作为地址时， 就是RAM的0 地址，这个地址里存的内容可以被赋值，但是这个地址0不可以被赋值。 它的下一个地址是1，1也是常数也不可被赋值。 可以把NULL复制给一个或多个变量（包括指针变量），任何一个常数都可以赋值给变量。但是任何一个常数都不能被赋值。 你可以x=5,，但是不可以5=x。除非5==x

C语言把NULL作为字符串的最后一个字符,以表示字符串到此结束."\0" 这个"\0"就是NULL的值。这个值是常数。常数不可以被赋值。

NULL是一个常数。常数是不可被赋值的。 例如3是一个常数，不可以3=5，连 3=3都是不可以的。

这个问题就好比你在问为什么 int 是整型  而不是dafds表示整型   规定如此  没什么为什么

没有相应地址的访问权限。 自然也就谈不上赋值了。

NULL的根本意义在于实际应用中不可能存在的指针，不同的架构会有不同的值。当NULL为0时，表示0不会被用作其它用途，当NULL为-1时，表示0xffffffff不会被用作其它用途。如果你的实际用途中包含这样的地址，那么说明你的NULL定义是有问题的。

地址一般都有访问权限的

实际上早期的系统比如DOS，是可以赋值的，当时操作系统还通过检查程序运行前后，0地址处的值有没有变化，来看程序有没有运行出错。也就是说，一般而言，往0地址写入值，都是程序运行期错误导致的。 现代系统中，一般把最低的1KB到4KB作为无效写入地址，只要程序访问了，就认为是运行期错误。毕竟系统分配给你的有效地址范围，肯定不包含这一段。

程序用的虚拟地址，不是RAM实际的地址。


Question: C语言写入txt文本用记事本打开出现乱码

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

估计是编码方式，你确认下软件解析所使用的默认编码

给点代码提示，很多时候你自己想当然的以为自己的代码没有问题

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

”1000以内用记事本打开正常“是啥意思？ 是所有小于1000的素数，还是第1个到第 999个素数？

以字符方式输出就不会有问题的。

===========贴代码===========

你代码贴一下，没有存成二进制吧？或者也可能是由于编码原因

编码问题吧，你看看用的什么编码


Question: 数据结构迷宫算法,找不到问题出在哪？

做bfs,这个队列才20,感觉太小了


Question: 帮忙解决一下这个自定义的函数的功能。谢谢

从功能上来看，就是把data按照4个字节组成一个32位的整数，简单的写法是：  unsigned int WHS(unsigned char* data) { 	unsigned int temp = data[0]; 	temp |= data[1] << 8; 	temp |= data[2] << 16; 	temp |= data[3] << 24; 	return temp; }

大概是data0~4分别存了一个整数的4个字节，data[i]范围应该都是0~255。 然后这个函数把这4个字节转成一个完整的整数。 但是temp不初始化真的好么？

就是大小端转换吧： 例子：  int array[4] = {0x12,0x34,0x56,0x78}; int *data = array; 转成=> temp = 0x78563412

引用 楼主 jk_101 的回复:这个是自己写的自定义的函数，现在不知道他的功能，求解决。 int WHS(int *data) { 	int temp; 	temp+=(data[3]/16)*16*16*16*16*16*16*16; 	temp+=(data[3]%16)*16*16*16*16*16*16; 	temp+=(data[2]/16)*16*16*16*16*16; 	temp+=(data[2]%16)*16*16*16*16; 	temp+=(data[1]/16)*16*16*16; 	temp+=(data[1]%16)*16*16; 	temp+=data[0]; 	return temp; }能具体一点吗？当初写的比较急  谢谢 。这个 有初始值的。


Question: 关于给指针分配内存大小的问题。为什么是加3？？

strlen + 3这句肯定是错的，改为str_len + 2不应该崩啊。 崩在哪行代码？ 你用的什么编译器？ 输入什么样的数据崩溃的？

把一个函数名字，函数指针拿来 +3 能有什么意义？

引用 1 楼 user-4 的回复:先把代码格式化一下吧开门，送代码的 #include<stdio.h> #include<stdlib.h> #include<string.h> #define BUF_len 100 #define GESHU 5 void shuchu_zifuchuan(char**,int); char*hebing_zifuchuan(char**,int); int main(void) {     int chang=BUF_len ;     char buf[chang];     int str_count=GESHU ;     char**pS=NULL ;     pS=(char**)malloc(str_count*sizeof(char*));     int i=0 ;          while(true)     {         fflush(stdin);         if(!gets(buf))         {             printf("\n shuru chucuo!");             break ;         }         if(strlen(buf)==0)break ;         int str_len=strlen(buf)+1 ;         char*pStr=NULL ;         pStr=(char*)malloc(str_len);         strcpy(pStr,buf);                  if(str_count==i)         {             str_count+=GESHU ;             pS=(char**)realloc(pS,str_count*sizeof(char*));         }         pS[i++]=pStr ;     }          char*p=hebing_zifuchuan(pS,i);     printf("%s",p);          for(int j=0;i<i;++j)     {         free(pS[j]);         pS[j]=NULL ;     }          return 0 ;      }  char*hebing_zifuchuan(char**pS,int shu) {     char*p=NULL ;     p=(char*)calloc(1,sizeof(char));     int zongchang=0 ;          for(int i=0;i<shu;++i)     {         size_t str_len=strlen(pS[i]);         pS[i][str_len]='\n' ;         pS[i][str_len+1]='\0' ;                  int chang=strlen+3 ;         //------这里为什么是3,改成2和4的时候都崩溃。为什么？         zongchang+=chang ;                  char*pT=NULL ;         pT=(char*)realloc(p,zongchang*sizeof(char));         if(!pT)printf("\n kuozhan neicun shibai!!");         p=pT ;         strcat(p,pS[i]);     }          return p ; }

先把代码格式化一下吧


Question: 怎样才能将多个.o文件一起链接生成一个.exe文件？？

MASM跟MinGW下的GCC貌似很契合... 可以直接链接OBJ

放几张图片自行感受下

引用 11 楼 baidu_15527759 的回复:[quote=引用 10 楼 u013550545 的回复:] [quote=引用 9 楼 baidu_15527759 的回复:] [quote=引用 7 楼 u013550545 的回复:] nasm默认用的是16bit mode ..  如果lz用的是16位的 记得在文件内指定段类型 如果是格式问题的话... 得先搞清楚连接器是用的神马格式的 ... 一般而言就是 COFF/OMF两种 ...加上 coff(omf) 参数 试试 怎么加？ [/quote]http://blog.163.com/lixiangqiu_9202/blog/static/53575037201272711947530/[/quote]  [/quote]MinGW... 默认使用的是coff格式的.o文件-_- //~(...基本不使用GCC(经常使用VC)和控制台编译器程序..除了D语言,这点还真没了解)  ... 链接器无效应该是OBJ函数名对不上. nasm 应该这样写 nasm -fcoff Demo.asm (此时.o文件才会有可供链接的符号, 生产符号名 Demo)  gcc 声明前面加上 extern"C" (不加extern"C" OBJ函数修饰就不是C所使用的了)  最后一点是 gcc 在生成.o 文件extern的符号会多加一个 _ (_Demo) 你在写函数实现的时候记得在函数前面多加一个下划线.. gcc写声明的时候加上 extern"C"和没加下划线的函数名 .c文件亦是如此  nasm 和 gcc 都用的很少、 暂时没找到其他好的办法

引用 10 楼 u013550545 的回复:[quote=引用 9 楼 baidu_15527759 的回复:] [quote=引用 7 楼 u013550545 的回复:] nasm默认用的是16bit mode ..  如果lz用的是16位的 记得在文件内指定段类型 如果是格式问题的话... 得先搞清楚连接器是用的神马格式的 ... 一般而言就是 COFF/OMF两种 ...加上 coff(omf) 参数 试试 怎么加？ [/quote]http://blog.163.com/lixiangqiu_9202/blog/static/53575037201272711947530/[/quote]

引用 9 楼 baidu_15527759 的回复:[quote=引用 7 楼 u013550545 的回复:] nasm默认用的是16bit mode ..  如果lz用的是16位的 记得在文件内指定段类型 如果是格式问题的话... 得先搞清楚连接器是用的神马格式的 ... 一般而言就是 COFF/OMF两种 ...加上 coff(omf) 参数 试试 怎么加？ [/quote]http://blog.163.com/lixiangqiu_9202/blog/static/53575037201272711947530/

引用 7 楼 u013550545 的回复:nasm默认用的是16bit mode ..  如果lz用的是16位的 记得在文件内指定段类型 如果是格式问题的话... 得先搞清楚连接器是用的神马格式的 ... 一般而言就是 COFF/OMF两种 ...加上 coff(omf) 参数 试试 怎么加？

引用 5 楼 baidu_15527759 的回复:[quote=引用 4 楼 SXJIAKE 的回复:] gcc obj1.o obj2.o obj3.o -o file.exe obj1.o:file not recognized:File format not recognized collect2: ld returned 1 exit status[/quote]obj1.o、obj2.o、obj3.o 只是例子，要用你的 o 文件名列表换掉…………

引用 5 楼 baidu_15527759 的回复:[quote=引用 4 楼 SXJIAKE 的回复:] gcc obj1.o obj2.o obj3.o -o file.exe obj1.o:file not recognized:File format not recognized collect2: ld returned 1 exit status[/quote] ...................

引用 4 楼 SXJIAKE 的回复:gcc obj1.o obj2.o obj3.o -o file.exe obj1.o:file not recognized:File format not recognized collect2: ld returned 1 exit status

gcc obj1.o obj2.o obj3.o -o file.exe

那可不可以用mingwa链接？

用链接器，C和ASM写得程序都可以编译为.o的目标代码。

用连接器。。。66666


Question: 服务器端 监听连接的socket 描述符 用 select 监听 没反应

nt maxfd = connfd;  FD_SET(connfd, &rd);  while(1){ select(maxfd+1,&rd,NULL,NULL,NULL); 要吧listenfd加入到rd中哦。


Question: 请问setvbuf（）函数关联流和缓冲区的作用是什么

SETVBUF Section: POSIX Programmer's Manual (P) Updated: 2003  --------------------------------------------------------------------------------    NAME setvbuf - assign buffering to a stream    SYNOPSIS #include <stdio.h>    int setvbuf(FILE *restrict stream, char *restrict buf, int type,         size_t size);      DESCRIPTION The setvbuf() function may be used after the stream pointed to by stream is associated with an open file but before any other operation (other than an unsuccessful call to setvbuf()) is performed on the stream. The argument type determines how stream shall be buffered, as follows:   * {_IOFBF} shall cause input/output to be fully buffered.   * {_IOLBF} shall cause input/output to be line buffered.   * {_IONBF} shall cause input/output to be unbuffered.   If buf is not a null pointer, the array it points to may be used instead of a buffer allocated by setvbuf() and the argument size specifies the size of the array; otherwise, size may determine the size of a buffer allocated by the setvbuf() function. The contents of the array at any time are unspecified.   For information about streams, see Standard I/O Streams .     RETURN VALUE Upon successful completion, setvbuf() shall return 0. Otherwise, it shall return a non-zero value if an invalid value is given for type or if the request cannot be honored,  and may set errno to indicate the error.     ERRORS The setvbuf() function may fail if:   EBADF  The file descriptor underlying stream is not valid.   The following sections are informative.     EXAMPLES None.     APPLICATION USAGE A common source of error is allocating buffer space as an "automatic" variable in a code block, and then failing to close the stream in the same block.   With setvbuf(), allocating a buffer of size bytes does not necessarily imply that all of size bytes are used for the buffer area.   Applications should note that many implementations only provide line buffering on input from terminal devices.     RATIONALE None.     FUTURE DIRECTIONS None.     SEE ALSO Standard I/O Streams , fopen() , setbuf() , the Base Definitions volume of IEEE Std 1003.1-2001, <stdio.h>     COPYRIGHT Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .  --------------------------------------------------------------------------------

setvbuf Controls stream buffering and buffer size.  int setvbuf( FILE *stream, char *buffer, int mode, size_t size );  Routine Required Header Compatibility  setvbuf <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  setvbuf returns 0 if successful, or a nonzero value if an illegal type or buffer size is specified.  Parameters  stream  Pointer to FILE structure  buffer  User-allocated buffer  mode  Mode of buffering  size  Buffer size in bytes. Allowable range: 2 < size < 32768. Internally, the value supplied for size is rounded down to the nearest multiple of 2.  Remarks  The setvbuf function allows the program to control both buffering and buffer size for stream. stream must refer to an open file that has not undergone an I/O operation since it was opened. The array pointed to by buffer is used as the buffer, unless it is NULL, in which case setvbuf uses an automatically allocated buffer of length size/2 * 2 bytes.  The mode must be _IOFBF, _IOLBF, or _IONBF. If mode is _IOFBF or _IOLBF, then size is used as the size of the buffer. If mode is _IONBF, the stream is unbuffered and size and buffer are ignored. Values for mode and their meanings are:  _IOFBF  Full buffering; that is, buffer is used as the buffer and size is used as the size of the buffer. If buffer is NULL, an automatically allocated buffer size bytes long is used.  _IOLBF  With MS-DOS, the same as _IOFBF.  _IONBF  No buffer is used, regardless of buffer or size.  Example  /* SETVBUF.C: This program opens two streams: stream1  * and stream2. It then uses setvbuf to give stream1 a  * user-defined buffer of 1024 bytes and stream2 no buffer.  */  #include <stdio.h>  void main( void ) {    char buf[1024];    FILE *stream1, *stream2;     if( ((stream1 = fopen( "data1", "a" )) != NULL) &&        ((stream2 = fopen( "data2", "w" )) != NULL) )    {       if( setvbuf( stream1, buf, _IOFBF, sizeof( buf ) ) != 0 )          printf( "Incorrect type or size of buffer for stream1\n" );       else          printf( "'stream1' now has a buffer of 1024 bytes\n" );       if( setvbuf( stream2, NULL, _IONBF, 0 ) != 0 )          printf( "Incorrect type or size of buffer for stream2\n" );       else          printf( "'stream2' now has no buffer\n" );       _fcloseall();    } }   Output  'stream1' now has a buffer of 1024 bytes 'stream2' now has no buffer   Stream I/O Routines  See Also   fclose, fflush, fopen, setbuf

另外指定一个缓冲区

大神在哪啊。。。


Question: 服务端原始套接字，收到UDP报文， 返回ICMP，并且发送了UDP报文，但对方收不到。

1. 服务端使用的原始套接字来接收数据，相当于是跳过了操作系统的协议栈吧，操作系统可能不知道程序里面有什么处理，以为没有人处理就回了一个 ICMP 的包吧。（猜测） 2. 如果 ICMP 先到达，有这种可能，试试在路由器过滤掉那个 ICMP 包来实验下呢。 不同的网络不一样有可能是因为这两个包达到的顺序不一样

补充一下， 并不是所有的客户端都有这个问题， 有些客户端，如果用了电信 移动的4G信号，则可以  出问题的客户端， 用的是移动的wifi。


Question: 求解操作符的先后顺序

+号的优先级高于<<位移 楼主，直接百度c语言符号优先级就能查到操作符优先级表

～比>>的优先级高，+比>>高 先~a，然后，右移（1+2+3）位 char signed、 char unsigned 、char和short int参与运算时会提升为类型int. a=0XA5 提示为0X000000A5 然后进行求反得到0XFFFFFF5A 然后移位得到0X03FFFFFD，变u char即0XFD，即253

引用 1 楼 linux_liyi的回复:先~a 和1+2+3 然后友移 那么结果不是00000001么

先~a 和1+2+3 然后友移


Question: 如何返回BSTR给VBA

自己顶一下,  问题还是自己解决了 将	plData=(long*)malloc(4+lLen+2); 替换为	plData=(long*)HeapAlloc( GetProcessHeap(), 0,(4+lLen+2));  看 malloc 语句介绍说,  它也是调用 HeapAlloc. 这两者有什么区别吗.? 麻烦路过的看官, 出手解答一下.

malloc,new,VirtualAlloc,HeapAlloc性能(速度)比较 http://www.cppblog.com/woaidongmao/archive/2011/08/12/153160.aspx  HeapAlloc(_crtheap, 0, size);  _crtheap 这里什么意思?

以上代码分配内存少加了一个\0终止符的长度,  改过来后,但问题依旧   BSTR __stdcall HexToStr(PWSTR String) { 	//BYTE* buf = new BYTE[sizeof(INT32) + (wcslen(sz)+1)*sizeof(OLECHAR) ]; 	long lLen=16; 	long* plData;	__int64* pllData; 	plData=(long*)malloc(4+lLen+2); 	*plData=lLen;  	pllData=(__int64*)(plData+1); 	*pllData=0x0030003000300030i64; 	*(pllData+1)=0x0033003300330033i64; 	 	return (BSTR)pllData; }


Question: C语言的命令行参数如何输入回车啊,莫非必须以空格为间隔

引用 1 楼 user-1 的回复:加引号，去掉回车换行 --Windows 下面 引号内的 命令行参数，看作一个整体。 引用 1 楼 user-1 的回复:加引号，去掉回车换行 --Windows 下面 引号内的 命令行参数，看作一个整体。  真是太感谢了,赞赞赞呐~


Question: 我的git打不开了，现实找不到tmp目录

那试着改一下你的tmp目录，不要含中文和空格：   引用 9 楼 u011054333 的回复:[quote=引用 8 楼 walkiz 的回复:] 试一下 git for windows 客户端。  [quote=引用 7 楼 u011054333 的回复:] [quote=引用 4 楼 walkiz 的回复:] 1、/tmp 目录应该跟编码没有关系； 2、git 工程建议放在简单的目录，不含中文字符和空格为最好； 3、建议用 git for windows 客户端（https://git-for-windows.github.io/） 。嗯，可是它默认的挂载目录我没法不让他不含中文啊，他的/tmp貌似映射到 c/user/我的中文用户/appdata下了，所以现在不知道该怎么弄了[/quote][/quote]我装的那个貌似就是啊，现在我已经滚回了git 1.9，我又去git for windows 的github issue上提交一下问题，发现这个问题还不止我一个，项目路径含有中文字符的也不行[/quote]

引用 8 楼 walkiz 的回复:试一下 git for windows 客户端。  [quote=引用 7 楼 u011054333 的回复:] [quote=引用 4 楼 walkiz 的回复:] 1、/tmp 目录应该跟编码没有关系； 2、git 工程建议放在简单的目录，不含中文字符和空格为最好； 3、建议用 git for windows 客户端（https://git-for-windows.github.io/） 。嗯，可是它默认的挂载目录我没法不让他不含中文啊，他的/tmp貌似映射到 c/user/我的中文用户/appdata下了，所以现在不知道该怎么弄了[/quote][/quote]我装的那个貌似就是啊，现在我已经滚回了git 1.9，我又去git for windows 的github issue上提交一下问题，发现这个问题还不止我一个，项目路径含有中文字符的也不行

引用 10 楼 walkiz 的回复:那试着改一下你的tmp目录，不要含中文和空格：   [quote=引用 9 楼 u011054333 的回复:] [quote=引用 8 楼 walkiz 的回复:] 试一下 git for windows 客户端。  [quote=引用 7 楼 u011054333 的回复:] [quote=引用 4 楼 walkiz 的回复:] 1、/tmp 目录应该跟编码没有关系； 2、git 工程建议放在简单的目录，不含中文字符和空格为最好； 3、建议用 git for windows 客户端（https://git-for-windows.github.io/） 。嗯，可是它默认的挂载目录我没法不让他不含中文啊，他的/tmp貌似映射到 c/user/我的中文用户/appdata下了，所以现在不知道该怎么弄了[/quote][/quote]我装的那个貌似就是啊，现在我已经滚回了git 1.9，我又去git for windows 的github issue上提交一下问题，发现这个问题还不止我一个，项目路径含有中文字符的也不行[/quote][/quote]O哦，有用了，哈哈，谢谢大神

重装一下好了，应该不会损失你的数据

试一下 git for windows 客户端。  引用 7 楼 u011054333 的回复:[quote=引用 4 楼 walkiz 的回复:] 1、/tmp 目录应该跟编码没有关系； 2、git 工程建议放在简单的目录，不含中文字符和空格为最好； 3、建议用 git for windows 客户端（https://git-for-windows.github.io/） 。嗯，可是它默认的挂载目录我没法不让他不含中文啊，他的/tmp貌似映射到 c/user/我的中文用户/appdata下了，所以现在不知道该怎么弄了[/quote]

你这个是服务端？

引用 4 楼 walkiz 的回复:1、/tmp 目录应该跟编码没有关系； 2、git 工程建议放在简单的目录，不含中文字符和空格为最好； 3、建议用 git for windows 客户端（https://git-for-windows.github.io/） 。嗯，可是它默认的挂载目录我没法不让他不含中文啊，他的/tmp貌似映射到 c/user/我的中文用户/appdata下了，所以现在不知道该怎么弄了

引用 3 楼 ckc 的回复:重装一下好了，应该不会损失你的数据重装好几次了我现在正在考虑要不要退回到git1.9我在机房电脑上装的git2.5由于他是英文名用户名反而工作的很好

引用 2 楼 q3733353520 的回复:你这个是服务端？是客户端，但是貌似由于它模拟的挂载目录映射到我的windows临时文件目录含有中文，所以无法正常使用了

重发一下图…… 貌似是我的中文用户名和编码问题  但是当我把文件编码改成gbk以后倒是不提示我出错了，变成了这个错误    我想着先取消挂载然后自己重新挂一个/tmp目录也不行，现在我是没招了，求助大神们该如何解决


Question: 使用ODBC如何保存char类型到数据库？

跟别的类型没什么差异啊


Question: 帮忙看看这个为什么我在win32中显示不了系统菜单

大佬，太感谢啦

引用 11 楼 u012792138 的回复:显示系统菜单怎么办？@？？？ 啥子咋办 系统菜单不是显示有的吗  你知道系统菜单是哪个不？ 在标题栏点右键弹出的菜单，你去试试，你添加的菜单项已经在里面了的。

呃 大佬对不起我明白了 嗨

显示系统菜单怎么办？@？？？

引用 8 楼 u012792138 的回复:上面这个我想显示一个按钮可显示不出来？？？  两个问题是一个错误吗？？  HWND	hwndpop=CreateWindow(_T("aa"),_T("KK"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 10,20,30,40,hwnd,(HMENU)1,((LPCREATESTRUCT)lParam)->hInstance,NULL);  改成  			HWND	hwndpop=CreateWindow(_T("button"),_T("KK"), 				WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 				10,20,30,40,hwnd,(HMENU)1,((LPCREATESTRUCT)lParam)->hInstance,NULL);

case WM_SYSCOMMAND: // switch(LOWORD(wParam)) { case IDR_SYS_MENU2:     MessageBox(NULL,_T("aaa"),_T("aa)"),MB_ICONERROR);    return 0; } return 0;   这里的 return 0 改成 DefWindowProc   case WM_SYSCOMMAND: // switch(LOWORD(wParam)) { case IDR_SYS_MENU2:     MessageBox(NULL,_T("aaa"),_T("aa)"),MB_ICONERROR);    return 0; } return DefWindowProc(hwnd, message, wParam, lParam);   你不让系统处理移动，关闭这些消息，自然没有反应了。

上面这个我想显示一个按钮可显示不出来？？？  两个问题是一个错误吗？？

#include <tchar.h> #include <windows.h> #define ID_TIME1  1 #define ID_TIME2  2 #define ID_TIME3  3 /*  Declare Windows procedure  */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);   /*  Make the class name into a global variable  */ TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");   int WINAPI WinMain (HINSTANCE hThisInstance,                      HINSTANCE hPrevInstance,                      LPSTR lpszArgument,                      int nCmdShow) {     HWND hwnd;               /* This is the handle for our window */     MSG messages;            /* Here messages to the application are saved */     WNDCLASSEX wincl;        /* Data structure for the windowclass */       /* The Window structure */     wincl.hInstance = hThisInstance;     wincl.lpszClassName = szClassName;     wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */     wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */     wincl.cbSize = sizeof (WNDCLASSEX);       /* Use default icon and mouse-pointer */     wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);     wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);     wincl.lpszMenuName = NULL;                 /* No menu */     wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */     wincl.cbWndExtra = 0;                      /* structure or the window instance */     /* Use Windows's default colour as the background of the window */     wincl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ;       /* Register the window class, and if it fails quit the program */     if (!RegisterClassEx (&wincl))         return 0;       /* The class is registered, let's create the program*/     hwnd = CreateWindowEx (            0,                   /* Extended possibilites for variation */            szClassName,         /* Classname */            _T("Code::Blocks Template Windows App"),       /* Title Text */            WS_OVERLAPPEDWINDOW, /* default window */            CW_USEDEFAULT,       /* Windows decides the position */            CW_USEDEFAULT,       /* where the window ends up on the screen */            544,                 /* The programs width */            375,                 /* and height in pixels */            HWND_DESKTOP,        /* The window is a child-window to desktop */            NULL,                /* No menu */            hThisInstance,       /* Program Instance handler */            NULL                 /* No Window Creation data */            );       /* Make the window visible on the screen */     ShowWindow (hwnd, nCmdShow);       /* Run the message loop. It will run until GetMessage() returns 0 */     while (GetMessage (&messages, NULL, 0, 0))     {         /* Translate virtual-key messages into character messages */         TranslateMessage(&messages);         /* Send message to WindowProcedure */         DispatchMessage(&messages);     }       /* The program return-value is 0 - The value that PostQuitMessage() gave */     return messages.wParam; }     /*  This function is called by the Windows function DispatchMessage()  */   LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {//Run-Time Check Failure #3 - The variable 'hwndpop' is being used without being initialized. 	HDC hdc; 	 //hwndpop; 		PAINTSTRUCT ps; 	static	int M=0,N=0;     switch (message)                  /* handle the messages */     { 	case WM_CREATE: 	{	//SetTimer(hwnd,ID_TIME1,1000,NULL); 		//SetTimer(hwnd,ID_TIME2,60000,NULL); 		//SetTimer(hwnd,ID_TIME3,3600000,NULL); 	HWND	hwndpop=CreateWindow(_T("aa"),_T("KK"), 							WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 							10,20,30,40,hwnd,(HMENU)1,((LPCREATESTRUCT)lParam)->hInstance,NULL); 		 		return 0;} 	/*case WM_TIMER: 			M=!M; 			 			InvalidateRect(hwnd,NULL,FALSE); 			return 0; 		 		//case ID_TIME2: 		//case ID_TIME3: 			//MessageBox(NULL,_T("hh"),_T("AA"),NULL); 			*/ 	case WM_PAINT: hdc=BeginPaint(hwnd,&ps);  //Rectangle(hdc,200,200,1000,1000); //InvalidateRect(hwnd,NULL,TRUE //UpdateWindow(hwndpop);  		//MoveToEx(hdc,0,0,NULL); 			//LineTo(hdc,120,120); 			//InvalidateRect(hwnd,NULL,TRUE);  EndPaint(hwnd,&ps); 			 		break;         case WM_DESTROY:             PostQuitMessage (0);       /* send a WM_QUIT to the message queue */             break;         default:                      /* for messages that we don't deal with */             return DefWindowProc (hwnd, message, wParam, lParam);     }       return 0; }

给你一个范例，参照它调试一下自己的代码：  #if defined(UNICODE) && !defined(_UNICODE)     #define _UNICODE #elif defined(_UNICODE) && !defined(UNICODE)     #define UNICODE #endif  #include <tchar.h> #include <windows.h>  /*  Declare Windows procedure  */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);  /*  Make the class name into a global variable  */ TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");  int WINAPI WinMain (HINSTANCE hThisInstance,                      HINSTANCE hPrevInstance,                      LPSTR lpszArgument,                      int nCmdShow) {     HWND hwnd;               /* This is the handle for our window */     MSG messages;            /* Here messages to the application are saved */     WNDCLASSEX wincl;        /* Data structure for the windowclass */      /* The Window structure */     wincl.hInstance = hThisInstance;     wincl.lpszClassName = szClassName;     wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */     wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */     wincl.cbSize = sizeof (WNDCLASSEX);      /* Use default icon and mouse-pointer */     wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);     wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);     wincl.lpszMenuName = NULL;                 /* No menu */     wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */     wincl.cbWndExtra = 0;                      /* structure or the window instance */     /* Use Windows's default colour as the background of the window */     wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;      /* Register the window class, and if it fails quit the program */     if (!RegisterClassEx (&wincl))         return 0;      /* The class is registered, let's create the program*/     hwnd = CreateWindowEx (            0,                   /* Extended possibilites for variation */            szClassName,         /* Classname */            _T("Code::Blocks Template Windows App"),       /* Title Text */            WS_OVERLAPPEDWINDOW, /* default window */            CW_USEDEFAULT,       /* Windows decides the position */            CW_USEDEFAULT,       /* where the window ends up on the screen */            544,                 /* The programs width */            375,                 /* and height in pixels */            HWND_DESKTOP,        /* The window is a child-window to desktop */            NULL,                /* No menu */            hThisInstance,       /* Program Instance handler */            NULL                 /* No Window Creation data */            );      /* Make the window visible on the screen */     ShowWindow (hwnd, nCmdShow);      /* Run the message loop. It will run until GetMessage() returns 0 */     while (GetMessage (&messages, NULL, 0, 0))     {         /* Translate virtual-key messages into character messages */         TranslateMessage(&messages);         /* Send message to WindowProcedure */         DispatchMessage(&messages);     }      /* The program return-value is 0 - The value that PostQuitMessage() gave */     return messages.wParam; }   /*  This function is called by the Windows function DispatchMessage()  */  LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {     switch (message)                  /* handle the messages */     {         case WM_DESTROY:             PostQuitMessage (0);       /* send a WM_QUIT to the message queue */             break;         default:                      /* for messages that we don't deal with */             return DefWindowProc (hwnd, message, wParam, lParam);     }      return 0; }

我想显示系统菜单 在windows程序设计.第10章里有个例子，可我运行就没有系统菜单还有就是什么都动不了只能靠任务管理器关闭？？？

没用啊？？不是这里问题？？

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

而且我运行之后整个都窗口都死掉了，关都关不了只有打开任务管理器才关掉


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

第一个问题：是将\n的值赋值个了 ch ，在     printf("请输入你要对数据的处理方式，若为加法请输入A ,若为乘法请输入B或者C。\n");     scanf("%c", &ch);  中间加getchar（）; 也就是   printf("请输入你要对数据的处理方式，若为加法请输入A ,若为乘法请输入B或者C。\n"); getchar（）； scanf("%c", &ch);

如果是double就改成 const double EPSILON = 1E-15;

引用 8 楼 believeforever6 的回复:系统运行会报错呀 error: 'ESPILON'  does not name a type  不好意思，写错了 const EPSILON = 1E-6; 改成 const float EPSILON = 1E-6;

引用 3 楼 ant2012 的回复:当你输入a b敲回车结束时，a b读完值后，将换行字符给了ch 这样，程序接着执行switch语句  解决办法：在输入字符前，加fflush(stdin);清空输入缓存区  正解

不过一般浮点型与0值的比较，需要设计精度的问题 const EPSILON = 1E-6; if(x >= -EPSILON && x <= EPSILON )  //x等于0

else if (x = 0)  x = 0 少了一个等号

两种方法都是可以的，谢谢两位了。 还有个问题想请问一下， # include <stdio.h> # include <math.h>  int main(void) {     float x, y;      printf("请输入该方程x的取值！\n");     scanf("%f",&x);      if (x > 0)     {         y = 4*x + sqrt(9);     }     else if (x = 0)     {         y = 0;     }     else     {         y = 4 + x ;                    // 为什莫会出错，此处输入负数之后运行结果错误！！！     }      printf("y = %f\n",y);       return 0; }

谢谢了，我试试，看看结果！

引用 1 楼 user-6 的回复:一看就知道是因为回车的问题, lz需要调试啊. 在"switch(ch)"这个地方下个断点, 啥问题都解决了..  很久没用标准输入了, 都忘记处理方式了. 试试    while(ch == '\n') scanf("%c", &ch);  需要初始化char ch = '\n';


Question: 很简单的问题:如何定义定长的常量数组.

谢谢 zhao4zhong1 赵4老师 提醒

谢谢  zilaishuichina, 赵4老师, 也谢谢 xihu1364 基本解决了我疑问. 只想找一种方便的写法. 没想到还是没有捷径。 但又学到一些  看看我这个代码还有优化的地方吗? 我自己 觉得很不错了.速度应该没比这个再快了(除了汇编)  //十进制转二进制 BSTR __stdcall DecToBin(long Number, long Places) { 	static __int64 DEC_BIN[16]={0x0030003000300030,0x0031003000300030,0x0030003100300030,0x0031003100300030,0x0030003000310030,0x0031003000310030,0x0030003100310030,0x0031003100310030,0x0030003000300031,0x0031003000300031,0x0030003100300031,0x0031003100300031,0x0030003000310031,0x0031003000310031,0x0030003100310031,0x0031003100310031}; 	__int64 wRet[8]={0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030};  	wRet[0]=DEC_BIN[(Number & 0xF0000000) >> 28]; 	wRet[1]=DEC_BIN[(Number & 0x0F000000) >> 24]; 	wRet[2]=DEC_BIN[(Number & 0x00F00000) >> 20]; 	wRet[3]=DEC_BIN[(Number & 0x000F0000) >> 16]; 	wRet[4]=DEC_BIN[(Number & 0x0000F000) >> 12]; 	wRet[5]=DEC_BIN[(Number & 0x00000F00) >> 8]; 	wRet[6]=DEC_BIN[(Number & 0x000000F0) >> 4]; 	wRet[7]=DEC_BIN[Number & 0x0000000F];  	//返回bstr数据 	return SysAllocStringLen((OLECHAR*)wRet, Places); }

楼主 你就  wchar_t DEC_BIN[16][5] = {{'0','0','0','0'},....} 了

哦 是wchar_t DEC_BIN[16][4]

引用 9 楼 topses 的回复:[quote=引用 7 楼 qq_30900077 的回复:] 用用这个吧  wchar_t* DEC_BIN[16] = {L"0000",L"0001",L"0010",L"0011",L"0100",L"0101",L"0110",L"0111",L"1000",L"1001",L"1010",L"1011",L"1100",L"1101",L"1110",L"1111"};  无语了....比我还菜的人有这多么多........ wchar_t* DEC_BIN....这个申明的是指针数组,日....不是我要的. 定长数组不懂吗?  要求, 申明一个元素为16字节长的数组就这么简单  三楼的是连续内存块,但老是多一个\0字符 const char DEC_BIN[16][5] = { "0000", "0001", "0002", "0003", "0004", "0005", "0006", "0007", "0008", "0009", "000A", "000B", "000C", "000D", "000E", "000F" }; [/quote]  多一个\0 是因为你用的字符串， "0000"你这样写，就是带\0的只是你看不见， 你不想要\0，就不要定义成字符串

const wchar_t DEC_BIN[16][4]={     {L'0',L'0',L'0',L'0'},     {L'0',L'0',L'0',L'1'},     {L'0',L'0',L'0',L'2'},     {L'0',L'0',L'0',L'3'},     {L'0',L'0',L'0',L'4'},     {L'0',L'0',L'0',L'5'},     {L'0',L'0',L'0',L'6'},     {L'0',L'0',L'0',L'7'},     {L'0',L'0',L'0',L'8'},     {L'0',L'0',L'0',L'9'},     {L'0',L'0',L'0',L'A'},     {L'0',L'0',L'0',L'B'},     {L'0',L'0',L'0',L'C'},     {L'0',L'0',L'0',L'D'},     {L'0',L'0',L'0',L'E'},     {L'0',L'0',L'0',L'F'}, };

引用 7 楼 qq_30900077 的回复:用用这个吧  wchar_t* DEC_BIN[16] = {L"0000",L"0001",L"0010",L"0011",L"0100",L"0101",L"0110",L"0111",L"1000",L"1001",L"1010",L"1011",L"1100",L"1101",L"1110",L"1111"};  无语了....比我还菜的人有这多么多........ wchar_t* DEC_BIN....这个申明的是指针数组,日....不是我要的. 定长数组不懂吗?  要求, 申明一个元素为16字节长的数组就这么简单  三楼的是连续内存块,但老是多一个\0字符 const char DEC_BIN[16][5] = { "0000", "0001", "0002", "0003", "0004", "0005", "0006", "0007", "0008", "0009", "000A", "000B", "000C", "000D", "000E", "000F" };

引用 6 楼 topses 的回复:我的要求很简单 在C中实现定长数组, 如果VB中dim FixedStr(15) as  string * 8  你们看,我只想用 wchar_t* DEC_BIN[16] = {L"0000",L"0001",L"0010",L"0011",L"0100",L"0101",L"0110",L"0111",L"1000",L"1001",L"1010",L"1011",L"1100",L"1101",L"1110",L"1111"};   完成下面的功能 __int64 DEC_BIN[16] = {0x30003000300030,0x30003000300031,0x30003000310030,0x30003000310031,0x30003100300030.......  上面是8字节为一组还好有int64对应,但如遇到16字节一组那咋写  const unsigned char DEC_BIN[16 * 8] = {  		0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,  		0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 		0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x30, 0x00, 		0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 		0x30, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 		0x30, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, 		0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 		0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 		0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 		0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 		0x31, 0x00, 0x30, 0x00, 0x31, 0x00, 0x30, 0x00, 		0x31, 0x00, 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 		0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 		0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, 		0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 		0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 	};

引用 2 楼 xihu1364 的回复:[quote=引用 楼主 topses 的回复:] 很简单的问题:如何定义定长的常量数组.   const wchar_t DEC_BIN[15]={"0000","0001","0002","0003","0004","0005","0006","0007","0008","0009","000A","000B","000C","000D","000E","000F"};  以上编译失败,帮我指点一下.  楼主，你这数组成员都是字符串啊  const wchar_t DEC_BIN[3]={0x00,0x01,0x02} 想这样？ 还是 const wchar_t DEC_BIN[3]={’0‘,’1‘,’2‘} ？[/quote]  我成员 是字符串, 但我想申明为连续的内存块. 版主你的只能单个字符  帮我看看下面的, 申明不是连续内存块.我要的是连续的内存块 wchar_t* DEC_BIN[16] = {L"0000",L"0001",L"0010",L"0011",L"0100",L"0101",L"0110",L"0111",L"1000",L"1001",L"1010",L"1011",L"1100",L"1101",L"1110",L"1111"};

我是想申明为连续的内存块, 二楼的不行

引用 楼主 topses 的回复:很简单的问题:如何定义定长的常量数组.   const wchar_t DEC_BIN[15]={"0000","0001","0002","0003","0004","0005","0006","0007","0008","0009","000A","000B","000C","000D","000E","000F"};  以上编译失败,帮我指点一下.  楼主，你这数组成员都是字符串啊  const wchar_t DEC_BIN[3]={0x00,0x01,0x02} 想这样？ 还是 const wchar_t DEC_BIN[3]={’0‘,’1‘,’2‘} ？

const char* DEC_BIN[16] = {"0000","0001","0002","0003","0004","0005","0006","0007","0008","0009","000A","000B","000C","000D","000E","000F"};  要用 wchar_t 的话，后面的初始值需要用 L.

引用 16 楼 topses 的回复:呵呵 10楼写起来会要了你命 我支持8楼和我自己的.这样直接在EXCEL模板里鼠标动动, 代码就生成了.  BSTR __stdcall DecToBin(long Number, long Places) { 	static __int64 DEC_BIN[16]={0x0030003000300030,0x0031003000300030,0x0030003100300030,0x0031003100300030,0x0030003000310030,0x0031003000310030,0x0030003100310030,0x0031003100310030,0x0030003000300031,0x0031003000300031,0x0030003100300031,0x0031003100300031,0x0030003000310031,0x0031003000310031,0x0030003100310031,0x0031003100310031}; 	__int64 wRet[8]={0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030,0x0030003000300030};  	wRet[0]=DEC_BIN[(Number & 0xF0000000) >> 28]; 	wRet[1]=DEC_BIN[(Number & 0x0F000000) >> 24]; 	wRet[2]=DEC_BIN[(Number & 0x00F00000) >> 20]; 	wRet[3]=DEC_BIN[(Number & 0x000F0000) >> 16]; 	wRet[4]=DEC_BIN[(Number & 0x0000F000) >> 12]; 	wRet[5]=DEC_BIN[(Number & 0x00000F00) >> 8]; 	wRet[6]=DEC_BIN[(Number & 0x000000F0) >> 4]; 	wRet[7]=DEC_BIN[Number & 0x0000000F];  	//修正占位符的长度 	short *wTmp = (short*)wRet; 	if ((Places < 1) || (Places > 32)) 	{	 		while(*wTmp == 0x30)  wTmp++;  		Places = 32 - (wTmp - (short*)wRet);  		if (Places <= 0)  Places = 1, wTmp--; 	}; 	//返回bstr数据 	return SysAllocStringLen((OLECHAR*)wTmp, Places); }  为了调整占用位符,这行代码,花了我整整1个小时.唉 那只是因为你用的编辑器不给力。 BSTR __stdcall DecToBin(long Number, long Places) {     static __int64 DEC_BIN[16]={         0x0030003000300030i64,         0x0031003000300030i64,         0x0030003100300030i64,         0x0031003100300030i64,         0x0030003000310030i64,         0x0031003000310030i64,         0x0030003100310030i64,         0x0031003100310030i64,         0x0030003000300031i64,         0x0031003000300031i64,         0x0030003100300031i64,         0x0031003100300031i64,         0x0030003000310031i64,         0x0031003000310031i64,         0x0030003100310031i64,         0x0031003100310031i64,     };     __int64 wRet[8]={         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,         0x0030003000300030i64,     };     wRet[0]=DEC_BIN[(Number & 0xF0000000) >> 28];     wRet[1]=DEC_BIN[(Number & 0x0F000000) >> 24];     wRet[2]=DEC_BIN[(Number & 0x00F00000) >> 20];     wRet[3]=DEC_BIN[(Number & 0x000F0000) >> 16];     wRet[4]=DEC_BIN[(Number & 0x0000F000) >> 12];     wRet[5]=DEC_BIN[(Number & 0x00000F00) >>  8];     wRet[6]=DEC_BIN[(Number & 0x000000F0) >>  4];     wRet[7]=DEC_BIN[(Number & 0x0000000F)      ];     //修正占位符的长度     short *wTmp = (short*)wRet;     if ((Places < 1) || (Places > 32)) {         while (*wTmp == 0x30)  wTmp++;         Places = 32 - (wTmp - (short*)wRet);         if (Places <= 0)  {Places = 1; wTmp--;}     }     //返回bstr数据     return SysAllocStringLen((OLECHAR*)wTmp,Places); }

支持10楼的


Question: 写一个算法，怎样将16进制的字符累加取反加1

#inlcude <stdio.h> char str[28]={ '\xaa','\x1d','\xea','\x00', '\x00','\x00','\x00','\x00', '\x00','\x02','\xaa','\x55', '\x04','\x00','\x13','\x02', '\xb9','\x0b','\x01','\x01', '\x01','\x01','\x00','\x00', '\x00','\x00','\x00','\x00', }; int i; unsigned char sum; int main() {     sum=0;     for (i=0;i<28;i++) sum+=(unsigned char)str[i];     sum=~sum+1;     printf("%02x\n",sum);     return 0; }

涉及到大数运算，建议直接用GMP库（https://gmplib.org/），或者是参考它的源代码。

如果数据非常多，连最大整形都hold不住，那就要字符串，对字符串重载+号和~号

你这样定义也不行，编译能不过  楼主，你可这样定义： unsigned char ch= 0xaa; 然后就可以累加和取反了，不过得注意越界问题，unsigned char 为1字节，最大为ff，即十进制255，可以考虑用unsigned short 或者 unsigned int

不好意思，是 char str[28]. 累加就是  aa+1d+ea+00 ......

引用 楼主 qq_24484465 的回复:输入 char str[10]={ "aa','1d','ea','00"     ,"00','00','00','00"     ,"00','02','aa','55"     ,"04','00','13','02"     ,"b9','0b','01','01"     ,"01','01','00','00",     "00','00','00','00"};  输出 20    怎样将16进制的字符累加取反加1   楼主，你这多少数据啊，怎么才用10个char类型存储  字符累加是什么意思，还请楼主详说，取反用~操作符就行了


Question: 编译错误  求指点    具体些  谢谢各位

int main(int argc, char **argv) { 	int i; 	int passed = 0; 	int failed = 0;  	printf("\n----------- Begin Unit Test ----------\n");  	BEGIN_TEST 		test_getlength(), 		test_constains(), 		test_put(), 		test_get(), 		test_replace(), 		test_remove(), 	END_TEST  	printf("Tests run: %d\n", sizeof(testResults) / sizeof(char*)); 	for(i = 0; i < sizeof(testResults) / sizeof(char*); ++i;) 	{ 		if(testResults[i]) 		{ 			printf("TEST %d Error: %s\n", i, testResults[i]); 			++passed; 		} 		else 		{ 			++failed; 			printf("TEST %d Passed", i); 		} 		printf("\n------------End Unit Test -------------\n"); 		printf("Passed: %d 个 \n",passed); 		printf("Failed: %d 个 \n",failed); 		printf("\n----------------------------------------\n"); 		return 0 	} }

main函数 里面 第四行 也就是BEGIN_TEST的上面一行， 又来一遍  int main(int argc, char **argv)， 我也没明白你想干点啥

BEGIN_TEST             test_getlength()             test_constains()             test_put()             test_get()             test_replace()             test_remove()             END_TEST  这段代码替换之后就是  char* testResults[] = {             test_getlength()             test_constains()             test_put()             test_get()             test_replace()             test_remove() };  lz我没有明白你这段代码想干点啥

test_getlength()             test_constains()             test_put()             test_get()             test_replace()             test_remove() 是不是中间少了逗号

没有symtable.h

宏是一种语法糖。 语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。


Question: 为什么结构体这样定义别人可以编译，我的却不能编译~？

该语法在c99下是可编译通过的， （问题出在了我的编译器设置问题，一个是c99编译，一个不是（我也不知道是哪个标准））。

const struct ke_state_handler TEST_spotar_state_handler[TEST_SPOTAR_STATE_MAX] = {     [TEST_SPOTAR_DISABLED]    = KE_STATE_HANDLER(TEST_spotar_disabled),     [TEST_SPOTAR_IDLE]        = KE_STATE_HANDLER(TEST_spotar_idle),     [TEST_SPOTAR_ACTIVE]   = KE_STATE_HANDLER(TEST_spotar_active), }; 但我在相同编译器下那样定义却不能通过定义。 结构体中[] = ,是什么意思？

还是少用些新特性吧，主动给自己系统以后的兼容性埋坑

const struct ke_state_handler TEST_spotar_state_handler[TEST_SPOTAR_STATE_MAX]  这是c的写法  struct ke_state_handler  表示一个类型 TEST_spotar_state_handler[TEST_SPOTAR_STATE_MAX]是数组  用c++的写法，可以如下： class ke_state_handler {    //.... }; const ke_state_handler TEST_spotar_state_handler[TEST_SPOTAR_STATE_MAX] = ｛...

windows 不区分大小写，linux,unix 区分 所以 .c,.C 对于Widows 都是 C文件 但是linux,unix 就不同了，我记着 ，大写是C++，小写是C

引用 3 楼 user-4 的回复:[quote=引用 2 楼 jimoxiaosage 的回复:] [quote=引用 1 楼 user-4 的回复:] 这是 c99 的特出语法，c++不支持。 我也用了同样的 编译器，也是不通过的哦~[/quote] 你两次编译的语言类型不一样，第一次程序按 C 语言编译，通过了；第二次按 C++ 的编译，没通过。 如果你用的是 VC，有可能是因为文件扩展名不同造成的，vc 会根据扩展名自动选择编译语言，.c 的按 C 编译，.cpp 的按c++编译。[/quote] 实际上 clang 也是自动选择，gcc 估计也是。

引用 2 楼 jimoxiaosage 的回复:[quote=引用 1 楼 user-4 的回复:] 这是 c99 的特出语法，c++不支持。 我也用了同样的 编译器，也是不通过的哦~[/quote] 你两次编译的语言类型不一样，第一次程序按 C 语言编译，通过了；第二次按 C++ 的编译，没通过。 如果你用的是 VC，有可能是因为文件扩展名不同造成的，vc 会根据扩展名自动选择编译语言，.c 的按 C 编译，.cpp 的按c++编译。

引用 1 楼 user-4 的回复:这是 c99 的特出语法，c++不支持。 我也用了同样的 编译器，也是不通过的哦~

这是 c99 的特出语法，c++不支持。


Question: pS【i】！=NULL，作为条件，来控制输出，为什么会出错

越界太危险，，

引用 2 楼 qq_30446977 的回复:那该怎么办呢？ 其实我也想到这个了，超出pS数组后，肯定是一个指针，但不一定是指向哪里的指针。后来我想改变循环条件，但是发现我居然对如何求一个字符串数组，有几个字符串，没办法。 怎么办？  子函数，加一个参数，传字符串个数。而且楼主你这存在内存泄露的问题

因为超出你赋值后，它的值虽然不为NULL，但是是个野指针