Question: linux下c语言gotoxy()实现代码，怎么这么神奇

学习了

++  引用 3 楼 KenZhang1031 的回复:ANSI转义序列，很多类unix的终端，包括linux控制台都解释ANSI转义序列，转义符就是ESC，ASCII码是0x1b，比如Esc[Line;Columnf就表示移动光标到(Line,Column)的位置。而你printf打印的字符串正是这个命令，其中0x1B正是 ESC的ASCII码。

In the following list of ANSI escape sequences, the abbreviation ESC represents the ASCII escape character 27 (1Bh), which appears at the beginning of each escape sequence.  ESC[PL;PcH     Cursor Position: Moves the cursor to the specified position     (coordinates). If you do not specify a position, the cursor moves to the     home position--the upper-left corner of the screen (line 0, column     0). This escape sequence works the same way as the following Cursor     Position escape sequence.  ESC[PL;Pcf     Cursor Position: Works the same way as the preceding Cursor Position     escape sequence.  ESC[PnA     Cursor Up: Moves the cursor up by the specified number of lines without     changing columns. If the cursor is already on the top line, ANSI.SYS     ignores this sequence.  ESC[PnB     Cursor Down: Moves the cursor down by the specified number of lines     without changing columns. If the cursor is already on the bottom line,     ANSI.SYS ignores this sequence.  ESC[PnC     Cursor Forward: Moves the cursor forward by the specified number of     columns without changing lines. If the cursor is already in the     rightmost column, ANSI.SYS ignores this sequence.  ESC[PnD     Cursor Backward: Moves the cursor back by the specified number of     columns without changing lines. If the cursor is already in the leftmost     column, ANSI.SYS ignores this sequence.  ESC[s     Save Cursor Position: Saves the current cursor position. You can move     the cursor to the saved cursor position by using the Restore Cursor     Position sequence.  ESC[u     Restore Cursor Position: Returns the cursor to the position stored     by the Save Cursor Position sequence.  ESC[2J     Erase Display: Clears the screen and moves the cursor to the home     position (line 0, column 0).  ESC[K     Erase Line: Clears all characters from the cursor position to the     end of the line (including the character at the cursor position).  ESC[Ps;...;Psm     Set Graphics Mode: Calls the graphics functions specified by the     following values. These specified functions remain active until the next     occurrence of this escape sequence. Graphics mode changes the colors and     attributes of text (such as bold and underline) displayed on the     screen. ……

不懂，mark。

只是特定控制台下，这串字会被视为光标命令，同c还是printf关系不大...


Question: 如果C语言函数参数太多,可以怎么优化?

参数的多少与你的问题的复杂度和解决问题的方式都有一定的关联。如果一个函数处理的问题所需要的参数就是那么多的话，就是合适的，不必修改。

使用可变类型和数量的原型，类似于printf： int printf (const char *, ...);

c语言的参数 http://www.alex999.com/c_language_parameters.html

七八个很好了。

引用 11 楼 jiandingzhe 的回复:[quote=引用 10 楼 u012997273 的回复:] [quote=引用 9 楼 jiandingzhe 的回复:] [quote=引用 1 楼 xingat110 的回复:] 完全可以用结构体 我反对任意地组织结构体。结构体应当尽量表现业务上的逻辑关联性，而不是简单地用来减少参数数量。[/quote] 反对无效，要发对也要说个大家都同意的理由啊[/quote] 会增加类型的数量，而这个类型基本只在这一个函数有用。想象代码里充斥着“typedef struct XXXArgType”一类的玩意，我宁可多用几个参数。 而且楼主的七八个参数也不是很多。[/quote] 非常赞同

引用 17 楼 starytx 的回复:结构体从技术上讲当然是可以的。但是一个函数参数这么多是否应该思考一下原因。同意9楼的观点，结构体应该是一组相关的数据组合，不是简单的为了减少参数个数而专门写一个结构体。其次，如果参数比较大，应该尽量用指针（如果只是输入，应该加const前缀）   函数实现的功能并不多,不过控制类的参数,和输出的参数有点多. 函数要实现打印明细的功能,根据个人账号,开始日期,截止日期查询,还需要用到文件指针,打印的是第几页,每页几条数据,当前页实际打印多少数据,是否全部打印.如果出错,需要把错误信息返回. 这就出现了很多的参数.

WIN32API参数也是众多。。

引用 27 楼 u011688498 的回复:我说的是不要超过三个参数  做内核的吧？

可能需要重构而不是优化.

使用数组喽。你们看数组行不？

结构体数组或者，分成几个函数来写，具体情况具体分析吧

一般来说,参数过多的原因是函数功能不单一.   do one thing, and do it well

来观摩观摩，学习学习

C/C++标准里面是否规定了函数参数个数最大值？ 急急如律令，请标准党现身——

引用 32 楼 zhao4zhong1 的回复:刚发现cryptui.dll中的 LocalEnroll     LocalEnrollNoDS 多达23个参数！ 你赢了，把Msdn上的搞过来。在实际项目中，没有人写这么多

其实可以采用不定参数。 结构体也行。

引用 24 楼 zhao4zhong1 的回复:有谁统计过Windows API中哪个函数的参数最多？ 有比 BOOL CreateProcessAsUser(   HANDLE hToken,         // handle to a token representing the logged-on user   LPCTSTR lpApplicationName,  // pointer to name of executable module   LPTSTR lpCommandLine,       // pointer to command line string   LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes   LPSECURITY_ATTRIBUTES lpThreadAttributes,  // thread security attributes   BOOL bInheritHandles,         // whether new process inherits handles   DWORD dwCreationFlags,        // creation flags   LPVOID lpEnvironment,         // pointer to new environment block   LPCTSTR lpCurrentDirectory,   // pointer to current directory name   LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO   LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION ); 还多的吗？ AccessCheckByTypeResultListAndAuditAlarmByHandle Function  The AccessCheckByTypeResultListAndAuditAlarmByHandle function determines whether a security descriptor grants a specified set of access rights to the client that the calling thread is impersonating. The difference between this function and AccessCheckByTypeResultListAndAuditAlarm is that this function allows the calling thread to perform the access check before impersonating the client.  The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a system access control list (SACL) with access control entries (ACEs) that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not currently supported.   BOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmByHandle(   __in          LPCTSTR SubsystemName,   __in          LPVOID HandleId,   __in          HANDLE ClientToken,   __in          LPCTSTR ObjectTypeName,   __in_opt      LPCTSTR ObjectName,   __in          PSECURITY_DESCRIPTOR pSecurityDescriptor,   __in_opt      PSID PrincipalSelfSid,   __in          DWORD DesiredAccess,   __in          AUDIT_EVENT_TYPE AuditType,   __in          DWORD Flags,   __in_out_opt  POBJECT_TYPE_LIST ObjectTypeList,   __in          DWORD ObjectTypeListLength,   __in          PGENERIC_MAPPING GenericMapping,   __in          BOOL ObjectCreation,   __out         LPDWORD GrantedAccess,   __out         LPDWORD AccessStatusList,   __out         LPBOOL pfGenerateOnClose );  自己PK自己！ 谁不服？上！


Question: 请问下面这题用C编程怎么求解。

4元一次方程,有若干解.

引用 4 楼 u012062607 的回复:[quote=引用 3 楼 derekrose 的回复:] 这还用c语言  a=1 d=9 剩下的自己解方程 答案我知道，1089.我只是想用C来解[/quote]  写代码又不是规定必须遍历之类，为什么不能再草纸上计算。 比如此题，四位数abcd*9=四位数dcba --》abcd <= 1111 --》a = 1，d = 9 --》b只能为0或1，b为1时，c仅仅只能取0（11c9 > 1111）,显然不成立，则b为0 --》10c9   你可以继续推到下去，难道一定要写效率低的代码

如果允许有进位，即限制A，B，C，D都在[0,9]的范围，那么if中加一个条件： （j < 10000）

程序解法： #include <stdio.h> #include <stdlib.h>  void main(void) { 	int i, j;  	for(i=0; i<10000; i++) 	{ 		j = i * 9; 		if(((j % 10) == ((i / 1000) % 10)) 			&& (((j / 10) % 10) == ((i / 100) % 10)) 			&& (((j / 100) % 10) == ((i / 10) % 10)) 			&& (((j / 1000) % 10) == (i % 10))) 		{ 			printf("%d\r\n", i); 		} 	} }  打印出所有小于10000的满足条件的数。

#include<stdio.h> int main(){ 	  int x=1111,m,y,i,l=0;  	for( i=1000;i<x;i++){  		y=i*9; 		l=y; 		m=0	;  		while(l){ 		 	m=m*10+l%10; 		 	l=l/10;	 		 		 		 } 		  			if (m==i){ 				printf("%d",y); 			} 	 	 	 } 	return 0; } 我的思路： 值为9999内的一个数反过来等于原数 新手一枚

引用 4 楼 u012062607 的回复:[quote=引用 3 楼 derekrose 的回复:] 这还用c语言  a=1 d=9 剩下的自己解方程 答案我知道，1089.我只是想用C来解[/quote]  效率高的代码，都是经过数学模型优化的。

#include <stdio.h> /* ABCD*9 = DCBA =>A=1 D=9 =>BC*9 + 8 = CB */ int main(){  int b, c;  for(b = 0; b < 10, b++){   for(c = 0; c < 10; c++){    if((b * 10 + c) * 9 + 8 == c * 10 + b) printf("%d\n", 1000 + b * 100 + c * 10 + 9);    }  }  return 0; }

引用 2 楼 user-13 的回复:穷举，最简单的4个for循环搞起~为啥不一个for循环直接搞定？

经测试 可以输出1089； #include <stdlib.h> #include <stdio.h> void math(void) { 		int a,b; 		int i,j,k; 		int A[4]={}; 		int B[4]={}; 		for(i=1000;i<2000;i++){//这里的i是个大体的范围 				a = i; 				b = a*9;//这个是满足 ABCD*9=DCBA的关系的 				for(j=0;j<4;j++){//这个循环是取出各位上的数值保存到数组中 						A[j] = a%10; 						a=a/10; 						B[j] = b%10; 						b = b/10; 				} 				for(j=0;j<4;j++)//这个是满足 ABCD*9=DCBA的关系的 						if(A[j] != B[3-j]) break;//如果不满足就跳出来 ； 				if(j==4)//如果 j == 4 说明上面的那个for循环全部执行了；所以此时所有的关系都满足了； 						printf("%d\n",i);//打印出这个数 		} }		  int main(int argc,char *argv[]) { 		math(); }

引用 楼主 u012062607 的回复:已知四位整数ABCD，满足下面关系式：ABCD*9=DCBA，   求ABCD的值。 谢谢各位大神。A是1，D是9，剩下的两层循环，楼上各位大神太给力了！

引用 15 楼 u012062607 的回复:[quote=引用 11 楼 u013235485 的回复:] 对c还在学习阶段，写个c#的，思想差不多，但不是一个好的办法。 将一个值x返转，如1985反转为5891,再看1985*9是否和5891相等。   class Program     {         static int fun(int x)         {             int d = x / 1000;             int c = (x % 1000) / 100;             int b = (x % 1000 % 100) / 10;             int a = x % 1000 % 100 % 10;             return int.Parse(string.Format("{0}{1}{2}{3}",a,b,c,d));         }          static void Main(string[] args)         {             for (int i = 1000; i <= 9999; i++)             {                 if (i * 9 == fun(i))                 {                     Console.WriteLine(i);                     break;                 }             }                }     }  这个看起来很高级的样子，不怎么看得懂。[/quote]  哥们，你腹黑啊。。

引用 11 楼 u013235485 的回复:对c还在学习阶段，写个c#的，思想差不多，但不是一个好的办法。 将一个值x返转，如1985反转为5891,再看1985*9是否和5891相等。   class Program     {         static int fun(int x)         {             int d = x / 1000;             int c = (x % 1000) / 100;             int b = (x % 1000 % 100) / 10;             int a = x % 1000 % 100 % 10;             return int.Parse(string.Format("{0}{1}{2}{3}",a,b,c,d));         }          static void Main(string[] args)         {             for (int i = 1000; i <= 9999; i++)             {                 if (i * 9 == fun(i))                 {                     Console.WriteLine(i);                     break;                 }             }                }     }  这个看起来很高级的样子，不怎么看得懂。

引用 12 楼 movsd 的回复:[quote=引用 9 楼 u012062607 的回复:] #include<stdio.h> void main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9};     int b[10]={0,1,2,3,4,5,6,7,8,9}; 	int c[10]={0,1,2,3,4,5,6,7,8,9}; 	int d[10]={0,1,2,3,4,5,6,7,8,9}; 	int x,y,i,j,k,l; 	i=0;j=0;k=0;l=0;     for(;i<10;i++) 		for(;j<10;j++) 			for(;k<10;k++) 				for(;l<10;l++) 				{ 					 x=1000*a[i]+100*b[j]+10*c[k]+d[l];                                          y=1000*d[l]+100*c[k]+10*b[j]+a[i]; 					 if(y==9*x&&x!=0) 						 printf("%d\n",x); 				}	 }  为什么这个程序不行啊。 没有输出， 把循环变量的初始化写在for里面。[/quote] 谢谢，问题解决了。

引用 10 楼 u012915226 的回复:[quote=引用 9 楼 u012062607 的回复:] [quote=引用 8 楼 user-13 的回复:] for(i = 0; i < 10; i++)   for(j = 0; j < 10; j++)      if((1000+i*100+j*10+9)*9 == 9000+j*100+i*10 +1)           printf("%d,%d",i,j);  #include<stdio.h> void main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9};     int b[10]={0,1,2,3,4,5,6,7,8,9}; 	int c[10]={0,1,2,3,4,5,6,7,8,9}; 	int d[10]={0,1,2,3,4,5,6,7,8,9}; 	int x,y,i,j,k,l; 	i=0;j=0;k=0;l=0;     for(;i<10;i++) 		for(;j<10;j++) 			for(;k<10;k++) 				for(;l<10;l++) 				{ 					 x=1000*a[i]+100*b[j]+10*c[k]+d[l];                                          y=1000*d[l]+100*c[k]+10*b[j]+a[i]; 					 if(y==9*x&&x!=0) 						 printf("%d\n",x); 				}	 } 为什么这个程序不行啊。 没有输出，[/quote]你那连续4个for 是要做肾  看起来怪怪的[/quote] 四位数，所以用四个for循环确定，

引用 9 楼 u012062607 的回复:#include<stdio.h> void main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9};     int b[10]={0,1,2,3,4,5,6,7,8,9}; 	int c[10]={0,1,2,3,4,5,6,7,8,9}; 	int d[10]={0,1,2,3,4,5,6,7,8,9}; 	int x,y,i,j,k,l; 	i=0;j=0;k=0;l=0;     for(;i<10;i++) 		for(;j<10;j++) 			for(;k<10;k++) 				for(;l<10;l++) 				{ 					 x=1000*a[i]+100*b[j]+10*c[k]+d[l];                                          y=1000*d[l]+100*c[k]+10*b[j]+a[i]; 					 if(y==9*x&&x!=0) 						 printf("%d\n",x); 				}	 }  为什么这个程序不行啊。 没有输出， 把循环变量的初始化写在for里面。

引用 9 楼 u012062607 的回复:[quote=引用 8 楼 user-13 的回复:] for(i = 0; i < 10; i++)   for(j = 0; j < 10; j++)      if((1000+i*100+j*10+9)*9 == 9000+j*100+i*10 +1)           printf("%d,%d",i,j);  #include<stdio.h> void main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9};     int b[10]={0,1,2,3,4,5,6,7,8,9}; 	int c[10]={0,1,2,3,4,5,6,7,8,9}; 	int d[10]={0,1,2,3,4,5,6,7,8,9}; 	int x,y,i,j,k,l; 	i=0;j=0;k=0;l=0;     for(;i<10;i++) 		for(;j<10;j++) 			for(;k<10;k++) 				for(;l<10;l++) 				{ 					 x=1000*a[i]+100*b[j]+10*c[k]+d[l];                                          y=1000*d[l]+100*c[k]+10*b[j]+a[i]; 					 if(y==9*x&&x!=0) 						 printf("%d\n",x); 				}	 } 为什么这个程序不行啊。 没有输出，[/quote]你那连续4个for 是要做肾  看起来怪怪的

引用 8 楼 user-13 的回复:for(i = 0; i < 10; i++)   for(j = 0; j < 10; j++)      if((1000+i*100+j*10+9)*9 == 9000+j*100+i*10 +1)           printf("%d,%d",i,j);  #include<stdio.h> void main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9};     int b[10]={0,1,2,3,4,5,6,7,8,9}; 	int c[10]={0,1,2,3,4,5,6,7,8,9}; 	int d[10]={0,1,2,3,4,5,6,7,8,9}; 	int x,y,i,j,k,l; 	i=0;j=0;k=0;l=0;     for(;i<10;i++) 		for(;j<10;j++) 			for(;k<10;k++) 				for(;l<10;l++) 				{ 					 x=1000*a[i]+100*b[j]+10*c[k]+d[l];                                          y=1000*d[l]+100*c[k]+10*b[j]+a[i]; 					 if(y==9*x&&x!=0) 						 printf("%d\n",x); 				}	 } 为什么这个程序不行啊。 没有输出，

引用 6 楼 user-13 的回复:[quote=引用 3 楼 derekrose 的回复:] 这还用c语言  a=1 d=9 剩下的自己解方程 +1 我想问下楼主是学什么的[/quote] 刚刚学C，学生一枚。


Question: ZOJ 1005 jugs 超时问题

一开始用C++，以为是cout，cin的问题，后来改用C写，还是超时，什么问题，求助大神。

你认为超时是什么引起的


Question: scanf的空格问题

引用 6 楼 truelance 的回复:当然是空格吸收掉回车. 而且一个空格可以吸收掉连续的多个空格/Tab/回车. 谢谢我明白了！

当然是空格吸收掉回车. 而且一个空格可以吸收掉连续的多个空格/Tab/回车.

引用 3 楼 truelance 的回复:C11标准7.21.6.2.5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. fscanf的格式串中有空格的话,就会跳过所有空字符(空格,tab键,回车)  如果格式串中没有空格, 则%c会读入任意字符, 参见c11标准7.21.6.2.8 Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier. 这么说，就不是空格吸收掉了回车键咯？

引用 3 楼 truelance 的回复:C11标准7.21.6.2.5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. fscanf的格式串中有空格的话,就会跳过所有空字符(空格,tab键,回车)  如果格式串中没有空格, 则%c会读入任意字符, 参见c11标准7.21.6.2.8 Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier. +1

引用 1 楼 user-2 的回复:scanf()函数从输入流缓冲区中读取值的，而读取时遇到回车(\n)而结束的。带空格的scanf(" %c")表示要从输入流缓冲区读两个字符，一个给空格，一个给%c。为什么加空格呢，是因为回车符(\n)也在输入流缓冲区中，所以将\n赋值给空格，以让%c被正确赋值。否则，不加空格，回车符\n会被赋值给%c。 我现在输入的时候改成，输入空格了，理应上来说，我输入空格+字符+回车，回车应该会被下一次循环的空格吸收掉，但是为什么结果不会有问题呢？


Question: gets和getchar一起用的问题

quote=引用 13 楼 u013190272 的回复:] 引用 11 楼 u013160932 的回复:[quote=引用 8 楼 u013190272 的回复:] [quote=引用 7 楼 u013160932 的回复:] [quote=引用 4 楼 u013190272 的回复:] get语句把字符串后面的回车键吞掉了，所以c字符是给了b，c变量是\n。可以说，gets()会舍弃最后的回车符！ gets是以回车结束的吧,怎么会吞掉呢= =,还有舍弃了最后的回车是什么意思= =[/quote] 就是说回车键不会被下一个getchar（）捕获.[/quote] 为什么不会被下一个回车捕获?[/quote] 3楼的大神已经告诉你了。gets（）会把后面的回车键清楚掉不让b=getchar（）；接收。这是gets（）；的特点。[/quote] 原来是这样,懂了,谢谢各位了,分数没那么多,只能给几位大神了,不好意思啊[

引用 10 楼 u013160932 的回复:[quote=引用 9 楼 u013190272 的回复:] #include <stdio.h> int main() {	 	char a[10],b,c; 	gets(a); 	scanf(" %c",&b); 	scanf(" %c",&c); 	printf("%s  %d  %d",a,b,c); 	return 0; } 我试了。、可以的。 C11标准7.21.6.2.5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. fscanf的格式串中有空格的话,就会跳过所有空字符(空格,tab键,回车)  如果格式串中没有空格, 则%c会读入任意字符, 参见c11标准7.21.6.2.8 好像scanf是可以,但是那个getchar怎么不行了[/quote] getchar（）；是不会跳过空白符（空格符，回车符，tab符）的，scanf（“ %c”）里面加空格就可以。

引用 8 楼 u013190272 的回复:[quote=引用 7 楼 u013160932 的回复:] [quote=引用 4 楼 u013190272 的回复:] get语句把字符串后面的回车键吞掉了，所以c字符是给了b，c变量是\n。可以说，gets()会舍弃最后的回车符！ gets是以回车结束的吧,怎么会吞掉呢= =,还有舍弃了最后的回车是什么意思= =[/quote] 就是说回车键不会被下一个getchar（）捕获.[/quote] 为什么不会被下一个回车捕获?

引用 9 楼 u013190272 的回复:#include <stdio.h> int main() {	 	char a[10],b,c; 	gets(a); 	scanf(" %c",&b); 	scanf(" %c",&c); 	printf("%s  %d  %d",a,b,c); 	return 0; } 我试了。、可以的。 C11标准7.21.6.2.5 A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. fscanf的格式串中有空格的话,就会跳过所有空字符(空格,tab键,回车)  如果格式串中没有空格, 则%c会读入任意字符, 参见c11标准7.21.6.2.8 好像scanf是可以,但是那个getchar怎么不行了

引用 7 楼 u013160932 的回复:[quote=引用 4 楼 u013190272 的回复:] get语句把字符串后面的回车键吞掉了，所以c字符是给了b，c变量是\n。可以说，gets()会舍弃最后的回车符！ gets是以回车结束的吧,怎么会吞掉呢= =,还有舍弃了最后的回车是什么意思= =[/quote] 就是说回车键不会被下一个getchar（）捕获.

引用 4 楼 u013190272 的回复:get语句把字符串后面的回车键吞掉了，所以c字符是给了b，c变量是\n。可以说，gets()会舍弃最后的回车符！ gets是以回车结束的吧,怎么会吞掉呢= =,还有舍弃了最后的回车是什么意思= =

引用 3 楼 truelance 的回复:1. gets()本身会吸收回车, 所以不需要再跟一个吸收回车的 2. gets()一直就是c语言里臭名昭著各类编程规范严禁使用的函数, 而且在最新的c11标准中已经删除了gets(), 所以不要再使用了. 因为需要输出带有空格的字符串所以才用的gets,而且吸收空格是为了不让后面的%c捕获到空格

引用 2 楼 ml0719787 的回复:scanf("%c")前面加个空格看看 scanf(" %c") 加空格也不行啊= =

scanf("%c")前面加个空格看看 scanf(" %c")

先占SF再看


Question: c课程设计结文文档

lz你们学院难道没有课程设计模板吗

百度一下应该有吧，比如：http://www.docin.com/p-439475698.html

这可能真的要问老师了，看看老师的要求是什么样的


Question: 对任意输入的一个字符进行加密 然后解密 输出加密解密的结果

没有实际意义的加解密。密码学最最基础的示例。  char encrypt_decryption(char ch, char key) { 	return ch ^ key; }  int main() {	 	unsigned char key = 9;//密钥 	char ch = getchar(); 	fflush(stdin); 	printf_s("原文:%c\n",ch);  	char encrypt_result = encrypt_decryption(ch, key);  	printf_s("加密后结果:%c\n",encrypt_result);  	char decryption_result = encrypt_decryption(encrypt_result,key); 	printf_s("解密原文:%c", decryption_result);  	return 0;  }

简单的加密就简单的加减一个定值就可以了

char  chx=0;  //原始字符 char  chy=0;  //加密后的字符 char  chz=0;  //解密后的字符  printf("请输入1个字符,手抖输多了的是王八蛋:"); scanf("%c",&chx);  chy=chx^0xAA;   //加密 chz=chy^0xAA;   //解密  printf("原始字符是:%c\n",chx); printf("加密后字符变成了:%c\n",chy); printf("解密后字符变成了:%c\n",chz);


Question: 关于大数据重复字数据的整理效率

我想了个方法，大致2倍读写(略多于2倍)。

引用 26 楼 zhao4zhong1 的回复:内存不够用不会用硬盘吗？ 用硬盘文件读写模拟内存读写，参考_lseeki64函数。 正解！

这种去重不是最适合MapReduce吗

关注一下，看看高手门的解决方案

引用 28 楼 angel_su 的回复:[quote=引用 27 楼 mmns 的回复:] ...楼主的问题其实就是这个，如果hash table中只存行的key及其在目标文件中的偏移，是没有内存问题的。 就这个问题本身来说，数据库不是个好解决方案。 单串6-24，那么20G得假设有1G个不同条目吧，貌似32位下一次性hash一样不够内存吧...[/quote] 极端情况下是的，比如：每20个Byte一行，而且每一行都不一样，而且产生的key也不一样，那确实会产生1G个key，确实会造成内存不够，

引用 9 楼 forcal 的回复:尝试用Lu脚本键树解决这个问题。 参考C/C++使用Lu脚本字符串键树：http://www.forcal.net/bczl/luc/insertkey.htm  9#的代码可改写为： #include <stdio.h> #include "lu32.h"  #pragma comment( lib, "lu32.lib" )  #define key_mystr	(luPriKey_User-20)	//私有键  void main(void) { 	char *StrName[]={"my","you","hello","lu","my","you","hi","lu","my","you","hi","hello","lu",""}; 	int i,k; 	void *NowKey;		//用于返回已存在的键值   	if(!InitLu()) return;	//初始化Lu  	for(i=0;StrName[i][0];i++) 	{ 		//在Lu键树中注册键值，注意参数0表示不更新键值，一定要为0 		k=InsertKey(StrName[i],(luKEY)strlen(StrName[i]),key_mystr,NULL,NULL,NULL,0,&NowKey); 		if(k==0) 		{ 			printf("第一个字符串，需要写盘： %s\n",StrName[i]); 		} 		else if(k==1) 		{ 			printf("重复字符串，忽略： %s\n",StrName[i]); 		} 		else 		{ 			printf("内存错误！由于可以使用虚拟内存，此问题大概不会出现。\n"); 		} 	}  	FreeLu();		//释放Lu }  结果：  第一个字符串，需要写盘： my 第一个字符串，需要写盘： you 第一个字符串，需要写盘： hello 第一个字符串，需要写盘： lu 重复字符串，忽略： my 重复字符串，忽略： you 第一个字符串，需要写盘： hi 重复字符串，忽略： lu 重复字符串，忽略： my 重复字符串，忽略： you 重复字符串，忽略： hi 重复字符串，忽略： hello 重复字符串，忽略： lu   无论多大数据量，以上代码中，InsertKey函数直接进行插入验证，不需要排序，效率极高。但对于大数据量，这段代码运行时唯一的问题是，它会消耗完内存，导致使用硬盘作为虚拟内存，从而运行速度显著变慢。

引用 27 楼 mmns 的回复:...楼主的问题其实就是这个，如果hash table中只存行的key及其在目标文件中的偏移，是没有内存问题的。 就这个问题本身来说，数据库不是个好解决方案。 单串6-24，那么20G得假设有1G个不同条目吧，貌似32位下一次性hash一样不够内存吧...

引用 25 楼 vipcxj 的回复:LZ的最大问题不是这个吧，他的最大问题是数据量太大，内存不够用，大家提议用数据库也是这个考量，虽然数据库慢，但至少对内存需求不会比将所有数据都读进内存那么大。 直接把数据都读入内存??这个不现实的方法是不用考虑的。但数据只要在硬盘上，就没有空间问题，关键就是时间问题。即使你使用数据库，也是数据库存储hash table而已,也不能把整个文件先读入数据库，把20g的数据先读入数据库，然后再让数据库来完成所需的操作，数据库也是要把数据分块并在内存和硬盘之间频繁交换，然后再把整理后库数据存成庞大的目标文件，要花费的时间也是很巨大的。 楼主的问题其实就是这个，如果hash table中只存行的key及其在目标文件中的偏移，是没有内存问题的。 就这个问题本身来说，数据库不是个好解决方案。

引用 24 楼 mmns 的回复:如果你的数据本来就存成了文件，而且目标数据也需要存成文件，那么基本上用数据库意义不大了。 假设不用数据库处理： 即使用数据库，以下两项工作的时间是不能省的： 1. 从原始文件中每次读取一行，直至读完。 2. 把不重复的的行写入目标文件。 下面工作是可以重点优化的步骤，也是核心算法所在： 3. 判断某一行是否已经存在于目标文件中。  一个简单易行的办法是在内存中创建一个hash表，每从源文件中读出一行，就为此行生成一个hash Key, 然后从hash表中查找次key是否存在，如果不存在就说明是没有重复的，可以直接写入目标文件，并把此key及其行在目标文件中的偏移存入hash表。如果次key已经存在，则需通过key从hash表中找到所有具有同一个key的行偏移，然后逐个对比......(你应该明白这个方法的大概步骤了，故此处略去更多说明，)。    关键在于你的hash key的生成算法，直接决定你的效率，在最佳的理想状态下，每一个不同的行生成的key都是不同的，此状态下效率最高。    一般这种问题需要根据文本内容的具体情况来确定hash key的生成算法。 LZ的最大问题不是这个吧，他的最大问题是数据量太大，内存不够用，大家提议用数据库也是这个考量，虽然数据库慢，但至少对内存需求不会比将所有数据都读进内存那么大。

变成数据库好了，不想的话就按某种条件自己分割成小文件，别再合并了，所谓大而无当...

http://www.ideawu.net/blog/ssdb 可以试试这个，SSDB，我虽然没用过，但看介绍，效率还是很高的，并且有能力处理大数据

仅供参考//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }

要是偶尔需要这样处理下，就sort file | unique >newfile 经常这样的话，还得找下大数据排序等方法

引用 1 楼 gz_qmc 的回复:这个可有含量了,不懂帮顶 +1我也不懂，帮顶，瞎说几句，呵呵

引用 12 楼 ALNG 的回复:增大内存和/或配个64G的SSD盘对解决你的问题很有好处 :)  mysql慢有慢的道理，硬件的限制在那里，自己写程序不使用恰当的数据结构可能更慢。 兄弟，看你很赞成用数据库，你认为检查主键比较快吗？还有，把所有数据都插入到数据库，在索引，你认为这个索引能比排序快吗？还有， 1、读取文件 2、写入数据库 3、索引 4、读取 5、写新文件  我不太明白你“初步估计相当于复制2.5次这个文件的耗时”怎么得出的结论，随意说的？

哦，4G内存不算太小，楼主机器的性能也不算太差，也许cat file.txt|sort -n |uniq > output.txt真的可行，那样最省事了。需要多久，试试就知道了。不会少于3-5倍复制时间吧。sort要完成才能够输出给uniq, 怀sort要读完文件才执行sort，因为内存不够，会反复swap,（如果sort保证前面的记录都被正确排序，swap的次数倒会少些, 取决于sort的实现)，uniq倒是简单，就是顺序读一遍。试试不行再自己写。

数据库肯定不行 20G MYSQL撑不住 慢死 除了提高硬件配置，进行分布式处理以外，单机就没有其他办法了吗


Question: 请教个移位<<问题

用对数函数。  引用 楼主 u013390375 的回复:比如，  	DWORD a = 8; 	DWORD b =1<<a;  这样b =256  二进制是100000000（后面a个0）   反过来推算：已知b=256,怎么求a啊？

DWORD b=256 DWORD a=0;  while(b>>1) a++;

__asm { 	bsf eax,b 	mov a,eax }

1）查表 2）循环判断


Question: 关于指针的种种用法

引用 楼主 w82076322 的回复: 这是今天老师讲的几种指针的用法，但是没有理解。 希望各位能够举例子来阐述这几种用法，谢谢各位。 你们的老师这么列出来讲说明教学水平有限啊，还好你没说你们老师介绍了常用的几种指针类型

推荐一个软件cdecl linux下面的 ，自己去学怎么写指针。 很不错

《c和指针》

好多高手 学习了

好吧，不理解就照着老师的代码敲敲

引用 17 楼 wuoomail 的回复:csdn 与国外社区的区别之一是, 回答问题的人喜欢嘲笑提问者来找寻一丝的优越感.  LZ 我不会说你老师讲得不错, 因为你老师的这个讲义我两年前就在网上见过, 我还下载过这个讲义的 pdf 版本, 我觉得这个讲义的原作者是你的老师的概率不大.  对刚开始学的人来说指针之所以难理解是因为我们不理解计算机的地址空间, 我认为这是所有教材的缺陷, 建议 LZ 去浅显的学习一下计算机基本原理和汇编语言, 可以看王爽的那本, 这本书讲了这两点, 非常浅显易懂. 我印象中这本书大约有400页左右吧, 但是相信我, 你只需要从头看完前200页左右, 你就能对指针有一个非常清晰的认识.你说对了，这个讲义的确是我老师从网上下的PDF文档。原作者也的确不是我老师。

引用 24 楼 w82076322 的回复:[quote=引用 17 楼 wuoomail 的回复:] csdn 与国外社区的区别之一是, 回答问题的人喜欢嘲笑提问者来找寻一丝的优越感.  LZ 我不会说你老师讲得不错, 因为你老师的这个讲义我两年前就在网上见过, 我还下载过这个讲义的 pdf 版本, 我觉得这个讲义的原作者是你的老师的概率不大.  对刚开始学的人来说指针之所以难理解是因为我们不理解计算机的地址空间, 我认为这是所有教材的缺陷, 建议 LZ 去浅显的学习一下计算机基本原理和汇编语言, 可以看王爽的那本, 这本书讲了这两点, 非常浅显易懂. 我印象中这本书大约有400页左右吧, 但是相信我, 你只需要从头看完前200页左右, 你就能对指针有一个非常清晰的认识.你说对了，这个讲义的确是我老师从网上下的PDF文档。原作者也的确不是我老师。[/quote] 原作者是谁不要紧，重要的是理解成自己的知识

引用 21 楼 vipcxj 的回复:[quote=引用 17 楼 wuoomail 的回复:] csdn 与国外社区的区别之一是, 回答问题的人喜欢嘲笑提问者来找寻一丝的优越感.  LZ 我不会说你老师讲得不错, 因为你老师的这个讲义我两年前就在网上见过, 我还下载过这个讲义的 pdf 版本, 我觉得这个讲义的原作者是你的老师的概率不大.  对刚开始学的人来说指针之所以难理解是因为我们不理解计算机的地址空间, 我认为这是所有教材的缺陷, 建议 LZ 去浅显的学习一下计算机基本原理和汇编语言, 可以看王爽的那本, 这本书讲了这两点, 非常浅显易懂. 我印象中这本书大约有400页左右吧, 但是相信我, 你只需要从头看完前200页左右, 你就能对指针有一个非常清晰的认识.  LZ贴的压根就不是在讲指针的用法，你竟然还敢说自己了解。LZ贴的是如何理解复杂声明，在C++中，除了"*"还有"&"呢，到时候你是不是的说这就叫引用的用法？[/quote]  理解了指针的本质, 有助于理解各种复杂的用法.

楼主好人a a

引用 17 楼 wuoomail 的回复:csdn 与国外社区的区别之一是, 回答问题的人喜欢嘲笑提问者来找寻一丝的优越感.  LZ 我不会说你老师讲得不错, 因为你老师的这个讲义我两年前就在网上见过, 我还下载过这个讲义的 pdf 版本, 我觉得这个讲义的原作者是你的老师的概率不大.  对刚开始学的人来说指针之所以难理解是因为我们不理解计算机的地址空间, 我认为这是所有教材的缺陷, 建议 LZ 去浅显的学习一下计算机基本原理和汇编语言, 可以看王爽的那本, 这本书讲了这两点, 非常浅显易懂. 我印象中这本书大约有400页左右吧, 但是相信我, 你只需要从头看完前200页左右, 你就能对指针有一个非常清晰的认识.  LZ贴的压根就不是在讲指针的用法，你竟然还敢说自己了解。LZ贴的是如何理解复杂声明，在C++中，除了"*"还有"&"呢，到时候你是不是的说这就叫引用的用法？

指针的用途只有一个，指向某个东西。

这个主要是关于声明的理解吧。我觉得先与什么结合代表什么记住就行了。 比我上课时老师讲的清晰。。。

老师讲得真心不错了。楼主需要些实际动手锻炼一下。

http://bbs.csdn.net/topics/390627329 ↑见过指针的这种用法吗？

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495 //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组指向了一个指针，该指针指向一个函数，该函数的无参数，返回一个指针，该指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*x000)[5];//返回值     char (*(x00)())[5];//函数原型，参数为空，返回值为指针     char (*(*x0)())[5];//数组的元素，是个函数指针     char (*(*x[3])())[5];//是个数组，大小为3      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

你们老师绝对比我当年的老师讲得好，LZ别抱怨了，与其怪你老师不如怪你的领悟力~ 当然有一点LZ你可能搞错了，这些东西讲得不是指针的用法，而是怎么理解C/C++的复杂声明。如果LZ连C/C++的一般声明都看不懂，那你老师讲得再透彻也没用。

你们老师讲的不错，尤其结合的优先级。多看书做练习就明白了。

指针的用法，只有你想不到的，没有他做不到的。你见过有什么变量能给你个地址么。。。

引用 10 楼 u012915226 的回复:int p[3] 是一个有3个元素的整型数组,每个元素是一个整型 例如int p[3]={1,2,3}; p[0]就为1，  p[1]就为2，p[2]就为3 int *p[3]也是一个有3个元素的数组且每个元素是一个整型指针 int (*p)[3]是一个数组的指针 这个指针指向一个有3个整型元素的数组 int p(int)是一个在普通不过的函数罢了 函数名为p 参数为int形 返回值为int 形 int (*p)(int)是一个函数的指针 这个指针指向一个【参数为int 返回为int】的一个函数函数的指针是做什么的？其意义是什么？  数组的指针和直接拿数组地址操作有什么区别？


Question: 关于递归的问题

没有什么问题，就是if少了个等号

第推公式 S1 =1       //n=1 Sn = Sn-1   //n=2,3,4,......  函数 int sum(int n) {     if(n = 1)        return 1;     else         return sum(n - 1)+ n; }  S-->sum n-->n  就是一个简单的替换。 递归训练的时候，可以这么做，不过写代码时，不要这么干 这种简单的递推关系，没有必要递归


Question: 结构体的定义到底是怎么样的？

#include <stdio.h>  typedef struct AA{ 	int val1; }A;//A是变量类型，相当于int,double...  struct BB{ 	int val2; }b;//b是变量，可以直接使用  int main() { 	A a;//由于A只是一个类型，所以必须先声明一个类型为A的变量a;等同于struct AA a; 	a.val1=1;  	b.val2=2;//b是变量，  	return 0; }

typedef struct s { }T; // 等价于 struct s { }; typedef struct s T; 至于如何理解，如果你知道typedef是啥，那就没什么可理解的了。


Question: 我应该深入学习C语言还是开始学习Java   求指教

引用 8 楼 SKATE11 的回复:学C吧 以后的数据结构课程 大都用C来实现   java没有指针我不知道有些数据结构是怎么实现的 不一样的，Java这种重视开发的语言，不需要去了解数据结构是怎么实现的，连一般自己打造容器的机会都比较少。大部分情况下，标准库里的容器都已经够用了。  至于Java里的指针，肯定是有的，只不过被内部隐藏了，外界（开发者）不需要知道。Java这种语言都是用class来实现的，说白了就是C++的引用机制。具体的找本数据结构的书看看就知道了。

引用 6 楼 xiao3404 的回复:java是这几年的趋势，java类的岗位比较多，但相对工资会差那么点，c类工作相比。。。 c语言相对有点难学而已，对应的工资高点，这只是一般情况。。。。。。 其实学java还是学c，与自己的规划有关，毕竟两者的应用领域不同。希望对你有点帮助 我才大一 对于以哪个语言为方向还没想过、 只是想能多学一点、 谢谢前辈指教

这两个在不同领域，你得考虑你想在什么领域下发展。。

引用 11 楼 max_min_ 的回复:http://download.csdn.net/detail/max_min_/6333711 把谭老师的书丢啦，用这本，上面的例程都自己动手敲敲！ 有了c语言基础的话，上手java就比较快！ 惊现版主 受宠若惊  这本书买了、最近在考试 打算寒假了 寒假好好静下心研究研究

学c语言看《The C Programming Language》第二版，绝对经典。

引用 4 楼 baichi4141 的回复:[quote=引用 2 楼 u013389825 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 说得好像专业课你敢不学似的…… 要专精的话，哪个都可以  这种水平的C语言开始学习JAVA会不会很难[/quote] java和c除了一些关键字相同之外，几乎完全不同 如果你的C语言水平很好，反而可能会在学习java时有一定干扰  当然，一个优秀的程序员应该对两者都很熟悉，他山之石可以攻玉嘛 但大多数程序员都只能精通其中一方面，因为一个大脑难以南辕北辙[/quote] 如果寒假开始学习java  看尚学堂的视屏怎么样呢  大婶求推荐几本好的入门书籍

引用 2 楼 u013389825 的回复:[quote=引用 1 楼 baichi4141 的回复:] 说得好像专业课你敢不学似的…… 要专精的话，哪个都可以  这种水平的C语言开始学习JAVA会不会很难[/quote] java和c除了一些关键字相同之外，几乎完全不同 如果你的C语言水平很好，反而可能会在学习java时有一定干扰  当然，一个优秀的程序员应该对两者都很熟悉，他山之石可以攻玉嘛 但大多数程序员都只能精通其中一方面，因为一个大脑难以南辕北辙

引用 2 楼 u013389825 的回复:[quote=引用 1 楼 baichi4141 的回复:] 说得好像专业课你敢不学似的…… 要专精的话，哪个都可以  这种水平的C语言开始学习JAVA会不会很难[/quote] 不会，JAVA不要求操作指针 最初另你感到难的地方会是面向对象，多态，继承

引用 1 楼 baichi4141 的回复:说得好像专业课你敢不学似的…… 要专精的话，哪个都可以  这种水平的C语言开始学习JAVA会不会很难

说得好像专业课你敢不学似的…… 要专精的话，哪个都可以


Question: 关于return的用法求教

#include <stdio.h> #include <string.h>  #define MAXWORLDLEN(len) if(len>20){return -1}   void ReverseStr(char* head, char* tail)   {       while(head < tail)       {           *head ^= *tail;           *tail ^= *head;           *head ^= *tail; 		head++; 		tail--;     }   }  void ReverseSentence(char *s)   {       // 这两个指针用来确定一个单词的首尾边界       char *p = s ;    // 指向单词的首字符       char *q = s ;    // 指向空格或者 '\0'          while(*q != '\0')       {   		bool bIsAlpha = (*q >= 'a' && *q <= 'z' || *q >= 'A' && *q <= 'Z'); 		bool bDouble = (*q == '-' && *(q+1) == '-' ); 		if( !bIsAlpha && *q != '-') 		{ 			ReverseStr(p, q - 1) ;   			*q = ' '; 			q++; 			p = q; 		} 		else if( !bIsAlpha && bDouble) 		{ 			ReverseStr(p, q - 1) ;   			*q++ = ' '; 			*q = ' '; 			q++; 		} 		else 			q++;       }          ReverseStr(p, q - 1) ; // 对最后一个单词逆序       ReverseStr(s, q - 1) ; // 对整个句子逆序(将整个句子看成一个单词)	 }   void main() { 	char src[] = "Test love-you";  	ReverseSentence(src); 	puts(src);  	getchar(); }[code=c][/code]

引用 10 楼 ShaelLancelot 的回复: void fn() {   for(;;)   {     while(1)     {       if(1 == 1){return;}     }   }  }  当执行return时，就直接跳出当前执行的函数fn了。 如果是递归的话，只跳出当前执行的fn函数，父fn函数还会继续执行。+1

我觉得用goto是恰到好处！

return 可以说是一种特殊的退出代码，指的是：“返回某个值” 使用方法是： return 常量、变量或表达式；   return可以嵌套在if和switch中使用： 例如： if(a > b) return a; else return b;  //这里的意思是，如果a比b大，那就返回a的值；否则（指的就是a小于或者等于b）返回b的值 //返回的值是返回给调用的变量或者函数，可以作为递归调用   注意的是：一个函数只能return一个值，就是说，不能多个返回多个调用！[b] [/b]

return的功能有两个：1.返回值; 2.返回控制。对于有返回值的函数，使用return，两个功能都用到了。而对于无返回值的函数，return也可以用，不过它只用来返回控制，当我们的代码运行到一个地方，我们确认后面的代码不需要再继续进行下去了，就可以使用return直接结束这个函数(被调用函数)，并返回控制权给调用函数。

最好不要使用goto了，跳来跳去的，你写这样的代码，以后维护自己都摸不清程序的执行顺序，如果是别人来维护你会被骂死

像一些多重循环中想要直接跳出执行一段代码，就用goto呀，而不会一层一层的break

那些循环从上往下缕 遇到return就返回 相关函数就执行到那

goto和全局变量是衡量你c语言能力的重要标志之一~~~

引用 7 楼 w82076322 的回复:[quote=引用 5 楼 missheaven2011 的回复:] [quote=引用 3 楼 w82076322 的回复:] [quote=引用 2 楼 a345485527 的回复:]  ？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？[/quote] 返回到调用该函数的地方去了，goto只能在函数内部调用[/quote]也就是说goto语句不能从一个子函数跳到另一个子函数或主函数？[/quote] 不能，有兴趣你可以测试一下，这样印象深刻点，函数间跳跃可以用setjump和longjump实现

引用 5 楼 missheaven2011 的回复:[quote=引用 3 楼 w82076322 的回复:] [quote=引用 2 楼 a345485527 的回复:]  ？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？[/quote] 返回到调用该函数的地方去了，goto只能在函数内部调用[/quote]也就是说goto语句不能从一个子函数跳到另一个子函数或主函数？

引用 4 楼 jerry_dqh 的回复:[quote=引用 3 楼 w82076322 的回复:] [quote=引用 2 楼 a345485527 的回复:]  ？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？[/quote]  return 直接函数返回了，goto你想怎么用呢，麻烦啊[/quote]那代码中return的-1给了谁呢？系统？ 我看《C语言入门经典》中讲的如果跳出多重循环可以直接使用goto语句跳到想到达的地方。

引用 3 楼 w82076322 的回复:[quote=引用 2 楼 a345485527 的回复:]  ？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？[/quote] 返回到调用该函数的地方去了，goto只能在函数内部调用

引用 3 楼 w82076322 的回复:[quote=引用 2 楼 a345485527 的回复:]  ？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？[/quote]  return 直接函数返回了，goto你想怎么用呢，麻烦啊

引用 2 楼 a345485527 的回复:？？  int foo() {         for(int i=0;i<10;i++) 		for(int j=0;j<10;j++) 			return -1;//函数在这里直接返回了  	return 0; } 请问在这里返回到哪里去了？为什么不使用goto语句呢？

return用于结束一个函数 需要返回值的，把返回值放在return语句中，不需要返回值的，直接return;即可


Question: 看看这段代码，为什么输出结果会是这样的啊？

首先，你没有对t赋值！！！！而且t也没有赋初值！这样的话t变量在内存中的数值就会飘忽不定！   #include<stdio.h>   /** 输出: 2003778602 **/ int main() {     int i,a[1],t;     i=0;     t = 2003778602;     printf("%d\n",t);     return 0; }         /** 输出: 1 **/ int main() {     int i,t;     i=0;     t = 1;     printf("%d",t);     return 0; }           /** 输出: 0 **/ int main() {     int t;     t = 0;     printf("%d",t);     return 0; }   可以弱弱说一句吗？你的代码里面i和数组a[i]没用啊

误解大家的意思了  引用 11 楼 lin5161678 的回复:[quote=引用 10 楼 u011569364 的回复:] 不是随机的吧，是分配给t的内存里原来的数据。PS:纠结这个问题真的很无聊。大家的随机表达的就是这个意思  的确是t的内存存放的数据  但是这个数据对程序员来说是不可控的  和随机没什么区别[/quote]

引用 10 楼 u011569364 的回复:不是随机的吧，是分配给t的内存里原来的数据。PS:纠结这个问题真的很无聊。大家的随机表达的就是这个意思  的确是t的内存存放的数据  但是这个数据对程序员来说是不可控的  和随机没什么区别

不是随机的吧，是分配给t的内存里原来的数据。PS:纠结这个问题真的很无聊。

这个我也试了一下，不过我这里 三个全是随机数！ 所以说 这个问题没有什么意思！

引用 2 楼 u013078986 的回复:[quote=引用 1 楼 user-11 的回复:] 与编译器有关 不是，我三段代码是在同一个编译器下运行的[/quote] 你把这3个代码都换个编译器，结果就和这个不同了

引用 4 楼 therry_ding 的回复:因为你没有初始化变量，变量所指向的内存是个垃圾数据，什么都有可能，所以会输出不同的值。 +1，引用未初始化变量是未定义行为

没啥意思，lz不用纠结于这个问题

t没有初始化，也就是没有负值，当你要输出t时，系统会随机产生一个整数输出

引用 1 楼 user-11 的回复:与编译器有关 不是，我三段代码是在同一个编译器下运行的

与编译器有关


Question: *************** 有关变长数组 *******************

引用 7 楼 taodm 的回复:能给的建议是：几乎永远不要使用变长数组。 尤其你这样业余玩票的，只能使用C89标准语法。  谢谢你的建议。另外编译器正确实现c11标准的变长数组，为什么不要用呢？

好像都没有回答的我问题啊。

引用 4 楼 gz_qmc 的回复:楼主 不是我说你  不学汇编 真的是你们的遗憾  你追求了半天 我就不信电脑就凭空生出个变长数组功能指令来 编译最后还是要转成定长数组加上一些灵活处理的代码 写编译器那家伙 他写的数组处理代码就一定比你自己写的好吗?  你宁愿花10倍的时间去追求那些东西 何不花1倍的时间用熟数据结构呢?  感谢回复，我的主要工作是开发web应用，学c只是个人爱好。 你也知道，你学会一门语言，如果超过1个月不用，就会忘记20%左右，再过一段时间不用，忘记的会更多。 平时我使用高级语言，用不到汇编，但并不说明汇编不重要。

IDE是IDE，编译器是编译器。

引用 1 楼 q745401990 的回复:我一般用c/c++来练习数据结构和算法，用的编译器是VC++ 6.0和dev-cpp，做开发的话，开发需要什么语言和编译器就用什么...  楼主没有必要纠结IDE，和某些变长或者不变长之类的，你刚说的即使它不是变长的，我依旧可以用malloc来开辟......  感谢回复 ，我的看法是新标准的制定就了为了弥补老标准的不足，而且可以提供更好的一些解决相同问题的更好方法


Question: 求教一个关于C语言数据溢出的检验程序问题和setjmp函数，有代码

引用 13 楼 znzp124900171 的回复:[quote=引用 12 楼 ALNG 的回复:] 内积的问题我似乎直接已经帮你改了，参我的修改代码。直接把每个相乘的一个运算数升级为double, 这样都成了double的乘和加，考虑到输入范围，溢出已经不可能了。  我的题目中要求要考虑到一些自定义范围，因为对于一些参数，比如滤波器参数等等，其处理的数据能力是有限的，所以当C语言在转换数据的过程当中，不可避免的会出现一些编译器无法发现的数据丢失，扩大数据的范围肯定能避免溢出，但是有时候数据的范围比较小，比如int，大部分数模转换器的数据类型都是int，那么在处理它们的过程中，溢出就会严重影响精度和结果，是这个意思。[/quote]  嗯，我知道你的意思了。如果更大的数据类型不存在或不方便，那只有依赖具体的检测。举个例子，假如你已经使用了C内建支持的最大的整数类型并不想使用自定义的大整数运算，而要计算整型的内积(不升级为double), 可以处理如下 typedef struct _Point{     long long x,y,z; }Point;  long long InnerProduct(const Point* p1, const Point* p2) {     long long _x, _y, _z, rslt;      _x=p1->x*p2->x;      if(p1->x && _x/p1->x!=p2->x)         longjmp(jump_buffer, 3);      _y=p1->y*p2->y;     if(p1->y && _y/p1->y!=p2->y)         longjmp(jump_buffer, 3);      _z=p1->z*pz->z;     if(p1->z && _z/p1->z!=p2->z)         longjmp(jump_buffer, 3);      rslt=_x+_y;     if( ((_x<0)^(_y<0)==0) && //both negative or both non-negative            (_x<0 && rslt>_x || // two negative number should add to a smaller rslt without overflow        _x>0 && rslt<_x) // 2 positive number should add to a bigger rslt without overflow     )         longjmp(jump_buffer, 3);           _x=rslt;     rslt+=_z;        if( ((_x<0)^(_z<0)==0) && //both negative or both non-negative            (_x<0 && rslt>_x || // two negative number should add to a smaller rslt without overflow        _x>0 && rslt<_x) // 2 positive number should add to a bigger rslt without overflow     )         longjmp(jump_buffer, 3);      // all overflow cases have been taken care of     return rslt; }

引用 12 楼 ALNG 的回复:内积的问题我似乎直接已经帮你改了，参我的修改代码。直接把每个相乘的一个运算数升级为double, 这样都成了double的乘和加，考虑到输入范围，溢出已经不可能了。  我的题目中要求要考虑到一些自定义范围，因为对于一些参数，比如滤波器参数等等，其处理的数据能力是有限的，所以当C语言在转换数据的过程当中，不可避免的会出现一些编译器无法发现的数据丢失，扩大数据的范围肯定能避免溢出，但是有时候数据的范围比较小，比如int，大部分数模转换器的数据类型都是int，那么在处理它们的过程中，溢出就会严重影响精度和结果，是这个意思。

对了，一个小建议。 sizeof(Point)=6， 传值调用在32位平台上可能稍微昂贵一些，可以考虑吧Add, Substra, Multiply的原型设计成类似  void Add(const Point* p1, const Point* p2, Point* rslt);  当然，不改问题也不大。

引用 9 楼 ALNG 的回复:太谢谢你了，例子十分清楚，容我追加一个问题，就是乘法的溢出，代码中我没有处理乘法部分是因为我还没弄明白如何处理他们？你有好的建议吗？尤其是对于带符号的向量，内积中可能会有一部分的乘法结果溢出，但是有负值的话，最后求得的内积的和还是有可能在范围内，导致加减法溢出的检验方法不适用。  =============== 一样啊。用一个更大的类型，比如int, 如果计算的结果超出了short的范围，则溢出。代码几乎一模一样，两overflow函数都是重用的。 void Multiply(Point p1, Point p2, Point* rslt) {    int x=(int)p1.x*p2.x;    int y=(int)p1.y*p2.y;    int z=(int)p1.z*p2.z;     if(overflow(x) || overflow(y) || overflow(z))        longjmp(jump_buffer, 3); // suppose we decide to differentiate MULTIPLY overflow    rslt->x=(short)x;    rslt->y=(short)y;    rslt->z=(short)z; }  随手敲的，不保证能够运行。意思在那里了。  十分感谢，问题解决，结贴

switch(setjmp(jump_buffer))     {     case 0: { 天，case 0: 后面的那个 { 多余，要去掉才能正常编译。

引用 6 楼 ALNG 的回复:一个是VC++ 12 32位的编译器，一个是g++ 4.8.2 64位的编译器.  对了上面那个while(getchar()!='\n');可以去掉，虽然无关紧要。  longjump应该放在Add, Substract和其他实现某个可能导致溢出或其他错误的函数代码中，这样的实现才有使用价值。本质上实现了类似C++ try{}catch(Exception1&){}catch(Exception2&){}的功能。这里不同的exception用一个非0的整型值来表示，再在我的示例中switch的不同分支来处理。为了展示longjmp的第二个参数的意义，我特意区分了加法溢出和减法溢出，实际应用中这个区分并无意义。  太谢谢你了，例子十分清楚，容我追加一个问题，就是乘法的溢出，代码中我没有处理乘法部分是因为我还没弄明白如何处理他们？你有好的建议吗？尤其是对于带符号的向量，内积中可能会有一部分的乘法结果溢出，但是有负值的话，最后求得的内积的和还是有可能在范围内，导致加减法溢出的检验方法不适用。

我把你的代码稍微改了一下，希望有助于你理解setjmp和longjmp： // //  main.c //  Bachelorarbeit // //  Created by Nan on 1/1/14. //  Copyright (c) 2014 Nan. All rights reserved. //   #include <stdio.h> #include <setjmp.h>   jmp_buf jump_buffer;   typedef struct Vektor{     short int x,y,z; }Point,*pPoint;   void Input(pPoint p) {     printf("please enter the value of x :");     scanf("%hd",&(p->x));     printf("please enter the value of y :");     scanf("%hd",&(p->y));     printf("please enter the value of z :");     scanf("%hd",&(p->z)); }     //Skalarprodukt double Inner(Point p1,Point p2) {     return (double)p1.x*p2.x+(double)p1.y*p2.y+(double)p1.z*p2.z; }   static int overflow(int x) { 	return x>32767 || x<-32768; }   //Addition void Add(Point p1,Point p2,Point *p3) { 	int x=(int)p1.x+p2.x; 	int y=(int)p1.y+p2.y; 	int z=(int)p1.z+p2.z; 	if(overflow(x) || overflow(y) || overflow(z)) 		longjmp(jump_buffer, 1);     p3->x=(short)x;     p3->y=(short)y;     p3->z=(short)z;      }   //Subtraktion void Subtra(Point p1,Point p2,Point *p4) { 	int x=(int)p1.x-p2.x; 	int y=(int)p1.y-p2.y; 	int z=(int)p1.z-p2.z; 	if(overflow(x) || overflow(y) || overflow(z)) 		longjmp(jump_buffer, 2);      p4->x=(short)x;     p4->y=(short)y;     p4->z=(short)z; }   void show_point(Point p) {     printf("(%.3d,%.3d,%.3d)", p.x, p.y, p.z); }   int main() {       Point p1, p2, p3,p4;           switch(setjmp(jump_buffer))     {     case 0: {         printf("\n*******input p1*******\n"), Input(&p1);         printf("\n*******input p2*******\n"), Input(&p2);         Add(p1, p2, &p3);         Subtra(p1, p2, &p4);         puts("\n=======result=======");         printf("\ninner: %.3lf", Inner(p1, p2));         printf("\nadd:"), show_point(p3);         printf("\nmin:"), show_point(p4);       	break;     case 1:     	printf("Addition overflow!\n");     	break;     case 2:     	printf("Substraction overflow!\n");     	break;     } //    while(getchar()!='\n');      puts("\npress enter to exit.\n");     getchar();     return 0; }

引用 2 楼 ALNG 的回复:g++ 4.8 64bit下测试也通过了。  你用的编译器？  不好意思，忘了引用你的回复

我试了两个，win下是DEV C++，然后mac下用的xcode，最后跳转后都是不停的重复printf的内容，之前我在else语句中加了longjmp(jump_buf,0),意思是想如果出现溢出，就在报错后再跳回去，重新输入point的值，之前测试了一下成功了，但是不知道怎么着就不行了，我把代码贴出来   // //  main.c //  Bachelorarbeit // //  Created by Nan on 1/1/14. //  Copyright (c) 2014 Nan. All rights reserved. //  #include <stdio.h> #include <setjmp.h>  jmp_buf jump_buffer;  typedef struct Vektor{     short int x,y,z; }Point,*pPoint;  void Input(pPoint p) {     printf("please enter the value of x :");     scanf("%hd",&(p->x));     printf("please enter the value of y :");     scanf("%hd",&(p->y));     printf("please enter the value of z :");     scanf("%hd",&(p->z)); }   //Skalarprodukt double Inner(Point p1,Point p2) {     return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z; }  //Addition void Add(Point p1,Point p2,Point *p3) {     p3->x=p1.x+p2.x;     p3->y=p1.y+p2.y;     p3->z=p1.z+p2.z; }  //Subtraktion void Subtra(Point p1,Point p2,Point *p4) {     p4->x=p1.x-p2.x;     p4->y=p1.y-p2.y;     p4->z=p1.z-p2.z; }  void show_point(Point p) {     printf("(%.3d,%.3d,%.3d)", p.x, p.y, p.z); }  int main() {      Point p1, p2, p3, p4;          if (setjmp(jump_buffer)==0) {         printf("\n*******input p1*******\n"), Input(&p1);         printf("\n*******input p2*******\n"), Input(&p2);         Add(p1, p2, &p3);         Subtra(p1, p2, &p4);         if(p3.x!=(p1.x+p2.x)){             longjmp(jump_buffer, 1);         }         puts("\n=======result=======");         printf("\ninner: %.3lf", Inner(p1, p2));         printf("\nadd:"), show_point(p3);         printf("\nmin:"), show_point(p4);      }     else{         printf("\n*******the result is overflow,pleas check your input and enter the value again*******\n");          longjmp(jump_buff,0);     }          while(getchar()!='\n');     puts("\npress enter to exit.\n");     getchar();     return 0; }

g++ 4.8 64bit下测试也通过了。  你用的编译器？

我用VS 2013 express的编译器运行无误, 参截图:


Question: 求大神帮忙求解指针数组

数组名当函数参数传入的时候 弱化成指针 也就是相当于那个函数只接受了你数组的首地址当作参数

楼上正解，数组名是常量，不能进行++操作。只有变量才可以！

数组名是个常量

第二个初始化，应该是  char **ch=a; 这样++ch 是没问题的。 或者，也可以这么初始化； 1） char *ch[3]={a[0],a[1],a[2]}; 2） char *ch[3];  ch[0]=a[0];  ch[1] = a[1];  ch[2] = a[2];   不过没有意义，而且 ++ch 同样是错误的  char *ch[3]; ch=a; 是错误的，C,C++数组不可整体赋值。 其他参见1楼，2楼。

数组名和数组首地址的区别  搜一下

同意楼上的说法  数组名字 是代表的数组   值是第一个元素的地址  数组的名字是固定的 不可以进行++之类的操作 因为++之类的操作改变了值    用函数调用  char *argv[] 其实跟 char** argv 没有区别 ,  argv是一个二级指针  由于函数参数进行的是传值调用  就是 把数组的值 也就是第一个元素的地址 赋值给 argv的二级指针  argv当然是可以变化的

数组名作为参数就相当于指针， 你有见过给数组名++的吗？数组访问还是使用下标


Question: 新手分不多 真心求帮忙啊 有关c语言

不知道你们有没有编程语言的限制，感觉这个如果用VB的话实现起来超简单，VC数据库操作比较麻烦。

天啊，楼主你做完没有？坑爹啊，求拯救啊。   我是图书管理系统

引用 11 楼 xinhua0910 的回复:这里只能给你建议了，给个相对简单的 1. 用纯C的话，你可以把电影信息写到一个文件file1，用“|”或者其他符号分隔，起到一个数据库的作用，存储你的电影信息 2. 每次一执行文件就把所有信息读到数组结构体中，或者放到链表中 3. 添加就是把从屏幕读到信息加到数组中 4. 修改、删除就是把数组信息对应给处理掉 5. 什么个人列表之类的就是写到另外一个文件file2，到时就根据file1、file2的内容就可以取到电影列表信息了 6. 如果退出的话，那就把你的数组信息写到文件中  当然，你也可以每一个操作都直接操作文件，只是会麻烦一点。慢慢做，做完会很有成就感的  谢谢啦 能把你QQ给我一下 我想遇见问题的时候请教你一下 `(*∩_∩*)′

[quote=引用 8 楼 benbudong 的回复:] [quote=引用 楼主 u013369893 的回复:] 都大二了编程能力实在是不行 果然女的不适合干这一行！！求大神帮我做一个纯c的程序   但是只能用纯c做啊  用到文件就行不用连接数据库什么的。

但是只能用纯c做啊  用到文件就行不用连接数据库什么的。

引用 楼主 u013369893 的回复:都大二了编程能力实在是不行 果然女的不适合干这一行！！求大神帮我做一个纯c的程序   ：图书管理程序 功能要求： 1．添加图书：书名、作者、出版社、分类（计算机、数学、文学等）、数量、简介等； 2．修改/删除：可以修改图书的相关信息； 3．查询：按书名、作者、分类等信息进行查询； 4．记录每天图书借出/归还情况； 5．查询统计每月借阅次数最多（时长最长）的图书，降序显示每月哪类图书借阅次数最多（时长最长）。  假期工程实践 做不完寒假就放不了假！！可怜可怜我吧  求大神求好心人  我想回家过年。

差不多就数据库操作～可看下相关c++操作数据库的文章

引用 5 楼 u013369893 的回复:[quote=引用 4 楼 zyx6a 的回复:] [quote=引用 3 楼 u013369893 的回复:] [quote=引用 1 楼 zyx6a 的回复:] 这类的代码网上应该有很多，http://blog.csdn.net/yueguanghaidao/article/details/7605283这是我随便找的一篇文章，你可以参考的改一改   贴错了 我要做的应该是    电影文件管理程序 功能要求： 1．添加电影：电影名称、主演、导演、分类（动作、爱情、恐怖等）、电影简介、电影文件路径等； 2．修改/删除：可修改电影的相关信息，可删除电影； 3．查询电影：全部查询，也可按电影名称、主演、导演或分类查询，显示所有符合条件的电影信息； 4．创建个人喜好播放列表：将个人喜欢（想看）的电影排列入该列表； 5．查询播放列表：选择播放列表的电影可以查询该电影的相关信息。  就是一直没有在网上找到模板[/quote] 这两个也没什么区别呀，换汤不换药嘛[/quote]   可以给我你的QQ吗？  我想遇到问题的时候问一下你 谢谢啦[/quote] 835248789

引用 4 楼 zyx6a 的回复:[quote=引用 3 楼 u013369893 的回复:] [quote=引用 1 楼 zyx6a 的回复:] 这类的代码网上应该有很多，http://blog.csdn.net/yueguanghaidao/article/details/7605283这是我随便找的一篇文章，你可以参考的改一改   贴错了 我要做的应该是    电影文件管理程序 功能要求： 1．添加电影：电影名称、主演、导演、分类（动作、爱情、恐怖等）、电影简介、电影文件路径等； 2．修改/删除：可修改电影的相关信息，可删除电影； 3．查询电影：全部查询，也可按电影名称、主演、导演或分类查询，显示所有符合条件的电影信息； 4．创建个人喜好播放列表：将个人喜欢（想看）的电影排列入该列表； 5．查询播放列表：选择播放列表的电影可以查询该电影的相关信息。  就是一直没有在网上找到模板[/quote] 这两个也没什么区别呀，换汤不换药嘛[/quote]   可以给我你的QQ吗？  我想遇到问题的时候问一下你 谢谢啦

引用 3 楼 u013369893 的回复:[quote=引用 1 楼 zyx6a 的回复:] 这类的代码网上应该有很多，http://blog.csdn.net/yueguanghaidao/article/details/7605283这是我随便找的一篇文章，你可以参考的改一改   贴错了 我要做的应该是    电影文件管理程序 功能要求： 1．添加电影：电影名称、主演、导演、分类（动作、爱情、恐怖等）、电影简介、电影文件路径等； 2．修改/删除：可修改电影的相关信息，可删除电影； 3．查询电影：全部查询，也可按电影名称、主演、导演或分类查询，显示所有符合条件的电影信息； 4．创建个人喜好播放列表：将个人喜欢（想看）的电影排列入该列表； 5．查询播放列表：选择播放列表的电影可以查询该电影的相关信息。  就是一直没有在网上找到模板[/quote] 这两个也没什么区别呀，换汤不换药嘛

引用 1 楼 zyx6a 的回复:这类的代码网上应该有很多，http://blog.csdn.net/yueguanghaidao/article/details/7605283这是我随便找的一篇文章，你可以参考的改一改   贴错了 我要做的应该是    电影文件管理程序 功能要求： 1．添加电影：电影名称、主演、导演、分类（动作、爱情、恐怖等）、电影简介、电影文件路径等； 2．修改/删除：可修改电影的相关信息，可删除电影； 3．查询电影：全部查询，也可按电影名称、主演、导演或分类查询，显示所有符合条件的电影信息； 4．创建个人喜好播放列表：将个人喜欢（想看）的电影排列入该列表； 5．查询播放列表：选择播放列表的电影可以查询该电影的相关信息。  就是一直没有在网上找到模板

图书管理系统源码


Question: 我写的辗转相除法，不知道为什么输不出结果来，看了半天也没发现问题

scanf("%d%d\n",&a,&b);//这里去掉\n，改成scanf("%d%d",&a,&b);


Question: 要开始找工作了，求各位前辈给点面试经验！！！

引用 1 楼 qq120848369 的回复:打铁还需自身硬，三本必读的书籍：UNIX环境高级编程 UNIX网络编程卷1+2 TCP协议详解卷1 这基本书是好书，我都有，不过作为应届毕业生，看这些书多找工作帮助不大。效果不明显： 推荐你基本数，林锐博士的C/C++高质量编程指南，C/C++求职宝典，解开C语言面试的秘密 高级一点的可以看看剑指offer 书名不一定完全准确，你可以搜搜

我也说一点，但是不是技术方面的：当你没有拿到书面的offer前，不要为这个口头的offer做任何决定，否则吃亏的只能是你自己，切记！！！本屌经历过两次，非常非常痛的领悟……

还是把基础做好吧，多数面试是以笔试开始的，笔试很多都是基础题，还有一些编程题。当然，还有一些智力题！

引用 1 楼 qq120848369 的回复:打铁还需自身硬，三本必读的书籍：UNIX环境高级编程 UNIX网络编程卷1+2 TCP协议详解卷1这就能把持得住？

关键是笔试

看笔试面试题就足够了

那要看你的定位是什么样的了，大公司的话那还是抓紧时间看看数据结构 和linux c 把

找一些linuxC的一些面试题目看看！ 估计就是问 c的一些基础知识， 然后Linux下vim的这些操作！  对应届生 要求应该不会很高，除非面试的比较好的IT公司

我是去年刚刚毕业的，找工作的时候还是要多看看笔试题，C语言的基础题，Linux的基本命令，数据结构还是要好好看看的，我面试时候基本都会问到数据结构的问题，再就是要根据你具体面试的公司要求，有针对性的准备下，比如网络或者数据库，或者其他的


Question: 为什么我的就不显示  DOWN  哪里错了

我把你的代码稍稍整理了一下，功能上是相同的: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> typedef struct _proc {     char name[32];           /*定义进程名称*/     int cylinder;                /*定义柱面号*/     int track;                  /*定义磁道面号*/     int rec;                 /*定义记录号*/     struct _proc *prior;     struct _proc *next; }PRO;       PRO *g_head=NULL,*g_curr=NULL,local/* no need to dynamically allocation local*/; int g_cylinder=0;                       //初始柱面号 int direction=1;                          //初始方向 int rec0=0;                        //初始记录号  // Add a new process with given parameters to the end of the  // global doubly linked list pointed by g_head //  void AddProcess(const char * name, int cylinder, int track, int rec) { 	PRO * p=(PRO*)malloc(sizeof(PRO)); 	strcpy(p->name, name); 	p->cylinder=cylinder; 	p->track=track; 	p->rec=rec; 	p->next=NULL; 	 	// should use a PRO* to point to the tail, or is g_curr designed for that purpose?? 	PRO** c=&g_head, *prior=NULL; 	while(*c) 		prior=*c, c=&(*c)->next;  	*c=p; 	p->prior=prior; 	printf("AddProcess %s, prior is %p\n", p->name, p->prior); }  // PRO as per its definition, can be copied bitwise void CopyProcess(PRO* dest, const PRO* src) { 	memcpy(dest, src, sizeof(PRO)); }  // Remove an existing PRO node from the double list pointed by g_head; // void RemoveProcess(PRO * p) { 	PRO * prev, *next; 	// FOR DEBUG 	printf("RemoveProcess:%s, %p, %p\n", p->name, p->prior, p->next); 	prev=p->prior; 	next=p->next; 	if(prev) 		prev->next=next; 	else // is the first node 		g_head=next; 	 	if(next) 		next->prior=prev; 	 	free(p); }   void init() { 	AddProcess("P1", 1, 2, 0); 	AddProcess("P2",2,3,3); 	AddProcess("P3", 3,5, 5); 	AddProcess("P4", 4, 5, 1); 	AddProcess("P5", 3, 5, 1); 	AddProcess("P6", 2, 5, 1);       	memset(&local, 0, sizeof(PRO));     strcpy(local.name, "P0"); }         void PrintInit()                                 /*打印I/O表*/ {     PRO *t = g_head;     printf("Current I/O table is：\n");     printf("         **********************************\n");     printf("         ");     printf("*Process   Cylinder   Track   Record*\n");     while(t!=NULL)     {         printf("         *%4s %8d %8d %5d    *\n", t->name, t->cylinder, t->track, t->rec );         t = t->next;     }     printf("         **********************************\n");     printf("Most recently disptached process:\n");     printf(" Process  Cylinder  Track  Record\n");     printf("%7s %8d %7d, %8d\n\nCurrent direction: %s\n---------------------\n", local.name, local.cylinder,     	local.track, local.rec, direction?"UP":"DOWN" ); }         void acceptreq()                        /*接受请求函数*/ {     PRO p;     printf("please input the information of the new process\n");     printf("Process:");     scanf("%s",p.name);     printf("Cylinder(0-199):");     scanf("%d",&p.cylinder);                    /*输入请求进程信息*/     printf("Track(0-20):");     scanf("%d",&p.track);     printf("Record(0-7):");     scanf("%d",&p.rec);     getchar();     AddProcess(p.name, p.cylinder, p.track, p.rec); }         void qddd()                         /*驱动调度函数*/ {     PRO *out, *p;     int deng=0;     int deng1=0;     int min;     int max;  	if(!g_head) 	{ 		printf("\n\n***Cannot disptach with an empty I/O table!***\n\n"); 		return; 	} 	     min=g_head->cylinder;     max=g_head->cylinder;       for (p=g_head;p!=NULL;p=p->next)     {         if(p->cylinder==g_cylinder)         {             min=p->rec;             out=p;             deng=1;             break;         }     }     switch(deng)     {     case 1:         for (p=g_head;p!=NULL;p=p->next)         {             if(p->cylinder==g_cylinder&&abs(p->rec-rec0)<=abs(min-rec0))             {                 min=p->rec;                 out=p;             }         }         break;     case 0:         switch (direction)         {         case 1:             for (p=g_head;p!=NULL;p=p->next)             {                 if (p->cylinder > g_cylinder)                 {                     min = p->cylinder; // what's the purpose of min? value assigned here never used later                     deng1=1;                     break;                 }             }             switch(deng1)             {             case 1:                 for (p=g_head;p!=NULL;p=p->next)                     {                         if (min>=p->cylinder&&p->cylinder>g_cylinder)                         {                             min=p->cylinder;                             out=p;                         }                     }                     break;             case 0:                 direction=0;                 for (p=g_head;p!=NULL;p=p->next)                 {                     if (max<=p->cylinder)                     {                         min=p->cylinder;                         out=p;                     }                 }                 break;             }             break;         case 0:             for (p=g_head;p!=NULL;p=p->next)             {                 if (p->cylinder < g_cylinder)                 {                     max = p->cylinder;                     deng1=1;                     break;                 }             }             switch(deng1)             {             case 1:                 for (p=g_head;p!=NULL;p=p->next)                     {                         if (max<=p->cylinder&&p->cylinder<g_cylinder)                         {                             max=p->cylinder;                             out=p;                         }                     }                     break;                 case 0:                     direction=1;                     for (p=g_head;p!=NULL;p=p->next)                     {                         if (min>=p->cylinder)                         {                             min=p->cylinder;                             out=p;                         }                     }                     break;             }             break;         }         break;     }     CopyProcess(&local, out);     RemoveProcess(out);     g_cylinder = local.cylinder;     rec0=local.rec; }     // prompt for user input // 0: 驱动调度 // 1： 接受请求 // other: exit void acceptinput()                             /*通过输入0或1选择‘驱动调度’或是‘接受请求’*/ {     int num, done;     do     {         printf("Please enter an integer to choose action to be taken: \n");         printf("0:Accept Request;    1:Driver Dispatch;    otherwise: Exit\n");         printf("num:");         scanf("%d",&num);         done=0;         switch(num){         case 1:    /*驱动调度*/             printf("----------------------------\n");             printf("Dispatching...\n");             qddd();                          /*调用函数进行调度*/ 			break; 		case 0: /*接受请求*/             printf("---------------------------------\n");             printf("Adding a new request...\n");             acceptreq();             break;         default:         	return; 		}         PrintInit();     }while(true); }         int main ()                           /*主程序*/ {     init();     PrintInit();     acceptinput();     return 0; }  注意，你的调度程序保证了柱面小的进程总是优先被调用，这样第172到174行的代码，转贴如下              {                 if (p->cylinder > g_cylinder)                 {                     min = p->cylinder; // what's the purpose of min? value assigned here never used later                     deng1=1;                     break;                 }             } 这个判断总是为真(p->cylinder等于g_cylinder的情形在157-164行处理了), 这样deng1永远不会为0，从而方向永远没有机会改变，总是输出为UP。 这是个逻辑错误，如果你贴出你的qddd的调度算法的描述或伪码，大家会更容易找出问题。  你的代码中修改的部分，比如local直接用一个全局PROC对象而非指针，g_head->next大部分替换为个g_head, 插入节点、删除节点、复制节点的代码抽取出来成为独立的函数等，我个人觉得是更好的设计。为了我个人的理解，对象名也通过查找替代整理了一下，如果原来的名字更方便你自己理解，当然应该保留。  不好意思，C我也不算熟，如果口气有点托大，请谅解。


Question: 关于c语言文件操作-使用a+模式打开

我也刚刚发现，你说的很对！谢谢了

a+表示用附加方式打开可读写的文件，即文件被打开时，文件的访问指针是在结尾，所以fgetc读取返回-1。而r+开打文件时，指针是在文件开头的，不一样。


Question: 关于获取窗口句柄的问题

引用 4 楼 jerry_dqh 的回复:有一个getchar,你的hello已经结束了，获取不到了。如果没有getchar,程序直接往下执行，这时候hello这个进程还没有来得及结束掉。当然也有可能你不加getchar，在下一句获取handle的时候也已经结束了。你将getchar换成sleep(2000)，你也获取不到句柄了。++

没有getchar,阻塞本进程，  引用 2 楼 wangli1000000 的回复:[quote=引用 1 楼 xihu1364 的回复:] [quote=引用 楼主 wangli1000000 的回复:] 如下：   #include <stdio.h> #include <windows.h>   int main(void) {          HANDLE hOut;                                       ShellExecute(NULL,"open","E:\\Hello.exe",NULL,NULL,SW_SHOWNOACTIVATE);  getch();     hOut=FindWindow(NULL,"E:\\Hello.exe");  /*获得窗口句柄*/     printf("%ld ",hOut);     getch();     PostMessage(hOut,WM_CLOSE,0,0);                exit(0);      }   有 getch(); 时，就能获取句柄；当把getch();删除后，句柄就为0了。请问为什么？谢谢。  没有getch();这个程序就直接将E:\\Hello.exe程序的句柄给关掉了（PostMessage(hOut,WM_CLOSE,0,0);）  getch();起的作用就是让程序停在这里。让你看见打印出来的句柄printf("%ld ",hOut);  你可以用while （1）｛Sleep（1000）;｝代替getch(); 这样也可以看到打印句柄[/quote]   没说清楚，我说的是ShellExecute 语句后的getch(); 不是第二个getch() .[/quote] 如果没有shellexecute后面阻塞一下，这个shellexecute本身的程序还没来得及把新的进程 创建出来，你就直接FindWinodws是找不到的，你阻塞一下那么Shellexecute的新进程就有足够时间 把新进程创建出来。因为Shellexecute本身是异步的。

原因很简单，ShellExecute返回是很快的，如果没有getch让程序停在那，就会立刻执行下一句FindWindow。但是此时ShellExecute所打开的程序的窗口甚至都没创建出来，自然是什么都find不到喽，所以就返回０，但有了getch，就有足够的时间让窗口彻底生成出来，这样等ｌｚ随便输个字符，就能正确找到窗口的句柄了

引用 1 楼 xihu1364 的回复:[quote=引用 楼主 wangli1000000 的回复:] 如下：   #include <stdio.h> #include <windows.h>   int main(void) {          HANDLE hOut;                                       ShellExecute(NULL,"open","E:\\Hello.exe",NULL,NULL,SW_SHOWNOACTIVATE);  getch();     hOut=FindWindow(NULL,"E:\\Hello.exe");  /*获得窗口句柄*/     printf("%ld ",hOut);     getch();     PostMessage(hOut,WM_CLOSE,0,0);                exit(0);      }   有 getch(); 时，就能获取句柄；当把getch();删除后，句柄就为0了。请问为什么？谢谢。  没有getch();这个程序就直接将E:\\Hello.exe程序的句柄给关掉了（PostMessage(hOut,WM_CLOSE,0,0);）  getch();起的作用就是让程序停在这里。让你看见打印出来的句柄printf("%ld ",hOut);  你可以用while （1）｛Sleep（1000）;｝代替getch(); 这样也可以看到打印句柄[/quote]   没说清楚，我说的是ShellExecute 语句后的getch(); 不是第二个getch() .

引用 楼主 wangli1000000 的回复:如下：   #include <stdio.h> #include <windows.h>   int main(void) {          HANDLE hOut;                                       ShellExecute(NULL,"open","E:\\Hello.exe",NULL,NULL,SW_SHOWNOACTIVATE);  getch();     hOut=FindWindow(NULL,"E:\\Hello.exe");  /*获得窗口句柄*/     printf("%ld ",hOut);     getch();     PostMessage(hOut,WM_CLOSE,0,0);                exit(0);      }   有 getch(); 时，就能获取句柄；当把getch();删除后，句柄就为0了。请问为什么？谢谢。  没有getch();这个程序就直接将E:\\Hello.exe程序的句柄给关掉了（PostMessage(hOut,WM_CLOSE,0,0);）  getch();起的作用就是让程序停在这里。让你看见打印出来的句柄printf("%ld ",hOut);  你可以用while （1）｛Sleep（1000）;｝代替getch(); 这样也可以看到打印句柄


Question: lwip snmp table获取问题

自己先顶一下！


Question: vc网络编程问题

表示不会，帮顶，顺便搞10个可用分！

dingyige


Question: 菜鸟来请教各位大神了，运行出错啊

scanf_s用得不对，改为： scanf_s("%lf %c %lf", &a, &c, 1, &b); 要不就直接用scanf，如下： scanf("%lf %c %lf", &a, &c, &b); 注意：不管你用哪个，由于你%lf %c %lf之间用了空格隔开，因此，你输入时也要用空格隔开，比如“6 + 5”，即格式要和scanf引号中的格式一一对应。

这是一个计算器，问题在于输入的6+5这样的，任何的运算式都不能识别，报错  引用 1 楼 turingo 的回复:要实现什么，错误又是什么？  [quote=引用 楼主 u013351990 的回复:] // ConsoleApplication8.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h"   void main() { 	double a = 0.0; 	double b = 0.0; 	char c = 0;  	printf("\n\t\t\t\t欢迎使用计算机程序"); 	printf("\n\n请输入计算式："); 	scanf_s("%lf %c %lf", &a, &c, &b);  	switch (c) 	{ 		case '+': 			printf("=%lf\n\a", a + b); 			break; 		case '-': 			printf("=%lf\n\a", a - b); 			break; 		case '*': 			printf("=%lf\n\a", a*b); 			break; 		case '/': 			if (b == 0) 				printf("\a\t抱歉分母为0，不能进行下一步计算！"); 			else 				printf("=%lf\n\a", a / b); 			break; 		case '%': 			if (long(b) == 0) 				printf("\a\t抱歉分母为0，不能进行下一步计算！"); 			else 				printf("=%lf\n\a", (long)a%long(b)); 			break; 		default: 			printf("抱歉，你输入的算术符号不对吧，估计是的，请检查输入的内容"); 			break; 	} }[/quote]

要实现什么，错误又是什么？  引用 楼主 u013351990 的回复:// ConsoleApplication8.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h"   void main() { 	double a = 0.0; 	double b = 0.0; 	char c = 0;  	printf("\n\t\t\t\t欢迎使用计算机程序"); 	printf("\n\n请输入计算式："); 	scanf_s("%lf %c %lf", &a, &c, &b);  	switch (c) 	{ 		case '+': 			printf("=%lf\n\a", a + b); 			break; 		case '-': 			printf("=%lf\n\a", a - b); 			break; 		case '*': 			printf("=%lf\n\a", a*b); 			break; 		case '/': 			if (b == 0) 				printf("\a\t抱歉分母为0，不能进行下一步计算！"); 			else 				printf("=%lf\n\a", a / b); 			break; 		case '%': 			if (long(b) == 0) 				printf("\a\t抱歉分母为0，不能进行下一步计算！"); 			else 				printf("=%lf\n\a", (long)a%long(b)); 			break; 		default: 			printf("抱歉，你输入的算术符号不对吧，估计是的，请检查输入的内容"); 			break; 	} }


Question: float类型的范围问题~~

楼主可以看看IEEE754标准中浮点数的存储 指出一点，指数是用移码表示的，将移码减去127就是指数的真值

记住一点就行了，计算机没有十个手指

楼主理解有误差，实际上，对于浮点型来说，在内存中，把一个浮点型数据分成小数部分和指数部分进行存储，在计算机中用二进制数来表示小数部分，用2的幂次来表示指数部分，而且对于浮点型的数值范围，在Turbo C，Turbo C++6.0，MS C中，float类型的数值范围是（-3.4*10^-38~3.4*10^38）,而在ANSI C中，并未具体规定每种类型数据的长度，精度和数值范围，所以不必太在意数值问题。

因为是二进制的数。  引用 2 楼 pokerLee 的回复:[quote=引用 1 楼 turingo 的回复:] 由指数范围决定的。  [quote=引用 楼主 pokerLee 的回复:] float的指数范围为-127~+128，而double的指数范围为-1023~+1024，并且指数位是按补码的形式来划分的。   其中负指数决定了浮点数所能表达的绝对值最小的非零数；而正指数决定了浮点数所能表达的绝对值最大的数，也即决定了浮点数的取值范围，float的范围为-2^128 ~ +2^128。  哪位大侠指点一下范围-2^128~+2^128是怎么来的~~跪求指点啊~~[/quote]为什么底数为2呢~~指数只是用8位内存表示了~~突然冒出来个2当底数~~求指点~~[/quote]

引用 1 楼 turingo 的回复:由指数范围决定的。  [quote=引用 楼主 pokerLee 的回复:] float的指数范围为-127~+128，而double的指数范围为-1023~+1024，并且指数位是按补码的形式来划分的。   其中负指数决定了浮点数所能表达的绝对值最小的非零数；而正指数决定了浮点数所能表达的绝对值最大的数，也即决定了浮点数的取值范围，float的范围为-2^128 ~ +2^128。  哪位大侠指点一下范围-2^128~+2^128是怎么来的~~跪求指点啊~~[/quote]为什么底数为2呢~~指数只是用8位内存表示了~~突然冒出来个2当底数~~求指点~~

由指数范围决定的。  引用 楼主 pokerLee 的回复:float的指数范围为-127~+128，而double的指数范围为-1023~+1024，并且指数位是按补码的形式来划分的。   其中负指数决定了浮点数所能表达的绝对值最小的非零数；而正指数决定了浮点数所能表达的绝对值最大的数，也即决定了浮点数的取值范围，float的范围为-2^128 ~ +2^128。  哪位大侠指点一下范围-2^128~+2^128是怎么来的~~跪求指点啊~~


Question: 贪吃蛇和俄罗斯方块

本人在做贪吃蛇的背景音乐，急求，希望牛人们解答

求怎样在获得相对路径

我觉得楼上答非所问~~~哈哈，虽然我不知道

循环播放就可以了。  引用 楼主 u012983920 的回复:求怎样在c#做的贪吃蛇中加背景音乐 ，加的是MP3格式的


Question: **********************求达人解释*************************

引用 5 楼 q745401990 的回复: 引用 6 楼 starytx 的回复:引用 4 楼 u013235485 的回复:引用 2 楼 starytx 的回复:  非常感谢，相当受益啊。 感谢二位。 祝2014年马上有钱。。。

引用 4 楼 u013235485 的回复:[quote=引用 2 楼 starytx 的回复:] 计算机处理浮点数只能做到近似，举个不太恰当的例子，有时候CSDN上的回复时间看起来是一样的，那为什么又有个先后呢？因为后台的时间还有毫秒，而我们看不到这个，同样对于浮点数来说因为他不“干脆”，所以使用==来判断是有风险的。通常的做法是做差，然后取绝对值，看这个差值是否在精度范围内即可认定是否相等  非常感谢。似乎懂了一些。那么请问在实际工作中，上面的对于浮点的相等比较是不是应该杜绝？？ 包括在其它计算机语言中。[/quote]是的，浮点数判断是否相等都应该取差值绝对值，判断是否小于一个精度范围的值比如0.000001来判断

记得包含math.h 头文件！！

引用 2 楼 starytx 的回复:计算机处理浮点数只能做到近似，举个不太恰当的例子，有时候CSDN上的回复时间看起来是一样的，那为什么又有个先后呢？因为后台的时间还有毫秒，而我们看不到这个，同样对于浮点数来说因为他不“干脆”，所以使用==来判断是有风险的。通常的做法是做差，然后取绝对值，看这个差值是否在精度范围内即可认定是否相等  非常感谢。似乎懂了一些。那么请问在实际工作中，上面的对于浮点的相等比较是不是应该杜绝？？ 包括在其它计算机语言中。

楼主应该知道浮点数有一个有效位数，其实浮点数的小数位往后甚至可以输出几十位，所有每一次浮点数做运算都是取若干位有效数字，等于就是近似求取，必然会丢失精度！在浮点数之间做比较时，一般是求两数的绝对值在某个区间内，简单的改了下你的程序 for (x = 0.0; fabs(x-2.0) > 0.00001  ; x += 0.2) 	{     	printf("%f\n",x); 	}

浮点数经过运算基本上都有一个精确位数，刚输入时应该还是比较准确


Question: 关于二维数组解引用问题

引用 2 楼 Automation_dmu 的回复:数组的地址和数组第一个元素的地址是一样的， 但是从指针的角度看， 指针对象却是不一样的 b++; *b++; 我就是不明白，b+1是二维数组b[1][0]的地址 那对(b+1)进行解引用，返回的应该是b[1][0]里面的值啊，为什么还是b[1][0]的地址？[/quote] 二维数组是一维数组的一维数组，二维数组名可以隐式转换为指向第一个一维数组的数组指针 b+1是指向第二个一维数组的数组指针，*(b+1)是第二个一维数组，也可以隐式转换为指向第二个一维数组第一个元素的指针 解引用是分层的，对b这个二维数组转换而成的一维数组指针进行一次解引用*，得到的不是元素而是一维数组转换而成的元素指针[/quote] 应该是明白了，谢谢~

引用 5 楼 Sharing_Li 的回复:[quote=引用 4 楼 xhbuming 的回复:] [quote=引用 1 楼 Sharing_Li 的回复:] 个人觉得是这样的：cout<<b+1；和cout<<*(b+1)；都是要输出相同的内容，不管解没解引用，要想打印这个值，就必须先找到存放这个值的地址，然后再把这个值打印出来，两个语句实现的功能一样，只是表现形式不一样，所以编译的汇编代码一样。 两个返回的都是地址而不是地址指向的值，难道解引用没有用？[/quote] 可以去看看C++中关于<<的重载[/quote] 这个与<<没关系吧，printf也输出相同的值啊？

引用 3 楼 xhbuming 的回复:[quote=引用 2 楼 Automation_dmu 的回复:] 数组的地址和数组第一个元素的地址是一样的， 但是从指针的角度看， 指针对象却是不一样的 b++; *b++; 我就是不明白，b+1是二维数组b[1][0]的地址 那对(b+1)进行解引用，返回的应该是b[1][0]里面的值啊，为什么还是b[1][0]的地址？[/quote] 二维数组是一维数组的一维数组，二维数组名可以隐式转换为指向第一个一维数组的数组指针 b+1是指向第二个一维数组的数组指针，*(b+1)是第二个一维数组，也可以隐式转换为指向第二个一维数组第一个元素的指针 解引用是分层的，对b这个二维数组转换而成的一维数组指针进行一次解引用*，得到的不是元素而是一维数组转换而成的元素指针

一维数组指针指向的是数组元素类型，二位数组指针指向的是一维数组指针  为什么结果一样，因为逻辑一样而已  实际上不应该是一样的

引用 4 楼 xhbuming 的回复:[quote=引用 1 楼 Sharing_Li 的回复:] 个人觉得是这样的：cout<<b+1；和cout<<*(b+1)；都是要输出相同的内容，不管解没解引用，要想打印这个值，就必须先找到存放这个值的地址，然后再把这个值打印出来，两个语句实现的功能一样，只是表现形式不一样，所以编译的汇编代码一样。 两个返回的都是地址而不是地址指向的值，难道解引用没有用？[/quote] 可以去看看C++中关于<<的重载

引用 1 楼 Sharing_Li 的回复:个人觉得是这样的：cout<<b+1；和cout<<*(b+1)；都是要输出相同的内容，不管解没解引用，要想打印这个值，就必须先找到存放这个值的地址，然后再把这个值打印出来，两个语句实现的功能一样，只是表现形式不一样，所以编译的汇编代码一样。 两个返回的都是地址而不是地址指向的值，难道解引用没有用？


Question: 用opencv实现车辆检测与计数功能，已实现前景检测，如何实现计数？

《学习OpenCV（中文版）》

cvFindContours 如果二值图已经是车辆的轮廓 直接利用轮廓检测函数直接检测就行 或者通过控制每一个轮廓的大小 过滤掉过小或者不符合轮廓逻辑规则的噪点

楼主，可不可以给发些资料,本人菜鸟一枚，体谅 1986642073@qq.com


Question: 致那些初学者的观点。

语言都是差不多了！

我在优化自己的程序的时候，把一个重要数据结构里的64位数改成16位，程序快了接近一个数量级。 然后，如果你不用指定长度的类型，库会遇到与长度相关的兼容性问题。

还是需要了解一下的

肉类对素食者无用，但是对我有用

C++是强数据类型的语言 当然得关注了

引用 1 楼 a345485527 的回复:不明觉厉...  那么你跪拜三天三夜吧。

不明觉厉...

引用 13 楼 BlackKOL 的回复:[quote=引用 6 楼 derekrose 的回复:] [quote=引用 5 楼 BlackKOL 的回复:] [quote=引用 4 楼 derekrose 的回复:] 肉类对素食者无用，但是对我有用   主要是先吃着素食。后面想长胖在去吃肉是可以的把。  主要刚一上。什么八进制。十六进制 真没有认真看过学习过。。  然后有又什么 科学记数法，指数记数法'e-记法'的。  初学真需要学的好好的吗。[/quote] 你没懂我的意思[/quote]   感觉我差不多说的像是懂了呀。求解释[/quote]  是否有用是具有相对性的

引用 6 楼 derekrose 的回复:[quote=引用 5 楼 BlackKOL 的回复:] [quote=引用 4 楼 derekrose 的回复:] 肉类对素食者无用，但是对我有用   主要是先吃着素食。后面想长胖在去吃肉是可以的把。  主要刚一上。什么八进制。十六进制 真没有认真看过学习过。。  然后有又什么 科学记数法，指数记数法'e-记法'的。  初学真需要学的好好的吗。[/quote] 你没懂我的意思[/quote]   感觉我差不多说的像是懂了呀。求解释

据说: 一楼的只能要饭 二楼的勉强温饱 三楼才能小康 四楼都是财主  有一部分人 爬到2楼就天天嘲笑爬3楼的 总觉得有吃的就可以混了还爬个屁 可一回过头 这些2B天天埋怨社会不公平

现在不用功, 遇到就发蒙. 觉得不重要, 感觉没啥用, 是因为你还没遇到....

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

工具就是工具，思想就是思想。 工具仅仅是用来实现思想而已

学以致用，但先学后用。

存在必有存在的价值

引用 5 楼 BlackKOL 的回复:[quote=引用 4 楼 derekrose 的回复:] 肉类对素食者无用，但是对我有用   主要是先吃着素食。后面想长胖在去吃肉是可以的把。  主要刚一上。什么八进制。十六进制 真没有认真看过学习过。。  然后有又什么 科学记数法，指数记数法'e-记法'的。  初学真需要学的好好的吗。[/quote] 你没懂我的意思

引用 4 楼 derekrose 的回复:肉类对素食者无用，但是对我有用   主要是先吃着素食。后面想长胖在去吃肉是可以的把。  主要刚一上。什么八进制。十六进制 真没有认真看过学习过。。  然后有又什么 科学记数法，指数记数法'e-记法'的。  初学真需要学的好好的吗。


Question: malloc内存分配，必须释放。否则内存泄漏？

对于1S种就结束的程序来说弹内存泄漏没意义。除非你来个循环，次次内存泄漏，这我就不说了。 对于长期运行的程序，内存泄漏是很有问题的，严重影响系统资源。用完了，就必须释放，不要侥幸。

引用 12 楼 cjfdqchwh 的回复:[quote=引用 11 楼 cjfdqchwh 的回复:] [quote=引用 6 楼 u011939931 的回复:] 不好意思，程序上错了。是这个…… int main(void) {   char *ptr = (char*)malloc(10);   if(NULL == ptr)   {     printf("\n Malloc failed \n");     return 0;   }   else   {   }   return 0;  }  这肯定内存泄露，不过这个函数不再一个循环里头，只是运行一次，所以程序运行一次，就会泄露了 10个char类型的内存[/quote]  当这个程序结束后，操作系统会自动去清扫分配给这个进程的资源。[/quote]

引用 14 楼 taodm 的回复:这说明楼主看错了书，把错误结论/有限制条件结论当普遍真理了。

这说明楼主看错了书，把错误结论/有限制条件结论当普遍真理了。

对于运行7*24小时的程序，不能容忍内存泄漏，你想想，一直想系统要内存，内存肯定会用光的  对于运行一下，就关掉的程序，内存泄漏一下也没什么关系。因为关掉程序后，内存又归系统了  但是你想，好的程序能让系统的内存用光吗？

引用 11 楼 cjfdqchwh 的回复:[quote=引用 6 楼 u011939931 的回复:] 不好意思，程序上错了。是这个…… int main(void) {   char *ptr = (char*)malloc(10);   if(NULL == ptr)   {     printf("\n Malloc failed \n");     return 0;   }   else   {   }   return 0;  }  这肯定内存泄露，不过这个函数不再一个循环里头，只是运行一次，所以程序运行一次，就会泄露了 10个char类型的内存[/quote]  当这个程序结束后，操作系统会自动去清扫分配给这个进程的资源。

引用 6 楼 u011939931 的回复:不好意思，程序上错了。是这个…… int main(void) {   char *ptr = (char*)malloc(10);   if(NULL == ptr)   {     printf("\n Malloc failed \n");     return 0;   }   else   {   }   return 0;  }  这肯定内存泄露，不过这个函数不再一个循环里头，只是运行一次，所以程序运行一次，就会泄露了 10个char类型的内存

但是在程序运行期间要是不释放那就是泄露了

因为在进程正常结束的情况下有操作系统给你做清理工作

如果整个过程中都需要使用的话，可以不释放！但是习惯不好！不推荐！ 还是释放会比较靠谱

不好意思，程序上错了。是这个…… #include <stdio.h> #include <malloc.h>  int main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("\n Malloc failed \n"); return 0; } else {  } return 0;  }

引用 2 楼 zhuobattle 的回复:如果不free，那就内存泄漏了。我给程序弄错了，本来里面没有free（ptr）这句。

malloc得到的内存不free 自然会 内存泄露  然后内存泄露是一个运行期的隐患  说什么程序结束之后 会回收资源就前言不搭后语了   另外你的代码有释放malloc得到的内存 至于返回值NULL 这种情况你没有获得malloc得到的内存 自然不存在什么释放的问题  再另外  free 之前 判断指针是否为NULL是多余的 因为free NULL是安全的 不过malloc 之后 判断指针是否是NULL 就是有必要的

如果这个程序要连续跑上一个月不结束，那么分配的内存如果不释放就会有问题 另外，这段代码释放掉了内存

如果不free，那就内存泄漏了。

不释放分配的内存，内存泄露是有的，只是没有影响到操作系统而已。 操作系统变聪明了，所以内存泄露不怕了。 如此而已. 另外，这段代码，已经释放内存了。 malloc 结果为NULL，表示分配内存失败，内存没有分配，不必释放。

参考《深入解析Windows操作系统-Windows Internals》进程管理。


Question: 小弟新人求解

有哪里奇怪？float总要有点误差吧

浮点数无法精确表示十进制小数，除非该小数恰好是0.5的n次方的整数倍 这是基础知识，请牢记


Question: 如何在程序里模拟在cmd里用管理员权限运行一条指令？

google搜索： shellexecuteex  runas

runas /noprofile /user:mymachine\administrator cmd 用runas试下，具体使用如何看下帮助。

啊，，哈哈 搞定啦，你那个命令差一点点就成了，改成这样就好了 ShellExecute(0,"runas", LPCSTR("cmd.exe"),LPCSTR("/c net user administrator /active:yes"),"",SW_HIDE);  多谢各位的帮助。。。

引用 5 楼 yangw150 的回复:啊，大神，你来啦， ShellExecuteA(0,"runas","cmd /c net user administrator /active:yes","","",1); 这个命令不行哦，我试过了 生成一个临时文本文件tmp.bat，内容为 runas /noprofile /user:mymachine\administrator "cmd /c \"net user administrator /active:yes\""  FILE *f; f=fopen("tmp.bat","r"); fprintf(f,"runas /noprofile /user:mymachine\\administrator \"cmd /c \\\"net user administrator /active:yes\\\"\"\n"); fclose(f); WinExec("cmd /c tmp.bat",SW_HIDE); remove("tmp.bat"); 再试试看。

ShellExecuteA(0,"runas","cmd /c net user administrator /active:yes","","",1);  试试看。  CreateProcessAsUser The CreateProcessAsUser function creates a new process and its primary thread. The new process then executes a specified executable file. The CreateProcessAsUser function is similar to the CreateProcess function, except that the new process runs in the security context of the user represented by the hToken parameter. By default, the new process is non-interactive, that is, it runs on a desktop that is not visible and cannot receive user input. Also, by default, the new process inherits the environment of the calling process, rather than the environment associated with the specified user.  BOOL CreateProcessAsUser(   HANDLE hToken,         // handle to a token representing the logged-on user   LPCTSTR lpApplicationName,  // pointer to name of executable module   LPTSTR lpCommandLine,       // pointer to command line string   LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes   LPSECURITY_ATTRIBUTES lpThreadAttributes,  // thread security attributes   BOOL bInheritHandles,         // whether new process inherits handles   DWORD dwCreationFlags,        // creation flags   LPVOID lpEnvironment,         // pointer to new environment block   LPCTSTR lpCurrentDirectory,   // pointer to current directory name   LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO   LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION );

ShellExecuteA(0,"runas","cmd","","",1);  这样是以管理员权限打开了cmd窗口，但怎么运行net user administrator /active:yes指令呢？


Question: pthread_mutex_lock 粒度

pthread_mutex_lock(&g_testlock); pthread_mutex_unlock(&g_testlock); // 休眠一会   pthread_mutex_lock(&g_testlock); pthread_mutex_unlock(&g_testlock); // 休眠一会  在试试，呵呵

修改成了  #include <stdio.h> #include <unistd.h> #include <pthread.h>   static pthread_mutex_t g_testlock;   void* thread_func(void* param) {           while(1)         {                 pthread_mutex_lock(&g_testlock);                 printf("thread lock\n");                 sleep(2);                 pthread_mutex_unlock(&g_testlock);                 printf("thread unlock\n");          }          return NULL;  }  int main() {         pthread_mutex_init(&g_testlock, NULL);         pthread_t threadId;         pthread_create(&threadId, NULL, thread_func, NULL);         while (1)         {                 pthread_mutex_lock(&g_testlock);                 printf("main lock \n");                 sleep(2);                 pthread_mutex_unlock(&g_testlock);                 printf("main unlock\n");         }           pthread_join(threadId, NULL);         pthread_mutex_destroy(&g_testlock);          return 0; } ~                                    结果 main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock main lock  main unlock

pthread_mutex_lock(&g_testlock); // 休眠一会 pthread_mutex_unlock(&g_testlock);   pthread_mutex_lock(&g_testlock); // 休眠一会 pthread_mutex_unlock(&g_testlock);  在试试，呵呵

好了，确实是如果unlock不停顿一下极可能又继续走对应的lock，而不会走另一个线程的lock


Question: 关于栈的内容，不能理解的一个地方。

引用 2 楼 bijiaoben 的回复:你这个递归调用了调用是3->2->1，然后打印顺序就是1->2->3了。楼主可以单步跟踪一下就明白了。 就是你的这段代码： int oneFewer = numberOfBottles - 1; printf("Take, p, %d bottles of beer on the wall.\n",oneFewer); singTheSong(oneFewer); printf("Put a bottle, %d empty bottles in the bin.\n",numberOfBottles);      我想我应该试理解了吧，是singTheSong 在递归的时候都进栈了，最后再一个个弹出来。    是这个意思吧？

引用 2 楼 bijiaoben 的回复:你这个递归调用了调用是3->2->1，然后打印顺序就是1->2->3了。楼主可以单步跟踪一下就明白了。 就是你的这段代码： int oneFewer = numberOfBottles - 1; printf("Take, p, %d bottles of beer on the wall.\n",oneFewer); singTheSong(oneFewer); printf("Put a bottle, %d empty bottles in the bin.\n",numberOfBottles);   说的是这边往回走吗？

引用 1 楼 user-2 的回复:这是递归，singTheSong一个个返回时，走的printf("Put a bottle,  学习编程，最好先学会单步调试  我会单步调试，也看到走printf("Put a bottle,但是后面的变量为什么会每次＋1这里不知道。 其次 谢谢


Question: 如何让fgetc读出字符而非ASCII码？如何读出全部？

文件保存的只是数据而已，读写的意义需要自己维护。  引用 楼主 u013369463 的回复:

cout << (char)i

楼主想问啥？

int i换成 char i;

应加两行： #include <stdio.h> #include <stdlib.h> int main() {  FILE *f;  int i;   f=fopen("文档.txt","r");  while (1) {   i=fgetc(f);   if (i==EOF) break;   printf("%c",i);  }  fflush(stdout);  fclose(f);  system("pause");  return 0; }

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  #include <stdio.h> #include <stdlib.h> int main() {  FILE *f;  int i;  while (1) {   i=fgetc(f);   if (i==EOF) break;   printf("%c",i);  }  fflush(stdout);  system("pause");  return 0; } 摒弃cin、cout 使用scanf、printf


Question: c语言获取系统时间，并插入数据库

#include <windows.h> #include <stdio.h> MSDN里面的例子：可以参考下，smallint的格式不知道 void main() {     SYSTEMTIME st, lt;          GetSystemTime(&st);     GetLocalTime(<);          printf("The system time is: %02d:%02d\n", st.wHour, st.wMinute);     printf(" The local time is: %02d:%02d\n", lt.wHour, lt.wMinute); }

#include <stdio.h> #include <time.h> char tmpbuf[20];//YYYY-MM-DD hh:mm:ss void main() {     time_t aclock;      time(&aclock);     strftime(tmpbuf,20,"%Y-%m-%d %H:%M:%S",localtime(&aclock));     printf("%s\n",tmpbuf); }


Question: 解惑，小case

一般头文件都会有防止重复包含的宏定义。两个都包含，要么是多人维护，写重了，但是由于防止重复包含的宏的存在，没有什么影响；要么就是有需要自己加了东西。 楼主可以试着保留库中的头文件看看编译运行有没有错，没错的话就把第一个去掉吧。

前人不小心留下的代码累赘

不会是自己定义的一个stdio.h跟系统的不一样？

包含100次也没问题，因为里边已经防止重复包含了，当然包含这么多也没啥意义

删除第一个。

那说明程序写的不好！  引用 楼主 abc594986308 的回复:一个程序包含下面两个头文件，是一起包含 #include "stdio.h" #include <stdio.h> 我知道#include "stdio.h"是在当前目录下查找标准头文件 #include <stdio.h>是直接到库中去查找 但是同一个程序同时包含这两个头文件是怎么一回事啊？


Question: 冒泡排序法实现中的问题

引用 14 楼 u013163178 的回复:[quote=引用 13 楼 u010800064 的回复:] [quote=引用 10 楼 u013163178 的回复:] [quote=引用 5 楼 derekrose 的回复:] [quote=引用 4 楼 u013163178 的回复:] [quote=引用 2 楼 u010800064 的回复:] a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.[/quote]上改后的代码[/quote]#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   [/quote]  #include <stdio.h>  int main(int argc, char **argv) {     int i,j,temp;     int a[10];     for(i=0; i<=9; i++)     {         printf("please enter a number\n");         scanf("%d",&a[i]);     }      for(j=0; j<=9; j++)     {         for(i=0; i<9-j; i++)         {             if(a[i] > a[i+1])             {                 temp = a[i];                 a[i] = a[i+1];                 a[i+1] = temp;             }         }     }      printf("排序后：\n");     for(i=0;i<=9;i++)     {         printf("%d",a[i]);     }      return 0; } [/quote]请问我的错在哪里，我的目的是要搞清楚哪里错了，避免下次发生类似错误[/quote] for(i=0;i<=9;i++)         {             if(a[i]>a[i-1])             {                 temp=a[i];                 a[i]=a[i-1];                 a[i-1]=temp;             }         } 在使用数组时第一要注意的就是你做循环有没有越界产生。 a[i-1] 当i=0 的也是越界了

引用 16 楼 cait_sith 的回复:[quote=引用 7 楼 u013163178 的回复:] [quote=引用 1 楼 user-7 的回复:] line 14 for(i=0;i<=9;i++) => for(i=0;i<9;i++)#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   I correct it，but it also can run.Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted[/quote]    for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		}  i=0时，a[0]>a[-1][/quote]解决了，谢谢你

引用 15 楼 Sharing_Li 的回复:[quote=引用 8 楼 u013163178 的回复:] [quote=引用 6 楼 Sharing_Li 的回复:] 嵌套循环中的if语句中，数组下标越界了。当i = 9时，a[i+1]= a[10]越界 if(a[i]>a[i-1])改成这样了，还是有点问题 “冒泡排序.exe”(Win32): 已加载“C:\Users\I love u\Desktop\新建文件夹\冒泡排序\Debug\冒泡排序.exe”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\ntdll.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\kernel32.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\msvcr110d.dll”。已加载符号。 Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted. 程序“[7592] 冒泡排序.exe”已退出，返回值为 0 (0x0)。 [/quote] ...因为等于0时，a[i-1] = a[-1]，下标错误，细心点哟[/quote]改好了，哎，我太粗行了

引用 7 楼 u013163178 的回复:[quote=引用 1 楼 user-7 的回复:] line 14 for(i=0;i<=9;i++) => for(i=0;i<9;i++)#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   I correct it，but it also can run.Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted[/quote]    for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		}  i=0时，a[0]>a[-1]

引用 8 楼 u013163178 的回复:[quote=引用 6 楼 Sharing_Li 的回复:] 嵌套循环中的if语句中，数组下标越界了。当i = 9时，a[i+1]= a[10]越界 if(a[i]>a[i-1])改成这样了，还是有点问题 “冒泡排序.exe”(Win32): 已加载“C:\Users\I love u\Desktop\新建文件夹\冒泡排序\Debug\冒泡排序.exe”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\ntdll.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\kernel32.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\msvcr110d.dll”。已加载符号。 Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted. 程序“[7592] 冒泡排序.exe”已退出，返回值为 0 (0x0)。 [/quote] ...因为等于0时，a[i-1] = a[-1]，下标错误，细心点哟

引用 13 楼 u010800064 的回复:[quote=引用 10 楼 u013163178 的回复:] [quote=引用 5 楼 derekrose 的回复:] [quote=引用 4 楼 u013163178 的回复:] [quote=引用 2 楼 u010800064 的回复:] a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.[/quote]上改后的代码[/quote]#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   [/quote]  #include <stdio.h>  int main(int argc, char **argv) {     int i,j,temp;     int a[10];     for(i=0; i<=9; i++)     {         printf("please enter a number\n");         scanf("%d",&a[i]);     }      for(j=0; j<=9; j++)     {         for(i=0; i<9-j; i++)         {             if(a[i] > a[i+1])             {                 temp = a[i];                 a[i] = a[i+1];                 a[i+1] = temp;             }         }     }      printf("排序后：\n");     for(i=0;i<=9;i++)     {         printf("%d",a[i]);     }      return 0; } [/quote]请问我的错在哪里，我的目的是要搞清楚哪里错了，避免下次发生类似错误

引用 10 楼 u013163178 的回复:[quote=引用 5 楼 derekrose 的回复:] [quote=引用 4 楼 u013163178 的回复:] [quote=引用 2 楼 u010800064 的回复:] a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.[/quote]上改后的代码[/quote]#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   [/quote]  #include <stdio.h>  int main(int argc, char **argv) {     int i,j,temp;     int a[10];     for(i=0; i<=9; i++)     {         printf("please enter a number\n");         scanf("%d",&a[i]);     }      for(j=0; j<=9; j++)     {         for(i=0; i<9-j; i++)         {             if(a[i] > a[i+1])             {                 temp = a[i];                 a[i] = a[i+1];                 a[i+1] = temp;             }         }     }      printf("排序后：\n");     for(i=0;i<=9;i++)     {         printf("%d",a[i]);     }      return 0; }

引用 7 楼 u013163178 的回复:[quote=引用 1 楼 user-7 的回复:] line 14 for(i=0;i<=9;i++) => for(i=0;i<9;i++)#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   I correct it，but it also can run.Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted[/quote]  #include <stdio.h>  int main(int argc, char **argv) {     int i,j,temp;     int a[10];     for(i=0; i<=9; i++)     {         printf("please enter a number\n");         scanf("%d",&a[i]);     }      for(j=0; j<=9; j++)     {         for(i=0; i<9-j; i++)         {             if(a[i] > a[i+1])             {                 temp = a[i];                 a[i] = a[i+1];                 a[i+1] = temp;             }         }     }      printf("排序后：\n");     for(i=0;i<=9;i++)     {         printf("%d",a[i]);     }      return 0; }

引用 9 楼 netbooting 的回复: #include <stdio.h>  int main(void) {     int   i, j, temp;     int   a[10];     int   swapped = 1;      for (i = 0; i <= 9; i++) {         printf("please enter a number\n");         scanf("%d", &a[i]);     }  	/* 冒泡排序 */     for (i = 0; swapped; i++) {     	/* 如果一轮检查下来没有一次交换，则说明数据已经排序排好，不用继续比较 */         swapped = 0;         /* j < 9 - i即可，因为9-i后面的数都是已经排好序的较大的数，不用再次比较 */         for (j = 0; j < 9 - i; j++) {             if (a[j] > a[j + 1]) {                 temp = a[j];                 a[j] = a[j + 1];                 a[j + 1] = temp;                 swapped = 1;             }         }     }      printf("排序后：\n");      for (i = 0; i <= 9; i++)         printf("%d ", a[i]);      return 0; }  /* j < 9 - i即可，因为9-i后面的数都是已经排好序的较大的数，不用再次比较 */有道理

引用 5 楼 derekrose 的回复:[quote=引用 4 楼 u013163178 的回复:] [quote=引用 2 楼 u010800064 的回复:] a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.[/quote]上改后的代码[/quote]#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }

引用 6 楼 Sharing_Li 的回复:嵌套循环中的if语句中，数组下标越界了。当i = 9时，a[i+1]= a[10]越界 if(a[i]>a[i-1])改成这样了，还是有点问题 “冒泡排序.exe”(Win32): 已加载“C:\Users\I love u\Desktop\新建文件夹\冒泡排序\Debug\冒泡排序.exe”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\ntdll.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\kernel32.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。已加载符号。 “冒泡排序.exe”(Win32): 已加载“C:\Windows\SysWOW64\msvcr110d.dll”。已加载符号。 Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted. 程序“[7592] 冒泡排序.exe”已退出，返回值为 0 (0x0)。

引用 1 楼 user-7 的回复:line 14 for(i=0;i<=9;i++) => for(i=0;i<9;i++)#include "stdafx.h" #include <stdio.h> int main() { 	int i,j,temp; 	int a[10]; 	for(i=0;i<=9;i++) 	{ 		printf("please enter a number\n"); 		scanf_s("%d",&a[i]); 	} 	for(j=0;j<=9;j++) 	{ 		for(i=0;i<=9;i++) 		{ 			if(a[i]>a[i-1]) 			{ 				temp=a[i]; 				a[i]=a[i-1]; 				a[i-1]=temp; 			} 		} 	} 	printf("排序后：\n"); 	for(i=0;i<=9;i++) 		printf("%d",a[i]); 	return 0; }   I correct it，but it also can run.Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted

引用 4 楼 u013163178 的回复:[quote=引用 2 楼 u010800064 的回复:] a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.[/quote]上改后的代码

引用 2 楼 u010800064 的回复:a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时我改了后还是这样Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.

for(i=0;i<=9;i++)         {             if(a[i]>a[i+1])  when i=9, a[i+1] is a[10], beyond scope

a[i]>a[i+1]  这个条件调用了越界的小标，当i=9时


Question: 怎么把a.txt和b.txt合到c。c.txt为什么打开失败

看下errno是什么， windows里，用DWORD GetLastError(void);

打开失败时, 看错误码吧.

system("copy a.txt+b.txt c.txt");


Question: 字符串翻转,出现Segmention fault, 怎么解决

谢了 你说的是主要的问题, 刚发现另外一个问题,一开始while(*str++); 把str移到 '\0'后面去了 我str--;只做了一次,结果显示不出来了,改正了,另外改了一下其他地方  上代码 #include <stdio.h>  void reverse(char str[]) {     char *start = str;     char temp = ' ';      while(*str)         str++;       str--;      while (start < str) {         temp = *start;         *start = *str;          *str = temp;          start++;         str--;    }  }  int main() {     char str[] = "abcdefg";     reverse(str);     printf("%s\n", str); }

C 语言常见问题集 2.13 以下的初始化有什么区别？char a[] = "string literal"; char *p = "string literal"; 当我向 p[i] 赋值的时候, 我的 程序崩溃了。  字符串常量有两种稍有区别的用法。用作数组初始值 (如同在 char a[]  的声明中), 它指明该数组中字符的初始值。其它情况下, 它会转化为一个 无名的静态字符数组, 可能会存储在只读内存中, 这就是造成它不一定能被修改。 在表达式环境中, 数组通常被立即转化为一个指针  (参见第 6 章), 因此第二个声明把 p 初始化成 指向无名数组的第一个元素。 为了编译旧代码, 有的编译器有一个控制字符串是否可写的开关。  参见问题 1.11、 6.1、 6.2 和 6.6。  参考资料: [K&R2, Sec. 5.5 p. 104]; [ISO, Sec. 6.1.4, Sec. 6.5.7]; [Rationale, Sec. 3.1.4]; [H&S, Sec. 2.7.4 pp. 31-2]。


Question: socket编程遇到SIGPIPE(broken pipe)错误信号

SIGPIPE是正常的信号，对端断开后本端协议栈在向对端传送数据时，对端会返回TCP RST，导致本端抛出SIGPIPE信号。  所有的网络程序都应该sigprocmask主动屏蔽掉这个信号。

// 关闭服务器端连接到客户端的套接字         close(client_socket_fd);  //这个不需要的！链路已经半关闭了，TIME_WAIT

引用 2 楼 missheaven2011 的回复:// 关闭服务器端连接到客户端的套接字  close(client_socket_fd);  这里你不就把服务端的套接字关闭掉了嘛，第二次肯定不行啦  对的，我把close(client_socket_fd);这行注释掉，客户端就可以多次发送消息，不报SIGPIPE了。  但是服务器端只读取到了第一条消息，如何让它不断读取客户端发送的消息

引用 3 楼 haoren026 的回复:[quote=引用 2 楼 missheaven2011 的回复:]  // 关闭服务器端连接到客户端的套接字  close(client_socket_fd);  这里你不就把服务端的套接字关闭掉了嘛，第二次肯定不行啦  对的，我把close(client_socket_fd);这行注释掉，客户端就可以多次发送消息，不报SIGPIPE了。  但是服务器端只读取到了第一条消息，如何让它不断读取客户端发送的消息[/quote] // 接受连接 client_socket_fd = accept(socket_fd, (struct sockaddr*) &client_name, &client_name_len); accept函数导致第二次接收数据被堵塞，你可以将套接字设置为非阻塞，也可以将这个函数的调用提前，放在while循环外面

服务端第一次接收数据之后已经将该连接关闭了，但是客户端没有关闭，继续往这条链接发送数据，自然报SIGPIPE(Broken Pipe)了。


Question: 算法题。。略难。。求助高手。。

还要扣掉重复的吧，貌似一次遍历过程中，算出当前连续匹配的长度是多少，扣除之即可...

int count=0; for(int i=0;i<n;i++) count+=n-i;

全组合问题，输出一个集合中所有的子集。


Question: 求判断数组连续个数的函数

1）最大的，找到连续数，记录连续数个数，最大值即可。 2）每次遇到新连续数序列，保留最大值，大的那个。

代码: long  GetCNum(int *x,int n) { 	if(NULL==x) return 0; 	int  pNum=*x; 	long count=1; 	long cMax=1; 	for(int i=1;i<n;i++) 	{ 		 pNum++;          if(*(x+i)==pNum) 		 { 			 count++; 		 } 		 else 		 { 			 if(cMax<count) cMax=count; 			 count=1; 			 pNum=*(x+i); 		 } 	} 	if(cMax<count) cMax=count; 	if(cMax==1) return 0; 	return cMax; }  测试: int main(int argc, char* argv[]) { 	     int n[8]={1,2,3,5,7,8,9,10};     int c=GetCNum(n,8); 	printf("最大连续数是:%d\n",c); 	retur 0; }

噢，后面要加个return max;

或者这么描述。设置两个变量，最大连续长度max, 当前连续长度cur, 两个都初始化为1，并认为数组的第一个元素已经被处理，从第二个元素开始处理。如果当前元素刚好比前一个元素多1，则++cur, 否则如果cur>max, 则max=cur, cur=1...重复以上直到数组结束，返回max   template <class Int, ForwardInter I> unsigned Streak(I first, I end) {      Int prev;      unsigned max=1, cur=1;      if(first==end)         return 0;      prev=*first++;      while(first!=end)      {          if(*first==++prev)             ++cur;          else{             if(cur>max)                 max=cur;             cur=1;             prev=*first;          }          ++first;      } }    没测试，大概意思到了吧。

引用 10 楼 u010222864 的回复: 你觉得这个长度的计算是数组的长度吗？？那么sizeof(itestarray)/sizeof(*itestarray)又是什么呢？？ 恩，漏了，呵呵

一定要注意这里的数组不是char类型的，一定要明白sizeof计算的是什么东西

引用 2 楼 thefirstz 的回复:把程序发上来，帮你看看 我的代码经过验证时错误的，只能从头数起。如1,2,3，4这样可判断，如果中间开始就不行了。

引用 1 楼 gz_qmc 的回复:那么请问  1 2 3 5 7 8  你希望是得到3还是2啊 期望得到2，返回连续的最大值

是你的代码有错求助还是想让兄弟们给你写一份代码啊？

int GetContinuum(int* piarray, int ilength) { 	int iRet = 1, itemp = 1; 	for(int i = 1; i < ilength; i++) 	{ 		if(piarray[i] == piarray[i - 1] + 1) 			itemp++; 		else 		{ 			if(itemp > iRet) iRet = itemp; 			itemp = 1; 		} 	} 	if(itemp > iRet) iRet = itemp; 	return iRet; }  int main(int argc, char* argv[]) { 	int itestarray[] = {1, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 20, 23, 22, 25}; 	printf("%d\n", GetContinuum(itestarray, sizeof(itestarray))); 	system("pause"); 	return 0; }  不知道行么，

把程序发上来，帮你看看

那么请问  1 2 3 5 7 8  你希望是得到3还是2啊


Question: 如何实现将变量依次传给函数？

捧个人场总行吧。

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 derekrose 的回复:] 难道楼主不知道有个东西叫数组 估计还没学到。[/quote]  赵老师你回这种贴能得分吗

引用 2 楼 derekrose 的回复:难道楼主不知道有个东西叫数组 估计还没学到。

难道楼主不知道有个东西叫数组

char* s[N]; int*  p[N];  int i; for(i = 0; i < N; ++i) printout(s[i], p[i]);


Question: 计算机软硬件接口问题.汇编转换问题..望内力深厚高手解答

编译，汇编过程中，绝对定位的，都要写在重定位表中。 链接后，应该还有重定位表，DOS实模式程序，必须有重定位表。  因为DOS实模式程序，加载的时候，才能定位程序。 加载程序会对 .exe,.com 做重定位。 Windows 32Bits  .exe加载时，重定位已经不是必须的了，不过应该，还保留着重定位表。

不知道，有个重定位表么？ 不知道实模式，保护模式，虚拟86模式么？  一切加载时，不需要改变的，就直接编码； 加载时，需要改变的，就填充为0，并记录到重定位表中。  1）立即数，是不需要改变的，直接编码。 2）相对地址寻址指令的偏移量，计算好以后，不会改变，直接编码。 3）实模式，直接定位的绝对地址的，直接编码。    3.1）操作系统，必须加载到一个绝对地址，不能有分毫改变。    3.2）直接写屏，必须写到绝对地址，这个地址，不能有分毫改变。    3.3）不属于这种直接定位的，绝对地址寻址的指令的操作数，进入重定位表。  4）随着加载变化的，进重定位表，就是3.3）那种情况，这里强调一下。    主要有绝对地址寻址，绝对跳转，调用地址。    包括一些加载段内偏移量，段地址的代码。  5）32Bits，DLL可能需要重定位，绝对地址，记录到重定位表中；    而导入导出函数，或者导入导出数据，记录在导入导出表中。 6）32Bits，exe,使用的每个动态库，包括系统动态库，里面的导出符号，在 exe的导入表中。    内部绝对定位数据（包括全局变量，跳转地址，调用地址），编译时，记录到重定位表中。    链接时，Windows 可能已经不需要重定位了，直接写成绝对地址就可以了。    不过不排除，重定位表，还保存在exe中的可能。     Windows Win32 程序，每个exe 都可以从同一个地址启动，缺省就是 0x400000；    即虚拟地址的4MBytes位置；    这是VC的缺省设置,这个地址好像是可以改变的。    因为进程地址空间是互相隔离的，所以链接以后，基本可以不必重定位。

1.这是16位汇编,寻址是物理地址,32位x86汇编是虚拟地址,寄存器是eax等 2.jmp label,实际上的指令是跳转到前面多少行,属于相对寻址,所以首地址加载哪里都不会错

汇编器产生的地址从0开始 你说是什么地址？   操作系统才能碰到物理地址，其余的都碰不到

汇编里面，每一个语句占用的内存的大小是固定已知的。 Label前面有多少个语句，算算就能知道Label所在位置的偏移是多少了。

《Windows PE权威指南》 《程序员的自我修养——链接、装载与库》

汇编区貌似人很少，还望各位大大帮忙解答下心中疑惑


Question: 宏定义会分配内存吗？

#define STRING "abcd" #define NUMBER 1  如果没用到 STRING, 那么这个宏定义相当于没定义, 不产生任何运行时的内存分配.  如果用到了, 并且在多个地方用到了, 内存如何分配要看使用场景和编译器了.  cons char* psz  = STRING; char szbuf[] = STRING;

不会  在编译时候才会分配

不会！预编译期完成的事情！还没运行！

楼主，我这么跟你解释：  宏，只是简单的复制、替换。  #define NUMBER 1 那么，凡是你代码中有 NUMBER 这个标识的，都会被替换成1，你代码编写的时候，没有编译的时候，是不占用空间的，但是，如果你代码编译运行了，就可能要占空间了。 比如说  #define STRING "abcd"  就需要存储在文字常量区

不会的

1.编译后放在常量数据区 2.不会

不会。 "abcd"那是在编译期才去处理的东西

会让编译器（比如gcc,g++,cl,……）在编译时分配内存。

宏定义只是在预处理器里进行文本替换

错！abcd还不存在呢。

宏是在编译期间起作用，还没到运行期间，所以没有内存分配这个说法


Question: 代码中有很多设置窗口或控件大小的代码，这些代码都是直接用数字来描述的。想要好一点的风格，应如何处理这些代码呢?

引用 楼主 huabinsir 的回复:代码中有很多设置窗口或控件大小的代码，这些代码都是直接用数字来描述的。想要好一点的风格，应如何处理这些代码呢?(是将数字定义成宏，再使用宏?)  要你擦屁股啊

使用宏比如#define WINDOWS_WIDTH 800再使用编辑器的串替换功能比如将代码中表示窗口像素宽度的800替换为WINDOWS_WIDTH。

过程要如何实现呢? (我主要是问过程)

思路正确！将数字定义成宏，再使用宏。  引用 楼主 huabinsir 的回复:代码中有很多设置窗口或控件大小的代码，这些代码都是直接用数字来描述的。想要好一点的风格，应如何处理这些代码呢?(是将数字定义成宏，再使用宏?)

把数字定义成宏

我其实是想了解一下有什么好的方法和思路.

引用 6 楼 xihu1364 的回复:[quote=引用 楼主 huabinsir 的回复:] 代码中有很多设置窗口或控件大小的代码，这些代码都是直接用数字来描述的。想要好一点的风格，应如何处理这些代码呢?(是将数字定义成宏，再使用宏?)  要你擦屁股啊[/quote] 根据帖主的头像来看，不仅要擦屁股，还要穿裤子。

宏当然是放在一个头文件中了。 参考include\limits.h

引用 4 楼 huabinsir 的回复:我主要是问步骤过程（比如:宏是定义在一个公共文件中还是其它地方. 数字有很多，不是要很多宏吗?  很多数字 很多宏，不是一样眼花吗?） 那还真不一定： 800 600 80 256 和 WINDOW_WIDTH WINDOW_HEIGHT CHARS_PERLINE CHARS_INPATH 哪个更花？


Question: 跪求！！！偏虚关系的哈斯图求解程序代码！！！

大神们


Question: 弱弱的问一句，内存中，数组是按行存储还是按列存储？

按行存储。。。

引用 14 楼 lm_whales 的回复:integer a dimesion a(5,4) data a    / 1,2,3,4,5   ,2,3,4,5,6   , 3,4,5,6,7   ,4,5,6,7,8  / 这是一个5 行4列的二维数组 下面是内存布局，和C语言4行5列的二维数组，内存布局完全一致。   //第  1(0),2(1),3(2),4(3),5(4) 行数据         {1   ,2   ,3   ,4   ,5  }， //第1（0）列 5个元素 ，即有5行       {2   ,3   ,4   ,5   ,6  }， //第2（1）列 5个元素 ，即有5行       {3   ,4   ,5   ,6   ,7  }， //第3（2）列 5个元素 ，即有5行       {4   ,5   ,6   ,7   ,8  }， //第4（3）列 5个元素 ，即有5行 dimesion a(5:4)改成dimesion a(5,4)

引用 4 楼 luozikuan 的回复:C++的vector吗？它是一个封装好的结构，应该不是简单的数组，要动态增长的话，本能地是想到链式存储。 vector是利用动态数组，元素增加了以后就要自动去扩大数组容量了，然后再复制过去。

对于Fortran integer a[N0][N1]....[Ni]; 对于 Fortran  integer a（N0,N1,....,Ni)

引用 19 楼 gz_qmc 的回复:内存是平坦的 所以,就算是外星来的开发软件 存储永远是按行存储的  如果你一定认为有按列储存的 请把数据阵列向右或向左旋转90度来看 其实就是先数哪个下标的问题。  C 下标 是从左到右数数，最后一个下标变化最快。即最右边的下标，变化最快。 Fortran 是是从右到左数数，，最后一个下标变化最快。即最左边的下标，变化最快。  对于C int a[N0][N1]....[Ni]; 从内存中第0～ 到第 ΠNi 个数据数数， 假设下标是 n0,n1,。。。。ni 那么 下标 ni 变化最快,n0 变化最慢  对于 Fortran integer a[N0][N1]....[Ni]; 从内存中第0～ 到第 ΠNi 个数据数数， 假设下标是 n0,n1,。。。。ni 那么 下标 n0 变化最快,ni 变化最慢   这个就是编程语言的数组内存布局的行优先和列优先的区别。  这种区别，对于两种语言的函数过程，互相调用的时候，就需要特别注意。 通常，只使用某种语言，是没有问题的。

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

引用 18 楼 micklexqg 的回复:[quote=引用 16 楼 zhao4zhong1 的回复:] 一维数组何来按行按列存储？ 二维数组才有按行按列存储。但vector < vector <> >个人认为根本不是二维数组。 这里不是几维的问题，就是如何访问vector中结构体元素的数据，数据成员都是int型的[/quote] #include <iostream> #include <vector> using namespace std; struct MY_S {  int d0;  int d1; }; typedef struct MY_S MY_STRUCT; vector <MY_STRUCT> my_structs(2); int main() {     my_structs[0].d0=10;     my_structs[0].d1=11;     my_structs[1].d0=20;     my_structs[1].d1=21;     cout<<my_structs[0].d0<<endl;     cout<<my_structs[0].d1<<endl;     cout<<my_structs[1].d0<<endl;     cout<<my_structs[1].d1<<endl;     return 0; } //10 //11 //20 //21 //

引用 16 楼 zhao4zhong1 的回复:一维数组何来按行按列存储？ 二维数组才有按行按列存储。但vector < vector <> >个人认为根本不是二维数组。 这里不是几维的问题，就是如何访问vector中结构体元素的数据，数据成员都是int型的

C/C++的数組并不存在所谓行和列的概念，这种自我杜撰出来的东西是国内烂书的又一项自以为是的“发明“，用这种方式去理解数組是有害的，正是由于这种破烂概念的存在才出现了楼主这种本不应该出现的疑问，可谓害人不浅。

C++的 vector 是动态的一维数组，所以没有行列的概念。

各个编程语言里，只有二维数组，才有行和列的概念。 因为有时用二维数组，表示矩阵。  至于多维数组，哪个维度算列，哪个算行？？？已经无法用行列来表示了。 而一维数组，可以当作列，也可以当作行。  只有二维数组，有清晰的行列概念。因为他和矩阵的概念对应，数组的行和列，对应矩阵的行和列。  C  行优先，各列数据，在每一行里，一个挨着一个排列。    数据是一行一行的，每行是连续排列的若干元素。 下面是个4行5列的二维数组： 注释里 小括号里是，C常用的索引方式，从0开始计数。 小括号外面是通常的方式，从1开始计数。  int a[4][5]={  //第  1(0),2(1),3(2),4(3),5(4) 列数据         {1   ,2   ,3   ,4   ,5  }， //第1（0）行 5个元素 ，即有5列       {2   ,3   ,4   ,5   ,6  }， //第2（1）行 5个元素 ，即有5列       {3   ,4   ,5   ,6   ,7  }， //第3（2）行 5个元素 ，即有5列       {4   ,5   ,6   ,7   ,8  }， //第4（3）行 5个元素 ，即有5列 };  Fortran 列优先 每行数据，在每一列里一个挨着一个排列。  integer a; dimesion a(5:4) data a    / 1,2,3,4,5   ,2,3,4,5,6   , 3,4,5,6,7   ,4,5,6,7,8  / 这是一个5 行4列的二维数组 下面是内存布局，和C语言4行5列的二维数组，内存布局完全一致。   //第  1(0),2(1),3(2),4(3),5(4) 行数据         {1   ,2   ,3   ,4   ,5  }， //第1（0）列 5个元素 ，即有5行       {2   ,3   ,4   ,5   ,6  }， //第2（1）列 5个元素 ，即有5行       {3   ,4   ,5   ,6   ,7  }， //第3（2）列 5个元素 ，即有5行       {4   ,5   ,6   ,7   ,8  }， //第4（3）列 5个元素 ，即有5行  所不同的是，行和列的意义，两种语言完全不同。 注意两种语言的下标的意义，完全相同，行列的意义却不同。 第一个下标，称作行，第二个下标称作列。这个在两种语言中没有区别。  内存布局则不同 C每行数据中的每一列，是一个挨着一个的。 Fortran 每列数据中的每一行，是一个挨着一个的。

某书说到是多维数组是先行后列存储。 用vs启动调试也可以看出。   int main() { 	char x[][5] = { "hello", "world" }; 	return 0;	 }     x[1]的地址总是从x[0]的地址偏移五个字节。也就是先存储x[0]中的五个字符，再存储x[1]的五个字符。

引用 10 楼 baichi4141 的回复:指针执行+时，按指针指向类型的大小计算偏移 如果一个结构体大小为100，那么指向这个结构体的指针执行++时，偏移100字节，执行+3时，偏移300字节 至于按行存储和按列存储，那纯属画图时的方向问题 你这里只是找到某个结构体的首地址，可是我还要找到这个结构体里的数据成员的具体地址，这样才能访问到数据啊

最终问题可以归纳为这样，vector在内存的存储，是存完一个结构体，接着存下一个结构体，按这样来理解是不是可以认为是按列存储的，然而我在用地址偏移的时候却发现按行来偏移的

我知道vector有多维的，但我这里只是问一维的vector，7楼没明白我的意思，我的意思是这样的，有一个一维的vector，其元素为结构体，结构体数据都是int型的，我想访问用指针方法访问结构体里的数据

动态数组不也是数组吗

引用 5 楼 micklexqg 的回复:[quote=引用 3 楼 zhuobattle 的回复:] [quote=引用 2 楼 micklexqg 的回复:] [quote=引用 1 楼 luozikuan 的回复:] 不同的语言有不同的规定，C是按行存，FORTRAN按列存。 vector是怎么存储的呢？[/quote] vector就是数组。[/quote] 那这么来说也是按行存储的了[/quote] vector不是多维的，有啥行和列？ 再说了，行和列只是业务逻辑，你认为第几维是行，它就是行。 就我自己来讲，平时从来不用多维数组。多维数据写个包装类，存在一维的vector里面。


Question: 请教一个问题，如何把TXT中的内容保存到链表中，TXT格式和链表已经定义好

引用 3 楼 user-1 的回复:写链表到是简单  文件解析比较麻烦  文件分析的代码我写了一个，链表操作有些难度，关于链表操作的部分都在main函数中 #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h>  const char *file = "conf.txt"; typedef struct _ConfElement{    char *pszkey;       char *pszvalue;     struct _ConfElement * next; }CONF_ELEMENT;  typedef struct _ConfSection{     char * pszSection;          struct CONF_ELEMENT * pszConfElement;     struct _ConfSection * next; }CONF_SECTION;  char *strtrimr(char *pstr); char *strtriml(char *pstr); char *strtrim(char *pstr); int get_item_from_line(char *line,CONF_SECTION *confSection);  /* *去除字符串右端空格 */ char *strtrimr(char *pstr) { 	int i; 	i = strlen(pstr) - 1; 	while (isspace(pstr[i]) && (i >= 0)) 	pstr[i--] = '\0'; 	return pstr; } /* *去除字符串左端空格 */ 	char *strtriml(char *pstr) { 	int i = 0,j; 	j = strlen(pstr) - 1; 	while (isspace(pstr[i]) && (i <= j)) 	i++; 	if (0<i) 	strcpy(pstr, &pstr[i]); 	return pstr; } /* *去除字符串两端空格 */ char *strtrim(char *pstr) { 	char *p; 	p = strtrimr(pstr); 	return strtriml(p); }  /* *从配置文件的一行读出key或value,返回item指针 *line--从配置文件读出的一行 */ int get_item_from_line(char *line,CONF_SECTION *confSection) { 	char *p = strtrim(line); 	int len = strlen(p); 	if(len <= 0){ 		return 1;//空行 	} else if(p[0]=='#'){ 	return 2; 	}else{ 		char *p2 = strchr(p, '='); 		*p2++ = '\0'; 		//confSection->pszConfElement->pszkey = (char *)malloc(strlen(p) + 1); 		//confSection->pszConfElement->pszvalue = (char *)malloc(strlen(p2) + 1); 		confSection->pszConfElement->pszKey=p; 		confSection->pszConfElement->pszValue=p2; 		//strcpy(confSection->pszConfElement->pszKey,p); 		//strcpy(confSection->pszConfElement->pszValue,p2);      		} return 0;//查询成功 }  int main(void)  {    FILE *fp;    char line[1024];   fp = fopen("conf.txt","r");    fseek(fp, 0, SEEK_SET);//指针指向文件头部       while (fgets(line, 1023, fp)){ 		//printf("%s\n",line); 		char *p = strtrim(line); 		if (p[0]=='<') 		{ 			strcpy(p,p+1);	 			int nLen = strlen(p); 			if(p[nLen-1]=='>') 			{ 			   p[nLen-1]='\0'; 			}				 			/*                         这部分要生成一个新的CONF_SECTION类型的链表，存储尖括号里的字符串                          */                          //confSection->pszSection=p; 			//printf("%s\n",confSection->pszSection); 							 		} 		else 		{                          /*这里把尖括号下面的内容存储到CONF_ELEMENT类型的链表中*/ 			//get_item_from_line(line,confSection); 		} 	} }

写链表到是简单  文件解析比较麻烦

引用 1 楼 user-1 的回复:原理很简单,可是说来话长啊  我现在处于能把过程想明白（就像你说的原理简单一样）具体的代码操作写不出来的阶段，比如链表里面套链表怎么写，怎么破？

原理很简单,可是说来话长啊