Question: 钩子如何屏蔽win键和菜单键的释放消息？

是否要用到全局钩子，dll 形式。

楼主应该去改键盘驱动。

是这样的：我在编写一个汉字输入法软件。汉字输入法软件，可以只针对某个窗口的。 如果你默认的汉字输入法是搜狗拼音输入法，那么你在某个记事本窗口中选择了五笔字型输入法的时候并不意味着其它窗口也选改成了五笔字型输入法，而仍然是默认的搜狗拼音输入法，你刚才选择的输入法改变仅在你刚才改变的那个窗口中有效，你如果要其它的窗口也改变，你就给一个一个去改。如果你安装了12个输入法，你可以为你的12个窗口各选一个不同的输入法。 底层键盘钩子也能这样吗？如果不能，那我就没有必要用底层钩子了，自然也就不用去钻研了。

看来上面的问题很难没人能答出。现在把问题改一下：  底层键盘钩子，是不是总是全局的？ 就是说，针对所有应用程序的？ 讲的更具体一些：是不是说，我一旦用底层键盘钩子把A改为B，那么所有的窗口，例如记事本、world、浏览器、股票交易软件、电子游戏等等，打A都出来B？能不能只针对notepad.exe的某个窗口而其他窗口不改？

LRESULT CALLBACK KeyboardCtl(int nCode, WPARAM wParam, LPARAM lParam) { 	if (nCode == HC_ACTION) 	{ 		if ((GetAsyncKeyState(VK_RWIN) & 0x8000) || (GetAsyncKeyState(VK_RCONTROL) & 0x8000) 		    || (GetAsyncKeyState(VK_RMENU ) & 0x8000) ||  (GetAsyncKeyState(VK_RALT ) & 0x8000)) 		{ 			return TRUE; 		} 	}  	return CallNextHookEx(hHook, nCode, wParam, lParam); }

因为处理win键和菜单键的程序逻辑不在HookAPI能控制的范围内？


Question: 求助。 ATM机的代码

另外，楼主应该用数据库的

追求效率，空间足够的话，另外建立一个文件来存吧，遇到要删除的跳过 空间有限的话，只能用fseek来回定位慢慢移了，就是定位到要删除的行首后，用下一行的字符填充，结束加EOF


Question: char 转 int 的一个问题 char = -1 的问题

我昨天晚上读书看到了类似的问题，int arry[] = {23, 34, 12, 17, 204, 99, 16};  #define TOTAL_ELEMENTS (sizeof(arry) / sizeof(arry[0]))  int main() { int d = -1; /* ...   */   if(d < = TOTAL_ELEMENTS -2) x = arry[d+1];  } 这里if表达式的值却不是真的，因为sizeof()的返回值是 unsigned int ，d的只是signed int，导致d 被转换成一个很大的正整数。楼主的和这个也差不多

引用 10 楼 mujiok2003 的回复:char a = -1;  int b = (signed char)a; // -1 int c = (unsigned char)a; //1   int c = (unsigned char)a; //255

whether a ``plain'' char is treated as signed is implementation-defined.

要解决移植问题，你可以直接用 signed char 或 unsigned char  用char的话，可以赋值给int时，加个到signed char或 unsigned char 的类型转换。

移植的時候是不是標頭檔要定義先

应该是有一个char被当作unsigned char 了。  在ios下面用这个代码：  ios下 unsigned char a = -1; int b = a; 这里的b = 255

引用 3 楼 qq_22545711 的回复:跟补码有关系，char里面的二进制换算成十进制是255， 你这种情况应该是在IOS里面转换的时候，在前面填充的都是1， 在android中应该填充的都是0.所以显示数字不同。+1

显式类型转换

直接指明是signed char还算unsigned char  另外，避免不同类型的初始化或赋值操作。

应尽量避免不同类型互相赋值，一般情况下： 如果 char b=-5; int    a=(unsigned char)b; a的值为251 而int    a=(signed char)b; a的值为-5; 如果以上办法行不通，那么可用如下方法  	int a = 0xff; 	char b = -5; 	 	if (b<0) 	{ 		a=-1; 		a&=b; 	} 	else 	{ 		a=0; 		a&=b; 	}


Question: C语言初学者 斐波那契数列求和

楼上的代码看起来是递归，其实不是，不过他体现了递归的思想，运行起来应该比递归快

我以前写的 /*************************************************************************     > File Name: fb.cpp     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年10月17日 星期五 18时00分28秒  ************************************************************************/ #include<vector> #include<iostream> using namespace std; int main() { 	long fib(int,vector<int>&); 	vector<int> v1; 	for(int i=0;i<=60;i++) 	{ 		v1.push_back(fib(i,v1)); 	} 	for(auto s:v1) 		cout<< s <<endl; 	return 0; } long fib(int n,vector<int> &v) { 	if(n==0 || n==1) 		return 1; 	else 		return v[n-2] + v[n-1]; }

#include <stdio.h>  int fib(int i) {     if (i == 0 || i == 1) {         return i;     } else {         return fib(i - 1) + fib(i - 2);     } }  int main(int argc, char *argv[]) {     int i, n;      n = 30;     for (i = 0; i < n; ++i) {         printf("F(%d)=%d\n", i, fib(i));      }      return 0; }

#include<iostream> #include<stdio.h> using namespace std; int f(int i) { 	if(i==1||i==2) 		return 1; 	else 		return f(i-1)+f(i-2); } int main() { 	int i; 	for(i=1;i<=20;i++) 	{ 		printf("%8d",f(i)); 		if(i%5==0) 			printf("\n"); 	} 	return 0; }

引用 楼主 yangqcjason 的回复:想用递归，但是学长说我用的不伦不类，不知道最普通的递归怎么做，求解答。   你这不是递归的问题吧，感觉你需要好好补补的是C语言的基础。

//1 1 2 3 5 8 13 21 34 55 89  1   1                                              2    1+1                                       3    (1+1)+2                                        4     (1+1+2)+3 5     (1+1+2+3)+5 6     (1+1+2+3+5)+8  fun(1)==1 fun(2)==fun(1)+1 fun(3)==fun(2)+2 fun(4)==fun(3)+3 fun(5)==fun(4)+5 fun(6)==fun(5)+8  sumfun(0)==0 sumfun(1)==sumfun(0)+1 sumfun(2)==sumfun(1)+1 sumfun(3)==sumfun(2)+2 sumfun(4)==sumfun(3)+3 sumfun(5)==sumfun(4)+5 sumfun(6)==sumfun(5)+8 可以看到，sumfun求和递归时，应是前一个求和值加一个斐波那契数列，数列生成用如下递归 fiber(1)==1 fiber(2)==1 fiber(3)==fiber(1)+fiber(2) fiber(4)==fiber(2)+fiber(3) fiber(5)==fiber(3)+fiber(4) 即fiber(1)=1,fiber(2)=1,n>2则fiber(n)=fiber(n-1)+fiber(n-2) 因此，sumfun的递归表述为:sumfun(0)=0,n>0则sumfun(n)==sumfun(n-1)+fiber(n) 原理如下，代码你自己来，祝你成功


Question: 点菜系统，C语言，求大神指教，结果有问题

#include<stdio.h> #include<stdlib.h>  int order(int a) {	 	char m; 	int n; 	scanf("%c",&m); 	if(m=='y') 	{ 		 		printf("输入编号，选择需要的菜品："); 			scanf("%d",&n); 		switch(n) 		{ 		case 1: 			printf("选定鱼香肉丝\n"); 			break; 		case 2: 			printf("已选定番茄鸡蛋\n"); 			break; 		case 3: 			printf("已选定紫菜蛋汤\n"); 			break; 		case 4: 			printf("已选定红烧茄子\n"); 			break; 		case 5:exit(0); 			break; 		default:printf("输入错误！"); 		}  	} 	 	else if(m=='n') 	{ 		a=1; 	} 	return a; } void menu() { 		 	int n,a; 	//char m; 	a=0; 	printf("-------------------------------------------------------------------\n"); 	printf("                          菜单系统                 \n"); 	printf("-------------------------------------------------------------------\n"); 	printf("\n"); 	printf("\n"); 	printf("选择需要的菜品：\n"); 	printf("1.鱼香肉丝；                  2.番茄鸡蛋;\n"); 	printf("3.紫菜蛋汤；                  4.红烧茄子;\n"); 	printf("5.退出;\n"); 	printf("\n"); 	printf("输入编号，选择需要的菜品：");  	scanf("%d",&n); 	switch(n) 	{ 	case 1: 		printf("已选定鱼香肉丝\n"); 		break; 	case 2: 		printf("已选定番茄鸡蛋\n"); 		break; 	case 3: 		printf("已选定紫菜蛋汤\n"); 		break; 	case 4: 		printf("已选定红烧茄子\n"); 		break; 	case 5:exit(0); 		break; 	default:printf("输入错误！"); 	}  	while(a==0) 	{ 		printf("是否继续点菜：y or n \n"); 		order(a); 	} 	 	printf("点菜完毕\n"); 	 } int main() { 	menu(); 	return 0; }  没什么大问题，这种程序中看不中用，看着口水都流出来了

#include<stdio.h> #include<stdlib.h>  int order(int a) { 	char m; 	int n; 	scanf("%c",&m); 	if(m=='y') 	{  		printf("输入编号，选择需要的菜品："); 			scanf("%d",&n); 		switch(n) 		{ 		case 1: 			printf("选定鱼香肉丝\n"); 			break; 		case 2: 			printf("已选定番茄鸡蛋\n"); 			break; 		case 3: 			printf("已选定紫菜蛋汤\n"); 			break; 		case 4: 			printf("已选定红烧茄子\n"); 			break; 		case 5:exit(0); 			break; 		default:printf("输入错误！"); 		} 	}  	else if(m=='n') 	{ 		a=1; 	} 	return a; } void menu() {  	int n,a; 	//char m; 	a=0; 	printf("-------------------------------------------------------------------\n"); 	printf("                          菜单系统                 \n"); 	printf("-------------------------------------------------------------------\n"); 	printf("\n"); 	printf("\n"); 	printf("选择需要的菜品：\n"); 	printf("1.鱼香肉丝；                  2.番茄鸡蛋;\n"); 	printf("3.紫菜蛋汤；                  4.红烧茄子;\n"); 	printf("5.退出;\n"); 	printf("\n"); 	printf("输入编号，选择需要的菜品：");  	scanf("%d",&n); 	switch(n) 	{ 	case 1: 		printf("已选定鱼香肉丝\n"); 		break; 	case 2: 		printf("已选定番茄鸡蛋\n"); 		break; 	case 3: 		printf("已选定紫菜蛋汤\n"); 		break; 	case 4: 		printf("已选定红烧茄子\n"); 		break; 	case 5:exit(0); 		break; 	default:printf("输入错误！"); 	}  	while(a==0) 	{ 		getchar(); 		printf("是否继续点菜：y or n \n"); 		a = order(a); 	}  	printf("点菜完毕\n");  } int main() { 	menu(); 	return 0; }

default:printf("输入错误！"); 输入错误后，难道仅仅输出“输入错误”就没了？ 可以在输出后面加一个exit(0)退出程序

引用 8 楼 u013564902 的回复:引用 6 楼 xiaodeerdeer 的回复:[quote=引用 5 楼 u013564902 的回复:] [quote=引用 4 楼 xiaodeerdeer 的回复:] a 始终都是0 所以结束不了order函数中，有另a=1的啊  在int order(int a)里面改变a值有用吗 最起码也的&a 才行啊[/quote]是这样？int order (int &a)? 但是结果中，是否继续点菜为什么还是出现了两次？[/quote] 	while(a==0) 	{ 		printf("是否继续点菜：y or n \n"); 		getchar(); 		order(a); 	} 加一个getchar，消除回车

引用 9 楼 xiaodeerdeer 的回复:还是你a 用的不对能不能直接帮我指出来

还是你a 用的不对

引用 6 楼 xiaodeerdeer 的回复:引用 5 楼 u013564902 的回复:[quote=引用 4 楼 xiaodeerdeer 的回复:] a 始终都是0 所以结束不了order函数中，有另a=1的啊  在int order(int a)里面改变a值有用吗 最起码也的&a 才行啊[/quote]是这样？int order (int &a)? 但是结果中，是否继续点菜为什么还是出现了两次？

引用 6 楼 xiaodeerdeer 的回复:引用 5 楼 u013564902 的回复:[quote=引用 4 楼 xiaodeerdeer 的回复:] a 始终都是0 所以结束不了order函数中，有另a=1的啊  在int order(int a)里面改变a值有用吗 最起码也的&a 才行啊[/quote]ORDER不是会返回a值吗，&a指的是在哪里？

引用 5 楼 u013564902 的回复:引用 4 楼 xiaodeerdeer 的回复:a 始终都是0 所以结束不了order函数中，有另a=1的啊  在int order(int a)里面改变a值有用吗 最起码也的&a 才行啊

a 始终都是0 所以结束不了

不行啊，结果出错。

什么问题楼主倒是说一下啊！！！万一因为运行环境不同，导致别人显示出现的错误和你不一样呢！！！


Question: 美国大学c语言题 高手进 在线等

引用 2 楼 user-2 的回复:[quote=引用 1 楼 wangzuxi 的回复:]  (*(long *)(&x+3))^=(*(long *)(&x+7))^((*(long *)(&x+7))^=(*(long *)(&x+3))^(*(long *)(&x+7)));  原理是很简单，就是栈区里保存的a()地址和b()地址调换一下。但是具体编译器不一样，a函数地址可以通过x地址来确定，保存b函数地址的栈地址就不好确定了，还是要看具体编译器，楼上的只能在gcc下正确通过，vc下会不正确。[/quote] 嗯，我只在gcc下测了，vc可能不对，原理比较简单，就是把a()调用b后返回的eip和b()调用c后返回的eip调换了一下；抛砖引玉，我也想看看有没有其他方法。

引用 1 楼 wangzuxi 的回复: (*(long *)(&x+3))^=(*(long *)(&x+7))^((*(long *)(&x+7))^=(*(long *)(&x+3))^(*(long *)(&x+7)));  原理是很简单，就是栈区里保存的a()地址和b()地址调换一下。但是具体编译器不一样，a函数地址可以通过x地址来确定，保存b函数地址的栈地址就不好确定了，还是要看具体编译器，楼上的只能在gcc下正确通过，vc下会不正确。


Question: 求助，不知道为什么char[]不能通过%s输出。可能是指针问题？

i...........

printf("temp->name = %s\n",i, temp->name)中缺少了一个控制符哈

printf("temp->name = %s\n",i, temp->name);//********************for testing 少了 i 对应的输出格式，变成成%s和i对应了所以乱码

printf("temp->name = %s\n",i, temp->name);  楼上的确实说对了，为什么人的代码还有个i在里面？是copy进没有改好吧

没看懂。。。


Question: opencv2.1 + vs2010 编译的问题！

看最后问题表述，貌似你的TBB版本与你的操作系统不匹配，你看下是否可以下载到支持你当前 操作系统的的TBB或者有没有兼容方式可以运行


Question: linux下C+gtk编程调用数据库问题

第一个问题无意中解决了，但是想知道一下原因？

sprintf(query,"select * from info where rec like '%c%s%c'",'%',gtk_entry_get_text(GTK_ENTRY(Sentry)),'%'); 也行

引用 1 楼 lklshr 的回复:第一个问题无意中解决了，但是想知道一下原因？  晕倒，这是%转义符的用法。要输入%,就要用两个%


Question: VC编程如何把十六进制数转换为点分法表示的IP地址？

typedef unsigned char BYTE; BYTEstr[20] = {0}; sprintf(str,"%u.%u.%u.%u",(BYTE)IP[0],(BYTE)IP[1],(BYTE)IP[2],(BYTE)IP[3]);

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。


Question: 大家来找茬，一道链表基础题

粗略写了份，测试OK。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h>   #define PRINT(msg)	print(msg)  void print(const char *msg) { 	printf("%s[%d]:%s\r\n", __FUNCTION__, __LINE__, msg); }  typedef struct _LinkList { 	int data; 	struct _LinkList *pnext; }Linklist;   int main(void) { 	int i = 0; 	int data = 0; 	Linklist *first_file = NULL, *last_file = NULL; 	Linklist *file = NULL;  	srand(time(NULL));  	while(i++ < 10) 	{ 		data = (rand() % 1000 + i)/i;  		file = (Linklist *)malloc(sizeof(Linklist)); 		if(file == NULL) 		{ 			PRINT("alloc memory failed.\n"); 		}  		file->data = data; 		file->pnext = NULL;  		if(first_file == NULL) 		{ 			first_file = file; 		}  		if(last_file == NULL) 		{ 			last_file = file; 		} 		else 		{ 			last_file->pnext = file; 			last_file = file; 		} 	} 	 	while(first_file != NULL) 	{ 		printf("%d ", first_file->data); 		first_file = first_file->pnext; 	} 	printf("\n");  }

#include "stdafx.h" #include "malloc.h" #include "string" #include <iostream>  typedef struct FileList{ 	int num; 	struct FileList *pnext; }FileList;  int main() { 	FileList *first_file; 	FileList *last_file,*file; 	int num;  	first_file = NULL; 	last_file = first_file;  	while(true) 	{ 		printf("please input num\n"); 		scanf("%d",&num);  		if (num<0) 		{ 			printf("quit"); 			break; 		}  		file = (FileList *)malloc(sizeof(FileList)); 		memset(file,0,sizeof(FileList)); 		file->num=num;		  // 		last_file=file; // 		last_file=file->pnext; 		if (first_file == NULL) //第一次计入数据 		{ 			file->pnext = last_file; 			last_file=file; 			first_file =file; 		} 		else 		{ 			file->pnext =first_file; 			first_file=file; 		 		} 	}   	 	FileList *temp_file = first_file;     //打印数据 	while(temp_file != NULL) 	{ 		std::cout<<temp_file->num;		 		temp_file = temp_file->pnext;		 	}  	//释放内存     temp_file = first_file; 	while(first_file != NULL) 	{ 		temp_file =first_file; 		first_file = first_file->pnext; 		delete  temp_file ; 		temp_file = NULL; 	}  	getchar(); 	getchar(); 	return 0; }

last_file=file;       last_file=file->pnext; 改成       last_file ? (last_file->pnext = file) : (first_file = file);       last_file=file;

链表没有建立起来，取自己的next，赋值给自己，你很好玩哈！没事“自己搞自己”，这个难度系数有点高哈 其次，内存泄漏 最后，不是病的病，头文件包含标准库的话，用《》得了，别让编译器再到本地目录查了！  至于修改，楼上给出一些方案了，我再给出另外一种解决方式，头插入法 这句  last_file=file; last_file=file->pnext;  替换为下面句  file->pnext = first_file; first_file = file;  over

//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

#include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct FileList{     int num;     struct FileList *pnext; }FileList;   void walk(FileList *head) {     FileList *file;      for (file = head; file; file = file->pnext) {         printf("%p:%d\n", file, file->num);     } }  int main() {     FileList *first_file;     FileList *last_file,*file;     int num;       first_file = NULL;     last_file = first_file;       while(1)     {       printf("please input num\n");       scanf("%d",&num);         if (num<0)       {           break;           printf("quit");           return -1;       }         file = (FileList *)malloc(sizeof(FileList));       memset(file,0,sizeof(FileList));       file->num=num;         /*       last_file=file;       last_file=file->pnext;       */       if (first_file == NULL) {           first_file = last_file = file;       } else {         last_file->pnext = file;         last_file = file;       }     }      walk(first_file);      return 0; }

file->pnext = last_file; last_file = file;

引用 13 楼 lyyiqo 的回复:最后两句互掉.............cuo le

最后两句互掉

1、最好不要添加删除语句 ======================

第34、35行改成：  if (last_file != NULL) {     last_file->pnext = file; } last_file = file;

一看就发现少了这一句 #include"stdio.h"

参考代码： http://pan.baidu.com/s/17yIcQ

引用 7 楼 smartjeckk 的回复:不要意思，我重新声明一下 1、最好不要添加删除语句 2、FileList *first_file为头结点 3、上面的修改没有成功的，运行有错误或者链表没有连接起来 第34、35行对应下面这两行：        first_file = first_file ? first_file : file;       last_file = last_file ? (last_file->pnext = file) : file;

上面的代码中对file初始化的的memset可以去掉了

去掉对空指针各种作死的引用，去掉定义指针后奇怪的误导初始化  typedef struct FileList{     int num;     struct FileList *pnext; }FileList;   int main() {     FileList *first_file=NULL;     FileList *last_file=NULL,*file=NULL;     int num;       while(1)     {       printf("please input num\n");       scanf("%d",&num);         if (num<0)       {           printf("quit");           return -1;       }         file = (FileList *)malloc(sizeof(FileList));              if (NULL!=file)       {         memset(file,0,sizeof(FileList));         file->num=num;         file->pnext=NULL;  		if (NULL == first_file)  		{  			first_file=file;   			last_file =file;  	    }  	    else  	    {  	    	last_file->pnext = file;  	    }  	    last_file=last_file->pnext;   	  }   	  else       {     	printf("malloc failed\n")     	return 1;       }     }         return 0; }

应该给出错误或者其他不合理现象之类的吧

34,35改为下边的： file->pnext = NULL; if(first_file == NULL) {     first_file = file; } last_file = file;


Question: 无符号数小的减去大的应该怎么算？

这个数据会比较大 小的减去大的 这个是补码的问题

这和是计算机组成原理的知识啊 /*************************************************************************     > File Name: unsigned.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月02日 星期日 10时28分51秒  ************************************************************************/  #include<stdio.h> int main() { 	unsigned a =1; 	unsigned b =2; 	printf("%u\n",a-b); 	printf("%d\n",a-b); 	return 0; }

不停的借位啊，结果还是无符号数

得到一个如下所示的结果： #include <stdio.h>  int main() { 	unsigned int i,j,k; 	 	i = 3; 	j = 7; 	k = i - j; 	 	printf("%#x - %#x = %#x",i,j,k);//0x3 - 0x7 = 0xfffffffc 	return 0; } 0xfffffffc用带符号整数的意义来解释是-4，用无符号数的意义来解释是一个很大的数字4294967292

《组成原理》

微机原理：加法器

减法运算其实就是小数加上大数的补码，然后最高位不解释为符号位，就得到结果。 #include<stdio.h> int main(){    unsigned int x=1,y=2,z;    z=x-y;    printf("%u\n",z);  //4294967295    z=-1;    printf("%u\n",z);  //4294967295    return 0; }

unsigned int a=1,b=2; a-b=2^32-(b-a);


Question: 0x54AF00B4 (msvcr110d.dll) (作业3.exe 中)处有未经处理的异常: 0xC0000005: 写入位置 0x00000000 时发生

scanf_s("%d",&(a->i)); 注意，要把输入的东西放到一个地址里 a->i是一个数，对应的地址通常是不能访问的

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


Question: 求教大神关于错误检测编码算法的c语言实现

奇偶校验，1位错可发现，2位错不可发现（奇数个错可发现，偶数个错不可发现） CRC校验，奇数或偶数个错均能发现


Question: 响应头回馈信息  最后怎么还有几个数字字母～～～～～～

下面应该是相应头的内容吧

引用 2 楼 rui___ 的回复:rver: squid/3.4.1 Date: Mon, 27 Oct 2014 12:00:40 GMT Content-Type: text/html; charset=GB2312 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Expires: Mon, 27 Oct 2014 12:01:40 GMT Cache-Control: max-age=60 Vary: Accept-Encoding X-Cache: MISS from shanghai.qq.com  3ecc <!doctype html>  <html>  <head>   <meta charset="gb2312"> 这响应头 3ecc  啥个意思      想截除包头  只留下下面的文本的   谁知道还有个3ecc Transfer-Encoding: chunked这行已经很明显了，是chunked编码，3ecc是十六进制的chunked长度

不知道。。。。

引用 楼主 rui___ 的回复:TTP/1.1 200 OK Server: squid/3.4.1 Date: Mon, 27 Oct 2014 11:24:31 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Expires: Mon, 27 Oct 2014 11:39:31 GMT Cache-Control: max-age=900 X-Cache: MISS from shanghai.qq.com 3f32   人呢   顶 人工顶     3f32   到底是啥呀


Question: free()出错

引用 2 楼 lovesmiles 的回复:并不是将hello copy给p所指的内存，而是改变了p的值 这句是重点，楼主对指针不太熟悉，可以去看一些相关的资料

int x = 3, y = 6; char *p = NULL; p = (char*)malloc(25); p = "hello";//这一句，并不是将hello copy给p所指的内存，而是改变了p的值，free 自然出错了。 cout << p << f(); free(p); cout << "abc" << f();  改成下面的代码  int x = 3, y = 6; char *p = NULL; p = (char*)malloc(25); strcpy(p,"hello"); cout << p << f(); free(p); cout << "abc" << f(); getchar();

p = "hello";  strcpy_s(p, 25, "hello");


Question: 双链表这里总是报错呢？

仅供参考//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>


Question: 键盘钩子截获消息时如何得知是哪个窗口的消息？

引用 2 楼 zhao4zhong1 的回复:FindWindow FindWindowEx 这个方法更难吧？我查到原型是： 函数原型 HWND FindWindowEx(     HWND hwndParent, // handle to parent window [父窗体句柄]     HWND hwndChildAfter, // handle to child window [子窗体句柄]     LPCTSTR lpszClass, // class name [窗体类名]     LPCTSTR lpszWindow // window name [窗体名] ); 这参数我哪知道？

GetWindowThreadProcessId The GetWindowThreadProcessId function retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.   DWORD GetWindowThreadProcessId(   HWND hWnd,             // handle to window   LPDWORD lpdwProcessId  // address of variable for process identifier );   Parameters hWnd  Handle to the window.  lpdwProcessId  Pointer to a 32-bit value that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the 32-bit value; otherwise, it does not.  Return Values The return value is the identifier of the thread that created the window.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Windows Overview, Window Functions    CreateToolhelp32Snapshot   Process32First   Process32Next  CloseHandle

引用 3 楼 tm1mc2 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] FindWindow FindWindowEx 这个方法更难吧？我查到原型是： 函数原型 HWND FindWindowEx(     HWND hwndParent, // handle to parent window [父窗体句柄]     HWND hwndChildAfter, // handle to child window [子窗体句柄]     LPCTSTR lpszClass, // class name [窗体类名]     LPCTSTR lpszWindow // window name [窗体名] ); 这参数我哪知道？[/quote] 先FindWindow，用其返回的值作为FindWindowEx的参数。 GetForegroundWindow The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working). The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.   HWND GetForegroundWindow(VOID)   Parameters This function has no parameters.   Return Values The return value is a handle to the foreground window.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Windows Overview, Window Functions, SetForegroundWindow

FindWindow FindWindowEx

我知道了：只要把wParam和lParam修改之后， return CallNextHookEx(hHook,nCode,wParam,lParam); 就可以了 但是问题不那么简单。 因为我编的钩子需要调用一些系统函数，这些系统函数的参数中有窗口句柄。我真不知道该如何是好。


Question: C语言应用程序可以连接到Tomcat服务器吗？

JNI看了一下视频，可能是我基础薄弱，没太听懂。现在打算利用把C程序输出的数据保存在文本中，再用java把数据读出来，大家觉得怎么样啊？

我做的事是这样的：我用android客户端连接到Tomcat服务器，向服务器发送指令，服务器接到指令后，然后传给电脑客户端（用C语言已经开发好了），电脑客户端再通过串口把指令传给**库，**库就会把相应的数据返回过来。现在最主要的问题是Tomcat服务器如何把指令（就是简单的字母：A、B、C之类的）传给C编写的客户端，其他的问题都已经解决了。大神看到后帮帮忙啊，我完全是新手啊！

有一种技术较JNI JNI可实现的功能： 1.java可调c接口； 2.c可调Java接口。 依LZ的需求： 1.android客户端与Tomcat通信LZ可自己实现； 2.Tomcat与C端通信，中间可以考虑加一步java程序，然后利用JNI，用C去掉java的接口。

socket 编程  connnect  一般tomcat默认端口号是8080  就能连上  如果是要连lz自己写的，部署在tomcat上的服务器程序， 那么lz自己监听的端口号是多少就连多少

tomcat都服务器了，你想干嘛，写个客户端？？

我没看懂，但是你电脑客户端c是怎么写的？服务器和电脑客户端协议对应起来不就行了，这不是应该和android客户端和服务器连接一样的办法么？还是因为你无法确保服务器是否连通了电脑客户端？而且C语言理论上是万能的！

还请LZ先解释清楚连上去了做什么，大家才好猜LZ所谓的连过去是怎么一回事。

引用 2 楼 lxnh1221 的回复:我是想在原有的C代码里面，继续开发新的功能（可以和Tomcat服务器通信：数据之间的传递）。你回答的不是我想要的，不好意思  Tomcat服务器通信 跑JAVA 那个吗？  不按套路走，比较困难，网络通信一个都socket编程，然后在上面跑你遵循的协议。

Tomcat服务器是什么意思？你是想和服务器进行http通信吗？流程如下： 1用socket和服务器建立tcp连接 2通过这个tcp连接发送http文件命令。 3获得的http数据就是你打开http网页的代码。


Question: 关于C的函数调用指针问题。

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

只改了形参啊，就是个局部变量，得通过指针修改，传递指针的地址，你把指针当成普通变量，就一切了然了

引用 6 楼 zdnexus 的回复:[quote=引用 2 楼 lkshflasgla 的回复:] #include<stdio.h> void kkk(int **pt); int main(void) {     int a = 7;     int *b = &a;     kkk(&b);     if (b == NULL)         printf("b is NULL.\n");     else         printf("b is not NULL.\n");       return 0; } void kkk(int **pt) {     *pt = NULL; } 这个我试过了。我的问题是指针指向了NULL，KKK函数没有后是不是就指针又还原了？[/quote]  程序中 函数kkk(b)执行过程的一种不严格解释方式如下： void kkk(b) {    pt = b;    pt = NULL; } 此函数仅改变pt变量，而pt属于局部变量，函数执行完自然释放掉了。 建议楼主回顾下指针相关知识。

引用 4 楼 zdnexus 的回复:[quote=引用 1 楼 lkshflasgla 的回复:]  #include<stdio.h> void kkk(int **pt); int main(void) {     int a = 7;     int *b = &a;     kkk(&b);     if (b == NULL)         printf("b is NULL.\n");     else         printf("b is not NULL.\n");       return 0; } void kkk(int **pt) {     *pt = NULL; }    指针本身也是变量。如果想通过调用函数改变该变量的值，需通过指针来操作。本例中需采用二级指针。 大哥的意思是如果想改变指针，必须用指向指针的指针来改变指针的变量？[/quote]  是的。

引用 6 楼 zdnexus 的回复:这个我试过了。我的问题是指针指向了NULL，KKK函数没有后是不是就指针又还原了？  你真试过就没这个疑问了

引用 4 楼 zdnexus 的回复:大哥的意思是如果想改变指针，必须用指向指针的指针来改变指针的变量？  对

引用 2 楼 lkshflasgla 的回复:#include<stdio.h> void kkk(int **pt); int main(void) {     int a = 7;     int *b = &a;     kkk(&b);     if (b == NULL)         printf("b is NULL.\n");     else         printf("b is not NULL.\n");       return 0; } void kkk(int **pt) {     *pt = NULL; } 这个我试过了。我的问题是指针指向了NULL，KKK函数没有后是不是就指针又还原了？

函数参数只传值，而非参数本体参与，C++用引用可以让参数本体参与运算 否则只能用地址直接访问参数来修改参数

引用 1 楼 lkshflasgla 的回复: #include<stdio.h> void kkk(int **pt); int main(void) {     int a = 7;     int *b = &a;     kkk(&b);     if (b == NULL)         printf("b is NULL.\n");     else         printf("b is not NULL.\n");       return 0; } void kkk(int **pt) {     *pt = NULL; }    指针本身也是变量。如果想通过调用函数改变该变量的值，需通过指针来操作。本例中需采用二级指针。 大哥的意思是如果想改变指针，必须用指向指针的指针来改变指针的变量？

楼上正解 二级指针


Question: ls命令输出格式算法

理解int idx = filesno / ((files_index + i) / (i + 1));这类公式/算法的方法之一： 写一小段能独立运行的代码，里面调用该公式（必要时将该公式拆为若干小步，并将每步的中间结果输出），让该公式的各个自变量在一定范围内循环加一。并将输出结果重定向到一个文本文件。

如果想简单实现，思路并不复杂。终端的长宽的字节数可以用函数ioctl获得，或者从shell的$LINES, $COLOWNS获得。然后把文件名按字母表排序，然后再根据文件名的长度决定每行显示几个文件，显示多少行。最后一步比较费劲。

引用 4 楼 u012786370 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 为什么不直接去看Linux源代码中的ls命令怎么实现的呢？ 那又为什么不自己先想一想呢？其实我正在看，告诉你吧，那个ls源码4000多行，还不算外部包含的[/quote] 你凭一己之力又怎么可能敌得过ls源代码自诞生以来到今天所经历的时间和一干作者和补丁者的智商呢？恐怕你学习都不一定学的过来。

引用 10 楼 zhao4zhong1 的回复:我猜ls源代码中的实现绝对比9楼的思路复杂得多，且还能处理很多事先想象不到的各种意外情况（比如文件名中包含Tab字符、汉字、图形符号、……）。 引用 9 楼 ForestDB 的回复:首先得到当前目录下所有文件名，不算太难吧 然后排序，会吧？ 排序同时可以得到最长的文件名的长度，比如39好了 那么一行（按80列算，这个80也是能动态取到的），可以放两个文件名（39加一个空格） 然后对于排好序的文件名列表，依次输出 %-40s %-40s \n 结束  可以写出来了么？ 这个是我从ls源码中摘出来的大概的一个算法，谁能给我解释一下这条语句为什么这样写  int idx = filesno / ((files_index + i) / (i + 1));  下面是全部代码，因为符合的是POSIX标准，所以在windows下不能编译，可以在linux下编译  #include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <unistd.h> #include <termios.h> #include <stdlib.h> #include <string.h>  /* Information about filling a column.  */ struct column_info {     int valid_len;     int line_len;     int *col_arr; }; struct column_info *column_info;  static int line_length;  /* Maximum number of columns ever possible for this display.  */ static int max_idx;  /* The minimum width of a colum is 3: 1 character for the name and 2 for the separating white space.  */ #define MIN_COLUMN_WIDTH	3  static inline int cmp_str(char const *lhs, char const *rhs, int(*cmp)(char const *, char const *)) {     return cmp(lhs, rhs); }  static int compare_str(const void *lhs, const void *rhs) {     return cmp_str(*(char **)lhs, *(char **)rhs, strcoll); }  unsigned short int get_ws_col() {     struct winsize size;     ioctl(STDIN_FILENO, TIOCGWINSZ, &size);     return size.ws_col; }  static void init_column_info(void) {     int i;     int allocate = 0;      line_length = get_ws_col();     max_idx = line_length / MIN_COLUMN_WIDTH;     if (max_idx == 0)         max_idx = 1;      if (column_info == NULL)     {         column_info = malloc(sizeof(struct column_info) * max_idx);         allocate = 1;     }      for (i = 0; i < max_idx; ++i)     {         int j;          column_info[i].valid_len = 1;         column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;          if (allocate)             column_info[i].col_arr = (int *)malloc(sizeof(int) * (i + 1));          for (j = 0; j <= i; ++j)             column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;     } }  static void indent(int from, int to) {     while (from < to)     {         putchar(' ');         from++;     } }  static void print_many_per_line(char *arr[], size_t files_index) {     struct column_info *line_fmt;     int filesno;			/* Index into files. */     int row;				/* Current row. */     int max_name_length;	/* Length of longest file name + frills. */     int name_length;		/* Length of each file name + frills. */     int pos;			/* Current character column. */     int cols;			/* Number of files across. */     int rows;			/* Maximum number of files down. */      int max_cols;      init_column_info();     /* Normally the maximum number of columns is determined by the     screen width.  But if few files are available this might limit it     as well.  */     max_cols = max_idx > files_index ? files_index : max_idx;      /* Compute the maximum number of possible columns.  */     for (filesno = 0; filesno < files_index; ++filesno)     {         int i;          name_length = strlen(arr[filesno]);          for (i = 0; i < max_cols; ++i)         {             if (column_info[i].valid_len)             {                 int idx = filesno / ((files_index + i) / (i + 1));                 int real_length = name_length + (idx == i ? 0 : 2);                 if (real_length > column_info[i].col_arr[idx])                 {                     column_info[i].line_len += (real_length                         - column_info[i].col_arr[idx]);                     column_info[i].col_arr[idx] = real_length;                     column_info[i].valid_len = column_info[i].line_len < line_length;                 }             }         }      }      /* Find maximum allowed columns.  */     for (cols = max_cols; cols > 1; --cols)     {         if (column_info[cols - 1].valid_len)             break;     }      line_fmt = &column_info[cols - 1];      /* Calculate the number of rows that will be in each column except possibly     for a short column on the right. */     rows = files_index / cols + (files_index % cols != 0);      for (row = 0; row < rows; row++)     {         int col = 0;         filesno = row;         pos = 0;         /* Print the next row.  */         while (1)         {             printf("%s", arr[filesno]);             name_length = strlen(arr[filesno]);             max_name_length = line_fmt->col_arr[col++];              filesno += rows;             if (filesno >= files_index)                 break;              indent(pos + name_length, pos + max_name_length);             pos += max_name_length;         }         putchar('\n');     } }  void main() {      char *arr[] =     {         "asdfasdf",         "adfasdf",         "sdfdaasd",         "sdfasdfasdg",         "ghjsdfa",         "asdfadsf",         "dgfsdg",         "文件",         "gsdgsrg",         "sdfgs",         "dfgsdhsdfgj",         "sdfg",         "qwersdfgsdfhs",         "sdfhfhdfgh",         "sdfg",         "dfgsdfg",         "sdfg",         "dsfgsdfg",         "电影",         "gsdfgsdfg",         "sdfgsdf",         "游戏",         "sdfgsdfg",         "dfghdfgjd",         "dfgh",         "sdfg",         "rsdfhfdgh",         "sdfhdf",         "dfgh",         "syutdfhsgd",         "ksdfgdsf",         "fgsdh",         "sdfh",         "yuosdfhsf",         "vbdfh",         "sdjklfhs",         "erfhsdfh",         "sdfh",         "sdfhsdfh",         "sdfh",         "wery",         "weywery",         "dfgh",         "sdfg",         "sdfhfdgh",         "sdfhdf",         "dfgh",         "sdfhsgd",         "sdfgdsf",         "sdfgsdh",         "sdfh",         "sdfhsf",         "sdfh",         "retfhs",         "fhsdfh",         "yudfh",         "sdfhsdfh"     };      qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), (__compar_fn_t)compare_str);     print_many_per_line(arr, sizeof(arr) / sizeof(arr[0]));      return; }

引用 4 楼 u012786370 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 为什么不直接去看Linux源代码中的ls命令怎么实现的呢？ 那又为什么不自己先想一想呢？其实我正在看，告诉你吧，那个ls源码4000多行，还不算外部包含的[/quote]4000行，还好吧

理解和讨论之前请先学会如何观察！ 想知道windows下dir命令的源码多少行吗？

引用 3 楼 zhao4zhong1 的回复:为什么不直接去看Linux源代码中的ls命令怎么实现的呢？ 那又为什么不自己先想一想呢？其实我正在看，告诉你吧，那个ls源码4000多行，还不算外部包含的

为什么不直接去看Linux源代码中的ls命令怎么实现的呢？

简化一下，就是如何将一个字符串数组按如上方式输出？

难道没人会吗？


Question: 大神们，求救！C语言%g（%G）是如何选择%f或者%e（%E）进行输出的……

大家好……我貌似找到了解决办法了……这是我刚刚在《C陷阱与缺陷》上看到的。 1：%g用于打印浮点型数据时，会去掉多余的零，至多保留六位有效数字 2：当%g用于打印超过6位的浮点型数据时，对于所有格式说明符都一样会遇到这样的问题，因为精度问题，%f不得不输出一个不精确的超过六位的数字，%e也是同样，而%g此时会选择%e格式进行输出，并且按第一条要求，去掉多余的零，并且四舍五入到6位数字。这是《C Primer Plus》中所说的超过精度的时候的情况。 3：当一个数字的绝对值很小的时候，要表示这个数字所需要的字符数目就会多到让人难以接受。举例而言，如果我们把π*10^-10写作0.00000000000314159就会显得非常丑陋不雅，反之，如果我们写作3.14159e-10，就不但简洁而且易读好懂，党支书是-4时，这两种表现形式大小相同。对于比较小的数值，除非该数的指数小于或者等于-5，%g才会采用科学技术发来表示，即，以%e的格式进行输出。 这下看来，我们可以讲谭书与《C Primer Plus》上所说的统一起来……让我们向Andrew Koenig先生致敬吧！

你既然能看C primer plus了，还看老谭的书作甚。 老谭的书就是一本改错习题集

double输入时必须%lf，但输出时可以%f 按我的理解， %g      根据数值不同自动选择 %f 或 %e ，%e 格式在指数小于-4或者大于等于精度时使用。 这里的%f指的是浮点数，已经大于精度了，所以这本其实也没错

引用 2 楼 mujiok2003 的回复:http://www.cplusplus.com/reference/cstdio/printf/ 如果按这么说来，谭浩强书上说的是对的嘛……可是C Primer Plus 为什么要这么说啊……难以理解还是……


Question: 自己琢磨了很久的排序搞定了，大家指点指点！

冒泡排序吗，可以将变量n和k去掉，只要用i和j就可以了，内层循环如下：          for (i = j+1; i < (number-1); i++)         {             if (temp < va[i])             {                 temp = va[i];                 va[i] = va[j];                 va[j] = temp;             }         }


Question: 求解数据结构一道题，链表问题！！

引用 7 楼 Starbucks_star 的回复:while(r->next!=p)             {                 if(r->fieq<p->fieq)                 {                     s->next=p;                     p->next=r;                    return ;                 }                 s=s->next;                 r=r->next;             }  谢谢哈，你修改的真不错！学到了很多。但还有一点不懂那个return在哪里有什么意思？？？？ 结点插入好了，这个函数此次使命就完成了，用return结束函数的执行，返回到主函数。

#include<stdio.h>  #include<malloc.h>  typedef struct LNode  {      int data;  //数据     int fieq;    //频率     struct LNode *next; //next指针 }*Linklist ;    void Creat(Linklist &L)  {      L=(Linklist)malloc(sizeof(LNode));      if(!L)          exit(0);      else          L->next=NULL;      printf("构建成功！\n");  }   void FindLNode(Linklist &L,int x)  {      Linklist p,q;      p=L->next;      q=L; //你的写法和你的要求不相符啊，频率高的在前，应该从前往后比呀      while(p!=NULL)      {          if(p->data==x)          {               p->fieq++;              q->next=p->next;  //取出该节点              Linklist r,s;              r=L->next;              s=L;              while(r->next!=p)              {                  //重新插入                 if(r->fieq<p->fieq)                  {                      s->next=p;                      p->next=r; return;                  }                  s=s->next;                  r=r->next;              }           }              q=q->next;              p=p->next;          }          if(p==NULL)          {              Linklist s=(Linklist)malloc(sizeof(LNode));//没初始化就用，运行竟然没崩溃？              s->data=x;              s->fieq=0;              s->next=NULL;                            if(L->next==NULL)              {                  L->next=s;                  s->next=NULL;              } //新加的，不然新结点怎么添加 else { q->next=s; s->next=NULL;     }          }       }       void print(Linklist L)      {          Linklist p=L->next;          while(p!=NULL)          {              printf("[%d 出现 %d次]\n",p->data,p->fieq);              p=p->next;          }       }      int main()      {          Linklist a;          printf("构建一个新链表：");          Creat(a);          FindLNode(a,5);          FindLNode(a,1);          FindLNode(a,2);          FindLNode(a,5);          FindLNode(a,3);          FindLNode(a,4);          FindLNode(a,4);          FindLNode(a,3);          FindLNode(a,3);          print(a);          getchar();          return 0;      }

看错了，收回刚才的话......

if(p==NULL)          {              Linklist s;              s->data=x;              s->fieq=0;              s->next=NULL;              if(L->next==NULL)              {                  L->next=s;                  s->next=NULL;              }           }   这段代码，如果p为空，就新建一个结点，然后把L指向它，L作为头结点，每次都指向新建结点，而新建的结点又指向NULL,那你怎么保存原有的结点呢。

Creat(a) 只是创建一个链表节点，并不是链表

亲们，没人理我吗？

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

引用 7 楼 Starbucks_star 的回复:while(r->next!=p)             {                 if(r->fieq<p->fieq)                 {                     s->next=p;                     p->next=r;                    return ;                 }                 s=s->next;                 r=r->next;             }  谢谢哈，你修改的真不错！学到了很多。但还有一点不懂那个return在哪里有什么意思？？？？直接函数返回，结束函数调用，相当于后面的代码都直接跳过

要求还有，左移频率高的节点，频率降序排列节点！！！


Question: 求一个大数运算的代码，学习一下！！！！

这东西网上很多啊。发出来的也不一定比你照的好

就是给个你们觉的好一点，简洁一点的代码。

引用 1 楼 user-6 的回复:嗯？这个不是网上很多嘛。 赵老师呢，赵老师的代码库~ #include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }  当然比GIMP库差不止十万八千里了！

是啊，网上不是有很多吗？

嗯？这个不是网上很多嘛。 赵老师呢，赵老师的代码库~


Question: 北大ACM1007，为什么会这样"0X004014al"指令引用的“0xccccccc"内存不能为”written"?？

很明显是指针没有分配内存。  是dna[i]。

楼主想实现什么功能，代码先简单介绍下吧


Question: 北大ACM1034，为什么运行结果对了，不能通过？

问题是Hunter Bob often walks with his dog Ralph. Bob walks with a constant speed and his route is a polygonal line (possibly self-intersecting) whose vertices are specified by N pairs of integers (Xi, Yi) ? their Cartesian coordinates.  Ralph walks on his own way but always meets his master at the specified N points. The dog starts his journey simultaneously with Bob at the point (X1, Y1) and finishes it also simultaneously with Bob at the point (XN, YN).  Ralph can travel at a speed that is up to two times greater than his master's speed. While Bob travels in a straight line from one point to another the cheerful dog seeks trees, bushes, hummocks and all other kinds of interesting places of the local landscape which are specified by M pairs of integers (Xj',Yj'). However, after leaving his master at the point (Xi, Yi) (where 1 <= i < N) the dog visits at most one interesting place before meeting his master again at the point (Xi+1, Yi+1).  Your task is to find the dog's route, which meets the above requirements and allows him to visit the maximal possible number of interesting places. The answer should be presented as a polygonal line that represents Ralph's route. The vertices of this route should be all points (Xi, Yi) and the maximal number of interesting places (Xj',Yj'). The latter should be visited (i.e. listed in the route description) at most once.  An example of Bob's route (solid line), a set of interesting places (dots) and one of the best Ralph's routes (dotted line) are presented in the following picture:   Input  The first line of the input contains two integers N and M, separated by a space ( 2 <= N <= 100 ,0 <= M <=100 ). The second line contains N pairs of integers X1, Y1, ..., XN, YN, separated by spaces, that represent Bob's route. The third line contains M pairs of integers X1',Y1',...,XM',YM', separated by spaces, that represent interesting places.  All points in the input file are different and their coordinates are integers not greater than 1000 by the absolute value.  Output  The first line of the output should contain the single integer K ? the number of vertices of the best dog's route. The second line should contain K pairs of coordinates X1'',Y1'' , ...,Xk'',Yk'', separated by spaces, that represent this route. If there are several such routes, then you may write any of them.

注意边界检查。而且它的测试用例很多，不能说你自己例举的一些用例通过没问题就没问题了。 注意代码健壮性

根据观察到的LZ程序中的问题，设计了以下测试用例： 3 2 0 0 2 0 2 2 1 1 1 -1  正确输出是： 5 0 0 1 -1 2 0 1 1 2 2  LZ程序输出是： 4 0 0 1 1 2 0 2 -858993460  其中-858993460是由于 printf("%d %d ",x[n+2],x[n+3]); 中最后一个点的下标错误引起。应改为： printf("%d %d\n",x[(n-1)*2],x[(n-1)*2+1]);  遗漏“1 -1”的问题需要大改。

样例仅仅是测试用例的一部分，后台还有很多未公开的测试用例。因此样例全部通过不能说明完全正确。否则，我针对样例if else输出一通就通过了。  acm讨论区里有许多其他人提供的已经通过的代码，你可以随机构造一些输入，利用他人的正确程序产生一些输出，然后用这些输入输出做测试用例来测试你的程序并找出问题所在。不过最好还是自己找出错误来了

样例对了不代表代码是对的。 不能通过说明你的代码是错误的。

题目要求是什么？！！！！！


Question: 关于c语言中指针变量的存储位置问题

你住在你家的房子里面，你家的房子住在哪里呢？不要把自己陷阱进去了。 变量无非就是一块内存而已，有的内存里面存放数据，有的内存存放的是别的内存的地址。

通用寄存器和普通的存储器的访问应该都差不多，但是访问通用寄存器的速度比普通的存储器的速度要快

p，q，r也是指针变量，他也是变量，在内存中和普通的变量一样分配内存，也有自己的存储位置（&p得到的是p的存储位置)，但是指针变量里面存的数据是他指向的变量的地址值，要说他和普通变量不一样的地方，就在于变量里存储的数据是其他变量的地址。

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

千万不要把自己陷进去了！ int **pP = &p

如果是局部变量的话，都存在栈上，a、b、c、p、q、t存储本质没有区别，只是a、b、c是按int 4字节存，p、q、t是按指针存，32位系统上是4字节，64位系统上是8字节

你的abc都是在内存中定义的整形变量，而你后面的pqt也是在内存中定义的，不过是指针变量。 好比你内存有6个空间，地址分别为123456，你的abc分别定义在123的地址中，pqt定义在456中。 而p存放的是地址1，q存放的是地址2，t存放的是地址3。

p,q,t自己的内存就在 a,b,c的后面啊 每个人人4个字节或者8个字节（指针大小）  你可以在调试的时候， 查看这6个变量的地址，就知道了

引用 6 楼 Vanquish_self 的回复:嗯    这样看来确实应该是存储在一块特定的区域  （我自己也懒，没有在程序上自己进行测试确实是自己的问题     麻烦了  谢啦） 不客气，嗯，自己动手试试很好，可以输出，也可以单步调试查看等等，动手是很好的

[quote=引用 4 楼 u012421456 的回复:] 假设在程序中声明了1个int型的变量a，其值为68。系统为变量a分配的首地址为0X65FDF4H，pa是存放变量a地址的指针变量，即pa中存放的值为0x065FDF4H。 对变量a的访问有两种方式：一是直接按地址0x065FDF4H找到a的存储单元，从而对变量a进行访问；二是按系统为pa分配的地址先找到pa，然后根据pa的值（即变量a地址0x065FDF4H）找到变量a在内存中的存储单元，从而对变量a进行访问。对于前一种访问方式称为直接访问方式，后一种访问方式称为间接访问方式。                  ——百度百科  引用那指针变量 p q t 呢  他们存储在什么地方呢？   是不是计算机中有一块专门的区域去管理这些指针变量？ 存储在某块区域 可以这么说吧   嗯    这样看来确实应该是存储在一块特定的区域  （我自己也懒，没有在程序上自己进行测试确实是自己的问题     麻烦了  谢啦）

你不是问他们存在哪里吗 那要打印他们的地址啊  printf("%p\n", &a); .... printf("%p\n", &p);

假设在程序中声明了1个int型的变量a，其值为68。系统为变量a分配的首地址为0X65FDF4H，pa是存放变量a地址的指针变量，即pa中存放的值为0x065FDF4H。 对变量a的访问有两种方式：一是直接按地址0x065FDF4H找到a的存储单元，从而对变量a进行访问；二是按系统为pa分配的地址先找到pa，然后根据pa的值（即变量a地址0x065FDF4H）找到变量a在内存中的存储单元，从而对变量a进行访问。对于前一种访问方式称为直接访问方式，后一种访问方式称为间接访问方式。                  ——百度百科  引用那指针变量 p q t 呢  他们存储在什么地方呢？   是不是计算机中有一块专门的区域去管理这些指针变量？ 存储在某块区域 可以这么说吧    引用 1 楼 relaxisland 的回复:p,q,t自己的内存就在 a,b,c的后面啊 你说的在后面是什么意思？


Question: C语言 1-1/2+1/3-1/4+...+1/99-1/100问题

引用 1 楼 user-1 的回复:i是整数，两个整数做除法结果还是整数，所以1/i=0 改成做浮点数除法才行。 p=p-1.0/i; p=p+1.0/i;   凹，有理！Thanks!


Question: 求帮助！！！！！！！

注意你输入的时候回车符

#include<stdio.h> #define M 5 void sort(int h[],int t) { 	int i,j,k=0; 	for(i=0;i<t-1;i++)//i<t改为i<t-1，你那样越界 	{ 		for(j=0;j<t-i-1;j++)//j<t-i改为j<t-i-1 		{ 			if(h[j]>h[j+1]) 			{ 				k=h[j+1]; 				h[j+1]=h[j]; 				h[j]=k; 			}	 		} 	} 	for(i=0;i<t;i++) 		printf("%d\t",h[i]); } int main() {	 	int a[M],b[M],c[M]; 	int i,j,k=0,y=0; 	printf("请输入数组A\n"); 	for(i=0;i<M;i++) 		scanf("%d",&a[i]); 	printf("输出有序表A\n"); 	sort(a,M); 	printf("\n"); 	printf("请输入数组B\n"); 	for(i=0;i<M;i++) 		scanf("%d",&b[i]); 	printf("输出有序表B\n"); 	sort(b,M); 	printf("\n"); 	return 0; }  调用函数的名字也别写错了

嗯，将第32行代码名字改正后没问题啊——

不对，报错提示是什么

楼主是不是程序写的有点问题？ 倒数第四行，sortwe函数是什么？多打了个we吧？


Question: 字符串复制求解

凶手就是这句代码 while((*pds=*pss)!='\0')

/*** *char *strcpy(dst, src) - copy one string over another * *Purpose: *       Copies the string src into the spot specified by *       dest; assumes enough room. * *Entry: *       char * dst - string over which "src" is to be copied *       const char * src - string to be copied over "dst" * *Exit: *       The address of "dst" * *Exceptions: *******************************************************************************/  char * __cdecl strcpy(char * dst, const char * src) {         char * cp = dst;          while( *cp++ = *src++ )                 ;               /* Copy src over dst */          return( dst ); }  参见源码 strcat.c

pss与pds是俩字符串的首地址。 所以*pss就是字符串的第一个元素"C"。 那么pds的第一个元素也等于pss的第一个元素等于“C”。而且他俩的值不为“\0”。 所以运行pss++，pds++； 然后*pss与*pds就指向字符串的下一个元素。同时重复上述循环。 知道*pss=“\n”即字符串结束符，并将这个赋给*pds时，循环结束。 所以字符串pds的值就与pss相同了。

完成复制的是这句： *pds=*pss pds++和pss++只是指针往后走，遍历下一个字符 下面这个实现更简洁： char *strcpy(char *dst, char *src) {       char *temp = dst;       while ((*dst++ = *src++) != '\0') ;       return temp; }

两个变量不断的自加1，指向的字符不断向后移 楼主了解指针吗？


Question: 【小白问问题】一个关于链表的问题

引用 1 楼 user-4 的回复:free(current);         current = current->next;  // current被free了之后就不要再用了。 改成这样：         next = current->next;         free(current);         current = next;  应该就是这样的原因了吧

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

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


Question: 关于C语言的实际程序设计应用

如果特别聪明，那么学什么都可以，如果不是天才，那么最好学一门工作中使用的语言，说到底，各种语言还是有差别的，能看懂代码，不表明对工具完全了解，不表明会修改，不表明会debug。

哇哇哇哇哇哇哈

可以试试在linux下编程试试，你会觉得界面其实不是那么重要，界面只是给用户看的，只是程序的冰山一角

Win32应用程序可以达到你的要求。 但是做界面这类的用c。mfc太累了也不好看。可以玩QT

mfc如果想学也是不错的，公司中用vc的相当多。

C语言说到底是一门以内存为中心的编程语言，学C语言到底学些什么—— 「语法」和「函数库」 可以好好看看这个——http://zhuanlan.zhihu.com/linjr/19694823

仅供参考#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");         ohfont=(HFONT)SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-720, r.top+r.bottom/2-120,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if( FAILED(RegisterClass(&wc)) ) return 1;      if(FAILED(CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL)))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }

c语言不是用来写窗口程序的。 要写窗口程序，应该是用C#或MFC吧


Question: face recognition,face verification,face identification

1:1 静态照片人脸验证 FaceVerification http://qiansou.cn/www/index.php/Web/tuwen_de/tid/81/id/94/iid/27

人脸识别，人脸检查，人脸认证？


Question: 各位大神求助啊。。。。。。

宏，只会作简单替换不会安全检查等这些工作。

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

两位都说的正确，这是宏的问题啊 http://baike.baidu.com/view/2076445.htm 带参数  除了一般的字符串替换，还要做参数代换 格式： #define宏名（参数表） 字符串 例如：#define S(a,b) a*b area=S(3,2)；第一步被换为area=a*b; ，第二步被换为area=3*2; 类似于函数调用，有一个哑实结合的过程： （1）实参如果是表达式容易出问题 #define S(r) r*r area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b; 正确的宏定义是#define S(r) ((r)*(r)) （2）宏名和参数的括号间不能有空格 （3）宏替换只作替换，不做计算，不做表达式求解 （4）函数调用在编译后程序运行时进行，并且分配内存。宏替换在编译前进行，不分配内存 （5）宏的哑实结合不存在类型，也没有类型转换。 （6）宏展开使源程序变长，函数调用不会 （7）宏展开不占运行时间，只占编译时间，函数调用占运行时间（分配内存、保留现场、值传递、返回值）[2]

第一短代码  宏替换后是 5.5*1+2*1+2=9.5 第二段代码  相当于  printf("%d",9.5)  在C标准里边   printf()中格式不匹配   结果是未定义的

第一段是宏定义问题   S（x+y）替换后是PT*x+y*x+y=5.5*1+2*1+2=9.5 第二段是数据类型的问题，%d是输出整型，而S（x+y）的结果不是整型


Question: 用scanf函数输入数据问题

C1读取缓冲区内的换行符，那c2不是就应该读取R字符呢？但为什么结果是c2也是空白字符呢？

%c不忽略空白字符，这个我明白。有点不懂，但有一点不理解： 在程序执行了scanf("%f##%f",&k,&m);这条语句之后 ，缓冲区留下了一个换行符，再执行scanf("%c,%c",&c1,&c2);语句时，读取换行符存入c1变量，那为什么c2读取的不是R字符呢？（我的调试结果c2输出@符号）？在缓冲区发生了什么变化呢？

引用 6 楼 u013824562 的回复:[quote=引用 1 楼 u012421456 的回复:]  前边加一个getchar 那为什么第一个scanf("i=%d**j=%d",&i,&j);后面不需要添加getchar()而第二个需要[/quote] 你第一个scanf，缓冲区内也有一个回车。只不过你第二个scanf一开始读的是 浮点数(忽略开始回车空格等空白字符)，如果此时你读取的不是浮点数或整数，而是字符或字符串，同样出问题。

引用 1 楼 u012421456 的回复: 前边加一个getchar 那为什么第一个scanf("i=%d**j=%d",&i,&j);后面不需要添加getchar()而第二个需要

清除

楼主可以搜——scanf清楚键盘缓冲区

#include<stdio.h> void main()  {     int i,j;     float k,m;     char c1,c2;     scanf("i=%d**j=%d",&i,&j);     scanf("%f##%f",&k,&m);     getchar();//接收换行     scanf("%c,%c",&c1,&c2);     printf("i=%d,j=%d,k=%.2f,m=%.1f,c1=%c,c2=%c",i,j,k,m,c1,c2); }

#include<stdio.h> void main()  { 	int i,j; 	float k,m; 	char c1,c2; 	scanf("i=%d**j=%d",&i,&j); 	scanf("%f##%f",&k,&m); 	getchar();//结束换行 	scanf("%c,%c",&c1,&c2); 	printf("i=%d,j=%d,k=%.2f,m=%.1f,c1=%c,c2=%c",i,j,k,m,c1,c2); }

前边加一个getchar


Question: C语言字符数组复制问题，求教、

from[i] != EOF 得出的是逻辑值真或假 返回的是1或0

！=的优先级高于 =

while(to[i] = (from[i] != EOF)) 先计算 from[i] != EOF，是逻辑判断 结果是真或者假 在把判断结果赋值给to[i] 因此全是1


Question: 如何不使用变量完成 atoi() 函数  (C语言)

楼上的方法我也想过，但是这么做意义不大，因为strlen已经是O(N)复杂度，这样子递归变成O(^2)复杂度了，还不如用一个简单的循环来完成

按楼主的思路稍微改动一下，好像可以实现，而且也没用变量，可我怎么觉得像作弊呢？ int my_atoi(const char *str) { if(*str) return  (*str-'0') * pow(10, strlen(str) - 1) + my_atoi(str+1); else return 0; }

使用sscanf就可以  #include <stdio.h>  void main( void ) {    char  tokenstring[] = "15 12 14...";    char  s[81];    char  c;    int   i;    float fp;     /* Input various data from tokenstring: */    sscanf( tokenstring, "%s", s );    sscanf( tokenstring, "%c", &c );    sscanf( tokenstring, "%d", &i );    sscanf( tokenstring, "%f", &fp );     /* Output the data read */    printf( "String    = %s\n", s );    printf( "Character = %c\n", c );    printf( "Integer:  = %d\n", i );    printf( "Real:     = %f\n", fp ); }  Output  String    = 15 Character = 1 Integer:  = 15 Real:     = 15.000000

不会写，写了几下，没想明白，不写了。   //high_syntax_c_hwnd ( 008E0640 , 00 )  //#include "stdafx.h" #include "stdio.h"  int my_atoi( int basevalue, const char *str) {  //...不使用变量  if(*str)  return my_atoi( ( basevalue + (*str-'0') ) *10, str+1);  else  return basevalue / 10; }   int main() {  char str1[256] = "123";  char str2[256] = "456";   int n_add1, n_add2;   n_add1 = my_atoi(0,str1);  n_add2 = my_atoi(0,str2);   printf("%d + %d = %d\n", n_add1, n_add2, n_add1 + n_add2);    return 0; }  //-----Final result ---  //

貌似不行的，递归只能从左到右，而且越后面权重越大


Question: 二进制与float的转换

原来用 FREAD 就可以读取各种类型的数据.学习了.第一个回贴的,就把分给出去..


Question: 来自高校俱乐部的挑战

引用 1 楼 brookmill 的回复:数据范围这么小，初始化的时候一次性处理，打个表就行了。 数组counts[1000000]，把counts[i]初始化为[0,i]之间的个数，可以做到O(1)的查询，直接counts[b]-counts[a]就行了。 有点小问题，counts[b]-counts[a]的结果是(a,b]的结果，需要单独再判断a是不是，如果是就把结果加1，不过还是O(1)

引用 3 楼 brookmill 的回复:初始化的过程： #define MAX_N 1000000 int counts[MAX_N]; int total = 0; void init() {   int i;   for (i = 0; i < MAX_N; i++) {     if (isHuiWen(i)) {       total++;     }     counts[i] = total;   } }  小弟没学数组，不懂这些代码什么意思

引用 2 楼 brookmill 的回复:[quote=引用 1 楼 brookmill 的回复:] 数据范围这么小，初始化的时候一次性处理，打个表就行了。 数组counts[1000000]，把counts[i]初始化为[0,i]之间的个数，可以做到O(1)的查询，直接counts[b]-counts[a]就行了。 有点小问题，counts[b]-counts[a]的结果是(a,b]的结果，需要单独再判断a是不是，如果是就把结果加1，不过还是O(1)[/quote] 那为啥不直接做counts[b]-counts[a-1]。。。

引用 1 楼 brookmill 的回复:数据范围这么小，初始化的时候一次性处理，打个表就行了。 数组counts[1000000]，把counts[i]初始化为[0,i]之间的个数，可以做到O(1)的查询，直接counts[b]-counts[a]就行了。长知识了，原来只会一边算一边计数

引用 5 楼 kamenriderdrive 的回复:小弟没学数组，不懂这些代码什么意思 那楼主想干什么啊


Question: 打印最长的文本行程序

引用 1 楼 u012061345 的回复:printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中  这句话不在循环中，所以不会打印你输入的每一个line。 但是会输出最后一个line。你考虑一下最后一个line是什么，为什么跟不打印的效果一样？ 想不出来就单步调试一下。

printf("%s",longest); 这句也不在循环中 为啥打印了额？

引用 2 楼 zxhuser-2 的回复:[quote=引用 1 楼 u012061345 的回复:] printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中+1[/quote]  引用 1 楼 u012061345 的回复:printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中 printf("%s",longest);那这句也不在循环中为啥打印输出了呢？  引用 2 楼 zxhuser-2 的回复:[quote=引用 1 楼 u012061345 的回复:] printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中+1[/quote]  引用 2 楼 zxhuser-2 的回复:[quote=引用 1 楼 u012061345 的回复:] printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中+1[/quote]  引用 2 楼 zxhuser-2 的回复:[quote=引用 1 楼 u012061345 的回复:] printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中+1[/quote]

引用 6 楼 u012061345 的回复:[quote=引用 1 楼 u012061345 的回复:] printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中  这句话不在循环中，所以不会打印你输入的每一个line。 但是会输出最后一个line。你考虑一下最后一个line是什么，为什么跟不打印的效果一样？ 想不出来就单步调试一下。[/quote] 我想了下所因为函数所值传递，所以line的值并未改变，所以最后一个line是空字符串。但是最后的longest为啥值改变了？

引用 1 楼 u012061345 的回复:printf("%s",line);   //为什么这句不能打印输出line  因为这句话不在循环中+1


Question: 字符串替换的问题，求大神指导

引用 1 楼 user-2 的回复:for(p1=p,p2=p+len-1;p1<p2;p1++,p2--)正解。


Question: 为什么当输入0时程序执行不正常

当是0时无法执行

你不讲讲是什么不正常吗？

vc++编译器

楼主程序能执行？楼主什么编译器啊


Question: linux 下c语言编程问题

给你段代码，我以前项目的工程中的统计个数的，应该是没问题工程内调用了  显示文件的，工程内没调用，所以没调试过     int GetReadFileListCounter(char *pcBasePath) {         DIR *pDir;     struct dirent *ptr;     char acBase[1000];     int iFilesNum = 0;//文件个数     if ((pDir=opendir(pcBasePath)) == NULL)     {         printf("Open dir error...");         return -1;     }      while ((ptr=readdir(pDir)) != NULL)     {         if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)    ///current dir OR parrent dir             continue;         else if((ptr->d_type == 8))  ///file         {                         //printf("d_name:%s/%s\n",pcBasePath,ptr->d_name);             //判断扩展名是否为txt，如果是就++             if(strcmp(strstr(ptr->d_name, ".txt"), ".txt") == 0)             {                 iFilesNum++;             }                      }                     else if(ptr->d_type == 10)    ///link file         {             //printf("d_name:%s/%s\n",pcBasePath,ptr->d_name);         }                     else if(ptr->d_type == 4)    ///dir         {             memset(acBase,'\0',sizeof(acBase));             strcpy(acBase,pcBasePath);             //判断最后一个字符是否是"/"             if(pcBasePath[strlen(pcBasePath) -1] != '/')             {                 strcat(acBase,"/");             }             strcat(acBase,ptr->d_name);             if(acBase[strlen(acBase) -1] != '/')             {                 strcat(acBase,"/");             }             iFilesNum += GetReadFileListCounter(acBase);         }     }     closedir(pDir);     return iFilesNum; }  int ShowReadFileList(char *pcBasePath) {         DIR *pDir;     struct dirent *ptr;     char acBase[1000];      if ((pDir=opendir(pcBasePath)) == NULL)     {         printf("Open dir error...");         return -1;     }      while ((ptr=readdir(pDir)) != NULL)     {         if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)    ///current dir OR parrent dir             continue;         else if(ptr->d_type == 8)    ///file             printf("d_name:%s/%s\n",pcBasePath,ptr->d_name);         else if(ptr->d_type == 10)    ///link file             printf("d_name:%s/%s\n",pcBasePath,ptr->d_name);         else if(ptr->d_type == 4)    ///dir         {             memset(acBase,'\0',sizeof(acBase));             strcpy(acBase,pcBasePath);             strcat(acBase,"/");             strcat(acBase,ptr->d_name);             ShowReadFileList(acBase);         }     }     closedir(pDir);     return 1; }

引用 2 楼 zy1404 的回复:http://www.php100.com/html/webkaifa/Linux/2009/1106/3485.html 这个建议很好，要是没有这本书的话可以搜一下电子版的就可以了。

看一下高编吧，都有的，不建议使用popen

文件操作 stat函数

赵老师怎么知道的这么多啊  怎么才能这样

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。  Linux用ls命令

引用 4 楼 mujiok2003 的回复:简单的办法， 使用管道调用shell+1

stat          api

简单的办法， 使用管道调用shell

《UNIX环境高级编程》这本书楼主看一下吧。这些问题可以在这本书中找到答案

mkdir dir1 创建一个叫做 'dir1' 的目录' mkdir dir1 dir2 同时创建两个目录 mkdir -p /tmp/dir1/dir2 创建一个目录树 rm -f file1 删除一个叫做 'file1' 的文件' rmdir dir1 删除一个叫做 'dir1' 的目录' rm -rf dir1 删除一个叫做 'dir1' 的目录并同时删除其内容 rm -rf dir1 dir2 同时删除两个目录及它们的内容  cd /home 进入 '/ home' 目录' cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd 进入个人的主目录  pwd 显示工作路径 ls 查看目录中的文件 ls -F 查看目录中的文件 ls -l 显示文件和目录的详细资料 ls -a 显示隐藏文件 ls *[0-9]* 显示包含数字的文件名和目录名


Question: 做回文数用循环，哪里有错

上面打错了。应该是： 各个变量都是全局变量，都被系统清零。因此a=b=c=e=q=0 既然q=0，那么只有第一个if是真的，因此输出“0”。

各个变量都是全局变量，都被系统清零。因此a=b=c=e=q=0 既然q=0，那么所有的if都为假，因此不会输出任何东西。

这部分代码编译都过不去吧， 1<=a && a<=9;    1<=b && b<=9;    1<=c && c<=9;    1<=e && e<=9; 这部分是伪代码？建议你通过自己首先把编译出错的问题去掉，然后通过打印的方法找到逻辑错误。这样进步更快吧~~~

#include <stdlib.h> #include <stdio.h> #include <string.h> void main() { 	int i,j,num; 	char str[20],str1[20]; 	printf("请输入数字的范围\n");//找出两个数字之间的所有回文数字 	scanf("%d %d",&j,&num); 	for (i=j;i<=num;i++) 	{ 		itoa(i,str,10);//转换成字符串 		itoa(i,str1,10); 		strrev(str1);//翻转字符串 		if (strcmp(str1,str)==0)// 		printf("%d\n",i); 	} }

#include <stdlib.h> #include <stdio.h> #include <string.h> void main() { 	int i,j,num; 	char str[20],str1[20]; 	printf("请输入数字的范围\n"); 	scanf("%d %d",&j,&num); 	for (i=j;i<=num;i++) 	{ 		itoa(i,str,10); 		itoa(i,str1,10); 		strrev(str1); 		if (strcmp(str1,str)==0) 		printf("%d\n",i); 	} }

附上代码供参考：  #include <stdio.h>  /** 该函数 判断是否是回文数。返回值 0 表示 否， 1 表示是回文数 */ int isPalindrome(int value) {     int sum = 0;     int i = 0;     int tmp = value;      while (0 != tmp)     {         sum = sum*10 + tmp%10;         tmp = tmp/10;     }      if (sum == value)     {         return 1;     }          return 0; }  int main(int argc, char* argv[]) {     int iRet = 0;  //用于存放函数返回值     int input_value = 0;  //存放用户输入的值     scanf("%d", &input_value);      iRet = isPalindrome(input_value);  //判断是否是回文数     if (1 == iRet)     {         printf("%d is a palindrome \n", input_value);     }     else     {         printf("%d is NOT a palindrome \n", input_value);     }      return 0; }

1<=a && a<=9;     1<=b && b<=9;     1<=c && c<=9;     1<=e && e<=9;     a==e,b==c  这些语句什么意思？？？  反正在代码里没起到任何作用。

printf("%d",q,q=a*10+b,a==b);  只打印一个整数， 输入了这么多参数。。。


Question: c语言，找志愿者，最优方案。

围观。。。。


Question: 我写的这个冒泡算法怎么可以编译成功但运行的时候没有最后的输出值

if后面没加｛｝。

jf

#include <stdio.h> #include <stdlib.h> int main() { 	int i,j,k,l,temp; 	int a[10]; 	printf("input number:\n"); 	for(k=0;k<10;k++) 		scanf("%d",&a[k]); 	for (i=0;i<=8;i++) 	{ 		for (j=0;j<9-i;j++) 		{ 			if (a[j]>a[j+1])///加括号 			{ 				temp=a[j+1]; 				a[j+1]=a[j]; 				a[j]=temp; 			} 		} 	} 	for (l=0;l<10;l++) 	{ 		printf("%3d",a[l]); 	} 	system("pause");////加上一个暂停，防止程序一闪而过 }

跟你的返回值return 0，有关，程序是对的，只是你显示的时候就是闪了一下就不见了，你在rerurn  0的上面加固定函数就可以了

引用 2 楼 greatkafka 的回复:[quote=引用 1 楼 u012421456 的回复:] 上图？别人怎么帮调试？ 第十行 不好意思啊 第一次发帖[/quote] 第一次发帖，不知道代码格式，这个没什么，但是点出这个问题了，楼主为何不代码格式重发一下代码？ 楼主莫非问题解决了？ 其实这个并不算难，网上应该也很好找到 楼主可以找一个能用的，然后对比自己的为什么不能用，找不到原因可以再来问

看着代码挺别扭，括号if{}没有

引用 2 楼 greatkafka 的回复:[quote=引用 1 楼 u012421456 的回复:] 上图？别人怎么帮调试？ 第十行 不好意思啊 第一次发帖[/quote]没学会走就学会跑了？lz看你骨骼惊奇，必是个练武奇才。。。

引用 1 楼 u012421456 的回复:上图？别人怎么帮调试？ 第十行 不好意思啊 第一次发帖

上图？别人怎么帮调试？ 第十行


Question: 使用MinGW编译的时候提示不能执行

求各位大牛指点迷津啊


Question: 关于scanf("%d",&num)的问题，有什么好的解决方案？

对 用字符串统一读 然后处理成数字 字符等其他

用gets读取整个一行，然后自己处理字符串。

可以用scanf的返回值。 要想完善处理，用1楼的方法。


Question: 请问下列两个宏的区别

引用 1 楼 Saleayas 的回复:因为 & 运算对机器来说比较简单啊。 引用 2 楼 u011779875 的回复:计算机中只有加法 减一个数即加上他的反码 通过减来使现除法  而加法实现根据基本的与 或 非 逻辑运算 实现 所有 &运算快于/ 第一个宏是把&的结果/8 第二个是直接/8 是这2个的区别

问题变成 一条add指令 和俩条and指令的比较

看俩段汇编代码 	key = ((((len) + 8 - 1)&(~(8-1)))/8); 000E1A4C  mov         eax,dword ptr [len]   000E1A4F  add         eax,7   000E1A52  and         eax,0FFFFFFF8h   000E1A55  cdq   000E1A56  and         edx,7   000E1A59  add         eax,edx   000E1A5B  sar         eax,3   000E1A5E  mov         dword ptr [key],eax      	key=((((len) + 8 - 1))/8); 008C1A4C  mov         eax,dword ptr [len]   008C1A4F  add         eax,7   008C1A52  cdq   008C1A53  and         edx,7   008C1A56  add         eax,edx   008C1A58  sar         eax,3   008C1A5B  mov         dword ptr [key],eax

因为 & 运算对机器来说比较简单啊。

看错了 效率是第二条 比第一条快  少了条000E1A52  and         eax,0FFFFFFF8h   可能如楼上所说 是为了留着以后的扩展问题吧

负数两个就有区别了。这就是为什么asm里有cdq指令 不过这个宏本身该不该用在负数上那是另一回事

#include <stdio.h> #define nbytes1(len) ((((len) + 8 - 1)&(~(8-1)))/8) #define nbytes2(len) ((((len) + 8 - 1))/8) int main() {     int L;      for (L=-17;L<=17;L++) {         printf("%4d %3d %3d\n",L,nbytes1(L),nbytes2(L));     }     return 0; } // -17  -2  -1 // -16  -2  -1 // -15  -1  -1 // -14  -1   0 // -13  -1   0 // -12  -1   0 // -11  -1   0 // -10  -1   0 //  -9  -1   0 //  -8  -1   0 //  -7   0   0 //  -6   0   0 //  -5   0   0 //  -4   0   0 //  -3   0   0 //  -2   0   0 //  -1   0   0 //   0   0   0 //   1   1   1 //   2   1   1 //   3   1   1 //   4   1   1 //   5   1   1 //   6   1   1 //   7   1   1 //   8   1   1 //   9   2   2 //  10   2   2 //  11   2   2 //  12   2   2 //  13   2   2 //  14   2   2 //  15   2   2 //  16   2   2 //  17   3   3 //

貌似结果没有区别呀！


Question: 关于赋值表达式a=b的值

引用 11 楼 junziruyu_ 的回复:恩，那这样说b=c这个表达式得值是多少呢，按照上面那段英语是等于b得值么[/quote] 对的，就等于赋值的结果 ，即b的值

基本算是搞懂了，谢谢大家帮忙

谢谢！学习了……

引用 8 楼 lm_whales 的回复:[quote=引用 4 楼 mymtom 的回复:] a=b=c 就是个赋值表达式呀，就是把 b = c 的值赋给a b = c 本身也是个赋值表达式, 就是把 c 值赋给b,  这个表达式的值就是 c 被赋值后的值。 哪里来的副作用啊？  C89  3.3.16 Assignment operators     An assignment operator stores a value in the object designated by the left operand.  An assignment expression has the value of the left operand after the assignment, but is not an lvalue.  表达式求值求的是表达式的值，求出这个值是表达式的（正）作用。 其他 因为获得这个结果而改变的过程， 例如 b=c 这个表达式 ，b 的值变成和c的值相同，这个作用就是副作用。  虽然赋值的本意，就是使得 b 和 c 的值相同， 但是表达式求值，求得的是整个表达式 b=c 的值，  而子表达式 b的值，是因为求得表达式 b=c 的值，而被改变， 所以，就是 表达式 b=c 的副作用。 所以，副作用的说法是没错的，这和C89的标准并不矛盾  如果 一个语言里赋值语句（表达式） b=c 不是表达式， 或者 这个表达式不需要求一个值来表示它本身。 那么这里面， 给b赋值，就不是副作用了。  C语言 ,每个表达式都有一个值， 而表达式求值，就是求出表达式的值（正作用）  所以很多正常意义的表达式功能， 只能看作表达式求值的副作用。  而很多语言里，本来没有多少意思的，可有可无的， b=c 这个表达式的值，反而成了正作用。   [/quote]恩，那这样说b=c这个表达式得值是多少呢，按照上面那段英语是等于b得值么

引用 8 楼 lm_whales 的回复:例如 b=c 这个表达式 ，b 的值变成和c的值相同，这个作用就是副作用。 晕！ 这个怎么就是副作用了呢？ b=c 的本意就是要把 b 的值变成和c的值相同呀

引用 5 楼 u013163178 的回复:[quote=引用 3 楼 jmy5945hh 的回复:] 之前写过一个程序，诡异地陷入死循环 原来 if (a=1) {    //... }  如果你输出 std::cout << (a=1) << std::endl 会发现这个值是 0 是1吧[/quote]+1

引用 4 楼 mymtom 的回复:a=b=c 就是个赋值表达式呀，就是把 b = c 的值赋给a b = c 本身也是个赋值表达式, 就是把 c 值赋给b,  这个表达式的值就是 c 被赋值后的值。 哪里来的副作用啊？  C89  3.3.16 Assignment operators     An assignment operator stores a value in the object designated by the left operand.  An assignment expression has the value of the left operand after the assignment, but is not an lvalue.  表达式求值求的是表达式的值，求出这个值是表达式的（正）作用。 其他 因为获得这个结果而改变的过程， 例如 b=c 这个表达式 ，b 的值变成和c的值相同，这个作用就是副作用。  虽然赋值的本意，就是使得 b 和 c 的值相同， 但是表达式求值，求得的是整个表达式 b=c 的值，  而子表达式 b的值，是因为求得表达式 b=c 的值，而被改变， 所以，就是 表达式 b=c 的副作用。 所以，副作用的说法是没错的，这和C89的标准并不矛盾  如果 一个语言里赋值语句（表达式） b=c 不是表达式， 或者 这个表达式不需要求一个值来表示它本身。 那么这里面， 给b赋值，就不是副作用了。  C语言 ,每个表达式都有一个值， 而表达式求值，就是求出表达式的值（正作用）  所以很多正常意义的表达式功能， 只能看作表达式求值的副作用。  而很多语言里，本来没有多少意思的，可有可无的， b=c 这个表达式的值，反而成了正作用。

没有一说的那么乱了！就是一个从右向左的赋值而已！ 如果乱的话，分开两条语句写

引用 3 楼 jmy5945hh 的回复:之前写过一个程序，诡异地陷入死循环 原来 if (a=1) {    //... }  如果你输出 std::cout << (a=1) << std::endl 会发现这个值是 0 是1吧

“=”的结合性从右至左。

先说b=c,这是一个赋值表达式，赋值运算符具有副作用，除了有个表达式值外，变量本身值也备改变。具体说，就是b=c的表达式值是c，变量b也被改变了。a=b=c的意思也就一样了，“＝”的结合性从有至左。

引用 3 楼 jmy5945hh 的回复:之前写过一个程序，诡异地陷入死循环 原来 if (a=1) {    //... }  如果你输出 std::cout << (a=1) << std::endl 会发现这个值是 0 乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单，不用格式控制符！ 但是不用格式控制符，输入输出恰好是你期望的格式的时候好说；等到输入输出不是你期望的格式的时候，你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout！ 使用scanf、printf。


Question: 字符串匹配问题

嗯好的，我去试试看

现在在用手机没法以代码框形式展现出来啦。 每次输入字符不会超过上限。例如 输入 3 aaa bbb aaa 输出本应当是1，运行结果却为0 修改了你上面提到的那两点。即 #include<stdio.h>  #include<string.h>  main()  {  int n,t,k,j,s=0;  char a[100][8];  	scanf("%d",&n);  	for(t=0;t<n;t++)  	{  	gets(a[t]);          getchar();  	}  	for(k=0;k<n;k++)  	{  		for(j=k+1;j<n;j++)  		{if(strcmp(a[k],a[j])==0) s++;}  	}  printf("%d\n",s);  }

引用 3 楼 xxt_99 的回复:我太笨啦。发这个贴之前我已经修改了这两处错误，但还是运行结果错误我才来询问的，不小心复制了错误代码过来～那请问更改了这两点以后还有什么错误呀？新手真的看不出来了π_π 1. 修改之后的代码麻烦你贴出来 2. 运行结果什么错误 3. 这个代码只能处理最长为7的字符串，你的输入没有更长的吧，输入了什么？

引用 6 楼 brookmill 的回复:还是回车的问题，改的不彻底呀。把getchar()从循环里拿出来，不用每次都做，但是要紧跟着scanf后面做一次。 scanf("%d",&n); getchar(); for(t=0;t<n;t++) { gets(a[t]); } 我觉得没有其它问题了。如果结果还是不对，自己调试一下，看看读入的结果对不对： scanf("%d",&n); getchar(); for(t=0;t<n;t++) { gets(a[t]); printf("%s\n", a[t]); // 加上这一行看看，确认读取正确。 } 改成这样就对了~谢谢大家。想知道为什么不用每一次循环都做一次getchar();，是因为gets()；不会把回车读进去么？

引用 1 楼 brookmill 的回复:{if(strcmp(a[k],a[j]==0)) s++; 括号错了 {if(strcmp(a[k],a[j])==0) s++; +++ 输入的字符个数不要超过6个，记着还有一个字符'\n'也会进入字符串里，因为你用的是gets（）；函数。

还有一个问题，第一次运行gets的时候，可能会把输入n的时候敲的回车读进去。如果你发现运行的时候少读了一行，那就是这个原因了，用getchar()之类的把那个回车先读出来就好了


Question: c 语音用什么编译器好，求推荐

写代码尽量避免不通用的问题。

可以看看——http://www.csdn.net/article/2014-02-27/2818564-best-compilers-and-ides-for-c-programmers

dev c++，codeblocks，c-free

初学者用VS

const int SIZE=6; char board[SIZE][SIZE]={0};  这条语句在C语言中有语法错误， 在C++中这样的语法是正确的。  编译器的话，linux系统下用GCC， windows装个VS, VC就行了啊。

不一定支持语法糖种类越多的编译器就越好用。

初学推荐：windows下devc++，linux下用gcc,g++ 编译不过的时候多思考原理，多实践，学的才是你的，代码质量会越来越好


Question: 求大神看看下面代码（语法没有错但是运行的时候会崩溃）

man下 strcmp吧！  不要轻视任何一些警告

strcpy(temp,aga[i]);  printf("%s",temp[i]);  这二句，都是以'\n'结束的。你的aga和temp都没有初始化为0，所以有可能访问数组越界

我的事dev c++

#include <stdio.h> #include <string.h>  int main() { 	char aga[80],temp[80]; 	int i, j = 0; 	gets(aga); 	for(i=0;i<=50;++i) 	{ 		 //		if(strcmp(aga[i], "a") != 0) 		if (aga[i] != 'a') 		{ //			strcpy(temp, aga[i]); 			temp[j] = aga[i]; 			j++; 		} 	} //	for(i=0;i<=50;++i) //		printf("%s", temp[i]); 	printf("%s\n", temp); 	 	return 0; } 字符串操作函数不能这么用 参考一下——http://blog.csdn.net/u012421456/article/details/38645335#t5 楼主什么编译器，我的直接报错了

还说语法没错，下面这句编译器不警告吗？ strcmp(aga[i],'a')

VC6比较老了，可以找一个比较新的编译器


Question: 又来了，一个小程序，运行出现了问题

引用 3 楼 zy1404 的回复:scanf() 引号中是格式控制符号 不能有回车换行抱歉，我太大意了，你那篇博客我也收藏了，会认真看的，谢谢！

输入两个数，中间最好加个空格，不然在某些情况下可能出现莫名的问题

scanf中不要随便加非输入控制符，尤其是\n——http://blog.csdn.net/u012421456/article/details/18501309

scanf() 引号中是格式控制符号 不能有回车换行

scanf() 引号中是格式控制符号

#include<stdio.h> int main(void) {   int i,min,max; //min，max代表下限和上限                                          while(2==(scanf("%d %d",&min,&max)))/////                                          {       printf("%5s %5s %5s\n","num","square","cube");       for(i=min;i<=max;i++)         {           printf("%4d %4d %4d\n",i,i*i,i*i*i);         }       scanf("%d %d",&min,&max);//////////                                            }   return(0); }


Question: 请教简单的字符串处理函数

void main() { 	char * str="abc1234def23ghi"; 	char dst[20] = {}; 	char ch[10] = {}; 	int j = 0; 	int k = 0; 	for(int i = 0; i < strlen(str); i++) 	{ 		if(str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z' ) 		{ 			dst[j] = str[i]; 			j++; 		} 		else 		{ 			ch[k] = str[i]; 			k++; 		} 	} 	strcat(dst,ch); 	printf("%s", dst); }

虽然楼主是搞VB的，但是这样的思维应该有吧，这个题楼主难道真的想不出来？ 还是楼主想做一个什么实验？

一楼的方法很好，相比2楼的方法就不那么快了

遍历两遍，第一遍只复制字母，第二遍只复制数字。

1先把字母提出来，放来a串 2再把数字提出业，放到b串 3将b串加到a串的末尾  这个a串就是你要求的。


Question: 请问为什么我这个追加空格的小算法输出有乱码?

引用 2 楼 hqbobo 的回复:memset (n,0,2 * len + 1);  最后一位不是0 可能出问题  对了...谢了...两位大侠...

memset (n,0,2 * len + 1);  最后一位不是0 可能出问题

return f;前加上（不是在for循环里）*n = '\0';


Question: 简单的代码，为什么这样赋值不行？

指针*dest赋值后已经在*str内存的后面了 可以定义另外一个指针*p 在while前 p=des; 在while后des=p;        p=dest;         while(*str)         {                 *res++=*str++;         }         dest=p;

dst=(char *)malloc(30);这句分配空间，就把指针dst指向最后啦

我是看大神指教的~

1楼是对的

引用 7 楼 zy1404 的回复:#include <stdlib.h> #include <stdio.h> int main(void) {   char * str="abcdef";   char * dst,*p;   dst=(char *)malloc(30);   p=dst;   while(*str)     {       *p++=*str++;     }   printf("%s",dst);   free(dst);    return 0; }  ++ lz咋会犯这种错误...

int main(void) { char * str="abcdef"; char * dst,*p; dst=(char *)malloc(30); p=dst; while(*p) {  *p++=*str++; } printf("%s",dst); return 0; }

头指针一般不直接操作  定义一个临时的指过去 再操作临时的

怎么让指针回到首地址？而不是通过dst-6的方式

哪一句表示dst已经指向了尾部？

你试试printf("%s",dst-6);  1楼说的很清楚。另外记得free()。

赋值没问题，问题是你的dst 现在已经指向了字符串的屁股。头指针你没保护起来


Question: 在运行时如何获取函数的大小

谢谢大家的回复，也许环境不一样，我是在嵌入式的板子上运行，定义两个函数的方式并不可行，在链接重定位的时候函数地址不能保证是连续的。目前用嵌入式汇编的方法解决，即保存开始于结束的PC指针，运算得出CODE的大小。

这样应该也可以吧

#include <Windows.h> #include <tchar.h>  #pragma comment(lib, "user32.lib")  #pragma comment(linker, "/SECTION:.text,ERW")  int lnth1; TCHAR szDlgTitle[] = _T("SMC example"); TCHAR Phony[]      = _T("This is lst call of proc."); TCHAR Replc[]      = _T("This is 2nd call of proc."); TCHAR ttl1[]       = _T("Original Code"); TCHAR ttl2[]       = _T("ReplaceMent Code");  void CalledProc(void); //void EndCalledProc(void); void RepalceMentProc(void); void EndRepalceMentProc(void);  int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {    int lnth1 = (TCHAR *)EndRepalceMentProc - (TCHAR *)RepalceMentProc;    CalledProc();    memcpy((TCHAR *)CalledProc, (TCHAR *)RepalceMentProc, lnth1);        CalledProc();    return 0; }  void CalledProc(void) {    MessageBox(NULL, Phony, ttl1, MB_OK);   }  //void EndCalledProc(void) //{ //}  void RepalceMentProc(void) {    MessageBox(NULL, Replc, ttl2, MB_OK | MB_ICONEXCLAMATION);  }  void EndRepalceMentProc(void) { }  /* 分析: 本例中,我们先执行了CalledProc函数,显示出一个MESSAGEBOX.然后,我们用RepalceMentProc函数的内容, 在运行过程中修改CalledProc函数,在C语言中,函数名代表函数的首地址,为了计算函数体的长度,我们在 函数后面定义了一个空函数,通过下面这样的公式,来大致的计算函数体的长度.主要原因是函数之间还有 空隙.lnth1 = (TCHAR *)EndRepalceMentProc - (TCHAR *)RepalceMentProc; 由于代码段属性是可写的,因此,我们在这里通过下面的代码 memcpy((TCHAR *)CalledProc, (TCHAR *)RepalceMentProc, lnth1); 使用RepalceMentProc函数体中的机器码替换了CalledProc函数中原有的机器码. 这样再次调用CalledProc的时候,实际就执行的是RepalceMentProc函数的代码了. */

下一个函数的起始地址减去本函数的起始地址，大致就是本函数的大小（可能略大于实际大小，因为编译器可能对齐函数起始地址）。

引用 楼主 spbb202 的回复:请问如何在运行时获取一个函数的大小，即这个函数的代码占了多少空间？ 例如有一个函数A，在函数B中通过 int func_start_addr = (int)A; 可以得到A的起始地址，如何获取A的结束地址或者A代码的size 一个函数的大小是指什么 ?如果是代码段表示这个函数的大小，可以直接读取代码段反汇编分析 。不过这个应用场景是啥呢？

我只举个例子  void func(int a) { if(a==1)return; else if(a==2) return; return; }  这个函数有三个结束点，你觉得那一个点才是这个函数的结束地址？

引用 楼主 spbb202 的回复:请问如何在运行时获取一个函数的大小，即这个函数的代码占了多少空间？ 例如有一个函数A，在函数B中通过 int func_start_addr = (int)A; 可以得到A的起始地址，如何获取A的结束地址或者A代码的size 好高深   有高手来说说 真的可以吗？


找到了，在WINUSER.H之中。

引用 1 楼 user-1 的回复:一般都在windef.h中 windef.h中没有

一般都在windef.h中


Question: c语言多个文件使用全局变量问题

变量和数组声明的extern 最好不要省略 函数的原型声明，以及函数定义的 extern  ....如果 不是  extern "C",,extern "C++" 那么完全可以省略。

没试过，但最好别这么做。。。

引用 3 楼 Saleayas 的回复:在link 的时候，由于 .h 里面定义的是弱符号，而在 .c 里面定义的是强名字。 此时他们可以合并的。  是这样吗？难道不是应该每include一次头文件，就产生一组新的变量？

如果把extern去掉，那么每个包含global.h的源文件里面都有一份定义，他们彼此是不相干的。按理在链接的时候是会冲突的

我也发现了，看起来应该是为了确保可以实现， 按我理解，如果去掉，应该是有可能出错，只是代码太简单正好没出错而已……


Question: 又是一个很难的题目（表示看不懂题目）

围观。。。。

建议，令 X< Y ,扫描 X~ X*Y 之间的数据，找到最小的那个数 个人人文 对于所有 > C=X*Y 数据，或者有类似结构的数据 一定可以表示为    aX+bY 不知道有没有道理

这个连续指的是，从最小值 （6）以后，所有正整数，都可以用 aX+bY表示，其中 a>=0,b>=0, X>0,Y>0

我想，这题完整的题目，大概是这样的 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 前面照抄，直到输入 X,Y 如果不互素，输出错误信息 ，X,Y必须互素，如果 不是正整数输出错误信息。X ,或者Y不是正整数 如果X,Y是互素的正整数，输出可表示的连续序列的最小值。  PS：  这个必须有一定数学知识，证明，你的方法确实找到了这个最小值，否则无从下手。

这是数论里的裴蜀定理

引用 1 楼 user-5 的回复:当X，Y互素时，aX+bY可以表示任意整数，例如输入X=3，Y=4， 1)a=0,b=0 aX+bY=0 2)a=-1,b=1 aX+bY=1 3)a=-2,b=2 aX+bY=2 4)a=1,b=0 aX+bY=3 ... 既然能表示任意整数，那这道题的意思是什么我也不知道。 看他举的例子，貌似a,b必须>0 ?  即使看懂了，感觉算法也不会啊 这是数学题目吧。


Question: 菜鸟求解

引用 1 楼 u010868023 的回复:传入的是一个指针    所以是四字节 strlen判断即可+1

a是一个指针，大小就是4字节，楼主是想要用这种方式判断数组大小，可惜的是C中间输出数组大小的功能

32位操作系统：指针占4个字节 64位操作系统：指针占8个字节  数组作参数会退化成指针，如果想要知道数组的长度，传一个数组的长度参数到函数即可 修改如下：  int main(void) {      char buffer[32]={0};      fun(buffer,32);      return 0; }  void fun(char * a, unsigned int len) {      int b =sizeof(a); }

引用 13 楼 zhao4zhong1 的回复:编译期，运行期。 直击要害，正解啊

引用 18 楼 yuefy520 的回复:还问一下高手们，fun函数参数赋值，如何防止赋值越界.没办法判断大小，就没办法知道这个函数参数大小。 和赵老师讲的一样, 你再加一个参数用来表示数组的大小

你传递的那个是指针, 指针的长度是和操作系统攸关, 所以字节是4

数组名当参数传递时会退化为指针

[quote=引用 4 楼 yuefy520 的回复:] 但有一点不明白，不知道为什么sizeof(buffer)  又是32字节了？[/quote  a 是一个指针，a里面放的是buffer的首地址相当于a = &buffer[0] 而 buffer是一个数组

void foo(char * buffer, int len)

int main(void) {      char buffer[32]={0};      fun(buffer,32);      return 0; }   void fun(char * a,int len) {      int b =len; }

我觉得五楼说的比较对

a是指针， 所以是4

编译期，运行期。

数组名当参数传递时会退化为指针

你这个是求得的指针的大小不是结构体的大小

楼上都没哟说到重点,重点是sizeof是一个运算符，不是一个函数，他是在预处理的时候就求得结果的，所以并没有调用函数，也不知道你传进来的数组有多长，甚至你传经来的可能不是数组，是一个字符的地址呢。所以sizeof(a)是指针的大小，不是数组的大小，那为什么用strlen可以得到字符串数组的大小呢，因为，strlen是一个函数，这个运行是绑定了参数，就知道你串进来的是一个字符串。

指针的字节数 与typeof(buffer)得到的数值 不是一个东西啊 在调用 fun(buffer); 的时候 是buffers数组的首地址传给了  void fun(char * a)  中的形参a

引用 2 楼 CKRGD 的回复:所有指针规定是4个字节 并不是所有指针都是4个字节  楼主还是没搞懂指针，传进的a是个指针，一般都是占四个字节 而在数组定义处，数组名是代表了整个的数组

buffer是一个数组，并且初始化了，在内存中分配了空间，sizeof(buffer)就是整个数组的长度了咯，不知道这样理解行不行？


Question: fflush好像不管用

恩...大神说的对，我用的就是GCC，fflush()不是C/C++标准里定义的函数  引用 2 楼 u013163178 的回复:C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说：“可是我用 flush(stdin) 解决了这个问题，你怎么能说是错的呢？”的确，某些编译器（如VC6）支持用 flush(stdin) 来清空输入缓冲，但是并非所有编译器都要支持这个功能（linux下的gcc就不支持，经我的GCC4.6.2测试），因为标准中根本没有定义 flush(stdin).

C/C++ 误区二：fflush(stdin)  1.       为什么 fflush(stdin) 是错的     首先请看以下程序：                        #include <stdio.h>     int main( void )  {      int i;      for (;;) {          fputs("Please input an integer: ", stdout);          scanf("%d", &i);          printf("%d\n", i);      }      return 0;  }     这个程序首先会提示用户输入一个整数，然后等待用户输入，如果用户输入的是整数，程序会输出刚才输入的整数，并且再次提示用户输入一个整数，然后等待用户输入。但是一旦用户输入的不是整数（如小数或者字母），假设 scanf 函数最后一次得到的整数是 2 ，那么程序会不停地输出“Please input an integer: 2”。这是因为 scanf("%d", &i); 只能接受整数，如果用户输入了字母，则这个字母会遗留在“输入缓冲区”中。因为缓冲中有数据，故而 scanf 函数不会等待用户输入，直接就去缓冲中读取，可是缓冲中的却是字母，这个字母再次被遗留在缓冲中，如此反复，从而导致不停地输出“Please input an integer: 2”。     也许有人会说：“居然这样，那么在 scanf 函数后面加上‘fflush(stdin);’，把输入缓冲清空掉不就行了？”然而这是错的！C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说：“可是我用 fflush(stdin) 解决了这个问题，你怎么能说是错的呢？”的确，某些编译器（如VC6）支持用 fflush(stdin) 来清空输入缓冲，但是并非所有编译器都要支持这个功能（linux 下的 gcc 就不支持），因为标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着fflush on input stream is an extension to the C standard（fflush 操作输入流是对 C 标准的扩充）。当然，如果你毫不在乎程序的移植性，用 fflush(stdin) 也没什么大问题。以下是 C99 对 fflush 函数的定义：     int fflush(FILE *stream);     如果 stream 指向输出流或者更新流（update stream），并且这个更新流 最近执行的操作不是输入，那么 fflush 函数将把这个流中任何待写数据传送至 宿主环境（host environment）写入文件。否则，它的行为是未定义的。  原文如下：   int fflush(FILE *stream);    If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.     其中，宿主环境可以理解为操作系统或内核等。         由此可知，如果 stream 指向输入流（如 stdin），那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin)  是不正确的，至少是移植性不好的。        2.       清空输入缓冲区的方法      虽然不可以用 fflush(stdin)，但是我们可以自己写代码来清空输入缓冲区。只需要在 scanf 函数后面加上几句简单的代码就可以了。          /* C 版本 */         #include <stdio.h>            int main( void )         {             int i, c;               for ( ; ; )             {                 fputs("Please input an integer: ", stdout);                 scanf("%d", &i);               if ( feof(stdin) || ferror(stdin) )                 { /* 如果用户输入文件结束标志（或文件已被读完）， */                   /* 或者发生读写错误，则退出循环               */                                  /* do something */                     break;                 }                 /* 没有发生错误，清空输入流。                 */                 /* 通过 while 循环把输入流中的余留数据“吃”掉 */                 while ( (c = getchar()) != '\n' && c != EOF ) ;                 /* 使用 scanf("%*[^\n]"); 也可以清空输入流， */                 /* 不过会残留 \n 字符。                          */                 printf("%d\n", i);             }               return 0;         }           /* C++ 版本 */         #include <iostream>         #include <limits> // 为了使用numeric_limits         using namespace std;                 int main()         {             int value;              for ( ; ; )             {                 cout << "Enter an integer: ";                 cin >> value;                 if ( cin.eof() || cin.bad() )                 { // 如果用户输入文件结束标志（或文件已被读完），                   // 或者发生读写错误，则退出循环                     // do something                     break;                 }                 // 读到非法字符后，输入流将处于出错状态，                 // 为了继续获取输入，首先要调用 clear 函数                 // 来清除输入流的错误标记，然后才能调用                 // ignore 函数来清除输入流中的数据。                 cin.clear();                 // numeric_limits<streamsize>::max() 返回输入缓冲的大小。                 // ignore 函数在此将把输入流中的数据清空。                 // 这两个函数的具体用法请读者自行查询。                 cin.ignore( numeric_limits<streamsize>::max(), '\n' );                  cout << value << '\n';             }             return 0;         }  参考资料：  ISO/IEC 9899:1999 (E) Programming languages— C 7.19.5.2 The fflush function  The C Programming Language 2nd Edition By Kernighan & Ritchie  ISO/IEC 14882(1998-9-01)Programming languages — C++

fflush是用于输出流的。

#include <stdio.h> int main() { 	int a; 	char c; 	 do 	  { 		a=-1; 		printf("请输入一个数字:\n"); 		scanf("%d",&a);                 /*scanf()用%d输入字符数据时，由于数据类型不一致，会一直读取数据                 导致无限循环 		*/ 		if(a==-1) 		{ 			while(getchar()!='\n') 			; 			printf("输入的数格式不对,请重新输入:\n"); 			continue; 		} 		c='\0';	 		printf("请输入一个字符:\n"); 		getchar(); 		scanf("%c",&c); 		/* 		if(c=='\0') 		{ 			while(getchar()!='\n') 			; 			printf("输入的不是字符，请重新输入:\n"); 			continue; 		} 		*/ //		fflush(stdin); //		fflush(stdin); 		printf("a=%d,c=%c\n",a,c); 	  } 	while(c!='N'); } 今天刚学到scanf("%d",&num)，也遇到了这问题，上面的方法能解决一部分，但是若输入 12a 之类的还是有BUG，期待大神回复！

如果需要清除stdin while((c=gethcar()) != EOF)

函数名: fflush 功 能: 清除读写缓冲区，需要立即把输出缓冲区的数据进行物理写入时 头文件：stdio.h 原型:int fflush(FILE *stream)   你的理解没对 其实应该理解为 针对输出的操作  每次当你进行print 或 write 类似操作的时候 系统可能不会直接操作  而保存在缓冲区  这个时候你调用fflush 当前操作就会马上执行...


Question: 新手，书上的一点问题

明白了。。。。。

加油加油加油加油

引用 5 楼 xpdavis 的回复:引用 4 楼 filia2014 的回复:[quote=引用 1 楼 xpdavis 的回复:] 楼主跟踪一下所有的循环，就知道整个过程是怎么进行的，内外层总共也才15次循环楼主就是跟踪了才有此疑问。。。。。 楼主需要仔细观察，认真思考，谨慎分析，一般不会有什么问题了[/quote]  问一下，if语句if（array[j]<array[k]）k=j;是不是只有条件达成才会进入到下一句k=j对吧，执行的也就只有一句k=j对吧，下面的t=什么的那些替换语句是每一次for循环都会做的对吧？书上说 如果if语句要做多个命令是不是要加上“{}”花括号才行？

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

引用 4 楼 filia2014 的回复:引用 1 楼 xpdavis 的回复:楼主跟踪一下所有的循环，就知道整个过程是怎么进行的，内外层总共也才15次循环楼主就是跟踪了才有此疑问。。。。。 楼主需要仔细观察，认真思考，谨慎分析，一般不会有什么问题了

void sort(int array[],int n) {int i,j,k,t; for(i=0;i<n-1;i++)   //循环n-1次，每次找出剩余数字中最小的 {k=i; for(j=i+1;j<,;j++)    //遍历数组找出剩余数字中最小的所在的数组序号 if(array[j]<array[k])k=j; t=array[k];array[k]=array[i];array[i]=t;  //把当前最小数字交换到当前位置 } }

for(j=i+1;j<,;j++)？？？   引用 楼主 filia2014 的回复:假设我要比较5个数：3 6 1 9 4  当array[2]也就是1，小于array[0]也就是3然后做了替换。进入到下次循环的时候if(array[j]<array[k])k=j;此时array[j=3]也就是9了，那么k这个时候是不是array[2]，上一轮j的值给赋给了k，这个时候是不是在跟array[2]做比较？那不是就是和3做比较？ 不清楚变量的变化，设断点自己单步调试看看吧，不行也可以在适当部分加上printf把相关变量的值输出看看

楼主跟踪一下所有的循环，就知道整个过程是怎么进行的，内外层总共也才15次循环


Question: 变长数组

这个数组越界访问合法，指针行吗？

看不出这种语言特性有什么用处，传一个变量无非就是为了计算地址嘛，简单的，可以化二维为一维或者用堆的空间来动态分配

引用 2 楼 xpdavis 的回复:这个并不是变长数组，C语言规定二维数组形参必须指定一维的尺寸，新的C标准支持用变量来指定 第二维不需要指定，你这个函数的效果跟下面的一样； int  arr_ele(int  n,  int  A[n][],  int  i,  int  j) {         return  A[i][j]; } 如果是一维数组，就不需要了 int  arr_ele(int  n,  int  A[],  int  i) {         return  A[i]; } 实际上，数组的空间是在函数调用之前分配好的，而不是在函数体内分配的 引用 3 楼 r_Jimy 的回复:楼主这个函数完全没必要，假设外面定义了数组 int arr[3][4]; 调用arr_ele（3,arr,2,2); 等同于直接访问arr[2][2]; 想要变长，其实用malloc动态申请内存就可以了 引用 4 楼 zhao4zhong1 的回复:思考一下为什么没人将整个互联网内容作为函数参数传来传去呢？ 我的那个例子不太好，5楼回复就不错

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

对于二维数组传参数，至少传递数组的列数。即 int arr_ele(int n, int arr[][n], int i, int j)

以下内容来自《c primer lus》，我搬运过来，也学习下   变长数组中的“变”并不是表示在创建数组后，您可以修改其大小。变长数组的大小是实在创建后就是保持不变的。“变”的意思是说其维度大小可以用变量来表示。 因为变长数组是新增的特性，所以目前支持他的并不多。让我们来看一个简单的例子，该例子阐明如何编写一个计算任意二维int数组的和的函数。 首先，下面代码示范了如何声明一个妲有二维变长数组参数的函数： int sum2d(int rows, int cols, int ar[rows][cols]);//ar是一个变长数组 注意两个参量用作ar的维度，因为ar声明中使用哦了rows和cols，所以在参量列表中，他们两个声明必须变早于ar.因此，下面原型是错的 int sum2d(int ar[rows][cols],int rows, int cols);//错的  又学习了


Question: fgetws

引用 6 楼 A812DLG1 的回复:赵老师：你说的VS也是编译器的一种吗？如果是敢问赵老师网上哪里有这种编译器？ http://bbs.csdn.net/topics/390812579

赵老师：你说的VS也是编译器的一种吗？如果是敢问赵老师网上哪里有这种编译器？

赵老师：你的三个方法我都试过了，还是报错。是不是程序有问题 啊？我是按书上给的程序练习的。“fgetws”它是函数吗？

我VC6没错。 建议重装VS

再不行，将所有printf("...改为wprintf(L"... ?

或者将#include <wchar.h>挪到第一行？

删掉#include <wchar.h>试试看。


Question: 简单C语言问题！

7楼应该是对的，楼主多调试，动手才能提高哦

单步调试，这样就知道代码的意思了。

引用这个回车是换行符吗？ 是  看这几个输出，楼主明白不 楼主输入的字符，只要是2，就会原样输出，其它字符都会变成输出b

getchar()是单个单个字符读入的，输入abcde，它会一个一个的去缓冲区读取a  ,  b  ,  c   , d  ,e 当按下换行符时，再读取'\n'，进而跳出while()循环

输入一个字符，知道这个字符是回车或者是EOF才结束

while ((c = getchar()) != EOF && c!='\n') 这一行应该如何理解？ 输入结束符或者回车，循环结束 你输入a再输回车，只会收到a 只有单输回车的时候，才会收到'\n'，结束循环

getchar()是输入字符，直到碰到回车才返回的，返回第一个字符，如果只敲回车，就返回回车 我看你的意思，是需要用 getche()函数 你看一下这个资料 http://blog.csdn.net/lhsgbc/article/details/7190432

EOF是文件结束标识，不能用来标识命令行结束输入。

那我输入abcdef的时候程序是怎样的一个流程。是不是我输入一个a然后程序讲a存到键盘缓冲区，然后我在如入b继续存入键盘缓冲区。然后我输入回车后，程序不是就跳出循环了吗？那它是怎么显示的呢？