Question: 网上找的一个2048，在Dev-Cpp可编译运行，VC编译出错，谁帮我看看，谢！

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

求解

仅供参考：#include <climits> #include <cstdio> #include <cstring> #include <stack> #include <string> #include <map> #include <vector> #include <cmath>  using namespace std;  const int MAXX = 10;  int box[MAXX][MAXX];  void moveLeft(int n, bool &ret){     for (int i = 0; i < n; ++i){         for (int j = 0; j < n; ++j){             int k;             for (k = j - 1; k >= 0; --k){                 if (box[i][k] != -1){                     break;                 }             }             box[i][k + 1] = box[i][j];              if ((k + 1) != j){                 box[i][j] = -1;                 ret = true;             }         }     } }  void mergeLeft(int n, bool &ret){     for (int i = 0; i < n; ++i){         for (int j = 0; j < n - 1; ++j){             if (box[i][j] == -1)continue;              if (box[i][j] == box[i][j + 1]){                 box[i][j] *= 2;                 box[i][j + 1] = -1;                 ret = true;                 ++j;             }         }     } }  bool left(int n){     bool ret = false;     moveLeft(n, ret);     mergeLeft(n, ret);     moveLeft(n, ret);     return ret; }  void moveRight(int n, bool &ret){     for (int i = 0; i < n; ++i){         for (int j = n - 1; j >= 0; --j){ 			if (box[i][j] == -1)continue;  			int k; 			for (k = j + 1; k < n; ++k){ 				if (box[i][k] != -1){ 					break; 				} 			}  			box[i][k - 1] = box[i][j]; 			if ((k - 1) != j){ 				box[i][j] = -1; 				ret = true; 			} 		} 	} }  void mergeRight(int n, bool &ret){ 	for (int i = 0; i < n; ++i){ 		for (int j = n - 1; j >0; --j){ 			if (box[i][j] == -1)continue;  			if (box[i][j] == box[i][j - 1]){ 				box[i][j] *= 2; 				box[i][j - 1] = -1; 				ret = true; 				--j; 			} 		} 	} }  bool right(int n){ 	bool ret = false; 	moveRight(n, ret); 	mergeRight(n, ret); 	moveRight(n, ret); 	return ret; }  void moveUp(int n, bool &ret){ 	for (int j = 0; j < n; ++j){ 		for (int i = 0; i < n; ++i){ 			int k; 			for (k = i - 1; k >= 0; --k){ 				if (box[k][j] != -1){ 					break; 				} 			} 			box[k + 1][j] = box[i][j];  			if ((k + 1) != i){ 				box[i][j] = -1; 				ret = true; 			} 		} 	} }  void mergeUp(int n, bool &ret){ 	for (int j = 0; j < n; ++j){ 		for (int i = 0; i < n - 1; ++i){ 			if (box[i][j] == -1)continue;  			if (box[i][j] == box[i + 1][j]){ 				box[i][j] *= 2; 				box[i + 1][j] = -1; 				ret = true; 				++i; 			} 		} 	} }  bool up(int n){ 	bool ret = false; 	moveUp(n, ret); 	mergeUp(n, ret); 	moveUp(n, ret); 	return ret; }  void moveDown(int n, bool &ret){ 	for (int j = 0; j < n; ++j){ 		for (int i = n - 1; i >= 0; --i){ 			if (box[i][j] == -1)continue;  			int k; 			for (k = i + 1; k < n; ++k){ 				if (box[k][j] != -1)break; 			}  			box[k - 1][j] = box[i][j];  			if ((k - 1) != i){ 				box[i][j] = -1; 				ret = true; 			} 		} 	} }  void mergeDown(int n, bool &ret){ 	for (int j = 0; j < n; ++j){ 		for (int i = n - 1; i > 0; --i){ 			if (box[i][j] == -1)continue;  			if (box[i][j] == box[i - 1][j]){ 				box[i][j] *= 2; 				box[i - 1][j] = -1; 				ret = true; 				--i; 			} 		} 	} }  bool down(int n){ 	bool ret = false; 	moveDown(n, ret); 	mergeDown(n, ret); 	moveDown(n, ret); 	return ret; }  void line(int n){ 	for (int i = 0; i < n; ++i){ 		printf("--------"); 	} 	printf("-"); 	printf("\n"); }  void print(int n){ 	for (int i = 0; i < n; ++i){ 		line(n); 		for (int j = 0; j < n; ++j){ 			printf("|"); 			if (box[i][j] == -1){ 				printf("\t"); 				continue; 			}  			printf("%2d\t", box[i][j]); 		} 		printf("|"); 		printf("\n"); 	} 	line(n); }  bool isFull(int n){ 	bool mark = true; 	for (int i = 0; i < n; ++i){ 		for (int j = 0; j < n; ++j){ 			if (box[i][j] == -1){ 				mark = false; 				return mark; 			} 		} 	} 	return mark; }  bool isOver(int n){ 	if (!isFull(n)){ 		return false; 	} 	for (int i = 0; i < n; ++i){ 		for (int j = 0; j < n; ++j){ 			if (box[i][j] == box[i][j + 1] || box[i][j] == box[i + 1][j]){ 				return false; 			} 		} 	} 	return true; }  void fillBox(int n){ 	int i, j, num;  	if (isFull(n)){ 		return; 	}  	while (true){         i = rand() % n;         j = rand() % n;         num = rand() % 2 == 0 ? 2 : 4;          if (box[i][j] == -1){             box[i][j] = num;             break;         }     } }  int main(){     //freopen("in.txt", "r", stdin);     memset(box, -1, sizeof(box));      int n;     bool mark;     scanf("%d%*c", &n);      fillBox(n);     fillBox(n);     print(n);      while (true){         char ch;         scanf("%c%*c", &ch);         if (ch == 'a'){             mark = left(n);         }         else if (ch == 'd'){             mark = right(n);         }         else if (ch == 'w'){             mark = up(n);         }         else if (ch == 's'){             mark = down(n);         }         else{             continue;         }         system("cls");         printf("Move:\n");         print(n);         if (!mark){             continue;         }         fillBox(n);         printf("Fill:\n");         print(n);          if (isOver(n)){             printf("\n\nGame Over!\n\n");             break;         }     }      return 0; }

学会调试，双击错误处……

控制台的2048我早就写过啦！没有界面，玩了伤眼啊


Question: C语言读取文本内容并分割到指定文本

才50行不到的代码，很好理解的，加油！

引用 7 楼 zhangxiangDavaid 的回复:这样可好：  #include <stdio.h> #include <string.h> FILE *f, *fset; char name[10]; char buf[256]; int i; int main(void) { 	if (NULL == (f = fopen("1.txt", "r"))) 	{ 		fprintf(stderr, "Unable to open file!\n"); 		return 1; 	} 	i = 1; 	sprintf(name, "set%d.txt", i++); 	if (NULL == (fset = fopen(name, "w"))) 	{ 		fprintf(stderr, "Unable to open file!\n"); 		return 1; 	} 	while (1) 	{ 		if (NULL == fgets(buf, 255, f)) break; 		if (strstr(buf, "set")) 		{ 			fclose(fset); 			sprintf(name, "set%d.txt", i++); 			if (NULL == (fset = fopen(name, "w"))) 			{ 				fprintf(stderr, "Unable to open file!\n"); 				return 1; 			} 		} 		fprintf(fset, "%s", buf); 	} 	fclose(f); 	return 0; }  Perfect！谢谢！如果可以给我讲解下就好了，谢谢

引用 10 楼 le0102 的回复:[quote=引用 9 楼 zhangxiangDavaid 的回复:] 才50行不到的代码，很好理解的，加油！ 再请教一个问题，如何获得指定的字符串呢？[/quote] 什么意思？具体点

引用 9 楼 zhangxiangDavaid 的回复:才50行不到的代码，很好理解的，加油！ 再请教一个问题，如何获得指定的字符串呢？

没读一行，看开头是不是set，等于是操作字符串

引用 4 楼 le0102 的回复:[quote=引用 2 楼 henuyx 的回复:] 一口气全读出来到一个buffer中（也可以每次读固定字节，比如10M？5M？1M？） 然后再分析这个buffer中的数据，每个set分一段即可。   ------------------ 个人理解。 不能固定字节，因为两个set之间的长度是会变的[/quote]  假如我给你一段字符串，然后告诉你这段字符串中有一些字符@，然后让你将以@分隔的字串提取出来，你会怎么做？？ 你是不是会了？  然后，现在这段字符串在文件里，而且这个特殊的字符@换成set，然后你会怎么做？ 一样道理！ 你管它每个set段多长了，尽管读出来就是了！想读多少读多少！一口气读完也没人管你！（当然前提内存受得了！） 然后你 按照set再去分段就是了。  只要注意最后一个set段可能不完整，下次读取的时候 注意就是了。   ------------------ 我不会再解释了....

引用 2 楼 henuyx 的回复:一口气全读出来到一个buffer中（也可以每次读固定字节，比如10M？5M？1M？） 然后再分析这个buffer中的数据，每个set分一段即可。   ------------------ 个人理解。 不能固定字节，因为两个set之间的长度是会变的

引用 1 楼 user-4 的回复:文件不大就全部读到内存中,, 当一个字符串处理 实际编写呢，用什么函数

文件不大就全部读到内存中,, 当一个字符串处理


Question: C语言中的变量的内存地址是不是不变的？

引用 3 楼 tangtangtangbaoli 的回复:计算机内存区分全局静态区,堆区,代码区,还有栈区,你的这段代码的二进制指令放在代码区,里面定义的这些变量,都在内存的栈区,可以直接对栈的内存的内容赋值谢谢大师，我懂了，谢谢

引用 1 楼 blueln 的回复:在一次运行过程中，操作系统为变量分配好空间后，变量地址就不变了。恩恩，我懂了，谢谢大神哈

int a; int * p = &a;

&a   变量a的地址 &b   变量b的地址

在一次运行过程中，操作系统为变量分配好空间后，变量地址就不变了。


Question: C语言中PlaySound的使用

楼上正解，要包含额外的库文件。

调用PlaySound函数需要加载头文件和库文件： #include <mmsystem.h>  #pragma comment(lib, "winmm.lib") 你不贴错误，让别人怎么看。另外playsound只能播放单个wav音频文件

第一，用MSDN而不是xxxx


Question: 关于内存，malloc的一个问题，在很多地方调用了malloc，但是有，也只有一个地方报错了

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

引用 6 楼 todo9351 的回复:malloc都是要判断返回值的，先在每次 malloc 之后检查一下返回值，可能是程序的堆栈设置过低，或者其他地方分配了巨大空间之类的，导致分配不出空间。  malloc返回的值不就是分配好的内存头地址吗？这个怎么检查？我都检查过了，有东西的

引用 4 楼 user-5 的回复:你不用强调新声明的 在你调用malloc之前，heap就已经被破坏了 要你跟的是这个，即对所有有操作的内存的跟踪  假如说，有一个地方的malloc造成了heap的破坏，那么我怎么看是否破坏了？  我的意思就是，调试的时候，我并不知道怎么才算是破坏了，你能给点建议吗？

引用 12 楼 yingzijuntuan 的回复:[quote=引用 11 楼 wang0635 的回复:] [quote=引用 9 楼 yingzijuntuan 的回复:] [quote=引用 8 楼 wang0635 的回复:] 126行：申请了一个struct  node_weight大小空间 131行：使用了多个，i大于0时就越界了  对于这个问题，我感觉很奇怪呢，为什么当时不报错呢？  其实我当时看到这里的时候，感觉到了很奇怪，但是，运行过去后，发现没问题，而且每个指针都有东西，所以我就没管。  我当时也觉得它是有问题的，但是为什么不报错呢？没有报指针越界的那种错误？[/quote]  C语法上不管越界的。不光越界问题，像参数传递、类型转换等，正确性都由程序员自己保证[/quote]  是的，我刚刚试过了，下面这段代码都没问题。 但是，我记得以前经常遇到指针越界的问题呀？我记得会报错的吧？不一定是这种情况下，但是，我记得如果有野指针的话，会报错的呀，是哪种情况？  int *a = (int *)malloc(sizeof(int)); 	a[0]=1; 	a[1]=2; 	printf("%d\n%d\n",a[0],a[1]);[/quote]  C语言甚至允许程序操纵内存任何位置，编译器不会报错。如果动了不该动的，是操作系统要提意见了

引用 11 楼 wang0635 的回复:[quote=引用 9 楼 yingzijuntuan 的回复:] [quote=引用 8 楼 wang0635 的回复:] 126行：申请了一个struct  node_weight大小空间 131行：使用了多个，i大于0时就越界了  对于这个问题，我感觉很奇怪呢，为什么当时不报错呢？  其实我当时看到这里的时候，感觉到了很奇怪，但是，运行过去后，发现没问题，而且每个指针都有东西，所以我就没管。  我当时也觉得它是有问题的，但是为什么不报错呢？没有报指针越界的那种错误？[/quote]  C语法上不管越界的。不光越界问题，像参数传递、类型转换等，正确性都由程序员自己保证[/quote]  是的，我刚刚试过了，下面这段代码都没问题。 但是，我记得以前经常遇到指针越界的问题呀？我记得会报错的吧？不一定是这种情况下，但是，我记得如果有野指针的话，会报错的呀，是哪种情况？  int *a = (int *)malloc(sizeof(int)); 	a[0]=1; 	a[1]=2; 	printf("%d\n%d\n",a[0],a[1]);

引用 9 楼 yingzijuntuan 的回复:[quote=引用 8 楼 wang0635 的回复:] 126行：申请了一个struct  node_weight大小空间 131行：使用了多个，i大于0时就越界了  对于这个问题，我感觉很奇怪呢，为什么当时不报错呢？  其实我当时看到这里的时候，感觉到了很奇怪，但是，运行过去后，发现没问题，而且每个指针都有东西，所以我就没管。  我当时也觉得它是有问题的，但是为什么不报错呢？没有报指针越界的那种错误？[/quote]  C语法上不管越界的。不光越界问题，像参数传递、类型转换等，正确性都由程序员自己保证

C语言不管这个

引用 8 楼 wang0635 的回复:126行：申请了一个struct  node_weight大小空间 131行：使用了多个，i大于0时就越界了  对于这个问题，我感觉很奇怪呢，为什么当时不报错呢？  其实我当时看到这里的时候，感觉到了很奇怪，但是，运行过去后，发现没问题，而且每个指针都有东西，所以我就没管。  我当时也觉得它是有问题的，但是为什么不报错呢？没有报指针越界的那种错误？

引用 2 楼 user-5 的回复:debugger加数据断点，多半哪里操作越界。  断点加过了，首先，这个变量是新申明的，然后给一个malloc的指针  不是加断点的问题，断点我加过了，就是malloc这里出问题，但是完全不知道怎么出的问题  你能帮忙看看吗？直接调试一下94行就行

debugger加数据断点，多半哪里操作越界。

错了，sorry，错误代码在94行 temp=(struct node *)malloc(sizeof(struct node ))  都不用管逻辑之类的问题，就是这个赋值有问题


Question: C语言对txt文件中某一行的某几个字符修改  和  fgets（）在vs2013怎么用

推荐一个博客可以参考一下http://blog.csdn.net/mg0832058/article/details/5890688

int main(void) { 	FILE *f1, *f2; 	f1 = fopen("1.txt", "r"); 	f2 = fopen("2.txt", "w"); 	char buf[256]; 	char *p; 	while (1) 	{ 		if (NULL == fgets(buf, 255, f1)) break; 		if (p = strstr(buf, "1234")) 		{ 			memmove(p + strlen("5678"), p + strlen("1234"), strlen(p + strlen("1234")) + 1); 			strncpy(p, "5678", strlen("5678")); 		} 		fprintf(f2, "%s", buf); 	} 	_fcloseall(); 	return 0; }

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。

把文件读入内存 对内存进行操作 将操作结果写会文件  基本上以下函数应该要会用 fopen fread/fscanf fwrite/fprintf fclose  字符串相关的函数要会用 指针操作要会


Question: 关于OJ中的Segmentation Fault

int count[1000000];这个作全局试试

不知道你n的取值范围是多少


Question: 大神帮帮忙，刚开始学的的c。老师布置的作业错了好多，大家帮忙找找

引用 6 楼 leee7338 的回复:5L威武

5L威武

修改如下：  #include<stdio.h> #include<stdlib.h> #include<conio.h> #define N 3 #define M 3 typedef struct student { 	int num; 	char name[20]; 	int score[3]; 	float average; }STU; STU stu[N]; void input(); void select(); void statistics(); void menu(); void input() { 	int i, j; 	float temp;   //zx 	printf("\t\t成绩录入\n\n"); 	for (i = 0; i < N; i++); 	{ 		temp = 0;   //zx 		printf("请输入学号："); 		scanf("%d", &stu[i].num); 		printf("请输入姓名："); 		//scanf("%s", &stu[i].name); 		scanf("%s", stu[i].name);   //zx 		for (j = 0; j < M; j++); 		{ 			printf("第%d门成绩的分数为：", j + 1); 			scanf("%d", &stu[i].score[j]); 			temp += stu[i].score[j];    //zx 		} 		stu[i].average = temp / M;   //zx 		printf("\n\n"); 	} 	printf("\n\n"); 	printf("输入完毕！按任意键返回主菜单！"); 	getch(); } void select(int no) { 	int i; 	printf("学生%d号:\n", no); 	printf("学号:%d\n", stu[no - 1].num); 	printf("姓名:%s\n", stu[no - 1].name); 	for (i = 0; i < M; i++) 	{ 		printf("第%d门的课程的成绩为：", i + 1); 		printf("%d\n", stu[no - 1].score[i]); 	} 	printf("\n按任意键返回主菜单!"); 	getch(); } void statistics() { 	int i = 0; 	int j = 0; 	/*学生成绩平均分*/ 	printf("\t\t3成绩统计\n\n"); 	printf("\n学生成绩平均分:"); 	for (j = 0; j < N; j++) 	{ 		printf("\n学生%s的成绩平均成绩为:", stu[j].name); 		printf("%0.2f分", stu[j].average); 	} 	/*排序*/ 	for (j = 1; j < N; j++) 		for (i = 0; i < N - j; i++) 			if (stu[i].average < stu[i + 1].average) 			{ 				//不可能只交换平均成绩 				//temp = stu[i].average; 				//stu[i].average = stu[i + 1].average; 				//stu[i + 1].average = temp; 				STU temp; 				temp = stu[i]; 				stu[i] = stu[i + 1]; 				stu[i + 1] = temp; 			} 	printf("\n\n学生平均成绩前三名:"); 	for (i = 0; i < 3; i++) 	{ 		printf("\n第%d名:%0.2f分", i + 1, stu[i].average); 	} 	printf("\n\n按任意键返回主菜单!"); 	getch(); } void menu() { 	int num = 0; 	int n = 0; 	printf("\n\\t\t\t学生成绩管理系统\n\n"); 	printf("\t\t\t1成绩录入\n\t\t\t2成绩查询\n\t\t\t3成绩统计\n\t\t\t4退出系统\n"); 	printf("\t\t\tchoose:"); 	scanf("%d", &num); 	system("cls"); 	switch (num) 	{ 	case 1: input(); break; 	case 2: printf("\t\t2成绩查询\n\n"); printf("请输入要查询的学生号（1~3)："); scanf("%d", &n); select(n); break; 	case 3: statistics(); break; 	case 4: exit(0); 	} } void main() { 	while (1) 	{ 		system("cls"); /*清屏*/ 		menu(); 	} }

加了这个结构体还是会出错

引用 2 楼 ldplsj 的回复:需要给结构体一个对象。 struct student { int num; char name[20]; int score[3]; float average;	 }stu; stu stu[N];

需要给结构体一个对象。

void input(); void select(); void statistics(); void menu(); void input() 这些函数没有传参，也没有相互调用，就算对了又怎样，有什么意义


Question: 调用fprintf函数，中文写入文件偶尔出错

fflush清空缓冲区，把缓冲区里的东西，写入目标。

fflush Flushes a stream.  int fflush( FILE *stream );  Function Required Header Compatibility  fflush <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  fflush returns 0 if the buffer was successfully flushed. The value 0 is also returned in cases in which the specified stream has no buffer or is open for reading only. A return value of EOF indicates an error.  Note   If fflush returns EOF, data may have been lost due to a write failure. When setting up a critical error handler, it is safest to turn buffering off with the setvbuf function or to use low-level I/O routines such as _open, _close, and _write instead of the stream I/O functions.  Parameter  stream  Pointer to FILE structure  Remarks  The fflush function flushes a stream. If the file associated with stream is open for output, fflush writes to that file the contents of the buffer associated with the stream. If the stream is open for input, fflush clears the contents of the buffer. fflush negates the effect of any prior call to ungetc against stream. Also, fflush(NULL) flushes all streams opened for output. The stream remains open after the call. fflush has no effect on an unbuffered stream.  Buffers are normally maintained by the operating system, which determines the optimal time to write the data automatically to disk: when a buffer is full, when a stream is closed, or when a program terminates normally without closing the stream. The commit-to-disk feature of the run-time library lets you ensure that critical data is written directly to disk rather than to the operating-system buffers. Without rewriting an existing program, you can enable this feature by linking the program’s object files with COMMODE.OBJ. In the resulting executable file, calls to _flushall write the contents of all buffers to disk. Only _flushall and fflush are affected by COMMODE.OBJ.  For information about controlling the commit-to-disk feature, see Stream I/O, fopen, and _fdopen.  Example  /* FFLUSH.C */  #include <stdio.h> #include <conio.h>  void main( void ) {    int integer;    char string[81];     /* Read each word as a string. */    printf( "Enter a sentence of four words with scanf: " );    for( integer = 0; integer < 4; integer++ )    {       scanf( "%s", string );       printf( "%s\n", string );    }     /* You must flush the input buffer before using gets. */    fflush( stdin );    printf( "Enter the same sentence with gets: " );    gets( string );    printf( "%s\n", string ); }   Output  Enter a sentence of four words with scanf: This is a test This is a test Enter the same sentence with gets: This is a test This is a test   Stream I/O Routines  See Also   fclose, _flushall, setvbuf

引用 1 楼 赵4老师的回复:请在每个fprintf函数后面紧接一句fflush 能具体解释一下吗？

请在每个fprintf函数后面紧接一句fflush


Question: Libevent windows下没有event_set吗？

引用 2 楼 fan20065 的回复:[quote=引用 楼主 fan20065 的回复:] Linux下面知道有，但是windows下没有 event_set 吗,？没有的话那要怎么用。。。 谢谢回答。  是直接把event_assign当event_set用吗，比如下面这个，event_assign完了还需要event_base_set吗， 新手，不要太介意。。。  event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL);  event_base_set(base, &listen_ev);[/quote]  旧的libevent接口是使用一个全局event_base，即全局变量。这是不好的。尽量放弃旧得都被抛弃的函数接口 对于event，建议使用event_new。不要使用栈上的event，尽量使用堆上的。 楼主可以看一下我之前写的一个libevent使用例子http://blog.csdn.net/user-1/article/details/39670221

引用 楼主 fan20065 的回复:Linux下面知道有，但是windows下没有 event_set 吗,？没有的话那要怎么用。。。 谢谢回答。  是直接把event_assign当event_set用吗，比如下面这个，event_assign完了还需要event_base_set吗， 新手，不要太介意。。。  event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL);  event_base_set(base, &listen_ev);


Question: 用四个线程进行快速排序。可是运行结果不正确，请大家帮忙看看问题出在哪？

另外你的多线程排序思想应该是不对的吧，看看这个例子

线程入口参数用错了  //传的是数据的地址  result_code = pthread_create(&threads[idx], NULL, WorkThread, (void *) &thread_args[idx]);  //用的的是数据的地址而不是值，应该是 *(int*)arg,  或者把上句中的&去掉  switch ((int)arg)

参考： C:\Microsoft SDK\src\crt\qsort.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\qsort.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\QSORT.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c  上面的回复总和楼主的问题有≥一毛钱的关系吧。 我还不信就蹭不了≥1分！

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

楼上两位的没看清楚问题吧，这个问题和加锁一毛钱的关系都没有。

多线程加锁了没

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


Question: 很明显的闪屏

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl  学习MSDN98中自带的GDI相关例子代码。

做个图片显示， 放大缩小的时候会闪屏


Question: 编译原理的问题

参考Tiny C Compiler源代码。

符号表管理。。


Question: 请教关于Dev-C++调试的使用

你先学习一下gdb调试就全知道了。


Question: 该如何解释这个程序为什么有这样的输出结果？

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

你可以按照这种方式来理解：int main() {     struct {         int i1;         int i2;         int i3;         int i4;     } *p;      // 打出指针的地址，也就是二级指针     printf("%p\n", &p);     // 因为指针指向的内容大小为16字节     // 因此++也将指针向前移动了16字节     p++;      printf("%p\n", &p);     p++;      printf("%p\n", &p);     p++;      printf("%p\n", &p);      return 0; }

因为指针指向一个 4 个 int 的数组，那么移动的时候就是以 sizeo(int) * 4 的大小来移动的，一次 16 字节，也就是十六进制的 0x10 了。上面的所说的有些不对，这个代码是可以编译的过去的，本身就没有语法错误。只是 p 没有指向任何数组而已，而你打出来的值实际上是这个数组指针 p 的地址，打出 &p[1] 的值也是可以的，只不过即便你指针指向有效的数组，这个地址也已经越界了。在指针指向有效的数组的前提下，如果你要打出四个元素各自的地址，应该是这样的： printf("0x%p, 0x%p, 0x%p, 0x%p.\n", (*p)[0], (*p)[1], (*p)[2], (*p)[3]);

int (*p)[4]; p是一个指向int[4]的指针，既然它是一个指针，可以想象有一个数组，它的每个元素都是int[4]，而p就是指向这个数组的第一个元素 这样一来p[0]、p[1]、p[2]、p[4]都是这个数组的元素，&就是对它们取地址 &p[0]就是第一个元素的地址，也就是p指向的地址 &p[1]就是第二个元素的地址，这两个地址间应该相差sizeof(int[4])，即0x4 * 4 = 0x10，从输出中可以验证。  可以用这样的代码来类比思考： int * p; &p[0]; &p[1]；  另外可以发现，p是没有初始化的。

引用 楼主 xuefenghan2011 的回复: #include <stdio.h>  int main() { int (*p)[4]; printf("%p>>%p>>%p>>%p\n",&p[0],&p[1],&p[2],&p[4]); return 0; }   输出结果：0xb779a000>>0xb779a010>>0xb779a020>>0xb779a040 楼主认为应该是什么样的结果呢？

int main() { 	int a[4]; 	int(*p)[4] = a; 	printf("%p>>%p>>%p>>%p\n", &p[0], &p[1], &p[2], &p[4]); 	return 0; }  首先p是一指针，并非数组。p[0]的写法让人疑惑，本质是*(p+0)。 清楚了p的类型，自然就知道了p+1相对于p的差值(字节数) 答案可得

这代码不可能编译通过。 因为p没有被初始化，编译器应该可以检测出。


Question: c处理字符串相关问题有没有简便方法

malloc,realloc,free

引用 4 楼 ForestDB 的回复:不知道LZ有没有看过STL的实现，其实最核心的不过也就是根据需要malloc／free／realloc LZ完全可以将class string用struct + function重写一遍 我没看stl实现，不过估计应该也是用c的基本函数封装实现，但毕竟没看源码不敢确定。不过照你这么一说的话，那么就算是string的加号重载，可能在实现上最终也是调到realloc的。

引用 5 楼 todo9351 的回复:这个函数设计上有点问题，如果返回值是函数内部分配的空间的话，调用者怎么知道要释放呢？从函数名上仅能看出是个转换函数而已。 如下API好一点 int  intToRoman(int num, char *roman, int len); 返回是否成功。调用者预估一个最大空间就可以了。 oj上原型就是这样咯，它肯定是知道要释放的。如果自己写应该会用你建议的原型。

引用 2 楼 kakulukia 的回复:知道realloc可以重新分配，但总觉得频繁调用重分配内存函数容易出错。例如【MCMLXXVI,1976】，要realloc七次。有没有类似string加号重载功能的函数或做法呢？  oj确实，看自己想怎么练。不过似乎是c更考查编程能力，尤其是涉及二维数组、字符串什么的。 realloc不仅可以扩展内存，还可以释放部分内存，所以只要最后一次性释放不需要的内存就可以了。 另外，字符串相加同样伴随着动态内存申请，运算符重载只是为了开发方便，运行效率未必高。

可以用realloc改变分配的内存的容量。 我觉得oj是用来练手的，不是考试，用什么取决于你想练习什么，练习数据结构就不管用什么语言都可以自己去实现，练习标准库的使用就可以直接使用库函数，并且leetcode会保存你所有通过了的算法，所以你可以尝试使用不同的方法来做同一道题。以上是我个人的一些看法。


Question: strcopy实现问题

引用 2 楼 Edward2Jason 的回复:[quote=引用 1 楼 user-4 的回复:] while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？[/quote] 这人一看就是复制粘贴估计根本就没研究内容。至于你说的返回哪个都对，不是吧？你 while 里用 s1 就返回 res，while 里用 res 就返回 s1，哪能随便返回呢。

返回s1，自己测试啊

引用 6 楼 SXJIAKE 的回复:[quote=引用 2 楼 Edward2Jason 的回复:] [quote=引用 1 楼 user-4 的回复:] while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？[/quote] 这人一看就是复制粘贴估计根本就没研究内容。至于你说的返回哪个都对，不是吧？你 while 里用 s1 就返回 res，while 里用 res 就返回 s1，哪能随便返回呢。[/quote]  是的，我理解错了！谢谢指正！

引用 5 楼 SXJIAKE 的回复:的确有一个错误是应该 return s1; 但楼主的疑惑明显不在于此。由于 while (a = b) 是先执行 b 赋值给 a 再判断 a 是否为零，所以这段代码，while (*(res++) = *(s2++)); 实际上尾零 '\0' 复制给 res 了之后，该循环才终止。  是的，应该return s1，这点错了！ 后面的一点跟我的理解一样，所以while (*(res++) = *(s2++)); 是可以对的！谢谢！

引用 3 楼 user-4 的回复:[quote=引用 2 楼 Edward2Jason 的回复:] [quote=引用 1 楼 user-4 的回复:] while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？[/quote] 如果”return s1 或者return res都对“，那么res这个变量就完全没有必要存在了。循环结束的时候，s1还在字符串开头，res在字符串结尾。 我还是觉得while没错。楼主可以给他留言直接问他，或者自己写点代码验证一下[/quote]  恩，你说的没错！是的，应该是return s1，谢谢你！

引用 2 楼 Edward2Jason 的回复:[quote=引用 1 楼 user-4 的回复:] while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？[/quote]n那是两点...

引用 2 楼 Edward2Jason 的回复:[quote=引用 1 楼 user-4 的回复:] while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？[/quote] 如果”return s1 或者return res都对“，那么res这个变量就完全没有必要存在了。循环结束的时候，s1还在字符串开头，res在字符串结尾。 我还是觉得while没错。楼主可以给他留言直接问他，或者自己写点代码验证一下

引用 1 楼 user-4 的回复:while没错，return错了。应该是return s1  return s1 或者return res都对吧！ 看博客：http://www.cnblogs.com/chenyg32/p/3739564.html，这面说while语句是错误的，我想了半天也没搞懂错哪了？

while没错，return错了。应该是return s1


Question: 虚拟设备的驱动程序是如何被加载的？

虚拟设备虽然不是真实存在，但是可以 模拟 / 仿真 物理设备  举个例子：  最近在研究虚拟磁盘，比如要模拟物理设备的 PnP 请求，可以发 IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION 到挂载管理器来  模拟 / 仿真 PnP 这个过程。  虚拟磁盘的读写 IRP 也不一定要转发的下层设备，也可以在虚拟磁盘这一层用文件来模拟下层的存储介质。


Question: 新手问题

精度问题 详见IEEE 754

引用 3 楼 windyful 的回复:[quote=引用 1 楼 mewiteor 的回复:] float改double 首先 感谢的你回答，改为double后运行正常。 但能否解释下为什么改为double就可以了呢？[/quote] float十进制有效数字大约7位，double十进制有效数字大约15位，printf中%f默认6位小数，这里的周长要8位有效数字，所以float不够，double够。 而面积输出看起来准确，是因为0.3不能用二进制精确表示，但乘5后就可以了。

引用 1 楼 mewiteor 的回复:float改double 首先 感谢的你回答，改为double后运行正常。 但能否解释下为什么改为double就可以了呢？

这个结果没问题，有的数只能近似表示

float改double


Question: OC中关于实例变量和成员变量的区别?类方法和对象方法的区别?

本人最近开始学习OC,之前学习过一些C语言.但是在学OC时遇到了一些难题,希望大神给予答案. 第一个问题 1.    -   对象方法(动态方法) 2.   +    类方法(静态方法) 如何区别类方法和对象方法?何时何地该用哪种方法?  方法的修饰符-/+即能做区分，至于功能上的区分 -对象方法即OO的基本精神之一——封装／信息隐藏，这个需要你对OO有理解 +类方法一般用作命名空间，用以组织一组功能函数；又或用作类的工厂函数，用以产生类的对象；不管哪种，都需要有大型项目的经验，才知道如何组织程序的复杂性及使用设计模式  第二个问题: 成员变量  和  实例变量的区别? 我的理解就是成员变量就是由对象创建的,实例对象就是由类创建的.但是该在代码中如何区别呢? 网上有个答案:http://leopard168.blog.163.com/blog/static/16847184420138153296930/,但是不理解啊.  @interface Person {   NSString * name; } @end Person * you ＝ [[Person alloc] init];  则有you为实例，you有成员name。  第三个问题: 在OC中如何准确创建一个变量,有些变量带*,比如NSString * name;    但有些又不带*,比如CGFloat  a    和NSInterger  b. 问了老师,老师说是只要是C语言的基本数据类型就不需要带*.是这样吗? 他还说,其实,c中没有类和对象的说法.是吗?  这是因为NSString是个类而NSInteger并不是，虽然长得像  #if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 typedef long NSInteger; typedef unsigned long NSUInteger; #else typedef int NSInteger; typedef unsigned int NSUInteger; #endif  int a; a就是int类的实例（即int对象） 你信吗？  建议： 先学好C语言，特别是关于语言的一些基本概念，比如类型，比如变量，比如作用域，比如⋯⋯ 然后是选一门较简单的OO语言入门，比如Java 基本功打好了，OO有一定的理解了，再来看OC。


Question: c语言在多线程快速排序中的一个问题

哦我修改了一下。。 现在是这样，但是好像有问题。 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <time.h> #include <assert.h>  #define NTHR   4 #define NUMNUM 1000 #define TNUM   NUMNUM/NTHR  void sort(int *array, int left, int right) {     int i = left;     int j = right;     int key = array[left];          while(i < j)     {         while(i < j && key <= array[j])         {             j--;         }                  array[i] = array[j];                  while(i < j && key >= array[i])         {             i++;         }                  array[j] = array[i];     }          array[i] = key;     sort(array, left, i - 1);     sort(array, i + 1, right);     return; }  void quicksort(int *array, int left, int right) {     if (left >= right) return;     int i = left;     int j = right;     int key = array[left];          while(i < j)     {         while(i < j && key <= array[j])         {             j--;         }                  array[i] = array[j];                  while(i < j && key >= array[i])         {             i++;         }                  array[j] = array[i];     }          array[i] = key;     quicksort(array, left, i - 1);     quicksort(array, i + 1, right); }  void *WorkThread(void *arg) {     int *array;     quicksort(array, (int)arg * TNUM, ((int)arg + 1) * TNUM - 1);     pthread_exit(NULL); }   int main() {     int array[NUMNUM];     srand((unsigned)time(NULL));     for (int i = 0; i < NUMNUM; i++) array[i] = rand();          sort(array, 0, NUMNUM - 1);          pthread_t threads[NTHR];     int thread_args[NTHR];     int result_code, index;          clock_t start, finish;     double duration;          start = clock();     for (index = 0; index < NTHR; ++index) {         thread_args[index] = index;         result_code = pthread_create(&threads[index], NULL, WorkThread, (void *) &thread_args[index]);         assert(0 == result_code);     }          for (index = 0; index < NTHR; ++index) {         result_code = pthread_join(threads[index], NULL);         assert(0 == result_code);     }          int k;     for (k = 0; k < NUMNUM; k++)         printf("%d\n", array[k]);          finish = clock();     duration = (double) (finish - start)/CLOCKS_PER_SEC;     printf("%f\n", duration);          exit(EXIT_SUCCESS); }

没试过这方法...


Question: malloc二次使用的问题。

引用 4楼haierpro 的回复:DEBUG能运行，release不能运行，多半都是内存访问越界。  newresl->dIp=(char*)malloc(sizeof(char));   这里给dlp分配了多少内存？  sprintf(resl->sIp,"%d.%d.%d.%d",ih->saddr.byte1,ih->saddr.byte2,ih->saddr.byte3,ih->saddr.byte4); 这里又往slp写入了多少字节？内存分配少了，*4就行了～

引用 3楼弓长羊羽 的回复:这段代码想干嘛？抓包，提取源IP，目的IP，协议，然后统计数目。

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

这段代码想干嘛？

把怀疑有问题的变量值输出到日志文件，另外看一下崩溃的core文件，malloc一般不会出问题，除非内存不够用了。 内存不足会返回一个空指针，也不会出问题，只能在后面赋值的时候出错。

参考代码段: https://github.com/user-5/Senior-middle-school/blob/master/Filling%20in%20the%20gaps.c


Question: 求c语言比较简单的学生成绩管理系统

自己写的  仅供参考  //person.h #ifndef __PERSON_H__ #define __PERSON_H__ #define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <signal.h> #define SUCCESS     0 #define FAILED    (!SUCCESS) #define SIZE   sizeof(struct Employee) //全局变量 int flag=0;//返回标志 char filename[30];//要打开的文件名 //员工信息结构体 struct Employee{ 	char name[20]; 	char tel[15]; 	char sex[5];	 	char num[10]; 	char age[3]; 	struct Employee* next; };  //建立一个链表 struct Employee* creat(int n);  //主函数 int Emp_Menu(); //首页打印 int Print_Head(); //删改打印 int Print_DelRev(); //增加打印 int Print_Add(); //表头打印 int Print_Tittle(); //新建文件写入 int WriteData_wb(struct Employee *head); //在已有的文件写入 int WriteData_ab(struct Employee *head); //添加 int Emp_Add(); //删除 int Emp_Del(); //修改 int Emp_Rev(); //查询 int Emp_Que(); //返回 int Emp_Return(); //退出 void Emp_Quit();  #endif //__PERSON_H__    //person.c #include "person.h"  //首页 int Print_Head(int * num) { 	printf("\t***********************************************\n"); 	printf("\t|                 职工管理系统                |\n"); 	printf("\t*---------------------------------------------*\n"); 	printf("\t|         【1】新增        【2】删改          |\n"); 	printf("\t*         【3】查询        【4】退出          *\n"); 	printf("\t***********************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //删改画面 int Print_DelRev(int* num) { 	printf("\t******************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*   【1】删除   【2】修改   【3】返回    *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //查询画面 int Print_Que(int* num) { 	printf("\t******************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*     【1】全部查询   【2】工号查询      *\n"); 	printf("\t*                                        *\n"); 	printf("\t*     【3】模糊查询   【4】返回菜单      *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //增加画面 int Print_Add(int* num) { 	int n=0; 	printf("\t******************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*   【1】新增   【2】添加   【3】返回    *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //标题头 int Print_Tittle() { 	printf("-------------------------------------------\n"); 	printf("  工号 |   姓名    |性别|年龄|    电话     \n"); 	printf("-------------------------------------------\n"); 	return SUCCESS; }  //选择将要打开的文件 int File_name() { 	printf("\n\t◎请输入您想要打开的文件:"); 	//memset(filename,0,sizeof(filename)); 	if(scanf("%s", filename)!=1){ 		printf("\a 选择文件错误!"); 		return FAILED; 	} 	return SUCCESS; }   //生成链表，参数n是add记录数量 struct Employee *Creat() { 	printf("\n\t◎请输入要添加的数据个数:"); 	int n; 	if(scanf("%d", &n)!=1) { 		printf("\a error!"); 	} 	struct Employee *head; 	struct Employee *p1, *p2;  	system("cls"); 	for(int i=1;i<n+1;i++) { 		p1 = (struct Employee*)malloc(SIZE); 		Print_Tittle(); 		scanf("%s%s%s%d%s",p1->num,p1->name,p1->sex, 		p1->age,p1->tel); 		p1->next = NULL; 		if(i==1) { 			head = p2 = p1; 		} 		else { 			p2->next = p1; 			p2 = p1; 		} 	} 	return(head); }  //建立新文件 int WriteData_wb(struct Employee *head) { 	FILE *fp; 	struct Employee *p; 	if((fp = fopen(filename, "wb"))==NULL) 	printf("\a 打开文件错误!");	 	p = head; 	while(p!=NULL) { 		if(fwrite(p,SIZE,1,fp)!=1) { 			printf("\b 写入数据出错\n"); 			fclose(fp); 			return FAILED; 		} 		p=p->next; 	} 	fclose(fp); 	return SUCCESS; }  //在已有文件添加 int WriteData_ab(struct Employee *head) { 	FILE *fp; 	struct Employee *p; 	if((fp = fopen(filename, "ab"))==NULL) 	printf("\a 打开文件错误!"); 	p = head; 	while(p!=NULL) { 	if(fwrite(p,SIZE,1,fp)!=1) { 			printf("\b 写入数据出错\n"); 			fclose(fp); 			return FAILED; 		} 		p=p->next; 	} 	fclose(fp); 	return SUCCESS; }   //增加 int Emp_Add() { 	system("cls"); 	getchar(); 	int add; 	while(1){ 		system("cls"); 		Print_Add(&add); 		while(add!='1' && add!='2' && add!='3') { 			putchar('\a'); 			printf("◎请重新输入有效序号(1~3):【   】\b\b"); 			add=getchar(); 		} 		switch(add){ 			case '1': 				WriteData_wb(Creat()); 				printf("\n◎新建文件成功数据已保存√\n"); 				system("pause"); 				system("cls"); 				Emp_Add(); 				break; 			case '2': 				WriteData_ab(Creat()); 				printf("\n◎数据已成功添加√\n"); 				system("pause"); 				system("cls"); 				Emp_Add(); 				break; 			case '3': 				system("cls"); 				getchar(); 				Emp_Return(); 				break; 		} 	} 		return SUCCESS; }  //读取文件的数据到链表中返回链表head指针 struct Employee *Read() { 	struct Employee *head = NULL; 	struct Employee *p1, *p2;//s = p1;p = p2;  	FILE *fp; 	if((fp=fopen(filename,"rb+"))==NULL) 	{ 		printf("打开文件出错\n"); 		exit(0); 	} 	while(!feof(fp)) { 		if((p1=(struct Employee*)malloc(SIZE))==NULL){ 			printf("内存申请出错\n"); 			fclose(fp); 			exit(0); 		} 		if(fread(p1,SIZE,1,fp)!=1){ 			free(p1); 			break; 		} 		if(head==NULL) 		head=p2=p1; 		else{ 			p2->next=p1; 			p2=p1; 		} 	} 	fclose(fp); 	return (head); }  //删除 int Emp_Del() { 	struct Employee* head; 	struct Employee* pt1,*pt2; 	char str_num[10]; 	memset(str_num,0,sizeof(str_num)); 	printf("\n◎请输入你要删除的学号信息："); 	scanf("%s",str_num); 	pt1=Read(); 	pt2=pt1->next; 	head=pt1; 	while(pt2!=NULL){ 		if(!strcmp(pt1->num,str_num)){ 			WriteData_wb(pt2); 		}else if(!strcmp(pt2->num,str_num)){ 			pt1->next=pt2->next; 			WriteData_wb(head); 		} 		pt2=pt2->next; 		pt1=pt1->next; 	} 	if(pt2!=NULL){ 		printf("\t◎没有你要删除的数据"); 	} 	return SUCCESS; }  //修改 int Emp_Rev() { 	struct Employee* pt1,*pt2,*head; 	char str_num[10]; 	printf("\t◎请输入要修改的学号信息："); 	scanf("%s",str_num); 	pt1=Read(); 	pt2=pt1->next; 	head=pt1; 	while(pt2!=NULL){ 		if(strcmp(pt1->num,str_num)==0) { 			Print_Tittle(); 			scanf("%s%s%s%d%s",pt1->num,pt1->name,pt1->sex, 			pt1->age,pt1->tel); 			WriteData_wb(head); 		} 		else if(strcmp(pt2->num,str_num)==0) { 			Print_Tittle(); 			scanf("%s%s%s%d%s",pt1->num,pt1->name,pt1->sex, 			pt1->age,pt1->tel); 			WriteData_wb(head); 		} 		pt2 = pt2->next; 		pt1 = pt1->next; 	} 	if(pt2!=NULL) 	printf("数据库中没有存储您要删除的数据！\n"); 	return 0; }  //删改 int Emp_DelRev() { 	 	getchar(); 	int delrev=0; 	while(1){ 		system("cls"); 		Print_DelRev(&delrev); 		while(delrev!='1' && delrev!='2' && delrev!='3'){ 			putchar('\a'); 			//getchar(); 			printf("○请重新输入有效序号(1~3):【   】\b\b"); 			delrev=getchar(); 		} 		switch(delrev){ 			case '1': 				Emp_Del(); 				printf("\n◎已成功删除指定数据!"); 				system("pause"); 				getchar(); 				break; 			case '2': 				Emp_Rev(); 				printf("\n◎已成功修改指定数据!"); 				system("pause"); 				getchar(); 				break; 			case '3': 				system("cls"); 				getchar(); 				Emp_Return(); 				break; 		} 	} 	return SUCCESS; }  //总体查询 int Emp_QueAll() { 	struct Employee *pt; 	pt = Read(); 	Print_Tittle(); 	do { 		printf("%2s%5s%4s%2d%3s\n", 			pt->num,pt->name,pt->sex,pt->age,pt->tel); 		pt = pt->next; 	}while(pt!=NULL); 	printf("\n\n"); 	return SUCCESS; }  //工号查询 int Emp_QueNum()  { 	struct Employee *pt; 	char str_num[10]; 	printf("\t◎请输入您要查询的学号:"); 	scanf("%s", str_num); 	pt = Read(); 	Print_Tittle(); 	do { 		if(!strcmp(pt->num,str_num)) { 			printf("%2s%5s%4s%2d%3s\n", 				pt->num,pt->name,pt->sex,pt->age,pt->tel); 			printf("\n\n"); 			return 0; 		} 		pt = pt->next; 	}while(pt!=NULL); 	printf("\t数据库中没有存储您要查询的数据！\n"); 	printf("\n\n"); 	return SUCCESS; }  //模糊查询 int Emp_QueVague() { 	struct Employee *pt; 	char str_vague[20]; 	int m=0; 	printf("\t◎请输入您要查询的关键词:"); 	scanf("%s", str_vague); 	pt = Read(); 	Print_Tittle(); 	do { 		if(strstr(pt->num,str_vague)!=0||strstr(pt->name,str_vague)!=0 		||strstr(pt->sex,str_vague)!=0||strstr(pt->age,str_vague)!=0 		||strstr(pt->tel,str_vague)!=0) { 			printf("%2s%5s%4s%2d%3s\n", 				pt->num,pt->name,pt->sex,pt->age,pt->tel); 			m = 1; 		} 		pt = pt->next; 	}while(pt!=NULL); 	if(!m) 		printf("数据库中没有存储您要查询的数据！\n"); 	printf("\n\n"); 	return SUCCESS; }  //查询 int Emp_Que() { 	system("cls"); 	int que; 	while(1){ 		system("cls"); 		fflush(stdin);//清空缓冲区 否则会出现问题 		Print_Que(&que); 		while(que!='1' && que!='2' && que!='3'){ 			putchar('\a'); 			printf("\t○请重新输入有效序号(1~3):【   】\b\b"); 			 			que=getchar(); 		} 		switch(que){ 			case '1': 				Emp_QueAll(); 				system("pause"); 				getchar(); 				break; 			case '2': 				Emp_QueNum(); 				system("pause"); 				getchar(); 				break; 			case '3': 				Emp_QueVague(); 				system("pause"); 				getchar(); 				break; 			case '4': 				Emp_Return(); 				system("pause"); 				getchar(); 				break; 		} 	} 	return SUCCESS; }  //返回 int Emp_Return() { 	Emp_Menu(); 	return SUCCESS; }  //退出 void Emp_Quit() { 	printf("\n\t◎谢谢使用！"); 	system("pause"); 	exit(0); }  //menu函数 int Emp_Menu() { 	//int* Menu=NULL; 	int menu=0; 	//Print_Head(&Menu); 	//menu=*Menu; 	//delete Menu; 	//printf("%d\n",menu); 	fflush(stdin); 	Print_Head(&menu); 	 	while(menu!='1' && menu!='2' && menu!='3'&& menu!='4') { 		printf("error! please input the right number!\n"); 		putchar('\a'); 		//getchar(); 		printf("◎请重新输入有效序号(1~4):【   】\b\b"); 		menu=getchar(); 	} 	switch(menu){ 		case '1': 			 			File_name(); 			Emp_Add(); 			break; 		case '2':  			File_name(); 			Emp_DelRev(); 			break; 		case '3':  			File_name(); 			Emp_Que(); 			break; 		case '4':  			Emp_Quit(); 			break; 	} 	return SUCCESS; } /*void Sig(int n) { 	printf("\n\t◎程序将要退出，操作已保存！"); 	system("pause"); 	exit(0); }*/ int main() { 	//printf("\t◎使用Ctrl+C终止现在程序的运行！\n"); 	//signal(SIGINT,Sig); 	Emp_Menu(); 	return SUCCESS; }

引用 1 楼 user-3 的回复:自己的想法呢？ 我想的是做一些简单的功能就好 成绩输入输出 修改增删 查询 平均分 不及格人数统计 有代码元吗

引用 2 楼 Aoiiii 的回复:或许可以用链表试试 可以告诉我代码吗  可以加qq联系吗 693682291

或许可以用链表试试

自己的想法呢？


Question: 大哥们，我有个程序出问题了，能帮忙看下吗

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

未初始化的指针变量，编译器默认将未初始化的指针初始化为0xcc,而0xcc是被保护的数据区，因此程序崩溃。

在main 函数中 pal.next = NULL; 然后把 &pal 传给了bulidstaff 在bulidstaff 中staffinfo *p = pal->next , 请问这句执行之后，p的值应该是什么，如果你看程序看不出来，那你可以通过DEBUG来查看p的值，看完之后，你就知道为什么 会出错了。

没法找到错误

修改如下：  #include <stdio.h> #include <stdlib.h> #include <string.h> int main(); int count = 3; int pass = 0; typedef struct staff { 	char name[10]; 	int age; 	int worktime; 	char sex[5]; 	char marrige[10];   //marriage 	int grade[5]; 	int wage; 	char tired[7]; }staff; typedef struct staffinfo { 	staff data; 	struct staffinfo *next; }staffinfo; staffinfo *a, *b; void loadstaff(staffinfo *pal) { 	FILE *fp; 	staffinfo *q; 	q = pal; 	q->next = NULL; 	fp = fopen("staff.c", "rb+"); 	if (fp == NULL) 	{ 		printf("canot open file"); 		system("cls"); 		return; 	} 	do 	{ 		a = (staffinfo *)malloc(sizeof(staffinfo)); 		if (a != NULL) 		{ 			if (1 == fread(&(a->data), sizeof(staff), 1, fp)) 			{ 				q->next = a; q = q->next; q->next = NULL; 			} 			else break;    //读到了最后 		} 	} while (a); 	//fflush(stdin);   //有什么用？ 	fclose(fp); return; } void savestaff(staffinfo *pal) { 	FILE *fp; 	staffinfo *p; 	fp = fopen("staff.c", "wb+"); 	if (fp == NULL)   //zx   NULL == fp 	{ 		printf("canot open file"); 		return; 	} 	//p = pal->next;   //不带头结点 	p = pal; 	while (p != NULL) 	{ 		if (fwrite(&p->data, sizeof(staff), 1, fp) != 1) 		{ 			printf("文件打开失败！"); 			return; 		} 		p = p->next; 	} 	fflush(stdin); 	printf("文件保存成功！！"); fclose(fp); } int command() { 	char a[20]; 	char password[] = { "宝塔镇河妖" }; 	scanf("%s", a); 	if (strcmp(a, password) == 0) 	{ 		printf("口令正确，你是合法用户"); 		system("pause"); 		pass = 1; 		return 1; 	} 	else 	{ 		printf("\t口令错误"); 		count--; 		printf("\t你还有%d次机会", count); 		system("pause"); 		if (count >0) 		{ 			fflush(stdin); 			command(); 		} 		else 		{ 			printf("你已经没有机会，程序将会退出!!"); 			system("pause"); 			main(); 		} 	} } int wagechange(staffinfo *a) { 	int increase; 	if (a->data.tired == "retired") 		increase = 50; 	else 		switch ((*a->data.grade)) 		{ 		case 1: 			increase = 20; break; 		case 2: 			increase = 40; break; 		case 3: 			increase = 60; break; 		case 4: 			increase = 80; break; 		case 5: 			increase = 100; break; 		default: 			break; 		} 	return increase; } void sreach(staffinfo *pal) { 	char name[10]; 	int worktime = 0; 	int grade = 0; 	int select = 0; 	char choose = 'y'; 	staffinfo *p; 	//p = pal->next; 	p = pal; 	printf("\t你可以根据职工的姓名，工龄，级别进行查询\n"); 	printf("\t1.按姓名查询\n"); 	printf("\t2.按工龄查询\n"); 	printf("\t3.按级别查询\n"); 	scanf("%d", &select); 	switch (select) 	{ 	case 1: 		printf("请输入你要查找的姓名\n"); 		scanf("%s", name); 		while (p != NULL) 		{ 			if (strcmp(p->data.name, name) == 0) 			{ 				printf("\t找到了，你要查找的姓名为%s的职工信息如下:", name); 				printf("姓名%s", a->data.name); 				printf("年龄%d", a->data.age); 				printf("工龄%d", a->data.worktime); 				printf("性别%s", a->data.sex); 				printf("婚姻情况%s", a->data.marrige); 				printf("级别%d", a->data.grade); 				printf("工资%d", a->data.wage); 				printf("是否在职？%s", a->data.tired); 				system("pause"); 				printf("是否继续查找？Y/N"); 				scanf("%c", &choose); 				if (choose == 'y' || choose == 'Y') 					sreach(pal); 				else 				{ 					printf("程序将返回主菜单"); 					main(); 				} 			}p = p->next; 		}fflush(stdin); 		printf("没有找到姓名为 %s的人", name); break; 	case 2: 		printf("请输入你要查找的工龄\n"); 		scanf("%d", &worktime); 		while (p != NULL) 		{ 			if (worktime == p->data.worktime) 			{ 				printf("\t找到了，你要查找的工龄为%d的职工信息如下:", worktime); 				printf("姓名%s", a->data.name); 				printf("年龄%d", a->data.age); 				printf("工龄%d", a->data.worktime); 				printf("性别%s", a->data.sex); 				printf("婚姻情况%s", a->data.marrige); 				printf("级别%d", a->data.grade); 				printf("工资%d", a->data.wage); 				printf("是否在职？%s", a->data.tired); 				system("pause"); 				printf("是否继续查找？Y/N"); 				scanf("%c", &choose); 				if (choose == 'y' || choose == 'Y') 					sreach(a); 				else 				{ 					printf("程序将返回主菜单"); 					main(); 				} 			}p = p->next; 		}fflush(stdin); printf("没有找到工龄是%d的人", worktime); break; 	case 3: 		printf("请输入你要查找的级别\n"); 		scanf("%d", &grade); 		while (p != NULL) 		{ 			if (grade == *p->data.grade) 			{ 				printf("\t找到了，你要查找的级别为%d的职工信息如下:", grade); 				printf("姓名%s", a->data.name); 				printf("年龄%d", a->data.age); 				printf("工龄%d", a->data.worktime); 				printf("性别%s", a->data.sex); 				printf("婚姻情况%s", a->data.marrige); 				printf("级别%d", a->data.grade); 				printf("工资%d", a->data.wage); 				printf("是否在职？%s", a->data.tired); 				system("pause"); 				printf("是否继续查找？Y/N"); 				scanf("%c", &choose); 				if (choose == 'y' || choose == 'Y') 					sreach(a); 				else 				{ 					printf("程序将返回主菜单"); 					main(); 				} 			}p = p->next; 		}fflush(stdin); printf("没有找到级别为%d的人", grade); break; 	default:printf("无效输入，返回中!"); system("pause"); main(); break; 	} } void bulidstaff() { 	staffinfo *head, *p, *q; 	head = p = NULL; 	printf("\t天王盖地虎\n"); 	printf("\t请输入口令，口令正确执行创建操作\n"); 	count = 3; 	char choose; 	command(); 	if (pass == 1) 	{ 		do 		{ 			q = (staffinfo *)malloc(sizeof(staffinfo)); 			if (q == NULL)return; 			//fflush(stdin);   //放到读入最近处 			printf("请输入职工的姓名"); scanf("%s", q->data.name); 			printf("请输入职工的年龄"); scanf("%d", &q->data.age); 			printf("请输入职工的工龄"); scanf("%d", &q->data.worktime); 			printf("请输入职工的性别"); scanf("%s", q->data.sex); 			printf("请输入职工的婚否"); scanf("%s", q->data.marrige); 			printf("请输入职工的级别"); scanf("%d", &q->data.grade); 			printf("请输入职工的工资"); scanf("%d", &q->data.wage); 			printf("请输入职工是否在职"); scanf("%s", q->data.tired); 			q->next = NULL; 			if (NULL == head) 			{ 				head = p = q; 			} 			else 			{ 				p->next = q; 				p = p->next; 			} 			printf("是否继续录入:y/n"); 			rewind(stdin);   //zx 			choose = getchar(); 		} while (choose == 'y' || choose == 'Y'); 	} 	savestaff(head); } void changestaff(staffinfo *pal) { 	staffinfo *p; 	//p = pal->next; 	p = pal; 	char name[20]; 	printf("请输入你要修改职工的姓名"); 	scanf("%s", name); 	for (; p != NULL && strcmp(name, p->data.name) != 0; ) 	{ 		p = (staffinfo *)malloc(sizeof(staffinfo)); 		p = p->next; 	} 	if (p = NULL) 	{ 		printf("找不到名字为%sde的人员", name); 	} 	else if (strcmp(name, p->data.name) == 0) { 		fflush(stdin); 		printf("找到了，请输入你要修改的员工的所有信息"); 		printf("请输入职工的姓名"); scanf("%s", p->data.name); 		printf("请输入职工的年龄"); scanf("%d", &p->data.age); 		printf("请输入职工的工龄"); scanf("%d", &p->data.worktime); 		printf("请输入职工的性别"); scanf("%s", p->data.sex); 		printf("请输入职工的婚否"); scanf("%s", p->data.marrige); 		printf("请输入职工的级别"); scanf("%d", &p->data.grade); 		printf("请输入职工的工资"); scanf("%d", &p->data.wage); 		printf("请输入职工是否在职"); scanf("%s", p->data.tired); 	} 	savestaff(pal); 	free(p); } void increasestaff(staffinfo *pal) { 	staffinfo *p; 	char choose; 	p = pal; 	while (p->next) p = p->next; 	do { 		p->next = malloc(sizeof(staffinfo)); 		p = p->next; 		p->next = NULL; 		printf("请输入职工的姓名"); scanf("%s", p->data.name); 		printf("请输入职工的年龄"); scanf("%d", &p->data.age); 		printf("请输入职工的工龄"); scanf("%d", &p->data.worktime); 		printf("请输入职工的性别"); scanf("%s", p->data.sex); 		printf("请输入职工的婚否"); scanf("%s", p->data.marrige); 		printf("请输入职工的级别"); scanf("%d", p->data.grade); 		printf("请输入职工的工资"); scanf("%d", p->data.wage); 		printf("请输入职工是否在职"); scanf("%s", p->data.tired); 		printf("添加成功，是否继续？y/n"); 		rewind(stdin); 		scanf("%c", &choose); 	} while (choose == 'Y' || choose == 'y'); 	savestaff(pal); } void delestaff(staffinfo *pal) { 	staffinfo *p, *q; 	char name[20]; 	char choose; 	printf("请输入你要删除职工的姓名"); 	scanf("%19s", name); 	p = pal; 	p = (staffinfo *)malloc(sizeof(staffinfo)); 	q = (staffinfo *)malloc(sizeof(staffinfo)); 	while (p != NULL) 	{ 		if (strcmp(p->data.name, name) == 0) 		{ 			if (p == pal) 			{ 				pal = p->next; 				free(p); 			} 			else 			{ 				q->next = p->next; 				free(p); 			} 			printf("删除成功，是否继续？y/n"); 			scanf("%s", &choose); 			if (choose == 'Y' || choose == 'y') 			{ 				delestaff(pal); break; 			} 			else 				main(); 		} 		else 		{ 			q = p; 			p = p->next; 		} 	} 	savestaff(pal); } int main() { 	int select = 0; 	char choose = 'y'; 	staffinfo pal; 	pal.next = NULL; 	loadstaff(&pal); 	printf("\t\t**************************************\n"); 	printf("\t*************欢迎使用本职工管理系统***************\n"); 	printf("\t1.创建职工信息              2.查询职工信息 \n"); 	printf("\t3.修改职工信息              4.添加职工信息 \n"); 	printf("\t5.删除职工信息              6.退出 \n"); 	printf("\t.*                                            *\n"); 	printf("\t.*                                            *\n"); 	printf("\t           请输入你的选择1-6        "); 	scanf("%d", &select); 	fflush(stdin); 	switch (select) 	{ 	case 1: 		//bulidstaff(&pal); 		bulidstaff(); 		system("pause"); 		main(); 		break; 	case 2: 		sreach(&pal); 		system("pause"); 		main(); 		break; 	case 3: 		changestaff(&pal); 		system("pause"); 		main(); 		break; 	case 4: 		increasestaff(&pal); 		system("pause"); 		main(); 		break; 	case 5: 		delestaff(&pal); 		system("pause"); 		main(); 		break; 	case 6: 		printf("确定要退出程序吗？y/n"); 		fflush(stdin); scanf("%c", &choose); 		if (choose == 'y' || choose == 'Y') 		{ 			printf("程序正在退出"); 			exit(0); 		} 		else if (choose == 'N' || choose == 'n') 		{ 			printf("选择的N/n,程序将会返回主菜单"); 			system("pause"); 			main(); 		} 		else 		{ 			printf("输入不合法，程序将会返回主菜单"); 			main(); 		}	break; 	default: 		printf("输入不合法，将返回主菜单"); 		system("pause"); 		system("cls"); 		main(); 		break; 	} 	return 0; }

条是没有问题，但是在操作程序时出现了问题

0x00CD1704 处有未经处理的异常(在 pr.exe 中):  0xC0000005:  写入位置 0x00000044 时发生访问冲突。是这个错误- -！

不好意思，是在执行了buildstaff函数的时候，出错了，我输完职工信息之后，程序出错 0x00111704 处有未经处理的异常(在 pr.exe 中):  0xC0000005:  写入位置 0x00000044 时发生访问冲突。void bulidstaff(staffinfo *pal)(q->next=NULL)前面那句。  {  staffinfo *p = pal->next , *q;  printf("\t天王盖地虎\n");  printf("\t请输入口令，口令正确执行创建操作\n");  count = 3;  char choose;  command();  if (pass == 1)  {  do  {  q = (staffinfo *)malloc(sizeof(staffinfo));  if (q == NULL)return;  fflush(stdin);  printf("请输入职工的姓名"); scanf("%s", q->data.name);  printf("请输入职工的年龄"); scanf("%d", &q->data.age);  printf("请输入职工的工龄"); scanf("%d", &q->data.worktime);  printf("请输入职工的性别"); scanf("%s", q->data.sex);  printf("请输入职工的婚否"); scanf("%s", q->data.marrige);  printf("请输入职工的级别"); scanf("%d",&q->data.grade);  printf("请输入职工的工资"); scanf("%d", &q->data.wage);  printf("请输入职工是否在职"); scanf("%s", q->data.tired);  q->next = NULL;  p->next = q;  p = p->next;  printf("是否继续录入:y/n");  choose = getchar();  } while (choose == 'y' || choose == 'Y');  }  savestaff(pal);    }

一上来就给一大串代码？而且有没有说明需求是什么？怎么帮你改啊？没时间去帮你做测试啊喂

你至少要说一下哪出错了  出什么错了


Question: 求解 C语言

这样可好：  #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct student { 	int number; 	struct student *next; }STU; STU* creat(int b); int main() { 	STU *b; 	b = creat(2); 	return 0; } STU* creat(int b) { 	STU *head, *next, *last; 	head = NULL; 	int i; 	for (i = 0; i < b; i++) 	{ 		next = malloc(sizeof(STU)); 		next->number = rand() % 100; 		next->next = NULL; 		if (NULL == head) 		{ 			head = last = next; 		} 		else 		{ 			last->next = next; 			last = next; 		} 	} 	return head; }

b是个野指针，给*b赋值

int main(int argc, char *argv[]) {     a b;     b = create(2); }

a creat(int b)这个函数没有看懂。创建链表？strcut  student* creat();


Question: 学生成绩管理系统的设计与实现（c实现）

引用 4 楼 qq_27350687 的回复:⑶可以查询某门课程的平均分，学生的排名，不同分数段的学生人数及学生信息等； ⑷可以查询学生的班级排名等； ⑸可以按学号排序输出全部学生的成绩信息、总分及班级排名等。   这几个要求都没有实现，， 思路是一样的，自己动手写，一会就写出来。

我自己写的，还有点不完善，但功能已经很多了。仅供参考，不懂的问我  // .h文件 #ifndef __PERSON_H__ #define __PERSON_H_ #define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <signal.h> #define SUCCESS     0 #define FAILED    (!SUCCESS) #define SIZE   sizeof(struct Employee) //全局变量 int flag=0;//返回标志 char filename[30];//要打开的文件名 //员工信息结构体 struct Employee{ 	char name[20]; 	char tel[15]; 	char sex[5];	 	char num[10]; 	char age[3]; 	struct Employee* next; };  //建立一个链表 struct Employee* creat(int n);  //主函数 int Emp_Menu(); //首页打印 int Print_Head(); //删改打印 int Print_DelRev(); //增加打印 int Print_Add(); //表头打印 int Print_Tittle(); //新建文件写入 int WriteData_wb(struct Employee *head); //在已有的文件写入 int WriteData_ab(struct Employee *head); //添加 int Emp_Add(); //删除 int Emp_Del(); //修改 int Emp_Rev(); //查询 int Emp_Que(); //返回 int Emp_Return(); //退出 void Emp_Quit();  #endif //__PERSON_H__   //.c文件 #include "person.h"  //首页 int Print_Head(int * num) { 	printf("\t***********************************************\n"); 	printf("\t|                 职工管理系统                |\n"); 	printf("\t*---------------------------------------------*\n"); 	printf("\t|         【1】新增        【2】删改          |\n"); 	printf("\t*         【3】查询        【4】退出          *\n"); 	printf("\t***********************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //删改画面 int Print_DelRev(int* num) { 	printf("\t******************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*   【1】删除   【2】修改   【3】返回    *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //查询画面 int Print_Que(int* num) { 	printf("\t******* ************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*     【1】全部查询   【2】工号查询      *\n"); 	printf("\t*                                        *\n"); 	printf("\t*     【3】模糊查询   【4】返回菜单      *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //增加画面 int Print_Add(int* num) { 	int n=0; 	printf("\t******************************************\n"); 	printf("\t*                                        *\n"); 	printf("\t*   【1】新增   【2】添加   【3】返回    *\n"); 	printf("\t*                                        *\n"); 	printf("\t******************************************\n"); 	printf("\t◎请输入想进行操作的序号【   】\b\b"); 	*num=getchar(); 	return SUCCESS; }  //标题头 int Print_Tittle() { 	printf("-------------------------------------------\n"); 	printf("  工号 |   姓名    |性别|年龄|    电话     \n"); 	printf("-------------------------------------------\n"); 	return SUCCESS; }  //选择将要打开的文件 int File_name() { 	printf("\n\t◎请输入您想要打开的文件:"); 	//memset(filename,0,sizeof(filename)); 	if(scanf("%s", filename)!=1){ 		printf("\a 选择文件错误!"); 		return FAILED; 	} 	return SUCCESS; }   //生成链表，参数n是add记录数量 struct Employee *Creat() { 	printf("\n\t◎请输入要添加的数据个数:"); 	int n; 	if(scanf("%d", &n)!=1) { 		printf("\a error!"); 	} 	struct Employee *head; 	struct Employee *p1, *p2;  	system("cls"); 	for(int i=1;i<n+1;i++) { 		p1 = (struct Employee*)malloc(SIZE); 		Print_Tittle(); 		scanf("%s%s%s%d%s",p1->num,p1->name,p1->sex, 		p1->age,p1->tel); 		p1->next = NULL; 		if(i==1) { 			head = p2 = p1; 		} 		else { 			p2->next = p1; 			p2 = p1; 		} 	} 	return(head); }  //建立新文件 int WriteData_wb(struct Employee *head) { 	FILE *fp; 	struct Employee *p; 	if((fp = fopen(filename, "wb"))==NULL) 	printf("\a 打开文件错误!");	 	p = head; 	while(p!=NULL) { 		if(fwrite(p,SIZE,1,fp)!=1) { 			printf("\b 写入数据出错\n"); 			fclose(fp); 			return FAILED; 		} 		p=p->next; 	} 	fclose(fp); 	return SUCCESS; }  //在已有文件添加 int WriteData_ab(struct Employee *head) { 	FILE *fp; 	struct Employee *p; 	if((fp = fopen(filename, "ab"))==NULL) 	printf("\a 打开文件错误!"); 	p = head; 	while(p!=NULL) { 	if(fwrite(p,SIZE,1,fp)!=1) { 			printf("\b 写入数据出错\n"); 			fclose(fp); 			return FAILED; 		} 		p=p->next; 	} 	fclose(fp); 	return SUCCESS; }   //增加 int Emp_Add() { 	system("cls"); 	getchar(); 	int add; 	while(1){ 		system("cls"); 		Print_Add(&add); 		while(add!='1' && add!='2' && add!='3') { 			putchar('\a'); 			printf("◎请重新输入有效序号(1~3):【   】\b\b"); 			add=getchar(); 		} 		switch(add){ 			case '1': 				WriteData_wb(Creat()); 				printf("\n◎新建文件成功数据已保存√\n"); 				system("pause"); 				system("cls"); 				Emp_Add(); 				break; 			case '2': 				WriteData_ab(Creat()); 				printf("\n◎数据已成功添加√\n"); 				system("pause"); 				system("cls"); 				Emp_Add(); 				break; 			case '3': 				system("cls"); 				getchar(); 				Emp_Return(); 				break; 		} 	} 		return SUCCESS; }  //读取文件的数据到链表中返回链表head指针 struct Employee *Read() { 	struct Employee *head = NULL; 	struct Employee *p1, *p2;//s = p1;p = p2;  	FILE *fp; 	if((fp=fopen(filename,"rb+"))==NULL) 	{ 		printf("打开文件出错\n"); 		exit(0); 	} 	while(!feof(fp)) { 		if((p1=(struct Employee*)malloc(SIZE))==NULL){ 			printf("内存申请出错\n"); 			fclose(fp); 			exit(0); 		} 		if(fread(p1,SIZE,1,fp)!=1){ 			free(p1); 			break; 		} 		if(head==NULL) 		head=p2=p1; 		else{ 			p2->next=p1; 			p2=p1; 		} 	} 	fclose(fp); 	return (head); }  //删除 int Emp_Del() { 	struct Employee* head; 	struct Employee* pt1,*pt2; 	char str_num[10]; 	memset(str_num,0,sizeof(str_num)); 	printf("\n◎请输入你要删除的学号信息："); 	scanf("%s",str_num); 	pt1=Read(); 	pt2=pt1->next; 	head=pt1; 	while(pt2!=NULL){ 		if(!strcmp(pt1->num,str_num)){ 			WriteData_wb(pt2); 		}else if(!strcmp(pt2->num,str_num)){ 			pt1->next=pt2->next; 			WriteData_wb(head); 		} 		pt2=pt2->next; 		pt1=pt1->next; 	} 	if(pt2!=NULL){ 		printf("\t◎没有你要删除的数据"); 	} 	return SUCCESS; }  //修改 int Emp_Rev() { 	struct Employee* pt1,*pt2,*head; 	char str_num[10]; 	printf("\t◎请输入要修改的学号信息："); 	scanf("%s",str_num); 	pt1=Read(); 	pt2=pt1->next; 	head=pt1; 	while(pt2!=NULL){ 		if(strcmp(pt1->num,str_num)==0) { 			Print_Tittle(); 			scanf("%s%s%s%d%s",pt1->num,pt1->name,pt1->sex, 			pt1->age,pt1->tel); 			WriteData_wb(head); 		} 		else if(strcmp(pt2->num,str_num)==0) { 			Print_Tittle(); 			scanf("%s%s%s%d%s",pt1->num,pt1->name,pt1->sex, 			pt1->age,pt1->tel); 			WriteData_wb(head); 		} 		pt2 = pt2->next; 		pt1 = pt1->next; 	} 	if(pt2!=NULL) 	printf("数据库中没有存储您要删除的数据！\n"); 	return 0; }  //删改 int Emp_DelRev() { 	 	getchar(); 	int delrev=0; 	while(1){ 		system("cls"); 		Print_DelRev(&delrev); 		while(delrev!='1' && delrev!='2' && delrev!='3'){ 			putchar('\a'); 			//getchar(); 			printf("○请重新输入有效序号(1~3):【   】\b\b"); 			delrev=getchar(); 		} 		switch(delrev){ 			case '1': 				Emp_Del(); 				printf("\n◎已成功删除指定数据!"); 				system("pause"); 				getchar(); 				break; 			case '2': 				Emp_Rev(); 				printf("\n◎已成功修改指定数据!"); 				system("pause"); 				getchar(); 				break; 			case '3': 				system("cls"); 				getchar(); 				Emp_Return(); 				break; 		} 	} 	return SUCCESS; }  //总体查询 int Emp_QueAll() { 	struct Employee *pt; 	pt = Read(); 	Print_Tittle(); 	do { 		printf("%2s%5s%4s%2d%3s\n", 			pt->num,pt->name,pt->sex,pt->age,pt->tel); 		pt = pt->next; 	}while(pt!=NULL); 	printf("\n\n"); 	return SUCCESS; }  //工号查询 int Emp_QueNum()  { 	struct Employee *pt; 	char str_num[10]; 	printf("\t◎请输入您要查询的学号:"); 	scanf("%s", str_num); 	pt = Read(); 	Print_Tittle(); 	do { 		if(!strcmp(pt->num,str_num)) { 			printf("%2s%5s%4s%2d%3s\n", 				pt->num,pt->name,pt->sex,pt->age,pt->tel); 			printf("\n\n"); 			return 0; 		} 		pt = pt->next; 	}while(pt!=NULL); 	printf("\t数据库中没有存储您要查询的数据！\n"); 	printf("\n\n"); 	return SUCCESS; }  //模糊查询 int Emp_QueVague() { 	struct Employee *pt; 	char str_vague[20]; 	int m=0; 	printf("\t◎请输入您要查询的关键词:"); 	scanf("%s", str_vague); 	pt = Read(); 	Print_Tittle(); 	do { 		if(strstr(pt->num,str_vague)!=0||strstr(pt->name,str_vague)!=0 		||strstr(pt->sex,str_vague)!=0||strstr(pt->age,str_vague)!=0 		||strstr(pt->tel,str_vague)!=0) { 			printf("%2s%5s%4s%2d%3s\n", 				pt->num,pt->name,pt->sex,pt->age,pt->tel); 			m = 1; 		} 		pt = pt->next; 	}while(pt!=NULL); 	if(!m) 		printf("数据库中没有存储您要查询的数据！\n"); 	printf("\n\n"); 	return SUCCESS; }  //查询 int Emp_Que() { 	system("cls"); 	int que; 	while(1){ 		system("cls"); 		Print_Que(&que); 		while(que!='1' && que!='2' && que!='3'){ 			putchar('\a'); 			printf("\t○请重新输入有效序号(1~3):【   】\b\b"); 			que=getchar(); 		} 		switch(que){ 			case '1': 				Emp_QueAll(); 				system("pause"); 				getchar(); 				break; 			case '2': 				Emp_QueNum(); 				system("pause"); 				getchar(); 				break; 			case '3': 				Emp_QueVague(); 				system("pause"); 				getchar(); 				break; 			case '4': 				Emp_Return(); 				system("pause"); 				getchar(); 				break; 		} 	} 	return SUCCESS; }  //返回 int Emp_Return() { 	Emp_Menu(); 	return SUCCESS; }  //退出 void Emp_Quit() { 	printf("\n\t◎谢谢使用！"); 	system("pause"); 	exit(0); }  //menu函数 int Emp_Menu() { 	//int* Menu=NULL; 	int menu=0; 	//Print_Head(&Menu); 	//menu=*Menu; 	//delete Menu; 	//printf("%d\n",menu); 	Print_Head(&menu); 	 	while(menu!='1' && menu!='2' && menu!='3'&& menu!='4') { 		printf("error! please input the right number!\n"); 		putchar('\a'); 		//getchar(); 		printf("◎请重新输入有效序号(1~4):【   】\b\b"); 		menu=getchar(); 	} 	switch(menu){ 		case '1': 			 			File_name(); 			Emp_Add(); 			break; 		case '2':  			File_name(); 			Emp_DelRev(); 			break; 		case '3':  			File_name(); 			Emp_Que(); 			break; 		case '4':  			Emp_Quit(); 			break; 	} 	return SUCCESS; } /*void Sig(int n) { 	printf("\n\t◎程序将要退出，操作已保存！"); 	system("pause"); 	exit(0); }*/ int main() { 	//printf("\t◎使用Ctrl+C终止现在程序的运行！\n"); 	//signal(SIGINT,Sig); 	Emp_Menu(); 	return SUCCESS; }

引用 楼主 qq_27350687 的回复:19、学生成绩管理系统的设计与实现 问题描述： 能够实现对学生成绩的常用管理功能。 基本要求： ⑴采用一定的存储结构对学生成绩进行管理； ⑵可以进行成绩的录入、查询、修改、删除等操作； ⑶可以查询某门课程的平均分，学生的排名，不同分数段的学生人数及学生信息等； ⑷可以查询某学生的各课程分数，总分及学生的班级排名等； ⑸可以按学号排序输出全部学生的成绩信息、总分及班级排名等。   求大神帮忙看一下，最好能够写一下代码(简单注释)！ 0.0

你是想要源代码？


Question: C语言，求教大神

修改如下：  int main() { 	char letter, c; 	printf("please enter the letter of someday\n"); 	letter = getchar(); 	switch (letter) 	{ 	case 'm': 	case 'M':printf("the day is monday\n"); break;  	case 't': 	case 'T': 		printf("please input the second letter\n"); 		rewind(stdin);    //zx 		c = getchar(); 		if ('u' == c) 			printf("the day is tuesday\n"); 		else if ('h' == c) 			printf("the day is thursday\n"); 		else 			printf("data error\n"); 		break; 	case 'w': 	case 'W':printf("the day is wednesday"); break; 	case 'f': 	case 'F':printf("the day is friday"); break; 	case 's': 	case 'S':printf("please input the second letter\n"); 		rewind(stdin);    //zx 		c = getchar(); 		if ('a' == c) 			printf("the day is saturday\n"); 		else if ('u' == c) 			printf("the day is sunday\n"); 		else 			printf("data error\n"); 		break; 	default:printf("the data error\n"); 	} 	return 0; }

首先，你应该考虑一下回车的问题；其次你一个字符读了两遍。

printf("please enter the letter of someday:"); 		letter=getchar(); 		switch(letter) 		{ 			case 'm': 			case 'M': 				printf("\n the day is monday"); 				break; 			case 't': 			case 'T': 				printf("please input the second letter:"); 				fflush(stdin); 				c=getchar(); 				if(c=='u'){ 					printf("\n the day is tuesday"); 				}else if(c=='h'){ 					printf("\n the day is thursday"); 				}else{ 					printf("\n data error"); 				} 				break; 			case 'w': 			case 'W': 				printf("\n the day is wednesday"); 				break; 			case 'f': 			case 'F': 				printf("\n the day is friday"); 				break; 			case 's': 			case 'S': 				printf("please input the second letter:"); 				fflush(stdin); 				c=getchar(); 				if(c=='a'){ 					printf("\n the day is saturday"); 				}else if(c=='u'){ 					printf("\n the day is sunday"); 				}else{ 					printf("\n data error"); 				} 				break; 			default: 				printf("\n the data error"); 		} 要编写清晰的代码


Question: 实习生，请看一下我的代码，不知道问题出现在哪里了

引用 2 楼 user-2 的回复:弄这么多循环？楼主好好看看你写的逻辑 我也是初学者，还没学到指针，也没写过什么代码，这是无意中想起生活中发生的事情，就想着是否可以用代码来完成，逻辑上啰嗦一些，还请指导，哪里需要改进？

引用 3 楼 brookmill 的回复:srand在整个程序里面调用一次就行了，一般是在main最开始的地方。 把Shuffle和Choice里面的srand删掉。 谢谢 就是这个问题 去掉了 其他的srand 问题就消失了，谢谢~

弄这么多循环？楼主好好看看你写的逻辑

偶尔会出现全都是一样的结果，请问问题出现在哪里？？？


Question: 隐藏窗口，显示托盘图标

引用 1 楼 ____________--------的回复:当最小化窗体时，调用函数ToTray()，实现隐藏窗体，显示托盘图标；  （三）实现代码  1、ToTray()的定义  void CTPDlg::ToTray() {     NOTIFYICONDATA  pnid;     pnid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);//该结构体大小     pnid.hWnd=this->m_hWnd;    //窗口句柄     //pnid.uID=(UINT)m_hIcon;      //图标句柄     pnid.uID=IDR_MAINFRAME;//图标句柄     pnid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ; //图标有效|自定义消息有效|鼠标指向显示文字有效     pnid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称，调用消息实现函数     pnid.hIcon=m_hIcon;         //图标句柄     lstrcpy((LPWSTR)pnid.szTip,TEXT("这是一个测试托盘的程序"));/*鼠标指向所显示的文字(在unicode下的表达方式,在非unicode的情况下可以用strcpy(pnid.szTip,"...")表达。*/     Shell_NotifyIcon(NIM_ADD,&pnid);    //在托盘区添加图标          ShowWindow(SW_HIDE);    //隐藏主窗口 } 谢谢！刚测试了一下，可用


Question: 您好，请看下我的代码不知道哪里出现了错误

#include <stdio.h> #include <time.h> #include <windows.h> #define MAX 100 int Shuffle(int order[], int Number); int Choice(int Complete[], int Number); int main()			//////////////产生随机牌序 { 	int Poker[MAX]; 	int Temporary, Search, Contrast, Determine_results; 	srand(time(NULL)); 	for (int i = 0; i < 50; i++){ 		for (Temporary = 1; Temporary < 55; Temporary++){ 			Poker[Temporary] = rand(time) % 54 + 1; 			for (Search = 1, Contrast = Temporary; Search < 54; Search++) 				if (Poker[Contrast] == Poker[Search] && Search != Contrast) 					Temporary--; 		}  		Determine_results = Shuffle(Poker, Temporary); 		if (i % 5 == 0) 			printf("\n"); 		switch (Determine_results){ 		case 1: printf("黑桃  A   "); break; case 2: printf("黑桃  2   "); break; case 3: printf("黑桃  3   "); break; case 4: printf("黑桃  4   "); break; case 5: printf("黑桃  5   "); break; 		case 6: printf("黑桃  6   "); break; case 7: printf("黑桃  7   "); break; case 8: printf("黑桃  8   "); break; case 9: printf("黑桃  9   "); break; case 10: printf("黑桃 10   "); break; 		case 11: printf("黑桃  J   "); break; case 12: printf("黑桃  Q   "); break; case 13: printf("黑桃  K   "); break; case 14:printf("红桃  A   "); break; case 15:printf("红桃  2   "); break; 		case 16:printf("红桃  3   "); break; case 17:printf("红桃  4   "); break; case 18:printf("红桃  5   "); break; case 19:printf("红桃  6   "); break; case 20:printf("红桃  7   "); break; 		case 21:printf("红桃  8   "); break; case 22:printf("红桃  9   "); break; case 23:printf("红桃 10   "); break; case 24:printf("红桃  J   "); break; case 25:printf("红桃  Q   "); break; 		case 26:printf("红桃  K   "); break; case 27:printf("方块  A   "); break; case 28:printf("方块  2   "); break; case 29:printf("方块  3   "); break; case 30:printf("方块  4   "); break; 		case 31:printf("方块  5   "); break; case 32:printf("方块  6   "); break; case 33:printf("方块  7   "); break; case 34:printf("方块  8   "); break; case 35:printf("方块  9   "); break; 		case 36:printf("方块 10   "); break; case 37:printf("方块  J   "); break; case 38:printf("方块  Q   "); break; case 39:printf("方块  K   "); break; case 40:printf("梅花  A   "); break; 		case 41:printf("梅花  2   "); break; case 42:printf("梅花  3   "); break; case 43:printf("梅花  4   "); break; case 44:printf("梅花  5   "); break; case 45:printf("梅花  6   "); break; 		case 46:printf("梅花  7   "); break; case 47:printf("梅花  8   "); break; case 48:printf("梅花  9   "); break; case 49:printf("梅花 10   "); break; case 50:printf("梅花  J   "); break; 		case 51:printf("梅花  Q   "); break; case 52:printf("梅花  K   "); break; case 53:printf("  王  5   "); break; case 54:printf("  王  6   "); break; 		} 	} 	printf("\n"); 	return 0; } int Shuffle(int order[], int Number)          //////////////////洗牌 { 	int array1[MAX]; 	int array2[MAX]; 	int Wash_the_cards[MAX]; 	int sheets_i, sheets_j, number, cards, Receive_i, Receive_j, i, j; 	int Temporary, Temporary1, Length_i, Length_j; 	srand(time(NULL)); 	for (number = 0; number < 3; number++){ 		for (Temporary = 1, Temporary1 = 28; Temporary < 28; Temporary++, Temporary1++){ 			array1[Temporary] = order[Temporary]; 			array2[Temporary] = order[Temporary1]; 			Receive_i = Receive_j = cards = 1; 			for (cards; cards < 55;){ 				sheets_i = rand(time) % 5 + 1; 				sheets_j = rand(time) % 5 + 1; 				Length_i = Receive_i + sheets_i; 				Length_j = Receive_j + sheets_j; 				if (Length_i >= 28) 					sheets_i = 28 - Receive_i; 				if (Length_j >= 28) 					sheets_j = 28 - Receive_j; 				for (i = 1, j = 1; i <= sheets_i && j <= sheets_j; i++, j++){ 					Wash_the_cards[cards++] = array2[Receive_j++]; 					Wash_the_cards[cards++] = array1[Receive_i++]; 				} 				for (i; i <= sheets_i; i++) 					Wash_the_cards[cards++] = array1[Receive_i++]; 				for (j; j <= sheets_j; j++) 					Wash_the_cards[cards++] = array2[Receive_j++]; 			} 		} 	} 	return Choice(Wash_the_cards, cards); } int Choice(int Complete[], int Number) { 	int The_ashing_card[MAX]; 	int Point, Poker_face, Confirm, Testing; 	srand(time(NULL)); 	Point = rand(time) % 54 + 1; 	Poker_face = Complete[Point]; 	if (Poker_face < 14){ 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} 	if (Poker_face > 13 && Poker_face < 27){ 		Poker_face -= 13; 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} 	if (Poker_face > 26 && Poker_face < 40){ 		Poker_face -= 26; 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} 	if (Poker_face > 39 && Poker_face < 53){ 		Poker_face -= 39; 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} 	if (Poker_face == 53){ 		Poker_face = 14; 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} 	if (Poker_face == 54){ 		Poker_face = 15; 		Testing = Poker_face + Point; 		if (Testing > 54) 			return Confirm = Complete[Testing - 54]; 		else 			return Confirm = Complete[Poker_face + Point]; 	} }

怎么不能编辑帖子了

引用 2 楼 liyoubaidu 的回复:能格式化一下吗，好难看啊    http://www.onvifb.com/ 怎么格式化，我不会呀

高手们都在干吗。。。


Question: 为什么C语言的字符串处理这么难呢- -

像这种错误，首先语法或用法本身就有错误问题上面已经列出来了。 如果确保用法或语法没有错误，那就多判断返回值，看看到底是哪一步出错了。HWND subwindow = CreateEdit(TEXT("我爱C语言"),10,10,150,20,hwnd,(HMENU)4); if (subwindow != NULL) {     int length = GetWindowTextLength(subwindow);     if (length++ > 0) {         TCHAR *edittext = calloc(length, sizeof(TCHAR));         GetWindowText(subwindow, edittext);         MessageBox(hwnd,edittext, TEXT("提示"),NULL);     } }从上到下一溜写下来，谁知道那里出错了。

18楼说的正确，你把你的subwindow设为一个全局看看   你这些WIN32的程序还用calloc啊，而且还用错了    最后掌握好F9 F10 F11

单步调试啊啊

引用 12 楼 qq_18599547 的回复:[quote=引用 10 楼 mewiteor 的回复:] [quote=引用 9 楼 mewiteor 的回复:] [quote=引用 8 楼 mewiteor 的回复:] 第一，字符类型统一用TCHAR。 第二，GetWindowText中的edittext不用取地址。 第三，GetWindowText的第三个参数GetWindowTextLength(subwindow)应该改为edittext的容量255，以防溢出。 还有，MessageBox里的  "提示"  改为  TEXT("提示")[/quote] 还有，MessageBox的最后一个参数类型是UINT，不是指针，用0就可以了，不用NULL。 calloc第二个参数改为sizeof(TCHAR),而不应该为指针。[/quote] 大神 还是空白啊   	TCHAR *edittext; 	HWND subwindow; 	switch(message) 	{ 	case WM_CREATE:		 		CreateButton(TEXT("启  动"),50,50,100,24,hwnd,(HMENU) 1); 		CreateButton(TEXT("取  消"),250,50,100,24,hwnd,(HMENU) 2); 		CreateButton(TEXT("哈哈"),50,100,100,24,hwnd,(HMENU) 3); 		subwindow = CreateEdit(TEXT("我爱C语言\0"),10,10,150,20,hwnd,(HMENU) 4); 		//timer = SetTimer(hwnd,1,1000,TimerProc);//启动计时器 		//GetDlgItemText(subwindow,4,&edittext,255);//获取字符串失败 //-----------------------------以上为创建子窗口------------------------------------- 		setfont(hwnd);//修改子窗口字体         return 0;     case WM_COMMAND: 	 		switch(LOWORD(wParam))//判断子窗口ID 		{ 	    case 1://ID为1 处理消息 			switch(HIWORD(wParam))//判断ID为1 的子窗口消息类型 			{ 			case BN_CLICKED://确定按钮被按下消息 				//setedittext(4,TEXT("哈哈ds")); 				edittext = (TCHAR *) calloc(255,sizeof(TCHAR)); 				GetWindowText(subwindow,edittext,255); 				MessageBox(hwnd,edittext,TEXT("是"),0);				 				free(edittext); [/quote] 问题在于你的subwindow，你的subwindow是个局部变量，只在创建消息时被赋值，消息结束后subwindow被释放，在当前消息的subwindow未被赋值，直接使用，此时的subwindow是个不确定的值。你可以把subwindow设成全局变量或者静态局部变量。 另外，你应该学会调试，在异常处之前设断点，单步调试，看一看变量在哪一步之后就不是预期值，以此来定位bug。

如果lz只是写个带界面的程序的话可以试试mfc或qt

引用 13 楼 zxh707wk 的回复:这不是win32吗...c++属性的... 是呀 写个窗口这么麻烦. 自己创建的控件 居然取不到字符串内容- -

引用 11 楼 paschen 的回复:"提示"改成_T("提示")  wchar_t建议改成TCHAR，因为TCHAR是通用的，在多字节下是char，在UNICODE下是wchar 改了 就什么都显示不出来了

引用 10 楼 mewiteor 的回复:[quote=引用 9 楼 mewiteor 的回复:] [quote=引用 8 楼 mewiteor 的回复:] 第一，字符类型统一用TCHAR。 第二，GetWindowText中的edittext不用取地址。 第三，GetWindowText的第三个参数GetWindowTextLength(subwindow)应该改为edittext的容量255，以防溢出。 还有，MessageBox里的  "提示"  改为  TEXT("提示")[/quote] 还有，MessageBox的最后一个参数类型是UINT，不是指针，用0就可以了，不用NULL。 calloc第二个参数改为sizeof(TCHAR),而不应该为指针。[/quote] 大神 还是空白啊   	TCHAR *edittext; 	HWND subwindow; 	switch(message) 	{ 	case WM_CREATE:		 		CreateButton(TEXT("启  动"),50,50,100,24,hwnd,(HMENU) 1); 		CreateButton(TEXT("取  消"),250,50,100,24,hwnd,(HMENU) 2); 		CreateButton(TEXT("哈哈"),50,100,100,24,hwnd,(HMENU) 3); 		subwindow = CreateEdit(TEXT("我爱C语言\0"),10,10,150,20,hwnd,(HMENU) 4); 		//timer = SetTimer(hwnd,1,1000,TimerProc);//启动计时器 		//GetDlgItemText(subwindow,4,&edittext,255);//获取字符串失败 //-----------------------------以上为创建子窗口------------------------------------- 		setfont(hwnd);//修改子窗口字体         return 0;     case WM_COMMAND: 	 		switch(LOWORD(wParam))//判断子窗口ID 		{ 	    case 1://ID为1 处理消息 			switch(HIWORD(wParam))//判断ID为1 的子窗口消息类型 			{ 			case BN_CLICKED://确定按钮被按下消息 				//setedittext(4,TEXT("哈哈ds")); 				edittext = (TCHAR *) calloc(255,sizeof(TCHAR)); 				GetWindowText(subwindow,edittext,255); 				MessageBox(hwnd,edittext,TEXT("是"),0);				 				free(edittext);

引用 9 楼 mewiteor 的回复:[quote=引用 8 楼 mewiteor 的回复:] 第一，字符类型统一用TCHAR。 第二，GetWindowText中的edittext不用取地址。 第三，GetWindowText的第三个参数GetWindowTextLength(subwindow)应该改为edittext的容量255，以防溢出。 还有，MessageBox里的  "提示"  改为  TEXT("提示")[/quote] 还有，MessageBox的最后一个参数类型是UINT，不是指针，用0就可以了，不用NULL。 calloc第二个参数改为sizeof(TCHAR),而不应该为指针。

引用 8 楼 mewiteor 的回复:第一，字符类型统一用TCHAR。 第二，GetWindowText中的edittext不用取地址。 第三，GetWindowText的第三个参数GetWindowTextLength(subwindow)应该改为edittext的容量255，以防溢出。 还有，MessageBox里的  "提示"  改为  TEXT("提示")

引用 6 楼 leee7338 的回复:弱弱的问一下  这是QT么？网上一搜一大堆 不知道啥是QT. 这个是我自己在VC6.0中写的窗口 我想获取edit控件的内容

谢谢大家了. 找出原因了 是句柄无效 错误码 1400 换成主窗口句柄成功获取标题 .

引用 17 楼 mewiteor 的回复:[quote=引用 12 楼 qq_18599547 的回复:] [quote=引用 10 楼 mewiteor 的回复:] [quote=引用 9 楼 mewiteor 的回复:] [quote=引用 8 楼 mewiteor 的回复:] 第一，字符类型统一用TCHAR。 第二，GetWindowText中的edittext不用取地址。 第三，GetWindowText的第三个参数GetWindowTextLength(subwindow)应该改为edittext的容量255，以防溢出。 还有，MessageBox里的  "提示"  改为  TEXT("提示")[/quote] 还有，MessageBox的最后一个参数类型是UINT，不是指针，用0就可以了，不用NULL。 calloc第二个参数改为sizeof(TCHAR),而不应该为指针。[/quote] 大神 还是空白啊   	TCHAR *edittext; 	HWND subwindow; 	switch(message) 	{ 	case WM_CREATE:		 		CreateButton(TEXT("启  动"),50,50,100,24,hwnd,(HMENU) 1); 		CreateButton(TEXT("取  消"),250,50,100,24,hwnd,(HMENU) 2); 		CreateButton(TEXT("哈哈"),50,100,100,24,hwnd,(HMENU) 3); 		subwindow = CreateEdit(TEXT("我爱C语言\0"),10,10,150,20,hwnd,(HMENU) 4); 		//timer = SetTimer(hwnd,1,1000,TimerProc);//启动计时器 		//GetDlgItemText(subwindow,4,&edittext,255);//获取字符串失败 //-----------------------------以上为创建子窗口------------------------------------- 		setfont(hwnd);//修改子窗口字体         return 0;     case WM_COMMAND: 	 		switch(LOWORD(wParam))//判断子窗口ID 		{ 	    case 1://ID为1 处理消息 			switch(HIWORD(wParam))//判断ID为1 的子窗口消息类型 			{ 			case BN_CLICKED://确定按钮被按下消息 				//setedittext(4,TEXT("哈哈ds")); 				edittext = (TCHAR *) calloc(255,sizeof(TCHAR)); 				GetWindowText(subwindow,edittext,255); 				MessageBox(hwnd,edittext,TEXT("是"),0);				 				free(edittext); [/quote] 问题在于你的subwindow，你的subwindow是个局部变量，只在创建消息时被赋值，消息结束后subwindow被释放，在当前消息的subwindow未被赋值，直接使用，此时的subwindow是个不确定的值。你可以把subwindow设成全局变量或者静态局部变量。 另外，你应该学会调试，在异常处之前设断点，单步调试，看一看变量在哪一步之后就不是预期值，以此来定位bug。[/quote]还有，你可以把msdn里GetLastError时的Sample的代码拷过来用，加在windows的API后面，可以显示一些有用的信息。

弱弱的问一下  这是QT么？网上一搜一大堆

引用 4 楼 wang0635 的回复: GetWindowText(subwindow,&edittext,GetWindowTextLength(subwindow)); //不用取地址吧   一直显示空白啊 我就纳闷了

MessageBox(hwnd,edittext,L"提示",NULL);


Question: 求帮忙找出我的逻辑错误

引用 6 楼 csdtdp 的回复:引用 4 楼 user-1 的回复:你用调试工具设断点  一步一步的看看就明白了  大神 我错误找出来了 是到第五层递归的时候  判断条件不满足 ，但是请教大神如何修改呢  我尝试了几次都没能成功 先睡觉了  脑子有点昏  明天帮你看看

回复楼上 错误我已经找出来了 但是我还是无法修改这个错误 。尝试了几中修改 方式 但是还是没能改出来

你用调试工具设断点  一步一步的看看就明白了

麻烦再帮我吧上面的这个代码看看哪里错误  谢谢大神

/* 例1：     1、2、3、4、5这5个数字,输出不同的顺序,其中4不可以排在第三位,     3和5不能相邻,请问有多少种组合?      总的 - 四在中间的 - 3和5相邻的 + 四中间 并3和5相邻的(只能在最左边或最右边)     5*4*3*2*1 - 4*3*2*1  - 4*3*2 *2 +2*2 *2     120 - 24 - 12*4 + 8     120 - 72 + 8 = 56 */ #define 	N  	5 void   TryNumber( int  i ); int   NumFlag[N+1]  =  {0}; int   NumTaken[N+1]  =  {0}; int   static count=0; main( ) {         TryNumber( 1 );         printf("%d\n",count); } void   TryNumber(int  i) {         int   j,  k;         for(j = 1;  j <= N;  j++)         {             if((NumFlag[j]  !=  0)||(NumTaken[3]==4)||(((NumTaken[i]==3)&&(NumTaken[i-1]==5))||(((NumTaken[i]==5)&&(NumTaken[i-1]==3)))  continue;             NumTaken[i] = j;             NumFlag[j] = 1;             if(i == N)             {                 count++;                 for(k = 1; k <= N; k++) printf("%d ", NumTaken[k]);                 printf("\n");             }             else    TryNumber(i + 1);             NumTaken[i] = 0;             NumFlag[j] = 0;          }  }

哪位大神如果能  优化下我if的条件判断 更加感谢    尤其是第二个 和三个if条件  我想暴力求解的 原来用的是 numtaken【i】==3&&nunmtaken[i-1]==5     但是显示的个数是96


Question: stdout不能作为变量初始化的值

估计是怕全局变量初始化顺序的问题。 FILE* Init() {     static FILE *out = stdout;     return out; }你看看这样是否满足你要求吧

引用 2 楼 user-2 的回复:很奇怪的是C不可以，C++可以。  workaround：  # include <stdio.h>  FILE * out;  int main() {     out = stdout;      ...      return 0; }  感谢！把编译器换成g++就可以了

看了下标准，c标准规定 All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals 所以全局变量是不能用另外一个变量初始化的。


Question: 如何使用数据链表存储多变元多项式？

参考单元多项式的链表实现 http://blog.csdn.net/zhangxiangdavaid/article/details/31032251


Question: c语言随机整数生成

仅供参考：#include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79

引用 10 楼 mewiteor 的回复:[quote=引用 9 楼 wo2cj 的回复:] [quote=引用 8 楼 mewiteor 的回复:] [quote=引用 6 楼 wo2cj 的回复:] 5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。[/quote]  20改成20000000后，当运行的时候，会出现 ‘停止运行’的结果。感觉是超出运行上限了。[/quote] 那就改成全局变量，应该是栈不够用。[/quote]  当数组是array[ 100000]，并且作为全局变量，可以运行，但是运行结果如下：  1 100000 99999 99998 99997  99996 99995 99994 99993 99992  99991 99990 99989 99988 99987  99986 99985 99984 99983 99982  99981 99980 99979 99978 99977  99976 99975 99974 99973 99972  99971 99970 99969 99968 99967  99966 99965 99964 99963 99962  99961 99960 99959 99958 99957  99956 99955 99954 99953 99952  99951 99950 99949 99948 99947  99946 99945 99944 99943 99942  99941 99940 99939 99938 99937  99936 99935 99934 99933 99932  99931 99930 99929 99928 99927  99926 99925 99924 99923 99922  99921 99920 99919 99918 99917  99916 99915 99914 99913 99912  99911 99910 99909 99908 99907  99906 99905 99904 99903 99902  99901 99900 99899 99898 99897  99896 99895 99894 99893 99892  99891 99890 99889 99888 99887  99886 99885 99884 99883 99882  99881 99880 99879 99878 99877  99876 99875 99874 99873 99872  99871 99870 99869 99868 99867  99866 99865 99864 99863 99862  99861 99860 99859 99858 99857  99856 99855 99854 99853 99852  ...............  101 100 99 98 97  96 95 94 93 92  91 90 89 88 87  86 85 84 83 82  81 80 79 78 77  76 75 74 73 72  71 70 69 68 67  66 65 64 63 62  61 60 59 58 57  56 55 54 53 52  51 50 49 48 47  46 45 44 43 42  41 40 39 38 37  36 35 34 33 32  12 29 2 24 25  21 13 28 8 20  18 5 27 16 31  15 3 9 17 30  11 14 23 7 19  4 10 26 6 22   运行结果基本都是有规律的，是由大到小的输出。

感谢所有人的帮忙，感谢mewiteor！

引用 12 楼 mewiteor 的回复:[quote=引用 11 楼 wo2cj的回复:][quote=引用 10 楼 mewiteor 的回复:] [quote=引用 9 楼 wo2cj 的回复:] [quote=引用 8 楼 mewiteor 的回复:] [quote=引用 6 楼 wo2cj 的回复:] 5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。[/quote]  20改成20000000后，当运行的时候，会出现 ‘停止运行’的结果。感觉是超出运行上限了。[/quote] 那就改成全局变量，应该是栈不够用。[/quote]  当数组是array[ 100000]，并且作为全局变量，可以运行，但是运行结果如下：  1 100000 99999 99998 99997  99996 99995 99994 99993 99992  99991 99990 99989 99988 99987  99986 99985 99984 99983 99982  99981 99980 99979 99978 99977  99976 99975 99974 99973 99972  99971 99970 99969 99968 99967  99966 99965 99964 99963 99962  99961 99960 99959 99958 99957  99956 99955 99954 99953 99952  99951 99950 99949 99948 99947  99946 99945 99944 99943 99942  99941 99940 99939 99938 99937  99936 99935 99934 99933 99932  99931 99930 99929 99928 99927  99926 99925 99924 99923 99922  99921 99920 99919 99918 99917  99916 99915 99914 99913 99912  99911 99910 99909 99908 99907  99906 99905 99904 99903 99902  99901 99900 99899 99898 99897  99896 99895 99894 99893 99892  99891 99890 99889 99888 99887  99886 99885 99884 99883 99882  99881 99880 99879 99878 99877  99876 99875 99874 99873 99872  99871 99870 99869 99868 99867  99866 99865 99864 99863 99862  99861 99860 99859 99858 99857  99856 99855 99854 99853 99852  ...............  101 100 99 98 97  96 95 94 93 92  91 90 89 88 87  86 85 84 83 82  81 80 79 78 77  76 75 74 73 72  71 70 69 68 67  66 65 64 63 62  61 60 59 58 57  56 55 54 53 52  51 50 49 48 47  46 45 44 43 42  41 40 39 38 37  36 35 34 33 32  12 29 2 24 25  21 13 28 8 20  18 5 27 16 31  15 3 9 17 30  11 14 23 7 19  4 10 26 6 22   运行结果基本都是有规律的，是由大到小的输出。[/quote] 把get_rand第一行的m的赋值改成 (1<<30)/mod*mod; 少了对括号[/quote]   谢谢！ 太感激了。

引用 11 楼 wo2cj的回复:[quote=引用 10 楼 mewiteor 的回复:] [quote=引用 9 楼 wo2cj 的回复:] [quote=引用 8 楼 mewiteor 的回复:] [quote=引用 6 楼 wo2cj 的回复:] 5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。[/quote]  20改成20000000后，当运行的时候，会出现 ‘停止运行’的结果。感觉是超出运行上限了。[/quote] 那就改成全局变量，应该是栈不够用。[/quote]  当数组是array[ 100000]，并且作为全局变量，可以运行，但是运行结果如下：  1 100000 99999 99998 99997  99996 99995 99994 99993 99992  99991 99990 99989 99988 99987  99986 99985 99984 99983 99982  99981 99980 99979 99978 99977  99976 99975 99974 99973 99972  99971 99970 99969 99968 99967  99966 99965 99964 99963 99962  99961 99960 99959 99958 99957  99956 99955 99954 99953 99952  99951 99950 99949 99948 99947  99946 99945 99944 99943 99942  99941 99940 99939 99938 99937  99936 99935 99934 99933 99932  99931 99930 99929 99928 99927  99926 99925 99924 99923 99922  99921 99920 99919 99918 99917  99916 99915 99914 99913 99912  99911 99910 99909 99908 99907  99906 99905 99904 99903 99902  99901 99900 99899 99898 99897  99896 99895 99894 99893 99892  99891 99890 99889 99888 99887  99886 99885 99884 99883 99882  99881 99880 99879 99878 99877  99876 99875 99874 99873 99872  99871 99870 99869 99868 99867  99866 99865 99864 99863 99862  99861 99860 99859 99858 99857  99856 99855 99854 99853 99852  ...............  101 100 99 98 97  96 95 94 93 92  91 90 89 88 87  86 85 84 83 82  81 80 79 78 77  76 75 74 73 72  71 70 69 68 67  66 65 64 63 62  61 60 59 58 57  56 55 54 53 52  51 50 49 48 47  46 45 44 43 42  41 40 39 38 37  36 35 34 33 32  12 29 2 24 25  21 13 28 8 20  18 5 27 16 31  15 3 9 17 30  11 14 23 7 19  4 10 26 6 22   运行结果基本都是有规律的，是由大到小的输出。[/quote] 把get_rand第一行的m的赋值改成 (1<<30)/mod*mod; 少了对括号

引用 6 楼 wo2cj 的回复:5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。

引用 9 楼 wo2cj 的回复:[quote=引用 8 楼 mewiteor 的回复:] [quote=引用 6 楼 wo2cj 的回复:] 5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。[/quote]  20改成20000000后，当运行的时候，会出现 ‘停止运行’的结果。感觉是超出运行上限了。[/quote] 那就改成全局变量，应该是栈不够用。

引用 8 楼 mewiteor 的回复:[quote=引用 6 楼 wo2cj 的回复:] 5楼的朋友给的程序是可以的，但是当数组array[ ]的上限不能达到20000000，请指教。 20改成20000000就可以了，我写20是为了输出方便。 array的容量上限与get_rand的实现有关。rand()&0x7f的上限是2^15，(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^30,((unsigned long long)rand()&0x7f)<<30|(rand()&0x7f)<<15|(rand()&0x7f)的上限是2^45,以此类推。[/quote]  20改成20000000后，当运行的时候，会出现 ‘停止运行’的结果。感觉是超出运行上限了。

#include<stdio.h> #include<stdlib.h> #include<time.h> #include<assert.h>  #define ARRAY_SIZE(array) sizeof(array)/sizeof(*(array)) void init_array(int *array,size_t size); void rand_sort(int *array,size_t size); void print_array(int *array,size_t size); int get_rand(int mod); void swap(int *a,int *b);  int main() { 	// int array[20000000];     int array[20]; // size最大2^30，即1073741824     init_array(array,ARRAY_SIZE(array));     rand_sort(array,ARRAY_SIZE(array));     print_array(array,ARRAY_SIZE(array));     return 0; }  int get_rand(int mod) {     int t,m=1<<30/mod*mod;     do     {         t=(((int)rand()&0x7f)<<15|(rand()&0x7f))%mod;     }while(t>=m); // 这里保证t%mod的结果均匀分布     return t%mod; }  void swap(int *a,int *b) {     int t;     assert(a!=NULL&&b!=NULL);     t=*a;     *a=*b;     *b=t; }  void rand_sort(int *array,size_t size) {     size_t i,j;     assert(array!=NULL);     srand(time(NULL));     for(i=size;i>1;--i)         swap(array+i-1,array+get_rand(i)); }  void init_array(int *array,size_t size) {     assert(array!=NULL);     assert(size!=0);     while(size--)array[size]=size+1; }  void print_array(int *array,size_t size) {     assert(array!=NULL);     assert(size!=0);     while(size--)printf("%d ",array[size]);     putchar('\n'); }

直接rand()函数来改一下就行了嘛。 就用两个值一个值最大是32768，两个的话，最大值可以变成3276832768里面？够给20000000用了。而前面两个值可以用int，那个值之后可以用一个长整形来声明嘛。

typedef int (*rng)(void); //假定eng()产生rngbits位随机正整数，在一定次数的调用 //eng()后生成[min, max)区间内均匀分布的正整数 int scale(rng eng, int rngbits, int min, int max) {     int range = max - min,         mask = 1 << rngbits,         count = 1, limit = range, i, ret;     //保证mask = count * 2 ^ rngbits大于range以便取余     while (mask < range)     {         mask <<= rngbits;         count++;     }     //设调用eng()函数count次后得到一正整数，该正整数     //如均匀落在[0, limit]内，则其对range取余的结果     //也将均匀地落在[0, range]内；否则，舍弃该结果     limit = mask / range * range;     while (1)     {         ret = 0;         for (i = 0; i < count; i++)         {             ret <<= rngbits;             ret |= eng();         }         if (ret <= limit) return (ret % range) + min;     } }

用编译系统自带的rand（）函数是实现不了了，倒是将0-20000000随机排序这个思路还可以试试

我是要输出0到20000000之间的所有随机整数。

#include <stdio.h> #include <time.h> #include <stdlib.h>  int main() { 	srand((unsigned)time(NULL)); 	for(int i=0;i<10;i++) 		printf("%d%d%d%d%d%d%d%d\n",rand()%2,rand()%10,rand()%10,rand()%10,rand()%10,rand()%10,rand()%10,rand()%10); 	return 0; } 用最简单的方法 你可以试试找rand函数的实现 在里面应该可以修改


Question: 找出重复数并合并

来用C++，unordered_map/unordered_set 拯救你

引用 1 楼 user-2 的回复:把一对数看成一条边, 每个连通图作为一组,是不是这个意思? 就是有一个元素重复的就合并，并把原先的删除掉，（3，4）（3，5）（5，4）就合并成   （3，4，5）

把一对数看成一条边, 每个连通图作为一组,是不是这个意思?

引用 2 楼 honeyroyal 的回复:[quote=引用 1 楼 user-2 的回复:] 把一对数看成一条边, 每个连通图作为一组,是不是这个意思? 就是有一个元素重复的就合并，并把原先的删除掉，（3，4）（3，5）（5，4）就合并成   （3，4，5）[/quote] 定义个二维数组保存这关系,比如G[N][N], G[2][3]=G[3][2]=1,然后遍历一下


Question: 帮忙看看我的双链表有没有问题，能不能作为商业代码？

建议去看看开源项目，redis底层数据结构就是双端链表。可以看看牛人是怎么实现的

几点建议： 1.宏全部改成do { ... } while (0) 2.写一个测试程序


Question: signal函数的困惑

引用 4 楼 u013493901 的回复:因为signal并不是可移植的函数，有些平台上的signal实现，调用handler后会恢复信号的默认处理方式。你改成这样： void handler(int sig) {     signal(SIGINT,handler);     printf("i catch the signum[%d].\n",sig); } 就能正常工作了。但是这段代码也是有问题的，存在一个竞争的问题，如果信号在handler中的signal还未执行前到来，又会出现意外的情况。 最好的方式是使用sigaction() 函数。 恩恩 我在公司的AIX服务器上和win7上的MingW上运行的，都是调用一次后就恢复默认处理方式了。

楼主确定按照你的代码会出错，我在乌班图上运行没有出错…你打印的pid都是一样的，循环里面没意思啊

这个因为打印进程号了，所以我可以在外面用kill结束这个进程，当然这不是重点，重点是按第二次Ctrl+C的时候，程序就退出了

你这没有写退出语句啊  怎么会退出


Question: 求大神告知字符串数组如何使用scanf语句对其赋值，

scanf （ "非输入控制符 输入控制符"，输入参数）； 非输出控制符必须原样输入 要实现楼主所说的情况有很多方法，指针数组，二维数组，结构体数组..........这些相信楼主已经了解。 对于scanf的用法一般用之前最好像1L赵四老师说的清空一下键盘输入缓冲区    给你写了一个程序作为参考：  #include <stdio.h> #include <stdlib.h> int main() {     char name1[11],name2[11]; 	int i=0; 	while(i!=3){	 		printf("please input tow name:"); 		//清空输入缓冲区 		int flag=scanf("%5s %10s",name1,name2);		 		printf("res: %d name %s and %s\n",flag,name1,name2); 		i++; 	} 	system("pause"); 	return 0; }  运行结果：  如果不清空缓冲区  就会出现第三次输入的情况。

引用 2 楼 u013790834 的回复:scanf("%10s", str[i]);//这里的%10s,是输入大小为10个以内的意思，保证输入不会溢出。 } 最好%9s，留一个给结束符‘\0’

char *a[100];     //定义一个字符串数组用于存放姓名 这句话的意思是一个数组大小100，每个装的都是指针。 如果需要用它来赋值就需要先进行初始化，不然会报错。初始化的方式可以是循环开辟空间。 for(int i = 0; i < 100; i++) {     a[i] = new char[10]; } 然后进行输入。 但是一般要对一个数组进行输入应该定义二维数组： char str[100][10];//表示一个100大小的数组，每个空间为10个字节。 for(int i = 0; i < 100; i++) {     scanf("%10s", str[i]);//这里的%10s,是输入大小为10个以内的意思，保证输入不会溢出。 }

#include<stdio.h> int main() {     int m,n;     while (1) {         printf("提示：人数应为组数的整数倍,并且最多能对100人进行分组\n");         printf("请输入要分组的人数: m=");fflush(stdout);         rewind(stdin);         scanf("%d",&m);         char a[100][30];     //定义一个字符串数组用于存放姓名         printf("请输入要分组的组数: n=");fflush(stdout);         scanf("%d",&n);         if (m%n==0||m<=100) {             printf("请输入姓名:\n");             for (int i=0;i<m;i++) {                 scanf("%29s",&a[i]);             }             printf("%s",a[1]);             char *b[3]={"小红","hell"};             printf("%s",b[0]);             break;         } else {             printf("输入错误，请重新输入\n");         }     }     return 0; }


Question: 求大神解答：error C2143: 语法错误 : 缺少“}”(在“常量”的前面)

extern void choleskyfenjie(double *QF,double A[][N],int N) {     int i,j,k,p=0;     double A[N][N]; // 最后一个形参int N跟N定义冲突,改成int n, 变量A命名冲突,改成其它名字

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

你这个问题太多了 ， 首先是楼上所说的N定义冲突 ， 然后还有double A[N][N];  这个声明也冲突了， 和形参里的那个声明

养成一个良好的编码习惯你就不会出现这样的问题了


Question: ffmpeg中的 av_gettime获取的时间是以什么时间为基准的？？？

时间溢出了。  自1970年到现在的经过的时间是1479190499704705 us;   int 32位数据已无法存储，请使用int64_t 来定义time变量

我也遇到这个问题了，然后找到了你的帖子。然后依旧没有解决


Question: 有两个关于c语言的小问题

第一题上面已经有答案了 第二题要是和六楼说的一样的话，四行五列的话，计算对角线元素的和，就直接用写下标出来就好了(又不会很长的）。 下标写举个例子就是 sum=a[0][0]+a[1][1]+a[2][2]+a[3][3]; 不过这题有点小问题，就是四行五列的对角线数组上连不上啊

四分五裂！

引用 1 楼 sinat_28956991 的回复:是全班同学的平均年龄 1.定义一个结构体  struct STUDENT{    int num;    char name[20];    int age;    ..... } srtuct STUDENT buff[10]; //然后用buff操作结构体就行了  2.楼主是说4行5列这样的？  我想先问问你，你想干嘛？

[b]第二个呢 [/b][b]第二个呢

引用 3 楼 benben0729 的回复:struct student { int num; int age; char name[20]; double score; }stu[10];+1

哪里来的作业题啊？

是全班同学的平均年龄


Question: 关于链表的排序问题，帮忙看看

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

链表直接说比较不易懂, 在纸上画个图就明白了

t = *p;  *p = *q; *q = t; 你要看这里，这里是整个节点进行互换，这种互换就包括节点包含的数据和指针。

在纸上画画，一个箭头指来指去。

引用 2 楼 yin153的回复:[quote=引用 1 楼 zhangxiangDavaid 的回复:] 两个数的交换 int tmp=a; a=b; b=tmp;  还是不太懂 这么交换 那么链表的顺序会变吗 链表节点的排序[/quote] 链表结点都没变，只是交换了每个节点里存储的数据，数据排列了，就实现了目的

一般只需交换数据区即可

参考代码段: https://github.com/user-7/Senior-middle-school/blob/master/Filling%20in%20the%20gaps.c

引用 1 楼 zhangxiangDavaid 的回复:两个数的交换 int tmp=a; a=b; b=tmp;  还是不太懂 这么交换 那么链表的顺序会变吗 链表节点的排序

两个数的交换 int tmp=a; a=b; b=tmp;


Question: 有个C语言的运算我没搞清楚

引用 2 楼 kongsu 的回复:[quote=引用 1 楼 user-3 的回复:] 看置顶帖http://bbs.csdn.net/topics/370153775  我能理解为。。。。 这个是没法直接解释的   要看编译器自己的处理顺序？ [/quote]   楼主不要怀疑自己，你只要知道j最后结果是多少就行。 但是有很多时候运算的结果不是上面所述。 因为在C语言中，编译器可以选择先计算函数里的那个参数的值，这个自由性提高了编译器的效率，但是如果变量使用了增量运算符就会带来麻烦。 就像你说的这个问题，它可能先计算括号里的，也可能先做变量的增量运算，这是不确定的。确定的是编译器在程序结束时j的值增加三次。  详解：C语言的副作用是指对对象或文件的修改，int  num=10；，这个简单的赋值语句从C的角度看是将变量num的值改成10，这就是一个副作用。 顺序点是程序执行中的一点，在这个点处所有副作用都在进入下一步前被计算，在C中；就标志了一个顺序点。 例子:  while(num++ < 10){     printf("%d\n",num); }  上面说了所有副作用都在顺序点之前完成，所以先做while（）中的计算（先判断在做后缀的++）再printf。 例子： num=(4 + x++)+(6 + x++); 先看（4 + x++），因为它不是一个完整的表达式（没有顺序点），所以不能确定到底是先做加法还是先 x++，但是在分号以前C编译器能保证x能自增两次。  所以我们要尽量避免用这样的语句。   希望对楼主有用。

如果不是为了考试什么的，没必要纠结于这类题目，因为不同的编译器的编译顺序不一样，得出的结果也会不一样

引用 1 楼 user-3 的回复:看置顶帖http://bbs.csdn.net/topics/370153775  我能理解为。。。。 这个是没法直接解释的   要看编译器自己的处理顺序？