Question: 读文件数据到链表

引用 3 楼 zhangxiangDavaid 的回复:遗憾的是最好没有释放动态分配的内存 最后

遗憾的是最好没有释放动态分配的内存

这样可好：  #include <stdio.h> #include <string.h> struct stu { 	char username[260];    //好友用户名 	struct stu* next; }; struct user { 	char username[260];   //用户名 	char passwd[260]; 	int fansCount;              //好友数量 	struct stu * fanslist;     //好友链表 }zs; FILE *f; char buf[256]; char *p; struct stu *ps; int L; int main(void) { 	if (NULL == (f = fopen("1.txt", "r"))) 	{ 		fprintf(stderr, "Can not open file 1.txt\n"); 		return 1; 	} 	//初始化zhangsan 	strcpy(zs.username, "zhangsan"); 	strcpy(zs.passwd, "000000");   //初始密码 000000 	zs.fansCount = 0; 	zs.fanslist = NULL; 	//读入文件中的好友 	while (1) 	{ 		if (NULL == fgets(buf, 255, f)) break; 		L = strlen(buf); 		if (1 == L) continue; 		buf[L - 1] = 0; 		if (p = strstr(buf, "zhangsan")) 		{ 			p += strlen(zs.username); 			for (p = strtok(p, " "); p; p = strtok(NULL, " ")) 			{ 				struct stu *pStu = malloc(sizeof(struct stu)); 				strcpy(pStu->username, p); 				pStu->next = NULL; 				if (NULL == zs.fanslist) 				{ 					zs.fanslist = pStu; 					ps = pStu; 				} 				else 				{ 					ps->next = pStu; 					ps = ps->next; 				} 			} 		} 	} 	fclose(f); 	//打印zhangsan的好友 	ps = zs.fanslist; 	while (ps) 	{ 		printf("%s\n", ps->username); 		ps = ps->next; 	} 	return 0; } //lisi //wangwu //zhaoliu

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8   //将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: c编程BMP模块，大神求解啊，完全不懂

第六问你是不是写反了？在我的认知里，24bit-->8bit可比8bit-->24bit简单多了。 引用 8 楼 u012924596 的回复:[quote=引用 5 楼 赵4老师的回复:]MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl  解析256色的代码MSDN98的例子代码里面有：  MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\PALETTE\*.* MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\SHOWDIB\*.* 第六问有具体的c程序吗[/quote]

引用 9 楼 super_admi的回复:第六问你是不是写反了？在我的认知里，24bit-->8bit可比8bit-->24bit简单多了。 [quote=引用 8 楼 u012924596 的回复:] [quote=引用 5 楼 赵4老师的回复:]MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl  解析256色的代码MSDN98的例子代码里面有：  MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\PALETTE\*.* MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\SHOWDIB\*.* 第六问有具体的c程序吗[/quote][/quote] 六问是把8位转为24位啊，有程序吗

引用 5 楼 赵4老师的回复:MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl  解析256色的代码MSDN98的例子代码里面有：  MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\PALETTE\*.* MSDN98\SAMPLES\VC98\SDK\GRAPHICS\GDI\SHOWDIB\*.* 第六问有具体的c程序吗

第六问有具体的c程序吗

用二进制打开文件, 跳过14字节,用这个头BITMAPINFOHEADER 读入,取出其中的biBitCount,如果是8就是256色, 如果是256, 接着256*4就是调色版

#include <Windows.h> #include <stdio.h>  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  struct MyRGB { 	BYTE b; 	BYTE g; 	BYTE r; };  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { 	TCHAR szAppName[] = TEXT("BMP_APP_CLASS"); 	HWND		hwnd; 	MSG			msg; 	WNDCLASS	wndClass; 	wndClass.style			= CS_HREDRAW|CS_VREDRAW; 	wndClass.lpfnWndProc	= WndProc; 	wndClass.cbClsExtra		= 0; 	wndClass.cbWndExtra		= 0; 	wndClass.hInstance		= hInstance; 	wndClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION); 	wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW); 	wndClass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH); 	wndClass.lpszMenuName	= NULL; 	wndClass.lpszClassName	= szAppName; 	if(!RegisterClass(&wndClass)) 	{ 		MessageBox(NULL, TEXT("This program requires Windows NT!"), 						szAppName, MB_ICONERROR); 		return 0; 	} 	hwnd = ::CreateWindow(szAppName,  						"BMP图片解析程序", 						WS_OVERLAPPEDWINDOW, 						CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, 						NULL, NULL, hInstance, NULL); 	::ShowWindow(hwnd,iCmdShow); 	::UpdateWindow(hwnd); 	while(::GetMessage(&msg, NULL, 0,0)) 	{ 		::TranslateMessage(&msg); 		::DispatchMessage(&msg); 	} 	return msg.wParam; }  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { 	HDC				hdc; 	PAINTSTRUCT		ps; 	RECT			rect; 	COLORREF	color; 	char		fileName[] = "1.bmp"; 	FILE		*fp; 	BITMAPFILEHEADER		fileHeader; 	BITMAPINFOHEADER		infoHeader; 	WINDOWINFO				windInfo; 	char	   information[] = "打开不正确的bmp文件"; 	char	   tmpFileValue[4]; 	MyRGB   bmpData; 	int tmpValue = 0;  	switch(message) 	{ 	case WM_CREATE: 		/*if(fp == NULL) 		{ 			::GetWindowInfo(hwnd,&windInfo); 			TextOut(hdc, ) 		}*/ 		return 0; 	case WM_PAINT: 		hdc = ::BeginPaint(hwnd, &ps); 		fp = fopen(fileName, "rb"); 		if(fp == NULL) 		{ 			::TextOut(hdc, 0,0, information, strlen(information)); 			return 0; 		} 		fread(&fileHeader, sizeof(fileHeader), 1, fp); 		fread(&infoHeader, sizeof(infoHeader), 1, fp); 		tmpValue = (4-infoHeader.biWidth%4)%4; 		//bmpData = (MyRGB*)(malloc(sizeof(MyRGB)*infoHeader.biWidth)); 		for(int i=0; i<infoHeader.biHeight; i++) 		{ 			//fread(bmpData, sizeof(MyRGB)*infoHeader.biWidth, 1, fp); 			for(int j=0; j<infoHeader.biWidth; j++) 			{ 				fread(&bmpData, sizeof(MyRGB), 1, fp); 				::SetPixel(hdc, j,infoHeader.biHeight-i, RGB(bmpData.r,bmpData.g,bmpData.b)); 			} 			fread(tmpFileValue, tmpValue, 1, fp); 			/*for(int j=0; j<infoHeader.biWidth; j++) 			{ 				fread(&bmpData, sizeof(MyRGB), 1, fp); 				::SetPixel(hdc, i,j, RGB(bmpData.r,bmpData.g,bmpData.b)); 			}*/ 		} 		//free(bmpData); 		fclose(fp); 		::EndPaint(hwnd, &ps); 		return 0; 	case WM_DESTROY: 		PostQuitMessage(0); 		return 0; 	} 	return ::DefWindowProc(hwnd, message,wParam, lParam); } 我的代码只做了解析真彩色的工作。判断是否是256色，只要判断infoHeader的biBitCount字段是否为8。没写过解析256色的代码。

引用 1 楼 u012924596 的回复:BMP文件模块				 	包含的功能有：			 	1、判定是否是256色BMP			 	2、读出256色BMP的调色板			 	3、读出256色BMP的图像数据			 	4、判定是否是24位色BMP			 	5、读出24位色BMP的图像数据			 	6、转换256色BMP为24位色BMP 先弄清bmp文件的每个字节的含义！

了解了bmp文件的格式后，获取特定字节的值就可以判断


Question: 关于"C语言深度剖析"这本书的一个疑问

引用 4 楼 innerX 的回复:[quote=引用 2 楼 user-2 的回复:] 数组作为参数传递会弱化为指针，如果是放到sizeof运算符中，因为sizeof不会进行求值运算，只会推导表达式最后的类型，所以导致这样的结果 我用的win8.1，装不了vc，现在在用vs2013，需要做“五子棋”的作业，不用graphic.h，改用Windows API可以吗？[/quote] 当然可以用window api代替，但windows GUI编程是另一套需要学的东西了。 不过，五子棋不是重在算法吗？用一些字符代表棋子不就可以了吗？

引用 2 楼 user-2 的回复:数组作为参数传递会弱化为指针，如果是放到sizeof运算符中，因为sizeof不会进行求值运算，只会推导表达式最后的类型，所以导致这样的结果 我用的win8.1，装不了vc，现在在用vs2013，需要做“五子棋”的作业，不用graphic.h，改用Windows API可以吗？

引用 1 楼 jiqiang01234 的回复:不如去看《c专家编程》 这本书我有，但感觉平时练习用体会不了里面的编程思想啊。 借这个机会问前辈一个问题啊，我们有一个用C写五子棋的作业，我看Visual Studio 2013发现里面没有graphic.h，所以找了一些Windows编程的书，想用Windows API实现，但现在觉得这个有点难，你有什么建议吗？

不如去看《c专家编程》


Question: c中如何从文件中指定字符串开始读取固定长度的字符串

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

引用 2 楼 zhangxiangDavaid 的回复:这样可好：  #include <stdio.h> #include <string.h> int main(void) { 	FILE *f = fopen("1.txt", "r"); 	char buf[256]; 	char *p; 	while (1) 	{ 		if (NULL == fgets(buf, 256, f)) break; 		if (p = strstr(buf, "ORA")) printf("%.9s\n", p); 	} 	fclose(f); 	return 0; } //ORA-00001 //ORA-20001 //ORA-30001  我给你发私信了，请你帮我解答一下。   楼上是正确的

fgets/feof


Question: 关于%ld的问题

%ld : long %d  : int time_t time(time_t *t) 返回值类型是time_t, 与int, long的关系不明确，所以建议转换 printf("%6ld\r", (long)(time(0)-start)):

time是unsigned long而不是int类型。

time_t start=time(0);

printf中，格式、长度说明必需输出项一致，一定得到正确结果。 否则后果自负。 负责任的编译器会帮我们检查的

long int和int可能长度不同


Question: C语言中关于字符串的返回 读取 疑问.

传一个数组进去，copy到数组里 或者传一个malloc出来的内存空间指针进去，copy到指针指向的空间

int main() {    	MSG msg; 	char *b = (char*) calloc(255,sizeof(char)); 	b = Gett(); 	MessageBox(NULL,b,TEXT("提示"),NULL); 	printf("%s",b); }   char *Gett() {     char *a="哈哈"; 	return a;//这里返回到调用函数 被转变成指针 也就是数据所在内存地址 第一个字节的地址 } 搞定了.谢谢大家了

引用 13 楼 leee7338 的回复:字符串对于初学者来说是个难点  再加上指针和数组  把这三者学好之后C语言就好学多了。 指针是指向一个地址的 地址就是内存地址  内存中存储着数据  这是我的理解 不知道对不对.

引用 2 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> #include <locale.h> char *GetT() {     char *a="哈哈"; 	return a;//这里返回到调用函数 被转变成指针 也就是数据所在内存地址 第一个字节的地址 } int main() {     char b[10];     setlocale(LC_ALL,"chs");     strncpy(b,GetT(),9);b[9]=0;     printf("[%s]\n",b);     return 0; }  为什么要用 setlocale 这个命令呢?   百度说这函数 是配置本地环境的

引用 4 楼 jiqiang01234 的回复:[quote=引用 3 楼 qq_18599547 的回复:] [quote=引用 1 楼 jiqiang01234 的回复:]  struct A { 	char s[100]; };  A get() { 	struct  A a; 	strncpy(a.s,"哈哈", sizeof(struct A));         return a; }  这个有点看不懂 - -[/quote] 直接返回结构体的实例[/quote] 有没简单点 又 无需处理内存的方法

引用 5 楼 leee7338 的回复:用指针做参数 把a指向的首地址带回来。 我得到 首地址指针了 如何读出数据来呢   我是新手 没系统学过 - -

引用 10 楼 paschen 的回复:楼主如果是要返回一个char[]数组的话，可以把这个数组作为函数参数传入：  void *GetT(char ch[])  然后函数中需要的字符往ch里写就行了 我是想返回 字符串   可以我总是无法获取数据 - - 我就纳闷了 可能是我把指针和数据搞混了

都有地址了，还怕得不到内容？

用指针做参数 把a指向的首地址带回来。

引用 3 楼 qq_18599547 的回复:[quote=引用 1 楼 jiqiang01234 的回复:]  struct A { 	char s[100]; };  A get() { 	struct  A a; 	strncpy(a.s,"哈哈", sizeof(struct A));         return a; }  这个有点看不懂 - -[/quote] 直接返回结构体的实例

引用 1 楼 jiqiang01234 的回复: struct A { 	char s[100]; };  A get() { 	struct  A a; 	strncpy(a.s,"哈哈", sizeof(struct A));         return a; }  这个有点看不懂 - -


Question: 关于.array和 [] 以及 [String]()

歌曲列表.values 就是打出来那一串 歌曲列表.values.array 才是array（打出来你看得懂的东西）


Question: C语言运算符的顺序的疑问？

注意符号位！！

int是有符号的 右移要保证符号不变

仅供参考： #include <stdio.h> unsigned short int ui;   signed short int si; int main() {     ui=(unsigned short int)0x8000u;     si=(  signed short int)0x8000;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=ui>>1;     si=si>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      printf("--------------\n");     ui=(unsigned short int)0x8000u;     si=(  signed short int)0x8000;     printf("ui=%u\n",ui);     printf("si=%d\n",si);     ui=((  signed short int)ui)>>1;     si=((unsigned short int)si)>>1;     printf("ui=%u\n",ui);     printf("si=%d\n",si);      return 0; } //ui=32768 //si=-32768 //ui=16384 //si=-16384 //-------------- //ui=32768 //si=-32768 //ui=49152 //si=16384

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

引用 6 楼 xviphackl 的回复:恍然大悟    感谢 @zhangxiangDavaid 大大的解答 我是小鲜肉，不是大大。

引用 5 楼 zhangxiangDavaid 的回复:[quote=引用 4 楼 xviphackl 的回复:] [quote=引用 3 楼 zhangxiangDavaid 的回复:] a=1; ~a=11111111 11111111 11111111 11111110 ~a>>2 11111111 11111111 11111111 11111111     //最左边两位用符号位填充 以上就是-1的补码  符文号为什么需要用两个1来填充？我知道符号位不是左边第一个 0 表示正数 1 表示负数？ [/quote] 本质上，用0或1填充都行。 那就是说，看编译器怎么处理 大多数编译器，是这么干的： 右移，用符号位填充 左移，用0填充[/quote]  恍然大悟    感谢 @zhangxiangDavaid 大大的解答

引用 4 楼 xviphackl 的回复:[quote=引用 3 楼 zhangxiangDavaid 的回复:] a=1; ~a=11111111 11111111 11111111 11111110 ~a>>2 11111111 11111111 11111111 11111111     //最左边两位用符号位填充 以上就是-1的补码  符文号为什么需要用两个1来填充？我知道符号位不是左边第一个 0 表示正数 1 表示负数？ [/quote] 本质上，用0或1填充都行。 那就是说，看编译器怎么处理 大多数编译器，是这么干的： 右移，用符号位填充 左移，用0填充

引用 3 楼 zhangxiangDavaid 的回复:a=1; ~a=11111111 11111111 11111111 11111110 ~a>>2 11111111 11111111 11111111 11111111     //最左边两位用符号位填充 以上就是-1的补码  符文号为什么需要用两个1来填充？我知道符号位不是左边第一个 0 表示正数 1 表示负数？


Question: 给定一个无符号32位二进制整数n，如何编程判断二进制数n中所有的1都是成对连续出现的？

bool check(int n){     while(n){         for(;n&1;n>>=2){ if((n&3)!=3) return false;}         n>>=1;     }     return true; }

这样可好：  int main()//52 { 	unsigned char buf[33] = { 0 }; 	unsigned int u = 6; 	_itoa(u, buf, 2); 	printf("u=%s\n", buf); 	int i = 0, zc = 0; 	while (i < 32) 	{ 		if ('0' == buf[i]) 		{ 			if (zc % 2) 			{ 				printf("NO!\n"); 				return 0; 			} 			else zc = 0; 		} 		else 		{ 			zc++; 		} 		i++; 	} 	printf("YES!\n"); 	return 0; }

你用11这个串左移然后与那个串作与运算 看结果就知道了

是的，两个相邻的1，4个相邻的1，8个相邻的1。。。。 这种模式

“成对”是指两个相邻的1吗？

引用 14 楼 haozhics 的回复:[quote=引用 12 楼 lin5161678 的回复:] int Check(uint32_t x) { 	while(x && ((x&3)==0 || (x&3)==3)) 		x>>=2; 	return !x; }  逻辑问题： 当输入6（即2进制110）时，应该返回1但该函数返回0[/quote] 你说得对

引用 12 楼 lin5161678 的回复:int Check(uint32_t x) { 	while(x && ((x&3)==0 || (x&3)==3)) 		x>>=2; 	return !x; }  逻辑问题： 当输入6（即2进制110）时，应该返回1但该函数返回0

参考《编译原理》中的词法分析和有限状态自动机。

引用 9 楼 user-7 的回复:bool Check(uint32_t x) {     while (x)     {         while ((x & 1) == 0) x >>= 1;         if ((x & 3) != 3)         {             return false;         }         x >>= 2;     }     return true; } 好算法

引用 5 楼 lin5161678 的回复:00000000 00000000 00000000 11100000 3个相邻的1 算yes 还是no no

谢谢，很直接的解法

可以具体些吗？

no'奇数个相邻的1都算no


Question: error C2059: syntax error : '{'

//uint16 W_RESVAL[2] = { 0, 0}; 	uint16 W_RESVAL[2] = { W_Regval_H(0x05,0x88), W_Regval_H(0x05,0x88) }; 	//W_RESVAL[2] = { W_Regval_H(0x05,0x88), W_Regval_H(0x05,0x88) };

mewiteor： 我有试过，可以运行，想一开始定义个常量进去，为什么会报错呢

W_RESVAL[2]={W_Regval_H(0x05,0x88),W_Regval_H(0x05,0x88)}; 错误出在这里。。。汗

uint16 W_RESVAL[2]={0, }; W_RESVAL[2]={W_Regval_H(0x05,0x88),W_Regval_H(0x05,0x88)}; 改成：   uint16 W_RESVAL[2]={W_Regval_H(0x05,0x88),W_Regval_H(0x05,0x88)};

话说你看一下错误不就明白了吗。。  uint16 W_RESVAL[2]={0, };   0后面的逗号。。

define不要直接换行，需要换行时在行尾加  \

引用 5 楼 maychard1121 的回复:mewiteor： 我有试过，可以运行，想一开始定义个常量进去，为什么会报错呢因为 ={xx,xx,...} 这种写法只能用于数组初始化，之后对数组元素赋值就只能一个一个的赋值了。

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


Question: 关于sniffer中的WSAIoctl，求高人解答

这个是错误

感谢提醒哈，已经格式化了

什么错误贴出来, 这个编译器没用过

在Windows下开发，不用VS是自虐或装B！

你用的什么编辑器，  我用vs2012 编译你的代码完全没问题的

代码格式化一下，一般哪有个高兴找你的71行。


Question: C语言字符串转成对应的ASCii码的问题。

这是要显示成字符串吧，跟ASCII码没什么关系，建议去搜索下标准输入输出函数的用法； 内存中的数据都是二进制，这些二进制需要按照一定的编码方式，才能转换为我们看到的各种字符，默认的编码方式是ASCII码！

我理解能力有点差。C语言接触不深，请大家不吝赐教。小弟在此谢谢大家了

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

引用 2 楼 jiqiang01234 的回复:字符串本身不就是ascii码吗？ 引用 4 楼 fly_dragon_fly 的回复:字串就是ascii码,要转成什么 两位的意思是字符串输出的时候以%s输出就是字符串，以%d输出就是ASCII？

字符串是ASCII？  不会吧

字串就是ascii码,要转成什么

这个方法是可行。但是我这个项目要求把写的API封装成库  最多占用1K的内存，还要定义两个256的数组。请问 有没有简单的方法

字符串本身不就是ascii码吗？

这样可好：  int main(void) { 	int i = 0, n; 	char *s = "abcdef"; 	char buf[256], *p; 	p = buf; 	for (i = 0; i < strlen(s); i++) 	{ 		n = sprintf(p, "%d", s[i]); 		p += n; 	} 	printf("%s=%s\n", s, buf); 	return 0; } //abcdef=979899100101102


Question: C#用xml生成控件 然后 以控件生成xml

引用 1 楼 user-1 的回复:这是C语言区 嗯 着急了

这是C语言区


Question: windows c语言下获取pc mac地址

WinExec("cmd /c ipconfig /all >ipconfig.txt",SW_HIDE); //然后读文件ipconfig.txt的内容。


Question: libsvm如何在VC中使用

http://www.csie.ntu.edu.tw/~cjlin/libsvm/ 这里提供了C++的源代码，windows下的。代码注释不怎么详细，你可以自己改着用。 好像没有dll的版本。


Question: 怎样申请能够存放不同数据类型的大块内存空间？

引用 24 楼 WUYUAN2011WOAINI 的回复:你 直接建个byte数组，把int什么的float什么的都 按内存拷贝方式拷进去，然后再拷出来  能否说更具体一点？有个例子最好。

佩服。 后来我想了一下，先用标识 和 数据分开存储的方法试试。 在一个内存块里折腾难度太大了。 感谢大家。

美中不足 最后加一句：free(base);

满足你：  #include <string.h> #include <stdio.h> typedef struct datainfo { 	unsigned int nNum;  //数据个数 	char type[10];      //数据类型 }DataInfo; void *base; void write() { 	//存数据 	void *p = base; 	*(int*)p = 2;   //前四个字节存放块数 	(char*)p += sizeof(int);  	DataInfo d1 = { 10, "int" }; 	memcpy(p, &d1, sizeof(d1)); 	(char*)p += sizeof(d1); 	int iarr[] = { 0,1,2,3,4,5,6,7,8,9 }; 	memcpy(p, iarr, sizeof(iarr)); 	(char*)p += sizeof(iarr);  	DataInfo d2 = { 10, "double" }; 	memcpy(p, &d2, sizeof(d2)); 	(char*)p += sizeof(d2); 	double darr[] = { 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 9.1 }; 	memcpy(p, darr, sizeof(darr)); 	(char*)p += sizeof(darr); } void read() { 	//取数据 	void *p = base; 	int i = 0, n = *(int*)p; 	(char*)p += sizeof(int); 	while (i < n) 	{ 		DataInfo d = *(DataInfo*)p; 		printf("nNum=%d,type=%s\n", d.nNum, d.type); 		if (0 == strcmp(d.type, "int")) 		{ 			int *q = (char*)p + sizeof(DataInfo); 			int i; 			for (i = 0; i < d.nNum; i++, q++) printf("%d ", *q); 			p = q; 		} 		else if (0 == strcmp(d.type, "double")) 		{ 			double *q = (char*)p + sizeof(DataInfo); 			int i; 			for (i = 0; i < d.nNum; i++, q++) printf("%g ", *q); 			p = q; 		} 		else 		{ 			printf("Type error!\n"); 			return; 		} 		printf("\n"); 		i++; 	} } int main(void) { 	base = malloc(1024 * 1024);   //申请1M内存 	write(); 	read(); 	return 0; } //nNum = 10, type = int //0 1 2 3 4 5 6 7 8 9 //nNum = 10, type = double //0.1 1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1

引用 14 楼 Philipyexushen 的回复:[quote=引用 13 楼 guoyunfei1 的回复:] 我现在就是想解决标识的问题。 其实我要存储大量float 类型数据 到一个Buffer里。 需要同时存入一些int 类型，作为标识数据，用于读取数据时辨识这些不同数据。 不知这个思路对不对。  那为什么要一定要一次性的分配一片内存来做这件事情呢？  分两个区域，一个储存，一个是指向BUFFER的标识不是更好吗[/quote]   我的想法是这样的:  先开辟一大块内存空间，比如10M。 用  BuffBcrv = (float*)  malloc( 1024* 1024*10 ); // deploy memory of xxx size for store the result B curve  要存入的数据分为两种不同用途，希望能够读取时分辨出是哪一种。  问题1：  然后依次存入不同大小的数据块。 为了读取方便，在存入不同大小数据块之前，先存入该数据块的大小数值。  问题2： 要存入的数据分两种不同类型，为了区分这两种类型，需要设置类型标识。  请问大家，如何设定数据块的标识？

引用 17 楼 zhangxiangDavaid 的回复:[quote=引用 16 楼 Philipyexushen 的回复:] [/code]  大神，我问个问题可以吗，为什么要写成12 & 0xffu和(12 >> 24) & 0xffu呢。。。。[/quote] 按每个字节取值[/quote]  懂了，谢谢

楼主要的是 union 吧 如我想这块内存可以存  坐标 int x, y, z 色彩 char r, g, b, a 贴图 float u, v ..........   typedef union vec {   struct { 	int x, y, z;   };    struct { 	unsigned char r, g, b, a;   };    struct { 	float u, v;   }; } vec_t;

引用 16 楼 Philipyexushen 的回复:[/code]  大神，我问个问题可以吗，为什么要写成12 & 0xffu和(12 >> 24) & 0xffu呢。。。。[/quote] 按每个字节取值

引用 8 楼 zhangxiangDavaid 的回复:[quote=引用 7 楼 guoyunfei1 的回复:] 谢谢。 那请问如果让   //i=12 //f=12.340000 //lf=12.340000 //cs=David 这几个数据依次存入申请的Base, 怎么写代码？ 亲，一定得这样吗：  #include <memory.h> int main(void) { 	//申请10个字节的空间 	void *base = malloc(sizeof(char) * 10); 	((char*)base)[0] = 12 & 0xffu; 	((char*)base)[1] = (12 >> 8) & 0xffu; 	((char*)base)[2] = (12 >> 16) & 0xffu; 	((char*)base)[3] = (12 >> 24) & 0xffu; 	printf("i=%d\n", *(int*)base);  	float f = 12.34f; 	((char*)base)[0] = ((char*)&f)[0]; 	((char*)base)[1] = ((char*)&f)[1]; 	((char*)base)[2] = ((char*)&f)[2]; 	((char*)base)[3] = ((char*)&f)[3]; 	printf("f=%f\n", *(float*)base);  	double lf = 12.34; 	((char*)base)[0] = ((char*)&lf)[0]; 	((char*)base)[1] = ((char*)&lf)[1]; 	((char*)base)[2] = ((char*)&lf)[2]; 	((char*)base)[3] = ((char*)&lf)[3]; 	((char*)base)[4] = ((char*)&lf)[4]; 	((char*)base)[5] = ((char*)&lf)[5]; 	((char*)base)[6] = ((char*)&lf)[6]; 	((char*)base)[7] = ((char*)&lf)[7]; 	printf("lf=%lf\n", *(double*)base);  	char *cs = "David"; 	((char*)base)[0] = cs[0]; 	((char*)base)[1] = cs[1]; 	((char*)base)[2] = cs[2]; 	((char*)base)[3] = cs[3]; 	((char*)base)[4] = cs[4]; 	printf("cs=%s\n", cs);  	free(base); 	return 0; } [/quote]  大神，我问个问题可以吗，为什么要写成12 & 0xffu和(12 >> 24) & 0xffu呢。。。。

这不就是结构体么...

引用 13 楼 guoyunfei1 的回复:我现在就是想解决标识的问题。 其实我要存储大量float 类型数据 到一个Buffer里。 需要同时存入一些int 类型，作为标识数据，用于读取数据时辨识这些不同数据。 不知这个思路对不对。  那为什么要一定要一次性的分配一片内存来做这件事情呢？  分两个区域，一个储存，一个是指向BUFFER的标识不是更好吗

引用 9 楼 guoyunfei1 的回复:高手。 您的功力确实了得。  不过抱歉我没把问题说清除， 我是想问，Base里面先放int 12,后面再添加进去float 12.34; 等等。 Base要大一点，里面同时放入不同类型的数据。 请问有没有办法实现？ 你需要的其实是一个可以存放任意类型的容器吧 这个当然是可以实现的，只是你得自己用一个标示来记录数据的类型，否则你取数据的时候是并不知道当前数据时什么类型的。 例如：    struct AnyData {      int m_datatype;        union      {            float m_floatval;            int    m_intval;      }; };  struct AnyData* base = (struct AnyData*)malloc(sizeof(AnyData) * N);

我也在想，怎么能让这些不同类型数据挨着存储。 尽量少浪费内存空间。

引用 9 楼 guoyunfei1 的回复:高手。 您的功力确实了得。  不过抱歉我没把问题说清除， 我是想问，Base里面先放int 12,后面再添加进去float 12.34; 等等。 Base要大一点，里面同时放入不同类型的数据。 请问有没有办法实现？ 是要连续存放吗？否则会覆盖掉

引用 7 楼 guoyunfei1 的回复:谢谢。 那请问如果让   //i=12 //f=12.340000 //lf=12.340000 //cs=David 这几个数据依次存入申请的Base, 怎么写代码？ 亲，一定得这样吗：  #include <memory.h> int main(void) { 	//申请10个字节的空间 	void *base = malloc(sizeof(char) * 10); 	((char*)base)[0] = 12 & 0xffu; 	((char*)base)[1] = (12 >> 8) & 0xffu; 	((char*)base)[2] = (12 >> 16) & 0xffu; 	((char*)base)[3] = (12 >> 24) & 0xffu; 	printf("i=%d\n", *(int*)base);  	float f = 12.34f; 	((char*)base)[0] = ((char*)&f)[0]; 	((char*)base)[1] = ((char*)&f)[1]; 	((char*)base)[2] = ((char*)&f)[2]; 	((char*)base)[3] = ((char*)&f)[3]; 	printf("f=%f\n", *(float*)base);  	double lf = 12.34; 	((char*)base)[0] = ((char*)&lf)[0]; 	((char*)base)[1] = ((char*)&lf)[1]; 	((char*)base)[2] = ((char*)&lf)[2]; 	((char*)base)[3] = ((char*)&lf)[3]; 	((char*)base)[4] = ((char*)&lf)[4]; 	((char*)base)[5] = ((char*)&lf)[5]; 	((char*)base)[6] = ((char*)&lf)[6]; 	((char*)base)[7] = ((char*)&lf)[7]; 	printf("lf=%lf\n", *(double*)base);  	char *cs = "David"; 	((char*)base)[0] = cs[0]; 	((char*)base)[1] = cs[1]; 	((char*)base)[2] = cs[2]; 	((char*)base)[3] = cs[3]; 	((char*)base)[4] = cs[4]; 	printf("cs=%s\n", cs);  	free(base); 	return 0; }

assert(sizeof(int)==sizeof(float));


Question: c语言（void *）问题，bsearch中的使用

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\bsearch.c /*** *bsearch.c - do a binary search * *   Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *   defines bsearch() - do a binary search an an array * *******************************************************************************/  #include <cruntime.h> #include <stdlib.h> #include <search.h> #include <internal.h>  #if defined (_M_CEE) #define __fileDECL  __clrcall #else  /* defined (_M_CEE) */ #define __fileDECL  __cdecl #endif  /* defined (_M_CEE) */ /*** *char *bsearch() - do a binary search on an array * *Purpose: *   Does a binary search of a sorted array for a key. * *Entry: *   const char *key    - key to search for *   const char *base   - base of sorted array to search *   unsigned int num   - number of elements in array *   unsigned int width - number of bytes per element *   int (*compare)()   - pointer to function that compares two array *           elements, returning neg when #1 < #2, pos when #1 > #2, and *           0 when they are equal. Function is passed pointers to two *           array elements. * *Exit: *   if key is found: *           returns pointer to occurrence of key in array *   if key is not found: *           returns NULL * *Exceptions: *   Input parameters are validated. Refer to the validation section of the function. * *******************************************************************************/  #ifdef __USE_CONTEXT #define __COMPARE(context, p1, p2) (*compare)(context, p1, p2) #else  /* __USE_CONTEXT */ #define __COMPARE(context, p1, p2) (*compare)(p1, p2) #endif  /* __USE_CONTEXT */  #if !defined (_M_CEE) _CRTIMP #endif  /* !defined (_M_CEE) */  SECURITYSAFECRITICAL_ATTRIBUTE #ifdef __USE_CONTEXT void * __fileDECL bsearch_s ( 	REG4 const void	*key, 	const void *base, 	size_t num, 	size_t width, 	int	(__fileDECL	*compare)(void *, const	void *,	const void *), 	void *context 	) #else  /* __USE_CONTEXT	*/ void * __fileDECL bsearch ( 	REG4 const void	*key, 	const void *base, 	size_t num, 	size_t width, 	int	(__fileDECL	*compare)(const	void *,	const void *) 	) #endif	/* __USE_CONTEXT */ { 	REG1 char *lo =	(char *)base; 	REG2 char *hi =	(char *)base + (num	- 1) * width; 	REG3 char *mid; 	size_t half; 	int	result;  	/* validation section */ 	_VALIDATE_RETURN(base != NULL || num ==	0, EINVAL, NULL); 	_VALIDATE_RETURN(width > 0,	EINVAL,	NULL); 	_VALIDATE_RETURN(compare !=	NULL, EINVAL, NULL);  		/* 		We allow a NULL	key	here because it	breaks some	older code and because we do not dereference 		this ourselves so we can't be sure that it's a problem for the comparison function 		*/  	while (lo <= hi) 	{ 		if ((half =	num	/ 2) !=	0) 		{ 			mid	= lo + (num	& 1	? half : (half - 1)) * width; 			if (!(result = __COMPARE(context, key, mid))) 				return(mid); 			else if	(result	< 0) 			{ 				hi = mid - width; 				num	= num &	1 ?	half : half-1; 			} 			else 			{ 				lo = mid + width; 				num	= half; 			} 		} 		else if	(num) 			return (__COMPARE(context, key,	lo)	? NULL : lo); 		else 			break; 	}  	return NULL; }  #undef __fileDECL #undef __COMPARE

你要觉得他写的不对，你给他改了！

_ACRTIMP void* __cdecl bsearch(     _In_                                               void const* _Key,     _In_reads_bytes_(_NumOfElements * _SizeOfElements) void const* _Base,     _In_                                               size_t      _NumOfElements,     _In_                                               size_t      _SizeOfElements,     _In_ int (__cdecl* _PtFuncCompare)(void const*, void const*)     );  这是vc下的bsearch声明。 “在一个数组中查找name所指向的字符串”？


Question: 请教动态链接库中内存释放的问题

这个就是单纯传指针的值，函数内部分配内存跟你一毛钱关系都木有； 函数内部分配内存是这样的： FindPeak(double *&a, double *&b)； 不过很容易错；

无new无delete 无alloc无free 无生无死

已经解决了，原来在外部就能释放 = =

引用 3 楼 xubinlife 的回复:[quote=引用 1 楼 user-5 的回复:] 你这个形式确定是动态库分配的内存？ 我写的有问题，麻烦再看看 结构体typedef struct{     int x;	     int y;	 }Peak; typedef struct{ 	int label; 	Peak* peaks; }Material;  动态库函数是int FindPeak(double *a,Material *b) ;  其中b->peaks = new Peak[3]; 外部调用FindPeak(a, &b); 这样的话怎么释放呢？[/quote] 从new关键字来看，用的是c++，那直接把结构体定义为下面的不就行了？为何非要手动管理内存  typedef struct{ int label; std::vector<Peak> peaks; }Material;

引用 2 楼 todo9351 的回复:你确定b是动态库里分配的？而不是由外部传入？？ 我化简了下。。写错了，麻烦看看上面的修改

引用 1 楼 user-5 的回复:你这个形式确定是动态库分配的内存？ 我写的有问题，麻烦再看看 结构体typedef struct{     int x;	     int y;	 }Peak; typedef struct{ 	int label; 	Peak* peaks; }Material;  动态库函数是int FindPeak(double *a,Material *b) ;  其中b->peaks = new Peak[3]; 外部调用FindPeak(a, &b); 这样的话怎么释放呢？

你确定b是动态库里分配的？而不是由外部传入？？

你这个形式确定是动态库分配的内存？


Question: c实现对结构体数据分组求和

上点代码来看看啊

lz应该数的是结构体数组sdata[]吧，以下给出伪代码： agroup=sdata[0].group; int sum[x];//和数组，自己确定大小 int y=0; for(int i=0;i<Number；i++) {  if(agroup==sdata[i].group)     sum[y]+=sdata[i].value; else {    sum[++y]=sdata[i].value;    agroup=sdata[i].group; } }

你是要怎么分组 你的分组规则是什么

std::map

有大神在吗？


Question: fseek计算文件长度出问题，请教

加断点看下文件有没打开成功

什么信号？ 这个函数？ void (__cdecl *signal(    int sig,     void (__cdecl *func ) (int [, int ] )))     (int);

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

引用 3 楼 maychard1121 的回复:文件是打开成功的，数据 2067 2065 2061 2059 2055 2053 2050 2049 2049 这样的数据16515个 ftell返回的是字节数


Question: for语句条件成立也没有执行

谢谢各位的帮助下，小的的代码页到问题了，是M的赋值问题。真是强大

这样可好：  #include <iomanip> #include <iostream> using namespace std; typedef struct SNode { 	int nData; 	struct SNode *next; }SNode, *LinkList; void CreateList(LinkList &L, int n) { 	//int i = n; 	int i = 2; 	L = (SNode*)malloc(sizeof(SNode)); 	L->nData = 1; 	L->next = NULL; 	LinkList p = L; 	while (i <= n) 	{ 		p->next = (LinkList)malloc(sizeof(SNode)); 		p = p->next;    //zx 		p->nData = i; 		//p->next = L->next; 		//L->next = p; 		i++; 	} 	p->next = L;   //构成环 } int main() { 	int M, N; 	int i, j = 0; 	LinkList L, temp; 	cout << "type in the value of N,M" << endl; 	cin >> N >> M; 	cout << endl; 	CreateList(L, N); 	temp = L; 	//while (temp->next != temp && temp) 	//{ 	//	for (i = M - 1; i>0; i--) 	//	{ 	//		if (temp->next == NULL) 	//			temp->next = L->next; 	//		else 	//			temp = temp->next; 	//	} 	//	cout << temp->next->nData << endl; 	//	temp->next = temp->next->next; 	//} 	i = 1; 	while (i < N) 	{ 		j = 0; 		while (1) 		{ 			if (0 != temp->nData) 			{ 				if (++j == M) break; 			} 			temp = temp->next; 		} 		cout << setw(3) << temp->nData; 		temp->nData = 0; 		i++; 	} 	while (0 == temp->nData) temp = temp->next; 	cout << endl << temp->nData << endl; 	return 0; }

引用 5 楼 fly_dragon_fly 的回复:M的值是多少 可以自己设的

#include <iostream> using namespace std; typedef struct SNode {     int nData; 	struct SNode *next; }SNode,*LinkList;  void CreateList(LinkList &L,int n) { 	int i = n;     L = (SNode*)malloc(sizeof(SNode)); 	L->next = NULL; 	LinkList p; 	while(i!=0) 	{ 		p = (LinkList)malloc(sizeof(SNode)); 		p->nData = i; 		p->next = L->next; 		L->next = p; 		i--; 	} }  void main() { 	int M,N; 	int i,j=0; 	LinkList L,temp; 	cout<<"type in the value of N,M"<<endl; 	cin>>N>>M; 	cout<<endl;     CreateList(L,N); 	temp = L; 	while(temp->next != temp && temp) 	{ 		for(i=M-1;i>0;i--) 		{          if(temp->next == NULL) 		    temp->next = L->next; 		 else 			temp = temp->next; 		}         cout<<temp->next->nData<<endl; 		temp->next = temp->next->next; 	} 	cout<<temp->nData<<endl; } 完整的代码。其实就是个简单的约瑟夫环的问题，可是自己写的就是有问题

M的值是多少

在for语句内外都打印循环变量不就清楚了吗？

单步调试还看不出问题？

[quote=引用 1 楼 user-5 的回复:] 你调试过了吗，确定没有执行，最好把完整的代码贴出来 确定

你调试过了吗，确定没有执行，最好把完整的代码贴出来


Question: 求大牛帮助 ，我这个代码错在哪里 ，不知道错在哪里

回复楼上版主 我这个问题出在 （*p)[6]这个作为函数参数 不是特别了解 ， 我刚学习c   里面的循环模块我自己调试的 。谢谢楼上大神的指教，和建议。

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

谢谢楼上的回答 我是个初学者哈

修改如下：  //65.二维数组排序。设有4×5的数组M， //通过排序使M[1][1]≤M[1][2]≤...≤M[1][5]≤M[2][1]≤M[2][2]≤...≤M[2][5]≤...≤M[4][1]≤M[4][2]≤...≤M[4][5]。 //排序时不允许引入其它数组。 #include<stdio.h> int sortarray(int(*s)[6])     //模块出错了 { 	int i = 0, j = 0, k, temp = 0; 	//for (i = 0; i < 4 * 5; i++) 	//{ 	//	for (j = 0; j<4 * 5 - i - 1; j++) 	//	{ 	//		if (s[j / 5 % 4][j % 5]>s[(j + 1) / 5 % 4][(j + 1) % 5]) 	//		{ 	//			temp = s[(i + 1) / 5 % 4][(i + 1) % 5]; 	//			s[j / 5 % 4][i % 5] = s[(j + 1) / 5 % 4][(j + 1) % 5]; 	//			s[j / 5 % 4][j % 5] = temp; 	//		} 	//	} 	//} 	for (i = 0; i < 5; i++) 		for (j = 1; j < 6; j++) 			for (k = 0; k < 6 - j; k++) 			{ 				if (s[i][k] > s[i][k + 1]) 				{ 					temp = s[i][k]; 					s[i][k] = s[i][k + 1]; 					s[i][k + 1] = temp; 				} 			} } int initarray(int(*s)[6])     //模块出错了 { 	int i = 0, j = 0; 	for (i = 0; i < 5; i++) 	{ 		for (j = 0; j < 6; j++) 		{ 			s[i][j] = rand() % 100; 		} 	} } int printfarray(int(*s)[6]) { 	int i = 0, j = 0; 	for (i = 0; i < 5; i++) 	{ 		for (j = 0; j < 6; j++) 		{ 			printf("\t%d", s[i][j]); 		} 		putchar('\n'); 	} 	printf("\n"); } int main() { 	int a[5][6] = { 0 }; 	initarray(a); 	printfarray(a); 	sortarray(a); 	printfarray(a); 	return 0; }


Question: VC C++ 6.0出现的bug吗？

额，初学者要善于观察啊。这种错误还会犯的。不过会犯错是好事来的。

引用 3 楼 cutmelon 的回复:尖括号和圆括号不是一码事啊！感谢指正，感谢！

引用 2 楼 iyomumx 的回复:#include <stdio.h> 你真的好好对比过吗感谢各位大大，对我这些小错误，指正！ 感谢！

引用 4 楼 u014306011 的回复:额，初学者要善于观察啊。这种错误还会犯的。不过会犯错是好事来的。 x谢谢！

你的头文件不能用圆扣号。。。可以用""可能你会分清楚点

尖括号和圆括号不是一码事啊！

#include <stdio.h> 你真的好好对比过吗

没看出什么问题啊！


Question: C代码的size是个什么样的概念

SIZE(1)                      GNU Development Tools                     SIZE(1)    NAME        size - list section sizes and total size.  SYNOPSIS        size [-A|-B|--format=compatibility]             [--help]             [-d|-o|-x|--radix=number]             [-t|--totals]             [--target=bfdname] [-V|--version]             [objfile...]  DESCRIPTION        The GNU size utility lists the section sizes---and the total size---for        each of the object or archive files objfile in its argument  list.   By        default,  one  line of output is generated for each object file or each        module in an archive. $ size /usr/bin/size              text    data     bss     dec     hex filename  390531    1624   16996  409151   63e3f /usr/bin/size $

理解和讨论之前请先学会如何观察！  Windows：dumpbin.exe Linux：objdump

引用 2 楼 batigol198 的回复:[quote=引用 1 楼 zhangxiangDavaid 的回复:] 你说的size，是指最后可执行文件的大小吗？  指的是 code size啊。[/quote] 呵呵，你认为什么才算是code size？ 除此之外，编译器还会添加一些代码、exe文件也有自身的格式…… 所以，粗略的讲，当然不是

引用 1 楼 zhangxiangDavaid 的回复:你说的size，是指最后可执行文件的大小吗？  指的是 code size啊。

你说的size，是指最后可执行文件的大小吗？


Question: net-snmp中snmp_alarm_register怎么使用，回调函数没有调用

snmp_alarm_register里指定了SA_REPEAT参数 ,为啥还要循环调用啊


Question: 关于 malloc的问题 ，

引用 3 楼 zhangxiangDavaid 的回复:当然是在你不用的时候+1

要是java的话，会自己释放空间的

申请,使用,释放 这是个好习惯

一般来说都是类的成员函数吧，这样把也指针写成成员，析构里面释放； 如果不是类就用静态指针，什么时候都可以释放； 什么都不做就是坑爹，不要指望调用者帮你释放，人家很忙的！

谁污染谁治理。

应该是在调用完这个函数之后，在开辟内存的函数中free，始终要记住的是：哪里开辟，哪里释放。

我在自己家里用彩陶做了一个盘子 ， 后来我把这个盘子的使用权租给邻居使用 ， 那我应该在什么时候和什么地方砸碎它呢 。。 如果不

malloc()和free()是成对出现的，你申请一片内存之后 可以立刻释放  也可以等你操作完你指针指向内存里的数据再释放。那要看你具体情况了。内存泄漏这个问题很严重。

这时你需要写一个"这个函数"以及"这个函数外面"都认识的一套规则  bool MyMalloc(size_t sz, void** ppMem); void MyFree(void* pMem);  然后都使用这两个函数就可以了,更复杂点可以用ref机制

谁负责申请，谁负责释放。

你再提供一个free的接口供别人调用，别人用完了自然得调用这个接口。 如果调用方直接free你dll里面申请得内存，会有问题的

始终不free，会造成内存泄露

当然是在你不用的时候

在使用完这个空间之后在这个函数中free，另外你最好把代码贴出来，这样大家也好帮你

如果不free 的话 ， 生成dll以后 在c#中调用 ， 他总告诉我 指针错误 ，debug assertion failed ，


Question: IntelliSense: 不能将 "void *" 类型的值分配到 "char*" 类型的实体

强制转换就没问题了

该disable的warning还是要disable的。

不要忽视warning 给你的代码加上cast而不是disable warning 看InteeliSense的文档如何disable warning

即使是警告，也不要忽略

(char*)强转一定可以解决问题，但你要保证逻辑上可行。

加一个指针强制类型转化就可以了，但类似的地方太多，不想去改了


Question: 关于变量存储的问题

用debugger看看这些地址呢？

static是在全局数据区中。  dumpbin.exe  VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

引用 5 楼 wjjll123 的回复:[quote=引用 1 楼 jiqiang01234 的回复:] 内存区域不只是“栈区”和“堆区”这两个。 这个文章写得比较清晰http://blog.csdn.net/yiya1989/article/details/8957370 恩，写的很详细，不过还有一点请教一下，以上的几种情况，变量还有值，是放在虚拟内存中还是实际的物理内存中？ [/quote] 虚拟内存，操作系统分配出去的内存，都是虚拟内存。物理内存由操作系统管理，会映射为虚拟内存。

引用 1 楼 jiqiang01234 的回复:内存区域不只是“栈区”和“堆区”这两个。 这个文章写得比较清晰http://blog.csdn.net/yiya1989/article/details/8957370 恩，写的很详细，不过还有一点请教一下，以上的几种情况，变量还有值，是放在虚拟内存中还是实际的物理内存中？

引用 2 楼 user-5 的回复:引用char* pc = "abc"; pc存储在什么里面，abc存储在什么里面 pc是 栈 "abc"  可能是在代码段 (根据具体实现不同而不同 只要求是静态存储)  引用char* newpc = pc; newpc存储在什么里面，newpc里面的abc是不是和pc里面的abc存放在一个位置 newpc 栈 是存放在同一个位置   引用char* mallpc = (char*)malloc(10); strcpy(mallpc, pc);mallpc存储位置是什么？mallpc里面的abc是不是和pc里面的abc是同一个abc??? mallpc 栈 不是同一个abc   还有一个问题请教一下，以上的几种情况，变量还有值，是放在虚拟内存中还是实际的物理内存中？

楼上正解 lz不要太纠结


Question: 数据结构求指教

修改如下：  #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX 100 typedef int Staff; typedef struct ElemType {    //学生信息结构体定义 	char num[MAX]; 	char name[20]; 	char sex[8]; 	char birth[20]; 	char telenum[20]; 	struct ElemType *next; }ElemType; typedef struct { 	ElemType *data; 	int length; }SqList; void ListInit(SqList &L) {//录入员工信息  	int x, i; 	L.length = 0; 	L.data = (ElemType *)malloc(sizeof(ElemType));   //头节点 	ElemType *p = L.data; 	printf("请输入要输入员工的人数：\n"); 	scanf("%d", &x); 	if(x >= 0) L.length = x;     //直接赋值 	//for (i = 0; i < x - 1; i++) { 	for (i = 0; i < x; i++) { 		p->next = (ElemType *)malloc(sizeof(ElemType)); 		p = p->next; 		printf("请输入第%d个员工的信息：\n", i + 1);    //输入数据元素 		printf("员工号："); 		scanf("%s", p->num); 		printf("姓名："); 		scanf("%s", p->name); 		printf("性别："); 		scanf("%s", p->sex); 		printf("出生日期："); 		scanf("%s", p->birth); 		printf("电话号码："); 		scanf("%s", p->telenum); 		//L.length++; 	} 	p->next = NULL; } void PrintList(SqList L) {//输出员工信息  	if (L.length){ 		int i; 		ElemType *p = L.data->next;   //跳过头节点，指向第一个节点 		printf("*****************************\n"); 		printf("输出员工表：\n"); 		printf("*****************************\n"); 		for (i = 0; i < L.length; i++) { 			printf("%s的信息为：\n", p->num); 			printf("姓名：%s\n", p->name); 			printf("性别：%s\n", p->sex); 			printf("出生日期：%s\n", p->birth); 			printf("电话号码：%s\n", p->telenum); 			p = p->next; 		} 	} } void LocateElem(SqList L) {//查询员工信息 	if (L.length) { 		int i; 		ElemType *p = L.data->next;   //跳过头节点，指向第一个节点 		char num1[MAX]; 		printf("请输入员工的员工号：\n"); 		scanf("%s", num1); 		printf("*****************************\n"); 		printf("输出员工表：\n"); 		printf("*****************************\n"); 		for (i = 0; i < L.length; i++) { 			if (!strcmp(num1, p->num)) { 				printf("%s的信息为：\n", p->num); 				printf("姓名：%s\n", p->name); 				printf("性别：%s\n", p->sex); 				printf("出生日期:%s\n", p->birth); 				printf("电话号码:%s\n", p->telenum); 				break; 			} 			p = p->next; 		} 		if (i == L.length)printf("输入有误，员工号不存在：\n"); 	} } void ListUpdate(SqList &L) { 	if (L.length) { 		ElemType *p = L.data->next; 		char num1[MAX]; 		printf("请输入员工的员工号：\n"); 		scanf("%s", num1); 		int i; 		//while (p->next) p = p->next; 		//q = (ElemType *)malloc(sizeof(ElemType)); 		//q->next = NULL; 		for (i = 0; i < L.length; i++) { 			if (!strcmp(num1, p->num)) { 				break; 			} 			p = p->next; 		} 		if (i == L.length) printf("输入有误，员工号不存在：\n"); 		else { 			printf("请输入%s员工的更改后的信息：\n");    //输入数据元素  			printf("姓名："); 			scanf("%s", p->name); 			printf("性别："); 			scanf("%s", p->sex); 			printf("出生日期："); 			scanf("%s", p->birth); 			printf("电话号码:"); 			scanf("%s", p->telenum); 			printf("修改成功\n"); 		} 	} } void ListInsert(SqList &L) {//添加员工信息 	ElemType *p = L.data; 	while (p->next) p = p->next; 	p->next = (ElemType *)malloc(sizeof(ElemType)); 	p = p->next; 	printf("请输入新员工的信息：\n");    //输入数据元素 	printf("员工号："); 	scanf("%s", p->num); 	printf("姓名："); 	scanf("%s", p->name); 	printf("性别："); 	scanf("%s", p->sex); 	printf("出生日期："); 	scanf("%s", p->birth); 	printf("电话号码:"); 	scanf("%s", p->telenum); 	p->next = NULL; 	L.length++; } void ListDelete(SqList &L) {//删除员工信息  	if (L.length) { 		int i; 		char num1[MAX]; 		ElemType *p = L.data, *q; 		printf("请输入员工的员工号：\n"); 		scanf("%s", num1); 		//if (!strcmp(num1, p->num))p = p->next; 		//else 		//for (i = 0; i < L.length - 1; i++) { 		for (i = 0; i < L.length; i++) { 			q = p->next; 			if (!strcmp(num1, q->num)) { 				p->next = q->next; 				L.length--; 				free(q);   //zx 				printf("删除成功\n"); 				break; 			} 			p = p->next; 		} 		if (i == L.length)printf("输入有误，员工号不存在：\n"); 	} } int main() {//主函数  	SqList L; 	int n; 	while (1) { 		printf("|******欢迎进入员工档案管理系统******|\n"); 		printf("|            1.录入员工信息          |\n"); 		printf("|            2.显示员工信息          |\n"); 		printf("|            3.查询员工信息          |\n"); 		printf("|            4.修改员工信息          |\n"); 		printf("|            5.添加员工信息          |\n"); 		printf("|            6.删除员工信息          |\n"); 		printf("|            7.统计员工信息          |\n"); 		printf("|            0.退出                  |\n"); 		printf("请输入您所选的选项（0--7）：\n"); 		scanf("%d", &n); 		if (0 == n) return 0; 		switch (n) { 		case 1: ListInit(L); break; 		case 2: PrintList(L); break; 		case 3: LocateElem(L); break; 		case 4: ListUpdate(L); break; 		case 5: ListInsert(L); PrintList(L); break; 		case 6: ListDelete(L); PrintList(L); break; 		default:printf("Enter data error!\n"); 		} 	} 	return 0; }

逻辑太有问题了，


Question: 运行时程序直接停止工作

修改如下：  #include <stdlib.h> #include <malloc.h> #include <time.h> #include <stdio.h> #include <math.h> typedef struct person { 	int age; 	int gene[32]; 	int Tc; 	struct person *link; }per; per *creat() { 	per *head, *p; 	int n = 0, i, j, k; 	//srand((unsigned)time(NULL));   //只需设置一次 	head= (per*)malloc(sizeof(per));   //头节点 	p = head; 	for (i = 0; i < 1000; i++) 	{ 		p->link = (per *)malloc(sizeof(per)); 		p = p->link; 		p->age = rand() % 32 + 1;//随机生成年龄1-32 		p->Tc = 0; 		for (j = 0; j < p->age; j++) 		{ 			//随机生成基因 			if (1 == (p->gene[j] = rand() % 2)) p->Tc++; //统计致病基因数量 		} 	} 	p->link = NULL; 	return(head); } int main() { 	per *p, *q, *head, *p1, *p2; 	FILE *fp; 	int x1, x2, x3, m, t, l, x, r; 	srand((unsigned)time(NULL)); 	//p = creat();     head = creat(); 	//head = p; 	fp = fopen("penna.txt", "w"); 	for (t = 0; t < 1000; t++)//1000个时间步   //不明白为什么要有循环？ 	{ 		p = head; 		q = p->link; 		while (q) 		{ 			if (q->age >= 32 || q->Tc >= 2) //老死||病死 			{ 				p->link = q->link; 				free(q); 				q = p; 			} 			p = q; 			q = q->link; 		}  		p = head->link; 		l = 0; 		while (p)//统计存活个数 		{ 			l++, p = p->link; 		}  		if (l >= 100000) //判断是否超环境容量 		{ 			printf("all dead"); 			break; 		} 		x = ceil((float)l / 100000 * 1000);//计算死亡率 		p = head; 		q = p->link; 		//srand((unsigned)time(NULL)); 		while (q) 		{ 			r = rand() % 1000 + 1; 			if (r < x)//满足条件则当前个体死亡 			{ 				p->link = q->link; 				free(q); 				q = p; 			} 			p = q; 			q = q->link; 		} 		p = head; 		q = p->link; 		p1 = (per *)malloc(sizeof(per));  //头节点 		p1->link = NULL; 		p2 = p1; 		while (q) 		{ 			if (q->age >= 8) 			{ 				p2->link = (per *)malloc(sizeof(per));//新个体 				p2 = p2->link; 				p2->link = NULL; 				p2->age = q->age;//复制过程 				for (m = 0; m < q->age; m++) p2->gene[m] = q->gene[m]; 				x1 = rand() % q->age;//突变过程M=2 				x2 = rand() % q->age; 				p2->gene[x1] = (!q->gene[x1]); 				p2->gene[x2] = (!q->gene[x2]); 				//p2 = head; 				//while (p2->link != 0) p2 = p2->link;//找寻链表的末尾 				//p2->link = p1;//在链表末尾加上新个体 				//p1->link = NULL; 			} 			p = q; 			q = q->link; 		} 		//把新个体添到链表的末尾 		p->link = p1->link; 		free(p1);    //释放头节点  		p = head->link, x3 = 1; 		//srand((unsigned)time(NULL)); 		while (p) 		{ 			p->gene[p->age] = rand() % 2, p->age++; 			x3++, p = p->link; 		} 		fprintf(fp, "%d\n", x3); 	} 	fclose(fp); 	return 0; }

引用 12 楼 qq_25720277 的回复:原谅我看不懂这么高深的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

请教一下我想把代码输入为 大家可以直接复制的那种样子，该怎么输入呢？

while(p->link!=NULL)  																					  { 																						  p->gene[p->age]=rand()%2,p->age++; 																						  x3++,p=p->link; 																					  } 																					  fprintf(fp,"%d\n",x3); 		  } 		                                                                             fclose(fp); } 我调试到最后这一小部分，出了acess violation的错误。查了资料，发现错误原因是访问了一块不再有效地内存，但我不知怎么改，求路过好心人指教，

原谅我看不懂这么高深的C语言。。

单步断点调试，肯定能找到问题

”写常量“是什么意思呢？

我调试过了，但是还是不行。。

凡事靠自己啊！一楼都解答了，剩下的自己找错啊！----我就是一个小白--路过此地！

点一下带<>的图标， 【code=c】将代码插入在此【/code】

引用 6 楼 qq_25720277 的回复:还有就是，我反复检查我的程序并没有发现下标越界，而且在调试时经常出现找不到变量的提示。麻烦哪位路过大神解答一下下 不要依赖调试环境，自己写日志调试。  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

谢谢，能具体一点吗

内存溢出,下标越界,写常量等...


Question: 菜鸟求助，度娘后不明所以（编译成功，运行中途停止不动） 在线等

引用 5 楼 wang0635 的回复:scanf("%d %d \n",&i,&j);   去掉 \n 引用 5 楼 wang0635 的回复:scanf("%d %d \n",&i,&j);   去掉 \n 引用 7 楼 wxymails 的回复:[quote=引用 6 楼 wt592376761的回复:]两个解决方案 （1）把 scanf("%d %d \n",&i,&j);中的\n 除掉（PS：好像scanf这类输入语句不能带转义符，\n,\t这类的）。 （2）输入的时候 输入3个数字就可以继续了。 [/quote] 谢谢各位，用你们提供的方法，已解决问题，另外第二个方法不太明白，为什么输入3个数字就可以呢？

scanf （ "非输入控制符 输入控制符"，输入参数）； 非输出控制符必须原样输入 例子:  int main() {       int num=0;       scanf("%d\n",&num);       printf("%d\n",num);       return 0; }  运行时：输入一个数字之后回车  光标停在下一行但没有出现结果   再输入\n才输出num. 用scanf 不要加入“\n”非输入控制符，系统在运行时会自动换行.

引用 6 楼 wt592376761的回复:两个解决方案 （1）把 scanf("%d %d \n",&i,&j);中的\n 除掉（PS：好像scanf这类输入语句不能带转义符，\n,\t这类的）。 （2）输入的时候 输入3个数字就可以继续了。

Turbo C或Borland C用Turbo Debugger调试  bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028

scanf("%d %d \n",&i,&j);   去掉 \n

死循环吧

我用TC编译的。

你好，修改之后，运行直接跳出。如图

首先 main（）缺少类型void   scanf换成  scanf_s #include<stdio.h>  void main() { 	int i; 	int j; 	int k; 	/*char u = 0xe3;*/ 	/* printf("insert i j ratings: \n");*/  	scanf_s("%d %d \n", &i, &j); 	printf("i,k is OK! \n"); 	k = i + j; 	printf("k = i + j. \n");  	/* printf("%d %d \n",k,(unsigned char)u);*/ 	/* printf("&i = %u;&j = %u;&k = %u \n,&i,&j,&k"); 	printf("int = %d \n",sizeof(char)); 	printf("int = %d \n",sizeof(int)); 	printf("i = %d \n",*&(char)k);*/  	/* printf("k = %d \n",&k); 	printf("k is ok !");*/ }


Question: 哪位大大帮我看下个阵列问题！谢谢先了

别忘了前面的 n++ 到取余时 n=1

这里的n,是一个计数器。当他是五的倍数时，打印换行。如果把n改为1;那么第一排应该只会打印4个数。后面的应该会5个数。所以你的10会跑到下面去吧！

常用技巧 n%5==0 n是5的倍数即可换行。 自然0也是5的倍数

每5个一换行,开始确实有个换行


Question: 如何判断数值溢出

long a; long b; long c = a + b; if (c < a)     // overflowed

楼主需要把这些东西转换为二进制然后根据结果判断结果和2个数的符号进行判断，或者通过符号位进位状态标识符CF 和 数值部分的最高位的进位标识符DF同时为1或0时，运算结果没有溢出，否则溢出，就是一个异或的关系；

一种情况是，两正数相加，结果是负数，就溢出了。可以通过符号判断。 其余情况类似

可以用long long

能不能进行预防呢 if ( m>0 && n>0 && ( LONG_MAX - m < n ) ) {  //error handling...  return;  }

这样判断不行，谁知道应该怎么做呢？


Question: C语言中没使用指针.为什么子函数改变了主函数,

数组参数相当于指针

引用 9 楼 mewiteor 的回复:[quote=引用 7 楼 zhangxiangDavaid 的回复:] [quote=引用 2 楼 mewiteor 的回复:] 形参中 int a[]就相当于int *const a 亲，这是谁说的[/quote]#include<iostream> #include<typeinfo> using namespace std; void foo(int a[3],int *const b) { 	int c[3]; 	cout<<"type of a:"<<typeid(a).name()<<endl; 	cout<<"type of b:"<<typeid(b).name()<<endl; 	cout<<"type of c:"<<typeid(c).name()<<endl; } int main() { 	int a[3]; 	foo(a,a); 	return 0; }这样可以吗？[/quote] 可以啊 但  	a = c;   //ok 	b = c;   //error

引用 9 楼 mewiteor 的回复:[quote=引用 7 楼 zhangxiangDavaid 的回复:] [quote=引用 2 楼 mewiteor 的回复:] 形参中 int a[]就相当于int *const a 亲，这是谁说的[/quote]#include<iostream> #include<typeinfo> using namespace std; void foo(int a[3],int *const b) { 	int c[3]; 	cout<<"type of a:"<<typeid(a).name()<<endl; 	cout<<"type of b:"<<typeid(b).name()<<endl; 	cout<<"type of c:"<<typeid(c).name()<<endl; } int main() { 	int a[3]; 	foo(a,a); 	return 0; }这样可以吗？[/quote]突然发现应该没有const

引用 7 楼 zhangxiangDavaid 的回复:[quote=引用 2 楼 mewiteor 的回复:] 形参中 int a[]就相当于int *const a 亲，这是谁说的[/quote]#include<iostream> #include<typeinfo> using namespace std; void foo(int a[3],int *const b) { 	int c[3]; 	cout<<"type of a:"<<typeid(a).name()<<endl; 	cout<<"type of b:"<<typeid(b).name()<<endl; 	cout<<"type of c:"<<typeid(c).name()<<endl; } int main() { 	int a[3]; 	foo(a,a); 	return 0; }这样可以吗？

指针就是干这个的。

引用 2 楼 mewiteor 的回复:形参中 int a[]就相当于int *const a没 const 什么事情  而且 如果是int *const 那么 这段代码是Error 懂伐

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  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

引用 2 楼 mewiteor 的回复:形参中 int a[]就相当于int *const a 亲，这是谁说的

引用 1 楼 lin5161678 的回复:函数参数列表写的数组都是指针的意思  这是常识.....+1,除了指针,引用也可以改变形参值

引用 2 楼 mewiteor 的回复:形参中 int a[]就相当于int *const a 吾未尝有闻。

形参中 int a[]就相当于int *const a

函数参数列表写的数组都是指针的意思  这是常识.....


Question: unsigned short 赋值给 unsigned char

运行下就知道了

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

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

PackCnt>>5; PackCnt会被提升为int，然后>>5的结果还是int，最后把这个int的结果赋值给uint8


Question: PAT1009 c语言字符串问题 我写的程序输出时起始位置会多一个空格，如何改正才能没有空格

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

每次得到一行,从行尾反向输出 是不是就可以了

大概思路应该是先写一个字符串反转函数，然后将整个字符串反转，最后再反转每个单词


Question: 关于 不定长结构体（struct）定义的问题

这个写法不是c标准定义的，所以有些编译器不支持。 http://blog.csdn.net/ce123_zhouwei/article/details/8973073 http://blog.csdn.net/code_crash/article/details/4854939

好不好不知道，反正微软的API经常这么用。

前段时间貌似看到过这个玩意儿，支持0的时候，可以很方便的进行指针代替，且不会占用内存，突然感觉这个方法好机智有木有。 不过，这种抖机灵的方法，真的好吗？   ----------------------- 个人见解


Question: 作为菜鸟的关于c的一点疑问

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

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  printf Type Field Characters  See Also  Send Feedback     The type character is the only required format field; it appears after any optional format fields. The type character determines whether the associated argument is interpreted as a character, string, or number. The types C, n, p, and S, and the behavior of c and s with printf functions, are Microsoft extensions and are not ANSI compatible.   Character  Type  Output format   c  int or wint_t  When used with printf functions, specifies a single-byte character; when used with wprintf functions, specifies a wide character.   C  int or wint_t  When used with printf functions, specifies a wide character; when used with wprintf functions, specifies a single-byte character.   d  int  Signed decimal integer.   i  int  Signed decimal integer.   o  int  Unsigned octal integer.   u  int  Unsigned decimal integer.   x  int  Unsigned hexadecimal integer, using "abcdef."   X  int  Unsigned hexadecimal integer, using "ABCDEF."   e  double  Signed value having the form [ – ]d.dddd e [sign]dd[d] where d is a single decimal digit, dddd is one or more decimal digits, dd[d] is two or three decimal digits depending on the output format and size of the exponent, and sign is + or –.   E  double  Identical to the e format except that E rather than e introduces the exponent.   f  double  Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.   g  double  Signed value printed in f or e format, whichever is more compact for the given value and precision. The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.   G  double  Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).   a  double  Signed hexadecimal double precision floating point value having the form [−]0xh.hhhh p±dd, where h.hhhh are the hex digits (using lower case letters) of the mantissa, and dd are one or more digits for the exponent. The precision specifies the number of digits after the point.   A  double  Signed hexadecimal double precision floating point value having the form [−]0Xh.hhhh P±dd, where h.hhhh are the hex digits (using capital letters) of the mantissa, and dd are one or more digits for the exponent. The precision specifies the number of digits after the point.   n  Pointer to integer   Number of characters successfully written so far to the stream or buffer; this value is stored in the integer whose address is given as the argument. See Security Note below.   p  Pointer to void  Prints the argument as an address in hexadecimal digits.   s  String   When used with printf functions, specifies a single-byte–character string; when used with wprintf functions, specifies a wide-character string. Characters are printed up to the first null character or until the precision value is reached.   S  String  When used with printf functions, specifies a wide-character string; when used with wprintf functions, specifies a single-byte–character string. Characters are printed up to the first null character or until the precision value is reached.    Note   If the argument corresponding to %s or %S is a null pointer, "(null)" will be printed.  Note   In all exponential formats, the default number of digits of exponent to display is three. Using the _set_output_format function, the number of digits displayed may be set to two, expanding to three if demanded by the size of exponent.  Security Note   The %n format is inherently insecure and is disabled by default; if %n is encountered in a format string, the invalid parameter handler is invoked as described in Parameter Validation. To enable %n support, see _set_printf_count_output.  See Also Concepts printf, _printf_l, wprintf, _wprintf_l Send feedback on this topic to Microsoft.

unsigned long index = 0; index -= 1; printf("%d\n", index);    //-1 printf("%hu\n", index);  //65535

明白了，感谢楼上两位

%d不管你实际是什么,都当int在处理

%d还是4字节的，你取到的是1111 1111 1111 1111 xxxx xxxx xxxx xxxx。x86计算机是小端的，所以如果后2字节是全0的话，显示的就是65535了。  你可以在前后各设一个short变量来验证一下（我忘了栈的方向了，不知道应该是前还是后）

%d是整型，%hd才是短整型


Question: 模拟输出排行榜的程序。在文件读写的过程中出现错误。麻烦大家帮我看一下，多谢啦

多谢你啦。我已经把程序改好了。在你的基础上做了一些修改。现在功能已经实现  引用 2 楼 zhangxiangDavaid 的回复:else 	{ 		//for (i = 1; i < NUM; i++) 		for (i = 0; i < NUM; i++) 		{ 			fgets(temp, MAX, fp);											//读文件第一行，即最高分数值  			int n = strlen(temp); 			temp[n - 1] = '\0';    //去除'\n' 			n--; 			//for (j = 0; (size_t)j < (strlen(temp)); j++)					//将数组str中的字符型数字转换成整型数字存放到数组a中  			for (j = 0; (size_t)j < n; j++) 			{ 				//str[j + 1] = (int)temp[j] - '0'; 				str[j] = (int)temp[j] - '0'; 			}  		//	sco[i] = str[i]; 			sco[i] = str[0];//此处应改为str[0] 			//for (j = 1; (size_t)j <= n; j++) 			for (j = 1; (size_t)j < n; j++)//此处不应有=，当数据只有一位的时候不乘以10. 			{ 				sco[i] = sco[i] * 10 + str[j]; 			} 		} [/code]

引用 2 楼 zhangxiangDavaid 的回复:修改如下：  int Came_Over()                          //游戏结束 { 	int i, j; 	int str[NUM] = { 0 }; 	int sco[NUM] = { 0 }; 	char temp[MAX] = { 0 }; 	int flag = 1; 	int t = 0; 	FILE *fp = NULL;  	IMAGE img;	// 定义 IMAGE 对象  				//memset(sco,0,NUM * sizeof(int));  	loadimage(&img, ("E:\\Microsoft Visual Studio\\MyProjects\\Timberman\\Timberman\\sucai\\dead.jpg"));	// 读取图片到 img 对象中 	putimage(0, 0, &img);												// 在坐标 (0, 0) 位置显示 IMAGE 对象  	setcolor(WHITE); 	setfont(60, 0, _T("黑体")); 	outtextxy(35, 190, "ＧＡＭＥ　ＯＶＥＲ");  	fp = fopen("score.txt", "rt");									//读文件 	if (NULL == fp) 	{ 		printf("文件打开失败\n"); 		return -1;//要返回错误代码 	} 	else 	{ 		//for (i = 1; i < NUM; i++) 		for (i = 0; i < NUM; i++) 		{ 			fgets(temp, MAX, fp);											//读文件第一行，即最高分数值  			int n = strlen(temp); 			temp[n - 1] = '\0';    //去除'\n' 			n--;  			//for (j = 0; (size_t)j < (strlen(temp)); j++)					//将数组str中的字符型数字转换成整型数字存放到数组a中  			for (j = 0; (size_t)j < n; j++) 			{ 				//str[j + 1] = (int)temp[j] - '0'; 				str[j] = (int)temp[j] - '0'; 			}  			sco[i] = str[0]; 			for (j = 1; (size_t)j <= n; j++) 			{ 				sco[i] = sco[i] * 10 + str[j]; 			} 		}  		//for (i = 1; (size_t)i <= (strlen(temp)); i++) 		//{ 		//	sco[i] = str[i]; 		//	for (j = i + 1; (size_t)j <= (strlen(temp)); j++) 		//	{ 		//		sco[i] = sco[i] * 10 + str[j]; 		//	} 		//}  		fclose(fp);														//关闭文件  		//if (score <= sco[10]) 		if (score <= sco[9]) 		{ 			printf("太遗憾了，没有破纪录。\n"); 		} 		else 		{ 			printf("排行榜：\t\n"); 			//sco[10] = score; 			sco[9] = score;  			for (i = 1; i <= NUM - 1 && flag; i++)   //冒泡排序 			{ 				flag = 0; 				//for (j = 1; j <= NUM - i; j++) 				for (j = 0; j < NUM - i; j++) 					if (sco[j] < sco[j + 1]) 					{ 						t = sco[j]; 						sco[j] = sco[j + 1]; 						sco[j + 1] = t; 						flag = 1; 					} 			}  			//for (i = 1; i <= 10; i++) 			for (i = 0; i < 10; i++) 			{ 				printf("%d.%d\n", i + 1, sco[i]); 			}  			fp = fopen("score.txt", "wt");										//写文件 			//for (i = 1; i <= 10; i++) 			for (i = 0; i < 10; i++) 			{ 				fprintf(fp, "%d\n", sco[i]); 			} 			fclose(fp);														//关闭文件 		} 	} 	Photo_Close(); 	getch(); 	exit(0); }    有新的问题，之前存在文件中的数据每次重新运行之后都会乘以10。而且运行3次以后。3~10会被填充为别的数字。（数字是一样的。）

你这个为什么循环里面好多数组下标都是从1开始的，你查查看是不是这个原因。


Question: 请教一个关于 char *a;char a[];char *a[]的问题

char* a; // 一个指针变量，注意:a的类型是char*,char*  才是表示指针（存放的是地址），那么a就是一个地址。*a表示取a这个地址的值。 char* a[ ]；//这个你一定很熟悉感觉，int main (int argc, char* argv[]).所以不用解释了吧。

再补充一个问题：换行符是“\n”,而不是"/n";因为\才是转义符

补充一点，打印printf 的问题，%c只是打印字符，要打印字符串需要用%s

1. char a:就是一个字符 2. char *a:就是一个指针，指针指向的是字符串 3. char a[]:就是一个字符数组 4. char* a[]:就是一个指针，指针指向的是字符串的数组。 针对这个问题： char a[9]="123456"； char *b = "4" ； a[2]=*b; printf("%c/n" , a); 为什么是124456呢？因为a[2]=*b;赋值就只是把a[2]修改了值，*b的值只是一个字符'4'； 后面理解正确。

引用 4 楼 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对应的汇编并单步执行观察相应内存和寄存器变化。）  xcode 怎么查看内存变化呢。。。我就是没找到

至少  比如 char b[5] ="1234"; 那 b[0]=1 b[1]=2 b[2]=3 b[3]=4 b[4]=\0 b[0]='1'; b[1]='2'; b[2]='3'; b[3]='4'; b[4]='\0';

引用 5 楼 birdmichael 的回复:[quote=引用 4 楼 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对应的汇编并单步执行观察相应内存和寄存器变化。）  xcode 怎么查看内存变化呢。。。我就是没找到[/quote] 搜“gdb GUI”

《c与指针》。多看书，就少了很多疑问

“”双引号的不是字符常量，那是字符串，你应该先好好把C语言字符部分的知识好好看看再来区分这几个定义的区别

我觉得差不多把！

今天，是我在这个论坛第一次发帖，也是第一次回复。。就当是开门红吧。  不知楼主有没有想过 signed char * , unsigned char * , 和 char * 的区别？可以去百度百科一下char .  还有 const * 指针，和数组名有什么联系？


Question: 关于c语言中指针和函数的一个问题

修改如下：  #include <stdio.h> void  out1(int *p, int n); void  plus1(int *p, int n); void  cpy1(int *p, int *q, int n); int main() { 	int a[10] = { 15,-12,10,-14,7,2,5,3,27,-6 }, b[10]; 	//out1(a);     	//输出数组a的所有元素 	out1(a, 10); 	//plus1(a);   	//对数组中所有的正整数分别加上??? 	plus1(a, 10); 	//cpy1(b, a);   	//将a数组所有元素复制到b数组中 	cpy1(a, b, 10); 	//out1(b); 		//输出数组b的所有元素 	out1(b, 10); 	system("pause"); 	return 0; } // 输出数组所有元素 //void  out1(int *p) void out1(int *p, int n) { 	int i = 0; 	for (i = 0; i < n; i++) 		printf("%d ", *(p + i)); } // 对数组中所有的正整数分别加上??? //void  plus1(int *p) void plus1(int *p, int n) { 	int i = 0; 	for (i = 0; i < n; i++) 	{ 		if (*(p + i) > 0) 			*(p + i) = *(p + i) + 5; 	} } //数组的复制 //void  cpy1(int *p, int *q) void cpy1(int *p, int *q, int n) { 	int i = 0; 	for (i = 0; i < n; i++) 	{ 		*(q + i) = *(p + i); 	} }

1) *p>0 这里错 2) cpy1(b,a); 其中b和a搞反了,你的实现是b->a, b本身是没初始化的 修改一个函数 void  plus1(int *p) {      for(int *pe=p+10;p<pe;p++)     {     if(*p>0) *p +=5;    } }

cpy1的参数顺序反了 另外就是楼上说的了 还有，*(p+i)很难看的，写成p[i]比较好

for(i=0;i<10;i++)    {     if(*p>0)     *(p+i)=*(p+i)+5;    }  暂时看到一个 判断*p>0肯定是不对的，应该是if(*(p+i)>0)


Question: 关于c指针问题求教，为什么输出结果全是1？

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

printf("%d\n", *(p+1)); 改成 printf("%d\n", *(p+i));

理解和讨论之前请先学会如何观察！  计算机组成原理→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

这种错误好恐怖

这个程序就是简单的实现指针的初始化吗，不知道楼主为什么要练习这个程序，不过我也是菜鸟，另外在出错之后应该好好检查的，希望对你有帮助

楼主既然搞定了，就把悬赏分砸给我吧。

我把i打打成了1


Question: 基于opengl的场景漫游，粒子系统出问题了怎么不下雨啊？求大神指教！！救命啊！！！

VC下运行的，我运行也是一堆错误，当时想知道粒子系统怎么运行的就

编译问题请说明编译环境,操作系统

楼主，你的代码要在什么环境下运行啊，我用VC++运行之后有一大堆错误啊，能否重发一下正确代码。里面有一些OpenGL的函数还不了解惹。

搜网络教程“学OpenGL编3D游戏”。

bool ChangeResolution(int w,int h,int bitdepth)   //改变屏幕分辨率 	{ 		DEVMODE devMode; 		int modeSwitch; 		int closeMode=0;  		EnumDisplaySettings(NULL, closeMode,&devMode);  		devMode.dmBitsPerPel=bitdepth; 		devMode.dmPelsWidth=w; 		devMode.dmPelsHeight=h; 		devMode.dmFields=DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;  		modeSwitch=ChangeDisplaySettings(&devMode,CDS_FULLSCREEN);  		if(modeSwitch==DISP_CHANGE_SUCCESSFUL) 		{ 			return true; 		} 		else  		{ 			ChangeDisplaySettings(NULL,0); 			return false; 		} 	}  	LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) //消息处理函数 	{ 		switch(message) 		{ 		case WM_CREATE: 		GetWindowRect(hWnd,&rect); 		sw=rect.right-rect.left; 		sh=rect.bottom-rect.top; 		SceneResizeViewport(sw,sh); 		return 0;  		case WM_SIZE: 			if(!fullscreen) 			{ 				GetWindowRect(hWnd,&rect); 				sw=rect.right-rect.left; 				sh=rect.bottom-rect.top; 				if(sw>0&&sh>0) 					SceneResizeViewport(sw,sh); 			} 			else 			{ 				SceneResizeViewport(GetSystemMetrics(SM_CXSCREEN), 									GetSystemMetrics(SM_CYSCREEN)); 			} 			return 0; 		 		case WM_CLOSE: 			ShowWindow(hWnd,SW_HIDE); 			PostQuitMessage(0); 			return 0;  		case WM_DESTROY: 			return 0;  		case WM_KEYDOWN: 			switch(wParam) 			{ 			case VK_ESCAPE: 				PostMessage(hWnd,WM_CLOSE,0,0); 				break; 			case VK_PRIOR: //page up 				lookupdown -= 1.0f; 				break; 			case VK_NEXT:  //page down 				lookupdown +=1.0f; 				break; 			case VK_UP://////// 					xpos -=q* (float)sin(heading*piover180)*0.5f; 					zpos -=q* (float)cos(heading*piover180)*0.5f; 				//	if (walkbiasangle>=359.0f){walkbiasangle=0.0f;} 				//	else {walkbiasangle+=10;} 				//	walkbias=(float)sin(walkbiasangle*piover180)/20.0f; 				break; 			case VK_DOWN:///// 					xpos +=q* (float)sin(heading*piover180)*0.5f; 					zpos +=q* (float)cos(heading*piover180)*0.5f; 				//	if (walkbiasangle<=1.0f){walkbiasangle=359.0f;} 				//	else {walkbiasangle-=10;} 				//	walkbias=(float)sin(walkbiasangle*piover180)/20.0f; 				break; 			case VK_RIGHT:///////////// 				heading -=2.0f; 				yrot = heading; 				break; 			case VK_LEFT: 				heading +=2.0f; 				yrot = heading; 				break; //////////-----XY轴旋转 			case 'A':   					xup +=q* (float)cos(-heading*piover180)*0.25f; 					zup +=q* (float)sin(-heading*piover180)*0.25f;				 				break; 			case 'D':  //y 					xup -=q* (float)cos(-heading*piover180)*0.25f; 					zup -=q* (float)sin(-heading*piover180)*0.25f;		 				break; 			case 'W':  //y上 				yup -=q*0.4f; 				break; 			case 'S':  //y下 				yup +=q*0.4f; 				break; ////////////////////////////////////// 			case 'B': 				if(!bp) 				{ 					bp=TRUE; 					blend=!blend; 					if(blend) 					{ 						glEnable(GL_BLEND);			//打开混合功能 						glDisable(GL_DEPTH_TEST);	//关闭深度测试 					} 					else 					{ 						glDisable(GL_BLEND);		//关闭混合功能 						glEnable(GL_DEPTH_TEST);	//打开深度测试 					} 				} 					else  					{ 						bp=FALSE; 					} 					break; //////////------路灯开关------------ 			case 'G': 				if(!goodlight) 				{ 					goodlight=TRUE; 				} 				else  				{ 					goodlight=FALSE; 				} 				break; //////////-----透明开关------------ 			case 'L': 				if(!lp) 				{ 					lp=TRUE; 					light=!light; 					if(!light) 					{ 						glDisable(GL_LIGHTING); 					} 					else 					{ 						glEnable(GL_LIGHTING); 					} 				} 				else 				{ 					lp=FALSE; 				} 				break; 			} 			return 0; 			case WM_LBUTTONDOWN:          //是否按下鼠标左键 				{ 					bRender=!bRender; 					return 0; 				}  			default: 				return DefWindowProc(hWnd,message,wParam,lParam); 		}  	} GLvoid KillGLWindow(GLvoid)								 	{ 		if (fullscreen)										 		{ 			ChangeDisplaySettings(NULL,0);					 			ShowCursor(TRUE);								 		}  		if (hRC)											 		{ 			if (!wglMakeCurrent(NULL,NULL))					 			{ 				MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 			}  			if (!wglDeleteContext(hRC))						 			{ 				MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 			} 			hRC=NULL;									 		}  		if (hDC && !ReleaseDC(hWnd,hDC))				 		{ 			MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 			hDC=NULL;										 		}  		if (hWnd && !DestroyWindow(hWnd))					 		{ 			MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 			hWnd=NULL;									 		}  		if (!UnregisterClass("OpenGL",hInstance))			 		{ 			MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 			hInstance=NULL;									 		} 	}

GLvoid glDrawCube()					// 绘制立方体 { 		glBegin(GL_QUADS);			 		// 前面 		glNormal3f( 0.0f, 0.0f, 1.0f);		 		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	 		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	 		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	 		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	 		// 后面 		glNormal3f( 0.0f, 0.0f,-1.0f);		 		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	 		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	 		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	 		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	 		// 上面 		glNormal3f( 0.0f, 1.0f, 0.0f);		 		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	 		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	 		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	 		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	 		// 下面 		glNormal3f( 0.0f,-1.0f, 0.0f);		 		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	 		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	 		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	 		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	 		// 右面 		glNormal3f( 1.0f, 0.0f, 0.0f);		 		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	 		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	 		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	 		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	 		// 左面 		glNormal3f(-1.0f, 0.0f, 0.0f);		 		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	 		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	 		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	 		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	 	glEnd();					 }  //天空盒的函数实现 void skybox() { glBindTexture(GL_TEXTURE_2D, texture[30]);//南 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, -50.0f, 50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( -50.0f, -50.0f, 50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( -50.0f, 50.0f, 50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 50.0f, 50.0f, 50.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[1]);//东 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 50.0f, -50.0f, 50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 50.0f, 50.0f, 50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 50.0f, 50.0f, -50.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[2]);//北 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( -50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 50.0f, 50.0f, -50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( -50.0f, 50.0f, -50.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[3]);//西 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( -50.0f, -50.0f, 50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( -50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( -50.0f, 50.0f, -50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( -50.0f, 50.0f, 50.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[4]);//底 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( -50.0f, -50.0f, -50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( -50.0f, -50.0f, 50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 50.0f, -50.0f, 50.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[5]);//顶 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, 50.0f, 50.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( -50.0f, 50.0f, 50.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( -50.0f, 50.0f, -50.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 50.0f, 50.0f, -50.0f); glEnd(); } void EnableOpenGL() { 	PIXELFORMATDESCRIPTOR pfd; 	int iFormat;  	hDC=GetDC(hWnd);  	ZeroMemory(&pfd,sizeof(pfd)); 	pfd.nSize=sizeof(pfd); 	pfd.nVersion=1; 	pfd.dwFlags= PFD_DRAW_TO_WINDOW | 				 PFD_SUPPORT_OPENGL | 				 PFD_DOUBLEBUFFER; 	pfd.iPixelType=PFD_TYPE_RGBA; 	pfd.cColorBits=16; 	pfd.cDepthBits=16; 	pfd.iLayerType=PFD_MAIN_PLANE;  	iFormat=ChoosePixelFormat(hDC,&pfd);  	SetPixelFormat(hDC,iFormat,&pfd);  	hRC=wglCreateContext(hDC); 	wglMakeCurrent(hDC,hRC); }  //取消OPENGL void DisableOpenGL() { 	wglMakeCurrent(NULL,NULL); 	wglDeleteContext(hRC); 	ReleaseDC(hWnd,hDC); 		if (fullscreen)										 	{ 		ChangeDisplaySettings(NULL,0);					 		ShowCursor(TRUE);								 	}  	if (hRC)											 	{ 		if (!wglMakeCurrent(NULL,NULL))					 		{ 			MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 		}  		if (!wglDeleteContext(hRC))						 		{ 			MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 		} 		hRC=NULL;									 	}  	if (hDC && !ReleaseDC(hWnd,hDC))				 	{ 		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 		hDC=NULL;										 	}  	if (hWnd && !DestroyWindow(hWnd))					 	{ 		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 		hWnd=NULL;									 	}  	if (!UnregisterClass("OpenGL",hInstance))			 	{ 		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 		hInstance=NULL;									 	}   }

void SceneInit (int w,int h) {	 	LoadGLTextures();			//条到处理调用位图并用此位图建立纹理的子程序 	glEnable(GL_TEXTURE_2D);	//纹理被创建，并允许2D纹理贴图  	glShadeModel(GL_SMOOTH); 	glClearColor(0.0,0.0,0.0,0.5); 	glClearDepth(1.0f); 	glEnable(GL_DEPTH_TEST); 	glDepthFunc(GL_LEQUAL); 	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 	//设置光源参数 	glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);		//设置环境光 	glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);		//设置漫反射光 	glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);		//光源的位置 	glEnable(GL_LIGHT1);								//允许光源一  	glColor4f( 1.0f, 1.0f, 1.0f, 0.5);					//全亮度，50%的透明 	glBlendFunc(GL_SRC_ALPHA,GL_ONE);					//基于半透明的混合方式 } void SceneResizeViewport(GLsizei w, GLsizei h) { 	if(h==0) 	{h=1;} 	aspect=(GLfloat)w/(GLfloat)h; glViewport(0,0,w,h); 	glMatrixMode(GL_PROJECTION);						//选择投影句镇 	glLoadIdentity(); gluPerspective(45.f,aspect,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } ///////////////这里进行说有的绘图工作//////////////////////////////////////// int SceneShow(GLvoid) { 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	//清屏和清除深度缓冲区 	glLoadIdentity();									//重置当前MODELVIEW矩阵 	glDisable(GL_BLEND); 	glDisable(GL_COLOR_BUFFER_BIT); 	glEnable(GL_TEXTURE_2D); GLfloat xtrans=-xpos; GLfloat ztrans=-zpos; 	GLfloat ytrans=-0.25f; 	GLfloat sceneroty=360.0f-yrot; 	//开始绘图     //开始绘图    glRotatef(lookupdown,1.0f,0,0);					//X旋转    glRotatef(sceneroty,0,1.0f,0);					//y旋转    skybox();    glTranslatef(xtrans+xup,ytrans+yup,ztrans+zup);	//移动    	//-------------------------------------------------------------------- 	if(keys[VK_TAB]) 	{ 	glBindTexture(GL_TEXTURE_2D,texture[22]);//绘制雨滴粒子 	 	for(int i=SOURCE/2;i<SOURCE;i++) 	{ 		for (loop=(i)*(MAX_PARTICLES/SOURCE);loop<(i+1)*(MAX_PARTICLES/SOURCE);loop++)					 		{ 			if (particle[loop].active)							 			{ 				float x=particle[loop].x=-25+(i-SOURCE/2)*(100/SOURCE);					 				float y=particle[loop].y+40;					 				float z=particle[loop].z+zoom;				  				 				glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);  				glBegin(GL_TRIANGLE_STRIP);						 				glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); 				glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); 				glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);  				glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); 				glEnd();										  				particle[loop].x+=particle[loop].xi/(slowdown*1000); 				particle[loop].y+=particle[loop].yi/(slowdown*1000); 				particle[loop].z+=particle[loop].zi/(slowdown*1000);  				particle[loop].xi+=particle[loop].xg;		 				particle[loop].yi+=particle[loop].yg;			 				particle[loop].zi+=particle[loop].zg;			 				particle[loop].life-=particle[loop].fade;		  				if (particle[loop].life<0.0f)				 				{ 					particle[loop].life=1.0f;					 					particle[loop].fade=float(rand()%100)/FADE+0.002f;	 					particle[loop].x=0.0f;						 					particle[loop].y=0.0f;						 					particle[loop].z=0.0f;						 					particle[loop].xi=xspeed+float((rand()%60)-32.0f); 					particle[loop].yi=yspeed+float((rand()%60)-30.0f);	 					particle[loop].zi=float((rand()%60)-30.0f); 					particle[loop].r=colors[0];			 					particle[loop].g=colors[1];			 					particle[loop].b=colors[2];			 				}  			} 				 			} 		} 	} return TRUE;											 }


Question: 我想问一个关于C语言的复制操作问题

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

vc下，选中size_t 按f12，即可看到 typedef unsigned int     size_t;

你这个一次打开，不会那样的

把经典书籍先看完吧。一切都懂哦了

那个 有OC和C的大神吗？，可以留个联系方式，带一下我这个小菜鸟吗？ 学海无涯 达者为师~


Question: 求救，程序写好后出了些问题，先是提示有堆问题，后来修改了下，就直接运行不了

引用 7 楼 qq_28917617 的回复:   这个地方错误，既然已经free（current），那么current=current->next还有什么意义。 谢谢，看到后马上去试了试，确实删掉之后不会有运行错误跳出来，不过这里我是按照书上的来写得，几乎跟书上一样，待会我去试试书上的程序会不会出现同样的错误。另外最后还是没有运行出我想要的结果~直接跳过了hashtab内容的输出~待会我再去调试下~ 谢谢这位朋友能把我打得这么乱的代码都看完，而且我还已经结贴了的情况下

调试才是王道，就算这次别人给你找到了错误，下次你还是不知道怎么解决问题。学学调试吧

楼上正解

哈哈~好的~谢谢各位啦~接下来我再自己一点点去调试看看问题出在哪了吧~基本功不扎实也是我的大问题~毕竟现学现卖~我再去研究下好了~谢谢啦~~

~每段和每句代码的意思我倒是清楚的……不过没看出来那里出现了问题，不是语法错误，所以应该是逻辑错误了，我这里有些代码可能写的不合适，或者表达上有问题，或者申请内存时出了问题什么的……不过我是最近自己自学然后一点点写的，因为要交了，所以基本功不是很扎实……有些逻辑问题或者申请内存没成功啥的，我看不太出来，所以才想请教下，至少有个方向的话我也知道该去哪里找相关资料看了，然后补充语句上去，如果是逻辑问题= = 我检查了下……在我的理解中应该就这样写才对啊……结构的部分跟书对了对也没差啊…………   不过我今天还会再去自己先检查下~ 所以才来请教下基础比我扎实很多的各位，谢谢啦~

自己写的每一行代码，自己反而不清楚是什么意思，有些莫名其妙


Question: C语句解析

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

装B的写&0x1F 呆萌的写%0x20 屌丝们写%32

引用 2 楼 zhangxiangDavaid 的回复:取数组名为 CHADResult 下标是ChndataTmp.CHStatus&0x1F 的成员变量CHStatus 的地址 zhangxiangDavaid老师的解答还是很准确的。

引用 3 楼 zhongel 的回复:明白了，谢谢。另外问一下，以下这句是ChndataTmp的成员变量与上0x1F的意思吗？ ChndataTmp.CHStatus&0x1F 这得看你的逻辑。 粗略看&1F保留了ChndataTmp.CHStatus二进制位的最小5位，对吗？

&( ( CHADResult[ (ChndataTmp.CHStatus) & 0x1F ] ).CHStatus )


Question: 求解：内存泄漏的原理(汇编角度)

Linux下，malloc和free是开源的。

《30天自制操作系统》内存管理

学了操作系统就应该理解起来比较容易

引用 2 楼 zhangxiangDavaid 的回复:未被释放，即是被占用，如何被分配第二次。一个坑，一个萝卜。 所以释放后，才有可能再次被分配。 表面上是这样解释的，我只是想知道本质，物理上内存是不可能消失的， 即“未被释放”、“分配”的本质的是啥意思，

不懂汇编，不会从汇编角度解释

上面错别字"请问为什么，为释放的堆内存，我下载再用malloc不" 应该是"请问为什么，未释放的堆内存，我下次再用malloc不"

内存泄漏：进程长期占用不使用的内存 进程结束OS会释放所以内存。

厕所里面有十个坑，但是这十个坑都写着有人在拉屎（其实里面没有一个人，有人故意恶作剧），来一个人看着满了，来一个发现还是满的。阿姨打扫卫生才让他们恢复过来。。。。

跟汇编没有关系，操作系统管理着空闲内存，有登记。入住之后，不退房，别人就不能再用。