引用 5 楼 vichare 的回复:[quote=引用 4 楼 caiwei_cs 的回复:] [quote=引用 3 楼 vichare 的回复:] 首先，sizeof(int)肯定是2的次方数，比如32位是4，64位是8  ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )  的意思就是，如果sizeof(n)是sizeof(int)的倍数，则保持不变，否则返回最小的，大于sizeof(n)的，sizeof(int)的倍数。 比如，如果sizeof(int)是4，那么sizeof(n)是1-4的时候返回4，5-8的时候返回8，以此类推  谢谢了，我算了一下，虽然不知道为什么数学上能够实现这个功能，但是确实可以。[/quote] 首先sizeof(int)写成2进制是1后面若干个0，假设是n个0 sizeof(int) - 1 就是n个1， 取非再和前面的数取与就是清除掉前面那个数的后面n比特。 如果sizeof(n) 后面n比特都是0，那么加sizeof(int)-1不进位，相当于加上再清除掉。 如果sizeof(n) 后面n比特至少有1位是1，那么加了之后会往前进1，相当于sizeof(n)  右移n位，加1，再补充上n个0。[/quote]  万分感谢。！！！

引用 4 楼 caiwei_cs 的回复:[quote=引用 3 楼 vichare 的回复:] 首先，sizeof(int)肯定是2的次方数，比如32位是4，64位是8  ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )  的意思就是，如果sizeof(n)是sizeof(int)的倍数，则保持不变，否则返回最小的，大于sizeof(n)的，sizeof(int)的倍数。 比如，如果sizeof(int)是4，那么sizeof(n)是1-4的时候返回4，5-8的时候返回8，以此类推  谢谢了，我算了一下，虽然不知道为什么数学上能够实现这个功能，但是确实可以。[/quote] 首先sizeof(int)写成2进制是1后面若干个0，假设是n个0 sizeof(int) - 1 就是n个1， 取非再和前面的数取与就是清除掉前面那个数的后面n比特。 如果sizeof(n) 后面n比特都是0，那么加sizeof(int)-1不进位，相当于加上再清除掉。 如果sizeof(n) 后面n比特至少有1位是1，那么加了之后会往前进1，相当于sizeof(n)  右移n位，加1，再补充上n个0。

引用 3 楼 vichare 的回复:首先，sizeof(int)肯定是2的次方数，比如32位是4，64位是8  ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )  的意思就是，如果sizeof(n)是sizeof(int)的倍数，则保持不变，否则返回最小的，大于sizeof(n)的，sizeof(int)的倍数。 比如，如果sizeof(int)是4，那么sizeof(n)是1-4的时候返回4，5-8的时候返回8，以此类推  谢谢了，我算了一下，虽然不知道为什么数学上能够实现这个功能，但是确实可以。

引用 1 楼 user-2 的回复:没细看，应该是基于int的大小进行取整，为了对齐吧。 不过，因为64位系统的出现，这个代码会是有疑问的。 是的，有这个意思，不过不明白为什么。  “这里涉及到内存对齐（alignment）问题，内存对齐跟具体使用的硬件平台有密切关系，比如大家熟知的32位x86平台规定所有的变量地址必须是4的倍数(sizeof(int) = 4)。va机制中用宏_INTSIZEOF(n)来解决这个问题，没有这些宏，va的可移植性无从谈起。”


Question: 求助：文件夹怎么压缩成二进制文件让c语言能够访问到？谢谢大家了

引用 楼主 z616913706 的回复:领导给我了酷派刷机文件，这个文件包括 他说是这些文价太杂了，客户看见不好。让我把它压缩起来，然后又c语言访问这个压缩包，说什么里面加入版本号之类的(c语言能访问压缩包？我去问他，他说你把这个压缩包变成二进制文件不就能访问了吗？)让后调用里面的bat文件开始刷机。这个怎么弄各位大神们？  libz

WinExec The WinExec function runs the specified application.   This function is provided for compatibility with 16-bit Windows. Win32-based applications should use the CreateProcess function.   UINT WinExec(   LPCSTR lpCmdLine,  // address of command line   UINT uCmdShow      // window style for new application );   Parameters lpCmdLine  Pointer to a null-terminated character string that contains the command line (filename plus optional parameters) for the application to be executed. If the name of the executable file in the lpCmdLine parameter does not contain a directory path, the system searches for the executable file in this sequence:  The directory from which the application loaded.  The current directory.  The Windows system directory. TheGetSystemDirectory function retrieves the path of this directory.  The Windows directory. TheGetWindowsDirectory function retrieves the path of this directory.  The directories listed in the PATH environment variable.  uCmdShow  Specifies how a Windows-based application window is to be shown and is used to supply the wShowWindow member of the STARTUPINFO parameter to the CreateProcess function. For a list of the acceptable values, see the description of the nCmdShow parameter of theShowWindow function. For a non-Windows – based application, the PIF file, if any, for the application determines the window state.  Return Values If the function succeeds, the return value is greater than 31.  If the function fails, the return value is one of the following error values:   Value Meaning  0 The system is out of memory or resources.  ERROR_BAD_FORMAT The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).  ERROR_FILE_NOT_FOUND The specified file was not found.  ERROR_PATH_NOT_FOUND The specified path was not found.    Remarks In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached. To avoid waiting for the time out delay, call the GetMessage function as soon as possible in any process started by a call to WinExec.   See Also Processes and Threads Overview, Process and Thread Functions, CreateProcess,GetMessage,GetSystemDirectory,GetWindowsDirectory, LoadModule,ShowWindow

引用 8 楼 zhao4zhong1 的回复:为什么不 WinExec("\"C:\\Program Files\\WinRAR\\rar.exe\" e myrar.rar mydir\\myfile.txt",SW_HIDE); 呢？这位大哥你这个是哪个函数啊？是用的c语言吗？

引用 6 楼 z616913706 的回复:引用 4 楼 starytx 的回复:用程序解压压缩包，然后访问解压文件夹里边的文件？可以使用winrar等压缩库这位大哥，麻烦能说的详细些吗？谢谢了用命令行方式来运行winrar的压缩包程序，需要带一些参数，这个参数具体可以参考winrar的帮助文档。代码示例，仅供参考 		STARTUPINFO si; 		PROCESS_INFORMATION pi;  		ZeroMemory(&si ,sizeof(si)); 		si.cb = sizeof(si); 		// 隐藏窗体 		si.wShowWindow = SW_HIDE; 		si.dwFlags = STARTF_USESHOWWINDOW; 		ZeroMemory(&pi ,sizeof(pi)); 		CString strcmdline; 		strcmdline=("d://winrar//winrar.exe" x -ep -inul -ibck -y -o+ -nd:\\test.rar  \"d:\\test1\" \"d:\\test2\"" );  		BOOL bFind = FALSE; 		// Start the child process.  		if( !CreateProcess( NULL, // No module name (use command line).  			strcmdline.GetBuffer(0),         // Command line.  			NULL,             // Process handle not inheritable.  			NULL,             // Thread handle not inheritable.  			FALSE,            // Set handle inheritance to FALSE.  			0,                // No creation flags.  			NULL,             // Use parent's environment block.  			NULL,             // Use parent's starting directory.  			&si,              // Pointer to STARTUPINFO structure. 			&pi )             // Pointer to PROCESS_INFORMATION structure. 			)  		{ 			return ; 		} 		// Wait until child process exits. 		WaitForSingleObject( pi.hProcess, INFINITE );  		// Close process and thread handles.  		CloseHandle( pi.hProcess ); 		CloseHandle( pi.hThread );

引用 3 楼 xiaohuh421 的回复:zip是标准的开源的算法, 网上有源码可下载. 安装时只需要解压到临时目录, 并运行那个bat文件即可.这位大哥，麻烦你能说的清楚一点吗？谢谢

用程序解压压缩包，然后访问解压文件夹里边的文件？可以使用winrar等压缩库

引用 楼主 z616913706 的回复:领导给我了酷派刷机文件，这个文件包括 他说是这些文价太杂了，客户看见不好。让我把它压缩起来，然后又c语言访问这个压缩包，说什么里面加入版本号之类的(c语言能访问压缩包？我去问他，他说你把这个压缩包变成二进制文件不就能访问了吗？)让后调用里面的bat文件开始刷机。这个怎么弄各位大神们？ 可以使用zlib。  个人建议，仅供参考。

1. 在网上找一个c语言实现的zip库源码. 2. 使用库提供的接口函数对你的文件进行压缩. 3.在使用的时候, 使用库中的解压接口函数对你打包的程序进行解压到临时目录. 4. 运行bat. 过程比较简单,  关键是找到一个zip库.  如果不管文件大小. 可以直接以二进制方式把全部文件的内容连接在一起, 形成你自己的数据文件.  需要运行的时候, 再把这个二进制文件按生成的逆过程, 变成一个一个文件.  //打开一个保存数据的文件 FILE *save = fopen("mydata.dat","wb");  //打开adb.exe文件 FILE *open = fopen("adb.exe", "rb"); fread(buf, 1,size, open); //读取adb.exe的文件内容 fwrite(buf, 1, size, save);//写到mydata.dat中. fclose(open);//关闭adb.exe这个文件  open=fopen("boot.img", "rb"); //打开boot.img文件 fread(buf, 1,size, open); //读取boot.img文件的内容到缓冲区 fwrite(buf, 1, size, save); //写入到mydata.dat中:  注意: 这里写入会写到文件后面, 即前面是adb.exe的内容, 现在又在后面写入了                //                                            boot.img的内容 fclose(open); ............ //到这里, mydata.dat文件中已经存放了adb.exe的内容和boot.img的内容. 即实现了把两个文件合成一个文件了. 当然, 上面只是伪代码, 为了方便还原成两个文件, 需要记录每个文件的大小, 也写入到mydata.dat文件中. 如果有目录结构, 还需要保存文件的目录结构.     引用 6 楼 z616913706 的回复:这位大哥，麻烦能说的详细些吗？谢谢了

引用 7 楼 starytx 的回复:引用 6 楼 z616913706 的回复:[quote=引用 4 楼 starytx 的回复:] 用程序解压压缩包，然后访问解压文件夹里边的文件？可以使用winrar等压缩库这位大哥，麻烦能说的详细些吗？谢谢了用命令行方式来运行winrar的压缩包程序，需要带一些参数，这个参数具体可以参考winrar的帮助文档。代码示例，仅供参考 		STARTUPINFO si; 		PROCESS_INFORMATION pi;  		ZeroMemory(&si ,sizeof(si)); 		si.cb = sizeof(si); 		// 隐藏窗体 		si.wShowWindow = SW_HIDE; 		si.dwFlags = STARTF_USESHOWWINDOW; 		ZeroMemory(&pi ,sizeof(pi)); 		CString strcmdline; 		strcmdline=("d://winrar//winrar.exe" x -ep -inul -ibck -y -o+ -nd:\\test.rar  \"d:\\test1\" \"d:\\test2\"" );  		BOOL bFind = FALSE; 		// Start the child process.  		if( !CreateProcess( NULL, // No module name (use command line).  			strcmdline.GetBuffer(0),         // Command line.  			NULL,             // Process handle not inheritable.  			NULL,             // Thread handle not inheritable.  			FALSE,            // Set handle inheritance to FALSE.  			0,                // No creation flags.  			NULL,             // Use parent's environment block.  			NULL,             // Use parent's starting directory.  			&si,              // Pointer to STARTUPINFO structure. 			&pi )             // Pointer to PROCESS_INFORMATION structure. 			)  		{ 			return ; 		} 		// Wait until child process exits. 		WaitForSingleObject( pi.hProcess, INFINITE );  		// Close process and thread handles.  		CloseHandle( pi.hProcess ); 		CloseHandle( pi.hThread );[/quote]这个好像不符合要求啊！版主，有没有你楼生的那种方法了，谢谢您啊

引用 11 楼 gz_qmc 的回复:才几百K，压缩个鸡巴 直接链接成一个数据文件 运行的时候先还原到临时目录 在调用请问大哥，这个怎么链接？

看看zip源码啥的吧


Question: 关于double和float的关系和区别的问题

#include <stdio.h> #include <stdlib.h>  int main() { 	double  sum = 0; 	double  * pd; 	int i, n; 	 	printf("Please input the number of the exploin:"); 	scanf("%d", &n); 	 	if (n <= 0) 	{ 		printf("error:the number should be bigger than 0!"); 		//getch(); 		exit(1); 	} 	 	pd = (double *)calloc(n, sizeof(double)); 	 	if ( !pd ) 	{ 		printf("error:创建失败!"); 		//getch(); 		exit(1); 	} 	 	for (i=0; i<n; i++) 	{ 		printf("第%d个员工的工资:", i+1); 		//	 scanf("%1f",&pd[i]); 		scanf("%lf", &pd[i]);////////////////////这里的%f改为%lf 	} 	 	printf("\n员工工资表\n"); 	printf("编号\t工资\n"); 	 	for (i=0; i<n; i++) 	{ 		printf("%d\t%lf\n", i+1, pd[i]);//////////////////////////这里的%f改为%lf 		sum += pd[i]; 	} 	 	printf("\n工资总额%f\t平均工资%f\n", sum, sum/n); 	 	return 0; } 这样改了就行了

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

引用 8 楼 u013594535 的回复:[quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 4 楼 mujiok2003 的回复:] scanf("%f",&pd[i]); %f--- float* %lf---double* 要匹配，这个问题人在问。 [/quote] 可是 这个地方我改成1f了，输出结果还是不对啊[/quote] 不是1f,是lf

引用 5 楼 mujiok2003 的回复:[quote=引用 4 楼 mujiok2003 的回复:] scanf("%f",&pd[i]); %f--- float* %lf---double* 要匹配，这个问题人在问。 [/quote] 可是 这个地方我改成1f了，输出结果还是不对啊

楼上动作够快的。

明显是scanf    %lf    么。

引用 4 楼 mujiok2003 的回复:scanf("%f",&pd[i]); %f--- float* %lf---double* 要匹配，这个问题人在问。

应该是楼主没有把该改的地方都改掉，所以出现误差。 一般来说，float型数据在运算时会转换为double型计算，如果你的其中某个过程还是float，那么精度会被截取，然后转换double时用0补上精度计算，就会出现误差。 不知道楼主的具体测试结果，所以只能这样推测。试试下面的代码。  #include <STDIO.H> #include <STDLIB.H>  int main() {    double  sum=0;    double  *pd;    int i,n;     printf("Please input the number of the exploin:");    scanf("%d",&n);     if (n<=0)    {       printf("error:the number should be bigger than 0!");       //getch();       exit(1);    }     pd=(double *)calloc(n,sizeof(double));     if (!pd)    {       printf("error:创建失败!");       //getch();       exit(1);    }     for (i=0;i<n;i++)    {       printf("第%d个员工的工资:",i+1);       //	 scanf("%1f",&pd[i]);       scanf("%f",&pd[i]);    }     printf("\n员工工资表\n");    printf("编号\t工资\n");     for (i=0;i<n;i++)    {       printf("%d\t%f\n",i+1,pd[i]);       sum+=pd[i];    }     printf("\n工资总额%f\t平均工资%f\n",sum,sum/n);     return 0; }

float改成double是不会有问题的，你测试结果是什么呢？

浮点数打印？  有请 赵老师的大作：    年终散分＋展示浮点数格式C代码 http://bbs.csdn.net/topics/390676437


Question: 【swu】新手求问！拜托了！

嗯，C语言这样好像不行啊！或许有些编译器可以吧！个人不推荐这样使用数组

根据C语言的规范，在数组定义中使用变量作为维度是不符合语法的。但是，某些编译器，比如gcc，确实可以支持这种做法；然而，某些则不可以。因此，不应使用这种特性。

//在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19

引用 6 楼 u012586257 的回复:[quote=引用 4 楼 user-5 的回复:] [quote=引用 3 楼 u014016447 的回复:] [quote=引用 1 楼 user-5 的回复:] 程序在编译的时候，就需要给数组分配内存 你对p的赋值操作是在程序启动之后，所以编译时数组长度未知  那我要怎样编写程序才可以解决这样的问题哎？[/quote] 万分抱歉，我上面的说法是错的，请无视。 你程序中错误之处在于，定义二维数组g[][p]时，没有指定第一维的大小。根据后面的代码，第一维的小大是3. 所以你把g[][p]改成g[3][p]，应该就可以了。  之前我说的用p来指定数组第二维的大小，为什么这种方法也可以，我也不是很明白。希望哪位能解释下。[/quote] 我认为改成g[3][p]也不行，不知道p大小不可能静态分配内存。 这里大概只能动态分配内存再转换成数组指针访问吧[/quote]      我从外面输入了一个数值给P呀！   如果我直接把p写成4就可以，为什么从外面赋值给p，再用p定义该二维数组的长度就不可以了呢？

引用 5 楼 u012421456 的回复:可以把main函数里边的前三行去掉，然后把数组中的p改为一个数值  我就是想从外面输入一个数来定义二维数组的长度哎！

引用 4 楼 user-5 的回复:[quote=引用 3 楼 u014016447 的回复:] [quote=引用 1 楼 user-5 的回复:] 程序在编译的时候，就需要给数组分配内存 你对p的赋值操作是在程序启动之后，所以编译时数组长度未知  那我要怎样编写程序才可以解决这样的问题哎？[/quote] 万分抱歉，我上面的说法是错的，请无视。 你程序中错误之处在于，定义二维数组g[][p]时，没有指定第一维的大小。根据后面的代码，第一维的小大是3. 所以你把g[][p]改成g[3][p]，应该就可以了。  之前我说的用p来指定数组第二维的大小，为什么这种方法也可以，我也不是很明白。希望哪位能解释下。[/quote] 我认为改成g[3][p]也不行，不知道p大小不可能静态分配内存。 这里大概只能动态分配内存再转换成数组指针访问吧

可以把main函数里边的前三行去掉，然后把数组中的p改为一个数值

引用 3 楼 u014016447 的回复:[quote=引用 1 楼 user-5 的回复:] 程序在编译的时候，就需要给数组分配内存 你对p的赋值操作是在程序启动之后，所以编译时数组长度未知  那我要怎样编写程序才可以解决这样的问题哎？[/quote] 万分抱歉，我上面的说法是错的，请无视。 你程序中错误之处在于，定义二维数组g[][p]时，没有指定第一维的大小。根据后面的代码，第一维的小大是3. 所以你把g[][p]改成g[3][p]，应该就可以了。  之前我说的用p来指定数组第二维的大小，为什么这种方法也可以，我也不是很明白。希望哪位能解释下。

引用 1 楼 user-5 的回复:程序在编译的时候，就需要给数组分配内存 你对p的赋值操作是在程序启动之后，所以编译时数组长度未知  那我要怎样编写程序才可以解决这样的问题哎？

那我要怎样编写程序才可以解决这样的问题哎？


Question: 关于文件读入然后写的大小改变问题，回复的马上有对象！

因为你写文件以后没有close文件，因此写的内容在内存缓冲中，没有真正写入到文件中。

仅供参考#include <sys\stat.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <string.h> #define MAX_CLU_BYTES 65536 FILE *fo; int fh; __int64 offs,offs1; __int64 rvi64; int rv,wrv; unsigned char buf[MAX_CLU_BYTES]; char ofn[_MAX_PATH]; char offstr[80]; void strcpybutcomma(char *t,char *s) {     char c;      while (1) {         c = *s++;         if (','!=c) *t++ = c;         if (0==c) break;     } } void main(int argc,char **argv) {     if (argc<3) {         printf("Copy File Tail.\n");         printf("Usage:\n");         printf("    cft filename.ext offset_begin[-offset_end]\n");         printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n");         printf("Note: Byte at offset_end is NOT included.\n");         printf("Example:\n");         printf("    cft abc.rar 12345\n");         printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");         printf("    cft abc.rar 123-12345\n");         printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");         printf("    cft abc.rar 0xAB-0xCD\n");         printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");         return;     }     strcpybutcomma(offstr,argv[2]);     rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);     if (rv==0) {         printf("offset %s is not number\n",argv[2]);         return;     }     fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYWR);     if (fh==-1) {         printf("_sopen %s errno=%d\n",argv[1],errno);         return;     }     if (rv==1) {         offs1=_filelengthi64(fh);         if (offs1==-1i64) {             printf("%I64=_filelengthi64 errno=%d\n",offs1,errno);             _close(fh);             return;         }     } else {//rv==2         if (offs1<offs) {             printf("%s offset_begin>offset_end error\n",argv[2]);             _close(fh);             return;         }     }     rvi64=_lseeki64(fh,offs,SEEK_SET);     if (rvi64!=offs) {         printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno);         _close(fh);         return;     }     sprintf(ofn,"%s-",offstr);     strcat(ofn,argv[1]);     fo=fopen(ofn,"wb");     if (fo==NULL) {         _close(fh);         printf("fopen %s error\n",ofn);         return;     }     cprintf("\n%I64u\r",offs);     while (1) {         rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));         if (rv==0) break;//         if (rv<0) {             fclose(fo);             _close(fh);             printf("_read %s offset %I64u error\n",argv[1],offs);             return;         }         wrv=fwrite(buf,1,rv,fo);         if (wrv!=rv) {             fclose(fo);             _close(fh);             printf("fwrite %s error\n",ofn);             return;         } else {             offs+=rv;             cprintf("%I64u\r",offs);             if (offs>=offs1) break;//         }     }     fclose(fo);     _close(fh);     printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn); }


Question: 如何调用，才能让MEMU_FOCUS_AT_AUTOFILP 的值为 0?

__sset_menu_id_e_pdf::MEMU_FOCUS_AT_AUTOFILP


Question: 不知道是程序哪里出错了，求帮助。

下次发全部代码不好吗

没包含math.h文件

仅供参考#include <stdio.h> #include <math.h> #ifndef M_PI #define M_PI       3.14159265358979323846 #endif #define W 80 #define H 20 char s[W][H]; double x,y; int i,j,i1; void main() {     for (j=0;j<H;j++)         for (i=0;i<W;i++)             s[i][j]=' ';     i1=0;     for (x=0.0;x<=359.0;x+=1.0) {         i=(int)(x*W/360.0);         if (i<0) i=0;         if (i>W-1) i=W-1;         y=sin(x*M_PI/180.0);         j=(int)(H/2-(H/2-1)*y);         if (j<0) j=0;         if (j>H-1) j=H-1;         if (i1!=i) {             s[i][j]='*';             i1=i;         }     }     printf("sin\n");     for (j=0;j<H;j++) {         for (i=0;i<W;i++) {             printf("%c",s[i][j]);         }         printf("\n");     }     for (j=0;j<H;j++)         for (i=0;i<W;i++)             s[i][j]=' ';     i1=0;     for (x=0.0;x<=359.0;x+=1.0) {         i=(int)(x*W/360.0);         if (i<0) i=0;         if (i>W-1) i=W-1;         y=cos(x*M_PI/180.0);         j=(int)(H/2-(H/2-1)*y);         if (j<0) j=0;         if (j>H-1) j=H-1;         if (i1!=i) {             s[i][j]='*';             i1=i;         }     }     printf("cos\n");     for (j=0;j<H;j++) {         for (i=0;i<W;i++) {             printf("%c",s[i][j]);         }         printf("\n");     } } //sin // //              ************* //            **             ** //          **                 ** //        **                     ** //      **                         ** //     *                             * //   **                               ** //  *                                   * // *                                     ** //                                         *                                     * //                                          *                                   * //                                           **                               ** //                                             *                             * //                                              **                         ** //                                                **                     ** //                                                  **                 ** //                                                    **             ** //                                                      ****** ****** //                                                            * //cos // // ******                                                                   ****** //       **                                                               ** //         **                                                           ** //           **                                                       ** //             **                                                   ** //               *                                                 * //                **                                             ** //                  *                                           * //                   *                                         * //                    **                                     ** //                      *                                   * //                       **                               ** //                         *                             * //                          **                         ** //                            **                     ** //                              **                 ** //                                **             ** //                                  ****** ****** //                                        *

#include <math.h>


Question: JNI 报错error: request for member ‘FindClass’ in something

同求答案，特来标记


Question: 关于skydriver（同步客户端win8）的实现原理的提问

没有大神吗 求助啊


Question: sprintf 的问题

引用 6 楼 niceteamwork 的回复:[quote=引用 4 楼 user-3 的回复:] 你的字符指针szsql指向了一个常量字符串""；所以对它进行操作是不可以的，如果定义成字符数组是可以的 哦，我定义成 char sql[512]后，结果是没问题了，但是调试动态链接库的控制台引用程序的黑框框一闪而过，这是为啥[/quote] 在cmd窗口中运行。

引用 4 楼 user-3 的回复:你的字符指针szsql指向了一个常量字符串""；所以对它进行操作是不可以的，如果定义成字符数组是可以的 哦，我定义成 char sql[512]后，结果是没问题了，但是调试动态链接库的控制台引用程序的黑框框一闪而过，这是为啥

char * szsql = ""; 这样的定义方法，szsql指针指向的是只读存储区。再用sprintf往只读存储区写的时候，肯定会报segment fault。 定义局部的字符数组，是在栈上分配的空间，可以自由的进行读写

引用 1 楼 zhao4zhong1 的回复:char * szsql = ""; 应改为 char szsql[512]; 为啥，赵老师？

这是错误的图片，我看了sprintf，貌似是这么用的，就是不知道为什么错了。

char * szsql = ""; 应改为 char szsql[512];


Question: 现在学c语言还需要深入的学吗，还是只为了学其他编程工具打基础。

不客气

引用 13 楼 u012421456 的回复:嗯，个人是这么认为的，虽然有很多人说学了C学其他高级语言就容易上手，事实也是如此，但C非常不好学啊！所以我认为如果不想在C方面发展，看了谭浩强的C语言就可以了，当然，如果想深入就要再多看些书了恩恩  谢谢你的建议

引用 11 楼 u012421456 的回复:[quote=引用 楼主 u013720580 的回复:] 现在学c语言还需要深入的学吗，还是只为了学其他编程工具打基础。 如果想深入的学习c语言请大神们介绍几本书。 是深入还是仅仅为学习其他打基础要看lz想咋样，想往哪儿块发展 关于书籍，这样的问题已经见过好几次了，我就发俩地址吧，这两个说的都不错，lz可以看看——http://bbs.csdn.net/topics/390638386 ——http://blog.csdn.net/thefutureisour/article/details/7598775[/quote]意思就是说我要是为了学其他编程工具打基础就不用在c上花太多时间了吧

引用 6 楼 yzkdj 的回复:[quote=引用 楼主 u013720580 的回复:] 现在学c语言还需要深入的学吗，还是只为了学其他编程工具打基础。 如果想深入的学习c语言请大神们介绍几本书。  最好看《C和指针》，由浅入深地讲，C PRIMER PLUS虽然讲的很详细，但都是只讲浅层次。 如果节省时间的话，建议看《C和指针》-->《C陷阱与缺陷》-->《C专家编程》[/quote]现在学c还需要深入的学吗，还是为学其他的打基础

引用 楼主 u013720580 的回复:现在学c语言还需要深入的学吗，还是只为了学其他编程工具打基础。 如果想深入的学习c语言请大神们介绍几本书。 是深入还是仅仅为学习其他打基础要看lz想咋样，想往哪儿块发展 关于书籍，这样的问题已经见过好几次了，我就发俩地址吧，这两个说的都不错，lz可以看看——http://bbs.csdn.net/topics/390638386 ——http://blog.csdn.net/thefutureisour/article/details/7598775

学习Python，配合C在Linux下开发，很爽很有前途！

学python

直接动手做些小程序吧，实现一些功能，学起来更有成就感。

引用 楼主 u013720580 的回复:现在学c语言还需要深入的学吗，还是只为了学其他编程工具打基础。 如果想深入的学习c语言请大神们介绍几本书。  最好看《C和指针》，由浅入深地讲，C PRIMER PLUS虽然讲的很详细，但都是只讲浅层次。 如果节省时间的话，建议看《C和指针》-->《C陷阱与缺陷》-->《C专家编程》

很久也在纠结这个问题。

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 u013720580 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  《C Primer Plus中文版》那是什么，学c语言的吗 [/quote] 看了就知道。[/quote]哦哦，谢了

引用 2 楼 u013720580 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  《C Primer Plus中文版》那是什么，学c语言的吗 [/quote] 看了就知道。

引用 1 楼 zhao4zhong1 的回复:先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  《C Primer Plus中文版》那是什么，学c语言的吗


Question: note: expected ‘char’ but argument is of type ‘ch怎么回事呢

char *lgm="i love china!"; 改为 char lgm[30]="i love china!"; 再试试？

引用 4 楼 zhao4zhong1 的回复:C怎么用Java VM运行？  因为我用到JNI

C怎么用Java VM运行？

引用 楼主 lgmsyy 的回复:char *lgm="i love china!";//我想以字符串作为传输传递给testInit函数，提示我错误 imghandle = testInitTHFaceID(lgm,frMode);  ---------------- 函数如下 int testInit(char *Path,int mode){   printf("%s\n",Path);	   return 1; } ------------- note: expected ‘char’ but argument is of type ‘ch 我应该怎么更改呢。  刚才说错了，加上也不行，编译没问题，执行的时候通过不了 报错如下： # An unexpected error has been detected by HotSpot Virtual Machine: # #  SIGSEGV (0xb) at pc=0xb76de821, pid=8129, tid=3076957888 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_22-b03 mixed mode, sharing) # Problematic frame: # C  [libc.so.6+0x73821] # # An error report file with more information is saved as hs_err_pid8129.log # # If you would like to submit a bug report, please visit: #   http://java.sun.com/webapps/bugreport/crash.jsp # 已放弃

引用 1 楼 zhao4zhong1 的回复:int testInit(const char *Path,int mode){ ?  const去掉也不行啊


Question: 返回结构体指针类型，出错

引用 4 楼 qingtianjushi 的回复:[quote=引用 3 楼 lming_08 的回复:] MyFile * MyFileOpen(char * fname, char * ftype)  { MyFile * ss; int a=100; short Mlevel=100; int Mflag=987; int * Mbuffer=&a;    ss->level=Mlevel; ss->flag=Mflag; ss->buffer=Mbuffer;       return ss; 这个里面的ss一离开{}，就被销毁了；要使用malloc申请 另外，建议调整下函数，将MyFile的申请放在函数外面申请，然后将指针传到MyFileOpen()里面，这样的好处是外面申请后不会忘记释放  嗯，是的，如果在内部申请，离开就会被销毁。但是多传入一个参数，导致这个函数参数有点复杂了。 	return ss; 	free(ss); 先返回，再销毁，这样应该没问题吧？[/quote] 这样就大错特错了！ return ss;  //执行完这句就返回了，后面的free(ss)根本就不会执行！ free(ss); 另外，你需要弄清楚栈内存和堆内存的区别，如果在内部申请，离开就会被销毁这句话不对，离开{}作用域会被销毁只是针对栈内存，用malloc申请是在堆内存，申请堆内存不会自动释放，必须手动释放free()。

引用 3 楼 lming_08 的回复:MyFile * MyFileOpen(char * fname, char * ftype)  { MyFile * ss; int a=100; short Mlevel=100; int Mflag=987; int * Mbuffer=&a;    ss->level=Mlevel; ss->flag=Mflag; ss->buffer=Mbuffer;       return ss; 这个里面的ss一离开{}，就被销毁了；要使用malloc申请 另外，建议调整下函数，将MyFile的申请放在函数外面申请，然后将指针传到MyFileOpen()里面，这样的好处是外面申请后不会忘记释放  嗯，是的，如果在内部申请，离开就会被销毁。但是多传入一个参数，导致这个函数参数有点复杂了。 	return ss; 	free(ss); 先返回，再销毁，这样应该没问题吧？

MyFile * MyFileOpen(char * fname, char * ftype)  ss没有分配内存是个野指针，赋值会导致出现内存异常

要用malloc给ss先分配内存。  引用 楼主 qingtianjushi 的回复://返回结构体指针类型，出错. #include<stdio.h> typedef struct Fdata { 	short level; 	unsigned int flag; 	int * buffer; }MyFile; MyFile * MyFileOpen(char * fname, char * ftype) ; int main() { 	MyFile *fp=MyFileOpen("",""); 	printf("level is %d \n",fp->level); //应该等于100 	printf("flag is %d \n",fp->flag);//应该等于987 	printf("buffer ADD is %x \n",fp->buffer);//应该输出a的地址   	return 0; } MyFile * MyFileOpen(char * fname, char * ftype)  { 	MyFile * ss; 	int a=100; 	short Mlevel=100; 	int Mflag=987; 	int * Mbuffer=&a; 	  	 	ss->level=Mlevel; 	ss->flag=Mflag; 	ss->buffer=Mbuffer;       	return ss; }


Question: 关于realloc和free

引用 11 楼 zhao4zhong1 的回复:[quote=引用 9 楼 yiyefangzhou24 的回复:] 找到原因了，realloc少分配了一个字节，最后的\0，这个函数心有余悸啊，擦 “多一少一”问题占程序员常犯错误的10%以上！ [/quote] 避免“多一少一”问题的方法之一是将比如≤10甚至≤5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

引用 9 楼 yiyefangzhou24 的回复:找到原因了，realloc少分配了一个字节，最后的\0，这个函数心有余悸啊，擦 “多一少一”问题占程序员常犯错误的10%以上！

请判断每个函数的返回值！

找到原因了，realloc少分配了一个字节，最后的\0，这个函数心有余悸啊，擦

free(p); return NULL; 更正楼上笔误，顺序反了

额。。。char * function1() {        char * p;char * p2;        p=(char *)malloc(x);        p2=(char *)realloc(p,x+y);        if(p2==NULL)        {              return NULL;              free(p);        }        p=p2;        return p; } void main() {       char * p;       p=function1();       if(p!=NULL)           free(p); }这样还是有错，我觉得我realloc的写法没错吧？

MALLOC Section: Linux Programmer's Manual (3 ) Updated: 1993-04-04  --------------------------------------------------------------------------------    NAME calloc, malloc, free, realloc - Allocate and free dynamic memory    SYNOPSIS #include <stdlib.h>  void *calloc(size_t nmemb, size_t size); void *malloc(size_t size); void free(void *ptr); void *realloc(void *ptr, size_t size);     DESCRIPTION calloc() allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero.  malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared.   free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is NULL, no operation is performed.   realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the call is equivalent to malloc(size); if size is equal to zero, the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.     RETURN VALUE For calloc() and malloc(), the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of variable, or NULL if the request fails.  free() returns no value.   realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched - it is not freed or moved.     CONFORMING TO ANSI-C    SEE ALSO brk(2), posix_memalign(3)    NOTES The Unix98 standard requires malloc(), calloc(), and realloc() to set errno to ENOMEM upon failure. Glibc assumes that this is done (and the glibc versions of these routines do this); if you use a private malloc implementation that does not set errno, then certain library routines may fail without having a reason in errno.  Crashes in malloc(), free() or realloc() are almost always related to heap corruption, such as overflowing an allocated chunk or freeing the same pointer twice.   Recent versions of Linux libc (later than 5.4.23) and GNU libc (2.x) include a malloc implementation which is tunable via environment variables. When MALLOC_CHECK_ is set, a special (less efficient) implementation is used which is designed to be tolerant against simple errors, such as double calls of free() with the same argument, or overruns of a single byte (off-by-one bugs). Not all such errors can be protected against, however, and memory leaks can result. If MALLOC_CHECK_ is set to 0, any detected heap corruption is silently ignored; if set to 1, a diagnostic is printed on stderr; if set to 2, abort() is called immediately. This can be useful because otherwise a crash may happen much later, and the true cause for the problem is then very hard to track down.     BUGS By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. This is a really bad bug. In case it turns out that the system is out of memory, one or more processes will be killed by the infamous OOM killer. In case Linux is employed under circumstances where it would be less desirable to suddenly lose some randomly picked processes, and moreover the kernel version is sufficiently recent, one can switch off this overcommitting behavior using a command like  # echo 2 > /proc/sys/vm/overcommit_memory  See also the kernel Documentation directory, files vm/overcommit-accounting and sysctl/vm.txt.  --------------------------------------------------------------------------------

REALLOC Section: POSIX Programmer's Manual (P) Updated: 2003  --------------------------------------------------------------------------------    NAME realloc - memory reallocator    SYNOPSIS #include <stdlib.h>    void *realloc(void *ptr, size_t size);      DESCRIPTION The realloc() function shall change the size of the memory object pointed to by ptr to the size specified by size. The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed. If the new size is larger, the contents of the newly allocated portion of the object are unspecified. If size is 0 and ptr is not a null pointer, the object pointed to is freed. If the space cannot be allocated, the object shall remain unchanged.   If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size.   If ptr does not match a pointer returned earlier by calloc(), malloc(), or realloc() or if the space has previously been deallocated by a call to free() or realloc(), the behavior is undefined.   The order and contiguity of storage allocated by successive calls to realloc() is unspecified. The pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the start (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer shall be returned.     RETURN VALUE Upon successful completion with a size not equal to 0, realloc() shall return a pointer to the (possibly moved) allocated space. If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. If there is not enough available memory, realloc() shall return a null pointer  and set errno to [ENOMEM].     ERRORS The realloc() function shall fail if:   ENOMEM  Insufficient memory is available.   The following sections are informative.     EXAMPLES None.     APPLICATION USAGE None.     RATIONALE None.     FUTURE DIRECTIONS None.     SEE ALSO calloc() , free() , malloc() , the Base Definitions volume of IEEE Std 1003.1-2001, <stdlib.h>     COPYRIGHT Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .  --------------------------------------------------------------------------------

realloc Reallocate memory blocks.  void *realloc( void *memblock, size_t size );  Routine Required Header Compatibility  realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.  Parameters  memblock  Pointer to previously allocated memory block  size  New size in bytes  Remarks  The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.  The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.  realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call   _set_new_mode(1)  early in your program, or link with NEWMODE.OBJ.  When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* REALLOC.C: This program allocates a block of memory for  * buffer and then uses _msize to display the size of that  * block. Next, it uses realloc to expand the amount of  * memory used by buffer and then calls _msize again to  * display the new amount of memory allocated to buffer.  */  #include <stdio.h> #include <malloc.h> #include <stdlib.h>  void main( void ) {    long *buffer;    size_t size;     if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )       exit( 1 );     size = _msize( buffer );    printf( "Size of block after malloc of 1000 longs: %u\n", size );     /* Reallocate and show new size: */    if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) ))          ==  NULL )       exit( 1 );    size = _msize( buffer );    printf( "Size of block after realloc of 1000 more longs: %u\n",              size );     free( buffer );    exit( 0 ); }   Output  Size of block after malloc of 1000 longs: 4000 Size of block after realloc of 1000 more longs: 8000   Memory Allocation Routines  See Also   calloc, free, malloc

况且我按照你这么写在main函数free(p);的时候还是会出错

引用 1 楼 zhao4zhong1 的回复:仅供参考//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; 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>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 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) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 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) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; } 赵大叔，你这段之前我看过了。  buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     .....                 }                 buf=buf2; 这个地方是不是一定要这么用，我看很多资料上都是直接p=(char *)realloc(p,x+y);我忘了写了，我上面代码会判断一下 p=function1(); if(p!=NULL)       free(p); realloc这里在分配内存的时候不是已经把第一个参数的那个指针处理过了（free）为什么还要手动free？


Question: 有谁电脑上有VC6的帮我看看这段SWITCH语句有什么问题

刚才重装了系统，没问题了，原来的程序也是正确的，看来确实是系统出了问题了 谢谢楼上各位，这个没问题了，分不多，热心的朋友又这么多，只能每个人意思一下了 但你们的热情和爱心是分数不能衡量的：）

我记得float 在存储过程中是有误差的，如果我 输入 99.99999 再  (int) 99.9999/10   如  #include <stdio.h>; int main(void) {    float i = 99.999999999999999;         printf(" i = %d\n", (int)i/10);      return 0; }   在VC++ 6.0输出的结果就是，虽然分数是不可能是这样子。。。  ------------------------------------------------  i = 10 Press any key to continue ---------------------------------------------------

确实没问题，我当时可能是电脑出了错了 我最近电脑出了问题了，正准备重新做个系统

lz你的VC6.0什么版的啊？ 我的是完整绿色版，没问题啊

引用 10 楼 u013595256 的回复:[quote=引用 9 楼 romabdwy 的回复:] 我刚才试了上面的三个方案 方案一：在main前面加了void程序正确 方案二：float score=0;程序正确了 方案三：switch ((int)(score/10))这样也正确，将(score/10.0f)弄成这样也是正确的  将方案二和三一起使用也正确，其他组合我就没试了 现在看来是赋值的问题？ 问题出在void main()上面？像这种情况？好像说main推荐的用法是void main()我测试好像没有问题，关于main的问题，现在main只有int main(void)和int main(int argc, char * argv[])两种定义，现在的部分c实现为了兼容之前K&R c的代码才允许void main的[/quote]  嗯将void main()改成int main()也是可以正确执行的，这种问题是什么问题知道吗？如果明天没有人回复我就结贴给分了：）

目测代码没有问题啊，估计是编译器的什么问题

也可能楼主的VC6没打SP6补丁。

引用 12 楼 romabdwy 的回复:嗯将void main()改成int main()也是可以正确执行的，这种问题是什么问题知道吗？如果明天没有人回复我就结贴给分了：） 这种问题为什么真是不太清楚，以前倒也见过几次，都是类似问题，不明白，但我一直是加着void或int，建议lz以后敲代码时也加着吧

#include<stdio.h> main() { 	float score; 	scanf("%f",&score); 	switch((int)(score/10)) 	{ 	case 10: 	case  9: printf("Your score is A\n"); break; 	case  8: printf("Your score is B\n"); break; 	case  7: printf("Your score is C\n"); break; 	case  6: printf("Your score is D\n"); break; 	default : printf("Your score is E\n");  	}  }

引用 9 楼 romabdwy 的回复:我刚才试了上面的三个方案 方案一：在main前面加了void程序正确 方案二：float score=0;程序正确了 方案三：switch ((int)(score/10))这样也正确，将(score/10.0f)弄成这样也是正确的  将方案二和三一起使用也正确，其他组合我就没试了 现在看来是赋值的问题？ 问题出在void main()上面？像这种情况？好像说main推荐的用法是void main()我测试好像没有问题，关于main的问题，现在main只有int main(void)和int main(int argc, char * argv[])两种定义，现在的部分c实现为了兼容之前K&R c的代码才允许void main的

C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value

常量也有类型！ C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

引用 5 楼 cocodada 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] #include<stdio.h> main() {     float score=0.0f;     scanf("%f",&score);     switch((int)(score/10.0f))     {     case 10:     case  9: printf("Your score is A\n"); break;     case  8: printf("Your score is B\n"); break;     case  7: printf("Your score is C\n"); break;     case  6: printf("Your score is D\n"); break;     default : printf("Your score is E\n");      }   }  score是浮点数，在和10运算的时候，10不是会自动类型转换成浮点数类型的么？[/quote] 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

引用 2 楼 zhao4zhong1 的回复:#include<stdio.h> main() {     float score=0.0f;     scanf("%f",&score);     switch((int)(score/10.0f))     {     case 10:     case  9: printf("Your score is A\n"); break;     case  8: printf("Your score is B\n"); break;     case  7: printf("Your score is C\n"); break;     case  6: printf("Your score is D\n"); break;     default : printf("Your score is E\n");      }   }  score是浮点数，在和10运算的时候，10不是会自动类型转换成浮点数类型的么？

同志，vc6太老，有bug的，在vc6中float是要初始化的 #include<stdio.h> main() {     float score=0;     scanf("%f",&score);     switch((int)score/10)     {     case 10:     case  9: printf("Your score is A\n"); break;     case  8: printf("Your score is B\n"); break;     case  7: printf("Your score is C\n"); break;     case  6: printf("Your score is D\n"); break;     default : printf("Your score is E\n");      }   }

没有VC6，也没看出有什么问题。 不过main()这个还是写全的好。  #include <stdio.h>  int main(void) { 	float score; 	scanf("%f", &score); 	switch((int)score/10) 	{ 	case 10: 	case  9: printf("Your score is A\n"); break; 	case  8: printf("Your score is B\n"); break; 	case  7: printf("Your score is C\n"); break; 	case  6: printf("Your score is D\n"); break; 	default: printf("Your score is E\n");  	}  	return 0; }

switch((int)score/10) 似应改为 switch((int)(score/10.0f))


Question: c语言文件的顺序读写程序问题?

输入football.txt


Question: C语言新人  求大神

谢谢各位大神 0.0

代码有两个错误，不能运行，第一个好改，在main（）前边加一个int,最后加一个return 0即可，第二个有些难度，得再看看

IOputData(&List); 中的&应去掉，List已经是LN *类型

IOputData(&List);   换成IOputData(List);

我也是新人啊


Question: 彩票问题（1到36中选7个不同的数）

//1到36中选7个不同的数 #include <stdio.h> #include <stdlib.h> #include <time.h> int d[37]; int i,n,a,b,t; int main() {     srand(time(NULL));     n=36;     for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */     for (i=n;i>1;i--) {/* 打乱1～n */         a=i;b=rand()%i+1;         if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}     }     for (i=1;i<=7;i++) printf("%d ",d[i]);/* 输出1～7 */     printf("\n");     return 0; }

不重复 ：36选1，35选1，.。。。。。。。。。30选1； 可重复 ：36选1，36选1，36选1，。。。。。。。。；

你的程序问题很多，首先大循环不能保证一定能产生7个数字，相同数字的判定也有问题；我的程序你参考一下# include <stdio.h> # include <stdlib.h> # include <time.h> int main() { 	int arr[7]; 	int val[37] = {0};//记录数字的标志位；1表示已有该数字 	int i = 0; 	int num;  	srand((unsigned)time(NULL)); 	while(i < 7) 	{ 		num = rand() % 36 + 1; 		if(val[num] == 0) 		{ 			val[num] = 1; 			arr[i] = num; 			i++; 		} 	} 	for(i = 0; i < 7; i++) 		printf("arr[%d] = %d\n", i, arr[i]); return 0; }


Question: 软件破解

引用 3 楼 user-3 的回复:去看雪论坛学 同意。 学不会的话，还可以掏钱请我破解。

引用 4 楼 zhao4zhong1 的回复:[quote=引用 3 楼 user-3 的回复:] 去看雪论坛学 同意。 学不会的话，还可以掏钱请我破解。[/quote]  不要这样啊，我也是工作需要才去破解的，并不是想专门去破解别人的劳动万里的！

主要是反汇编

去看雪论坛学

引用 1 楼 merlinfang 的回复:主要是反汇编  具体步骤是什么?


Question: [SWU] putty  中文乱码

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

选择正确的字体和正确的编码


Question: 关于C语言指针的问题，求大神指点

#include <stdio.h> #include <stdlib.h> int main() { 	void *p = NULL ; 	 	printf("p = %p\n",p); 	printf("(int *)p[1] = %p\n",&((int*)p)[1] ); 	printf("(double *)p[i] = %p\n",&((double*)p)[1]);  //	printf("(void *)p[i] = %p",&p[1]); 此处编译错误，因为p是void*类型， //p[1]的值无法计算，[ ]符号是根据指针类型来计算便宜地址，更正之前回复中的错误  	return 0 ; }

A[B]等价于*(A+B)

楼主显然不懂 指针和数组的区别和关系呢！

计算机组成原理→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

我的代码中，输出错了吗？感觉应该没错啊，但是输出的结果不对啊

可是我的代码就是这么写的，为什么这个输出不对呢？

scanf("%d",(此处为地址)); p[i]是变量名，&p[i]就是p[i]的地址咯 // [ ] 是计算便宜地址的符号，int a[3];  a[i] 的地址是 a的地址 + i * sizeof(int) ; pd是指针变量，它的值是一个地址，p[i]的地址是 p的值 + sizeof(指针指向的数据类型（此处为double）)

举个例子哈 数组 int b[5]; 数组名 p就是一个指针常量 所以 *b=b[0];  b=&b[0]    要是在定义一个指针 int *p； p可以这么用 p=a; 结果呢 p[i]就可以等于b[i]啦     数组其实和指针某些方面 可以互用的 还有你说的两个疑惑地地方 是你理解错了 pd[i]是数组 不是指针 我也在学C语言 一起加油哈 坚持！！！

数组的[]操作符代表的意义就是 : a[i] = *(a+i),a代表数组的首地址，及对首地址取i的地址偏移量，最后取地址里的内容

pd[i]  = *(pd+i)   所以我记得c++里 还可以这么写 i[pd]


Question: 快速排序，找不到错误了，希望大神们给找一下

引用 6 楼 wang0635 的回复: int main() {      printf("待排数组为：\n");      for(int i=0;i<LEN;i++)      {           printf("%d,",a[i]);      }      printf("\n");       QuickSort(a,0,LEN); //应该是 LEN - 1 吧 }我晕。。。谢谢！！！

楼上说的对，你的交换函数就错了，应该应用指针传递而不是值传递，这样交换的只是拷贝的值，可以这样修改： void Swap(int *a,int *b) {     int temp=0;     temp=*a;     *a=*b;     *b=temp; } 或者直接使用algorithme库中的swap()函数 另外几点小错误，35行while（true）中true ，c是不支持bool类型的,可以换成1,但我认为你应该修改你的逻辑 以及for(int i = 0;;)你在for语句中定义变量是不被vc6.0支持的，gcc添加 -std=c99 关于你的快排函数有点逻辑混乱，建议你单步调试，看看课本上的代码吧。

引用 3 楼 wang0635 的回复:C语言函数参数是值参数。仔细看看课本，这一段都讲得很详细，一般也拿swap函数做例子确实swap函数有问题，但是结果现在成了 待排数组为： 5,2,4,7,1,3,2,6, 当前P的值是：5 当前Q的值是：5 2,2,4,0,1,3,5,6, 当前P的值是：2 当前Q的值是：2 0,1,2,4,2,3,5,6, 当前P的值是：0 当前Q的值是：0 0,1,2,4,2,3,5,6, 当前P的值是：4 当前Q的值是：4 0,1,2,3,2,4,5,6, 当前P的值是：3 当前Q的值是：3 0,1,2,2,3,4,5,6, 当前P的值是：6 当前Q的值是：6 0,1,2,2,3,4,5,6, 请按任意键继续. . . 我的7去哪了

引用 1 楼 wang0635 的回复:至少Swap函数不对，没有真正对换。用指针做参数Swap函数应该对吧，为什么不对呢？

至少Swap函数不对，没有真正对换。用指针做参数


Question: 【C语言程序】：关于输入日期输出星期的程序问题

COleDateTime::GetDayOfWeek int GetDayOfWeek( ) const;  Return Value  The day of the week represented by the value of this COleDateTime object.  Remarks  Call this member function to get the day of the month represented by this date/time value.  Valid return values range between 1 and 7, where 1=Sunday, 2=Monday, and so on. If the status of this COleDateTime object is not valid, the return value is AFX_OLE_DATETIME_ERROR.  For information on other member functions that query the value of this COleDateTime object, see the following member functions:   GetDay   GetMonth   GetYear   GetHour   GetMinute   GetSecond   GetDayOfYear  COleDateTime Overview |  Class Members |  Hierarchy Chart  See Also   COleDateTime::COleDateTime, COleDateTime::SetDateTime, COleDateTime::operator =, COleDateTime::GetStatus


Question: VS2012 C语言程序 找不到标识符是怎么回事儿？

1、把函数定义搬到前面，或者在前面加上函数声明。 2、 #include <iostream>  using namespace std;  //---------------------------------------------------------- // 快速排序 O(NlogN)  // 返回调整后基准数的位置 int partition(int data[], int low, int high) { 	int i = low, j = high; 	int x = data[low]; 	while (i < j) 	{ 		// 从右向左找小于x的数来填data[i] 		while(i < j && data[j] >= x) 			j--;  		if(i < j) 		{ 			data[i] = data[j]; // 将data[j]填到data[i]中，data[j]就形成了一个新的坑 			i++; 		}  		// 从左向右找大于或等于x的数来填data[j] 		while(i < j && data[i] < x) 			i++;  		if(i < j) 		{ 			data[j] = data[i]; // 将data[i]填到data[j]中，data[i]就形成了一个新的坑 			j--; 		} 	}  	// 退出时，i等于j。将x填到这个坑中。 	data[i] = x;  	return i; }  void quickSort(int data[], int low, int high) { 	if (low < high) 	{ 		int pivot = partition(data, low, high); 		quickSort(data, low, pivot - 1); 		quickSort(data, pivot + 1, high); 	} }  int main() { 	int array[] = {9, 6, 3, 8, 7, 1, 5, 2, 4}; 	int count = sizeof(array) / sizeof(array[0]);  	quickSort(array, 0, 8);  	for(int i = 0; i < count; ++i) 		cout << array[i] << " ";  	cout << endl;  	return 0; }

引用 2 楼 gcy77 的回复:引用 1 楼 user-2 的回复:把swap函数定义挪到partition函数前面去有用！swap和partition都需要移到quicksort前面，还有其他解决办法吗？提醒：这个程序的结果不对，刚运行了一下。。。 其他方法就是追加函数声明 程序运行结果不对，你需要做的是单步调试，看看到底是哪里不对

把swap函数定义挪到partition函数前面去


Question: 一道题，请大家帮我看看为什么vs2013下执行不了，谢谢啦

好像找到原因了，你在VS2013中把scanf的 _s 去掉试试

在VS2012下也可以用，并且是可以连续输入，即计算完输入的两个数后程序不会退出，还可以继续输入两个数，这个会不会是VS2013的问题啊，这些新东西一般都好有些问题，如果不是因为这个，那我就不清楚了，看楼下吧

出来这个东西，在vc中是可以执行的


Question: 刚看了文件映射，有些不明白的地方，求助

这里的不必执行IO操作，是指用户不必显式的执行IO操作，系统会帮你完成这个工作。 映射就是系统将文件的内容与内存的某个区域相关联，系统会将对内存的读写转换成对文件的读写操作。


Question: 关于CRC16算法的问题


Question: C语言字符串中间插入的问题

使用snprintf，合成字符串吧

我也犯过同样的问题， char * a = "I have a %s question";是字符串常量，注意是常量，是不能修改的 char  a[] = "I have a %s question";是字符数组，是可修改的， 并且也要注意内存存储的位置，这两个字符串是存在不同内存区的

仅供参考#include <stdio.h> #include <string.h> #include <locale.h> char s[256]; char *p; int r,n,i; int main() {     setlocale(LC_ALL,"chs");     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //

不用现成函数的想法是不对的。  这个问题先准备一个通常足够大的buffer，做snprintf并得到返回值，如果返回值小于buffer的大小那么格式化完整，否则动态分配一个返回值+1那么大buffer，然后放心的snprintf进去即可。

直接写在代码中的"I have a %s question"是一个常量数组，很多编译器会直接把它放在只读内存区，任何对其内容的修改都是不允许的，很有可能导致程序崩溃——当然重要的不是崩溃不崩溃，而是你不该改变它

引用 2 楼 Keneth_cs 的回复:[quote=引用 1 楼 merlinfang 的回复:] a首先要有那么大的空间， 比如a[100] =  "I have a %s question"; char *b = "incomprehension"; sprintf(a,b); 就可以了 这个我知道，我现在知道的是 假如是直接用字符串直接初始化的指针，能不能也实现替换一段替换后长度比之前长的字符串，会越界吗？？ [/quote] 会的

引用 1 楼 merlinfang 的回复:a首先要有那么大的空间， 比如a[100] =  "I have a %s question"; char *b = "incomprehension"; sprintf(a,b); 就可以了 这个我知道，我现在知道的是 假如是直接用字符串直接初始化的指针，能不能也实现替换一段替换后长度比之前长的字符串，会越界吗？？


Question: 结构体数组溢出

其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

index[i]在运行时其实是这样的：*(idex +i),即在idex的基础上在正向偏移i*（12）个字节的位置（这个12字节，其实就是struct index的大小），再取其中的值，由于你的index之定义了1个元素，那么对于i》=1的情况，所做的诸如 index[i].start赋值，都是在修改index界外的内容；溢出的时，出现什么情况是不一定的，比如你的溢出操作修改了其他进程中正在使用的变量，就会出现问题了，比如造成了空指针操作，程序需肯定就崩溃了。

主要了解一下进程的”虚拟地址空间“概念，你操作的内存如果恰好已被分配，那么读写它是不会出现”段错误“的

个人认为与数组类似，当数组溢出时如果其下一个地址没有存放对于整个系统来说比较重要的数据那么溢出后将下一个地址所存放的数据破坏后，运行是不会出现异常的，同样这样的Bug也是比较难发现的，但一旦有问题或者运行时间长了后所造成的结果将会是致命的。


Question: 关于软件工程专业大三实习

这个世界上就没有精通C这回事！！

可以找吧，我出了学校就是半吊子的C水平，其他各种不会，在深圳找了个公司实习，1600/月

引用 楼主 RJGCSS 的回复:本人大三马上就要面临找工作了。 大三下学期就结束了大学课程，所以想要在暑假找个单位实习。    我想找个关于C程序设计的工作， 希望在Linux环境下。 请问各位， 要找这样一份工作需要具备什么知识呢？ Linux下用C主要做什么开发呢？ 开了一些招聘单位的要求“精通C”， 我想知道到底要超什么方向去努力。     我知道自己现在水平很浅， 薪资方面没有太多要求。 就是希望有一个实习的机会。     实习和正式找工作的流程都一样吗？ 希望各位给些建议。 谢谢！  不知道你C水平咋样，或者说不知道你对计算机和操作系统体系理解程度咋样。 如果你仅仅是C学的好，找个像样的实习工作还是比较难的，毕竟没有太多公司愿意培养新人。不过做一些相对简单的上层后台应用没问题。

《Linux C编程一站式学习》

引用 7 楼 mxgsgtc 的回复:很多啊， 我就是系统方向， 主要是参与编程   请问薪资方面怎么样， 谢谢

很多啊， 我就是系统方向， 主要是参与编程

引用 4 楼 mxgsgtc 的回复:[quote=引用 3 楼 RJGCSS 的回复:]     [quote=引用 2 楼 mxgsgtc 的回复:] 不知道楼主c现在是什么水平，精通的话应该不是针对应届生吧，最好自己搞过点小东西，比如在linux在自己开发过小程序，那样比较好找   你指的是Linux上的图形界面程序， qt方面的还是网络方面的？[/quote] 看自己想干什么方向的，我说的是网络和系统编程方面的[/quote]   Linux C 的应用多吗？ 应届生找网络和系统编程方面的工作怎么样？  的确对这方面了解不多。

个人感觉大学森不要在简历里写“精通”→_→ 网上搜索下嵌入式课程，按照那课程表参考着自学就行了，一搜一大把。

引用 3 楼 RJGCSS 的回复:[quote=引用 2 楼 mxgsgtc 的回复:] 不知道楼主c现在是什么水平，精通的话应该不是针对应届生吧，最好自己搞过点小东西，比如在linux在自己开发过小程序，那样比较好找   你指的是Linux上的图形界面程序， qt方面的还是网络方面的？[/quote] 看自己想干什么方向的，我说的是网络和系统编程方面的

引用 2 楼 mxgsgtc 的回复:不知道楼主c现在是什么水平，精通的话应该不是针对应届生吧，最好自己搞过点小东西，比如在linux在自己开发过小程序，那样比较好找   你指的是Linux上的图形界面程序， qt方面的还是网络方面的？


Question: 两个有序整数集合的交集怎么求

无满意回复！

仅供参考#include <algorithm> #include <iostream> #include <functional> #include <cstring> using namespace std; int main() {     char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;     char *Vowels   = "aeiou" ;     char *AlphaNum = "0123456789abcdef" ;     char result[45] ;     char *last ;      int lenA  = strlen(Alphabet) ;     int lenV  = strlen(Vowels  ) ;     int lenAN = strlen(AlphaNum) ;      cout << "Alphabet = " << Alphabet << endl ;     cout << "Vowels   = " << Vowels   << endl ;     cout << "AlphaNum = " << AlphaNum << endl ;      cout << "\nusing non-predicate versions" << endl ;      //non-predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //non-predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //non-predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      cout << "\nusing predicate versions" << endl ;      //predicate set_difference     last = set_difference(Alphabet, Alphabet+lenA,                           AlphaNum, AlphaNum+lenAN,                           result  , less<char>()) ;     *last = 0 ;     cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_intersection     last = set_intersection(Alphabet, Alphabet+lenA,                             AlphaNum, AlphaNum+lenAN,                             result  , less<char>()) ;     *last = 0 ;     cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;      //predicate set_symmetric_difference     last = set_symmetric_difference(Alphabet, Alphabet+lenA,                                     Vowels  , Vowels  +lenV,                                     result  , less<char>()) ;     *last = 0 ;     cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;      //predicate set_union     last = set_union(Alphabet, Alphabet+lenA,                      AlphaNum, AlphaNum+lenAN,                      result  , less<char>()) ;     *last = 0 ;     cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;      return 0 ; }

如果用Bits表示 求并的操作为 O(1) 转换为Bits表示（或者输入直接转换Bits表示）操作为O（M+N） 输出操作为 O（M+N）

求并的操作为 O((N+M)/8)=O(M+N) 不过操作不一样 不用比较操作，只需要Or 操作

求并的操作为 O(N/8)

引用 1 楼 user-3 的回复:有的，用量子计算机来算，复杂度为O（1）。 求具体算法 O(∩_∩)O

有的，用量子计算机来算，复杂度为O（1）。


Question: 函数中返回static变量引用的疑惑

静态变量只被初始化1次。

引用 3 楼 xgqxgqxx 的回复:[quote=引用 1 楼 mujiok2003 的回复:] static int t=x; 因为这个语句只执行一次。   改成这样试试: static int t ; t = x;  第二次调用的时候t变成5了 但是一返回引用有变回1了这是为啥？？[/quote] 没有改变，还是5，    int t=f(5);     cout<<x<<endl; 因为你输出的是x，输出t就是5;

引用 楼主 xgqxgqxx 的回复:#include <iostream> #include <vector> #include <string> using namespace std;  static int& f(int x) {     static int t=x;     cout<<t<<".."<<x<<endl;     return t; }  int main() {     int x=f(1);     cout<<x<<endl;     int t=f(5);     cout<<x<<endl; }   为啥都是输出1  为什么不是第二次覆盖第一次 而是 第一次覆盖第二次？？？ 代码问题： 1. 为什么要使用static？C++中尽量不要使用static，除非用于类成员和类方法，如果想定义常量，请使用enum或者const；如果想定义全局变量，最好使用未命名的namespace； 2. 引用最好用于占内存较大的对象或结构，也许你只是想试试引用的用法

引用 5 楼 xgqxgqxx 的回复:[quote=引用 4 楼 mujiok2003 的回复:] [quote=引用 3 楼 xgqxgqxx 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] static int t=x; 因为这个语句只执行一次。   改成这样试试: static int t ; t = x;  第二次调用的时候t变成5了 但是一返回引用有变回1了这是为啥？？[/quote]  #include <iostream> //#include <vector> //#include <string> using namespace std;  static int& f(int x) {     static int t;      t=x;     cout<<t<<".."<<x<<endl;     return t; }  int main() {     int &x=f(1);     cout<<x<<endl;     f(5);     cout<<x<<endl; } [/quote] 为啥第二次这样写就改变了？？？您能详细的解释下吗？？[/quote]  因为main中x是f中的t的引用

引用 4 楼 mujiok2003 的回复:[quote=引用 3 楼 xgqxgqxx 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] static int t=x; 因为这个语句只执行一次。   改成这样试试: static int t ; t = x;  第二次调用的时候t变成5了 但是一返回引用有变回1了这是为啥？？[/quote]  #include <iostream> //#include <vector> //#include <string> using namespace std;  static int& f(int x) {     static int t;      t=x;     cout<<t<<".."<<x<<endl;     return t; }  int main() {     int &x=f(1);     cout<<x<<endl;     f(5);     cout<<x<<endl; } [/quote] 为啥第二次这样写就改变了？？？您能详细的解释下吗？？

引用 3 楼 xgqxgqxx 的回复:[quote=引用 1 楼 mujiok2003 的回复:] static int t=x; 因为这个语句只执行一次。   改成这样试试: static int t ; t = x;  第二次调用的时候t变成5了 但是一返回引用有变回1了这是为啥？？[/quote]  #include <iostream> //#include <vector> //#include <string> using namespace std;  static int& f(int x) {     static int t;      t=x;     cout<<t<<".."<<x<<endl;     return t; }  int main() {     int &x=f(1);     cout<<x<<endl;     f(5);     cout<<x<<endl; }

引用 1 楼 mujiok2003 的回复:static int t=x; 因为这个语句只执行一次。   改成这样试试: static int t ; t = x;  第二次调用的时候t变成5了 但是一返回引用有变回1了这是为啥？？


Question: linux下怎么发送syslog到相应的服务器

请问楼主，问题解决了没有？我现在也遇到这个问题了。。 我是ubuntu14.04    /etc/rsyslog.conf 文件最后一行 加入了： *.*        @ip   重启了服务  但windows7 系统上 安装的 kiwi_syslog 服务端接收不到ubuntu发来的消息，可以接受到本机的syslog日志。。

引用 2 楼 gigglesun 的回复:ftp首选 也可考虑用scp对方测试 只要求我们设备能发送syslog协议的日志  他们使用Kiwi_Syslogd作为服务器能接收到就可以通过，问题是我的linux系统设备该怎么发送syslog协议的报文，谢谢

引用 1 楼 zmlovelx 的回复:email   ftp   scp   socket ==对方测试 只要求我们设备能发送syslog协议的日志  他们使用Kiwi_Syslogd作为服务器能接收到就可以通过，问题是我的linux系统设备该怎么发送syslog协议的报文，谢谢

引用 楼主 chezzz 的回复:大家好！由于需要，我需在linux下把一些日志信息以syslog协议的标准发送到相应的服务器，我想请教下，该怎么做。网上看到一些说在/etc/rsyslog.conf文件中加入服务器IP即可，我查看了我们设备下的linux，没有此配置文件，因为是小设备linux是裁剪的。想要移植的话该怎么做，哪个能帮助下，谢谢。对方测试 只要求我们设备能发送syslog协议的日志  他们使用Kiwi_Syslogd作为服务器能接收到就可以通过，问题是我的linux系统设备该怎么发送syslog协议的报文，谢谢

ftp首选 也可考虑用scp

email   ftp   scp   socket ==


Question: epoll接收火狐浏览器的链接后，能读到http表头，但是发送给浏览器的数据，浏览器不显示？

先使用同步读写确认HTTP协议OK，然后再引入epoll。


Question: 求大神看看为什么这个程序没法执行，急求

#include<stdio.h> void fun(int*a,int*b) {     int t;     if(*a>*b) {         t=*a;         *a=*b;         *b=t;     } } int main() {     int x=8,y=4;     printf("%d%d\n",x,y);     fun(&x,&y);     printf("%d%d",x, y);     return 0; }

已经找到原因了

把指针好好看下吧


Question: c语言 如何记录指针所申请内存空间大小

引用 16 楼 u012526168 的回复:[quote=引用 14 楼 lovesmiles 的回复:] [quote=引用 12 楼 u012526168 的回复:] [quote=引用 8 楼 zxcvbnm0014 的回复:] /*(p+20) = 'z';  字符数组越界了。p指针指向的数据是char型的，p+1就向后移动一个char所占内存的大小。 谢谢回答，但是我问的不是为什么报错，我是想问机器是怎么知道指针所指的对象的长度的[/quote]  你是怎么知道机器知道了指针所指对象的长度？机器完全不知道它所指向对象的长度，只知道指针类型，而这个类型是你声明了的，就这么简单。没有问题了吧？你不信，你随便给指针赋个值完后再访问看看，你的程序肯定死掉，因为程序根本就没有你想像的那样知道它指向了什么，指向的东西有多长。[/quote]  其实我原来是这样想的啊。 char *p = (char*)malloc(sizeof(char)); *(p+0)= 'a'; *(p+1)='b'; *(p+2)='c'; *(p+3)='\0'; printf("%s",p); 结果是abc 符合我的理解。 然而 char a[]= "hello world!"; char *p = a; *(p+12)= 'a'; *(p+13)='b'; *(p+14)='\0'; printf("%s",p); 它的结果我以为是hello world!abc   但是它却崩了，我就开始怀疑之前认为的，这里为什么会崩呢，我以为是机器在某个地方标记了其长度，越界了所以就崩了。 那如果不是这样，这里为什么会崩？ 1中的char *p = a;和2中的char *p = (char*)malloc(sizeof(char));的什么区别导致了上述结果呢？ [/quote]  这两个是有区别的，malloc 是从堆中分配内存，char a[]是由系统从栈中分配内存，这两块内存位置是不一样的。堆内存访问越界也是可能崩溃的，只不过因为你的堆没有分配其它数据，越界也没有破坏什么，所以你没有碰到崩溃。栈数据的空间是很紧凑的，所以访问越界常常崩溃掉。  这个崩溃和你说的系统知道了指针所指的长度没有关系。

引用 14 楼 lovesmiles 的回复:[quote=引用 12 楼 u012526168 的回复:] [quote=引用 8 楼 zxcvbnm0014 的回复:] /*(p+20) = 'z';  字符数组越界了。p指针指向的数据是char型的，p+1就向后移动一个char所占内存的大小。 谢谢回答，但是我问的不是为什么报错，我是想问机器是怎么知道指针所指的对象的长度的[/quote]  你是怎么知道机器知道了指针所指对象的长度？机器完全不知道它所指向对象的长度，只知道指针类型，而这个类型是你声明了的，就这么简单。没有问题了吧？你不信，你随便给指针赋个值完后再访问看看，你的程序肯定死掉，因为程序根本就没有你想像的那样知道它指向了什么，指向的东西有多长。[/quote]  其实我原来是这样想的啊。 char *p = (char*)malloc(sizeof(char)); *(p+0)= 'a'; *(p+1)='b'; *(p+2)='c'; *(p+3)='\0'; printf("%s",p); 结果是abc 符合我的理解。 然而 char a[]= "hello world!"; char *p = a; *(p+12)= 'a'; *(p+13)='b'; *(p+14)='\0'; printf("%s",p); 它的结果我以为是hello world!abc   但是它却崩了，我就开始怀疑之前认为的，这里为什么会崩呢，我以为是机器在某个地方标记了其长度，越界了所以就崩了。 那如果不是这样，这里为什么会崩？ 1中的char *p = a;和2中的char *p = (char*)malloc(sizeof(char));的什么区别导致了上述结果呢？

引用 17 楼 lovesmiles 的回复:[quote=引用 16 楼 u012526168 的回复:] [quote=引用 14 楼 lovesmiles 的回复:] [quote=引用 12 楼 u012526168 的回复:] [quote=引用 8 楼 zxcvbnm0014 的回复:] /*(p+20) = 'z';  字符数组越界了。p指针指向的数据是char型的，p+1就向后移动一个char所占内存的大小。 谢谢回答，但是我问的不是为什么报错，我是想问机器是怎么知道指针所指的对象的长度的[/quote]  你是怎么知道机器知道了指针所指对象的长度？机器完全不知道它所指向对象的长度，只知道指针类型，而这个类型是你声明了的，就这么简单。没有问题了吧？你不信，你随便给指针赋个值完后再访问看看，你的程序肯定死掉，因为程序根本就没有你想像的那样知道它指向了什么，指向的东西有多长。[/quote]  其实我原来是这样想的啊。 char *p = (char*)malloc(sizeof(char)); *(p+0)= 'a'; *(p+1)='b'; *(p+2)='c'; *(p+3)='\0'; printf("%s",p); 结果是abc 符合我的理解。 然而 char a[]= "hello world!"; char *p = a; *(p+12)= 'a'; *(p+13)='b'; *(p+14)='\0'; printf("%s",p); 它的结果我以为是hello world!abc   但是它却崩了，我就开始怀疑之前认为的，这里为什么会崩呢，我以为是机器在某个地方标记了其长度，越界了所以就崩了。 那如果不是这样，这里为什么会崩？ 1中的char *p = a;和2中的char *p = (char*)malloc(sizeof(char));的什么区别导致了上述结果呢？ [/quote]  这两个是有区别的，malloc 是从堆中分配内存，char a[]是由系统从栈中分配内存，这两块内存位置是不一样的。堆内存访问越界也是可能崩溃的，只不过因为你的堆没有分配其它数据，越界也没有破坏什么，所以你没有碰到崩溃。栈数据的空间是很紧凑的，所以访问越界常常崩溃掉。  这个崩溃和你说的系统知道了指针所指的长度没有关系。[/quote]  太谢谢了。

你要弄清楚指针变量的概念，指针变量存储区域的是一个地址 这个地址是指针所指向内存区域的首地址，而指针所指的数据类型是决定所以想的那块地址的长度。

引用 12 楼 u012526168 的回复:[quote=引用 8 楼 zxcvbnm0014 的回复:] /*(p+20) = 'z';  字符数组越界了。p指针指向的数据是char型的，p+1就向后移动一个char所占内存的大小。 谢谢回答，但是我问的不是为什么报错，我是想问机器是怎么知道指针所指的对象的长度的[/quote]  你是怎么知道机器知道了指针所指对象的长度？机器完全不知道它所指向对象的长度，只知道指针类型，而这个类型是你声明了的，就这么简单。没有问题了吧？你不信，你随便给指针赋个值完后再访问看看，你的程序肯定死掉，因为程序根本就没有你想像的那样知道它指向了什么，指向的东西有多长。

引用 10 楼 baichi4141 的回复:建议楼主不要空想 稍微学一下汇编语言，看看你写的代码被编译成了哪些机器命令，就知道空想是多么的无价值了  指针指向内存中的一个位置，这个位置存在或不存在，都和指针没关系 如果你申请了一块内存，那么内存管理机制就会记录下分给你的这块内存的大小及位置。如果指针指向的不是你申请的内存，那么这块内存有谁何时怎么样处理，你都不应该猜想。 char a[] = "hello world!";这条语句定义了一个局部数组，而数组在编译后运行时根本不记录其大小，越界修改将导致修改其他数据从而程序运行出错甚至崩溃，这一切都是程序员自作自受，没有任何安全机制供程序员撒娇。 唉，都不好意思说我已经学过汇编了，当时没好好学。 我提这个问题是这样想的：像i386的段描述符八个字节一部分是用于标记段基址的，一部分是标记段限长的，那为什么指针的四个字节全部标记的是所指对象的地址，没有标记所指对象的长度，那机器是如何知道其长度的，是不是内存管理机制有片空间专门用于记录指针长度的？ 刚才又做了几个实验，字符指针申请了一个字节的内存空间，但是可以在*(P+7)处给予赋值，确实如你所说。 哈哈我都忘了可以反汇编来看执行过程。 谢谢了。

引用 8 楼 zxcvbnm0014 的回复:/*(p+20) = 'z';  字符数组越界了。p指针指向的数据是char型的，p+1就向后移动一个char所占内存的大小。 谢谢回答，但是我问的不是为什么报错，我是想问机器是怎么知道指针所指的对象的长度的

哪怕是同样的申请内存，在不同的内存管理机制中也有不同的实现。 例如MFC的DLL，就是每个DLL分别维持一个内存堆记录，如果你跨DLL进行申请/释放内存，也就是在一个DLL里new另一个DLL里delete，就可能导致该块内存无法被正确释放等后果。 所以不要空想，去学，去查，去理解。没有知识的想象只能成为妄想，任何踏踏实实学东西的人都不该像民科一样。

引用 4 楼 derekrose 的回复:如果是new一个对象  那么内存的大小就是对象的大小  如果new一个数组 那么申请内存的大小就是数组元素的大小乘以数组元素的个数 我想问的是申请的内存大小数值保存在哪？仅有的四个字节32位全部用于记录所指对象的地址了，但是没有记录所指对象占的内存空间大小，那机器如何知道所指的对象的长度呢？应该是一楼说的那样吧。

引用 2 楼 xia597289162 的回复:p保存的是数组a的地址， 当p++的地址超过a 分配的地址，后面的数据是随机值的。p只是以a地址为起始地址。 真不好意思，回复错了，想回复三楼的，回复给你了

引用 2 楼 xia597289162 的回复:p保存的是数组a的地址， 当p++的地址超过a 分配的地址，后面的数据是随机值的。p只是以a地址为起始地址。 又试了几个越界的数，不行，将20换成13,14,15...都不行，指针使用前还是要声明内存空间大小的，看来这里就是将a的长度传给了p，越界就可能有问题。

引用 2 楼 xia597289162 的回复:p保存的是数组a的地址， 当p++的地址超过a 分配的地址，后面的数据是随机值的。p只是以a地址为起始地址。  确实能运行 可为什么下边这就运行不了呢，char *p = a;不是只给p申请了13字节的内存，P+20不是没有申请吗？ int main(){          char a[] = "hello world!";          char *p = a;          *(p+12) = 'z';          *(p+13) = 'y';          *(p+14) = '\0';          printf("%s",p);          return 0; }  int main(){          char a[] = "hello world!";          char *p = a;          *(p+12) = 'z';          *(p+13) = '\0';          *(p+14) = 'w';          printf("%s",p);          return 0; } 这样也运行不了，把*(p+14) = 'w'注释了就能了

用DEV验证楼主代码，去掉注释并不会乱码 因为%s是以'\0'作为结束符，楼主写的p+20是'\0'之后的字节，改变了未知地方的内存 字符串定义后，a就是指向"hello world!"字符串的首地址，p=a也只是把p的值赋值为 "hello world!"字符串的首地址 当a赋值为"hello world!"后，地址a为'h',a+1为'e'以此类推，最后一个字节存'\0'共13个 字节，操作系统并没有在其它地方另存一个13，要计算a的空间还是得以'\0'作判断

申请内存的时候，内存库会记录下来某个指针对应的内存块大小的


Question: 求教，为什么报错

经过大侠们的指导程序如下之后就OK了 # include <stdio.h> # include <malloc.h>  struct student {       int age;       char name[100];       float score; };  void input(struct student ** q, int * l) {     int i;      for (i=0; i<*l; i++)     {            printf ("请输入第%d个学生的信息：\n", i+1); 	   printf ("age = "); 	   scanf ("%d", &((*q)[i].age));  	   printf ("name = "); 	    scanf ("%s", (*q)->name);  	    printf ("score = "); 	    scanf ("%f", &((*q)->score));        } }  void output(struct student ** r, int * l) {        int j;          printf ("\n\n学生信息如下：\n");         for (j=0; j<(*l-1); j++)          { 	        printf ("第%d个学生的信息是：\n", j+1); 	        printf ("age = %d\n", (*r)->age); 	        printf ("name = %s\n", (*r)->name); 	        printf ("score = %0.1f\n", (*r)->score);           } }  int main (void) {       int len;       struct student * p; 	        printf ("请输入学生的个数:\n");        printf ("len = ");        scanf ("%d", &len);        p = (struct student *)malloc(len * sizeof(struct student));         input(&p, &len);        output(&p, &len);         return 0; }

刚学到链表呢，努力中!!

引用 6 楼 u012526168 的回复:[quote=引用 5 楼 cocodada 的回复:] [quote=引用 1 楼 u012526168 的回复:] # include <stdio.h> # include <malloc.h>  struct student {     int age;     char name[100];     float score;     struct student *next; };  void input(struct student **head, int len) {     int i;     struct student *hd ,*tail;     hd =  (struct student*)malloc(sizeof(struct student));     tail = hd;     for (i = 0; i < len; i++)     {         printf ("请输入第%d个学生的信息：\n", i+1);         printf ("age = ");         scanf ("%d", &(tail->age));          printf ("name = ");         scanf ("%s", tail->name);          printf ("score = ");         scanf ("%f", &(tail->score));          tail->next = (struct student*)malloc(sizeof(struct student));         tail = tail ->next;     }     tail = NULL;     *head = hd; }  void output(struct student *hd, int len) {     int j;     struct student *tail = hd;      for (j= 0; j < len; j++)     {         printf ("\n\n学生信息如下：\n");         printf ("第%d个学生的信息是：", j+1);         printf ("age = %d\n", tail->age);         printf ("name = %s\n", tail->name);         printf ("score = %0.1f", tail->score);         tail = tail->next;     } }  int main (void) {     int len;     struct student * p = NULL;      printf ("请输入学生的个数:\n");     printf ("len = ");     scanf ("%d", &len);      input(&p,len);     getchar();     output(p,len);      return 0; }  弱弱的问一下，这里malloc的内存不用free掉吗？[/quote] free掉，忘了。[/quote]  看你没有free，我就自己尝试实现了一下，如果名字用string类型的话，用malloc就会出错，如果不是内置类型的话，malloc只会分配内存，不会调用构造函数，同样delete会调用析构函数，而free不会。。 #include <iostream> #include<string> using namespace std;  struct student { 	string name; 	int age; 	float score; 	struct student * next; };  void input( student **head, int len) { 	student *hd, *tail; //	tail = (struct student *)malloc(sizeof(struct student)); 	tail = new struct student; 	if( tail == NULL) return ; 	hd = tail; 	 	for( int i = 0; i != len; ++i) 	{ 		cout<<"please input number "<<len +1<<" student's information:"<<endl; 		cout<<"name:"; 		cin>>tail->name; 		cout<<"age:"; 		cin>>tail->age; 		cout<<"score:"; 		cin>>tail->score;  		cout<<endl; 		//tail->next = (struct student *)malloc(sizeof(struct student)); 		tail-> next = new struct student; 		tail = tail->next; 	} 	tail= NULL; 	*head = hd; }  void output( student **head, int len) { 	struct student *hd = *head; 	for(int i = 0; i != len; ++i) 	{ 		cout<<"number "<<len + 1<<"student's information are:"<<endl; 		cout<<hd->name<<endl; 		cout<<hd->age<<endl; 		cout<<hd->score<<endl;  		hd = hd->next; 	}  	 	for(int j =0; j != len; ++j) 	{ 		hd = *head; 		*head = (*head)->next; 		delete hd; 	} }  int main() { 	int num; 	cin>>num;  	student * p;  	input(&p,num); 	getchar(); 	output(&p,num); 	return 0; }

引用 5 楼 cocodada 的回复:[quote=引用 1 楼 u012526168 的回复:] # include <stdio.h> # include <malloc.h>  struct student {     int age;     char name[100];     float score;     struct student *next; };  void input(struct student **head, int len) {     int i;     struct student *hd ,*tail;     hd =  (struct student*)malloc(sizeof(struct student));     tail = hd;     for (i = 0; i < len; i++)     {         printf ("请输入第%d个学生的信息：\n", i+1);         printf ("age = ");         scanf ("%d", &(tail->age));          printf ("name = ");         scanf ("%s", tail->name);          printf ("score = ");         scanf ("%f", &(tail->score));          tail->next = (struct student*)malloc(sizeof(struct student));         tail = tail ->next;     }     tail = NULL;     *head = hd; }  void output(struct student *hd, int len) {     int j;     struct student *tail = hd;      for (j= 0; j < len; j++)     {         printf ("\n\n学生信息如下：\n");         printf ("第%d个学生的信息是：", j+1);         printf ("age = %d\n", tail->age);         printf ("name = %s\n", tail->name);         printf ("score = %0.1f", tail->score);         tail = tail->next;     } }  int main (void) {     int len;     struct student * p = NULL;      printf ("请输入学生的个数:\n");     printf ("len = ");     scanf ("%d", &len);      input(&p,len);     getchar();     output(p,len);      return 0; }  弱弱的问一下，这里malloc的内存不用free掉吗？[/quote] free掉，忘了。

引用 1 楼 u012526168 的回复:# include <stdio.h> # include <malloc.h>  struct student {     int age;     char name[100];     float score;     struct student *next; };  void input(struct student **head, int len) {     int i;     struct student *hd ,*tail;     hd =  (struct student*)malloc(sizeof(struct student));     tail = hd;     for (i = 0; i < len; i++)     {         printf ("请输入第%d个学生的信息：\n", i+1);         printf ("age = ");         scanf ("%d", &(tail->age));          printf ("name = ");         scanf ("%s", tail->name);          printf ("score = ");         scanf ("%f", &(tail->score));          tail->next = (struct student*)malloc(sizeof(struct student));         tail = tail ->next;     }     tail = NULL;     *head = hd; }  void output(struct student *hd, int len) {     int j;     struct student *tail = hd;      for (j= 0; j < len; j++)     {         printf ("\n\n学生信息如下：\n");         printf ("第%d个学生的信息是：", j+1);         printf ("age = %d\n", tail->age);         printf ("name = %s\n", tail->name);         printf ("score = %0.1f", tail->score);         tail = tail->next;     } }  int main (void) {     int len;     struct student * p = NULL;      printf ("请输入学生的个数:\n");     printf ("len = ");     scanf ("%d", &len);      input(&p,len);     getchar();     output(p,len);      return 0; }  弱弱的问一下，这里malloc的内存不用free掉吗？

二楼好厉害！  我们也是刚开数据结构课，学习一下

是的，刚学的，谢谢呀

一看就是刚开始学习c语言。 代码主要有以下几点错误： 1.所有的指针都是先申请内存后使用，使用链表，结构体必须包含指向自身类型的next指针，这样才能链起来啊。 函数对其next指针所指空间赋值之前都要先申请内存 2.函数调用传值与传址的理解，好多书上都是这样讲的，其实两者本质上是一样的。只不过指针的值是一个地址而已。 首先输入的同学信息的长度没必要用指针类型。只是把这个数值传给被调用的函数就行。 建立链表要用头指针的地址作为参数才能把链表建立起来。 主函数中&p的值一个结构体student指针的地址，调用input函数是将&p的值传给head. 这样*head = hd;就是将hd的地址赋给*head就是主函数中的p，也就是将p= hd；这样链表就建立起来了，p指向结点。


Question: 请问一下如何求得整数1489各位上的数值

引用 5 楼 romabdwy 的回复:[quote=引用 2 楼 u012421456 的回复:] # include <stdio.h> # include <windows.h>  void fun(int n)//函数不要返回值 { 	int a, b, c, e ; 	a = n%10 ; 	b = n/10%10 ; 	c = n/100%10 ; 	e = n/1000 ; 	printf("a = %d\nb = %d\nc = %d\ne = %d\n", a, b, c, e) ;//在这里输出printf } int main()  ///////////////////////// { 	int num = 1489 ; 	fun(num) ;//直接调用就行,不用printf了  	system("pause"); 	return 0;////////////////// }  lz你给的网址上那个稍微改改就能用， 改的地方是这样/////////////////////////////  晕死，用你这个可行，我又跑回去原来的网址，重新把那个第二个答案给复制粘贴了一下发现又正常了，可能是我的VC装的有问题，哎奇了怪了，不过还是要非常感谢[/quote] 不客气

第二行和最后二行在VC6中确实可以不要，原来给的百度的那个第二个答案可行，4楼对于我来说似乎困难了点儿啊，不过我会看一下，一并谢谢

引用 2 楼 u012421456 的回复:# include <stdio.h> # include <windows.h>  void fun(int n)//函数不要返回值 { 	int a, b, c, e ; 	a = n%10 ; 	b = n/10%10 ; 	c = n/100%10 ; 	e = n/1000 ; 	printf("a = %d\nb = %d\nc = %d\ne = %d\n", a, b, c, e) ;//在这里输出printf } int main()  ///////////////////////// { 	int num = 1489 ; 	fun(num) ;//直接调用就行,不用printf了  	system("pause"); 	return 0;////////////////// }  lz你给的网址上那个稍微改改就能用， 改的地方是这样/////////////////////////////  晕死，用你这个可行，我又跑回去原来的网址，重新把那个第二个答案给复制粘贴了一下发现又正常了，可能是我的VC装的有问题，哎奇了怪了，不过还是要非常感谢

那个第二行和倒数第二行去掉也没事，它的功能就是暂停，如果在VC6.0那样的编译器下，不加都行，但在VS下，不加的话黑色底框就会一闪而逝

编译连接的时候总是有问题 把问题贴出来啊，要不别人怎么帮你看


Question: 【SWU]

引用 3 楼 Falleyes 的回复:直接gets，然后处理字符串吧  具体怎么操作？

直接gets，然后处理字符串吧

比如 char a[1000]; gets(a); 得到参数的一个数组，比如你的输入的时候每个参数是用‘，’分隔开的，那么就使用split函数将分隔的结果存到字符串数组中。 最后，将这些字符串转化成你需要的数据类型。

这个我觉得很麻烦，有没有更简单的

可以while (scanf())循环读取。


Question: 请教一下指针赋值的问题？

int* p 这个只是声明 怎么扯到运算符上面去了    这里的*不是运算符


Question: 我定义的函数表为什么不对？

#include <stdio.h>  int f0() {     return 3; }  char f1() {     return 'a'; }  int main() {     void *pa[2];     int a = f0();     char b = f1();     pa[0] = (void*)(&a);     pa[1] = (void*)(&b);     int* myint = (int*)pa[0];     char* mychar = (char*)pa[1];     printf("%d\n",*myint);     printf("%c\n",*mychar);     return 0;      /*int (*p)() = f0;     printf("%d",p());*/ } 试试这个

#include <stdio.h>   int f0() {     return 3; }   char f1() {     return 'a'; }   void main() {     void *pa[2];     pa[0] = f0;     pa[1] = f1;     int myint = (int)pa[0]();     char mychar = (char)pa[1]();     printf("%d\n",myint);     printf("%c\n",mychar);  }

你用void*是无类型，只是方便你收纳不同的函数，后头使用时得正确转回原来类型... //int myint = (int)pa[0]; int myint = ((int (*)())pa[0])(); //char mychar = (char)pa[1]; char mychar =(((char (*)())pa[1])();  觉得函数类型很绕，就事先typedef简化一下... typedef int (*fx)(); typedef char (*fy)(); ... int myint = ((fx)pa[0])(); char mychar =(((fy)pa[1])();

我用的就是函数指针数组呀，打印的也不是函数的地址，而是函数的返回值

为什么不使用函数指针数组，为什么要当作char和int打印函数的地址。

参数与返回值都必须一致才可以，最好用typedef定义

你的Pa[]在那里声明了？怎么声明的？这个指针数组的声明类型和函数类型不一致。 typedef int(*)() ptr_func;  ptr_func pa[2];  这样定义你的函数指针。不过还是给它赋char (*)()指针时还是会有错的，你需要做指针强制转换。

int f0() {     return 3; } char f1() {     return 'a'; }  不是同种类型的函数 怎么定义成数组。 int (*p)() 是第一个函数的函数指针形式  char (*p1)()是第一个函数的函数指针形式

int myint = (int)*pa[0];     char mychar = (char)*pa[1];   这样试试吧

我是要使用在数组中的函数指针，而不是分开的单个的函数指针

#include <stdio.h> int f0() {     return 3; } char f1() {     return 'a'; }   int main() {     int (*pi) () =f0;     char (*pc) ()=f1;     int myint=(int)pi();     char mychar=(char)pc(); /*   	pa[0] = f0;     pa[1] = f1;     int myint = (int)pa[0];     char mychar = (char)pa[1]; */     printf("%d\n",myint);     printf("%c\n",mychar);   /*   	int (*p)() = f0;     printf("%d",p()); */ }  error: invalid conversion from `int (*)()' to `void*' 要声明函数指针，错误显示指针类型不对


Question: 求助：C语言链栈Pop输出不对劲，输出的是菱形符号

但是，就不出结果了 .显示.exe不能正常工作了

void InitStack(LinkStack &top)   void Push(LinkStack &top, char x)   void Pop(LinkStack &top,char &x)


Question: EOF问题

引用 10 楼 zhao4zhong1 的回复:Windows：Enter，Ctrl+Z，Enter Linux：Ctrl+D这下对了。谢谢老师。

引用 10 楼 zhao4zhong1 的回复:Windows：Enter，Ctrl+Z，Enter Linux：Ctrl+D 引用 10 楼 zhao4zhong1 的回复:Windows：Enter，Ctrl+Z，Enter Linux：Ctrl+D +1

ctrl+z不是undo的意思吗

引用 10 楼 zhao4zhong1 的回复:Windows：Enter，Ctrl+Z，Enter Linux：Ctrl+D 赵老师说的对，不过在输入完成后要先按下回车（ENTER），再按下 Ctrl + Z才行。

char ch;应改为int ch;

Windows：Enter，Ctrl+Z，Enter Linux：Ctrl+D

引用 5 楼 u012523688 的回复:引用 4 楼 niceworkteam 的回复:难道不能用EOF吗，如果用EOF,我该怎么用呢  EOF 是文件结尾标识，用于读取磁盘上的文件的。这里并不适用。在控制台应用程序里，从用户使用的情况来看，一般以回车键位终止输入，这是用户习惯，所以检查是否读取了 '\r' 或者 '\n'这两个标识。

引用 6 楼 wwwzys 的回复:CTRL + C我加了system（“pause”）运行窗口好像是有结果，但是也还是闪退了。

引用 6 楼 wwwzys 的回复:CTRL + C运行窗口直接闪退了

CTRL + C

#include <stdio.h> #include <ctype.h> int main(void) { 	char ch; 	int lower = 0,upper = 0; //	while((ch = getchar()) != EOF) 	while((ch = getchar()) != '\n') 	{ 		if ( islower(ch) ) lower++; 		if ( isupper(ch) ) upper++; 	} 	printf("lower: %d, upper: %d\n",lower,upper); 	return 0; }  EOF 是文件结尾标识，这里用 '\n' 代表换行

引用 1 楼 niceworkteam 的回复:楼主上代码看看#include <stdio.h> #include <ctype.h> int main(void) { 	char ch; 	int lower = 0,upper = 0; 	while((ch = getchar()) != EOF) 	{ 		if ( islower(ch) ) lower++; 		if ( isupper(ch) ) upper++; 	} 	printf("lower: %d, upper: %d\n",lower,upper); 	return 0; }不好意思，我怎么给忘了。

楼主上代码看看


Question: c++容器vector的初始化问题

可参考 《Working Draft, Standard for Programming Language C++》等类似的c++规范文档的Declaratros --> Initializers章节 获得更多细节。

是的，需要编译器支持c++ 11特性。

是C++11的内容 VS的话需要2013


Question: 请教各位如何做不能被用户卸载的软件

木马类做法，多个程序互相监控，被杀就启动对方，进入内核级，伪装进程，嵌入到其它进程  ==

直接断网不就完了，费这劲干啥

固化在bios里，自己做板子

做不到...


Question: Hanoi塔 递归

这种二路递归，一般是形成一棵递归树（二叉树）。 执行到每棵子树，都到达叶节点，即非递归分支（i == 1） 为止。 hanoi 相当于遍历高度为 n的满二叉树。

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

hanni(n,A,B,c) ;的执行过程 hanni(n-1,A,C,B)  ;       //先把A上的n-1个盘子移到B上 printf（“%c -> %c ”,A,C）;   //再把A上最后一个盘子移到到C上 hanni（n-1，B,A,C）;  //再把B上的n-1个盘子移到到C上  至于第一步中如何A上的n-1个盘子移到B上 那就是hanni(n-1,A,C,B)  ; 的执行过程 hanni(n-2,A,B,C)  ;       //  把n-2个盘字从A移到C上 printf（"%c  -> %c",A,C）//再把A上的倒数第二个盘子从A移到B上 hanni(n-2,C,A,B)  ;     //把n-2个盘子从C移到B上 ........... 就这样递归下去。   直到hanni（1，.....) 压栈出栈。直至结束 以三为例，我画了个他的执行过程：  递归要我的理解与函数调用差不多 只不过是调用的这个函数是函数本身，调用被调用函数之前都要将自身的参数进行压栈，函数之间不断的调用，循环往复，遇到最终的结束条件之后，开始出栈，有一步步的出栈.... 说的够清楚了吧 每五个换行就是在它每打印一次时判断一下是否够五个了，够了打印换行，就是二楼的做法。 #include <stdio.h>  void hanoi(int i , char A , char B , char C); int count=0;  int main() {     int n;     while(scanf("%d",&n)!=EOF) 	{         if(n==0)             return 0;         hanoi(n , 'A' , 'B' , 'C');         printf("\n"); 	}     return 0 ; }  void hanoi(int i , char A , char B , char C) {     if(i == 1)     {         printf("%c-->%c   ",A, C);         count++;         if(count % 5 == 0)             printf("\n");     }     else     {         hanoi(i - 1 , A , C , B);   //函数递归调用         printf("%c-->%c   ",A, C);         count++;         if(count % 5 == 0)             printf("\n");         hanoi(i - 1 , B , A , C);     } }

lz要不看看这个，看能明白不 http://www.360doc.com/content/12/0727/11/219024_226737868.shtml

根据楼楼上的，  我知道递归要根据参数条件，  可根据那三个语句看来，  不断地递归，n会等于1，  等n=1的时候，执行if语句，  那么 那三个语句的下面两个语句是干嘛的？     else   {     hanoi(i - 1 , A , C , B);   //函数递归调用      move(i , A , C);     hanoi(i - 1 , B , A , C);   }

看了你的博客，上面对hanoi塔的分析很详尽，但是那些我也懂，我的问题在于递归啊！   当执行到hanoi这一句时， 程序是调用hanoi自身一次，然后执行Move语句， 还是调用Hanoi自身一次，然后又执行到这里，继续调用hanoi？ 还是两步同时进行？ 还是调用hanoi直到i=1,然后执行move？可是这时候i是1了，move一次后，move后的hanoi的第一个参数就变成0了，函数怎么继续执行下去呢？

引用 楼主 u012514377 的回复:当执行到hanoi这一句时， 程序是调用hanoi自身一次，然后执行Move语句， 还是调用Hanoi自身一次，然后又执行到这里，继续调用hanoi？ 还是两步同时进行？ 还是调用hanoi直到i=1,然后执行move？可是这时候i是1了，move一次后，move后的hanoi的第一个参数就变成0了，函数怎么继续执行下去呢？  这是我的第一个疑惑， lz了解递归吗？正像一楼所说的，每次调用的参数都不同，符合条件就继续调用，不符合就靠 if 语句结束，否则又怎么结束递归呢？  能否继续下去，要看符不符合的条件

可以参考下我的blog:  汉诺塔(the Tower of Hanoi )  http://blog.csdn.net/ithiker/article/details/5498118

在main的每组输入后清count 在move函数中count++和输出回车  #include <stdio.h>  void hanoi(int i , char A , char B , char C); void move(int i , char x , char y);  int count=0;  int main() {   int n;   while(scanf("%d",&n)!=EOF)   {     count=0;//加     if(n==0)       return 0;     hanoi(n , 'A' , 'B' , 'C');     printf("\n");   }   return 0 ; }  void hanoi(int i , char A , char B , char C) {   //count++;   if(i == 1)   {     move(i , A , C);     //if(count%5==0)     //printf("\n");   }   else   {     hanoi(i - 1 , A , C , B);   //函数递归调用      move(i , A , C);     hanoi(i - 1 , B , A , C);   } }  void move(int i , char x , char y) {   //static int c = 1 ;   //局部变量i申明为 static    printf("%c-->%c   ",x , y);   if((++count)%5==0) printf("\n");//改 }

执行到hanoi时会不会继续递归下去当然要看本次调用的参数咯。每一次调用到hanoi时参数的值并不都是一样的。


Question: C我的困惑，需要您的建议，谢谢

同意楼上的观点，“先糊口”，踏实地干一段时间再说！

引用 1 楼 user-8 的回复:先糊口，语言其实真的不是那么重要。  个人建议，仅供参考。 嗯，+1，我只是个新手，想问问lz访问过这样的网站吗——http://www.job592.com/tag/cn_400.html

搞嵌入式需要一些基础，建议你去搞Linux，那是c语言的用武之地！

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

那就赶紧换嵌入式行业。  引用 楼主 u014113806 的回复:我是14年的 毕业生，我很喜欢C，并且在网上经常看到这样的文章，计算机的主要核心还是C，可我还要工作赚钱啊养活自己，在现在看来C的就业也没有java什么的 高，我很纠结，又想深入的了解人类从一无所知到用代码来控制机器，指挥，达到目的，我想学习他的根本，现在真的不知道怎么去走，希望有资深的大大能够给我一些建议，带我走出这个困圈。

想当初我对计算机这个东西感兴趣的时候，也想过把计算机从硬件层一直到软件层都弄清楚（其实已经不是出于软件开发的兴趣了）。最后怎么了，啥能糊口学啥。

引用 楼主 u014113806 的回复:我是14年的 毕业生，我很喜欢C，并且在网上经常看到这样的文章，计算机的主要核心还是C，可我还要工作赚钱啊养活自己，在现在看来C的就业也没有java什么的 高，我很纠结，又想深入的了解人类从一无所知到用代码来控制机器，指挥，达到目的，我想学习他的根本，现在真的不知道怎么去走，希望有资深的大大能够给我一些建议，带我走出这个困圈。  嵌入式开发很多需要C,主要是看你的C能力如何

先糊口，语言其实真的不是那么重要。  个人建议，仅供参考。


Question: 求助：思考了很久还是想不出为什么结果是这样的，希望大家能指点指点，谢谢~

请参考置顶帖 传送门~http://bbs.csdn.net/topics/370153775

具体的执行顺序由编译器自行决定！禁制同一变量在一个语句中多次改变！

月经贴。。真不知道哪个公司还会出这种面试题。。

不必纠结，现实中编程不允许这样的代码存在。实现的差异，结果也可能存在差异。


Question: 函数表如何处理不同返回值的函数指针

全部强制转换为void *。


Question: 关于for循环的层数问题

引用 3 楼 u014100290 的回复:把M当做一个固定值就行了，前提是肯定要进行赋值或者从其他地方得到它的值+1

用栈（用递归就是用栈，也可以不用递归，自己整一个栈结构来处理。）

用个动态数组，来模拟看看 实在不行直接用递归

个人建议用递归，可以用M作为边界判定值

引用 5 楼 WizardOz 的回复:用栈（用递归就是用栈，也可以不用递归，自己整一个栈结构来处理。） 英雄所见略同。

把M当做一个固定值就行了，前提是肯定要进行赋值或者从其他地方得到它的值

就比方说要求1--m的排列，m是个不确定的值，这种情况 应该怎么处理

for 层数怎么不确定法 你写个不确定层数的for循环出来？


Question: SWU 找错

至少格式化应该修改成 %f 。


Question: 求解-  -

你哪个学校的？

[code=c ]#include<stdio.h> int main(void) {int(n,n2,n3);//不需要"" n=5; n2=n*n; n3=n2*n; printf('n=%d,n squared=%d,n cubed=%d\n",n.n2,n3);//这里 return 0; }[/code]

第三行，还有倒数第三行，lz你好好看看一楼的代码 说起来lz你的这些代码都是从哪儿弄的啊？怎么老是出这样的错误，你看哪本书啊？就是谭浩强的书好像都没这样的  首先lz需要知道一个简单的代码需要注意什么，语句最后加分号，stdio.h需要尖括号等等，这些如果不明白，怎么敲代码啊？ 我个人的学习建议是，有问题了自己好好看看，不会了看书，认真点，仔细点，实在不行了谷歌百度，再不行了再来论坛，lz你看你前后问的这几个问题，

怎么写的这么不规范

#include <stdio.h>  int main(void) {     int n,n2,n3;     n = 5;     n2 = n * n;     n3 = n2 * n;     printf("n=%d,n squared=%d,n cubed=%d\n", n, n2, n3);     return 0; }


Question: C语言调用.SO中的函数，为什么没有结果呢

test; --〉 test();


Question: c语言关于字符串的几个问题，求前辈解答

可是还没有学到字符串，用指针函数，scanf怎么写呢

18. #include <stdio.h> #include <stdlib.h>  int word_length(const char *p) { 	int length = 0; 	for (; isalpha(*p++); ++length); 	return length; }  void output(const char *p, int length) { 	while (length-- > 0) 		fputc(*p++, stdout); }  int main(void) { 	char input[100]; 	char *p = input; 	char *longest = input; 	int length = 0; 	 	fgets(input, 100, stdin);  	while (*p) 	{ 		int len = word_length(p); 		if (len > length) 		{ 			longest = p; 			length = len; 		}  		++p; 	}  	output(longest, length);  	return 0; }

17..  #include <stdio.h> #include <stdlib.h>  int main(void) { 	int count = 0; 	int in_word = 0; 	char line[100]; 	char *p = line;  	fgets(line, 100, stdin);  	while (*p) 	{ 		if (isalpha(*p)) 		{ 			if (!in_word) 			{ 				in_word = 1; 				++count; 			} 		} 		else 		{ 			in_word = 0; 		}  		++p; 	}  	printf("Total %d words.\n", count);  	return 0; }

求高手速度解答呀，坐等！！！


Question: 实在看不懂这段位运算了

就是一个状态机 (threes twos ones)当1出现的次数是0,1,2,3次时取值分别为 (0 0 0) (1 0 1) (1 1 0) (0 0 0) 然后循环。这样出现3次的元素都会被清0, 只有非3次的元素才能保留。 但是这个代码有一个bug, 就是题目没有说那个非3次的元素出现了1次还是2次. 所以结果应该是return threes;


Question: 求助宏中的展开顺序

#define _STR(s)      #s  #define STR(s)       _STR(s)           // 转换宏  void main() {       enum { a = 121321}; printf("%s\n", STR(a)); // 这个似乎是，输出121321 }

printf("%s\n", STR(121321));

跟宏扯不上关系，想输出121321，直接用printf("%d\n",a);   引用 楼主 wuyangzu01 的回复:#define _STR(s)      #s  #define STR(s)       _STR(s)           // 转换宏  void main() {       	int a = 121321; 	printf("%s\n", STR(a));  } 不明白为什么答应的结果还是a而不是121321??


Question: c语方如何实现字符串转变为变量名称

引用 楼主 surepretty 的回复:目前是这样的，希望根据当前的一些信息，来动态的确认加载哪个变量数据。  具体如下，  已知信息char aaa[128] ="MN3456";  希望如果用他来动态确认或转成变量 int MN3456_HAHA;  在没有办法的时候是通过switch case处理的，但随着支持的东西越来越多。。case N很大了，加载的东西也很多了。 希望能找到个更合适的方法。  求大牛来指教。谢谢  lz这个想法是错误的，编译后，程序中不存在任何的变量名或函数名，他们都被转换为内存地址 你一个功能实现可以使用数组或者使用一个分支判断  if(条件1成立) ｛ a=MN3456_HAHA; ｝ else if(条件2成立) { a=MN3456_BEBE; } ...... char aaa[128] ="MN3456";

简单说就是 写代码生成代码

语言本身应该没法实现你说的字符串转变量名的。功能实现上可以采用map来存储结构信息

变量经过编译之后，名称信息就消失，每个变量都转换成了程序的逻辑地址，使用普通的变量是无法实现lz的功能的 但可以使用一个结构{名称，值} 然后使用一个数组保存这样的结构，加载的时候将“名称-值”存入数组，删除的时候从中删除  或者使用map数据结构，本身的一个名称-值对的结构

这种工作是无法省的，数据量再大也不会增加复杂度，维护起来简单，而用switch的话后面的维护会让人抓狂； 另外还有一种更有弹性的做法，就是把变化的部分放到lua脚本中去，C这边驱动脚本即可。  引用 3 楼 surepretty 的回复:[quote=引用 1 楼 turingo 的回复:] 用查表的方式去做，就是建立一个常量的结构体数组。  [quote=引用 楼主 surepretty 的回复:] 目前是这样的，希望根据当前的一些信息，来动态的确认加载哪个变量数据。  具体如下，  已知信息char aaa[128] ="MN3456";  希望如果用他来动态确认或转成变量 int MN3456_HAHA;  在没有办法的时候是通过switch case处理的，但随着支持的东西越来越多。。case N很大了，加载的东西也很多了。 希望能找到个更合适的方法。  求大牛来指教。谢谢[/quote] 嗯，这样是可以实现 的，但这样处理，还是需要罗列全部的数据到大的结构体里。[/quote]

引用 1 楼 turingo 的回复:用查表的方式去做，就是建立一个常量的结构体数组。  [quote=引用 楼主 surepretty 的回复:] 目前是这样的，希望根据当前的一些信息，来动态的确认加载哪个变量数据。  具体如下，  已知信息char aaa[128] ="MN3456";  希望如果用他来动态确认或转成变量 int MN3456_HAHA;  在没有办法的时候是通过switch case处理的，但随着支持的东西越来越多。。case N很大了，加载的东西也很多了。 希望能找到个更合适的方法。  求大牛来指教。谢谢[/quote] 嗯，这样是可以实现 的，但这样处理，还是需要罗列全部的数据到大的结构体里。

很多是多多？ 个人意见：不超过10000继续用switch case 真超过10000，可以考虑改用map<string,int> name2value;

用查表的方式去做，就是建立一个常量的结构体数组。  引用 楼主 surepretty 的回复:目前是这样的，希望根据当前的一些信息，来动态的确认加载哪个变量数据。  具体如下，  已知信息char aaa[128] ="MN3456";  希望如果用他来动态确认或转成变量 int MN3456_HAHA;  在没有办法的时候是通过switch case处理的，但随着支持的东西越来越多。。case N很大了，加载的东西也很多了。 希望能找到个更合适的方法。  求大牛来指教。谢谢


Question: 风格比较

感觉C语言更精简写； Pascal更容易读懂；

每个人喜好不同

楼主不妨试试用Pascal重写一下这个。 http://bbs.csdn.net/topics/380157851

引用 楼主 zcfloder 的回复:软件从小程序时代向大规模软件工程方向发展是个历史的趋势。仅从程序风格上讲，Pascal更加易读，便于编程者了解他人的思想，加快开发的速度和降低维护难度，更加利于交流合作。另外比较二者的风格也要看用武之地，如果写的多是格式化流程化的东西，Pascal接近自然语言，输入速度快（至少不用经常切换上档键去找符号），如同写文章般一样自然优雅；对于写一些短小技巧性强的程序，C会更为灵动，能体现算法的精妙。    个人很喜欢Pascal的语法，清晰严谨，优雅易读。即使对于一个陌生的代码，也多能像读信一样，纵览一遍便能知其八九。Pascal的语法中有严格的数学意义，如前面有位朋友提到:=赋值，其实这种设计比C更加严谨。=表示左右两边的相互等价，1个馒头=5角钱，反过来不一定成立。  萝卜青菜各有所爱，每种语言都是一工具，无他，唯手熟尔

赞同！  引用 楼主 zcfloder 的回复:软件从小程序时代向大规模软件工程方向发展是个历史的趋势。仅从程序风格上讲，Pascal更加易读，便于编程者了解他人的思想，加快开发的速度和降低维护难度，更加利于交流合作。另外比较二者的风格也要看用武之地，如果写的多是格式化流程化的东西，Pascal接近自然语言，输入速度快（至少不用经常切换上档键去找符号），如同写文章般一样自然优雅；对于写一些短小技巧性强的程序，C会更为灵动，能体现算法的精妙。    个人很喜欢Pascal的语法，清晰严谨，优雅易读。即使对于一个陌生的代码，也多能像读信一样，纵览一遍便能知其八九。Pascal的语法中有严格的数学意义，如前面有位朋友提到:=赋值，其实这种设计比C更加严谨。=表示左右两边的相互等价，1个馒头=5角钱，反过来不一定成立。

不了解 Pascal，  我们一开始是学C语言，而后是C++，现在是JAVA，都只是浅谈辄止，唉


Question: ubuntu下make后面目标文件不能自动补全

将make拷贝叫umake后，就可以补全了。


Question: 算法求助

如果真不怕浪费空间，排序做到O(N)都是可以的

第一个时间O(N)，空间O(N) Bits 或者bool 数组记录每个数字是否出现过 第二个 O(N^2)不确定有没有，可能没有。 第三个和快排的实现有关，其中据说，实用的O(NlogN) 算法是, 快排递归深度到一定的时候，转为堆排序，可以保证是O(NlogN)  由于随机数生成器的问题，据说随机的快排算法，不是实用的算法。  就像O(N) 的选择算法中，五数中值的中值，那个算法一样不实用。 具体要看有没有人，真的做出来，并应用了随机的快排算法，就知道了。


Question: 我就想知道你们怎么实现的，全排列。

//全排列的生成算法 //  全排列的生成算法就是对于给定的字符集，用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1～n的n个数字的排列一一对应， //  因此在此就以n个数字的排列为例说明排列的生成法。 //  n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外，都有一个后继；除第一个排列外，都有一个前驱。每个排列的后继都可以从 //  它的前驱经过最少的变化而得到，全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。 //  全排列的生成法通常有以下几种： //  字典序法 //  递增进位数制法 //  递减进位数制法 //  邻位交换法 //  递归类算法 //1.字典序法 效率高且顺序自然 //  字典序法中，对于数字1、2、3......n的排列，不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345，排列12345在前， //  排列12354在后。按照这样的规定，5个数字的所有的排列中最前面的是12345，最后面的是54321。 //  字典序算法如下： //  设P是1～n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn //  1）从排列的右端开始，找出第一个比右边数字小的数字的序号j（j从左端开始计算），即 j=max{i|pi<pi+1} //  2）在pj的右边的数字中，找出所有比pj大的数中最小的数字pk，即 k=max{i|pi>pj}（右边的数从右至左是递增的，因此k是所有大于pj的数字中序号最大者） //  3）对换pi，pk //  4）再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1，这就是排列p的下一个下一个排列。 //  例如839647521是数字1～9的一个排列。从它生成下一个排列的步骤如下： //  自右至左找出排列中第一个比右边数字小的数字4 839647521 //  在该数字后的数字中找出比4大的数中最小的一个5 839647521 //  将5与4交换 839657421 //  将7421倒转 839651247 //  所以839647521的下一个排列是839651247。 //2.递增进位数制法 //  在递增进位制数法中，从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数，则排列的中介数就是对应的 //  排列k1 ...... ki...... kn-1。 //  例如排列839647521的中介数是72642321，7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。 //  中介数是计算排列的中间环节。已知一个排列，要求下一个排列，首先确定其中介数，一个排列的后继，其中介数是原排列中介数加1，需要注意的是，如果中介数的 //  末位kn-1+1=2，则要向前进位，一般情形，如果ki+1=n-i+1，则要进位，这就是所谓的递增进位制。例如排列839647521的中介数是72642321，则下一个排列的中介数 //  是67342221+1=67342300（因为1+1=2，所以向前进位，2+1=3，又发生进位，所以下一个中介数是67342300）。 //  得到中介数后，可根据它还原对应得排列。 //  算法如下： //  中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数，因此，要按k1、k2、......、kn-1的值从右向左 //  确定n、n-1、......、2的位置，并逐个放置在排列中：i放在右起的ki+1位，如果某位已放有数字，则该位置不算在内，最后一个空位放1。 //  因此从67342300可得到排列849617523，它就是839647521的后一个排列。因为9最先放置，k1=6，9放在右起第7位，空出6个空位，然后是放8，k2=7，8放在右起第8位， //  但9占用一位，故8应放在右起第9位，余类推。 //3.递减进位制数法 //  在递增进位制数法中，中介数的最低位是逢2进1，进位频繁，这是一个缺点。把递增进位制数翻转,就得到递减进位制数。 //  839647521的中介数是67342221(k1k2...kn-1)，倒转成为12224376(kn-1...k2k1)，这是递减进位制数的中介数：ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p， //  p的下一个排列的中介数定义为p的中介数加1。例如p=839647521，p的中介数为12224376，p的下一个排列的中介数为12224376+1=12224377，由此得到p的下一个 //  排列为893647521。 //  给定中介数，可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中，可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下： //  1）如果p(i)=n且i<>n，则p(i)与p(i-1)交换 //  2）如果p(n)=n，则找出一个连续递减序列9、8、......、i，将其从排列左端删除，再以相反顺序加在排列右端，然后将i-1与左边的数字交换 //  例如p=893647521的下一个排列是983647521。求983647521的下一个排列时，因为9在最左边且第2位为8，第3位不是7，所以将8和9从小到大排于最右端364752189， //  再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列，只需要将9876从小到大排到最右端并将5与其左方数字3对调， //  得到534216789。 //4.邻位对换法 效率最高但顺序不自然 //  邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例，将最后的元素4逐次与前面的元素交换，可以生成4个新排列： //  1 2 3 4, 1 2 4 3, 1 4 2 3, 4 1 2 3 //  然后将最后一个排列的末尾的两个元素交换，再逐次将排头的4与其后的元素交换，又生成四个新排列： //  4 1 3 2, 1 4 3 2, 1 3 4 2, 1 3 2 4 //  再将最后一个排列的开头的两个元素交换，将4从后往前移： //  3 1 2 4, 3 1 4 2, 3 4 1 2, 4 3 1 2 //  如此循环4!次既可求出全部排列。 //5.元素增值法（n进制法）效率低 //  1）从原始排列p=p1p2......pn开始，第n位加n-1，如果该位的值超过n，则将它除以n，用余数取代该位，并进位（将第n-1位加1） //  2）再按同样方法处理n-1位，n-2位，......，直至不再发生进位为止，处理完一个排列就产生了一个新的排列 //  3）将其中有相同元素的排列去掉 //  4）当第一个元素的值>n则结束 //  以3个数1、2、3的排列为例：原始排列是1 2 3，从它开始，第3个元素是3，3+2=5，5 Mod 3=2，第2个元素是2，2+1=3，所以新排列是1 3 2。通过元素增值，顺序产生的 //  排列是：1 2 3，1 3 2，2 1 1，2 1 3，2 2 2，2 3 1，2 3 3，3 1 2，3 2 1 //  有下划线的排列中存在重复元素，丢弃，余下的就是全部排列。 //6.递归类算法 //  全排列的生成方法用递归方式描述比较简洁，实现的方法也有多种。 //  1）回溯法 //  回溯法通常是构造一颗生成树。以3个元素为例；树的节点有个数据，可取值是1、2、3。如果某个为0，则表示尚未取值。 //  初始状态是(0，0，0)，第1个元素值可以分别挑选1，2，3，因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值，如此反复进行，一旦出现新结点的3个 //  数据全非零，那就找到了一种全排列方案。当尝试了所有可能方案，即获得了问题的解答。 //  2）递归算法 //  如果用P表示n个元素的排列，而Pi表示不包含元素i的排列，(i)Pi表示在排列Pi前加上前缀i的排列，那么，n个元素的排列可递归定义为： //  如果n=1，则排列P只有一个元素i //  如果n>1，则排列P由排列(i)Pi构成（i=1、2、....、n-1）。 //  根据定义，容易看出如果已经生成了k-1个元素的排列，那么，k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1，对与个 //  元素而言，p1是2 3和3 2，在每个排列前加上1即生成1 2 3和1 3 2两个新排列，p2和p3则是1 3、3 1和1 2、2 1，按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。 //  3）循环移位法 //  如果已经生成了k-1个元素的排列，则在每个排列后添加元素k使之成为k个元素的排列，然后将每个排列循环左移（右移），每移动一次就产生一个新的排列。 //  例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3，将它循环左移可再生成新排列2 3 1、3 1 2，同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。

引用 3 楼 bfdeh 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:]  弱弱的问一句 qplw.cpp 中的 qplw==Quan Pai Lie W???[/quote] Quan Pai Lei with Width limit. 请原谅我又拼音＋英语了。 （为什么我要说“又”？）

引用 5 楼 user-3 的回复:[quote=引用 2 楼 huanglin02 的回复:] http://bbs.csdn.net/topics/80248065是这个嘛 额，呵呵，你不是做java的么，怎么跑这里来了啊[/quote]看见他的传送门，就过来了

引用 2 楼 huanglin02 的回复:http://bbs.csdn.net/topics/80248065是这个嘛 额，呵呵，你不是做java的么，怎么跑这里来了啊

引用 2 楼 huanglin02 的回复:http://bbs.csdn.net/topics/80248065是这个嘛不是，原帖是1234567说是被老师罚。

引用 1 楼 zhao4zhong1 的回复:  弱弱的问一句 qplw.cpp 中的 qplw==Quan Pai Lie W???

//qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出