Question: 莫名其妙的问题，急求帮助

而之后的FPrt(FILE * &Data, CT * TP)函数里传送的是错误指针，但是实际上文件正确建立，并且无报错，文件指针顺利传送回去可以使用。

E:ClientData.txt 到打开文件时fopen函数内部参数的值，出奇了，竟然顺利打开不报错

引用 12 楼 RACHETIME 的回复:在赋值字符串之前和全局初始化一致为0000.......  当然看之后了，另外你好奇可以跟到fopen函数内，看怎么执行的

在赋值字符串之前和全局初始化一致为0000.......

引用 10 楼 RACHETIME 的回复:。。。没办法我这人太钻牛角尖了。。数组我初始化为0，但是模块直接在空指针的情况下进入，文件不存在，换成其他盘符就不行了，唯独E盘可以，这是编译器的问题还是windows7的bug呢，的确值得研究啊。  你一步一步跟踪，看路径字符串里存的是什么

之前那段代码在之下这个运行之后就直接进入了  #define OK 1//状态宏 #define ERROR  0//状态宏 typedef int Status;//状态宏  typedef struct Client//单个客户的链表结构体节点 { 	char PhoneNumber[12];//手机号码 	char Price[6];//价格 	int Time;//相对时间 	struct Client * next;//存放下一结点地址 }CT;//重命名 typedef struct AssList//用于解决单链表下表问题快速排序存放链表地址的结构体，动态分配节点个后进行快排 { 	struct Client * AssClient;//存放单链表结构体 }AL;  //功能函数 Status Cybernetics(void);//菜单OK CT * LoadData(FILE * &Data);//第一次载入按时间排序的客户文件信息OK CT * AddToData(FILE * &Data, CT * Server);//追加文件OK CT * InsertInf(FILE * &Data, CT * Server);//手动插入数据多选择OK CT * DeleteTHP(FILE * &Data, CT * Server);//删除最高价，对文件修改OK void UriResult(CT * Server, int Amount);//根据产品数量决定竞价结果OK void SerTop(CT * Server);//查询当前最高价格OK  //工具函数 CT * InsertSort(AL * &AssList, FILE * &Data, int Low, int High, CT *Key);//对插入信息进行折半排序插入OK CT * FastSort(AL * &AssList, FILE * &Data, int Time);//对文件载入快速排序OK Status AssFS(AL * &AssList, int Left, int Right);//快速排序主体函数OK void GiAss(AL * &AssList, CT * TP);//给数组AssList赋值 void CloList(AL * &AssList, int Count);//连接链表 Status CompChP(CT * &AssListP, CT * BssListP);////比较函数隐含条件 > 号大于返回1，小于-1，相等时间大 0 、 小 2 OK void FPrt(FILE * &Data, CT * TP);//文件写入 int ROrt(FILE * &Data, CT * TP, int Time);//文件读出 void Color(int Optional);//1红，2绿，3黄，4蓝Color();  char  FileServer[100] = {0}; //用于存放绝对路径，路径以后可以随时使用方便  //功能函数 Status Cybernetics(void)////菜单 { 	FILE * Data = NULL;//文件复用指针 	CT * Server = NULL;//数据操作单链表 	int Optional;//选项 	int Amount = 0;  	while(1) 	{ 		Color(2); 		puts("\n\n\n\t============================================================"); 		Color(3); 		puts("\t 1. 第一次载入按时间排序的客户文件信息.\t2. 手动添加用户信息\n"); 		puts("\t 3. 删除最高价，对文件修改.            \t4. 追加文件\n"); 		puts("\t 0. 退出系统                           \t5. 统计得奖名单.\n"); 		puts("\t 6. 查询当前报价."); 		Color(2); 		puts("\t============================================================"); 		Color(3); 		printf("\t输入选项(0 ~ 1):"); 		Color(1); 		scanf("%d", &Optional);//输入选项 		Color(3); 		switch(Optional) 		{ 		case 0: 			if(Data != NULL) fclose(Data);//退出系统前关闭文件,至少打开过一次 			exit(0);//退出系统  			break; 		case 1: 			if(Data == NULL)//防止重复录入文件 			{ 				if(Server = LoadData(Data))//判断是否录入成功 				{ 					puts("\t录入成功."); 					Color(4); 					printf("\t当前最高价为:%s %s\n", Server->PhoneNumber, Server->Price); 					Color(3); 				} 				else 				{ 					puts("\t录入失败."); 				} 			} 			else 			{ 				puts("\t已经录入文件，是否追加."); 				AddToData(Data, Server); 			} 			break;//第一次录入文件后返回操作单链表 		case 2: 			Server = InsertInf(Data, Server); 			break; 		case 3: 			if(Server != NULL) 			{ 				Server = DeleteTHP(Data, Server);//删除最高价，对文件修改 			} 			else 			{ 				puts("\t未录入数据，请先录入."); 			} 			break; 		case 4: 			if(Server != NULL) 			{ 				Server = AddToData(Data,Server); 			} 			else 			{ 				puts("\t还未录入数据，请录入数据."); 			} 			break; 		case 5: 			if(Server != NULL) 			{ 				printf("\t请输入产品量:");                 Color(1); 				scanf("%d", &Amount); 				Color(3); 				UriResult(Server, Amount); 			} 			else 			{ 				puts("\t还未录入数据请先录入数据!"); 			} 			break; 		case 6: 			SerTop(Server); 			break; 		default: 			printf("\t您的输入有误,重新输入!");  		}  		getchar();//用与使屏幕停顿，防止直接清屏 		getchar(); 		system("CLS");//清屏 	}  }

引用 6 楼 RACHETIME 的回复:puts("\t当前生成文件保存于 E:\ClientData.txt 中\n");  strcpy(FileServer, "E:\ClientData.txt");  Data = fopen(FileServer, "w+");//以清除全部的方式打开文件 FPrt(Data, Server);  Color(4);  这里我是为了防止程序第一次录入文件为空导致出错直接生成文件，但是这里竟然转义字符问题失效，而且仅限于我的E盘符。文件结构体指针之前的指针为空，这是让我感觉莫名其妙的地方，什么时候语法也可以变得这么模棱两可了。  字符串中要 \\ 才表示实际的 \  ， 不要浪费精力去研究错误，错误可能带来各种结果，包括你希望的与不希望的 如果想分析原因，可以单步调试，观察变量里存成什么了，不过这种研究没意义，楼主记得要用两个就行了

补充一下编译环境VS2010，论坛没法发送附件所以完整程序没法发了大概有1000行左右一发浏览器就挂了。

嗯，的确是转义字符问题。但是我再上传另一个程序吧，这个里面有段代码竟然在无文件存在情况下 \  也可以通过。 CT * InsertInf(FILE * &Data, CT * Server)//手动插入数据多选择 { 	if(Server) 	{ 		Color(4); 		printf("\n\t当前最高报价为:%s %s\n", Server->PhoneNumber, Server->Price); 		Color(3); 		int Optional = 0; 		AL * AssList;//用于存放排序连续内存首地址 		CT * TP;//链表辅助指针 		int Count;//用于计算链表长度以确定辅助内存空间  		while(1) 		{ 			printf("\t是否插入多条信息(>=2), 输入1多条，2单条,0退出:"); 			Color(1); 			scanf("%d", &Optional); 			Color(3); 			if(Optional == 1) 			{ 				puts("\t输入-1 -1 则停止录入."); 				while(1) 				{ 					TP = Server; 					for(Count=1; TP->next != NULL; Count++) TP = TP->next;//计算节点个数，并且将TP移动到最后一个节点 					TP = (CT *)malloc(sizeof(CT)); 					TP->next = NULL; 					TP->Time = Count;//加入相对时间 					getchar(); 					printf("\t请输入手机 号码 价格:"); 					Color(1); 					scanf("%s%s", TP->PhoneNumber, TP->Price); 					Color(3); 					if(strcmp(TP->PhoneNumber, "-1") != 0) 					{ 						AssList = (AL *)malloc(sizeof(AL) * Count); 						GiAss(AssList, Server); 						Server = InsertSort(AssList, Data, 0, Count, TP);//折半插入 ///可用ftell函数代替一下操作  						fclose(Data); 						Data = fopen(FileServer, "w+");//以清除全部的方式打开文件 						FPrt(Data, Server); 						free(AssList); 					} 					else if(strcmp(TP->PhoneNumber, "-1") == 0) 					{ 						free(TP); 						break; 					} 				} 				Color(4); 				printf("\t当前最高报价为:%s %s\n", Server->PhoneNumber, Server->Price); 				Color(3); 				rewind(Data); 				return Server; 			} 			else if(Optional == 2) 			{ 				TP = Server; 				for(Count=1; TP->next != NULL; Count++) TP = TP->next;//计算节点个数，并且将TP移动到最后一个节点 				TP = (CT *)malloc(sizeof(CT)); 				TP->next = NULL; 				TP->Time = Count;//加入相对时间 				getchar(); 				printf("\t请输入手机 号码 价格:"); 				Color(1); 				scanf("%s%s", TP->PhoneNumber, TP->Price); 				Color(3); 				AssList = (AL *)malloc(sizeof(AL) * Count); 				GiAss(AssList, Server); 				Server = InsertSort(AssList, Data, 0, Count-1, TP);//折半插入 ///可用ftell函数代替一下操作  				fclose(Data); 				Data = fopen(FileServer, "w+");//以清除全部的方式打开文件 				FPrt(Data, Server); 				Color(4); 				printf("\n\t当前最高报价为:%s %s\n", Server->PhoneNumber, Server->Price);  				rewind(Data); 				free(AssList); 				return Server; 			} 			else if(Optional == 0) 			{ 				return Server; 			} 			else 			{ 				puts("\t您的输入有误重新输入."); 			} 		} 	} 	else 	{ 		while(1) 		{ 			int Optional; 			printf("\t您的录入信息为空，是否开始手动录入，1是，0否:"); 			Color(1); 			scanf("%d", &Optional); 			Color(3); 			if(Optional == 1) 			{ 				AL * AssList;//用于存放排序连续内存首地址 				CT * TP, * TPN;//链表辅助指针 				int Count = 0;//用于计算链表长度以确定辅助内存空间  				puts("\t输入-1 -1 则停止录入."); 				Server = (CT *)malloc(sizeof(CT)); 				TP = Server; 				strcpy(TP->PhoneNumber, "0"); 				while(strcmp(TP->PhoneNumber, "-1") != 0) 				{ 					printf("\t请输入手机 号码 价格:"); 					Color(1); 					scanf("%s%s", TP->PhoneNumber, TP->Price); 					Color(3); 					TP->Time = Count; 					TP->next = NULL;  					if(strcmp(TP->PhoneNumber, "-1") != 0) 					{ 						TPN = (CT *)malloc(sizeof(CT)); 						TP->next = TPN; 						TPN = TP; 						TP = TP->next; 						Count++; 					} 				} 				if(Count > 0) 				{ 					TPN->next = NULL; 					free(TP);  					AssList = (AL *)malloc(sizeof(AL) * Count); 					GiAss(AssList, Server); 					Server = FastSort(AssList, Data, Count-1);  				 puts("\t当前生成文件保存于 E:\ClientData.txt 中\n"); 					strcpy(FileServer, "E:\ClientData.txt"); 					Data = fopen(FileServer, "w+");//以清除全部的方式打开文件 					FPrt(Data, Server); 					Color(4); 					printf("\n\t当前最高报价为:%s %s\n", Server->PhoneNumber, Server->Price); 					Color(3); 					free(AssList); 					rewind(Data); 					return Server; 				} 				else 				{ 					free(Server); 					return NULL; 				} 				return Server; 			} 			else if(Optional == 0) 			{ 				return NULL; 			} 			else 			{ 				puts("您的输入有误重新输入."); 			} 		}  	} }

GenList函数放到main上面 要两个\\是因为\是转义字符，两个\\才表示实际的\

楼上两位都说的对着，我自己也试了下，对着。  #include <stdio.h>  #include <time.h> #include <stdlib.h> #include <string.h> //#include"PressTest.h"  FILE * GenList(void);//生成文件 int main(void) { 	FILE * TF; 	TF = GenList(); 	return 0; }   FILE * GenList() { 	char FileS[100]; 	FILE * TF = NULL; 	int ID; 	strcpy(FileS, "D:\\test.txt"); 	TF = fopen(FileS, "w+");  	srand((unsigned)time(NULL)); 	for(ID=0; ID<3000; ID++) 	{ 		fprintf(TF, "%d %d", ID, rand() % 9999); 		if(ID < 2999) fputc('\n', TF); 	} 	rewind(TF); 	return TF; }  （1)strcpy(FileS, "D:\\test.txt");为什么要多一个“\”呢？ （2）函数声明要放在函数调用之前。

很明显，函数作用域问题，把FILE * GenList(void);//生成文件放到main函数上边

strcpy(FileS, "D:\\test.txt");


Question: 有没有一种方法能够不经过驱动程序直接向USB接口输出数据呢？？？

楼主现在弄得怎么样了？可否借鉴下？我现在遇到了同样的问题，想和你交流一下，QQ1628711961

遇到同样问题，能交流下吗？QQ525393212

引用 楼主 u012666501 的回复:萌新不懂底层开发，目前被领导要求鼓捣一台赛默飞世尔的近红外光谱仪，遇到不明白的问题了，希望论坛大神能够帮帮我。        问题描述：我需要开发一个操作仪器的应用程序，但是最关键的设备驱动程序API设备生产厂家拒绝提供，原因是希望我们使用他们配套设备出售的软件。                            所以现在我需要在没有驱动程序API的情况下操作设备了。怎么看都是不可能的事情。所以我现在尝试绕过驱动层，直接模拟配套软件在控制设备的过程中USB口上流过的数据来达到控制设备的目的。                            各位大神们，有没有方法能够让我直接向一个USB接口发送数据？？而不是Createfile之后在使用Writefile和Readfile或是Controldevice和驱动程序交互。当然由于驱动程序还是存在的所以Createfile能够成功拿到设备控制句柄。   剩下的就100分了，不成敬意   楼主现在弄得怎么样了？可否借鉴下？

顶一下，我公司现在也有相同的需求，让我做……看了厂商的驱动，本来想要不要自己写一个驱动上去……上面告诉我尽量不要动驱动的东西，因为只是做一个测试的程序

引用 12 楼 kuyucman 的回复:你不是破解了他们的协议吗 我所知道的只是，驱动程序和设备之间交互的信息格式，也就是USB口上流过的数据。

你不是破解了他们的协议吗

引用 10 楼 kuyucman 的回复:我之前是通过USB设备连接后找注册表的变化，来确定USB设备的名称，然后createFile进行IO  可以尝试用下libusb库 我现在USB设备的连接和获取控制句柄已经不成问题，现在就是不知道驱动程序的API，导致我不能控制设备，不能和设备交互

你现在和 USB 的关系不大了，除非你没有解析出 USB 使用的端口等等。 USB 很多的端口，硬件在报告的时候，不告诉你使用的是什么接口，什么端口。 只要争取了就可以和设备通信。  但是， API 的提供的功能，还需要对这些 API 的参数进行打包到 InBuffer。 然后使用 USB 的通信功能传输到设备，然后设备接收到数据，根据你的函数代码，解析出InBuffer 数据。 设备动作后返回结果给你。  你看看 LastError 是否是不正确的函数。

这个就是设备的函数代码，驱动和设备根据这个函数代码来执行不同的函数。 你可以理解为函数名。 你不是已经解析了协议了吗？ 协议的第一个就是这个，没一个功能对应一个，而且没有函数代码都有自己的缓冲区内容的解析和填充方式。

引用 9 楼 Saleayas 的回复:举个简单的例子，比如说，有一个 API，她会点亮设备上的 LED 灯。 这个 API 的参数就是 LED 灯的序号，返回点亮灯的颜色。  此时这个 API 其实很简单，就是通过 USB 传输参数到设备，然后设备动作并返回数据。 如果你对 API 的协议很清楚，那么就可以直接写一个同样的 API，甚至于你可以把这个 API 的动作写在你的程序中。 但是你需要确实知道 API 的协议，比如说如何初始化，函数代码，也就是功能号，缓冲区大小。  如果返回失败，看看 lastError. 我突然发现一个严重的问题，那就是调用deviceiocontrol时候的第二个参数dwIoControlCode我不知道，之前我设置为0 ，结果调用失败，也许就是这个原因，但是要获取这个参数的正确输入好像根本不可能，它的宏定义较为复杂；这样我是不是应该收工不干了？？根本干不了。  网上的朋友们说叫我使用winusb.sys这个东西去开发，不知道可行不可行

驱动是绕不过去的坎  你需要的是了解设备如何工作的 调用设备驱动的哪些功能

引用 6 楼 Saleayas 的回复:既然你已经有与硬件的协议，那么很简单。 自己写一个封装就可以了。 因为 USB 驱动是系统的。 使用 CreateFile 打开 USB 端口。 使用 WriteFile/ReadFile 或者 DeviceIOControl 和硬件通讯就可以了。 很具协议中的功能函数号实现你需要的 API。 她们的提供的 API 也是这样开发的。 我在和你确认一下啊，我现在拥有的东西，第一是设备驱动程序已经安装好了，系统能够识别设备，只是缺少应用程序可调用的驱动程序API；第二，我已经通过监听USB口上流过的数据，完整的逆推除了驱动程序和设备交互的协议格式。  在这种情况下，按照你说的方法真的能够实现？？？？ 顺便提一下，之前我试过这个方法，其中Createfile方法能够成功的拿到设备控制句柄，但是在使用writefuke或是devicecontrol向设备写入数据的时候却返回false。现在不知道问题处在什么地方

引用 4 楼 u012666501 的回复:[quote=引用 3 楼 user-7 的回复:] [quote=引用 2 楼 u012666501 的回复:] [quote=引用 1 楼 user-7 的回复:] 前年我做过类似的事情，用device monitoring studio截取了设备和PC之间的报文，然后逆向分析出了要用到部分协议和账号密码，要逆向出完整的协议是几乎不可能的，除非协议特别简单功能特别少。 我已经逆推出完整的协议，协议为明文格式的XML文档，可以说只要能够发送数据就应该能够完成了，求直接向USB口发送数据的方式。[/quote]  那只能自己做一个驱动了，跟自己的驱动通信[/quote] 不能直接往USB接口写数据吗？？不经过驱动，我只要求直接往接口发送数据[/quote]  usb有20个大类的设备，每个大类里面可能还有几个小类，你不用驱动去做些初始化和转换，操作系统怎么知道你的设备是哪个类型的，又该如何工作？驱动是绕不过去的，可以用别的驱动代替厂家的驱动，但是不能没有驱动。

引用 3 楼 user-7 的回复:[quote=引用 2 楼 u012666501 的回复:] [quote=引用 1 楼 user-7 的回复:] 前年我做过类似的事情，用device monitoring studio截取了设备和PC之间的报文，然后逆向分析出了要用到部分协议和账号密码，要逆向出完整的协议是几乎不可能的，除非协议特别简单功能特别少。 我已经逆推出完整的协议，协议为明文格式的XML文档，可以说只要能够发送数据就应该能够完成了，求直接向USB口发送数据的方式。[/quote]  那只能自己做一个驱动了，跟自己的驱动通信[/quote] 不能直接往USB接口写数据吗？？不经过驱动，我只要求直接往接口发送数据

引用 2 楼 u012666501 的回复:[quote=引用 1 楼 user-7 的回复:] 前年我做过类似的事情，用device monitoring studio截取了设备和PC之间的报文，然后逆向分析出了要用到部分协议和账号密码，要逆向出完整的协议是几乎不可能的，除非协议特别简单功能特别少。 我已经逆推出完整的协议，协议为明文格式的XML文档，可以说只要能够发送数据就应该能够完成了，求直接向USB口发送数据的方式。[/quote]  那只能自己做一个驱动了，跟自己的驱动通信

引用 1 楼 user-7 的回复:前年我做过类似的事情，用device monitoring studio截取了设备和PC之间的报文，然后逆向分析出了要用到部分协议和账号密码，要逆向出完整的协议是几乎不可能的，除非协议特别简单功能特别少。 我已经逆推出完整的协议，协议为明文格式的XML文档，可以说只要能够发送数据就应该能够完成了，求直接向USB口发送数据的方式。


Question: c语言实验   求大神解释


Question: 有大神吗？求帮忙

为什么输入文件路径后显示无法打开

学会看错误提示：  f 函数中 str变量没有声明  另外他提示'fp' 变量声明了没被引用，不过这只是一个警告而已

这样改 #include<stdio.h> #include<string.h> #include<stdlib.h> int main()//定义主函数 { 	int f(char file[]);//声明函数 	FILE *fp; 	char file1[50],file2[50]; 	printf("请输入所用的文件名："); 	scanf("%s,%s",file1,file2);//输入两个文件名 	f(file1);//执行函数 	f(file2); 	if(f(file1)==f(file2)) 		printf("这两个同学存在抄袭"); 	else 		printf("这两个同学不存在抄袭");//判断是否抄袭 	return 0; } int f(char file[]) { 	int n,sum[1000]={0}; 	FILE *fp;//定义文件指针 	if((fp=fopen(file,"r"))==NULL)//判断文件是否存在并打开 	{ 		printf("无法打开此文件："); 		exit(0); 	} 	char str[10000] = {0}; 	fgets(str,10000,fp);//从fp指向的文件读入字符串，并存入字符数组str中 	 	while (fgets(str,10000,fp)!=NULL)  	{	 		n=strlen(str);//测定str的字符长度 		for(int i=0;i<n;i++) 		{ 			if(str[i]=='i'&&str[i+1]=='f')//对if计数 				sum[0]+=1; 			if(str[i]=='d'&&str[i+1]=='o')//对do计数 				sum[1]+=1; 			if(str[i]=='w'&&str[i+1]=='h'&&str[i+2]=='i'&&str[i+3]=='l'&&str[i+4]=='e')//对while计数 				sum[2]+=1; 			if(str[i]=='f'&&str[i+1]=='o'&&str[i+2]=='p'&&str[i+3]=='e'&&str[i+4]=='n')//对fopen计数 				sum[3]+=1; 			if(str[i]=='f'&&str[i+1]=='g'&&str[i+2]=='e'&&str[i+3]=='t'&&str[i+4]=='s')//对fgets计数 				sum[4]+=1; 			if(str[i]=='f'&&str[i+1]=='c'&&str[i+2]=='l'&&str[i+3]=='o'&&str[i+4]=='s'&&str[i+5]=='e')//对fclose计数 				sum[5]+=1; 			if(str[i]=='f'&&str[i+1]=='p'&&str[i+2]=='u'&&str[i+3]=='t'&&str[i+4]=='s')//对fputs计数 				sum[6]+=1; 			if(str[i]=='s'&&str[i+1]=='t'&&str[i+2]=='r'&&str[i+3]=='l'&&str[i+4]=='e'&&str[i+5]=='n')//对strlen计数 				sum[7]+=1; 			if(str[i]=='f'&&str[i+1]=='o'&&str[i+2]=='r')//对for计数 				sum[8]+=1; 			if(str[i]=='s'&&str[i+1]=='t'&&str[i+2]=='r'&&str[i+3]=='u'&&str[i+4]=='c'&&str[i+5]=='t')//对struct计数 				sum[9]+=1; 		} 	} 	strcpy(file,(char*)sum);//将sum数组复制给file数组 	fclose(fp);//关闭文件 	return 1; }

而且已经把单斜杠换成双斜杠

我是直接将文件拖拽入输入黑框的

引用 3 楼 qchengzi 的回复:为什么输入文件路径后显示无法打开  文件路径是否存在  https://msdn.microsoft.com/en-us/library/yeby3zcb.aspx


Question: 哈夫曼程序问题

在百度搜“霍夫曼编码 C源代码”

也是新手，看不出来


Question: 这段程序哪哪有问题啊

不能把一个函数定义在另一个函数里

LZ真会提问。 既不给报错信息，也没有错误描述。 给了一大段代码，格式又不用论坛的代码规整。


Question: 这段程序哪些地方有问题呢

不能把函数定义在另一个函数中！

这样改 #include <stdio.h> #include <string.h> #define  MAX_LEN 10      /* 字符串最大长度 */ #define  STU_NUM 30      /* 最多的学生人数 */ #define  COURSE_NUM      /* 最多的考试科目数 */ int m,n; struct list { 	int num; 	char name[20]; 	int score[6]; 	double av; 	double sum; }stu[30];  int Menu(); void ReadScore(int n,int m); void AverSumofEveryCourse(void); void AverSumofEveryStudent(void); void Ascending(void); void Descending(void); void AsSortbyNum(void); void SortbyName(void); void SearchbyNum(void); void SearchbyName(void); void PrintScore(void); /*void StatisticAnalysis(void);*/  void main(void) { 	int i; 	printf("input student number(n<30)\n"); 	scanf("%d",&n); 	printf("input course number(m<=6)\n"); 	scanf("%d",&m); 	 	i=Menu(); 	while(i!=0) 	{ 		switch (i) 		{ 		case 1:ReadScore(n,m);break; 		case 2:AverSumofEveryCourse();break; 		case 3:AverSumofEveryStudent();break; 		case 4:Descending();break; 		case 5:Ascending();break; 		case 6:AsSortbyNum();break; 		case 7:SortbyName();break; 		case 8:SearchbyNum();break; 		case 9:SearchbyName();break; 			/*case 10:StatisticAnalysis();break;*/ 		case 11:PrintScore();break; 		} 		i=Menu(); 	} 	printf("\nEnd of program!\n"); }   int Menu() {   	int ch; 	printf(" \nManagement for Students' scores\n"); 	printf(" 1.Input record\n"); 	printf(" 2.Caculate total and average score of every course\n"); 	printf(" 3.Caculate total and average score of every student\n"); 	printf(" 4.Sort in descending order by score\n"); 	printf(" 5.Sort in ascending order by score\n"); 	printf(" 6.Sort in ascending order by number\n"); 	printf(" 7.Sort in dictionary order by name\n"); 	printf(" 8.Search by number\n"); 	printf(" 9.Search by name\n"); 	printf(" 10.Statistic analysis\n"); 	printf(" 11.List record\n"); 	printf(" 0.Exit\n"); 	printf(" Please Input your choice:\n"); 	for( ; ; ) 	{ 		scanf("%d",&ch); 		if(ch<0||ch>11) 			printf(" 输入错误，请选择 0-11："); 		else 			break; 	} 	return (ch); }  void ReadScore(int n,int m) {int i,j;  printf("Input student's ID, name and score:\n"); for(i=0;i<n;i++) { 	scanf("%ld\t%s",&stu[i].num,&stu[i].name); 	for(j=0;j<m;j++) 		scanf("%.0f\t",&stu[i].score[j]); } }  void AverSumofEveryCourse(void) { 	int i,j; 	for(i=0;i<m;i++) 	{ 		stu[i].sum=0; 		for(j=0;j<n;j++) 			(stu[i].sum)+=stu[j].score[i]; 		stu[i].av=(stu[i].sum)/n; 		printf("course%d:sum=%.0f,aver=%.0f\n",i+1,stu[i].sum,stu[i].av); 	} }  void Ascending(void) { 	int i,j; 	struct list temp; 	for(i=0;i<n-1;i++) 	{for(j=i+1;j<n;j++) 	if(stu[i].av>stu[j].av) 	{ temp=stu[i]; 	stu[i]=stu[j]; 	stu[j]=temp; 	} 	printf("Sort in ascending order by score:\n"); 	printf("number\tname\tscore1\tscore2\tscore3\tnum\taver\t"); 	for(i=0;i<n;i++) 	{ 		printf("%ld\t%s\t",stu[i].num,stu[i].name); 		for(j=0;j<m;j++) 			printf("%.0f\t",stu[i].score[j]); 		printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	} 	} }  void Descending(void) { 	int i,j; 	struct list temp; 	for(i=0;i<n-1;i++) 	{for(j=i+1;j<n;j++) 	if(stu[i].av<stu[j].av) 	{ temp=stu[i]; 	stu[i]=stu[j]; 	stu[j]=temp; 	} 	printf("Sort in descending order by score:\n"); 	printf("number\tname\tscore1\tscore2\tscore3\tnum\taver\t"); 	for(i=0;i<n;i++) 	{ 		printf("%ld\t%s\t",stu[i].num,stu[i].name); 		for(j=0;j<m;j++) 			printf("%.0f\t",stu[i].score[j]); 		printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	} 	} }  void AsSortbyNum(void) { 	int i,j; 	struct list temp; 	for(i=0;i<n-1;i++) 	{for(j=i+1;j<n;j++) 	if(stu[i].num>stu[j].num) 	{   temp=stu[i]; 	stu[i]=stu[j]; 	stu[j]=temp; 	} 	printf("Sort in ascending order by number:\n"); 	printf("number\tname\tscore1\tscore2\tscore3\tnum\taver\t"); 	for(i=0;i<n;i++) 	{ 		printf("%ld\t%s\t",stu[i].num,stu[i].name); 		for(j=0;j<m;j++) 			printf("%.0f\t",stu[i].score[j]); 		printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	} 	} }  void SortbyName(void) { 	int i,j; 	struct list temp; 	for(i=0;i<n-1;i++) 	{for(j=i+1;j<n;j++) 	if(strcmp((stu[i].name),(stu[j].name))>0) 	{   temp=stu[i]; 	stu[i]=stu[j]; 	stu[j]=temp; 	} 	printf("Sort in dictionary order by name:\n"); 	printf("number\tname\tscore1\tscore2\tscore3\tnum\taver\t"); 	for(i=0;i<n;i++) 	{ 		printf("%ld\t%s\t",stu[i].num,stu[i].name); 		for(j=0;j<m;j++) 			printf("%.0f\t",stu[i].score[j]); 		printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	} 	} }  void SearchbyNum(void) { 	int j; 	int number,i,k=0; 	printf("Input the number you want to search:"); 	scanf("%d",&number); 	for(i=0;i<n;i++) 	{if((stu[i].num)==number) 	{printf("%ld\t%s\t",stu[i].num,stu[i].name); 	for(j=0;j<m;j++) 		printf("%.0f\t",stu[i].score[j]); 	printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	k=1;} 	} 	if(k=0) printf("Not found!"); }  void SearchbyName(void) { 	int i,j; 	char nam[20]; 	int k=0; 	printf("Input the number you want to search:"); 	gets(nam); 	for(i=0;i<n;i++) 	{if(strcmp((stu[i].name),nam)==0) 	{printf("%ld\t%s\t",stu[i].num,stu[i].name); 	for(j=0;j<m;j++) 		printf("%.0f\t",stu[i].score[j]); 	printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	k=1;} 	} 	if(k=0) printf("Not found!"); }  void PrintScore(void) { 	int i,j; 	printf("number\tname\tscore1\tscore2\tscore3\tnum\taver\n"); 	for(i=0;i<n;i++) 	{ 		printf("%ld\t%s\t",stu[i].num,stu[i].name); 		for(j=0;j<m;j++) 			printf("%.0f\t",stu[i].score[j]); 		printf("%.0f\t%.0f\t",stu[i].sum,stu[i].av); 	} }   void AverSumofEveryStudent(void) { 	int i,j; 	for(i=0;i<n;i++) 	{ 		stu[i].sum=0; 		for(j=0;j<m;j++) 			stu[i].sum+=stu[i].score[j]; 		stu[i].av=(stu[i].sum)/m; 		printf("stu%d:sum=%.0f,aver=%.0f\n",i+1,stu[i].sum,stu[i].av); 	} }  /*void StatisticAnalysis(void) { int i; for(i=0;i<m;i++) { printf("for course%d:\n",i+1); printf("<60\t%d\t%.2f%\n",,); printf("60-69\t%d\t%.2f%\n",,) printf("70-79\t%d\t%.2f%\n",,) printf("80-89\t%d\t%.2f%\n",,) printf("90-99\t%d\t%.2f%\n",,) printf("100\t%d\t%.2f%\n",,) } }*/


Question: 关于scanf中读取域宽的问题

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

编译愿意把谁放在前面都可以，也可以在两者之间插入任意长度的 padding (就是说两者也不一定就是连续的）。  不同的编译选项，程序上的（细微的）不同，不同的版本，可能都会导致结果的不同。  至于 gcc 具体规则，恐怕要去读 gcc 的代码了。

输出两个连续的局部变量真的会影响它们在栈里面的相对地址吗？ 这个问题呢不好回答，具体怎么实现呢，我觉得和编译器有关系，就看编译器模型中占内存如何抉择 但是我要提醒下，你这样的代码并不可靠~~~ 也许不同版本不同厂家的编译器编译出来，运行结果不一样

可能编译器是这样想的, 谁先用就先给谁地址, 第1个先出现&a, 先分配, 第2个从压栈顺序来说是先出现&b,  以上纯属猜想, 这用法应该也算是越界了

额，图片好像不挂vpn看不见(贴的外链)，无所谓了，上面已经有运行结果说明了

额，图片好像不挂vpn看不见(贴的外链)，无所谓了，上面已经有运行结果说明了

引用 9 楼 lm_whales的回复:编译器如果懒惰一点，那就按照定义顺序，安排。这也是经常会看到的。 如果想精细一点，那就会不耐其烦的依照某种策略安排变量内存位置。 谢谢大家的回答，我明白了


Question: 帮忙设计个程序

我觉可以这样采用位图操作 利用20个bit表示20个灯笼亮的情况 利用20个位表示操作情况 比如1表示亮 0表示不亮 对某个位进行异或操作 1^1=0   0^0=0 1^0=1 0^1=1 比如a c d f g 表示为0000 0000 0000 0110 1101          b k f m g 表示为    0000 0000 1000 0110 0010 进行异或操作后就是acdbkm   然后针对具体数据完成 你的代码呗  我的算法就是这样咯

7个按钮, 最多2^7种组合, 直接枚举一下就可以了

每个按钮控制的灯数量随机 那么按下多少按钮后灯笼能全亮，这个多少是不确定的 是要求最少按下多少个按钮？ 最少按下一个，即按下的那个按钮控制着除开始亮着之外的所有等

引用 1 楼 fly_dragon_fly的回复:7个按钮, 最多2^7种组合, 直接枚举一下就可以了 如何穷举? 我只是求个程序 我没学C语言啊


Question: 小白问题，宏的用法

理解和讨论之前请先学会如何观察！  VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

求解答啊,我也想知道

就是直接替换

只是相当于一个函数头和一些定义 你把宏展开就知道了


Question: C语言题目，为什么这样？

引用 29 楼 gblhack 的回复:容易迷惑的地方可能是short i = -4，在内存中是FF FC ，我们用%d就是输出的 FF FC ，其实%d输出的是“i”这个表达式的结果，而不是其在内存中存放的值。 这里更正一下: short i  =-4； printf("%d  %o  %x  %u",i,i,i,i);  并不是说把short型的参数i转换成%d对应的int，而是C语言对此有约定，如fefe82老师所说的 引用short 类型的变量 i 用于 printf(format, ...) 后面 ... 部分的参数，会经历 integer promotion 也就是说i被转换成int型和%d %o %x %u占位符无关，而是C语言规定函数中未进行类型说明的参数，在传参时会对实参进行Default Argument Promotion（缺省参数提升）。default argument promotion包括fefe82老师说的integer promotion和一个float转换成double(相对于printf函数，其他的不清楚)。 而我前面说的“其实%d输出的是“i”这个表达式的结果，而不是其在内存中存放的值” 是错误的，%d就是以int型读取i的“内存”，这里仅用内存来说可能也不太准确，因为这涉及到一个栈的概念，但我还没有学习到，所以就不和你多说了，以免对你再次误导。 至于“%d就是以int型读取i的“内存”的证明：printf("%d  %d",1.0,(int)1.0); %d输出(int)1.0结果为1，%d输出1.0结果为0。 参考资料http://www.zhihu.com/question/28467596  http://blog.csdn.net/astrotycoon/article/details/8284501 最后可能需要再说明一点，由于我也是一个C语言初学者，所以我的所有回复并非专业问答，而是报着学习交流的态度与同样的初学者共同探讨，如果我的观点对你产生了误导，我对此十分抱歉。

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

要限定IA32，也能做。。 啥也不限定，是单片机 还是ia32 还是64.。。 就写个 main。。

。。又是谭浩强的 掉书袋的 题 么。。

printf 在传递参数时，对于 char、short、int 都提升到了 int 类型，相当于有个隐式转换。转换后的结果取决于编译器位数，这跟你前面用的是 short 还是 char 还是 int 没关系，结果都是一样的。如果是 16 位的编译器，int 通常也是 16 位，转换之后也是 16 位整数。32 位的编译器，int 通常也是 32 位，转换之后也是 32 位整数。用计算器以 16 位和 32 位分别对照 -4 在不同进制下的值就明白了。

可能和系统内存有关，目前正在学习

引用 30 楼 qq_33417622 的回复:非常感谢啊！！！谢谢谢谢！ 相互学习

试了一下，32位系统得到的结果是：-4    177774    ffc   fffffffc  64位系统没试。

对的,非常正确

跟系统最大取值范围有关，楼主别纠结这个问题了 书上肯定都老爷机了 换本书看吧  那本太老了

计算机位数问题，16位与32位是有区别的

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

引用 29 楼 _郭的回复:[quote=引用 11 楼 qq_33417622 的回复:] [quote=引用 7 楼 _郭的回复:]这个问题很简单，第一你要sizeof(int)看一下占用几个字节，然后确定-4在内存中的存放形式。 我这里假设int占用4个字节，那么-4在内存中 ： 1111 1111 1111 1111 1111 1111 1111 1100    (至于为什么是这样存放的请参看一下有符号整数在内存中的存放形式) 用16进制输出这个2进制数就是 FFFFFFFC 8进制输出： 37777777774 10进制输出： 4294967292 至于你怎么笔算的，没说过程不知道你错在哪里，但肯定是错的。 另外你可以参考：   unsigned int n =0xFFFFFFFF;   printf("%d",n); 变量n的类型决定它怎么存放，而%d决定以什么方式读取n的这块内存。 我用sizeof测试，short占用两个字节的。也就是16位。[/quote]  只注意到了有符号到无符号的转换，没注意到short到int的转换，这位老师说的很清楚，你可以看一下  引用 8 楼 fefe82 的回复:2) short 类型的变量 i 用于 printf(format, ...) 后面 ... 部分的参数，会经历 integer promotion 。   经过 integer promotion ，它会被转换为 int （如果 sizeof(short) < sizeof(int)）或 unsigned int （如果 sizeof(short) == sizeof(int)）。 3) 在以上情况下，如果一个小于零的 short i 转换为 int ，其值不变。否则(即被转换为了 unsigned int)，其值变为 UINT_MAX + 1 + i (请按数学中的基本运算规则计算这个值，而不是按 C 语言中的表达式计算规则）   其中，UINT_MAX 是 unsigned int 所能表示的最大的值。由于 sizeof(int) 是依赖于编译器的，UINT_MAX 也是  ———————————————————————————————————————————— 便于理解我做一个测试： 断下单步执行后，先看一下局部变量窗口i的值(数组的地址)，然后再内存窗口跳转到该地址，可以看到数组i在内存中存放的形式 (16进制显示的)。  至于为什么要用数组和为什么要解释这一步，是因为看到上面有人说什么把它后面的数据也输出了，故验证一下。  下面验证fefe82老师说的short转换成int：  我们可以看到short转换成int确实会经历integer promotion(整型提升)，也就是说我们把i[1]赋值给变量ii并不只是简单的内存拷贝。 我简单说一下我理解的转换过程：  int ii = i[1]; 首先int ii，编译器会为ii分配4个字节的内存地址，然后再根据“=”号右边的表达式的结果初始化； "="号右边是i[1]，编译器首先会取出它的值，得出结果 -4，然后用-4初始化变量ii； 把 -4 存储在ii的内存空间。 ———————————————————————————————————————————————— 而你的实验用%d %o 等输出short i，相当于： printf("%d  %o  %x  %u",-4,-4,-4,-4); 容易迷惑的地方可能是short i = -4，在内存中是FF FC ，我们用%d就是输出的 FF FC ，其实%d输出的是“i”这个表达式的结果，而不是其在内存中存放的值。 __________________________________________________________________________________ 最后再感谢一下fefe82老师，另外同学其实不必过于纠结存储方式和占用多少字节什么的，了解就可以了。[/quote] 非常感谢啊！！！谢谢谢谢！

GP论坛没落了，这样就能留人？

不同的编译环境导致分配的存储字节大小有差异，有的分配2个字节有的是4个字节。

引用 11 楼 qq_33417622 的回复:[quote=引用 7 楼 _郭的回复:]这个问题很简单，第一你要sizeof(int)看一下占用几个字节，然后确定-4在内存中的存放形式。 我这里假设int占用4个字节，那么-4在内存中 ： 1111 1111 1111 1111 1111 1111 1111 1100    (至于为什么是这样存放的请参看一下有符号整数在内存中的存放形式) 用16进制输出这个2进制数就是 FFFFFFFC 8进制输出： 37777777774 10进制输出： 4294967292 至于你怎么笔算的，没说过程不知道你错在哪里，但肯定是错的。 另外你可以参考：   unsigned int n =0xFFFFFFFF;   printf("%d",n); 变量n的类型决定它怎么存放，而%d决定以什么方式读取n的这块内存。 我用sizeof测试，short占用两个字节的。也就是16位。[/quote]  只注意到了有符号到无符号的转换，没注意到short到int的转换，这位老师说的很清楚，你可以看一下  引用 8 楼 fefe82 的回复:2) short 类型的变量 i 用于 printf(format, ...) 后面 ... 部分的参数，会经历 integer promotion 。   经过 integer promotion ，它会被转换为 int （如果 sizeof(short) < sizeof(int)）或 unsigned int （如果 sizeof(short) == sizeof(int)）。 3) 在以上情况下，如果一个小于零的 short i 转换为 int ，其值不变。否则(即被转换为了 unsigned int)，其值变为 UINT_MAX + 1 + i (请按数学中的基本运算规则计算这个值，而不是按 C 语言中的表达式计算规则）   其中，UINT_MAX 是 unsigned int 所能表示的最大的值。由于 sizeof(int) 是依赖于编译器的，UINT_MAX 也是  ———————————————————————————————————————————— 便于理解我做一个测试： 断下单步执行后，先看一下局部变量窗口i的值(数组的地址)，然后再内存窗口跳转到该地址，可以看到数组i在内存中存放的形式 (16进制显示的)。  至于为什么要用数组和为什么要解释这一步，是因为看到上面有人说什么把它后面的数据也输出了，故验证一下。  下面验证fefe82老师说的short转换成int：  我们可以看到short转换成int确实会经历integer promotion(整型提升)，也就是说我们把i[1]赋值给变量ii并不只是简单的内存拷贝。 我简单说一下我理解的转换过程：  int ii = i[1]; 首先int ii，编译器会为ii分配4个字节的内存地址，然后再根据“=”号右边的表达式的结果初始化； "="号右边是i[1]，编译器首先会取出它的值，得出结果 -4，然后用-4初始化变量ii； 把 -4 存储在ii的内存空间。 ———————————————————————————————————————————————— 而你的实验用%d %o 等输出short i，相当于： printf("%d  %o  %x  %u",-4,-4,-4,-4); 容易迷惑的地方可能是short i = -4，在内存中是FF FC ，我们用%d就是输出的 FF FC ，其实%d输出的是“i”这个表达式的结果，而不是其在内存中存放的值。 __________________________________________________________________________________ 最后再感谢一下fefe82老师，另外同学其实不必过于纠结存储方式和占用多少字节什么的，了解就可以了。

我用64位的运行了一下 结果分别是 -4  37777777774    fffffffc   4294967292

引用 22 楼 user-14的回复:跟你的编译环境有关啊，16位跟32位数据肯定不相同啊，负数首位是1，后面跟的0差好多，位数不同转换后的数差十万八千里啊 你看看我的解释，编译环境不同，你看看楼上我的思考


Question: 编译器错误怎么解决[Error] ld returned 1 exit status

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt


Question: C语言如何让编译界面显示输出内容

在return 0;前面加上system("pause");//暂停 需要头文件#include <iostream>

Alt - F5 ？记不清了，太多年了

引用 2 楼 both_war的回复:还真是，请问 return 0; 是什么意思，能不能设置成 按任意键继续 加个循环，循环中调用getchar，有字符则输出，否则等待输入

还真是，请问 return 0; 是什么意思，能不能设置成 按任意键继续

在return 0;前面加一句getchar();

TC的IDE内部一直都是可以见到结果的 选择菜单 File DOS shell 就可以了 输入exit 可以返回编辑器界面


Question: The Art and Science of C 《C语言科学与艺术》 的库文件问题

初学请严格按照书中说明搭建实验环境。如果环境太旧无法搭建，可在虚拟机中搭建。

谢谢，使用的就是在windows IDE环境下对应的文件。仍然不能编译，说缺少了布尔文件吧，不过初学，还不知道那是什么。。。。

微软有很多自家的"语言特性"，你编译通不过正常，你应该查看源文件附带的文档，看看是在什么环境下开发的


Question: modbus tcp功能码编程  请高手给个范例

tcp只是modbus的传输方式而已，用串口是一样的。 重点得看modbus的帧格式


Question: 关于单链表的逆转，这一段源程序看不懂

我画了个图，你瞅瞅？

你可以画一个有3个结点的链表，然后照着代码一步一步走，直到循环结束，应该就能看出来了。

楼主的程序应该是带表头结点的单向链表吧，这样逻辑就是对的。 每次都是在表头结点H的后面依次插入原链表的结点，插入到末尾链表就逆序了。


Question: 为什么这里要用n+1而不能是n++

n++; 会改变n的值，而n+1不会。

++n和n++是不一样的

第7行和第13行，n++不就是n+1么


Question: C语言中数组这样的写法为什么

i[a]???这样也太任性了吧，即使可以，最好也别这样写，可读性太差了

你想问的是为何i[a]也行吧，c陷阱和缺陷里面提到了这一点。首先数组下标其实就是借用了指针运算，即a[i]的本质就是*(a+i)，明白这一点后题主的问题很好理解了，即i[a]就是*(i+a)。所以i[a]和a[i]等价

没明白你意思，这样写没问题啊，你问的是什么为什么

可以这样写啊 只是循环中如果你把7写成10或者其他更大的数 就会发生越界而已

这么写真的不会被打吗。。

呵呵，等价于a[i]，问问坛子里的zhao4zhong1 http://my.csdn.net/zhao4zhong1


Question: 闭包的意义是什么？

up 起来，然更多的人看到，帮忙解答。

继续接8楼：  def count():     fs = [] # 列表开始为空     i = 2      def f(): # 定义函数（闭包），但是并没有调用它         print 'python'         return i*i # 这里闭包可以访问局部变量i     fs.append(f) # 将函数（闭包）加入列表，但是还是没有调用它     print fs     return fs # 返回列表                                                                                f1 = count() # 将返回的列表中的元素（闭包）分别赋给f1, f2, f3 print f1() # 调用闭包，所以只是调用了一次而已  去掉for 循环。 运行结果：   TypeError: 'list' object is not callable  何故 ?

接7楼，最后一个实验：  ef count():     fs = [] # 列表开始为空     for i in range(1, 5):          def f(): # 定义函数（闭包），但是并没有调用它             print 'python'             return i*i # 这里闭包可以访问局部变量i         fs.append(f) # 将函数（闭包）加入列表，但是还是没有调用它         print fs                                                                                return fs # 返回列表         f1,f2, f3, f4 = count() # 将返回的列表中的元素（闭包）分别赋给f1, f2, f3  运行结果是：    [<function f at 0x7fae472021b8>] [<function f at 0x7fae472021b8>, <function f at 0x7fae47202320>] [<function f at 0x7fae472021b8>, <function f at 0x7fae47202320>, <function f at 0x7fae47202398>] [<function f at 0x7fae472021b8>, <function f at 0x7fae47202320>, <function f at 0x7fae47202398>, <function f at 0x7fae47202410>] python 16  说明fs 中存储了4个函数，  可是为什么这4个函数的调用结果是一样的 ？？   确实让人费解

引用 6 楼 ForestDB 的回复:可以简单认为闭包是可以保存局部变量的函数，然后该函数可以在后面调用。  def count():     fs = [] # 列表开始为空     for i in range(1, 4):          def f(): # 定义函数（闭包），但是并没有调用它             print 'python'                                                                                return i*i # 这里闭包可以访问局部变量i         fs.append(f) # 将函数（闭包）加入列表，但是还是没有调用它     return fs # 返回列表   f1, f2, f3 = count() # 将返回的列表中的元素（闭包）分别赋给f1, f2, f3 print f1() # 调用闭包，所以只是调用了一次而已   多谢前辈指点，  为了验证你的说法，我做了一个改进：  def count():     fs = [] # 列表开始为空     for i in range(1, 5):                                                                                def f(): # 定义函数（闭包），但是并没有调用它             print 'python'             return i*i # 这里闭包可以访问局部变量i         fs.append(f) # 将函数（闭包）加入列表，但是还是没有调用它     return fs # 返回列表  f1,f2, f3, f4 = count() # 将返回的列表中的元素（闭包）分别赋给f1, f2, f3 print f1() # 调用闭包，所以只是调用了一次而已  注意： f1,  f2 ,f3, f4   range(1, 5)，   再做一个实验：  >>> fs =[1, 2, 3, 4] >>> a, b, c, d = fs >>> print a 1 >>> print b 2 >>> print 3 3 >>> print c 3 >>> print d 4   这2个实验可以得出结论： python 的赋值技法 太复杂了，原来这样子赋值！！！！

引用 3 楼 akirya 的回复:不太懂python， f只保存了i 没有保存 fs  大神不懂python啊

不太懂python， f只保存了i 没有保存 fs

引用 1 楼 user-3 的回复:这个是lua吗 python

这个是lua吗


Question: C语言怎样实现多线程？

引用 10 楼 fefe82 的回复:自从 C11 ，C 语言已经开始提供线程支持，并提供了 <threads.h>  C11只是建议，但是否支持多线程，取决于C实现。C并不提供<threads.h>，那是C实现提供的。

自从 C11 ，C 语言已经开始提供线程支持，并提供了 <threads.h>

Thread support library 在visual studio中需包含头文件<thr\threads.h>

引用 11 楼 sholber 的回复:[quote=引用 10 楼 fefe82 的回复:] 自从 C11 ，C 语言已经开始提供线程支持，并提供了 <threads.h>  C11只是建议，但是否支持多线程，取决于C实现。C并不提供<threads.h>，那是C实现提供的。[/quote]  这个东西确实是 conditional supported ，也就是可选的。  但是 C11 确实定义了 threads.h ，以及其中需要提供的类型、函数等，及其功能。

系统调用系统api CreateThread(....); 需要包含头文件 #include <windows.h>

sorry 需要调用

c语言没有提供  需要调用操作系统api !!!!  c不像某些高级语言，比如java，就自带线程接口

楼主，可以试试beginthread，endthread

创建一个线程用来计时，CreateThread

百度一下 C语言 线程创建 以及多线程通讯

_beginthread CreateThread


Question: Huffuman树的基础构造（C语言实现）

引用 1楼user-1 的回复:当前n个,按从大到小排序, 最后2个加起来, 然后n-1个排序, 一直到结束加起来然后存放的位置呢…

当前n个,按从大到小排序, 最后2个加起来, 然后n-1个排序, 一直到结束


Question: [新人求助]下面这段代码第二次运行的结果为什么会是1!!

11楼的解释很好，又学到了。

引用 11 楼 northwesternwind 的回复:[quote=引用 8 楼 coderCold 的回复:] [quote=引用 7 楼 user-3 的回复:] 例如一个文件只有一个字符 他的内容是 ’1‘，0xFF,0xFF 这是16Bits系统文本文件的结构 或者‘1’，0xFF,0xFF,0xFF,0xFF 如今也许是这个样子 文件指针指向‘1’ 即0x33的时候，文件并没有结束 只有指向0xFF这个位置的时候，feof 才会报告文件结束 写文件的时候，除非出错，永远是可写的，所以永远不会是文件结束位置。 只有读文件，fseek 等操作，才会遇到文件结束。 我明白了,但是这些还不能解释我提出的那个问题.根据我的理解: 假设是8Bits文本文件结构 第一次运行后内容是:'1',0xFF 第二次运行时文件指针指向'1',ReadChar读到了'1',之后文件指针后移到0xFF,然后写入一个字符'2',这是文件内容应该变为'1','2',0xFF 可是我运行的结果显示文件内容还是'1'[/quote] 难倒我了。研究半天才发现原因，这是VC特有的特征，在linux上结果会不一样, MSDN的帮助： 当指定 "r+","w+", 或 "a+" 访问类型时，允许读取和写入。（文件将处于打开状态以进行“更新”。） 但是，当你从读取切换到写入时，输入操作必须遇到 EOF 标记。如果没有 EOF，必须使用对文件定位函数的干预调用。文件定位函数是 fsetpos、fseek 和 rewind。从写入切换到读取时，必须使用对 fflush 或文件定位函数的干预调用。 如果你检查fputc返回值，会发现第二次fputc其实是执行失败了，返回值为-1。 [/quote] 真棒!谢谢~

引用 8 楼 coderCold 的回复:[quote=引用 7 楼 user-3 的回复:] 例如一个文件只有一个字符 他的内容是 ’1‘，0xFF,0xFF 这是16Bits系统文本文件的结构 或者‘1’，0xFF,0xFF,0xFF,0xFF 如今也许是这个样子 文件指针指向‘1’ 即0x33的时候，文件并没有结束 只有指向0xFF这个位置的时候，feof 才会报告文件结束 写文件的时候，除非出错，永远是可写的，所以永远不会是文件结束位置。 只有读文件，fseek 等操作，才会遇到文件结束。 我明白了,但是这些还不能解释我提出的那个问题.根据我的理解: 假设是8Bits文本文件结构 第一次运行后内容是:'1',0xFF 第二次运行时文件指针指向'1',ReadChar读到了'1',之后文件指针后移到0xFF,然后写入一个字符'2',这是文件内容应该变为'1','2',0xFF 可是我运行的结果显示文件内容还是'1'[/quote] 难倒我了。研究半天才发现原因，这是VC特有的特征，在linux上结果会不一样, MSDN的帮助： 当指定 "r+","w+", 或 "a+" 访问类型时，允许读取和写入。（文件将处于打开状态以进行“更新”。） 但是，当你从读取切换到写入时，输入操作必须遇到 EOF 标记。如果没有 EOF，必须使用对文件定位函数的干预调用。文件定位函数是 fsetpos、fseek 和 rewind。从写入切换到读取时，必须使用对 fflush 或文件定位函数的干预调用。 如果你检查fputc返回值，会发现第二次fputc其实是执行失败了，返回值为-1。

引用 9 楼 jackydi 的回复:应该是没有清除输入缓冲区的问题吧，getchar()之后是否应该使用fflush()清除一下输入缓冲区呢？ 是这样吗? ReadChar(fp); fflush(fp); PutChar(fp); 结果还是不对.

引用 7 楼 user-3 的回复:例如一个文件只有一个字符 他的内容是 ’1‘，0xFF,0xFF 这是16Bits系统文本文件的结构 或者‘1’，0xFF,0xFF,0xFF,0xFF 如今也许是这个样子 文件指针指向‘1’ 即0x33的时候，文件并没有结束 只有指向0xFF这个位置的时候，feof 才会报告文件结束 写文件的时候，除非出错，永远是可写的，所以永远不会是文件结束位置。 只有读文件，fseek 等操作，才会遇到文件结束。 我明白了,但是这些还不能解释我提出的那个问题.根据我的理解: 假设是8Bits文本文件结构 第一次运行后内容是:'1',0xFF 第二次运行时文件指针指向'1',ReadChar读到了'1',之后文件指针后移到0xFF,然后写入一个字符'2',这是文件内容应该变为'1','2',0xFF 可是我运行的结果显示文件内容还是'1'

引用 5 楼 user-3 的回复:写文件永远也不会到文件结束 除非fseek 读才会到文件结束 文件结束标志读出来以后，文件就结束了，否则还没有 还是没懂,拜托能更详细的讲解一下吗

引用 3 楼 northwesternwind 的回复:[quote=引用 2 楼 coderCold 的回复:] [quote=引用 1 楼 northwesternwind 的回复:] 第一次运行后文件中已经有个1了. 用r+打开从头开始读，所以第二次运行后文件内容应该是1和2。 问题就是按照理解第二次运行后文件的内容是1和2,但是实际跑下来的结果却只有1.[/quote] 开始时候文件是空，还是有一个空行或者空格？应该和这个有关系。但第二次结果应该会 出现2的情况，不会是只有1。[/quote] 第一次文件里面是什么都没有,没有空行和空格.

引用 2 楼 coderCold 的回复:[quote=引用 1 楼 northwesternwind 的回复:] 第一次运行后文件中已经有个1了. 用r+打开从头开始读，所以第二次运行后文件内容应该是1和2。 问题就是按照理解第二次运行后文件的内容是1和2,但是实际跑下来的结果却只有1.[/quote] 开始时候文件是空，还是有一个空行或者空格？应该和这个有关系。但第二次结果应该会 出现2的情况，不会是只有1。

引用 1 楼 northwesternwind 的回复:第一次运行后文件中已经有个1了. 用r+打开从头开始读，所以第二次运行后文件内容应该是1和2。 问题就是按照理解第二次运行后文件的内容是1和2,但是实际跑下来的结果却只有1.


Question: 【数据结构】C程序有一个测试点出了段错误，求解...

Windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  Linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

引用 楼主 jyty001 的回复:[原题] 两个有序链表序列的合并   (20分) 已知两个非降序链表序列S1与S2，设计函数构造出S1与S2的并集新非降序链表S3。 输入格式: 输入分两行，分别在每行给出由若干个正整数构成的非降序序列，用−1表示序列的结尾（−1不属于这个序列）。数字用空格间隔。 输出格式: 在一行中输出合并后新的非降序链表，数字间用空格分开，结尾不能有多余空格；若新链表为空，输出NULL。 输入样例: 1 3 5 -1 2 4 6 8 10 -1 输出样例: 1 2 3 4 5 6 8 10  [测试结果]   [源码] #include <stdio.h> #include<stdlib.h> typedef struct node { 	int data; 	struct node *next; }LNode,*LinkList; LinkList create() { 	int num; 	LinkList p,r,list=NULL; 	while(1) 	{ 		scanf("%d",&num); 		if(num==-1) 			break; 		p=(LinkList)malloc(sizeof(LNode)); 		p->data=num; 		p->next=NULL; 		if(list==NULL) 			list=p; 		else 			r->next=p; 		r=p; 	} 	if(r!=NULL) 		r->next=NULL; 	return list; } void print(LinkList L) { 	while(L!=NULL) 	{ 		printf("%d",L->data); 		L=L->next; 		if(L!=NULL) 			printf(" "); 	} } int main() { 	LinkList s1,s2; 	s1=create(); 	s2=create(); 	if(s1==NULL&&s2==NULL) 	{ 		printf("NULL"); 		return 0; 	} 	else if(s1==NULL) 	{ 		print(s2); 		return 0; 	} 	else if(s2==NULL) 	{ 		print(s1); 		return 0; 	} 	while(s1!=NULL&&s2!=NULL) 	{ 		if(s1->data<s2->data) 		{ 			printf("%d",s1->data); 			s1=s1->next; 			if(s2!=NULL||s1!=NULL) 				printf(" "); 		} 		else if(s1->data==s2->data) 		{ 			printf("%d %d",s1->data,s2->data); 			s1=s1->next; 			s2=s2->next; 			if(s2!=NULL||s1!=NULL) 				printf(" "); 		} 		else 		{			 			printf("%d",s2->data); 			s2=s2->next; 			if(s2!=NULL||s1!=NULL) 				printf(" "); 		} 	} 	if(s1==NULL&&s2!=NULL) 	{ 		print(s2); 	} 	if(s1!=NULL&&s2==NULL) 	{ 		print(s1); 	} 	free(s1); 	free(s2); 	return 0; }给r赋初值为NULL；否则直接输-1的话就出错了，看起来没影响，实际上系统随机为r分配的地址可就被篡改了(release模式下，debug下好像会给个固定的错误地址)。

以下输入使程序出现段错误： -1 1 -1  把以下一行 LinkList p,r,list=NULL; 改为 LinkList p,r=NULL,list=NULL;


Question: 求问在C语言编译过程中汇编文件以ASCII码形式存储还是二进制编码的机器指令存储？

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


Question: 求问在C语言编译过程中汇编文件以ASCII码形式存储还是二进制编码的机器指令存储？

编译生成的目标代码，以及连接生成的可执行代码 通常都是二进制代码 格式和平台相关 例如C51生成的可执行代码，通常是是intel格式的.hex 文件（一种十六进制表示的二进制代码）,用于烧写到 rom 中。 dos 生成的代码，有目标文件.obj,静态库.lib  ,可执行文件有.com，.exe，等等 据说是OMF 格式 Windows 可执行文件.exe.dll 是PE格式 据说是一种 COFF格式的变体.obj,.lib 也是这种格式 Linux可执行文件 是ELF 格式 .a 也是这种格式  大概只有DOS的.com文件，是赤裸裸的代码。 很多文件格式，都是有一定的组织结构的。

一般来书，编译生成的 是二进制代码，是按照某种格式组织的,二进制代码。 但是你可以让他(同时)生成汇编语言源文件，（文本文件） 你还可以让他生成 包含C（C++）原始代码的汇编语言源文件 如果你对二进制代码感兴趣，还可以同时也生成二进制代码（十六进制表示的文本形式）。

你如果需要输出汇编的结果，当然是文本。  但是内部在内存里是什么样子的，就不知道了。

代码文件的话是用文本存储的，如果编译链接后PE文件则是用二进制存储的

编译过程中根本就不会出现汇编文件，你的问题本身就不成立。


Question: 求问C语言编译过程中汇编文件以ASCII字符存储还是以二进制存储？

正常编译，是不输出汇编源文件的，除非设置为输出。

二进制存储。查看时可以使用很多编码方式。你说的ascii只是一种编码方式。记住一句话，在计算机里所有的数据都是二进制。但是查看二进制的方法有千万种

引用 3 楼 user-4 的回复:代码文件应该就是按文本格式存的 谢谢

引用 3 楼 user-4 的回复:代码文件应该就是按文本格式存的谢谢

引用 3 楼 user-4 的回复:代码文件应该就是按文本格式存的谢谢

代码文件应该就是按文本格式存的

代码文件应该就是按文本格式存的

代码文件应该就是按文本格式存的


Question: visual c++6.0断点调试该怎么做？求详解

引用 2 楼 jutiafuweh 的回复:是不是有的地方不能加断点，加断点有什么限制吗？ 加断点的行有对应的汇编指令且程序运行时能经过该汇编指令。

是不是有的地方不能加断点，加断点有什么限制吗？

简单的说就是在要断的地方插入断点，程序运行到就会断下，可以观察此时各变量及各种环境值，方便调试 可以配合逐步运行、步入、步出等一起使用  http://blog.csdn.net/zxq1138634642/article/details/8108983

谢谢各位的指导


Question: 为什么在Ubuntu里，单独用cpp, cc1, as, ld产生的程序执行出错

找不到入口点

最后链接时需要加上 crt0.o，或者类似的文件。文件名有些记不清了。这个文件里包含了程序真正的入口。然后由它来调用main函数

引用 5 楼 user-3 的回复: --dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o -lc  完整的需要很多工作的，你可以用 gcc --verbose main.c 看一下具体有多少内部流程 好的谢谢了，虽然没看懂哪些信息。

引用 1 楼 user-3 的回复:ld main.o -o main -lc --entry main 这样的话执行程序的时候又产生了这个错误：

ld main.o -o main -lc --entry main


Question: strcmp函数

引用 楼主 qq_18888869 的回复:#include<stdio.h> #include<string.h> #define N 80  int fun(char *str) { 	char*pf,*pt; 	int flag=1;;  	for(pf=str,pt=str+strlen(str)-1;pf<pt;pf--,pt++) 		if(strcmp(*pf,*pt)) 		//if(*pf!=*pt) 			flag=0;     return flag;  } 为什么我用strcmp这个函数不能比较呀 。求指教  参数有误吧 strcmp 是比较字符串 不是比较字符~~~~

strcmp(pf,pt)

我也有同样的问题   楼主解决了没

extern int strcmp(const char *s1,const char *s2);所以传值参数应该是地址

引用 9 楼 qq_18888869 的回复:引用 7 楼 butters10 的回复:strcmp参数要求是比较字符串的首地址我把pt赋值为一个字符的地址 那*pt代表的应该是从这个字符到\0位置的字符串吧 *pt是该字符串的第0个字符

1、应该使用if(*pf！=*pt）这个判断语句，逐个字符比较是否相等； 2、strcmp是字符串比较函数，比较的是字符串的大小，参数是要比较的字符串的首地址； 3、如果fun的参数为字符串"abcdefa"，则pf所指向的字符串为"abcdefa",pt所指向的字符串为"a"，变成两个字符串的比较，实现不了最初的目的；

字符串的首地址

楼主你首先得知道strcmp的参数 它有两个参数，类型都是const char * 而你调用时传的是char类型实参 当然不对

引用 4 楼 qq_18888869 的回复:[quote=引用 1 楼 adusuccessfully 的回复:] 楼主看下是不是for(pf=str,pt=str+strlen(str)-1;pf<pt;pf--,pt++)写错了 应该是for(pf=str,pt=str+strlen(str)-1;pf<pt;pf++,pt--) 确实是错了  现在 如果用那个if(*pf！=*pt)的话能得到正确结果，但是用strcmp还是会出现:\Users\Administrator\Desktop\try\try.cpp(11) : error C2664: 'strcmp' : cannot convert parameter 1 from 'char' to 'const char *'       这样的问题 这个问题你知道为什么吗 很感谢你  [/quote] 楼主可以百度下strcmp函数的用法  #include<stdio.h> #include<string.h> void main() { 	char *s1 = "abcd"; 	char *s2 = "abcd"; 	if(!strcmp(s1,s2)) 		printf("相同"); 	else 		printf("不同"); }

strcmp参数要求是比较字符串的首地址

引用 1 楼 adusuccessfully 的回复:楼主看下是不是for(pf=str,pt=str+strlen(str)-1;pf<pt;pf--,pt++)写错了 应该是for(pf=str,pt=str+strlen(str)-1;pf<pt;pf++,pt--) 确实是错了  现在 如果用那个if(*pf！=*pt)的话能得到正确结果，但是用strcmp还是会出现:\Users\Administrator\Desktop\try\try.cpp(11) : error C2664: 'strcmp' : cannot convert parameter 1 from 'char' to 'const char *'       这样的问题 这个问题你知道为什么吗 很感谢你

strcmp参数要求是比较字符串的首地址

strcmp参数要求是比较字符串的首地址


Question: 检测回文 （比如123321就是回文）有个问题不知道问什么不能运行

int fun(char *str) { 	char*pf,*pt; 	int flag=1;;  	for(pf=str,pt=str+strlen(str)-1;pf<pt;pf++,pt--) 		//if(strcmp(*pf,*pt)) 			if(*pf!=*pt) 				flag=0; 	return flag;  }

3楼正解！！

引用 3 楼 Arvll 的回复:pf应该是++,pt应该是--++

引用 3 楼 Arvll 的回复:pf应该是++,pt应该是--++

pf应该是++,pt应该是--

你的main函数在哪里

引用 1 楼 user-5 的回复:你的main函数在哪里int main() { 	char S[N]; 	printf("Ener s str:\n"); 	gets(S); 	puts(S); 	if(fun(S)) 		printf("YES\n"); 	else 	printf("NO");  	     return 0; } 在这里


Question: 把字符串中非字母字符去掉

引用 1楼user-1 的回复:for(i=0;a[i]!='\0';) { if(!(65<=a[i]&&a[i]<=90||97<=a[i]&&a[i]<=122)) ｛ for(k=i;a[k]!='\0';k++) a[k]=a[k+1]; } else i++; }嗯，这办法可以，学习了，谢谢哈


Question: 新人求助 报错LNK1168

如果看不到那个窗口，可以打开任务管理器，找到映像名称为 test4.exe 的进程，结束它即可

是因为你已经打开了一个控制台程序，就是你运行了一个程序了，要先关闭运行窗口在运行当前程序才可以正常运行新的程序

是楼主的编译环境问题么，我看程序没问题，我在VS2010上试是对的。


Question: 帮忙看下

引用 2 楼 qq_33484912 的回复:能不能直接发给我看下 不好意思，不好意思，不好意思 链接复制错了： http://bbs.csdn.net/topics/391880431

能不能直接发给我看下

楼主提的问题跟昨天的一个贴子很像，可以参考下，里面有我的回复，链接是： http://bbs.csdn.net/topics/391881448


Question: 开关语句问题

switch需要一个大括号：   int main() { 	int i; 	for(i=0;i<10;i++) 	{ 		switch(i) 		{         case 0: 			printf("零\n"); 			break; 		case 1: 			printf("壹\n"); 			break; 		case 2: 			printf("贰\n"); 			break; 		case 3: 			printf("叁\n"); 			break; 		case 4: 			printf("肆\n"); 			break; 		case 5: 			printf("伍\n"); 			break; 		case 6: 			printf("陆\n"); 			break; 		case 7: 			printf("柒\n"); 			break; 		case 8: 			printf("捌\n"); 			break; 		default: 			printf("玖\n"); 			break; 		} 	} }


Question: C,#define,

使用代码生成技术？ 仅供参考：//codegen.c // 输入一组字符串，比如 // aa ss ddd dd 33 dd // 然后自动生成一个函数 int A(const char*); // 实现A("aa")返回0  A("ss")返回1 依次类推 #include <stdio.h> int main(int argc,char **argv) {     int i;     if (argc<2) {         printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);         return 1;     }     //printf("#include <string.h>\n");     printf("int A(const char *a) {\n");     for (i=0;i<argc-1;i++) {         printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);     }     printf("    return -1;\n");     printf("}\n");     return 0; } //C:\test\Debug>codegen.exe //codegen.exe p1 [p2 ...] [>result.c] //Generate code int A(const char *a); 0==A("p1") 1==A("p2") ... //C:\test\Debug>codegen.exe aa ss ddd dd 33 dd //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} // //c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c // //c:\test\Debug>type result.c //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} //

你是想今天把后天的午饭先吃了

仅供参考：  #与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

引用 6 楼 wsdxyz 的回复:[quote=引用 4 楼 Saleayas 的回复:] 如果一定要这么做，那么使用一个数组，把编译期和运行时联系起来。 thanks for you replay, but any clear solution/suggestions ?[/quote] Can you bright me with more clear solution? THX!

引用 5 楼 paschen 的回复:http://blog.csdn.net/jiangjingui2011/article/details/6706967 谢谢你的回复，虽不明觉厉,但 然并卵.

引用 4 楼 Saleayas 的回复:如果一定要这么做，那么使用一个数组，把编译期和运行时联系起来。 thanks for you replay, but any clear solution/suggestions ?

如果一定要这么做，那么使用一个数组，把编译期和运行时联系起来。

如果一定要这么做，那么使用一个数组，把编译期和运行时联系起来。

实现不了，你得想其它办法。

你给宏传的参数有问题，getCtrlViaStr(i)只是用i来代替参数，所以得到PANEL_FORM_NUMERIC_i很正常。 要得到PANEL_FORM_NUMERIC_81，试着这样调用ctrID =getCtrlViaStr(81).


Question: #define

引用 11 楼 chehw_1 的回复:[quote=引用 10 楼 wsdxyz 的回复:] 请问 如何获得 #define PANEL_FORM_NUMERIC_81 的地址?谢谢！  #define的功能只是文本的替换，宏名称没有地址。  i = 81;  i的值（81）是在程序运行后才知道的，预编译期不可能知道“81”这个数（除非你自己写个特定的编译器），所以没法把“81”这个数值替换进去。  想实现你想要的结果，通常需要自己写个映射：   #define getCtrlViaStr(n) PANEL_FORM_NUMERIC_##(n)  static inline int map_ctrl(int i) { switch(i) { case 81:  return getCtrlViaStr(81);  // 直接写PANEL_FORM_NUMERIC_81也行 case 0: return getCtrlViaStr(0);  case 1: return getCtrlViaStr(1);  ... default:   break; } return -1; }   i = ...;  ctrlID = map_ctrl(i);    [/quote] 谢谢！

引用 9 楼 jackydi 的回复:[quote=引用 7 楼 Minikinfish 的回复:] =1~10,j=1~10,   GetContrl( "PANEL_FORM_NUMERIC_" i j)  用这个 _stprintf("PANEL_FORM_NUMERIC_%d%d" i j);  他的目的应该不是获取这个字符串，而是这个字符串所代表的宏，所以像你楼下所说的那样，使用一个映射表应该是比较好的方法。[/quote] 请问 如何获得 #define PANEL_FORM_NUMERIC_81 的地址?谢谢！

引用 7 楼 Minikinfish 的回复:=1~10,j=1~10,   GetContrl( "PANEL_FORM_NUMERIC_" i j)  用这个 _stprintf("PANEL_FORM_NUMERIC_%d%d" i j);  他的目的应该不是获取这个字符串，而是这个字符串所代表的宏，所以像你楼下所说的那样，使用一个映射表应该是比较好的方法。

引用 10 楼 wsdxyz 的回复:请问 如何获得 #define PANEL_FORM_NUMERIC_81 的地址?谢谢！  #define的功能只是文本的替换，宏名称没有地址。  i = 81;  i的值（81）是在程序运行后才知道的，预编译期不可能知道“81”这个数（除非你自己写个特定的编译器），所以没法把“81”这个数值替换进去。  想实现你想要的结果，通常需要自己写个映射：   #define getCtrlViaStr(n) PANEL_FORM_NUMERIC_##(n)  static inline int map_ctrl(int i) { switch(i) { case 81:  return getCtrlViaStr(81);  // 直接写PANEL_FORM_NUMERIC_81也行 case 0: return getCtrlViaStr(0);  case 1: return getCtrlViaStr(1);  ... default:   break; } return -1; }   i = ...;  ctrlID = map_ctrl(i);

或者自己写一个map映射关系

使用宏的方式应该是不能达到你的目的的，使用其他方式吧。

引用 1 楼 jackydi 的回复:使用#和##符号实现，具体使用方法在网上搜  你好，我想实现的功能如下， 将其中的81 变更为变量: #define getCtrlViaStr(n) PANEL_FORM_NUMERIC_##(n);   ctrlID=getCtrlViaStr((81));   SetCtrlAttribute (panelHdlFormula, ctrlID, ATTR_CTRL_MODE, VAL_HOT);  但是变量代替后,如： i=81;  ctrID =getCtrlViaStr(i);  获得的值是 PANEL_FORM_NUMERIC_i , 而不是想要的  PANEL_FORM_NUMERIC_81; 请问这个如何实现 ？  谢谢！

#define getCtrlViaStr(n) PANEL_FORM_NUMERIC_##(n); ctrlID=getCtrlViaStr((81)); SetCtrlAttribute (panelHdlFormula, ctrlID, ATTR_CTRL_MODE, VAL_HOT);  我想实现的是 81 用 一个变量代替, i=81; 如 ctrID =getCtrlViaStr(i);  但是 这样之后，获得的值是 PANEL_FORM_NUMERIC_i , 而不是 PANEL_FORM_NUMERIC_81; 请问这个如何实现 ？ 谢谢！

引用 楼主 wsdxyz 的回复:已有CVI 控件清单(p1), 类型为int, 如何根据其 名称 来循环调用所有 控件？ 如： i=1~10,j=1~10,  GetContrl( "PANEL_FORM_NUMERIC_" i j) ...   #define getCtrlViaStr(n) PANEL_FORM_NUMERIC_##(n);  ctrlID=getCtrlViaStr((81));  SetCtrlAttribute (panelHdlFormula, ctrlID, ATTR_CTRL_MODE, VAL_HOT);  我想实现的是 81 用 一个变量代替,如： i=81; ctrID =getCtrlViaStr(i);  但是 这样之后，获得的值是 PANEL_FORM_NUMERIC_i , 而不是 PANEL_FORM_NUMERIC_81; 请问这个如何实现 ？  谢谢！

使用 宏循环来做这个。直接使用源代码展开。 但是不建议。  因为宏是预编译期的，而你的要求是运行时的。 运行时宏是看不到的。

使用#和##符号实现，具体使用方法在网上搜


Question: 怎样让输入3接着12的操作而且能够返回

引用 3 楼 DJYLSY 的回复:还有为啥我在输入函数里改成%D输入然后调用显示数据函数就输出的全部是0？ 你是怎么修改的？怎么输入的？按照我给你修改的输入有问题？

还有为啥我在输入函数里改成%D输入然后调用显示数据函数就输出的全部是0？

为啥输入的数据和显示的数据有一个不相同啊？

#include<stdio.h> #define N 2 #define M 4 float score[M][N]={0}; float cla[M]={0},people[N]={0}; int main() {     void input(void);     void aver1(void);     void aver2(void); 	void data(void); 	char ch; 	printf("1:输入数据\n2:显示数据\n3:计算每个人的平均成绩\n4:计算每门课的平均成绩\n5:返回\n");	 	scanf("%c",&ch); 	getchar(); 	while(ch!=0) 	{ 		switch(ch) 		{ 		case '1':input(); 		case '2':data(); 			break; 		case '3':aver2();break; 		case '4':aver1();break; 		case '5':return 0;break; 		} 		printf("1:输入数据\n2:显示数据\n3:计算每个人的平均成绩\n4:计算每门课的平均成绩\n5:返回\n"); 		 		scanf("%c",&ch); 		getchar(); 	}  }  void input(void) {     int i,j;     for(i=0;i<N;i++)     {         printf("\nthe score of student %2d:",i+1001);         for(j=0;j<M;j++)             scanf("%f5",&score[i][j]);     } 	getchar(); } void data(void) { 	int i,j; 	printf("\nNO.     cour1   cour2    cour3   cour4   aver\n"); 	for(i=0;i<N;i++) 	{ 		printf("NO%2d",i+1001); 		for(j=0;j<M;j++) 			printf("%8.2f",score[i][j]); 	} }  void aver1(void) {     int i,j;     float s[N] = {0.0};     for(i=0;i<N;i++)     {         for(j=0;j<M;j++)             s[i]+=score[i][j];         people[i]=s[i]/(float)M;     } 	for(i=0;i<N;i++)     {         printf("NO%2d",i+1001);         for(j=0;j<M;j++) 			printf("%8.2f\n",people[i]);     } 	     printf("\naverage:"); } void aver2(void) {     int i,j;     float s[M] = {0.0};     for(j=0;j<M;j++)     {         for(i=0;i<N;i++)             s[j]+=score[i][j];         cla[j]=s[j]/(float)N;     } 	for(j=0;j<M;j++)         printf("%8.2f",cla[j]);     printf("\n"); }


Question: 汉诺塔问题:求大神指点递归函数中的堆栈是怎么运行的

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

这图看上去确实头痛,讲递归画栈反而把问题搞复杂了 1) 假设3个盘(A,B,C) 如果前2个盘移动到C(显然是从A 通过B, 到C),同理也可以把前2个盘移动到B(从A通过C到B,对称), 换句话说就是前两个盘从所有柱子可以通过另一个柱子到目标柱子, 现在假定前2个盘移动了C, 下一步就3号盘移动B, 现在1.2在C柱就可以通过A移动到B, 从而完成移动 2) 如果4个盘, 前3个盘按上面方法移动到B, 把4移动到C, 然后从B通过A到C, 整个过程都是对称的, 递归函数就很好写了,如果还不明白,再看一下上面1)


要想写磁盘速度尽量快，还是换块固态硬盘更靠谱。

《Windows核心编程》

引用 1 楼 zhao4zhong1 的回复:O_DIRECT|O_ASYNC 如果用单进程同时发送10个写请求到设备上，使用O_DIRECT打开设备，发现是完成一个再发送下一个，本来打算看看aio能否达到同时下发的目的，发现也不行，您在我的另一个帖子里面说用进程同步，我试来一下，多进程同步确实可以达到多个请求同时下发的目的，但我现在碰到另一个问题，就是使用多进程后，由于其并发性难以预测，对后面请求的下发顺序有影响，就是本来都是按下发时间进行顺序的，后来用多进程并发，后面的顺序难以保证了，不知道大师可否帮我一下，苦逼学生党啊


Question: 请教一下，这个C程序，运行后，为什么输入100printf不出来

C语言比较 大小的运算符 ，关系运算符 为 > ,>=,<,<=,==,!= 分别表示 大于，大于等于，小于，小于等于，等于，不等于  = 是赋值运算符，用于 初始化和赋值

感谢楼上，豁然开朗

引用 1 楼 u012442535 的回复:#include <stdio.h> main() { int a=0; printf("请输入一个有效的分数（1-100）"); scanf("%d",&a); if(a<60&a>=0) printf("%d为不及格 \n",a); else if(a<80&a>=60) printf("%d为及格",a); else if(a<90&a>=80) printf("\n%d为优良\n",a); else if(a<100&a>=90) printf("%d为优秀",a); else  if(a=100&a<101) printf("满分"); }   所有的 && 都写成 & 了 最后的 a==100 写成 a=100 了


Question: N后问题，求大神帮忙改改，现在是只能显示一种正确的情况，麻烦帮忙改成能显示所有正确放置方案

只运行一次是没有递归 void n_queens(int n, int x[],int d=1){     if(d>n){         //print         return;     }     for(int i=0;i<n;i++) if(place(x,i)){         x[d] =i;         n_queens(n,x,d+1);     } }

引用 2 楼 u011672336 的回复:第一：你的函数执行完第一次就打印了。 第二：递归是递归了，你却没有清空区间内的值，导致判断语句上完全就算你全部放好了。 第三：calloc没有free(),这是个很大的坏习惯。 另外附送我所能想到的最快八皇后 /* N皇后终结版 a[N]为已占用的行编号，b[N]为右斜对角编号，c[N]为左斜对角编号*/ #include "stdio.h" #define N 8 int a[N] = {1, 1, 1, 1, 1, 1, 1, 1} , b[2 * N - 1] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} , c[2 * N - 1] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} , mark[8]; int count = 0;  int cacl(int i){ 	int j; 	if (i == N){ 		print(); 		clear(i);                                             //输出后清除第八位 		return 0; 	} 	for (j = 0; j < N; j++){                                  //递归试放皇后，cheak成功后递归，否则继续执行for 		if(cheak(i, j)){ 			cacl(i+1);			 		} 	} 		if( j == N){                                          //若for结束，仍然没能进入下层递归，清除上一位 			clear(i); 			return 0;	 		}  	return 1; }   int write(int i, int j){ 	a[j] = 0; 	b[i + j] = 0; 	c[i - j + N - 1] = 0; 	mark[i] = j;                                              //mark数组记录j的位置 	return 0; }  int clear(int i){ 	a[mark[i - 1]] = 1; 	b[i - 1 + mark[i - 1]] = 1; 	c[i - 1 - mark[i - 1] + N - 1] = 1; }  int cheak(int i, int j){ 	int z; 	if (a[j] == 0 || b[i + j] == 0 || c[i - j + N - 1] == 0){		 		return 0; 	} 	else{ 		write(i, j); 		return 1;	 	}  }  int print(){ 	int i; 	printf("%d\n", ++count); 	for (i = 0; i < N; i++) 	{ 		printf("%d ", mark[i]); 	} 	printf("\n");  	 }  int Quess() { 	cacl(0); 	return 0; }  非常感谢您提出的三点，学习了

引用 1 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }  能否麻烦您在我的代码上修改成能显示全部情况的N皇后呢

引用 2 楼 u011672336 的回复:第一：你的函数执行完第一次就打印了。 第二：递归是递归了，你却没有清空区间内的值，导致判断语句上完全就算你全部放好了。 第三：calloc没有free(),这是个很大的坏习惯。 另外附送我所能想到的最快八皇后 /* N皇后终结版 a[N]为已占用的行编号，b[N]为右斜对角编号，c[N]为左斜对角编号*/ #include "stdio.h" #define N 8 int a[N] = {1, 1, 1, 1, 1, 1, 1, 1} , b[2 * N - 1] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} , c[2 * N - 1] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} , mark[8]; int count = 0;  int cacl(int i){ 	int j; 	if (i == N){ 		print(); 		clear(i);                                             //输出后清除第八位 		return 0; 	} 	for (j = 0; j < N; j++){                                  //递归试放皇后，cheak成功后递归，否则继续执行for 		if(cheak(i, j)){ 			cacl(i+1);			 		} 	} 		if( j == N){                                          //若for结束，仍然没能进入下层递归，清除上一位 			clear(i); 			return 0;	 		}  	return 1; }   int write(int i, int j){ 	a[j] = 0; 	b[i + j] = 0; 	c[i - j + N - 1] = 0; 	mark[i] = j;                                              //mark数组记录j的位置 	return 0; }  int clear(int i){ 	a[mark[i - 1]] = 1; 	b[i - 1 + mark[i - 1]] = 1; 	c[i - 1 - mark[i - 1] + N - 1] = 1; }  int cheak(int i, int j){ 	int z; 	if (a[j] == 0 || b[i + j] == 0 || c[i - j + N - 1] == 0){		 		return 0; 	} 	else{ 		write(i, j); 		return 1;	 	}  }  int print(){ 	int i; 	printf("%d\n", ++count); 	for (i = 0; i < N; i++) 	{ 		printf("%d ", mark[i]); 	} 	printf("\n");  	 }  int Quess() { 	cacl(0); 	return 0; }  能否麻烦您在我的代码上修改成能显示全部情况的N皇后呢


Question: 老和尚汉诺的问题（在思路上有点小问题求解答求解答谢谢）

1) 这是调用树, 要清楚一点你可以在函数入口打印一下参数 比如加上 printf("call (%d) %c->%d\n",n,one three) 这样就看得比较清楚. 2) 直接从函数名上理解相对简单一些, han（int n,char one ,char two ,char three)代表移动n个盘子从one到three, 中间通过two, 那么如果是n+1个盘子, 显然要先把n个盘子移动two, 然后把第n+1直接移动three, 然后再把前n个移动c, 函数终止条件显然是n==1


Question: 关于float 转化成字符串之后，打印出现-1.#IND00或者-1.#J的问题

算了，不研究了  sprintf(str,"%.2f",human[0].score3);        sprintf(strtemp,"%.2f,%.2f",human[0].score2,human[0].score1); strcat(str,strtemp); printf(str); 这样就没问题，奇怪  先结贴

浮点数可能除以了0

应该是没有获取到human[0].score3，而你的human又没有初始化，所以才会输出错误

To set a breakpoint when a variable human[0].score3 changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable human[0].score3. Click OK to set the breakpoint.

把数据库获取数据原先赋给human[0].score3的值赋给human[0].score2,看看是否正常. 正常则是你数据库获取数据有问题或是对human[0].score3操作有问题.


Question: 用for编写一个程序

引用 7 楼 sholber 的回复:声明一下，我的上一个回复不得转载。是我从自己的书上摘录的，你要转载的话，不是朕找你，恐怕闹出格的话出版社会找你。

这个题目并不简单，因为涉及到字符集和字符编码的问题。而且Linux和Windows下的编写规则都不太一样。 以下是一个通用的解决方案： # include <locale.h> # include <wchar.h> # include <wctype.h>  # if defined (PWINDOWS) #     define LOCSTR ".936" # elif defined (PLINUX) #     define LOCSTR "zh_CN.UTF-8" # else #     define LOCSTR "C" # endif // defined  int main (void) {     setlocale (LC_ALL, LOCSTR);     for (int x = 0; x < 2; x ++) wprintf (L"中国\n");     return 0; }  宽字符的编码方案和具体使用的是哪个国家的语言文字无关，但是程序的执行和宽字符的具体操作就不能不考虑这些因素。特别是，如果需要一个从宽字符到多字节字符的转换（在本程序中，wprintf函数就执行这种转换），则必须指定多字节字符集（代码页）。为此，程序中就需要调用setlocale函数来设置和区域有关的参数，很多宽字符处理函数的执行都会受这些参数的影响。以下是该函数的原型： # include <locale.h> char * setlocale (int category, const char * locale); 该函数的第一个参数用于指定和区域有关的项，LC_ALL表示整个区域的所有项；第二个参数是字符串，其内容取决于C实现，用于选取同第一个参数相对应的值。对于Windows简体中文版的控制台来说，它的活动代码页是936，实际上对应于GBK字符集，所以这个字符串可以是“.936”，但也可以使用“chs”或者“chinese”；对于Linux控制台来说，它使用的是Unicode字符集，采用UTF-8编码方案，因此这个字符串可以是“zh_CN.UTF-8”。 为了使当前程序能够在Windows和Linux上编译，同时又不用修改源程序，这里使用了预处理指令（条件编译指令）。如果已经定义了宏PWINDOWS，则将宏LOCSTR定义为字符串“.936”，如果已经定义了宏PLINUX，则将宏LOCSTR定义为字符串“zh_CN.UTF-8”，如果PWINDOWS和PLINUX都未定义，则将宏LOCSTR定义为字符串“C”，它对应着每个程序启动之后的最小环境。GCC允许使用编译选项-D来预定义一个可以在编译期间使用的宏，因此，假定上述程序的源文件是exam.c，则可以在Linux上用下面的方法转换它： gcc exam.c –fwide-exec-charset=UTF-32LE –DPLINUX 相对应地，如果是在Windows上，可以使用下面的方法： gcc exam.c –fwide-exec-charset=UTF-16LE –DPWINDOWS

你想用什么语言写

我是想用双字符型来表示。

用c++编写

哦，徒手写，没注意看，需要把i<1改成 i<2

。。。楼主刚开始学习编程？请看代码：   #include <stdio.h>  void main(void) {     int  i = 0;      for (i=0; i<1; i++)     {         printf("中国\n");     } }


Question: 含有读写锁的结构无法释放

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

qp = (struct myqueue*)calloc(1,sizeof(struct myqueue));  ========不是======= qp = (struct myqueue*)calloc(1,sizeof(struct myqueue*));  继续请教，两者有什么区别，编译都能通过啊？

#include <stdio.h> #include <stdlib.h> #include <pthread.h>   pthread_t tid1,tid2,tid3,tid4;  struct job{     struct job *prev;     struct job *next;     pthread_t id; };  struct myqueue{     struct job *head;     struct job *tail;     pthread_rwlock_t qlock;  /* protect head and tail pointer */ };  struct myqueue *qp; struct job *job1,*job2,*job3,*job4;  int init_queue() {     int err;          /* initializing work queue*/	     qp = (struct myqueue*)calloc(1,sizeof(struct myqueue*)); /* calloc(): clean up */     err = pthread_rwlock_init(&qp->qlock, NULL); /* 注释掉该行，可以释放qp */     if(err != 0)     	return err;          /* initializing jobs */         job1 = (struct job*)calloc(1,sizeof(struct job*));     job2 = (struct job*)calloc(1,sizeof(struct job*));     job3 = (struct job*)calloc(1,sizeof(struct job*));     job4 = (struct job*)calloc(1,sizeof(struct job*));	 }   int main() {     /* 1.initializing queue and jobs */     init_queue();                  pthread_rwlock_destroy(&qp->qlock);	     free(qp);  /* 该行出现问题 */            return 0; }

提供一下程序吧 ...


Question: 怎么将这个程序用主函数和trans函数表示，trans函数将行列式转置

#include<stdio.h> #include <stdlib.h>  int** trans(int a[][3], int n) {     int **ret, i, j;     ret = (int**)malloc(3*sizeof(int*));     for (int i = 0; i < 3; i ++) {         ret[i] = (int*)malloc(n * sizeof(int));         for (j = 0; j < n; j ++) {             ret[i][j] = a[j][i];         }     }     return ret; }  int main() {     int a[2][3];     int i,j;     for(i=0;i<2;i++)     {         printf("请输入第行%d数:",i+1);         for(j=0;j<3;j++)         {             scanf("%d",&a[i][j]);         }     }             for(j=0;j<3;j++)     {         for(i=0;i<2;i++)         {             printf("%d\t",a[i][j]);         }         printf("\n");     }     int** t = trans(a, 2);     for (i = 0; i < 3; i ++) {         for (j = 0; j < 2; j ++)             printf("%d\t", t[i][j]);         printf("\n");     } }


Question: web压力测试原理是什么?_?

引用 2 楼 zhao4zhong1 的回复:这方面是有开源项目的。 引用 6 楼 mxway 的回复:webbench是开源的

webbench是开源的

ab和siege是最常见的压力测试工具

ab命令可以吗。。

引用 2 楼 zhao4zhong1 的回复:这方面是有开源项目的。  有没有简单的实现，先看个简单的。

这方面是有开源项目的。

使用多线程模拟多个客户的并发请求。计算服务器的响应时间和吞吐量。


Question: 最匹配的重载方法具有一些无效参数

引用 7 楼 northwesternwind 的回复:[quote=引用 6 楼 u012404135 的回复:] [quote=引用 5 楼 northwesternwind 的回复:] [quote=引用 4 楼 u012404135 的回复:] [quote=引用 3 楼 user-3 的回复:] SqlHelper.ExecuteReader() 参数不匹配 第一个参数，要求的是类型为string 第二个，类型是CommandType 第三个，string 你调用的第三个参数类型有问题，是否第一、二个顺序反了，查查示例程序吧 我还是不太懂啊，你说说如果第一，二个顺序反了应该怎么修改，[/quote] 额滴神呀，顺序反了怎么改？改顺序呀！！！[/quote] 修改了又出现一个错误 错误1	参数 3: 无法从“System.Data.SqlClient.SqlParameter[]”转换为“string”	 帮我看看参数三怎么修改，谢谢[/quote] 需要看SqlHelper.ExecuteReader的定义才能知道到底为啥错了。[/quote]     都不懂

引用 6 楼 u012404135 的回复:[quote=引用 5 楼 northwesternwind 的回复:] [quote=引用 4 楼 u012404135 的回复:] [quote=引用 3 楼 user-3 的回复:] SqlHelper.ExecuteReader() 参数不匹配 第一个参数，要求的是类型为string 第二个，类型是CommandType 第三个，string 你调用的第三个参数类型有问题，是否第一、二个顺序反了，查查示例程序吧 我还是不太懂啊，你说说如果第一，二个顺序反了应该怎么修改，[/quote] 额滴神呀，顺序反了怎么改？改顺序呀！！！[/quote] 修改了又出现一个错误 错误1	参数 3: 无法从“System.Data.SqlClient.SqlParameter[]”转换为“string”	 帮我看看参数三怎么修改，谢谢[/quote] 需要看SqlHelper.ExecuteReader的定义才能知道到底为啥错了。

引用 5 楼 northwesternwind 的回复:[quote=引用 4 楼 u012404135 的回复:] [quote=引用 3 楼 user-3 的回复:] SqlHelper.ExecuteReader() 参数不匹配 第一个参数，要求的是类型为string 第二个，类型是CommandType 第三个，string 你调用的第三个参数类型有问题，是否第一、二个顺序反了，查查示例程序吧 我还是不太懂啊，你说说如果第一，二个顺序反了应该怎么修改，[/quote] 额滴神呀，顺序反了怎么改？改顺序呀！！！[/quote] 修改了又出现一个错误 错误1	参数 3: 无法从“System.Data.SqlClient.SqlParameter[]”转换为“string”	 帮我看看参数三怎么修改，谢谢

引用 4 楼 u012404135 的回复:[quote=引用 3 楼 user-3 的回复:] SqlHelper.ExecuteReader() 参数不匹配 第一个参数，要求的是类型为string 第二个，类型是CommandType 第三个，string 你调用的第三个参数类型有问题，是否第一、二个顺序反了，查查示例程序吧 我还是不太懂啊，你说说如果第一，二个顺序反了应该怎么修改，[/quote] 额滴神呀，顺序反了怎么改？改顺序呀！！！

引用 3 楼 user-3 的回复:SqlHelper.ExecuteReader() 参数不匹配 第一个参数，要求的是类型为string 第二个，类型是CommandType 第三个，string 你调用的第三个参数类型有问题，是否第一、二个顺序反了，查查示例程序吧 我还是不太懂啊，你说说如果第一，二个顺序反了应该怎么修改，

。。在线等。。

这个怎么修改啊，小白，不太懂，求大神


Question: 图书管理系统

图形用户界面，包括登陆界面和主界面，登陆界面包括管理员登陆和普通用户登录。 主界面又分若干个操作，添加修改，删除，查询，借书信息，还书信息等， 看你需要实现什么功能了。 需要用到的SQL，图形用户界面设计，c/c++.

实用真实一点的管理系统需要数据库知识、图形用户界面编程，这两个是C++ Builder和Delphi的强项，用CB和D也是最容易的，用C#也差不多，三者只是语言不同（C++，Object Pascal，C#），其它类似。

把基本语法知识搞扎实就够了，先把基础打好！


Question: help，关于uint64类型数据的打印

引用 6 楼 LLW059 的回复:出现负数是溢出了，可以使用unsigned long long 或long long 类型，转换说明符使用"%llu"和"%lld"  多谢！结贴了

引用 1 楼 user-4 的回复:会有啥权限问题阻止你看到它的具体定义？  ==  试试 %ld 。不过看不到定义，只是瞎猜。  == 你是什么系统，什么编译器？  linux系统，gmake

引用 2 楼 yangyunzhao 的回复:理论上不可能阻止的，如果仅仅声明而不定义的话，就必须提供一大堆函数来让你使用uint64  ps，可以用unsigned long long来做吧？windows下用%I64u，linux用%llu  试一下，有结果告诉你 ：）

%llu


Question: 超市货物管理系统

如果用数据库，可以定义好数据表各字段，创建表，把数据插入数据库表。 如果用文件代替数据库，初始信息可以使用txt文本文件，可以自己定义格式，比如每一行一条商品信息，商品编号，商品名，数量，单价等等属性之间用空格或者自定义的特殊符号隔开。导入以后可以写到二进制文件，一条商品信息对应一个结构体，结构自己定义。 也可以使用XML，需要第三方的库来读写XML。

在百度搜“超市货物管理系统 C源代码”


Question: 指针跟踪数组

p + str，两个指着相加，是什么意思？

没有指针加指针的运算！ 只有指针加减一个整数，或者两个指针相减的运算 16行之所以对，是因为两指针相减后得到的是一个整数，然后就变成指针与整数相加

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


Question: C实现有向图的拓扑排序出现问题

谢谢大家了，自己动手解决了

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

建议学会自己调试，逐步运行程序，通过各种窗口观察分析

将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”.  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

拓扑的结果总是0... 求解


Question: c语言关于if判断的问题

把两个if 合并了吧 c1,c2只保留c1 简化为c 并作为参数传递

每次操作完之后清空缓冲区？

在scanf前多加一句试试  rewind(stdin); scanf("%d",&c2);

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

引用 3 楼 u011672336 的回复:当我连续几次输入1，运行的时候，再输入2.会出现多个“谢谢使用!”。这个错误的原因是因为这个动作c1运行之后，还有c2，也是依次再调用回ccc函数。  调用回自己这是一个递归，递归的含义是什么请寻找度娘。只能说你调用几次自己就会出现调用次数+1次的“谢谢使用”，其次我认为你的基础架构知识有很严重的偏差，为什么连打开文档都会了就不会switch函数呢………………还有，算了……没了，程序看得很头疼，没主函数没返回值……上次有好多大神告诉我，只贴有问题的地方。所以这次在贴了这个地方，其他的太多了，看起来会更头疼。

引用 1 楼 lm_whales 的回复:感觉你做复杂了求指点.......

感觉你做复杂了


Question: 学生成绩系统问题

print函数的参数也要改成指针形式的

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

试了，没有用~~ 感觉应该不是这个问题吧

void input(struct student* stu)  //函数头改成这样！

楼主，替换一行：float pro[0], pro[1], pro[2], pro[3]; 替换为：float pro[4]; 先这样改着试试，要把代码贴上来！！！


Question: 矩阵操作（新手上路，各位好心的帮帮忙吧）

谢谢你的帮助，虽然那个并不是我想要的，第一次发帖有人回还是很高兴，谢谢你

可是在百度里找不到，如果你有代码，可以请你发个链接给我吗？麻烦你了

在百度搜“矩阵操作 C源代码”


Question: 【加急】大神们，指点一下，应该怎么做，

引用 4 楼 user-2的回复:建议：不要一上来就直接要整个实现的代码，自己先写，有什么问题可以贴代码上来问，这样才能学到东西 嗯嗯，好的，谢谢老师的建议

引用 3 楼 赵4老师的回复:“仅供参考”的意思不是“这是一种答案” 嗯嗯，我晓得了，谢谢老师指导

再供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

“仅供参考”的意思不是“这是一种答案”

谢谢一楼老师的回复，但是你的程序跟我想要的不是一样的，你没用字符串输入多项式，麻烦你仔细看一下题意

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }


Question: c

楼主只是没将代码放在对应的虚拟机里面编译而已。

app store 里搜索 C++ Programming Language

只要不调用api或其他一些平台特性就可以

引用 1 楼 赵4老师的回复:可以 可我把一些游戏代码复制上去运行不了(贪吃蛇，21点)

引用 3 楼 醉花阴柳的回复:只要不调用api或其他一些平台特性就可以 什么意思，请求详细解答

引用 1 楼 zhao4zhong1 的回复:可以 真精辟 ，是不是等级高回复字数可以少点

可以


Question: 在Visual Studio 2012中，如何找到Windows的Masked Edit控件？

引用 2 楼 Ma_shuhua 的回复:C#的，不是C++的。  那移步去C#版块提问啊

CMFCMaskedEdit只能供C#用？

C#的，不是C++的。

CMFCMaskedEdit                             支持掩码编辑控件，验证用户输入掩码并基于模板显示验证的结果。  https://msdn.microsoft.com/zh-cn/library/bk77x1wx(v=vs.110).aspx


Question: 关于const修饰的常量的修改问题

这么神奇，在我机器上，都输出3 另外建议你把 -Wall 加上

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

编译时编译器可能直接拿用立即数代替，而不是从内存地址中读取，请自己看生成的汇编

这种做法是错误的。  这种错误可能带来任何结果，包括无法理解的结果。

编译器的确为const 声名的变量分配了一个内存空间，但是在引用了该变量的地方编译器在编译时都将该变量替换为了常数，就像宏代换那样，也就是说运算用到的实际数值是在代码区存放的常数，而并非在数据空间的那个数，所以你通过指针可以修改数据空间的值并不影响a本身的值，当然不同的编译器可能是不一样的

const 的作用是你对编译器负责，编译器告诉你，如何使用可能会出错。 一旦你用了const 关键字，表明你跟编译器签订了条约。 你确信，你的代码里，不会出现修改const 修饰的那个对象的值的代码。 一旦出现修改const 修饰的那个对象的值，那就是你想错了，或者笔误，请编译器给你指出错误。 而不是相反，编译器不必对你写出来的const 负责； const 是约束程序员而不是编译器的。

C++ 和 C对const修饰的处理方法不一样。  你把文件名由“point.cpp”改成"point.c"，重新编译一下，再看看，就会有另一种结果。


Question: 有没有大神帮我看看这段代码具体是什么意思？

引用 6 楼 xzxlemontea 的回复:[quote=引用 5 楼 qq_33028645 的回复:] 那你这段代码需要实现什么呢？你要大致讲下啊 就分支界限法 我已经搞定了~~~[/quote] 求人不如求己。

引用 5 楼 qq_33028645 的回复:那你这段代码需要实现什么呢？你要大致讲下啊 就分支界限法 我已经搞定了~~~

那你这段代码需要实现什么呢？你要大致讲下啊

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

重新编排一下： 一下是全部代码：  #include<stdio.h> #include<stdlib.h> #include<string.h> #include <time.h> #include <assert.h>  #define MAX 32 int CITYNUM=0; const int INF=1000000000; int map[MAX][MAX]={0}; int min[MAX][2];   struct EDGE { int cost[MAX][2];/*距离*/ int sta; int lb,len; char seq[MAX]; }q[1000000];   /*求下界*/ int calc(int cost[MAX][2],int n) { int sum=0,i; for(i=0;i<n;i++) { if(cost[i][1]!=INF) { sum+=cost[i][0]+cost[i][1]; } else if(cost[i][0]!=INF) { sum+=cost[i][0]; if(cost[i][0]==min[i][0]) sum+=min[i][1]; else sum+=min[i][0]; } else { sum+=min[i][0]+min[i][1];	/*最小里面的一个，那么就是最小两个相加*/ } } if(sum&1)sum=sum/2+1; else sum/=2; return sum; }  /*挑选*/ void BFS(int s,int n) { int front=-1,rear=0; int i,step=0;  q[0].sta=1; q[0].len=1; q[0].seq[0]='a'; q[0].seq[1]=0; for(i=0;i<n;i++) q[0].cost[i][0]=q[0].cost[i][1]=INF; while(front!=rear) { int size=rear-front; step++; int min=INF; for(i=front+1;i<=rear;i++) { if(q[i].lb<min) min=q[i].lb; } while(size--) { front++;  int sta=q[front].sta;  if(q[front].lb!=min) continue;  for(i=0;i<n;i++) { int tsta; char tseq[MAX];	/*存城市*/ int tlen=q[front].len+1; strcpy(tseq,q[front].seq); tseq[tlen-1]=i+'a'; tseq[tlen]=0; if(i==2&&(sta&2)==0) { printf("%s",tseq); printf(": error,C can't before b\n"); continue; } if((1<<i)&sta) continue; tsta=(1<<i)+sta; rear++; q[rear].sta=tsta; strcpy(q[rear].seq,tseq); q[rear].len=tlen; memcpy(q[rear].cost,q[front].cost,sizeof(q[front].cost)); int from=q[front].seq[q[front].len-1]-'a';  if(q[rear].cost[i][0]==INF) { q[rear].cost[i][0]=map[from][i]; } else {  q[rear].cost[i][1]=map[from][i];  } if(q[rear].cost[from][0]==INF) { q[rear].cost[from][0]=map[from][i]; } else { q[rear].cost[from][1]=map[from][i]; } q[rear].lb=calc(q[rear].cost,n); printf("%s",tseq); printf(": lb=%d\n",q[rear].lb); } } } }   /*自动生成文件*/   int main() {  printf("请输入城市的数目（大于1的整数）："); scanf(" %d",&CITYNUM); CITYNUM=CITYNUM-1; int i = 0, ncount = CITYNUM, *val = 0; int temp; int loop; int n=0,d,cnt=0; char sa[10],sb[10]; int j;   FILE *fpp; fpp = fopen("in.dat","rb"); while(fscanf(fpp,"%s%s%d",sa,sb,&d)!=EOF)	/*文件读取*/ { sa[0]=sa[0]-'a'; sb[0]=sb[0]-'a'; if(sa[0]+1>n) n=sa[0]+1; if(sb[0]+1>n) n=sb[0]+1; map[sa[0]][sb[0]]=map[sb[0]][sa[0]]=d; cnt++; } fclose(fpp); for(i=0;i<n;i++) map[i][i]=min[i][0]=min[i][1]=INF; for(i=0;i<n;i++)	/*把每个点最小的两个找出来*/ { for(j=0;j<n;j++) { if(map[i][j]<=min[i][0]) { min[i][1]=min[i][0]; min[i][0]=map[i][j]; } else if(map[i][j]<min[i][1]) { min[i][1]=map[i][j]; } } } /*分支限界*/ BFS(0,n); }  一下是我看不懂的  void BFS(int s,int n) { int front=-1,rear=0; int i,step=0;   q[0].sta=1; q[0].len=1; q[0].seq[0]='a'; q[0].seq[1]=0; for(i=0;i<n;i++) q[0].cost[i][0]=q[0].cost[i][1]=INF; while(front!=rear) { int size=rear-front; step++; int min=INF; for(i=front+1;i<=rear;i++) { if(q[i].lb<min) min=q[i].lb; } while(size--) { front++;   int sta=q[front].sta;   if(q[front].lb!=min) continue;   for(i=0;i<n;i++) { int tsta; char tseq[MAX];    /*存城市*/ int tlen=q[front].len+1; strcpy(tseq,q[front].seq); tseq[tlen-1]=i+'a'; tseq[tlen]=0; if(i==2&&(sta&2)==0) { printf("%s",tseq); printf(": error,C can't before b\n"); continue; } if((1<<i)&sta) continue; tsta=(1<<i)+sta; rear++; q[rear].sta=tsta; strcpy(q[rear].seq,tseq); q[rear].len=tlen; memcpy(q[rear].cost,q[front].cost,sizeof(q[front].cost)); int from=q[front].seq[q[front].len-1]-'a';   if(q[rear].cost[i][0]==INF) { q[rear].cost[i][0]=map[from][i]; } else {   q[rear].cost[i][1]=map[from][i];   } if(q[rear].cost[from][0]==INF) { q[rear].cost[from][0]=map[from][i]; } else { q[rear].cost[from][1]=map[from][i]; } q[rear].lb=calc(q[rear].cost,n); printf("%s",tseq); printf(": lb=%d\n",q[rear].lb); } } } }

void BFS(int s,int n) { int front=-1,rear=0; int i,step=0;  q[0].sta=1; q[0].len=1; q[0].seq[0]='a'; q[0].seq[1]=0; for(i=0;i<n;i++) q[0].cost[i][0]=q[0].cost[i][1]=INF; while(front!=rear) { int size=rear-front; step++; int min=INF; for(i=front+1;i<=rear;i++) { if(q[i].lb<min) min=q[i].lb; } while(size--) { front++;  int sta=q[front].sta;  if(q[front].lb!=min) continue;  for(i=0;i<n;i++) { int tsta; char tseq[MAX];	/*存城市*/ int tlen=q[front].len+1; strcpy(tseq,q[front].seq); tseq[tlen-1]=i+'a'; tseq[tlen]=0; if(i==2&&(sta&2)==0) { printf("%s",tseq); printf(": error,C can't before b\n"); continue; } if((1<<i)&sta) continue; tsta=(1<<i)+sta; rear++; q[rear].sta=tsta; strcpy(q[rear].seq,tseq); q[rear].len=tlen; memcpy(q[rear].cost,q[front].cost,sizeof(q[front].cost)); int from=q[front].seq[q[front].len-1]-'a';  if(q[rear].cost[i][0]==INF) { q[rear].cost[i][0]=map[from][i]; } else {  q[rear].cost[i][1]=map[from][i];  } if(q[rear].cost[from][0]==INF) { q[rear].cost[from][0]=map[from][i]; } else { q[rear].cost[from][1]=map[from][i]; } q[rear].lb=calc(q[rear].cost,n); printf("%s",tseq); printf(": lb=%d\n",q[rear].lb); } } } }  这一段不太懂


Question: perl大数值输出请教

会计算244的847次方大约等于10进制数多少位吗？

看来无人识这个，结贴

有人懂这个吗？

已经解决，是要在cmd界面进入到perl.exe所在文件夹，如，c:\perl64\bin>perl -Mbigint -e "print 244**847%2773",即可得到所要的答案465.


Question: 一个关于while循环的问题

引用 2 楼 caterpillarous 的回复:[quote=引用 1 楼 hy09070422 的回复:] 因为你输入1，之后按的回车键被getchar接收了，程序已经执行完AddVertex(G,vp);然后才退出的。 这样 scanf("%s\n", &a); 试试 谢谢哈 一般项目中怎么处理这个问题啊 挺想知道的[/quote] 不客气，比如在有的情形下可能会输入回车键，而此时的回车键不是输入的确认，而是在程序中可能会用到，这样的话就只能用getchar了，其他情况下用scanf更多。 此处按输入习惯，没必要用getchar。 个人愚见，仅供参考。

scanf("%d",&a); 	getchar(); //接收掉\n

引用 1 楼 hy09070422 的回复:因为你输入1，之后按的回车键被getchar接收了，程序已经执行完AddVertex(G,vp);然后才退出的。 这样 scanf("%s\n", &a); 试试 谢谢哈 一般项目中怎么处理这个问题啊 挺想知道的


Question: 题目不完全，而我也没学好，求大神帮忙填空，并指导哈

同意二楼的答案。

1) traver(a,N);  2)int(*p)[M], int row  3)p[i][j]


Question: printf函数的实现

单步运行步进就可以跟踪到printf里面，如下是我跟进去的代码：   int __cdecl printf (         const char *format,         ...         ) /*  * stdout 'PRINT', 'F'ormatted  */ {     va_list arglist;     int buffing;     int retval;      _VALIDATE_RETURN( (format != NULL), EINVAL, -1);      va_start(arglist, format);      _lock_str2(1, stdout);     __try {         buffing = _stbuf(stdout);          retval = _output_l(stdout,format,NULL,arglist);          _ftbuf(buffing, stdout);      }     __finally {         _unlock_str2(1, stdout);     }      return(retval); }    里面他又调用了其他函数，这里不贴了，楼主想看可以自己跟进去看

你这是问的什么。。。


Question: 关于昨天CCF软件认证上的ACS|| Art的题目

#include <stdio.h> #define MAX 100  char graph[MAX][MAX]; char c; int weigh, heigh; int visited[MAX][MAX];  void fill(int x,int y) {     if (x < weigh && y < heigh && x >= 0 && y >= 0 && graph[y][x] != '+' && graph[y][x] != '|' && graph[y][x] != '-' && visited[y][x])     {         visited[y][x] = 0;         graph[y][x] = c;         fill(x+1,y);         fill(x-1,y);         fill(x,y+1);         fill(x,y-1);     } }  int main() {     int count, choice;     int x1, y1, x2, y2;     int x, y;     int i, j;     scanf("%d %d %d", &weigh, &heigh, &count);     for (i = 0; i < heigh; i++)         for (j = 0; j < weigh; j++)         {             graph[i][j] = '.';             visited[i][j] = 1;         }     while (count--)     {         scanf("%d", &choice);         switch (choice)         {             case 0:                 scanf("%d %d %d %d", &x1, &y1, &x2, &y2);                 if (y1 == y2)                 {                     if (graph[y1][x1] == '|')                         graph[y1][x1] = '+';                     else                         graph[y1][x1] = '-';                     if (graph[y2][x2] == '|')                         graph[y2][x2] = '+';                     else                         graph[y2][x2] = '-';                     while ((++x1) != x2)                         graph[y1][x1] = '-';                 }                 else if (x1 == x2)                 {                     if (graph[y1][x1] == '-')                         graph[y1][x1] = '+';                     else                         graph[y1][x1] = '|';                     if (graph[y2][x2] == '-')                         graph[y2][x2] = '+';                     else                         graph[y2][x2] = '|';                     while ((++y1) != y2)                         graph[y1][x1] = '|';                 }                 break;             case 1:                 scanf("%d %d %c", &x, &y, &c);                 fill(x,y);                 break;         }     }     for (i = 0; i < heigh; i++)         for (j = 0; j < weigh; j++)         {             if (j == weigh-1)                 printf("%c\n", graph[i][j]);             else                 printf("%c", graph[i][j]);         }     return 0; }   CSDN保佑 一发上来就自己解决了 加了个visited[MAX][MAX]标志数组就好了


引用 3 楼 zhao4zhong1 的回复:你可以使用多进程并发。 我来试试，谢谢你

你可以使用多进程并发。

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

引用 1 楼 zhao4zhong1 的回复:一个执行完再发送下一个,我猜。 那么如果我想用O_DIRECT来绕过缓冲区，同时希望请求可以批量发送,有这样的方式吗？求指教啊

一个执行完再发送下一个,我猜。


Question: java的语言改用成c语言的形式，output改一下就行了。用c语言怎么改？

这个循环还是没有看懂，是怎么依次输出它的最后的4个想x【31】【30】【29】【28】

#include <stdio.h> #include <stdint.h>   #define BSWAP_32(x) ( 	((uint32_t)(x)  << 24) | \ 						(((uint32_t)(x) <<  8) & 0x00ff0000) | \ 						(((uint32_t)(x) >>  8) & 0x0000ff00) | \ 						((uint32_t)(x)  >> 24) )  void SMS4Crypt(...) {     int j;     ...         for(j = 0; j < 4; ++j)     {         *(uint32_t *)&Output[j * 4] = BSWAP_32(x[3 - j]);      } }

byte型右移24位,16位,8位没意义了吧


Question: C语言可以指定多个不同类型的可变参数吗?比如这次是int..然后下个是float,再是char这种方式?

头文件：#include <stdarg.h> type va_arg(va_list argptr, type);   void va_end( va_list argptr);   void va_start( va_list argptr, last_parm); typedef char * va_list;

可以，不过需要你自己用某种方法确定实际类型

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

引用 6 楼 yyxgs 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 参考printf函数的实现：crt\src\output.c    VS2015下是哪个文件呀？[/quote] 全盘搜索output.c 如果找不到，安装Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

引用 2 楼 zhao4zhong1 的回复:参考printf函数的实现：crt\src\output.c    VS2015下是哪个文件呀？

参考stdarg.h头文件

参考printf函数的实现：crt\src\output.c

不支持, 用c++模板或者auto


Question: 俄罗斯方块问题，求帮忙看下问题

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

你这样放大段代码上来，大家很难帮你，让别人首先看懂你的逻辑，再查处可能哪有问题，不是短时间能解决的。 还是建议你，自己别嫌麻烦，仔细看的一点点看。 单步调试，打印关键字什么的都用上，多总结，多分析。

能帮我看看么？？ 谢谢了

求帮忙啊  谢谢了

我是想帮我看看 哪里出了问题 。

网上搜“俄罗斯方块 C语言”

QQ457796406  身份验证 麻烦说下  帮忙 就行 真心谢谢了

void print_tetris(HANDLE hOut,struct Tetris* tetris) { 	//HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); 	for (i = 0; i <= 3; i++) 	{ 		b[i] = 1; //先把数组b赋值为1.调用make_Tetris函数，赋值1 表示方块  	} 	 make_Tetris(tetris);//调用制作俄罗斯方块函数，并并且将有光标指向的位置赋值为1  	for (i = tetris->x - 2; i <= tetris->x + 4; i += 2) 	{ 		for (j = tetris->y - 2; j <= tetris->y + 1; j++) 		{ 			if (a[i][j] == 1 && j > FrameY) 			{ 				gotoxy(hOut, i, j); 				printf("□");     //打印边框内的方块 			}  		}  	} 	//打印右边窗口信息 	gotoxy(hOut, FrameX + 2 * Frame_width + 3, FrameY + 1); 	printf("等级：%d", tetris->level); 	gotoxy(hOut, FrameX + 2 * Frame_width + 3, FrameY + 3); 	printf("分数：%d", tetris->score); 	gotoxy(hOut, FrameX + 2 * Frame_width + 3, FrameY + 5); 	printf("难度：%dms", tetris->speed);  } /*--------------------以上打印俄罗斯方块------------------------*/  void clear_tetris(HANDLE hOut, struct Tetris* tetris) { 	for (i = 0; i <= 3; i++) 	{ 		b[i] = 0; 	} 	make_Tetris(tetris); 	for (i = tetris->x - 2; i <= tetris->x + 4; i += 2) 	{ 		for (j = tetris->y - 2; j <= tetris->y + 2; j++) 		{ 			if (a[i][j] == 0 && j > FrameY) 			{ 				gotoxy(hOut, i, j); 				printf(" ");     //清除方块 			}  		}  	}  } /*--------------------以上清除俄罗斯方块的痕迹------------------------*/ void del_full(HANDLE hOut, struct Tetris* tetris) { 	//当一行有Frame_width-2个方块时删除这行的方块。（利用循环输出“ ”清除） 	int k, del_count = 0;//分别用于记录某行方块的个数和删除方块的行数的变量  	for (j = FrameY + Frame_height; j >= FrameY + 1; j--) 	{ 		k = 0; //赋值0 		for (i = FrameX; i <= FrameX + Frame_height; i += 2) 		{  			if (a[i][j] == 1)  //=1表示有方块，来判断该行是否满行 			{  				  k++;//用于记录该行方块的个数  				  if (k == Frame_width - 2) 				  { 					  for (k = FrameX + 2; k <= FrameX + 2*Frame_width - 2; k += 2) 					  {  						  a[k][j] = 0;//准备清除方块  						  gotoxy(hOut, k, j);//不断把该行删除 						  printf(" ");  						  Sleep(1);/*sleep()方法是使线程停止一段时间的方法。 									 在sleep 时间间隔期满后，线程不一定立即恢复执行。 									 是windows中的函数，以为毫秒计数  及间隔1ms*/  					  } 					  //当你删除方块行上有方块时，则要先清除，并且把上一行方块下落 			for (k = j - 1; k > FrameY; k--) 			{ 				for (i = FrameX + 2; i < FrameX + 2 * Frame_width - 2; i += 2) 				{ 						 if (a[i][k] == 1)//当这个有方块的时候 					{ 						 a[i][k] = 0; 						 gotoxy(hOut, i, k); 						 printf(" ");  						 a[i][k + 1] = 1; 						 gotoxy(hOut, i, k + 1); 						 printf("□");   							  } 						  } 			}  					  j++;//方块下落，在判断是否满行 					  del_count++;//记录删除行数的个数用于评分   				  }//if (k == Frame_width - 2)的那层括号 			}//if（a[i][j]==1）那层的括号 		} 	} 	tetris->score += 100 * del_count;//每删除一行得100分，就增加难度 	if (del_count > 0 && (tetris->score % 1000 == 0) || 		tetris->score / 1000 > tetris->level - 1) 	{ 		tetris->speed -= 20;//速度加快20ms 		tetris->level++;  	}               } /*--------------------以上删除满行方块并且下落一个单位的过程------------------------*/  void start_game() { 	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量  	struct Tetris t, *tetris = &t; //定义结构体指针并指向结构体变量 	unsigned char ch; //定义接受从键盘输入的变量 	tetris->count = 0;//初始化变量 	tetris->speed = 300;//定义开始的速度设为300ms 	tetris->score = 0;//初始化分数 为0 	tetris->level = 1;//等级开始为1及对应300ms速度 	/* 这里均为初始化变量*/  	while (1) 	{  		//用于产生方块 		get_number(tetris);//调用函数  		temp = tetris->number;//调用全局变量 记录 		//打印右边窗口中的方块，下一个方块的样子 		tetris->x = FrameX + 2 * Frame_width + 6; 		tetris->y = FrameY + 10; 		tetris->number = tetris->next; 		print_tetris(hOut,tetris);//打印  		tetris->x = FrameX +  Frame_width;//初始化中心方块的坐标 		tetris->y = FrameY - 1; 		tetris->number = temp;//当前方块的序号取出 		 		while (1) 		{  //控制方向 		print_tetris(hOut, tetris);//打印方块 			Sleep(tetris->speed);//减慢时间 			clear_tetris(hOut, tetris);//清楚方块痕迹 			temp1 = tetris->x;//记录中心方块的坐标 			temp2 = tetris->number;//记住当前方块的序号  			if (_kbhit()) 			{     //判断是否有键盘输入 				ch = _getch();  				if (ch == 75) //按向左键，则横坐标减2 				{ 					tetris->x -= 2;  				} 				if (ch == 77)//按向右键，则横坐标加2 				{ 					tetris->x += 2;  				} 				if (ch == 72)   // 向上键变体 				{ 					if (tetris->number >= 2 && tetris->number <= 3)//1字方块的变体 					{ 						tetris->number++; 						tetris->number %= 2; 						tetris->number += 2;  					} 					if (tetris->number >= 4 && tetris->number <= 7)//T字方块的变体 					{  						tetris->number++; 						tetris->number %= 4; 						tetris->number += 4;  					} 					if (tetris->number >= 8 && tetris->number <= 11)//Z字方块的变体 					{ 						tetris->number; 						tetris->number %= 4; 						tetris->number += 8;  					}  					if (tetris->number >= 12 && tetris->number <= 15)//7字方块的变体 					{  						tetris->number++; 						tetris->number %= 4; 						tetris->number += 12;  					} 					if (tetris->number >= 16 && tetris->number <= 19)/*向左的7字方块 																		   变体*/ 					{ 						tetris->number++; 						tetris->number %= 4; 						tetris->number += 16;  					} 				}   			}//if (ch == 72)的括号 				     			  			tetris->y++;//没有指令，向下移动 			if (if_moveable(tetris) == 0)//向下移动不能移动 			{ 			 				tetris->y--; 				print_tetris(hOut, tetris); 				del_full(hOut,tetris); 				break; 			} 			        		} 		for (i = tetris->y - 2; i < tetris->y + 2; i++) 		{            //当方块碰到顶部的时候，结束游戏 			if (i == FrameY) 			{ 				j = 0;//游戏结束 			}  		}  		if (j == 0)//游戏结束 		{ 			system("cls"); /*执行控制台命令cls，就是CMD下 						     面的cls，功能是清屏，清除所有显示的信息。*/ 			_getch(); 			break;  		}  		//清除提示的下一个方块的信息 		tetris->number = tetris->next; 		tetris->x = FrameX + 2 * Frame_width + 6; 		tetris->y = FrameY + 10; 		clear_tetris(hOut, tetris);  	}  } void main() { 	 	make_Gamewindow(); 	start_game(); 	 }    只有几种特定的方块 可以继续游戏   我不知道 哪里错了  可以有人帮我么？？  上面的边框 不能发送  所以没有边框  我的QQ457796406  求大神 帮帮我  我给你 有边框 的代码  我真的不太会了


Question: 大神们对这道题有什么见解，下生想学习学习,超级感谢！

引用 3 楼 fly_dragon_fly 的回复:用Bresenham画线算法即可 说的对

用Bresenham画线算法即可

线段(X1,Y1)-(X2,Y2)上的点(X,Y)满足： X=X1*t+(X2-X1)*(1-t) Y=Y1*t+(Y2-Y1)*(1-t) 其中t=0～1

用二维数组(初始化为0)模拟整个屏幕，对在两点间的数组元素赋值1，最后循环二维数组并输出星号或空格


Question: 有个问题，一直很好奇黑客是怎么把木马程序文件部署用户电脑上的？

肯定是用户自己下载的啊，躲杀软还不好说，直接引导用户将此软件标记为信任，或者引导用户关闭或者卸载杀软不就好了。

钓鱼网站是不需要认证也不需要方在用户电脑上的， DNS劫持也不需要

方在→放在


Question: 相容类型的相容如何理解

引用 10 楼 qq_29120981 的回复:[quote=引用 8 楼 均陵鼠侠的回复:] const char **和char **相不相容暂且不说，但它们符合除相容之外的所有条件。两个操作数都是指向无限定符，左边指针的指向类型(const char *)具有右边指针指向类型(char *)的全部限定符[/quote]  你只知其一，不知其二。类型兼容（相容）是一回事，赋值是另一回事。左边指针的指向类型具有右边指针指向类型的全部限定符是赋值表达式的额外要求，和两个类型是否兼容还不一样。

引用 9 楼 qq_29120981 的回复:[quote=引用 7 楼 fefe82的回复:]相同的类型是相容的。不同的类型通常是不相容的。  const char ** 与 char ** 被指向的类型为 const char* 与 char * 左右指向的是无限定符的不相容类型(const char * 与 char *)  const char * 与 char * 被指向的类型为 const char 与 char 左右指向的是有限定符(const) 和 无限定符的相容类型(均为 char)，且左侧有右侧的全部限定符。  注意这里是对指针指向的类型的要求，而不是要求两个指针类型本身的要求。 const int a，这个a的类型算int 还是算const int？如果算const int那问什么const char *和char *(前者指向const char后者指向char)明明指向的类型不同为何还要说它们指向相同类型char？如果算int，那么const char **和char **(前者指向const chat *后者指向char *)所指向的类型就都是char *？？[/quote]  1，在C中，任何类型和它的限定版本都是截然不同的类型，因此，int和const int是不同的类型，这点没有任何疑问。 2，const char *和char *是不同的类型。因为这两个指针指向的类型不同。 3，const char * *和char * *也是不同的类型，前者指向const char *，后者指向char *。两个指针兼容的唯一条件是它们指向的类型是兼容的。

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

引用 11 楼 fefe82的回复:const char * 与 char * 是不相容的类型。因为他们指向的类型（一个是 const char ，一个是 char ），不同。  他们不是有限定符和无限定符的相容类型：char * 加上 const 限定符是 char *const ； const char * 加上const 限定符是 const char * const 。  const char * 与 char * 都没有（顶层的） const 限定符。  =====  const int a1; int const a2; const int *pa3; int const *pa4; int *const pa5;  a1 与 a2 类型是相同的。 pa3 与 pa4 的类型是相同的。 但 pa5 具有与 pa3 和 pa4 不同的类型。  a1 a2 pa5 是有（顶层的）限定符的，但是 pa3 和 pa4 没有（顶层的）限定符。  pa3 和 pa4 只是指向了一个有限定的类型，但是他们本身并没有限定符。 感谢大家的回答，我想这篇博文能够解答我的疑问了 blog.csdn.net/code_crash/article/details/4854974

参数是 const 只是说明它“保证”不会修改（至于真的不会不会修改，我们不关心），那么把一个本来可以修改的内容传递给一个保证不会修改你内容的参数，这是可以理解的。然而把一个 const 内容，即本身不可修改的内容，传递给一个一定会修改内容的参数，导致你的只读数据被修改了，程序可能会崩溃。

引用 8 楼 均陵鼠侠的回复: const char **和char **相不相容暂且不说，但它们符合除相容之外的所有条件。两个操作数都是指向无限定符，左边指针的指向类型(const char *)具有右边指针指向类型(char *)的全部限定符

引用 7 楼 fefe82的回复:相同的类型是相容的。不同的类型通常是不相容的。  const char ** 与 char ** 被指向的类型为 const char* 与 char * 左右指向的是无限定符的不相容类型(const char * 与 char *)  const char * 与 char * 被指向的类型为 const char 与 char 左右指向的是有限定符(const) 和 无限定符的相容类型(均为 char)，且左侧有右侧的全部限定符。  注意这里是对指针指向的类型的要求，而不是要求两个指针类型本身的要求。 const int a，这个a的类型算int 还是算const int？如果算const int那问什么const char *和char *(前者指向const char后者指向char)明明指向的类型不同为何还要说它们指向相同类型char？如果算int，那么const char **和char **(前者指向const chat *后者指向char *)所指向的类型就都是char *？？

引用 4 楼 user-5的回复:http://bbs.csdn.net/topics/330029633 看完整个帖子后，我还是懵懂。说到底就是下面这不理解: 书上说const char**和char**不相容的原因是前者指向const char*后者指向char*，这是两个不同的类型。那么问题来了，const char *和char *，前者指向const char，后者指向char，这应该是两个不同的类型啊。为何这两个又相容呢？

书上说const char**和char**不相容的原因是前者指向const char*后者指向char*，这是两个不同的类型。那么问题来了，const char *和char *，前者指向const char 后者指向char。为何这两个又相容呢

引用 2 楼 赵4老师的回复:在我眼里，任何类型都是相容类型！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… 既然老师认为都是相容的那为何把char ** 类型的指针赋给const char **p会warning呢？

很抱歉，楼主手机版不能发帖后用网页版发帖没想到一连发了三个...对于版面的印象只能跟大家说声对不起了，还有，谁知道如何删帖吗？对于题主的问题在这个帖讨论吧，我正在找方法把发重的帖子删掉。万分抱歉


Question: 相容类型的相容如何理解


Question: 相容类型的相容如何理解