Question: C语言简单的编程 请牛人指出一下错误，新人菜鸟 勿喷

引用 1 楼 turingo 的回复:a循环每次都要清零：     谢谢牛人！！！感激！！

a循环每次都要清零：  #include <stdio.h>  int main(int argc, char* argv[]) {     int m;     int n;     int a;     int b = 0;     int i;     int j;          scanf("%d%d", &m, &n);     for(i = m; i <= n; i++)     {         a = 0;         for(j = 2; j <= i; j++)         {             if((i%j) == 0)             {                 a = a + 1;             }         }         if(a <= 1)         {             printf("%d ",i);             b++;         }     }          if(b == 0)     {         printf("no");     }     printf("\n");          return 0; }


Question: 对文件的概念

你说的是逻辑上的文件，书上说的是物理上的文件。

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

顶楼上大神。。。。 PS：建议lz可以看看操作系统原理.....然后就明白鸟

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

文件就是一块存储的区域。里面存的就是你要的信息。 你说的照片也是存在你硬盘上的。

文件，不管是什么，就是信息。是信息，就得找个地方存储它。那么，存储它的地方就是一块存储区域。对程序而言，文件管理的任务，就是管理这些存储区域，他关心的是这些信息有多大，要占用多少地方，存到哪里去或者从哪里区，而不会管存储的到底是什么玩意儿。

存储区域不就是用来存储信息和数据的吗？

那是逻辑上的说法，或者说通俗的理解，其本质不都是存储在硬盘或内存中的信息吗？


Question: textbox居中显示怎么弄

发错地方了。。。

引用 2 楼 CC520xiaoguai 的回复:我把代码改成 <div style="margin:0px auto; ">  居中也不对啊 是让那个文本框居中还是文本框的文字居中啊？ 文本框居中，也就是说包含文本框的容器宽度 100% 才行啊 width 它要是跟文本框一样的宽度，那居中不居中也看不出来

不是这里？

额，你发错帖子了，发错地方了

发错地方了？ TextBox 设置 style="text-align:center;" ？


Question: 谁能给我指一条路

多看书，靠老师讲的那些根本不可能懂。

有学习黑客知识的地方嘛 书籍。。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

从 http://www.pediy.com/ 开始上路。


Question: 实在搞不明白为什么错了 总是提示错误

引用 5 楼 xiaoxinwen0001 的回复:哦哦 谢谢大家 知道了 我用的VC++ 6.0的不好意思 我是新手 还是没理解这个错误是什么原因

Compiling... nnn.c G:\C\nnn.c(4) : error C2061: syntax error : identifier 'IsPrime' G:\C\nnn.c(4) : error C2059: syntax error : ';' G:\C\nnn.c(4) : error C2059: syntax error : 'type' G:\C\nnn.c(39) : warning C4013: 'IsPrime' undefined; assuming extern returning int G:\C\nnn.c(41) : error C2001: newline in constant G:\C\nnn.c(42) : error C2143: syntax error : missing ')' before 'else' 执行 cl.exe 时出错.  nnn.obj - 1 error(s), 0 warning(s) 总提示我 这个文件名错误 无奈

# include <stdio.h>   bool IsPrime (int val) { 	 	int i ;  	 	for (i = 2 ; i < val ; ++i) 	{ 		 		if (val% i == 0) 			break; 		 		 		 	} 	     if (i == val )  		return true ; 	else  		return false ; 	 	 	 	 }   int main (void)  { 	 	int m ; 	 	scanf("%d", &m); 	 	 	if ( IsPrime(m) ) 		 		printf ("Yes! \n"); 		else 		printf("No!\n"); 	 	 	 	 	 	 	return 0 ; }  我是就把老师代码 粘贴过来都出错 但是有时候就不出错 我是在怀疑 有没有可能是我的编译器有毛病啊 感觉不对劲呢

# include <stdio.h>   int     IsPrime (int val) { 	 	int i ;  	 	for (i = 2 ; i < val ; ++i) 	{ 		 		if (val% i == 0) 			break; 		 		 		 	} 	     if (i == val )  		return 1 ; 	else  		return 0 ; 	 	 	 	 }   int main (void)  { 	 	int m ; 	 	scanf("%d", &m); 	 	 	if ( IsPrime(m) ) 		 		printf ("Yes! \n"); 		else 		printf("No!\n"); 	 	 	 	 	 	 	return 0 ; }  这样就行了 还真是对bool类型的 不敏感啊

仅供参考 /*************************************************************************     > File Name: isprimer.c     > Author: 傻李     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月18日 星期二 17时30分46秒  ************************************************************************/ #include<time.h> #include<stdlib.h> #include<stdio.h> int isprimer(int n) { 	int state = 1; 	int i; 	for(i =2; i < n;++i) 	{ 		if(0 == n%i) 		{ 			state = 0; 			break; 		} 	} 	return state; }  int main() { 	time_t t; 	srand((unsigned)time(&t)); 	int i =(int)random()%100; 	printf("%d\n",i); 	if(isprimer(i)) 		printf("YES\n"); 	else 		printf("NO\n"); 	return 0; }

引用 10 楼 FENGQIYUNRAN 的回复:7楼的调试方法值得楼主学习 货卖识家！

bool  IsPrime (int val) {	int i ; 	for (i = 2 ; i < val ; ++i) 	{ 		if (val% i == 0) 			break; 	}  	if (i == val )  		return true ; 	else  		return false ; }   int main (void) { 	int m ; 	scanf("%d", &m);  	if ( IsPrime(m) )  		printf ("Yes! \n"); //这里错了 	else 		printf("No!\n");  	system("pause"); 	return 0 ; }

7楼的调试方法值得楼主学习

不管用的哪个编译器，都会报错的，哪怕不准确。

少了一个" 在第一个printf

++  引用 1 楼 u012878380 的回复:楼主要细心你的主函数第一个printf少一个引号

楼主要细心你的主函数第一个printf少一个引号

引用 6 楼 xiaoxinwen0001 的回复:我问一下 您用的这个编译器是？ c-free 比较不错的，还有dev c++、codeblocks等等，楼主可以从网上搜搜相关资料 比如——C/C++开发者必不可少的15款编译器+IDE

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

引用 4 楼 u012421456 的回复:这种错误，编译器会报错的，楼主要学会自己看编译器的报错提示，如果你的编译器没有报错，那建议换一个   我问一下 您用的这个编译器是？

哦哦 谢谢大家 知道了 我用的VC++ 6.0的


Question: 想将字符数组中的数据转换成整型后存入一个新的整型数组中

这写法好牛！！！if(i%1 == 0 && i) cout << endl;你文本里面是什么样的格式？

谢谢6楼，我再试试

还没弄出来？好吧，仅供参考…… #include <stdio.h> #define MAXLINE 100   int main () {   	int str[MAXLINE + 1];   	FILE * fp;   	int count = 0, i;  	if(NULL == (fp = fopen("abc.txt", "r"))) 	{ 		printf("Open error!\n"); 		return -1; 	}  	 	while(EOF != (fscanf(fp, "%d", &str[count++])))     { 		if (count >= MAXLINE)	//越界 		{ 			printf("too much...\n"); 			break;	 		} 		     } 	  	for(i = 0; i < count; i++)   		printf ("I have read: %d\n",str[i]);   	return 0; }

myFile.open("c:\\5.txt"); int c[5000]; int i = 0; if(myFile.is_open()) { 	while(!myFile.eof()) 	{ 		myFile >> c[i]; 		cout << c[i] << ' '; 		++i; 	} } myFile.close();

3楼：.txt中存放的不就是字符型吗，怎么直接读成整形啊？

直接读成整型数据

是这样的


Question: fscanf

请检查fscanf函数的返回值！

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.  To read strings not delimited by space characters, a set of characters in brackets ([ ]) can be substituted for the s (string) type character. The corresponding input field is read up to the first character that does not appear in the bracketed character set. If the first character in the set is a caret (^), the effect is reversed: The input field is read up to the first character that does appear in the rest of the character set.  Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]. This is a common scanf function extension, but note that the ANSI standard does not require it.

引用 1 楼 turingo 的回复:这是正则表达式的写法，参考 http://blog.sina.com.cn/s/blog_52ffdb690100j3im.html  博客我看了，但还是不能理解。比如第一句中%已经和 [] 匹配了，那后面的s怎么理解呢，还有#号


Question: c入门以后，该怎样提高，还有以后该如何选方向啊

C语言学了要用，如果想学windows下的编程，推荐一个视频：  http://edu.51cto.com/course/course_id-2402.html

做一个实际的程序是唯一的道路。 光是编程语言本身是没法做很多事情的，得要有可调用的工具/接口/API/库等。 推荐NI的LabWindows/CVI，纯C的图形界面，工程师快速开发的福音。

引用 27 楼 kingbummy 的回复:1.耐性 2.坚持 3.自信 有了这三个，虽然这语言可怕，你会掌握的。加油哥们。多谢鼓励！

引用 23 楼 WizardOz 的回复:光看语言是没有用的，严蔚敏的《数据结构》可以学一下，上面的结构都用C语言自己写一遍，C语言就算合格了，没有必要继续纠结于语言层面。可以多看一些算法和操作系统的东西。学一些开源框架的结构。然后涉猎一些其它语言。多谢了

引用 25 楼 haha5722166 的回复:同信计的，学了数据结构了吗？学了啊

同信计的，学了数据结构了吗？

另外，直接看什么内核源代码是不推荐的。自己没有写过一定量的代码，直接看那些高手写的东西，你很难理解，纯属浪费时间。

白费功夫呀，兄弟 计算机不是这么学的

实践吧，如果只是学了几个月，能入门真是强人了。

也过来看看，大家一起加油！

谢谢！

没有让你读内核源码。

以后的方向该怎么选啊？

感谢13楼，但是这样的开源代码，比如内核没有注释，怎么弄明白呢

引用 14 楼 w74839520 的回复:感谢13楼，但是这样的开源代码，比如内核没有注释，怎么弄明白呢这就需要功底了

开开源代码,写代码. 书本上讲的东西基本没什么用的,主要是架构设计和业务理解.

专攻一个平台，Linux或者Windows； 读完一个开源代码，比如apache或者nginx。  其实C语言本身是比较简单的。

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


Question: 大神们帮我看看这个求平均值的C程序，为什么输出结果有错

谢谢大家！  已经知道噜  以后会好好注意标准输出函数的格式的

#include <stdio.h> int main(void) {     float * average(float a[]);     float arry[4];     float *p;     printf("Enter arry[3]'s value:");     scanf("%f,%f,%f", &arry[0], &arry[1], &arry[2]);     p = average(arry);     printf("this arry's average is%f:\n",*(p+3));     return 0; } float * average(float a[]) {     a[3] = (a[0] + a[1] + a[2]) / 3.0;     return a; }    scanf哪里有些改变，

return a，何不直接改为return &a[3]?输出直接*p;

引用 4 楼 w74839520 的回复:[quote=引用 3 楼 u013163178 的回复:] scanf_s("%f,%f,%f", &arry[0], &arry[1], &arry[2]); 改成 scanf_s("%f%f%f", &arry[0], &arry[1], &arry[2]);   逗号需要原样输入才行。 [/quote]是的

格式化输入输出重点为格式，一个萝卜一个坑，拒绝和尚多粥少和和尚少粥多的中国特色，格式需要绝对匹配。  PS：建议楼主还可以顺便看一看关于C语言变参函数的知识，未来编程会有帮助。。。。。

PS:  建议参见百度百科中的Scanf函数原理讲解     http://baike.baidu.com/view/1390039.htm?fr=aladdin

引用 3 楼 u013163178 的回复:scanf_s("%f,%f,%f", &arry[0], &arry[1], &arry[2]); 改成 scanf_s("%f%f%f", &arry[0], &arry[1], &arry[2]);   逗号需要原样输入才行。

同意1楼，代码没问题，估计是输入的问题

#include <stdio.h> int main(void) { 	float * average(float a[]); 	float arry[4]; 	float *p; 	printf("Enter arry[3]'s value:"); 	scanf("%f,%f,%f", &arry[0], &arry[1], &arry[2]);  	//楼主你的这个scanf的输入需要输入其中的逗号，你可能忘记输入了吧。 	//这程序没有错。 	p = average(arry); 	printf("this arry's average is%f:\n",*(p+3)); 	return 0; } float * average(float a[]) { 	a[3] = (a[0] + a[1] + a[2]) / 3.0; 	return a; }


Question: 如何实现上下键输入历史命令

readline不只是有历史功能  license是个问题的话，可以读懂readline，取其中历史这块实现之。

看不懂你题目说的，如果是把字符串发给标准输入stdin，可以直接调用write：  char *buf = "hello\0"; write(fileno(stdin), buf, strlen(buf));   上下键输入历史命令的话，你得对历史命令进行缓冲，链表形式存放

_pipe Creates a pipe for reading and writing.  int _pipe( int *phandles, unsigned int psize, int textmode );  Routine Required Header Optional Headers Compatibility  _pipe <io.h> <fcntl.h>,1 <errno.h>2 Win 95, Win NT    1 For _O_BINARY and _O_TEXT definitions.  2 errno definitions.  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  _pipe returns 0 if successful. It returns –1 to indicate an error, in which case errno is set to one of two values: EMFILE, which indicates no more file handles available, or ENFILE, which indicates a system file table overflow.  Parameters  phandles[2]  Array to hold read and write handles  psize  Amount of memory to reserve  textmode  File mode  Remarks  The _pipe function creates a pipe. A pipe is an artificial I/O channel that a program uses to pass information to other programs. A pipe is similar to a file in that it has a file pointer, a file descriptor, or both, and can be read from or written to using the standard library’s input and output functions. However, a pipe does not represent a specific file or device. Instead, it represents temporary storage in memory that is independent of the program’s own memory and is controlled entirely by the operating system.  _pipe is similar to _open but opens the pipe for reading and writing, returning two file handles instead of one. The program can use both sides of the pipe or close the one it does not need. For example, the command processor in Windows NT creates a pipe when executing a command such as  PROGRAM1 | PROGRAM2  The standard output handle of PROGRAM1 is attached to the pipe’s write handle. The standard input handle of PROGRAM2 is attached to the pipe’s read handle. This eliminates the need for creating temporary files to pass information to other programs.  The _pipe function returns two handles to the pipe in the phandles argument. The element phandles[0] contains the read handle, and the element phandles[1] contains the write handle. Pipe file handles are used in the same way as other file handles. (The low-level input and output functions _read and _write can read from and write to a pipe.) To detect the end-of-pipe condition, check for a _read request that returns 0 as the number of bytes read.  The psize argument specifies the amount of memory, in bytes, to reserve for the pipe. The textmode argument specifies the translation mode for the pipe. The manifest constant _O_TEXT specifies a text translation, and the constant _O_BINARY specifies binary translation. (See fopen for a description of text and binary modes.) If the textmode argument is 0, _pipe uses the default translation mode specified by the default-mode variable _fmode.  In multithreaded programs, no locking is performed. The handles returned are newly opened and should not be referenced by any thread until after the _pipe call is complete.  In order to use the _pipe function to communicate between a parent and a child process, each process must have only one handle open on the pipe. The handles must be opposites: if the parent has a read handle open, then the child must have a write handle open. The easiest way to do this is to OR (|) the _O_NOINHERIT flag with textmode. Then, use _dup or _dup2 to create an inheritable copy of the pipe handle you wish to pass to the child. Close the original handle, and spawn the child process. Upon returning from the spawn call, close the 'duplicate' handle in the parent process. See Example 2 below for more information.  In Windows NT and Windows 95, a pipe is destroyed when all of its handles have been closed. (If all read handles on the pipe have been closed, writing to the pipe causes an error.) All read and write operations on the pipe wait until there is enough data or enough buffer space to complete the I/O request.  Example 1  /* PIPE.C: This program uses the _pipe function to pass streams of  * text to spawned processes.  */  #include <stdlib.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <process.h> #include <math.h>  enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */ #define NUMPROBLEM 8  void main( int argc, char *argv[] ) {     int hpipe[2];    char hstr[20];    int pid, problem, c;    int termstat;     /* If no arguments, this is the spawning process */    if( argc == 1 )    {        setvbuf( stdout, NULL, _IONBF, 0 );        /* Open a set of pipes */       if( _pipe( hpipe, 256, O_BINARY ) == -1 )           exit( 1 );         /* Convert pipe read handle to string and pass as argument         * to spawned program. Program spawns itself (argv[0]).        */       itoa( hpipe[READ], hstr, 10 );       if( ( pid = spawnl( P_NOWAIT, argv[0], argv[0],              hstr, NULL ) ) == -1 )           printf( "Spawn failed" );        /* Put problem in write pipe. Since spawned program is         * running simultaneously, first solutions may be done         * before last problem is given.        */       for( problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000)       {           printf( "Son, what is the square root of %d?\n", problem );          write( hpipe[WRITE], (char *)&problem, sizeof( int ) );        }        /* Wait until spawned program is done processing. */       _cwait( &termstat, pid, WAIT_CHILD );       if( termstat & 0x0 )          printf( "Child failed\n" );         close( hpipe[READ] );       close( hpipe[WRITE] );     }     /* If there is an argument, this must be the spawned process. */    else    {        /* Convert passed string handle to integer handle. */       hpipe[READ] = atoi( argv[1] );        /* Read problem from pipe and calculate solution. */       for( c = 0; c < NUMPROBLEM; c++ )       {          read( hpipe[READ], (char *)&problem, sizeof( int ) );         printf( "Dad, the square root of %d is %3.2f.\n",                  problem, sqrt( ( double )problem ) );        }    } }   Output  Son, what is the square root of 1000? Son, what is the square root of 2000? Son, what is the square root of 3000? Son, what is the square root of 4000? Son, what is the square root of 5000? Son, what is the square root of 6000? Son, what is the square root of 7000? Son, what is the square root of 8000? Dad, the square root of 1000 is 31.62. Dad, the square root of 2000 is 44.72. Dad, the square root of 3000 is 54.77. Dad, the square root of 4000 is 63.25. Dad, the square root of 5000 is 70.71. Dad, the square root of 6000 is 77.46. Dad, the square root of 7000 is 83.67. Dad, the square root of 8000 is 89.44.   Example 2  // This is a simple filter application.  It will spawn  // the application on  command line. But before spawning  // the application, it will create a pipe that will direct the  // spawned application's stdout to the filter.  The filter  // will remove ASCII 7 (beep) characters.  // Beeper.Cpp  /* Compile options needed: None */ #include <stdio.h> #include <string.h>  int main() {    int   i;    for(i=0;i<100;++i)       {          printf("\nThis is speaker beep number %d... \n\7", i+1);       }    return 0; }   // BeepFilter.Cpp /* Compile options needed: none    Execute as: BeepFilter.exe <path>Beeper.exe */ #include <windows.h> #include <process.h> #include <memory.h> #include <string.h> #include <stdio.h> #include <fcntl.h> #include <io.h>  #define   OUT_BUFF_SIZE 512 #define   READ_HANDLE 0 #define   WRITE_HANDLE 1 #define   BEEP_CHAR 7  char szBuffer[OUT_BUFF_SIZE];  int Filter(char* szBuff, ULONG nSize, int nChar) {    char* szPos = szBuff + nSize -1;    char* szEnd = szPos;    int nRet = nSize;     while (szPos > szBuff)    {       if (*szPos == nChar)          {             memmove(szPos, szPos+1, szEnd - szPos);             --nRet;          }       --szPos;    }    return nRet; }  int main(int argc, char** argv) {    int nExitCode = STILL_ACTIVE;    if (argc >= 2)    {       HANDLE hProcess;       int hStdOut;       int hStdOutPipe[2];        // Create the pipe       if(_pipe(hStdOutPipe, 512, O_BINARY | O_NOINHERIT) == -1)          return   1;        // Duplicate stdout handle (next line will close original)       hStdOut = _dup(_fileno(stdout));        // Duplicate write end of pipe to stdout handle       if(_dup2(hStdOutPipe[WRITE_HANDLE], _fileno(stdout)) != 0)          return   2;        // Close original write end of pipe       close(hStdOutPipe[WRITE_HANDLE]);        // Spawn process       hProcess = (HANDLE)spawnvp(P_NOWAIT, argv[1],         (const char* const*)&argv[1]);        // Duplicate copy of original stdout back into stdout       if(_dup2(hStdOut, _fileno(stdout)) != 0)          return   3;        // Close duplicate copy of original stdout       close(hStdOut);        if(hProcess)       {          int nOutRead;          while   (nExitCode == STILL_ACTIVE)          {             nOutRead = read(hStdOutPipe[READ_HANDLE],               szBuffer, OUT_BUFF_SIZE);             if(nOutRead)             {                nOutRead = Filter(szBuffer, nOutRead, BEEP_CHAR);                fwrite(szBuffer, 1, nOutRead, stdout);             }              if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode))                return 4;          }       }    }     printf("\nPress \'ENTER\' key to continue... ");    getchar();    return nExitCode; }   Process and Environment Control Routines  See Also   _open


Question: int a['10'];  这样编译不会报错，sizeof测试数组长度也是有值，为什么呢？

字母在编译器看来是整形得！编译器会把它翻译成字母对应的asll吗

引用 1 楼 JiangWenjie2014 的回复:multi-character character constant  具体的值是多少由编译器自己决定。

'10' 会自动转化成整形，具体值是多少就要看ANSII表

我明白了，‘10’在内存中由于小端存放所以是的是30 31，然后系统对他用四个字节进行解析!所以得到的值是12592！谢谢各位的帮助

为什么‘10’=0x3130  ？怎么转换的十六进制？

multi-character character constant

'10'等同于'1'，所以应该是0x31，楼主试试看是不是？

1. int a[N]    N是一个整形，“10”  是1个字符串   而你写成 ‘10’   如： char c = ‘10’;   int i = c; 此时的 i = 48    也就是c = ‘10’  截断了  变成 c = ‘0’ 单字符写成2个字符....  2.写成‘10’，会转换成整形，所以sizeof（a）就有数撒

警告是有的：warning: multi-character character constant 编译器会把字符转换成整数，‘10’ = 0x3130 = 12592

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


Question: C源代码经过编译后最终生成可执行文件(机器码)

底层指令相同是对的 但是在底层架构的上面还有一层操作系统层，要知道你的程序是跑在os层，而不是直接在底层架构上跑的，简单的理解就是，os是负责连接你程序和底层的架构的。  所以不同的操作系统在沟通你的程序和底层是有所不同的，造成了这种问题

引用 5 楼 gscaiyucheng 的回复:[quote=引用 1 楼 luciferisnotsatan 的回复:] 你编完的东西实在操作系统上运行的。windows提供的系统函数和ubuntu一样么？ 如果你不用操作系统提供的任何东西，那程序应该是可以在硬件上运行的。不错这也就没有为什么不能在ubuntu上运行这回事了，压根和ubuntu没任何关系。  也就是说：百度上面说的生成可执行的机器语言代码，这个机器语言代码其实还是要调用操作系统的给的接口是吗？麻烦您了[/quote] 是的。 其实在你代码能调系统API之前，先要系统能认识你这个文件是可执行文件，并把它执行起来。可执行文件的格式，window和linux是不一样的。

引用 1 楼 luciferisnotsatan 的回复:你编完的东西实在操作系统上运行的。windows提供的系统函数和ubuntu一样么？ 如果你不用操作系统提供的任何东西，那程序应该是可以在硬件上运行的。不错这也就没有为什么不能在ubuntu上运行这回事了，压根和ubuntu没任何关系。  也就是说：百度上面说的生成可执行的机器语言代码，这个机器语言代码其实还是要调用操作系统的给的接口是吗？麻烦您了

编译方式以及系统调用决定了

操作系统对自己可执行文件的调度方式是不一样的，参考http://www.it165.net/os/html/201409/9304.html，而Windows下的exe文件的处理又是另外一种方式。

你写的是操作系统上跑的程序，不是操作系统本省。

引用 楼主 gscaiyucheng 的回复:如题，在网上查了下  百度上说：高级语言经编译最终生成可执行的机器码文件  wiki上说：有一些编译器输出的代码，将运行于与编译器所在相同类型的计算机和操作系统之上，这种编译器叫做本地编译器  疑问： 1.如果最终生成可执行文件里面都是机器码，也就是机器可以识别的代码，指的是指令集吗？ 2.如果是cpu指令集，那么同一台X86架构的计算机装的双系统(windows,ubuntu)，在windows下编译生成的文件为什么不能在ubuntu下不能运行呢？  希望有大侠指点一下，非常感谢 有空参考我的博文：http://blog.csdn.net/binaryhead/article/details/41083927，希望对你有帮助。


Question: c生成dll文件

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……

两种方法： 1.自己定义一个头文件，包含C文件函数； 2.定义一个.def文件，导出函数名

C++写成   extern "C " _stdcall  int   fun_xxxx(int a){return 0;};  C写成   _stdcall  int   fun_xxxx(int a){return 0;};  主要有原因是，Windows  API 函数都不是 （_cdcel ）C调用约定 而是 _stdcall 调用约定 所以 Windows 上的每种开发语言，几乎都支持这种调用约定生成的函数。  如果想再可靠些, 可以写成  WINAPI int  fun_xxxx(int a){return 0;}; WINAPI 是 windows.h 中定义了的一个宏，代表 WINAPI 的调用约定。   生成DLL的几种方法：      1)命令行方式 ，可以直接命令行编译生成 .dll 这必须了解，编译的细节，         在这个时代只有那些愿意深入学习的人          才会用命令行方式编译      2) 修改编译选项，这个也必须有一个已经创建的工程，才能修改      3)在VC（VS）开发环境里，直接创建一个 .dll 工程，创建新的 .c,.cpp 或者添加现有的 .c 到 这个工程             这里，创建.dll 工程的时候，有几个选项，每个选项会产生一种类型的 dll。

C 语言对函数名的改编很简单，往往只是在前面加一个 下划线 因为C语言没有函数重载，所以每个编译后的函数名和代码里的函数名非常一致。 C++ 有函数重载，做不到编译后的函数名和代码里的函数名一致 所以有一套比较复杂的名字改编规则，而且每个编译器做法不同 C++要想达到C的效果，往往 要 在函数前面，加 extern “C” 让编译器像C那样生成 函数名字。  linux 有 共享库 后缀是 .so 这是linux 系统的动态库  效果 等同于 DOS ,windows 上的.dll C语言的 DLL 有几种办法生成，最简单的是让 VC自动生成一个框架，然后把 .c 文件添加进去 而写def 对于生成 .dll 是最直接，最能够清晰控制生成的dll 中输出函数的方式  一般来说，写成   C++ extern "C " _stdcall  int   fun_xxxx(int a){return 0;}; 这种方式是不用担心 生成的函数，其它语言不能调用的  一般  .def 这么写就可以了 ;xxx.def Libray  xxx      EXPORTS  fun_xxxx      ;

引用 3 楼 lm_whales 的回复:dll 和对应的头文件，没关系 提供头文件是为了更方便使用 dll  .c 如果不包含 main ,可以很简单的生成  dll 单一 .c 如果没有引用其他文件定义的函数函数（包括库函数），不需要额外的头文件，就可以生成   dll 如果引用了别的文件定义的函数，则通常必须有对应的头文件 （可能还需要.lib .obj 文件）  。。。。。头文件内容，有时候，可以复制过来，这样就不用 包含头文件了， 不过通常都是包含头文件的，因为包含头文件更简单，更不容易出错。 可为什么我生成不了呢？还有，我想再问一个问题，就是我用c生成dll和用c++生成dll，对于python有什么不同（语法和传递函数），我在网上看的大都是c生成的，

引用 1 楼 user-4 的回复:建一个 dll 的工程，把你的 c 文件放进去，定义函数导出，编译我用vs试的，但是它需要头文件，我这个没有，只有.c

建一个 dll 的工程，把你的 c 文件放进去，定义函数导出，编译


Question: 赋值地址的问题~~

引用 4 楼 pokerLee 的回复:[quote=引用 2 楼 u011337306 的回复:] LZ没有发现p[n]本身就是一个地址？而p[n] = str[n]其实就是对二维数组某一行首地址赋值给p[n] 如果你将p = str， 仅仅只是给p[0]赋值了！！！我想请教为什么要做这么一个赋值？原因是什么呢？[/quote] LZ你要看后面函数传递的是指针，而这些函数对指针所做的修改，也就是对数组str的修改，如果要使用str，当然可以！但楼主要看清这段代码的意思，如果使用str，并且当成一个二维数组来理解，是不是使得代码变得晦涩、难以理解？尤其注意origin_put(p,n)，这里就已经将整个str二维数组传递进去了！这样子是不是就可以随便对str的某一行进行修改了？这样子很方便的！这样子赋值就是将二维数组变成一维指针数组，方便对二维数组的修改以及函数参数的传递，不知道LZ还有问题没？   switch(command[0])    {    case 'a': puts("put originally:");      origin_put(p,n); break;    case 'b': puts("put in order of ascii:");     ascii_put(p,n);  break;    case 'c': puts("put in order of string's length:");  length_put(p,n); break;    case 'd': puts("put in order of first word's length:"); word_put(p,n);   break;    case 'e': break;

因为后面一堆函数的参数都是p而非str

引用 2 楼 u011337306 的回复:LZ没有发现p[n]本身就是一个地址？而p[n] = str[n]其实就是对二维数组某一行首地址赋值给p[n] 如果你将p = str， 仅仅只是给p[0]赋值了！！！我想请教为什么要做这么一个赋值？原因是什么呢？

应该是与函数的参数有关。  例如 origin _put(p, n);  第一个参数的类型是一个指针数组，用p正好。 而如果使用str，类型就不相符了，会有警告或者错误。  如果在设计origin _put()时，直接把形参定为二维数组，这也是不行的，严格说是不方便的。  所以origin _put()的形参应该是指针数组，而不是二维数组。那么在主函数调用时就要做一个小处理。

*p[10]是一个一维数组，里面存有10个char*变量，可以说是10个c字符串。 我猜函数length_put(p,n)的第一个参数应该是一维字符串数组，如果不用p[n] = str[n],那么这个地方就不好写了。 比如你写成length_put(str,n),这个结果应该不正确，因为str是一个元素为char（而不是字符串char*）的二维数组。 如果你写length_put(str[1],1)应该能输出第一行（str[1]被处理为一个字符串），但只能输出一行，失去了length_put（）函数的使用意义，当然也可以使用循环来输出，只是这样就要多写几行代码。 个人观点，仅供参考，希望有用。

估计是后面调用函数内部会对p进行改变，str[]保存原来的串


Question: static？

这样也可以  //b.cc int *M()   {     static int a=2;     int *b=&a;     return b;   } int main()   {     cout<<*M()<<endl;   }

引用第一个得到的是一个垃圾值，也就是不确定值。不要范低级错误。 1.a.cc 程序用gcc编译通过，但是，有陷阱。 对么？  2.b.cc 变量：a，b，必须两个都是static。 否则，程序也有陷阱。 对么？

第一个得到的是一个垃圾值，也就是不确定值。不要范低级错误。

这种写法 好像这个： int i = 0; const int * const j = i;

静态变量有两个特点 １．生存起和程序一样长。 ２．无外部链接属性。

哥， 你还是好好看书吧。 这个跟引用是一个道理。


Question: 在C语言中，else不是与最近的一个if结合么？为何我这里不是

#include<stdio.h> int main(){     int year,month,day=0;     printf("input year,month:\n");     scanf("%d,%d",&year,&month);  if(month==2 && (year%4==0 && year%100!=0 || year%400==0))         day=29;     else day=28;     if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)          day=31;     if(month==4||month==6||month==9||month==11)         day=30;         printf("days=%d",day);     return 0; } 非得要这样就把润年的放在前面

多个条件语句换成else if 比较符合逻辑

LZ顺序语句和条件语句没学好`

楼主是有些逻辑问题，像二楼说的，前面的if全作废，几乎是无用的

我是个菜鸟，赞同二楼的讲法。

二楼是重点，要实现这个，可以用switch，也可以 #include<stdio.h> int main(){ 	int year,month,day=0; 	printf("input year,month:\n"); 	scanf("%d,%d",&year,&month); 	if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { 		day=31; 		goto Print; 	} 	if(month==4||month==6||month==9||month==11) { 		day=30; 		goto Print; 	} 	if(month==2 && (year%4==0 && year%100!=0 || year%400==0)) { 		day=29; 		goto Print; 	}	 	else  		day=28; 	Print:  	printf("days=%d",day); 	return 0; }

是与最近的没有结合的else结合

二楼说得对，就最后那个if else有用，days不是28就是29 ，前面不管咋样都被覆盖了

LZ怎么输入的？

跟你的件有关系，

后边两个if前要加 else  否则那个最后的else 就和前边两个if没关系了，也就是除了月份是2并且是闰年以外的所有情况。而你的意图是除了上边那些情况之外的所有情况

逻辑问题。。。

引用 楼主 w82076322 的回复:#include<stdio.h> int main(){ 	int year,month,day=0; 	printf("input year,month:\n"); 	scanf("%d,%d",&year,&month); 	if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)  		day=31; 	if(month==4||month==6||month==9||month==11) 		day=30; 	if(month==2 && (year%4==0 && year%100!=0 || year%400==0)) 		day=29; 	else day=28; 	printf("days=%d",day); 	return 0; }   在执行过程中，总会执行到day=28，输出结果于是总是28. 这段代码来自《C语言编程技巧分析》（清华大学出版社   高禹 主编  2014年1月第一版） 不要改成if-else if，我会那种方法，只想知道这段代码为何总执行else 看2楼的，仔细想想吧，编译器除了优化外，都会按照程序员写出来的程序语句翻译的。

逻辑问题，不是语法问题  3楼说得对

if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) day=31;  else if(month==4||month==6||month==9||month==11)day=30;  else  if(month==2 && (year%4==0 && year%100!=0 || year%400==0))day=29;  else day=28;

楼主的逻辑也不对哦，     if(month==2 && (year%4==0 && year%100!=0 || year%400==0))         day=29;     else day=28; ===>     if(month==2 && (year%4==0 && year%100!=0 || year%400==0))         day=29;     else if(month==2) day=28; 或者 ===>     if(month==2)          if (year%4==0 && year%100!=0 || year%400==0))             day=29;         else             day=28;

输入 2000,2 输出就是29啊 注意要输入逗号哦！

确实是只和最近的if结合，所以你的day只能是29，或者28。 前面的几个if全部作废了。 即使前面是赋值31，后面的if和else会重新赋值

当month == 1,3,4,5,6,7,8,9,10,11,12时 if(month==2 && (year%4==0 && year%100!=0 || year%400==0))条件不满足就执行else语句day=28;


Question: 各路大神 求助 我现在想自学c语言  准备备考明年2级  求支招

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

多练习就可以了，

不管怎么说：要想学习一门知识，首先你需要了解这个语言的特点（c语言嘛：你最关键的是要了解它的语法特点，比如：关键字的使用！）。。当你把所有的基本语法都了解后。。然后，就是多练习。。。多做例题。。。。这些都做完了你也就基本掌握了。。

http://blog.csdn.net/u012421456/article/details/40681247 如果只是2级考试，看谭浩强的书吧，考试的题里有些真是。。。 视频，入门可以看郝斌的，网上一搜就有

如果只是考级，做真题吧。

理论和实践相结合吧，首先搭建一个环境，编辑器、编译器；找一个好一点的编译器和编辑器会让你的学习事半功倍。

貌似2级没什么用吧，C语言的视频、书籍网络上一大把……


Question: 指针数组的初始化----《C和指针》

少输入了一个＊，字符串作为数据的元素，返回的是地址 #include<stdio.h> // #include<string.h> int main()  { char const *keyword[]  = {          "do",         "for",         "if",         "while" };     return 0; }

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

书没错   根据楼主指示重新看了这一篇幅，发现应该是楼主断章取义了。。。。    这里人家都说了【这个数组可以用于.......】没说是【这个指针数组.....】  作者实际的意思是值后边p165页的这一部分   希望能够解除对大家的误导  PS：@楼上所有大神   当然，怀疑书的精神配得上32个赞

LZ看的是中文还是英文？ 哪个出版社的？ 有无官方网站？ 网站上有无勘误表？

引用 9 楼 u013163178 的回复:你的是不是盗版啊 正版啊～

引用 9 楼 u013163178 的回复:你的是不是盗版啊  确实是书错了，不是盗版。

你的是不是盗版啊

引用 6 楼 mujiok2003 的回复:char const* keyword[] 恩，现在搞清楚了，是书的错误

引用 5 楼 u010059138 的回复:[quote=引用 4 楼 SKY962464 的回复:] [quote=引用 3 楼 u010059138 的回复:] [quote=引用 2 楼 SKY962464 的回复:] [quote=引用 1 楼 u010059138 的回复:] char const keyword[]????   指针数组？？？？？？？  哪里是指针你告诉我 《C和指针》这本书p163页这么写的，我也觉得不太对，应该是书印错了。。。[/quote] 你在仔细看看？ 这么经典的书应该不会犯这么低级的错误的 char *  keyword[]这个才是指针数组[/quote] 的确实这书错了，就是因为经典我才怀疑的，即使我测了一边证实是书错了我还是怀疑，所以我发帖的。。。我觉得应给是书的印刷错误吧[/quote]  书就是用来怀疑- 验证的[/quote] 这话有道理，不能相信别人做好了的结果，要相信你做出来的结果

char const* keyword[]

引用 4 楼 SKY962464 的回复:[quote=引用 3 楼 u010059138 的回复:] [quote=引用 2 楼 SKY962464 的回复:] [quote=引用 1 楼 u010059138 的回复:] char const keyword[]????   指针数组？？？？？？？  哪里是指针你告诉我 《C和指针》这本书p163页这么写的，我也觉得不太对，应该是书印错了。。。[/quote] 你在仔细看看？ 这么经典的书应该不会犯这么低级的错误的 char *  keyword[]这个才是指针数组[/quote] 的确实这书错了，就是因为经典我才怀疑的，即使我测了一边证实是书错了我还是怀疑，所以我发帖的。。。我觉得应给是书的印刷错误吧[/quote]  书就是用来怀疑- 验证的

引用 3 楼 u010059138 的回复:[quote=引用 2 楼 SKY962464 的回复:] [quote=引用 1 楼 u010059138 的回复:] char const keyword[]????   指针数组？？？？？？？  哪里是指针你告诉我 《C和指针》这本书p163页这么写的，我也觉得不太对，应该是书印错了。。。[/quote] 你在仔细看看？ 这么经典的书应该不会犯这么低级的错误的 char *  keyword[]这个才是指针数组[/quote] 的确实这书错了，就是因为经典我才怀疑的，即使我测了一边证实是书错了我还是怀疑，所以我发帖的。。。我觉得应给是书的印刷错误吧

引用 2 楼 SKY962464 的回复:[quote=引用 1 楼 u010059138 的回复:] char const keyword[]????   指针数组？？？？？？？  哪里是指针你告诉我 《C和指针》这本书p163页这么写的，我也觉得不太对，应该是书印错了。。。[/quote] 你在仔细看看？ 这么经典的书应该不会犯这么低级的错误的 char *  keyword[]这个才是指针数组

引用 1 楼 u010059138 的回复:char const keyword[]????   指针数组？？？？？？？  哪里是指针你告诉我 《C和指针》这本书p163页这么写的，我也觉得不太对，应该是书印错了。。。


Question: extern,static存储类型？

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

static说明生存期是全局的，也就是直到程序结束运行变量才消失。而extern说明链接属性，他们唯一联系起来的就是static变量没有extern链接属性。

7楼正解啊！

操作系统是内存大管家，它负责分配内存给程序，当然也负责回收已分配的内存。当程序结束后(退出后)，程序占有的所有内存都被操作系统回收。被操作系统回收，也就是说内存释放了。

楼上都讲比较清楚了，  核心值不愿意改变的用static  extern 用在声明  如头文件中。  然后包含XX.h  就好了

extern,static存储类型的变量初始化后，对于一般程序来说，他们所占用的内存会在程序结束时被释放（对于大多数程序来说，不是关机）。另外，static 生命的全局变量的生命周期是编译单元，比如头文件中初始化了一个static变量，而这个头文件被两个.cpp文件引用，这时这个变量在两个编译单元中被视为两个不同的变量（或者讲是两个不同的内存单元），但不会出现链接错误（如果你在头文件初始化的是一个非静态的全局变量，编译器就会在链接程序时报重定义错误，是链接的时候才报错），而extern 声明的变量与此不同，意思是说这个变量在别的编译模块中定义了，编译时不会报错，链接的时候会在其他编译单元中搜寻这个变量，并进行链接。 简单讲讲效果上不同：static全局变量在两个编译单元中引用时，我们改变一个编译单元中的变量，另一个编译单元中不会变化（即在编译单元中是唯一的）。 而extern全局变量在一个编译单元中被改变时，另一个编译单元中也会改变（即在程序中唯一）。 另外，现代编译器拥有代码优化功能，当两个编译模块中从始至终都没有改变过的static全局变量，会被编译器优化为同一块内存，但是在代码中有改变的话，编译器就会为其分配两个不同的内存。 建议参考一下《编译原理》。 个人观点，仅供参考，希望有用

不对。。。。

存储生存期(static ,automatic 和 allocaed)和  符号的连接属性(linkage: extern/static)是两个不同的概念。  请自己翻一番标准:

引用 5 楼 mujiok2003 的回复:[quote=引用 3 楼 Daffodiles 的回复:] 3.auto存储类型，只可以用在函数体内(块内)。可以省略不写。 对么？ 不对， 全局变量也可以auto[/quote] 错了，请忽略。

引用 3 楼 Daffodiles 的回复:3.auto存储类型，只可以用在函数体内(块内)。可以省略不写。 对么？ 不对， 全局变量也可以auto

程序结束后就会释放了，不会等到关机；

3.auto存储类型，只可以用在函数体内(块内)。可以省略不写。 对么？

1.int a; 变量：a，前面没任何存储类型。它是什么存储类型？ 2.extern存储类型，在块内，块外。 它们的链接有什么不同？

extern 不是 extern的意思是，这个变量或者函数在别的地方定义过了 这里只是声明一下 如果用到了 就到那个定义过它的地方找它 static是 static限制了变量或者函数的范围  让它们变成了文件或者函数范围  而且会一直存在  直到你的程序完全执行结束，也就是main执行结束了  然后就会把static返还给计算机了---------不需要关机，程序结束就被释放了   只要程序结束，任何你程序里存在的东西都会释放


Question: C语言，关于字符串copy的问题，不是大神，一般人看不出来有问题。

引用 10 楼 bear234 的回复:[quote=引用 9 楼 hwx342840456 的回复:] [quote=引用 8 楼 bear234 的回复:] c语言最基本的知识........需要大神才能看出来么？ 字符串存储在什么地方？ 为什么c primer plus说如果用char ×指向一个字符串，强烈建议前面加const？  你自己看不出来罢了.... 我能说谭浩强的书上有这么一段话么？C语言对字符串常量是按字符数组处理的，在内存开辟了一个字符数组用来存放该字符串常量。也就是说,char *a="string"相当于指针a指向一个字符数组的首地址，而两个字符数组里面存的字符是可以交换的。也就是说*a=*b是可以进行操作的。你发给我的全英文，我没有看懂。PS：第一段代码是书上的例子。我时觉得应该没有问题，但是确实报错了。不知道是不是我的环境有问题。你如果有环境，你编译试试？直接看可能还真看不出来。[/quote]  我没有给你发英文啊～～ 早已听说谭浩强的书不怎么样，但也不会犯这种错误吧  我想你估计是看到它在介绍数组如何处理字符串的内容了吧 不过这段话的确很垃圾...... 如果实在觉得不好，就换成c primer plus去看  总之呢，如果你直接用指针指向一个引号引起来的字符串，那么是不能通过指针去改变这个字符串的，因为这个时候字符串是常量   有一些老的编译器的确可以通过你贴出来的这段代码～～但是这是严重的错误，如果你的编译器也能通过，那么你可以这样编译一下看看： char *a = "abc"; a[1] ='z'; //试图把a指向的字符串从abc变成azc  如果你的编译器能通过你贴出来的代码，那么这里也可以通过 printf("abc");//如果上面两句都通过了，那么这里就会显示出“azc”  这里可以看到，我们以为第三句会显示出abc，但是它却显示的是azc   这是因为，在编译器眼里，任何引号形式的字符串都是一个地址信息，a指向“abc”的地址，你通过a把第二个字符改了，而当编译器再碰到“abc”时，它还是会找这个字符串原来的地址----这个地址从来就没变过，所以就会显示出此时这个地址存放的字符串，即“azc” 这也就是为什么现在编译器都禁止你贴出来的代码，也就是为什么在写char *a = "abc"的时候，会强烈建议前面加上const[/quote]  果然，学习了。当字符串为常量时，确实不能通过指针来改变它。谢谢咯。

指针指向的地方你要能写。

引用 9 楼 hwx342840456 的回复:[quote=引用 8 楼 bear234 的回复:] c语言最基本的知识........需要大神才能看出来么？ 字符串存储在什么地方？ 为什么c primer plus说如果用char ×指向一个字符串，强烈建议前面加const？  你自己看不出来罢了.... 我能说谭浩强的书上有这么一段话么？C语言对字符串常量是按字符数组处理的，在内存开辟了一个字符数组用来存放该字符串常量。也就是说,char *a="string"相当于指针a指向一个字符数组的首地址，而两个字符数组里面存的字符是可以交换的。也就是说*a=*b是可以进行操作的。你发给我的全英文，我没有看懂。PS：第一段代码是书上的例子。我时觉得应该没有问题，但是确实报错了。不知道是不是我的环境有问题。你如果有环境，你编译试试？直接看可能还真看不出来。[/quote] 谭浩强写那本书的时代，是DOS时代，DOS是实模式，问题暴露不出来

引用 9 楼 hwx342840456 的回复:[quote=引用 8 楼 bear234 的回复:] c语言最基本的知识........需要大神才能看出来么？ 字符串存储在什么地方？ 为什么c primer plus说如果用char ×指向一个字符串，强烈建议前面加const？  你自己看不出来罢了.... 我能说谭浩强的书上有这么一段话么？C语言对字符串常量是按字符数组处理的，在内存开辟了一个字符数组用来存放该字符串常量。也就是说,char *a="string"相当于指针a指向一个字符数组的首地址，而两个字符数组里面存的字符是可以交换的。也就是说*a=*b是可以进行操作的。你发给我的全英文，我没有看懂。PS：第一段代码是书上的例子。我时觉得应该没有问题，但是确实报错了。不知道是不是我的环境有问题。你如果有环境，你编译试试？直接看可能还真看不出来。[/quote]  我记得我三年前学c语言的时候，看的是c primer plus，上面在讲这部分的时候，就举出了我上面给你写的那三行代码的例子，我当时用的一个很垃圾的编译器，可以编译通过这三行代码，估计这个编译器也能通过你贴出来的代码........现在我用的是vs，你的代码报错了.......  换书吧哥们儿.....谭浩强的书最大的意义就是能让完全不懂计算机的人短时间内考过二级......想好好学就看c primer plus

引用 9 楼 hwx342840456 的回复:[quote=引用 8 楼 bear234 的回复:] c语言最基本的知识........需要大神才能看出来么？ 字符串存储在什么地方？ 为什么c primer plus说如果用char ×指向一个字符串，强烈建议前面加const？  你自己看不出来罢了.... 我能说谭浩强的书上有这么一段话么？C语言对字符串常量是按字符数组处理的，在内存开辟了一个字符数组用来存放该字符串常量。也就是说,char *a="string"相当于指针a指向一个字符数组的首地址，而两个字符数组里面存的字符是可以交换的。也就是说*a=*b是可以进行操作的。你发给我的全英文，我没有看懂。PS：第一段代码是书上的例子。我时觉得应该没有问题，但是确实报错了。不知道是不是我的环境有问题。你如果有环境，你编译试试？直接看可能还真看不出来。[/quote]  我没有给你发英文啊～～ 早已听说谭浩强的书不怎么样，但也不会犯这种错误吧  我想你估计是看到它在介绍数组如何处理字符串的内容了吧 不过这段话的确很垃圾...... 如果实在觉得不好，就换成c primer plus去看  总之呢，如果你直接用指针指向一个引号引起来的字符串，那么是不能通过指针去改变这个字符串的，因为这个时候字符串是常量   有一些老的编译器的确可以通过你贴出来的这段代码～～但是这是严重的错误，如果你的编译器也能通过，那么你可以这样编译一下看看： char *a = "abc"; a[1] ='z'; //试图把a指向的字符串从abc变成azc  如果你的编译器能通过你贴出来的代码，那么这里也可以通过 printf("abc");//如果上面两句都通过了，那么这里就会显示出“azc”  这里可以看到，我们以为第三句会显示出abc，但是它却显示的是azc   这是因为，在编译器眼里，任何引号形式的字符串都是一个地址信息，a指向“abc”的地址，你通过a把第二个字符改了，而当编译器再碰到“abc”时，它还是会找这个字符串原来的地址----这个地址从来就没变过，所以就会显示出此时这个地址存放的字符串，即“azc” 这也就是为什么现在编译器都禁止你贴出来的代码，也就是为什么在写char *a = "abc"的时候，会强烈建议前面加上const

引用 8 楼 bear234 的回复:c语言最基本的知识........需要大神才能看出来么？ 字符串存储在什么地方？ 为什么c primer plus说如果用char ×指向一个字符串，强烈建议前面加const？  你自己看不出来罢了.... 我能说谭浩强的书上有这么一段话么？C语言对字符串常量是按字符数组处理的，在内存开辟了一个字符数组用来存放该字符串常量。也就是说,char *a="string"相当于指针a指向一个字符数组的首地址，而两个字符数组里面存的字符是可以交换的。也就是说*a=*b是可以进行操作的。你发给我的全英文，我没有看懂。PS：第一段代码是书上的例子。我时觉得应该没有问题，但是确实报错了。不知道是不是我的环境有问题。你如果有环境，你编译试试？直接看可能还真看不出来。

http://stackoverflow.com/questions/12121759/difference-between-char-str-and-char-strn  自己看吧  第一种情况是在常量区 是不允许修改的 只读

多看看字符串常量、字符数组方面的介绍……

引用 4 楼 user-6 的回复:1：我指的常量是"string";这个字符串，这个字符串存储在常量区。 :2：char a[]="string";这里的a不是常量。 3：const char *a="string" 和char *const  a="string";的区别我估计你分别不出来。  1、我不明白； 2、char a[]=string 这里的a绝对是个常量，因为你开辟的是数组，一旦开辟数组，数组的首地址就是确定的，无法修改的； 3、const char *a应该是只a是个固定的char的指针类型，char *const a，应该是指a是固定的指针，不能修改。不知道这样理解对不对。

引用 2 楼 user-6 的回复:不是大神也看出来了。 char *a="string";指针a指向字符串常量。个人觉得等价于const char *a="string";  我觉得不是你这么看的，char a[]="string";a才是常量。 char *a，a是指针变量，不是常量。不是大神，看不出来。哈哈

老规矩，沙发自己占。我顶。


Question: 用链表实现元素整体互换，出现内存不能为read

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

或者加上你的append函数 #include<stdio.h> #include<stdlib.h> #define  OK   1 typedef int ElemType; #define LENGTHOFLIST 10  typedef struct LNode{ 	ElemType data; 	struct LNode *next; }LNode,*LinkList;  int InitLink(LinkList &L) { 	L=(LinkList)malloc(sizeof(LNode)); 	L->next=NULL; 	return OK; } //该函数没有问题 int ListLength(LinkList L) { 	struct LNode *p; 	int i=0; 	p=L->next; 	while(p) 	{ 		p=p->next; 		i++; 	} 	return i; }  int Append(LinkList &L,LinkList &p) { 	LNode *position = L; 	while(position->next!=NULL) 		position = position->next; 	position->next=p; 	return OK; }   void ZTHH(LinkList &L,int m,int n) { 	struct LNode *pa,*pb;  	LNode *List1,*List2,*List3;		//用来截取链表的头指针变量 	LNode *position;				//一个表示当前读取位置的临时变量 	 	int i=0; 	int j=ListLength(L); 	pa=L;  	while(i<m) 	{ 		pa=pa->next; 		i++; 	} 	position = pa;				//保存第一次截断的位置 	pb = pa->next;				//这个语句意思和你之前的一样 	List1=L->next;				//链表1从头开始到position的位置 	List2=position->next;		//链表2从position的下一个位置开始 	position->next = NULL;		//截断第一个链表  	i = 0; 	while(i<j-m-n-1)				//pb此时指向的是中间的位置,就是你要保留下来的部分起始位置		 	{								//因为此时pb不是头节点,而且我们是要找到最后一个保留的位置,因此应该-1 		pb=pb->next;			 		i++; 	} 	position = pb;				//保存第二次阶段的位置 	List3=position->next;		//链表3开始了,一直到最后(此处不用截断,因为L的最后一个元素指向NULL) 	position->next = NULL;		//截断第二个链表 	L->next = NULL;				//此时L已经截断,将他的下一个元素指向NULL 	 	Append(L,List3); 	Append(L,List2); 	Append(L,List1); }  int main() { 	int m,n,i; 	struct LNode *a,*p; 	LinkList L;    //头节点 	InitLink(L);   	//插入法建立链表 	for(i=0;i<LENGTHOFLIST;i++) 	{ 		p=(LinkList)malloc(sizeof(LNode)); 		p->data=i; 		p->next = L->next; 		L->next = p; 	}  	//查看是否建表成功 	a=L->next; 	while(a) 	{ 		printf("%d ",a->data); 		a=a->next; 	} 	//分两次输入,而且你的scanf还用错了 	printf("\ninput m,n\n"); 	scanf("%d",&m); 	scanf("%d",&n); 	printf("input END,NOW Let's see the result:	\n"); 	//增加判断m、n是否超过0-LENGTHOFLIST的语句,同时需要判断m+n是否超过了LENGTHOFLIST 	if(m<0 || m>LENGTHOFLIST || n<0|| n>LENGTHOFLIST || m+n > LENGTHOFLIST)  	{ 		printf("input error！"); 		return -1; 	} 	ZTHH(L,m,n); 	a=L->next; 	while(a) 	{ 		printf("%d ",a->data); 		a=a->next; 	} 	free(a); 	return OK; }  结果是一样的. 你的主要问题是链表和指针的问题.不过你还不错,就是不够细心,加油吧!

在尽量不更改你代码的情况下,帮你改正了一下 #include<stdio.h> #include<stdlib.h> #define  OK   1 typedef int ElemType; #define LENGTHOFLIST 10  typedef struct LNode{ 	ElemType data; 	struct LNode *next; }LNode,*LinkList;  int InitLink(LinkList &L) { 	L=(LinkList)malloc(sizeof(LNode)); 	L->next=NULL; 	return OK; } //该函数没有问题 int ListLength(LinkList L) { 	struct LNode *p; 	int i=0; 	p=L->next; 	while(p) 	{ 		p=p->next; 		i++; 	} 	//free(p)? 	return i; } /* int Append(LinkList &L,LNode *p){ struct LNode *n; n=(LinkList)malloc(sizeof(LNode)); n=L->next; while(p){ n->data=p->data; n=n->next; n=(LinkList)malloc(sizeof(LNode)); p=p->next;} return OK; } */  void ZTHH(LinkList &L,int m,int n) { 	struct LNode *pa,*pb/*,*pc,*p*/;  	LNode *List1,*List2,*List3;		//用来截取链表的头指针变量 	LNode *position;				//一个表示当前读取位置的临时变量 	 	int i=0; 	int j=ListLength(L); 	//LinkList La; 	//截断第一部分   	pa=L/*->next*/;  	/*if(i<m)*/					//应该用for/while/do-while而不是if 	while(i<m) 	{ 		pa=pa->next; 		i++; 	} 	position = pa;				//保存第一次截断的位置 	pb = pa->next;				//这个语句意思和你之前的一样 	List1=L->next;				//链表1从头开始到position的位置 	List2=position->next;		//链表2从position的下一个位置开始 	position->next = NULL;		//截断第一个链表  	//截断第二部分   	//if(i<j-n)					//同理应该使用循环语句,而且你的i<j-n太复杂了,不就是将中间不需要变化的保存下来吗?直接点. 	i = 0; 	while(i<j-m-n-1)				//pb此时指向的是中间的位置,就是你要保留下来的部分起始位置		 	{								//因为此时pb不是头节点,而且我们是要找到最后一个保留的位置,因此应该-1 		pb=pb->next;			 		i++; 	} 	position = pb;				//保存第二次阶段的位置 	List3=position->next;		//链表3开始了,一直到最后(此处不用截断,因为L的最后一个元素指向NULL) 	position->next = NULL;		//截断第二个链表 	L->next = NULL;				//此时L已经截断,将他的下一个元素指向NULL   	//----逻辑错误，你的整条链都是连着的，pa后面是pb然后是pc，所以经过这个操作L=pa(也就是 L)+pb（pb后面还有pc挂在上面）+pc---- 	//	----你可以先把L分成三分，就不会有问题了----------------  	//	InitLink(La); 	//Append(La,pc); 	//Append(La,pb); 	//Append(La,pa); 	//L=La; 	//free(La); 	 	//合并链表 	L->next = List3; 	position = L->next;  	//找出第List3的最后一个元素,也就是此时L的最后一个元素 	while(position->next!=NULL) 		position = position->next; 	position->next = List2;				//将list2接到L上  	//找出第List2的最后一个元素,也就是此时L的最后一个元素 	while(position->next!=NULL) 		position = position->next; 	position->next = List1;				//list1链接到L上 	//因为list2的最后一个元素为NULL,因此不用再制定NULL 	//L=La; 	//free(La); }  int main() { 	int m,n,i; 	struct LNode *a,*p; 	LinkList L;    //头节点 	InitLink(L); 	//--------------这里开始就错了--------------- 	//	p=L->next; 	//  for(i=0;i<100;i++){ 	//	p=(LinkList)malloc(sizeof(LNode)); 	//	p->data=i; 	//	p=p->next; 	//---------------------------------------------  	//插入法建立链表 	for(i=0;i<LENGTHOFLIST;i++) 	{ 		p=(LinkList)malloc(sizeof(LNode)); 		p->data=i; 		p->next = L->next; 		L->next = p; 	}  	//查看是否建表成功 	a=L->next; 	while(a) 	{ 		printf("%d ",a->data); 		a=a->next; 	} 	//分两次输入,而且你的scanf还用错了 	printf("\ninput m,n\n"); 	scanf("%d",&m); 	scanf("%d",&n); 	printf("input END,NOW Let's see the result:	\n"); 	//增加判断m、n是否超过0-LENGTHOFLIST的语句,同时需要判断m+n是否超过了LENGTHOFLIST 	if(m<0 || m>LENGTHOFLIST || n<0|| n>LENGTHOFLIST || m+n > LENGTHOFLIST)  	{ 		printf("input error！"); 		return -1; 	} 	ZTHH(L,m,n); 	a=L->next; 	while(a) 	{ 		printf("%d ",a->data); 		a=a->next; 	} 	free(a); 	return OK; }  以10个数字作为参考的结果如下:

可操作链表？定义两指针，一个定头一个可遍历增加删除。没看懂你写的意思。

--------------这里开始就错了--------------- 	p=L->next; 	for(i=0;i<100;i++){ 	p=(LinkList)malloc(sizeof(LNode)); 	p->data=i; 	p=p->next; --------------------------------------------- ----逻辑错误，你的整条链都是连着的，pa后面是pb然后是pc，所以经过这个操作L=pa(也就是 L)+pb（pb后面还有pc挂在上面）+pc---- 	InitLink(La); 	Append(La,pc); 	Append(La,pb); 	Append(La,pa); 	L=La; 	free(La);

就是前m个元素和后n个元素整体换位置

首先format一下你输入的代码，这样好看清楚，然后你所的元素整体互换是什么意思？


Question: 关于二维指针的问题

到21行，每一个Tmp.pTest[i]都指向了一个stTest1。 但你的stTest1中只有指针，所以还是需要分配内存才能使用，例如strcpy之类。 逻辑上，你这里其实有三层指针。

#include<iostream>  using namespace std;  struct stTest1 {     char *szUserid;     char *szUserName; };  struct stTest2 {    struct stTest1 **pTest; };  int main() {    struct stTest2 stTmp;    stTmp.pTest = (struct stTest1**)malloc(100*sizeof(struct stTest1*));    for(int i=0;i<100;++i){        stTmp.pTest[i] = (struct stTest1*)malloc(sizeof(struct stTest1));        stTmp.pTest[i]->szUserid = NULL;//此处仍需分配内存才能使用     }    return 0; }

我编译你的，VS报： 运行时内存操作错误 操作了不属于自己的内存 你看我写的你满意不？  struct stTest1 { 	char *szUserid; 	char *szUserName; };  struct stTest2 { 	struct stTest1 **pTest; };  int main() { 	struct stTest2 stTmp; 	stTest1* ptest1 = (struct stTest1*)malloc(sizeof(stTest1)); 	ptest1->szUserid = (char *)malloc(50*sizeof(char)); 	ptest1->szUserName = (char *)malloc(50*sizeof(char)); 	stTmp.pTest = &ptest1; 	strcpy(((stTest1*)(*stTmp.pTest))->szUserid,"001"); 	strcpy(((stTest1*)(*stTmp.pTest))->szUserName,"xxoo"); 	printf("%s\n",ptest1->szUserid); 	printf("%s",ptest1->szUserName); 	system("pause"); 	return 1;  }


Question: 可以输入，，无法输出   求大神帮忙看一下

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

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

单步调试一下。

谢谢，，有好多东西要静下来仔细看呢


Question: 用VS2010运行C语言程序，运行结果闪一下就没了

在工具栏上添加“开始执行（不调试）的按钮，如图片中所示，这样就不会一闪而过~~~（

加个getchar();就OK了。

最好在cmd窗口中输入以下命令： cd /d “exe程序所在盘符和目录” “exe程序”

加一句system("pause"); 或者while(1);

引用 14 楼 delandi 的回复:[quote=引用 6 楼 mujiok2003 的回复:] 多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？ 不好意思哈，我是新手[/quote] 不是说你，说的是那些回帖的人。

引用 6 楼 mujiok2003 的回复:多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？  不好意思哈，我是新手

引用 12 楼 zhouxiaofeng1021 的回复:加 #include<stdlib.h> system("pause"); 或者 getchar(); getchar();  你说的第一种方法可以，运行完出来按任意键继续，要的就是这种效果哈，谢谢你 我用VS2010的win32控制台应用程序

引用 10 楼 binaryhead 的回复:[quote=引用 9 楼 mujiok2003 的回复:] [quote=引用 8 楼 binaryhead 的回复:] [quote=引用 6 楼 mujiok2003 的回复:] 多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？ 你设想一下楼主使用情形，极有可能使直接运行可执行程序，此时调试器还真帮不上忙呢。[/quote] 直接运行也可托到一个控制台中，修改代码实在是下下之策[/quote] ，十分同意。增加的代码与应用的逻辑毫无关系，所给楼主讲明一闪而过的原因，指导他学会使用cmd.exe是根本方法。[/quote] en.

引用 9 楼 mujiok2003 的回复:[quote=引用 8 楼 binaryhead 的回复:] [quote=引用 6 楼 mujiok2003 的回复:] 多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？ 你设想一下楼主使用情形，极有可能使直接运行可执行程序，此时调试器还真帮不上忙呢。[/quote] 直接运行也可托到一个控制台中，修改代码实在是下下之策[/quote] ，十分同意。增加的代码与应用的逻辑毫无关系，所给楼主讲明一闪而过的原因，指导他学会使用cmd.exe是根本方法。

引用 8 楼 binaryhead 的回复:[quote=引用 6 楼 mujiok2003 的回复:] 多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？ 你设想一下楼主使用情形，极有可能使直接运行可执行程序，此时调试器还真帮不上忙呢。[/quote] 直接运行也可托到一个控制台中，修改代码实在是下下之策

引用 6 楼 mujiok2003 的回复:多少年了， 还有那么多人加getchar(), system("pause")， 难道真当调试器是摆设？ 你设想一下楼主使用情形，极有可能使直接运行可执行程序，此时调试器还真帮不上忙呢。

在输出语句后面加个断点或者CTRL + F5 直接运行

引用 4 楼 user-9 的回复:[quote=引用 2 楼 delandi 的回复:] [quote=引用 1 楼 user-9 的回复:] 在return  之前  加上一句    system("pause");   error C3861: “system”: 找不到标识符[/quote] 我一直使用都没有添加头文件的啊  你试试 添加上头文件 #include<system.h>  如果不行试试 getchar();  前提是  你说的是DOS窗口[/quote] 不要说DOS窗口好不好，控制台窗口如何？

引用 2 楼 delandi 的回复:[quote=引用 1 楼 user-9 的回复:] 在return  之前  加上一句    system("pause");   error C3861: “system”: 找不到标识符[/quote] 我一直使用都没有添加头文件的啊  你试试 添加上头文件 #include<system.h>  如果不行试试 getchar();  前提是  你说的是DOS窗口

引用 2 楼 delandi 的回复:[quote=引用 1 楼 user-9 的回复:] 在return  之前  加上一句    system("pause");   error C3861: “system”: 找不到标识符[/quote] 太乐了， 要不你试试在return  之前  加上一句  getchar();

引用 1 楼 user-9 的回复:在return  之前  加上一句    system("pause");   error C3861: “system”: 找不到标识符

在return  之前  加上一句    system("pause");


Question: 指针 数组 数据转换问题

引用 1 楼 zhao4zhong1 的回复:unsigned char sz[5][20],*p; p=(unsigned char *)pMyStruct; for (i=0;i<5;i++) {  memcpy((void *)&sz[i][0],(void *)((unsigned char *)p+i*20),20); }  谢谢


Question: C语言如何将字符串写入二进制文件中？这个文件存储的应该是二进制数据，用记事本打开是乱码

二进制读写和文本读写是两个概念。  字符数据本身在内存中就经过了编码，所以无论是二进制还是文本形式都是一样的，而对于非字符数据来说，例如inti=10；如果用二进制来进行存储的话为1010，但是如果需要用文本形式来进行存储的话就必须进行格式化编码（对1和0分别编码，即形式为‘1’和‘0’分别对应的码值）

引用 27 楼 ForestDB 的回复:你老师所说的0x0990 到底是0x0990？还是"0x0990"？ 还请先弄清楚。字符串“0X0990”

引用 18 楼 wsckxs 的回复:[quote=引用 17 楼 luciferisnotsatan 的回复:] ‘0' 这个字符的ACSII码值是 0x30。  unsigned short 的值为0x30时，它代表数值为0么？额，应该不是吧。。什么意思啊不懂。。[/quote]  char a = '0'; // 相当于 char a = 0x30 unsigned short b = a;   ------------------------------------------------ unsigned short b = 0;  一个是给b 赋值 48， 一个是赋值 0.  这个和big endian没什么关系，你在同一台机器上运行的，没这个问题。

引用 25 楼 ForestDB 的回复:不过看LZ的标题，似乎应该是 char * i = "0x0990"; 如果是这样的化，就该 int ii = atoi(i); 然后再 fwrtie(&ii, sizeof(int), 1 file);什么意思？运行一下结果没道理啊

引用 16 楼 wsckxs 的回复:[quote=引用 13 楼 luciferisnotsatan 的回复:] [quote=引用 10 楼 wsckxs 的回复:] [quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？其实我也是这么写的，老师说结果不对[/quote] 你是不是直接把 ini 里的内容读出来然后直接写到 dat 里？  感觉你老师说的是： 从 ini 里读到字符串 “0x0990”， 然后转成 unsigned short（两字节）值，再存到 dat 里 [/quote]我确实是直接写到dat里了，为什么要转换为unsigned short？[/quote]老师之前提到过要big endian，我不知道什么意思，是不是跟这个有关啊

引用 17 楼 luciferisnotsatan 的回复:‘0' 这个字符的ACSII码值是 0x30。  unsigned short 的值为0x30时，它代表数值为0么？额，应该不是吧。。什么意思啊不懂。。

引用 13 楼 luciferisnotsatan 的回复:[quote=引用 10 楼 wsckxs 的回复:] [quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？其实我也是这么写的，老师说结果不对[/quote] 你是不是直接把 ini 里的内容读出来然后直接写到 dat 里？  感觉你老师说的是： 从 ini 里读到字符串 “0x0990”， 然后转成 unsigned short（两字节）值，再存到 dat 里 [/quote]我确实是直接写到dat里了，为什么要转换为unsigned short？

引用 8 楼 ForestDB 的回复:int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？00000000 00000001是这样吧

引用 13 楼 luciferisnotsatan 的回复:[quote=引用 10 楼 wsckxs 的回复:] [quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？其实我也是这么写的，老师说结果不对[/quote] 你是不是直接把 ini 里的内容读出来然后直接写到 dat 里？  感觉你老师说的是： 从 ini 里读到字符串 “0x0990”， 然后转成 unsigned short（两字节）值，再存到 dat 里 [/quote]为什么？？？

引用 23 楼 ForestDB 的回复:int i = 0x0990; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);这样是不对的，我这么写老师说不对。。 我想是不是应该将0990这样的十六进制数据写入，像这样： sscanf( data, "%x", &j );//data[]字符数组存储数据0990，j是unsigned short格式 fwrite(&j,sizeof(unsigned short),1,fp2);

引用 10 楼 wsckxs 的回复:[quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？其实我也是这么写的，老师说结果不对[/quote] 你是不是直接把 ini 里的内容读出来然后直接写到 dat 里？  感觉你老师说的是： 从 ini 里读到字符串 “0x0990”， 然后转成 unsigned short（两字节）值，再存到 dat 里

字符串只是二进制的一个表现形式

引用 9 楼 wsckxs 的回复:[quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？REG_BURST= 0x0990, 0x000C, 0x0000, 0x002B, 0x0000, 0x0006, 0x0000, 0x035A, 0x02D0这样的数据[/quote] LZ想多了，我就是问我的代码执行后test.dat中应该有什么。

引用 21 楼 ForestDB 的回复:[quote=引用 15 楼 wsckxs 的回复:] [quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？00000000 00000001是这样吧[/quote] 差不多，但是不太准确 0x00 0x00 0x00 0x01 如果你认为我说的和你说的是一回事，同时也知道大小端的问题，那么可以认为你理解了二进制文件 那么就是你没有理解老师的需求 [/quote]老师就是让把类似0x0990这样的数据以二进制形式写入文件，你觉得应该怎么做？

引用 15 楼 wsckxs 的回复:[quote=引用 8 楼 ForestDB 的回复:] int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？00000000 00000001是这样吧[/quote] 差不多，但是不太准确 0x00 0x00 0x00 0x01 如果你认为我说的和你说的是一回事，同时也知道大小端的问题，那么可以认为你理解了二进制文件 那么就是你没有理解老师的需求

引用 8 楼 ForestDB 的回复:int i = 1; FILE * file = fopen("test.dat", "wb"); fwrite(&i, sizeof(int), 1, file); fclose(file);  test.dat中应该有什么？其实我也是这么写的，老师说结果不对


Question: 求C语言大神，时间紧迫

已收藏^_^

大神啊，写的很好呢，但是因为第二题是个H难度的题目，可不可以在实行的时候有文字步骤呢。还有哪些地方有易错点？求大神救救渣渣

仅供参考//输入一个小于200的字符串，将该字符串以“_”分割成小于20的字串。请输出原串和子串。 //请注意以下测试用例： //·输入空串 //·输入长度为9的字符串 //·输入长度为19的字符串 //·输入长度为20的字符串 //·输入长度为38的字符串 //·输入长度为205的字符串 //·理论上还应该考虑输入串中包含_如何处理的逻辑（这个在我的代码中没有体现） #include <stdio.h> #include <string.h> char s[201]; char d[11][21]; int i,L,n; void main() {     fgets(s,201,stdin);     L=strlen(s);     if ('\n'==s[L-1]) {s[L-1]=0;L--;}     for (i=0;i<L;i++) {         d[i/19][i%19]=s[i];         if (i!=L-1 && 18==(i%19)) {             d[i/19][19]='_';             d[i/19][20]=0;         }     }     d[i/19][i%19]=0;     if (i>0 && 0==(i%19)) {         n=i/19;     } else {         n=i/19+1;     }     printf("s=\"%s\"\n",s);     for (i=0;i<n;i++) {         printf("d[%2d]=\"%s\"\n",i,d[i]);     } }

应该不是吧，我们老师现在哪有时间上网，你会吗，关键是第二题。

引用 3 楼 mengjiegao_ 的回复:你怎么知道是作业，不会写啊 没准人家就是你的老师。

你怎么知道是作业，不会写啊

作业自己做吧

参考 http://blog.csdn.net/gaowen1860/article/details/4725794


Question: 一个关于字符连续输出的问题

1. if(i < 1); 这里多了个分号 2. i++要往后移两行或三行


Question: 多线程创建问题

在看6L和你9L的说法，主要还是你的bench有问题。

其实是应该都有问题，只是刚好数组形式的没有发作而已，看bt，感觉你的入口函数中是不是调用了非线程安全的东西？

coredump的bt栈信息  (gdb) bt #0  __tsearch (key=key@entry=0x7f3205f416f8,      vrootp=vrootp@entry=0x7f3211f5a728,      compar=compar@entry=0x7f329e9c04a0 <known_compare>) at tsearch.c:251 #1  0x00007f329e9c10af in __GI___nss_lookup_function (ni=0x7f3211f5a700,      fct_name=fct_name@entry=0x7f329ea234e8 "gethostbyname_r")     at nsswitch.c:468 #2  0x00007f329e9c15fe in __GI___nss_next2 (ni=ni@entry=0x7f3205f417c0,      fct_name=fct_name@entry=0x7f329ea234e8 "gethostbyname_r",      fct2_name=fct2_name@entry=0x0, fctp=fctp@entry=0x7f3205f417d0,      status=<optimized out>, all_values=all_values@entry=0)     at nsswitch.c:282 #3  0x00007f329e9b1799 in __gethostbyname_r (     name=name@entry=0x603440 <hostname> "www.baidu.com",      resbuf=resbuf@entry=0x7f329ec668a0 <resbuf>,      buffer=0x24f3030 "\377\002", buflen=1024,      result=result@entry=0x7f3205f41850,      h_errnop=h_errnop@entry=0x7f3205f41840) at ../nss/getXXbyYY_r.c:281 #4  0x00007f329e9b0ef6 in gethostbyname ( ---Type <return> to continue, or q <return> to quit---     name=0x603440 <hostname> "www.baidu.com") at ../nss/getXXbyYY.c:116 #5  0x000000000040111e in Socket () #6  0x0000000000401a89 in bench () #7  0x00007f329ec71182 in start_thread (arg=0x7f3205f42700)     at pthread_create.c:312 #8  0x00007f329e99e30d in clone ()     at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

mallco的返回值肯定OK,因为线程以及开始创建了，只是创建了部分线程后出现段错误,

soga！！！！

我猜你没判断malloc函数的返回值。

我的arg是只读的，不需要加锁了把，我也没有free(p) ,我也写过用简单的bench函数代替，想重现问题所在，但是使用简单的bench函数代替就没问题了，但是我搞不懂为什么使用数组的pthread_t就OK了

仅供参考//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

还要确保各线程访问arg时加了锁。

是不是bench函数的问题呀，写个简单的函数代替bench试试

pthread_t *p;         p = (pthread_t*)malloc(clients*sizeof(pthread_t));         assert(p);         //请确保本进程退出前不要free(p) pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);         for(i = 0;i < clients;i++)         {                 if(pthread_create(&p[i],NULL,bench,(void *)&arg))                         perror("client %d create failue:",i); //              usleep(50);         }

基本肯定是函数里面越界了把数据破坏了

pthread_t p[PTHREAD_MAX];   //这种方式没问题，使用下面的这种指针分配空间就有问题 //      pthread_t *p; //      p = (pthread_t*)malloc(clients*sizeof(pthread_t)); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);         for(i = 0;i < clients;i++)         {                 if(pthread_create(&p[i],NULL,bench,(void *)&arg))                         perror("client create failue:");                 usleep(50);         }  bench这个函数代码比较多，这里就不贴出来了

相关代码请贴全。

都有coredump了，上debugger看看调用栈什么的吧。

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


Question: 有返回值的main函数

引用 25 楼 layershow 的回复:if (no break && no exit && no goto && ...) {     while = 死循环; }  if (while == 死循环) {     执行不到 return; }   ，那是误会了。只是C语言中，exit刚好是一个标准的系统函数，我看到它（而且还是全小写），我自然就联想到一个函数了，不过你21楼明确用了“调用”两个字，希望我没有再次误解你！

引用 19 楼 binaryhead 的回复:[quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote] 我懂你在说什么，你懂我在说什么呢？

引用 22 楼 bbs2241 的回复:[quote=引用 21 楼 binaryhead 的回复:] [quote=引用 20 楼 bbs2241 的回复:] [quote=引用 19 楼 binaryhead 的回复:] [quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote]  return后也是调用exit。[/quote] 不要这么肯定好不好？首先，即使return后调用exit也并不支持你前面的while 中调用exit后会执行return的叙述。其次，return之后是否调用exit绝对是一个特定C编译器的具体实现问题，甚至与使用编译器的选项相关（参见我的博文：http://blog.csdn.net/binaryhead/article/details/18088785），请不要把它作为一个确定的规律好不好？在我的那个博文中你能确定main最后的return之后会调用exit？[/quote]  你想说明什么问题吗？ 还有你前面的回答又想说明什么问题呢?[/quote] 瞧你这质问的口气，很冲啊。 我想说明： 1、19楼纠正你18楼叙述中我认为不妥当的地方。 你20楼试图补充你18楼中我认为不妥的地方，或者可能是想纠正我19楼的叙述。 2、我21楼纠正你20楼的补充叙述。 除此之外，我不想说明任何问题。

引用 21 楼 binaryhead 的回复:[quote=引用 20 楼 bbs2241 的回复:] [quote=引用 19 楼 binaryhead 的回复:] [quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote]  return后也是调用exit。[/quote] 不要这么肯定好不好？首先，即使return后调用exit也并不支持你前面的while 中调用exit后会执行return的叙述。其次，return之后是否调用exit绝对是一个特定C编译器的具体实现问题，甚至与使用编译器的选项相关（参见我的博文：http://blog.csdn.net/binaryhead/article/details/18088785），请不要把它作为一个确定的规律好不好？在我的那个博文中你能确定main最后的return之后会调用exit？[/quote]  你想说明什么问题吗？ 还有你前面的回答又想说明什么问题呢?

引用 20 楼 bbs2241 的回复:[quote=引用 19 楼 binaryhead 的回复:] [quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote]  return后也是调用exit。[/quote] 不要这么肯定好不好？首先，即使return后调用exit也并不支持你前面的while 中调用exit后会执行return的叙述。其次，return之后是否调用exit绝对是一个特定C编译器的具体实现问题，甚至与使用编译器的选项相关（参见我的博文：http://blog.csdn.net/binaryhead/article/details/18088785），请不要把它作为一个确定的规律好不好？在我的那个博文中你能确定main最后的return之后会调用exit？

引用 23 楼 binaryhead 的回复:[quote=引用 22 楼 bbs2241 的回复:] [quote=引用 21 楼 binaryhead 的回复:] [quote=引用 20 楼 bbs2241 的回复:] [quote=引用 19 楼 binaryhead 的回复:] [quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote]  return后也是调用exit。[/quote] 不要这么肯定好不好？首先，即使return后调用exit也并不支持你前面的while 中调用exit后会执行return的叙述。其次，return之后是否调用exit绝对是一个特定C编译器的具体实现问题，甚至与使用编译器的选项相关（参见我的博文：http://blog.csdn.net/binaryhead/article/details/18088785），请不要把它作为一个确定的规律好不好？在我的那个博文中你能确定main最后的return之后会调用exit？[/quote]  你想说明什么问题吗？ 还有你前面的回答又想说明什么问题呢?[/quote] 瞧你这质问的口气，很冲啊。 我想说明： 1、19楼纠正你18楼叙述中我认为不妥当的地方。 你20楼试图补充你18楼中我认为不妥的地方，或者可能是想纠正我19楼的叙述。 2、我21楼纠正你20楼的补充叙述。 除此之外，我不想说明任何问题。[/quote]  额额，也不知谁如此激动。  你看出我19楼认为你评论不当？再仔细品味一下，如果还这么认为，那是我语文没学好，是我描述不当。  ps：我也不知道你给了个博客想说明什么，你想说我说的不正确，你完全可以找出反例，对不对？ansi c或者iso c？不要动不动就说别人说话冲，我完全是以询问的口气说话在问。

引用 9 楼 mymtom 的回复:[quote=引用 8 楼 nice_cxf 的回复:] 7楼乱误导，现在基本都不会有人写void main()，都是int main()，实际就算是int main()，也可以不用写return，但是这样写程序不是好习惯   是的呀，C89 里就说好了main的返回值是int的，国内某些教材祸害了几代C程序员啊  2.1.2.2 Hosted environment     A hosted environment need not be provided, but shall conform to the following specifications if present.  "Program startup"     The function called at program startup is named main .  The implementation declares no prototype for this function.  It can be defined with no parameters:           int main(void) { /*...*/ }  or with two parameters (referred to here as argc and argv , though any names may be used, as they are local to the function in which they are declared):           int main(int argc, char *argv[]) { /*...*/ }  [/quote] 版主大人“祸害几代人”的说法严重了，前面10楼的网友的看法我认为也有些偏颇。         1、从一个通用的C编译器来说，对一个特定函数名称函数的原型加以限制，实现并不难（虽然这种限制是遵照规范要求而不是编译器厂商的扩展），当然像main这种程序的启动点函数加以特殊照顾也不会过。版主如果有C89的原文链接给出的话，本人十分感谢，我很想知道C89 规范2.1.2.2的前后相关内容。个人的感觉是，C89制定的背景主要是针对Unix系统的。Unix上一个程序运行之后有一个返回值，其它程序可以检测此返回值作进一步处理，这符合操作系统（包括Windows）下应用开发的惯例，所以C89用了“shall conform”的强烈建议的词汇，不过还没有用must！实际上，恰恰是一些嵌入式C编译器，考虑到用户的系统可能并没有操作系统存在，就一个单一任务，main的返回值并不重要，所以允许void main形式的声明，比如本人经常用到的Keil C 51。         2、对10楼网友，void函数并不只是让程序员感受好一点，如果声明了void型函数，编译器是否真的要准备返回值（比如x86下放在EAX寄存器中），恐怕只有试验过每一个编译器才好这么说。尽管不声明返回类型的函数，一些C语言编译器可能并不提示，强制当成返回整型值处理（好像是C标准，具体忘了在哪里了）。但不能由此推论void返回函数编译器就一定准备返回值，我估计C标准也不会建议编译器这么实现的。

不只是 main 函数，所有函数的 void 返回只是用来让程序员好受一点，表示不关心这个返回值，帮我忽略了它 函数的那个返回值是一直存在的

引用 8 楼 nice_cxf 的回复:7楼乱误导，现在基本都不会有人写void main()，都是int main()，实际就算是int main()，也可以不用写return，但是这样写程序不是好习惯   是的呀，C89 里就说好了main的返回值是int的，国内某些教材祸害了几代C程序员啊  2.1.2.2 Hosted environment     A hosted environment need not be provided, but shall conform to the following specifications if present.  "Program startup"     The function called at program startup is named main .  The implementation declares no prototype for this function.  It can be defined with no parameters:           int main(void) { /*...*/ }  or with two parameters (referred to here as argc and argv , though any names may be used, as they are local to the function in which they are declared):           int main(int argc, char *argv[]) { /*...*/ }

引用 楼主 u014544409 的回复: 如上面的函数所示，主函数有返回值，但是当程序进入while(1)这个循环函数之后，一直在里面执行里面的内容，至于while(1)结束之后的return 0这个语句，如果while(1)这个循环不结束，应该不会执行这个语句吧，请大家帮忙分析一下，谢谢了。         “如果while(1)这个循环不结束”，当然不会执行return 0这个语句。如果你觉得return 0这条语句多余，只需修改main函数的声明：void main()就是了。         顺便纠正4楼的提法：没有编译器会强制要求有return，如果强制要求有return，不是编译器的问题，是你的函数声明的问题。比如：int main()，你明明告诉编译器这个函数有一个整型返回值，当然最后得有一条return语句了，尽管实际上这条return语句可能永远都不会执行到。不过就我碰到的，特定平台上部分编译器会对特殊函数main的原型声明有要求：比如必须要返回整型值。

不执行return 0也可以返回的。  exit(0);

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

不会执行到，一些嵌入式编译器规定必须有return，否则会产生警告，其实你可以换一种写法：  int main(void) {     int loop = 1;     ...     while(loop)     {         ...     }      return 0; }   这样有机会通过修改loop退出主循环，不过对于嵌入式系统来讲没什么意义。  引用 楼主 u014544409 的回复: 如上面的函数所示，主函数有返回值，但是当程序进入while(1)这个循环函数之后，一直在里面执行里面的内容，至于while(1)结束之后的return 0这个语句，如果while(1)这个循环不结束，应该不会执行这个语句吧，请大家帮忙分析一下，谢谢了。

不会执行哟，亲

只有while循环break后才会执行下边的语句，如果循环中有能满足条件的return或exit等结束程序语句，程序会直接退出

不会执行，main 返回程序就结束了

引用 19 楼 binaryhead 的回复:[quote=引用 18 楼 ForestDB 的回复:] 如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。[/quote]  return后也是调用exit。

引用 18 楼 ForestDB 的回复:如果while中没有break，没有exit，没有其它导致流程跳转的东西存在，那么while就是死循环，这样的话return就执行不到。 exit是一个普通的函数，不是C语言的一个关键字。exit直接退出，绕过了从调用exit函数点之后直到main出口的正常执行顺序。结论：“没有exit，”应删除。


Question: 1f8b08是gzip的文件标记吗？那1fc2808呢？我用C+zlib解析不了。

先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\cvt\latin2 C:\Program Files\Microsoft Visual Studio 10.0\VC\include\cvt\latin2

utf-8转latin1好难哦，调试了两天，今天见到曙光了，不过转换的结果解压只得部分结果，现在还没确定是转换代码的问题，还是解压代码的问题?  iconv库要是自己编译的吧，WIN＋CocdBlocks+gcc，头大。有没有现成的utf-8转latin1的C代码？！谢谢。

引用 18 楼 Qiaorui 的回复:[quote=引用 14 楼 angel_su 的回复:] 试试utf-8转latin1，确定开头是1f8b08才能gzip解码... 表示不熟悉ISO Latin-1字符集，尽管学XML时已经用过，但是确定不知道已经用了ISO Latin-1字符集:) [/quote]  1.txt是上面你说的256字节数据，转成latin1后像是gzip的...  User@T2370 ~ $ od -t x1 1.txt 0000000 1f c2 8b 08 00 00 00 00 00 00 00 c3 ad c2 bd c3 0000020 ab 73 c3 9b 58 7a 27 c3 bc 7d c3 bf c2 8a c2 ae 0000040 c3 be c2 b0 c2 b5 5b c3 a5 c3 99 c3 b8 c3 92 c2 0000060 9d c2 9d 79 c2 91 49 6a c2 92 77 53 c2 b5 c2 bb 0000100 c3 89 5e 2a c3 99 c3 bd c3 ae c3 8c 38 c3 99 c2 0000120 ae 77 c2 a6 3d c3 9b c3 ad 4e 32 7f 0e 48 59 c2 0000140 a6 25 c3 8a c3 a2 0d 00 49 c3 b0 4e c2 90 04 01 0000160 c2 82 c2 84 00 10 c2 a4 69 c3 99 c2 b2 64 59 6e 0000200 5b c2 b6 c2 ac c3 8b c2 b4 24 4b 2d c3 97 7b 7e 0000220 38 c2 84 48 c3 aa 4a c3 88 c2 a4 2f c3 89 54 c3 0000240 99 22 70 c3 8e c3 81 01 c3 b0 c3 a0 5c c2 9e c3 0000260 ab c3 af c3 b9 c2 93 3f c3 bb c3 a7 c3 9f c3 bc 0000300 c3 ba c2 b3 7f c2 bc c3 b1 c3 8d c2 b7 5f c3 9d 0000320 c3 bc c3 ba c3 a7 c2 9f 5f c3 b9 0f c2 97 3f c3 0000340 bf c3 ac c3 86 c3 97 c2 bf c2 bc c3 b9 c2 ab c2 0000360 af c2 be c3 be c2 87 c2 9f 7f c3 be c2 bf c3 be 0000400  User@T2370 ~ $ iconv -f utf-8 -t latin1 1.txt | od -t x1 0000000 1f 8b 08 00 00 00 00 00 00 00 ed bd eb 73 db 58 0000020 7a 27 fc 7d ff 8a ae fe b0 b5 5b e5 d9 f8 d2 9d 0000040 9d 79 91 49 6a 92 77 53 b5 bb c9 5e 2a d9 fd ee 0000060 cc 38 d9 ae 77 a6 3d db ed 4e 32 7f 0e 48 59 a6 0000100 25 ca e2 0d 00 49 f0 4e 90 04 01 82 84 00 10 a4 0000120 69 d9 b2 64 59 6e 5b b6 ac cb b4 24 4b 2d d7 7b 0000140 7e 38 84 48 ea 4a c8 a4 2f c9 54 d9 22 70 ce c1 0000160 01 f0 e0 5c 9e eb ef f9 93 3f fb e7 df fc fa b3 0000200 7f bc f1 cd b7 5f dd fc fa e7 9f 5f f9 0f 97 3f 0000220 ff ec c6 d7 bf bc f9 ab af be fe 87 9f 7f fe bf 0000240 fe 0000241

file命令LZ可有使用？

引用 17 楼 Qiaorui 的回复:[quote=引用 13 楼 ForestDB 的回复:] file命令LZ可有使用？ 没有linux环境，也不大懂:([/quote] 有可能但是自己不去尝试，那没办法了。

引用 14 楼 angel_su 的回复:试试utf-8转latin1，确定开头是1f8b08才能gzip解码... 表示不熟悉ISO Latin-1字符集，尽管学XML时已经用过，但是确定不知道已经用了ISO Latin-1字符集:)

引用 13 楼 ForestDB 的回复:file命令LZ可有使用？ 没有linux环境，也不大懂:(

我写的代码，头三个字节1F 8B 08可以解压缩，但是1f c2 8b 08开头一直毫无头绪

该格式是web服务传递数据过程中默认的Gzip数据压缩格式。  头三个字节1F 8B 08可以解压缩。本人亲测过，POST数据解压缩。  BOOL fnGzipDecompressPacket   (__IN_PARAM unsigned char* gzipDataBuffer,   __IN_PARAM size_t gzipDataBuffer_Length,    __OUT_PARAM char* pChDataBuffer,   __OUT_PARAM DWORD *pdwLength);    封装好的函数。  http://blog.csdn.net/microzone/article/details/38367797

前256字节数据  0x3d55f8: 1f c2 8b 08 00 00 00 00|00 00 00 c3 ad c2 bd c3    .??........?-??? 0x3d5608: ab 73 c3 9b 58 7a 27 c3|bc 7d c3 bf c2 8a c2 ae    ?s??Xz'??}?????? 0x3d5618: c3 be c2 b0 c2 b5 5b c3|a5 c3 99 c3 b8 c3 92 c2    ???°?μ[?￥??????? 0x3d5628: 9d c2 9d 79 c2 91 49 6a|c2 92 77 53 c2 b5 c2 bb    ???y??Ij??wS?μ?? 0x3d5638: c3 89 5e 2a c3 99 c3 bd|c3 ae c3 8c 38 c3 99 c2    ??^*????????8??? 0x3d5648: ae 77 c2 a6 3d c3 9b c3|ad 4e 32 7f 0e 48 59 c2    ?w?|=???-N2.HY? 0x3d5658: a6 25 c3 8a c3 a2 0d 00|49 c3 b0 4e c2 90 04 01    |%???￠..I?°N??.. 0x3d5668: c2 82 c2 84 00 10 c2 a4|69 c3 99 c2 b2 64 59 6e    ????..?¤i???2dYn 0x3d5678: 5b c2 b6 c2 ac c3 8b c2|b4 24 4b 2d c3 97 7b 7e    [???????′$K-??{~ 0x3d5688: 38 c2 84 48 c3 aa 4a c3|88 c2 a4 2f c3 89 54 c3    8??H?aJ???¤/??T? 0x3d5698: 99 22 70 c3 8e c3 81 01|c3 b0 c3 a0 5c c2 9e c3    ?"p????.?°??\??? 0x3d56a8: ab c3 af c3 b9 c2 93 3f|c3 bb c3 a7 c3 9f c3 bc    ??ˉ?1??????§???? 0x3d56b8: c3 ba c2 b3 7f c2 bc c3|b1 c3 8d c2 b7 5f c3 9d    ?o?3???±???·_?? 0x3d56c8: c3 bc c3 ba c3 a7 c2 9f|5f c3 b9 0f c2 97 3f c3    ???o?§??_?1.???? 0x3d56d8: bf c3 ac c3 86 c3 97 c2|bf c2 bc c3 b9 c2 ab c2    ????????????1??? 0x3d56e8: af c2 be c3 be c2 87 c2|9f 7f c3 be c2 bf c3 be    ˉ??????????????   使用UTF-8转UNICODE后得到以下数据，可是zlib好像不支持wcar_t  0x3d3dd8: 1f 00 8b 00 08 00 00 00|ab ab ab ab ab ab ab ab    ..?.....???????? 0x3d3de8: 00 00 00 00 00 00 00 00|04 00 04 00 00 07 18 00    ................ 0x3d3df8: 89 3d 3d 00 00 00 00 00|ab ab ab ab ab ab ab ab    ?==.....???????? 0x3d3e08: 00 00 00 00 00 00 00 00|0e 00 04 00 00 07 1c 00    ................ 0x3d3e18: 01 00 00 00 a8 03 00 00|a8 03 00 00 00 00 00 00    ....¨...¨....... 0x3d3e28: 04 08 00 00 04 08 00 00|04 08 00 00 04 08 00 00    ................ 0x3d3e38: 04 08 00 00 00 00 00 00|02 00 00 00 f8 27 3d 00    ............?'=. 0x3d3e48: 18 28 3d 00 d0 3f 3d 00|b0 27 3d 00 b0 27 3d 00    .(=.D?=.°'=.°'=. 0x3d3e58: 08 3f 3d 00 70 24 3d 00|72 24 3d 00 f0 3f 3d 00    .?=.p$=.r$=.e?=. 0x3d3e68: f0 3f 3d 00 ab ab ab ab|ab ab ab ab ee fe ee fe    e?=.?????????t?t 0x3d3e78: 00 00 00 00 00 00 00 00|08 00 0e 00 00 07 19 00    ................ 0x3d3e88: 43 68 69 6e 65 73 65 5f|50 65 6f 70 6c 65 27 73    Chinese_People's 0x3d3e98: 20 52 65 70 75 62 6c 69|63 20 6f 66 20 43 68 69     Republic of Chi 0x3d3ea8: 6e 61 2e 39 33 36 00 ab|ab ab ab ab ab ab ab fe    na.936.????????t 0x3d3eb8: 00 00 00 00 00 00 00 00|08 00 08 00 00 07 19 00    ................ 0x3d3ec8: 43 68 69 6e 65 73 65 5f|50 65 6f 70 6c 65 27 73    Chinese_People's   再转ANSI，文件头又不对了  0x4c0048: 1f 3f 08 00 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .?...e-o.e-o.e-o 0x4c0058: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0068: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0078: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0088: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0098: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00a8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00b8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00c8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00d8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00e8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c00f8: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0108: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0118: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0128: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o 0x4c0138: 0d f0 ad ba 0d f0 ad ba|0d f0 ad ba 0d f0 ad ba    .e-o.e-o.e-o.e-o

怀疑是UTF－8编码的数据，java写的。

前256字节数据  0x3d55f8: 1f c2 8b 08 00 00 00 00|00 00 00 c3 ad c2 bd c3    .??........?-??? 0x3d5608: ab 73 c3 9b 58 7a 27 c3|bc 7d c3 bf c2 8a c2 ae    ?s??Xz'??}?????? 0x3d5618: c3 be c2 b0 c2 b5 5b c3|a5 c3 99 c3 b8 c3 92 c2    ???°?μ[?￥??????? 0x3d5628: 9d c2 9d 79 c2 91 49 6a|c2 92 77 53 c2 b5 c2 bb    ???y??Ij??wS?μ?? 0x3d5638: c3 89 5e 2a c3 99 c3 bd|c3 ae c3 8c 38 c3 99 c2    ??^*????????8??? 0x3d5648: ae 77 c2 a6 3d c3 9b c3|ad 4e 32 7f 0e 48 59 c2    ?w?|=???-N2.HY? 0x3d5658: a6 25 c3 8a c3 a2 0d 00|49 c3 b0 4e c2 90 04 01    |%???￠..I?°N??.. 0x3d5668: c2 82 c2 84 00 10 c2 a4|69 c3 99 c2 b2 64 59 6e    ????..?¤i???2dYn 0x3d5678: 5b c2 b6 c2 ac c3 8b c2|b4 24 4b 2d c3 97 7b 7e    [???????′$K-??{~ 0x3d5688: 38 c2 84 48 c3 aa 4a c3|88 c2 a4 2f c3 89 54 c3    8??H?aJ???¤/??T? 0x3d5698: 99 22 70 c3 8e c3 81 01|c3 b0 c3 a0 5c c2 9e c3    ?"p????.?°??\??? 0x3d56a8: ab c3 af c3 b9 c2 93 3f|c3 bb c3 a7 c3 9f c3 bc    ??ˉ?1??????§???? 0x3d56b8: c3 ba c2 b3 7f c2 bc c3|b1 c3 8d c2 b7 5f c3 9d    ?o?3???±???·_?? 0x3d56c8: c3 bc c3 ba c3 a7 c2 9f|5f c3 b9 0f c2 97 3f c3    ???o?§??_?1.???? 0x3d56d8: bf c3 ac c3 86 c3 97 c2|bf c2 bc c3 b9 c2 ab c2    ????????????1??? 0x3d56e8: af c2 be c3 be c2 87 c2|9f 7f c3 be c2 bf c3 be    ˉ??????????????  使用UTF-8转UNICODE后得到以下数据，可是zlib好像不支持wcar_t，  再转ANSI，数据又变成1F3F08

从文件的用途和文件头前四字节，基本上可断定这是.gz文件。就是不好理解第2字节的C2怎么来。看文件编码是UTF-8，但是fread()又读不出UTF-8的标志，郁闷。 哪位遇到过同样的问题，指点一下迷津，感激不尽。

可以用linux的file命令帮你猜测。

http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html  Compressed files File type 	Typical extension 	Hex digits xx = variable 	Ascii digits . = not an ascii char Bzip 	.bz 	42 5a 	BZ Compress 	.Z 	1f 9d 	.. gzip format 	.gz 	1f 8b 	.. pkzip format 	.zip 	50 4b 03 04 	PK..

查了很多资料，gz文件头格式为1F8B08，其中08代表压缩方式，我的代码可以解压。但这次文件头居然是1FC28B08，这个C2是怎么回事呢？求高手指教！

应该是gzip（.gz）格式的，无论怎样可以试着用7-zip来解压。

7-Zip解不开，网站用的离线包，应该遵守一定的规则吧？哪有相关说明呢，有C代码更佳。


Question: 谁拿了最多奖学金 这一题的文件调用有问题 请大神帮帮改一下

仅供参考 /*************************************************************************     > File Name: tyvj_1002.cpp     > Author: 傻李     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月13日 星期四 16时10分40秒  ************************************************************************/  #include<iostream> #include<vector> using namespace std;  struct student { 	string name; 	int aver_result; 	int class_result; 	char leader; 	char west; 	int npaper; }; struct award { 	int naward;//奖金数目 //	int times; 	string name; }; void sum_award(struct student & stu, struct award &v) { 	v.naward = 0; 	//v.times = 0; 	v.name = stu.name; 	//院士奖学金 	if(stu.aver_result > 80 && stu.npaper >=1) 	{ 	//	v.times++; 		v.naward += 8000; 	} 	//五四等奖学金 	if(stu.aver_result > 85 && stu.class_result > 80) 	{ 	//	v.times++; 		v.naward += 4000; 	} 	//成绩优秀奖 	if(stu.aver_result > 90) 	{ 	//	v.times++; 		v.naward += 2000; 	} 	//西部奖学金 	if(stu.aver_result > 85 && stu.west == 'Y') 	{ 	//	v.times++; 		v.naward +=1000; 	} 	//班级贡献奖 	if(stu.class_result > 80 && stu.leader == 'Y') 	{ 	//	v.times++; 		v.naward +=850; 	} } int sum_of_award(struct award *p, int N) { 	int sum = 0; 	for(int i = 0; i < N; ++i) 	{ 		sum = sum + p[i].naward; 	} 	return sum; }  //寻找奖金最高的人 struct award find(struct award *p,int N) { 	struct award tmp; //	tmp.times = 0; 	tmp.naward= 0; 	for(int i =0 ; i < N; ++i) 	{ 		if(p[i].naward > tmp.naward) 		{ 			tmp.naward = p[i].naward; 		//	tmp.times = p[i].times; 			tmp.name = p[i].name; 		} 	} 	return tmp; }  int main() { 	int N; 	cin >> N; 	struct student *stu = new struct student[N]; 	struct award *p = new struct award[N]; 	for(int i = 0; i < N; ++i) 	{ 		cin >> stu[i].name; 		cin >> stu[i].aver_result; 		cin >> stu[i].class_result; 		cin >> stu[i].leader; 		cin >> stu[i].west; 		cin >> stu[i].npaper;         sum_award(stu[i],p[i]); 	} 	auto sum = sum_of_award(p,N); 	auto tmp = find(p,N); 	cout << tmp.name << endl; 	cout << tmp.naward << endl; 	cout << sum << endl; }

请楼主参考 http://www.pudn.com/downloads464/sourcecode/others/detail1950857.html http://huobumingbai.blog.51cto.com/1196746/425898


Question: 杭电 2012

求s的表达式错了，应该是i而不是x

…我郁闷了一夜没看出来

试试这个 /*************************************************************************     > File Name: isperimer.cpp     > Author: 傻李     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月12日 星期三 22时50分48秒  ************************************************************************/  #include<iostream> #include<vector> using namespace std;  bool isprimer(int n) { 	int i; 	bool state = true; 	for(i = 2; i < n; ++i ) 	{ 		if(0 == n % i) 		{ 			state = false; 			break; 		} 	} 	return state; }  int main() { 	int x,y,z; 	int i; 	vector<int> v; 	bool state = true; 	vector<bool> result; 	cin >> x >> y; 	while (x !=0 && y !=0) 	{ 		for(i = x; i <= y; ++i) 		{ 			z = i*i + i + 41; 			state = isprimer(z); 			if(state == false) 				break; 		} 		result.push_back(state); 		state = true; 		cin >> x >> y; 	} 	for(vector<bool>::iterator iter = result.begin();iter != result.end(); ++iter) 	{ 		if(true == *iter) 			cout << "OK" << endl; 		else 			cout << "Sorry" << endl; 	} 	return 0; }

s=x*x+x+41 这个不是应该s=i*i+i+41?

y-x+1表示定义域內所有整数 count=y-x+1说明所有的都是素数  输出OK。  scanf我那种写法也行吧

if(count==y-x+1) 貌似词不达意  另外 !(x==0&&y==0) 最好写成 (x!=0||y!=0) 可读性更好一点

Problem Description 对于表达式n^2+n+41，当n在（x,y）范围内取整数值时（包括x,y）(-39<=x<y<=50)，判定该表达式的值是否都为素数。    Input 输入数据有多组，每组占一行，由两个整数x，y组成，当x=0,y=0时，表示输入结束，该行不做处理。    Output 对于每个给定范围内的取值，如果表达式的值都为素数，则输出"OK",否则请输出“Sorry”,每组输出占一行。    Sample Input 0 1 0 0    Sample Output OK   提示wrong answer

代码有啥问题？代码干啥的？lz都没有说明白。。。