Question: 读取文件的问题

把指定文件内容读到控制台  #include <stdio.h> char buf[256]; char *fname = "data.txt"; FILE *fp; int main(void) { 	fp = fopen(fname, "r"); 	if (NULL == fp) return 0; 	while (1) { 		if (NULL == fgets(buf, 256, fp)) break; 		printf("%s\n", buf); 	} 	fclose(fp); 	return 0; }

第10行做修改：  printf("%s", buf);

引用 1 楼 piaobotudou 的回复:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); size指读取元素的大小，count为读取元素的个数 这里sizeof(Buf)应该是指针的大小，你读取了8个字节，所以你应该编译的是一个64位程序。  应该是这样的，  64位指针是 8 个字节

fread(Buf, sizeof(Buf), 1, fp);这个size是有问题的，size之后不是字符串的大小，是Buf这个指针的大小，如果想读出指定的Buf大小，需要当做参数值传进来。楼主你这判断语句里加一个;可以正确执行么？

char Buf[SIZE]

收获良多！谢谢！

呵呵，也做过sizeof指针这事呢

你的Buf不是字符数组，而只是一个char*的指针，所以sizeof返回的是指针大小4（32位）


Question: if的多重嵌套可以怎么改进，新手求助

如果只是求闰年的话，可以跳过检查4的倍数，直接检查是否100,400的倍数 让年数一定是4的倍数就可以了 仅仅是100 的倍数非闰年，同时还是400的倍数，是闰年， 非100 的倍数，是闰年

引用 5 楼 paschen 的回复:四年一闰，百年不闰，四百年再闰  if((year/4==0&&year/100!=0)||(year/400==0)) 显示出来的只有非闰年，没有闰年啊 #include <stdio.h>  int main() { 	int year = 2000; 	for (year = 2000; year <= 2500; year++) 	{ 		if ((year / 4 == 0 && year / 100 != 0) || (year / 400 == 0)) 		{ 			printf("闰%d\n", year); 		} 		else 		{ 			printf("非闰%d\n", year); 		} 	}  	int a = 0; 	scanf("%d",&a); 	//控制程序悬停  	return 0; }

给代码看下 你刚才的例子5楼有解释了

你先给出代码才能改的，没代码改什么？

写错了，是4才对

上面直接取余3就行了，我只是想问多重嵌套可以怎么改，求别沉贴

引用 1 楼 user-5 的回复:int k=年 if(k%4==0) { 润年 } 我是想问多重嵌套可以怎么改，上面只是举例

int k=年 if(k%4==0) { 润年 }

引用 8 楼 zxq1994929 的回复:[quote=引用 5 楼 paschen 的回复:] 四年一闰，百年不闰，四百年再闰  if((year/4==0&&year/100!=0)||(year/400==0)) 显示出来的只有非闰年，没有闰年啊 #include <stdio.h>  int main() { 	int year = 2000; 	for (year = 2000; year <= 2500; year++) 	{ 		if ((year / 4 == 0 && year / 100 != 0) || (year / 400 == 0)) 		{ 			printf("闰%d\n", year); 		} 		else 		{ 			printf("非闰%d\n", year); 		} 	}  	int a = 0; 	scanf("%d",&a); 	//控制程序悬停  	return 0; }[/quote]  / 换成 % ， 是取余，上面打错了

引用 8 楼 zxq1994929 的回复:[quote=引用 5 楼 paschen 的回复:] 四年一闰，百年不闰，四百年再闰  if((year/4==0&&year/100!=0)||(year/400==0)) 显示出来的只有非闰年，没有闰年啊 #include <stdio.h>  int main() { 	int year = 2000; 	for (year = 2000; year <= 2500; year++) 	{ 		if ((year / 4 == 0 && year / 100 != 0) || (year / 400 == 0)) 		{ 			printf("闰%d\n", year); 		} 		else 		{ 			printf("非闰%d\n", year); 		} 	}  	int a = 0; 	scanf("%d",&a); 	//控制程序悬停  	return 0; }[/quote]  不是除是  %


楼上兄弟，俺是零售系统pos机打印，dos环境下用的c语言开发，esc/pos指令直接打印二维码，不是嵌入式开发。  多谢你的指点。

楼主代码不全吧，端口都没打开

fprintf(stdprn,"%s","xxxx"); 这个是嵌入式向打印设备发送命令吧？调试： 1、查看设备支持的命令手册，看发送的命令格式、内容是否正确。（最好了解每条命令代表什么意思） 2、设备要能读出内容，打断点，看看每条命令是否正确发送，是否正确被设备接收。 3、如果和开发手册一样，并且设备正确接收了命令，找芯片厂商定位问题。给厂商描述就是手册说明+实际内存数据。 有兴趣联系我，可以发邮箱user-2@126.com


Question: 有关 “初始化”: 截断常量值 的warning

引用 1 楼 user-2 的回复:楼主可以看一下char的取值范围，char的取值范围为-128~127，也就是说，char字节中1一个是符号位，7个是表示的数值 符号位：表示数字 1 111 11111 0xff，也就是 1111 1111，也就是255，超出了char能够表示的范围。 而0x1f，也就是 0001 1111，也就是31，在char的表示的范围内。 按照以上方式，0x7f 0111 1111，也就是127，是char能够表示的最大值了，在这种情况下，不会有warn提示。 嗯，我之前有点搞混了，char在内存中存储是0x00~0xff，就觉得可以直接把0xff赋值给char。

引用 1 楼 user-2 的回复:楼主可以看一下char的取值范围，char的取值范围为-128~127，也就是说，char字节中1一个是符号位，7个是表示的数值 符号位：表示数字 1 111 11111 0xff，也就是 1111 1111，也就是255，超出了char能够表示的范围。 而0x1f，也就是 0001 1111，也就是31，在char的表示的范围内。 按照以上方式，0x7f 0111 1111，也就是127，是char能够表示的最大值了，在这种情况下，不会有warn提示。  感谢@user-2，已经说明白了，题主一定要赋值0xff的话，可以试下这段代码：  unsigned char a = 0xff;


Question: Linux 下如何获得 C 程序的代码段,数据段等各段地址.

引用 11 楼 yuelengdihai 的回复:引用 6 楼 Z_R_Z_798205 的回复:[quote=引用 4楼yuelengdihai 的回复:]打log出来看就行了我换个方式问，如何获得 .text .data 和 .init 的值 Linux中可执行文件的格式是ELF，其实编译过程中的中间文件*.o文件、动态共享库*.so文件也是ELF格式的。在链接器看来，当它通过*.o或者配合*.so文件来生成可执行文件时，它对ELF格式的文件以链接视图(Linking View)进行看待。也就是说链接器以Section的形式来对待和处理ELF文件，诸如我们常见说的代码段(.text)、数据段(.data和.bss)等待概念    readelf –h命令能够可以查看一个EFL文件的头部信息[/quote]  我在 C 源码中这样编写来获得 .text .data 和 .init 的值    extern char _text, _data,_init;  通过上面的代码可以获得对应的值

引用 6 楼 Z_R_Z_798205 的回复:引用 4楼yuelengdihai 的回复:打log出来看就行了我换个方式问，如何获得 .text .data 和 .init 的值 Linux中可执行文件的格式是ELF，其实编译过程中的中间文件*.o文件、动态共享库*.so文件也是ELF格式的。在链接器看来，当它通过*.o或者配合*.so文件来生成可执行文件时，它对ELF格式的文件以链接视图(Linking View)进行看待。也就是说链接器以Section的形式来对待和处理ELF文件，诸如我们常见说的代码段(.text)、数据段(.data和.bss)等待概念    readelf –h命令能够可以查看一个EFL文件的头部信息

引用 8 楼 jianwen0529 的回复:这应该是操作系统和文件的东西了吧  系统加载可执行文件到哪里，如何各段在可执行文件中的偏移？  这个问题是在 linux 上 gcc 编译器 ld链接器, .text .data .init 的值应该是由链接器设定,我现在的问题是如何获得这些值.

引用 3楼nadleeh 的回复:[quote=引用 楼主 Z_R_Z_798205 的回复:] 基于 Linux,如何在编写代码来获得该 C 程序的数据段地址和代码段地址?  楼主忘记 ./  装载器了,应用程序运行时都是动态的[/quote]我换个方式问，如何获得 .text .data 和 .init 的值

引用 1楼赵4老师 的回复:使用嵌入汇编？ 搜“gcc-inline-asm.pdf”我换个方式问，如何获得 .text .data 和 .init 的值

打log出来看就行了

引用 楼主 Z_R_Z_798205 的回复:基于 Linux,如何在编写代码来获得该 C 程序的数据段地址和代码段地址?  楼主忘记 ./  装载器了,应用程序运行时都是动态的

引用 1楼赵4老师 的回复:使用嵌入汇编？ 搜“gcc-inline-asm.pdf”应该和链接器有关

使用嵌入汇编？ 搜“gcc-inline-asm.pdf”


Question: 关于C语言中的自加运算

这和程序所用的编译器不同，所算的结果也不同， x=5，x=++x+++x+++x，： 1、优先级自增++，优先于加法运算符+，2、太坑了

庸人自扰之。。。。

想学好c，入门的时候，这类麻烦的问题少研究。前些时看了下考试的题库，真的奇怪为什么会有这些乱起八糟的语句和题目。 如果是为了考试，直接问老师标准答案。 由浅入深，慢慢来。多看下经典的代码例子。

引用 1 楼 happy2study 的回复:说句题外话：如果不是研究编译器，最好别拿这样的问题来烧脑。  加括号让优先级明确才是王道。这样的表达式 加括号毫无意义

进来看看大神们的逻辑！！！

我只能告诉你为什么会出现这种结果。 不能告诉你编译器为什么要这么处理，因为那东西也不是我写的。 不同的编译器会有不同的处理方式，所以这种问题应该没有多大意义（考试应该不考）。

如果你得出的是22，我可以断定你用的是很老的编译器，比如VC6.0. 它的逻辑是i++=6,i++=7;7+7=14;i++=8;14+8=22; 但是新的C++标准不是这样的，应该是 i++=6;i++=7;i++=8;8+8+8=24; 遇到这种问题你可以查看反汇编结果，通过汇编语句查看整个运行情况

这个求值顺序没有标准，6+7+8、7+7+8、8+8+8都可以

结果是24；

语法没规定死这种操作的答案，所以不同的编译器结果不同

这种代码没意义

引用 87 楼 zhao4zhong1 的回复:[quote=引用 86 楼 zilaishuichina 的回复:] 我就好奇 这个2年前的帖子 ，是基于什么原因，被翻出来的 太阳黑子爆发，一缕γ射线击穿了CSDN服务器的时钟，导致其时间计算紊乱了一阵子。[/quote] 大学考试考这个,我竟然醉了,最后不还是得按老师的题库来

引用 72 楼 i_wish 的回复:这个问题， 跟编译器有很大关系。 有的编译器会将 i+1执行4次，在计算4个i的值， 有的则会边加计算，主要看编译器 有些结果是21怎么编译计算的啊

第一次 ++i后i==6 第二次 ++i后i==7 第三次7+7==14 第四次++i后i==8 第五次14+i后 ==22

这种问题虽然很无聊，但还是可以关注一下的。

我也是来看评论的

引用 86 楼 zilaishuichina 的回复:我就好奇 这个2年前的帖子 ，是基于什么原因，被翻出来的 太阳黑子爆发，一缕γ射线击穿了CSDN服务器的时钟，导致其时间计算紊乱了一阵子。

我就好奇 这个2年前的帖子 ，是基于什么原因，被翻出来的

引用 66 楼 zhao4zhong1 的回复:如果上帝当初设计的DNA这个生物编译器没有未定义行为的话，今天还能进化出人类吗？   如果上帝不能设计未定义行为，那么它不是万能的，如果上帝能够设计未定义行为，那么它不能定义所有行为，也不是万能的，于是上帝说...

22  可能是  (++i)+(++i)  = 7  + 7 = 14  + （++i）= 14 + 8 = 22   第二个+运算优先级和第一个+一样  所以 取出栈中元素运算


Question: linux stat函数问题

引用 1 楼 user-2 的回复:fgets 最后会带 \n ， 稍微写点代码去掉下。 if ('\n'==filename[strlen(filename)-1]) filename[strlen(filename)-1]=0;

fgets 最后会带 \n ， 稍微写点代码去掉下。


Question: 学了有半个月的语言了，今天发现个小问题，求指教！

float 的精度

这很正常，很多十进制浮点数是不能用二进制精确表示的，浮点数是会有误差的，float有效位数只有7位左右，如果不够可以考虑double

二进制浮点数不能精确表示十进制的小数。  ================= 就像十进制小数不能精确表示 1/3 一样。

浮点数格式 http://bbs.csdn.net/topics/390676437

float保留小数点后七到八位，如果你想要变成99.9，可以输出%.1f的格式


Question: turbo c的一个问题

3Q 赵4老师

建议学习使用TurboDebug  bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028

或许可以试试 mov dx aaa  一般来说 ds 可能只有一个，就不用动了。如果用到了多个，估计要用 far 指针 ，就不太清楚了了。

试过了,貌似不起作用,我还是用far指针实现吧,谢谢


Question: C语言输入问题

EOF  end of file

如果在cmd窗口中运行时在命令行使用“< 某个文本文件”指定输入重定向自文本文件的话，读到文件结束时也会返回EOF的。

就是结束标记，按ctrl + z 回车  将返回EOF

VS IDE中，在不明白的符号EOF上点鼠标右键，选转到定义。  键盘输入想得到EOF的话， Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter

文件结束标志，EOF(end of file)

EOF是End Of File 的缩写，表示“文件结束”。返回一个 Integer，它包含 Boolean 值 True，表明已经到达为 Random 或顺序 Input 打开的文件的结尾。 使用EOF是为了避免因试图在文件结尾处进行输入而产生的错误。 从输入流读取数据，如果到达文件末尾（遇到文件结束符），eof函数值为非零值（表示真），否则为0（表示假）。 直到到达文件的结尾，EOF 函数都返回 False。对于为访问 Random 或 Binary 而打开的文件，直到最后一次执行的 Get 语句无法读出完整的记录时EOF都返回 False。 对于为访问 Binary 而打开的文件，在EOF函数返回 True 之前，试图使用 Input 函数读出整个文件的任何尝试都会导致错误发生。在用 Input 函数读出二进制文件时，要用 LOF 和 Loc 函数来替换EOF函数，或者将 Get 函数与EOF函数配合使用。对于为 Output 打开的文件，EOF总是返回 True。

在C语言中，或更精确地说成C标准函数库中表示文件结束符（end of file）。在while循环中以EOF作为文件结束标志，这种以EOF作为文件结束标志的文件，必须是文本文件。在文本文件中，数据都是以字符的ASCII代码值的形式存放。我们知道，ASCII代码值的范围是0~127，不可能出现-1，因此可以用EOF作为文件结束标志。 应用 档案存取或其它 I/O 功能可能传回等于象征符号值 (巨集) EOF 指示档案结束的情形发生。实际上 EOF 的值通常为 -1，但它依系统有所不同。巨集 EOF会在编译原始码前展开实际值给预处理器。 C语言中，EOF常被作为文件结束的标志。还有很多文件处理函数处错误后的返回值也是EOF，因此常被用来判断调用一个函数是否成功。 例如： #include <stdio.h> int main(void) { int n,i; int array[25]; while (scanf("%d",&n),n!=EOF) //while(scanf("%d",&n)!=EOF) { for (i=0; i<n; i++) scanf("%d",array+i); for (i=0; i<n; i++) printf ("%d ",array[i]); } return 0; } 在 UNIX中， EOF表示能从交互式 shell (终端) 送出 Ctrl+D (习惯性标准)。在微软的 DOS 与 Windows 中能送出 Ctrl+Z。在某些例子处理纯文字档案或从"字元设备"读入资料，微软MS-DOS的 shell 或系统程序会加入ASCIIControl-Z 字元到磁碟档案结束处 (尽管基本核心MSDOS.SYS档案写入呼叫从未附加 Control-Z)。这是向下相容于一些奇特的CP/M功能，从CP/M 档案系统只能就记录的档案长度分配多少 128 位元 "记录"。MS-DOS 档案系统从一开始就能精确的记录档案的位元长度。 ASCII控制字符在字元串流是 out-of-band 不可列印字元。通常表可读的助忆码。 在控制台要输入eof的话 按ALT+65535就可以了 与feof C语言中，当把数据以二进制形式存放到文件中时，就会有-1值的出现，此时不能采用EOF作为二进制文件的结束标志。为解决这个问题，ANSI C提供一个feof函数，用来判断文件是否结束。如果遇到文件结束，函数feof（fp）的值为1，否则为0.feof函数既可用以判断二进制文件是否结束，也可以用以判断文本文件是否结束。 例如：编写程序，用于把一个文本文件（源文件）复制到另一个文件（目的文件）中。源文件名为file_a.dat，目的文件名为file_b.dat。程序如下： #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> voidfilecopy(FILE *,FILE *); main ( ) { FILE*fpin,*fpout; fpin =fopen ("file_a.dat","r"); /*打开输入文件*/ fpout = fopen ("file_b.dat","w"); /*打开输出文件*/ filecopy( fpin,fpout ); /*把fpin所指文件中的内容输出到fpout所指文件中*/ fclose ( fpin );fclose ( fpout ); /*关闭输入输出文件*/ } voidfilecopy( FILE *fpin, FILE *fpout ) { char ch; ch = getc ( fpin ); /*先读一次文件再去判文件是否结束*/ while ( !feof( fpin ) ) /*当未到文件末尾是进行循环*/ { putc ( ch, fpout ); ch= getc ( fpin );} /*逐个字符进行复制*/ } }


Question: 命令行参数的问题

引用 3 楼 iyomumx 的回复:linux的情况，shell会自行对 * 进行扩展为当前目录下所有内容 用 \* 转义代替应该就可以了  测试了，用gcc的话，无论是linux还是dos下，编译出的程序都会把‘*’替换成当前目录下的所有文件名， 但是用 VC++的话，就能取得预期效果。  唉~

汗，我的虚拟机上效果是这样的。。。 命令行参数为 1 * 3，从图看到，1和3之间都是当前目录文件名。。。   啥情况，换了台机器也是如此。

我的机器上:


Question: 如何用代码把png转换成jpg

感谢2位，最终用libpng + libjpeg-trubo接决了问题 http://libpng.org/pub/png/book/

GDI+

简单的可以用stb_image,想支持的格式多一点可以找libpng和libtubrojpg之类的,有很多库的


Question: 谁给拆一下这个公式 怎么代进去的。关于编码的

西格玛是求和符号，从下标(i=0)到上标(i=w-1)，代入每一个子项，求和。 式中w=4

就是 二进制变 十进制  怎么代进去是什么意思？


Question: posix信号量，利用共享内存通信。发送SIGINT信号。导致内存出错的问题

系统对SIGINT信号的缺省处理是Terminate（注意进程不是SIGINT信号结束的，而是是系统的缺省处理结束的）。  你自己处理SIGINT时，如果希望结束进程，则需要调用exit(0);


Question: 关于C中调用fwrite()和fread(),但不能写读内容.请大神帮忙.

嗯嗯...搞好了.

在main函数中，把Load()/ Save()前面的“void”去掉。


Question: 这题什么意思啊？是关于逻辑运算符 与 或 非的

就是通过 异或  达到 两个数 交换目的。  第一步 a   a^b 第二部 a^(a^b)  a^b    //a^(a^b) =a^a^b = 0^b=b 第三步 b  a^b^b          //(a^b)^b =a^(b^b) = a^0 = a


Question: switch在调用自定义函数时执行时直接跳过了case输出了default后的内容，哪里出错了？

引用 3 楼 chengeng_jd 的回复:[quote=引用 2 楼 lm_whales 的回复:] 接受了回车估计 不是回车的原因，因为scanf就是需要回车才确认输入。 估计是大小写的原因，case 'A'，那么小写的'a'是不行的。[/quote]scanf %c并不跳过空白，空白字符对于 %c也是一个字符  其它格式可以跳过空白字符， %c不会， 所以虽然是 scanf 依然要当心 空白字符，包括回车

根据你的程序和运行截图看是收到了上一次未处理完的字符。 	rewind(stdin); 	scanf("%c", &sign); 建议按照赵老师的方式改一改你的程序。  引用 8 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

case后你敲空格了没

引用 2 楼 lm_whales 的回复:接受了回车估计 不是回车的原因，因为scanf就是需要回车才确认输入。 估计是大小写的原因，case 'A'，那么小写的'a'是不行的。

case 'A': case 'a':   addition();   break; 试试

从你贴的代码判断看，最有可能的是stdin中的'\n'没有处理掉（可能之前有代码调用scan后，在stdin中还残留'\n')。  把代码中的scanf("%c", &c) 改为下面的形式，再试一下：  scanf("%[^\n]%*c", &c);  // %[^\n]%* 的作用是如果读取到'\n'则忽略

执行时并没有输入A，B就直接跳掉了default部分，不明白哪里出错了

接受了回车估计

自己单步调试看sign的值是什么


Question: UIScreenEdgePanGestureRecognizer使用时候不用判断是左边屏幕边缘还是右边边缘吗

参考这方面的开源软件人家是怎么做的。


Question: getmask_code.c:27:16: warning: assignment makes pointer from integer without a c

为什么第27行和第31行编译会出现这种警告： getmask_code.c:27:16: warning: assignment makes pointer from integer without a cast [enabled by default]   net_ip_string = inet_ntoa(net_ip_address); /*把二进制网络地址格式转换为字符串形式*/                 ^ getmask_code.c:31:18: warning: assignment makes pointer from integer without a cast [enabled by default]   net_mask_string = inet_ntoa(net_mask_address); /*把二进制掩码地址转换为字符串形式*/ 求大神赐教。

为什么第27行和第28行编译会出现这种警告： getmask_code.c:27:16: warning: assignment makes pointer from integer without a cast [enabled by default]   net_ip_string = inet_ntoa(net_ip_address); /*把二进制网络地址格式转换为字符串形式*/                 ^ getmask_code.c:31:18: warning: assignment makes pointer from integer without a cast [enabled by default]   net_mask_string = inet_ntoa(net_mask_address); /*把二进制掩码地址转换为字符串形式*/ 求大神赐教。


Question: 编译器如何解析指针

谢谢分享

指针是烧脑的难题。。。

这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做...所以要定制一款cpu ,具备初级的编译变量指针的功能和简单的内存管理功能.

这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做

这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做

数据在内存里存储的位置就是地址，在c语言里就是指针，如果没有操作系统的话，这个地址在硬件上是固定的，也是一个8位or16位or32位...的二进制数据，也可以保存。 所以指针类似int变量，保存的也只是一串01而已，访问数据的时候根据那一串地址找到位置读数据，但读出来的一串01你不知道它是哪国语言，还要翻译，所以指针还要有一个类型，这个类型就是告诉你这串01应该翻译成什么语言

example:  "int *p"                    ===> 0x000001                    ===> record of cpu [M(0x000001)]                   ===> [M(0x000001) + rs(32/64)] * (0x000001 >> 0x00000F)                   ===> [M(0x00001)] go [M(rs(32/64))]                   ===> rs--                   ===> 0x000000                   ===> "int * p" = 0x000000 == null

int *p; int a; p = &a;上面p是指针，指向a的地址。 编译器如何解析指针？ 编译器在做语法分析时，遇到*时，会将其值视为一个指针，而不是数值；在遇到&时，会做取地址的操作。这些逻辑上不会有什么问题吧？

查看汇编的寻址就可以了。。

指针也是一种变量，只不过用来表示地址的

补充： 计算机将整数作为标识内存地址来使用，其能使用的最大内存长度就是无符号整数的最大值， 8位，16位、32位CPU就是整数的长度，其相应的指针范围也就相应不同。 指针计算中，如char *p, *p1, *p2；p = p1 + 3; int i = p1 - p2; 编译器都是完全当成整数进行编译。

指针的本质就是使用一个int来记录内存地址，所以它的具体实现完全等同与int，在汇编级别就是一个int，它的存储和读取都和int完全一样，可以自由的与int进行转换和使用，空指针就是整数0，也就是NULL。  做为指针它完全不需要一定存在它所指向的内存前面，它可以存在int可以存在的任何位置，对编译器来说，重点就是将这个int当指针来使用，在编泽中，它会将其按其所指向的数据类型进行对应的读写数据编译。  举例：我们在一个子程序中写下: char a[10];(此只为举例，假设a首地址为：0x12345678) char *p = a; 编程器就会将指针p在内存上视为一个int，和其它的变量完全一样在栈中给它一个整数长度的内存，然后在这个内存中写入数组a的第一个内存地址0x12345678这个整数值，如果你完全能确定a的地址，也可以直接写成: char *p = reinterpret_cast<char*>(0x12345678); //编译器将整数当成指针直接进行赋值 或者 *reinterpret_cast<int *>(&p) = 0x12345678;	//编译器将字符指针直接当成一个整数来用，使用整数赋值   编译器在计算时将其作为整数处理，然后按其约定类型，如整数型指针还是字符型指针等，对使用它进行内存读写的代码进行相应编译，同一个指令在操作不同类型数据时，机器码会有一定变动。这段代码在CPU运行时，会先将p作为普通整数读取到寄存器中，再将这个寄存器视为地址寄存器，对此整数所指向的内存位置进行相应类型的数据读写。 如: mov ebx, [esp+4]  //假设p在栈中位置为esp + 4，先将esp+4这个内存视为普通整数装入ebx中      mov [ebx], 'c'  //将ebx中整数所指向的内存赋值为‘c'， 即*p = 'c'

指针也是一个变量  指针也存在内存中。   指针中存储的是一个内存地址，直接到指针所指向的地址取出数据就行了（根据指针类型决定取多少个字节）  内存就是一个大的字节数组

1、指针也是一个数据 2、不同CPU处理指针不同，但是一般都有一个数据地址寄存器，用于从某个地址取出数据 3、例如int i = &k; 在汇编中要具体看CPU和编译器，可以参考： http://www.cnblogs.com/findumars/archive/2013/09/05/3302457.html  4. 寄存器间接寻址方式（寄存器在括号里） MOV BX,[DI] 操作数的有效地址用SI、DI、BX和BP等四个寄存器之一来指定，称这种寻址方式为寄存器间接寻址方式。 若有效地址用SI、DI和BX来指定，则其缺省的段寄存器为DS； 若有效地址用BP来指定，则其缺省的段寄存器为SS(即：堆栈段)。 5. 寄存器相对寻址方式（一个寄存器和一个立即数在括号里，并且还要计算） MOV BX, [SI+100H]

想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！

以python为例，系统会对所有的对象附上一个id值，这个值就是指针，当开发者需要调用时对象时，需要提供句柄（也即可以理解为标签），编译器会根据句柄的特性，找到所需要的地址空间

楼主可以参考g++源代码中解析指针相关片断。 不过如果楼主因此过劳死的话，那纯属巧合，与本ID无关。

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

想多了，都是数据操作而已，写程序是按编译器要求写的，编译器也不在乎这个那个的，倒是ide编写比编译器要考虑更多的事情，比如语法即时分析，各种跳转等。


Question: 求助：为什么在一趟排序完毕后要回归关键数

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

我靠 ，看了网上的例子都说是key跟a[i]或者a[j]交换树值，原来只是a[i]或者a[j]互相赋值，根本没有交换。  那这段 a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/     sort(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/     sort(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/                        /*当然最后可能会出现很多分左右，直到每一组的i = j 为止*/  我换成这样 a[j] = key;     sort(a, left, j - 1);     sort(a, j + 1, right); 是不是也对呀

把作为分界值的那个数key放到这个位置。要不的话，这个数就丢了，因为后面再递归对两边的排序，哪一边都没有它，left的位置可能已经被别的数占了，之前有下面的语句         a[i] = a[j];         /*找到一个这样的数后就把它赋给前面的被拿走的i的值（如果第一次循环且key是         a[left]，那么就是给key）*/

下一句要排的是 left .. i-1 ，不包括 a[i] 。  一遍排序完成是 key 应该在 a[i] 的位置，所以需要把 key 赋值给 a[i]

同样的算法，竟然思路这么不同， 这个不知道要比运用临时变量交换a[i]和a[j]的值的那个思路运算快多少？ 唉，同样一把剑，用起来高下立分


Question: c语言二维数组

a是二维数组，可以看成一个表格。

就是给这个元素赋值1，建议先把基础打好

a[21][9]赋值为1 就是第22行，第10列这个格子赋值为1 下标从0开始


Question: cannot convert from 'double (__cdecl *)(double)' to 'double (__cdecl *)(void)'

引用 7 楼 paschen 的回复:引用 4 楼 qq_18543005 的回复:[quote=引用 3 楼 paschen 的回复:] 提示说的很明白了，类型不同，这里不能进行隐式转换可是这是我照着练习题上抄下来的。。。答案就是这样f=f1，f=f2  C语言下允许这种隐式转换，但C++不行[/quote]明白了

引用 4 楼 qq_18543005 的回复:引用 3 楼 paschen 的回复:提示说的很明白了，类型不同，这里不能进行隐式转换可是这是我照着练习题上抄下来的。。。答案就是这样f=f1，f=f2  C语言下允许这种隐式转换，但C++不行

为什么这个就可以

提示说的很明白了，类型不同，这里不能进行隐式转换

f = f1;  f  的类型是 double (*)() f1 的函数指针类型是 double (*)(double)  两者不同，无法转换。

#include <stdio.h>  double f1(double x) { 	return x*x; } double f2(double x,double y) { 	return x*y; } double fun(double a,double b) { 	double (*f)(); 	double r1,r2; 	f = f1; 	r1=f(a); 	f = f2; 	r2=(*f)(a,b); 	return r1+r2; } main () {double x1=5,x2=3,r; r=fun(x1,x2); printf("\nx1=%f,x2=%f,x1*x1+x1*x2=%f\n",x1,x2,r); }


Question: 请教一个内存释放的问题

你可以看看malloc的实现 每块申请的内存 会有相应的大小信息记录

这个涉及到malloc和free的实现原理，网上一搜一大堆。 malloc分配内存时会多申请一点内存用于记录申请的信息，所以free时就不需要指定大小等信息。

怎么一口气发了两个贴子了.

引用 1 楼 lgbxyz 的回复:能 free是根据地址来进行操作了，不是sizeof(你申请的类型)  它是怎么知道我要free多少大小的.难道是我程序分配出来的空间.系统作了标记?

能 free是根据地址来进行操作了，不是sizeof(你申请的类型)


Question: 这种情况有几个tcp 连接？

引用 3 楼 u010165006 的回复:用CGI吗？不过CGI比较老了，Java应该更强大。 没有搞过这个，只有概念。 浅谈Java Servlets与CGI程序 http://developer.51cto.com/art/200907/135211.htm

用CGI吗？不过CGI比较老了，Java应该更强大。 没有搞过这个，只有概念。

tcp 连接有几条  这个得看 HTTP 协议了。不同的配置下会不同。

需要网站的机器 来处理你访问资源的请求


Question: 杭电acm2072  求解，找了几个都不能AC 啊

#include "stdafx.h" #include<stdio.h> #include<string.h> #include<stdlib.h>   typedef struct {     int table_size;     int *index;     char **string;     int count; }Hash;  Hash HashTable(int size) {     Hash hashtable;     hashtable.table_size = size;     hashtable.index = (int *)malloc(sizeof(int)*size);     hashtable.string = (char **)malloc(sizeof(char *)*size);     memset(hashtable.index, 0, sizeof(int)*size);     hashtable.count = 0;     return hashtable; } void FreeHashTable(Hash *hashtable) {     for (int i = 0; i < hashtable->table_size; i++) {         if (hashtable->index[i] != 0) {             free(hashtable->string[i]);             hashtable->string[i] = NULL;         }     }     free(hashtable->index);     hashtable->index = NULL;     free(hashtable->string);     hashtable->string = NULL; } int hash(Hash *hashtable,char * string) {     int index = 0;     for (int i = 0; string[i] != '\0'; i++)     {         index = index * 257 + string[i] + 128;         index = index % hashtable->table_size;      }     return index; } void Insert(Hash * hashtable, char * string) {     int hashv = hash(hashtable, string);     while (hashtable->index[hashv] == 1 && (strcmp(hashtable->string[hashv], string) != 0))         hashv++;     if (hashtable->index[hashv]==0) {         hashtable->index[hashv] = 1;         hashtable->string[hashv] = (char *)malloc(sizeof(char)*(strlen(string)+1));         strcpy(hashtable->string[hashv], string);         hashtable->count++;     } }  void countword(char * a) {     char * word = strtok(a, " ");     Hash hashtable = HashTable(strlen(a));     while (word != NULL) {         Insert(&hashtable, word);         word = strtok(NULL, " ");     }      printf("%d\n", hashtable.count);     FreeHashTable(&hashtable); }  int main() {     char a[10000];     while (1) {         gets_s(a, 10000);         if (strcmp(a, "#")==0)             break;         countword(a);     }     system("pause");     return 0; }稍微修改一下就能用了

可以用树（二叉树来做），也可以用字典树做 每次插入单词，统计一下如果是新单词，单词数量加一

有个小陷阱，比如输入 you are my friend you are my friend # 正确输出应该是4。其它没什么要注意的了。


Question: 两个计算机系统基础问题

楼主打算这辈子都停留在不懂汇编和计算机组成原理的状态中吗？ 还是拿出缺啥立即补啥，不知道啥立即学啥的勇气？

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

不够减可以借位，或者直接用计算器算

引用 2 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！ 赵老师，我没大学学历。只是想在空闲的时间尽可能的多学点东西。 我这不是迷信，是因为我可以说根本没有基础。我现在想要做到理解程序这个东西就得通过这些书本。我的另外一个账号也有你的回答。  你给的建议是 看书看一千遍，不如自己手敲一遍。我调试了，看了调试时给出的信息我也是知其然不知其所以然。因为我没基础。 而现在这本深入计算机系统，就是在讲 为什么。你曾经说要看汇编窗口 栈这些东西。可我到现在还没能理解到栈是什么东西。汇编更看不懂。所以还是老老实实打基础。 我以前把不懂的地方，发到我加的C语言讨论QQ群里面去问，没想到居然有人说要请我写软件。我当时就想就我这水平还写软件。所以就跟对方说我有自知之明，目前为止没有那水平。

1、a-c不够减，向左借位，借一当十六。左边e借出一位后成了d，本位结果：a+十六-c得十四，即e 2、不知道函数show_bytes的作用，不好妄猜。不过，四字节的0x87654321在大端机器内存中从起始地址开始依次存放的是0x87，0x65，0x43，0x21；在小端机器内存中从起始地址开始依次存放的是0x21，0x43，0x65，0x87


Question: 关于指针 赋值 分配内存问题。

一根棍子，抓住一头，你就可以举起来了，不用每个位置都抓住 同样一块内存，找到首地址，你就可以找到其他地址了 同样找到地址，你就可以找到地址中的对象了 这就像找到你家，只要你在家中，就一定能见到你一样。  因此无论分配多少内存，只需要一个指针就可以储存了（储存首地址，第一个对象的地址） C,C++ 动态分配的地址，对应的内存中的对象，是没有名字的，只以地址值来表示这块内存。 C,C++更常用的是用名字来使用内存 变量名。数组名，函数名 这些名字 都可以代表某个地址中的对象  而动态分配的对象没有名字 因此不立即使用的话，必须用一个名字和他联系起来，把他的地址记录下来 才可以用到，不会丢失找不到。  指针变量储存地址正合适。他就是干这个勾当的 所以通常，用指针变量，储存动态分配的内存的（首）地址。

说是一物即不中

引用 8 楼 qq_33515515 的回复:[quote=引用 5 楼 u010165006 的回复:] int *p=(int *)malloc(10000); 等同于： int *p; p=(int *)malloc(10000); 不过要注意malloc(10000)是分配1万个字节，再把指针类型强制转换为 int * 如果要分配10000个int变量的空间，正确的应该是： p=(int *)malloc(10000*sizeof(int)); malloc函数分配一段连续的内存空间，返回值是连续内存空间的首地址，首地址赋给指针变量p，通过p加偏移就可以访问这一段内存数据，只要不越界。  返回值是连续内存空间的首地址，首地址赋给指针变量p。这正是我不理解的地方，谢谢你。[/quote]指针变量你可以理解为用来写一个门牌地址的纸条，纸条A=xxx，表示在纸条A上保存住了xxx这个地址信息，通过纸条A上的值（地址），就可以找到某个地方

引用 5 楼 u010165006 的回复:int *p=(int *)malloc(10000); 等同于： int *p; p=(int *)malloc(10000); 不过要注意malloc(10000)是分配1万个字节，再把指针类型强制转换为 int * 如果要分配10000个int变量的空间，正确的应该是： p=(int *)malloc(10000*sizeof(int)); malloc函数分配一段连续的内存空间，返回值是连续内存空间的首地址，首地址赋给指针变量p，通过p加偏移就可以访问这一段内存数据，只要不越界。  返回值是连续内存空间的首地址，首地址赋给指针变量p。这正是我不理解的地方，谢谢你。

c指针 http://blog.csdn.net/zhangxiangdavaid/article/details/37885275

推荐一本书： 《深入理解C指针》

引用 1 楼 user-7的回复:不知道问的意图是什么， 无从答起，随便写写。  int *p=(int *)malloc(10000) --》 含义更明确写法是 int *p=(int *)malloc(10000*sizeof(int)) 就是分配 可以保存10000个int数据的内存，并返回它的开始位置，赋值给p， 以后就可以对p进行操作了。  后面两个无非是把int 变为， 指针， 或者结构体。 你好，你所说的赋值给p，正是我不理解的地方，p只是一个指针，如何给指针分配内存？指针不是4字节吗？

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

malloc(size)返回是首地址,返回类型是void *, 不是int *,char**之类,后面有size个字节的空间可用


Question: 输入输出都不会的小白，请指教。

格式规范的领域：scanf和wscanf功能 格式规范具有以下形式： %  [宽度] [ { H | L | I64 | L } ]型 格式参数指定输入的解释，并且可以包含以下的一个或多个： 空格字符：空白（''）；标签（'\t'）；或换行符（'\n'）。一个空格字符导致scanf读取，但没有商店，所有连续的空格字符输入到下一个非空格字符–。格式中的一个空格字符匹配任意数量（包括0）和在输入中的空格字符的组合。 非空白字符，除了%符号（%）。一个非空格字符的原因–scanf读取，但不存储，–匹配非空白字符。如果在输入下一个字符不匹配，scanf终止。 格式规范，介绍了百分之百的符号（%）。一个格式说明原因scanf读取和转换字符在输入到一个指定类型的值。该值被分配给参数列表中的一个参数。 格式是从左到右读。在格式规范有望匹配输入字符序列特征；匹配字符在输入扫描但不存储。如果一个字符在输入与格式规范，冲突scanf终止，和字符留在stdin为未读。 当遇到第一种格式规范时，根据本规范将第一输入字段的值转换，并存储在第一个参数指定的位置中。二次格式规范使得二次输入字段被转换并存储在第二个参数中，因此通过格式字符串的结尾。 输入字段定义为所有字符到第一个空白字符（空格，制表符，换行符，或或），不能按规范格式转换的第一个字符，或直到字段宽度（如果指定）达到。如果有太多的参数，对于给定的规格，额外的参数进行评估，但忽略。如果格式规范没有足够的参数，结果是不可预测的。 的格式规范的各个领域是一个字符或一个数字代表一个特定格式选项。的类型字符，它出现在上一个可选的格式字段，确定输入字段是否被解释为一个字符，一个字符串，或一个数字。 最简单的格式规范仅包含%符号和类型字符（例如%）。如果百分之一个符号（%）后跟一个没有意义的字符，字符和下面的字符（最多为下一个符号）被视为一个普通的字符序列，即必须匹配输入的字符序列。例如，要指定百分之一个符号字符为输入，请使用%。 星号（*）以下百分号抑制下一个输入字段赋值，它被解释为一个字段指定类型的。该字段被扫描但未存储。

多谢各位提醒，最起码的用法都不知道。

scanf那句改成：scanf("%c %c %c",&a1,&b1,&c1); 然后输入q w e 中间用一个空格分割

楼主确定没说错么，不是 q（换行）（空行）w么？因为scanf的输入模式和双引号""中的必须一样。 也就是"%c%c%c"，输入的时候必须连着，qwe，如果按照楼主这么输入的话就应该是"%c %c %c"。中间加空格了。

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


Question: C语言算法问题，A到B来回往复,自己试着写了一段，帮看看哪儿出了问题？

判断浮点数相等请不要用==这种， 而是根据你需要的精度用大于小于判断 比如  if（fabs(day-300.0f)<0.1f）

等号用错了吧，变成赋值了

if里面应该是||不是&&

if(day == 300.0f)  if(day == -300.0f)

if(day ==  300.0f)

void main() {     int k=0;     float day = -300.0f;     int n=0;      while (1) {         switch (k) {             case 0:                 day = day +0.01;                 if(day >=  300.0f) k =1;             break;             case 1:                 day = day -0.01;                 if(day <= -300.0f) k =0;             break;         }         n++;         printf("n:%03d k:%d day:%.6g\n",n,k,day);         if (n>700) break;     } }


Question: C语言有关输入的问题

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

每组数据单独输入比较好，分别有结束标识

可是没看懂啊。。。我如果只是想简单的读入这两组数据呢  3 3 1 2 3 1 4 7 3 7 2 5 8 2 3 4 5 6 7 8  0 0

数据是随便输入，关键是数据如何分组以及如何存放


Question: 求助 调用函数求素数问题 为什么代码能成功运行 求解答

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

引用 3 楼 paschen 的回复:for循环内部是没有执行 可是下面 x 与 i都是2，所以执行了if(x == i)  return true; 同意3楼，楼主写代码最好加一加大括号，尽管里面只有一条语句。加大括号是一个良好的编程习惯。

bool IsPrime(int x) {     int i,j;       for(i=2;i<x;++i)      if(0 == x%i)        break;         if(x == i)         return true;     else         return false;     }   如果代码是这样，x=2，当然跳过for循环，而执行if(x==i)这句了，此时的变量i已经被赋值为2，与x的参数值相等。

for语句? 代码加花括号对.


Question: 求助c语言时间函数的问题

用定时器，每分钟或者每30 秒更新一次时间。 需要刷新界面，则刷新时候更新时间。

/* localtime example */ #include <stdio.h>      /* puts, printf */ #include <time.h>       /* time_t, struct tm, time, localtime */  int main() {     time_t rawtime;     struct tm* timeinfo;      time(&rawtime);     timeinfo = localtime(&rawtime);     printf("Current local time and date: %s", asctime(timeinfo));       time_t timer;     struct tm y2k;      // 2000-01-01 01:01:01      y2k.tm_hour = 1;   y2k.tm_min = 1; y2k.tm_sec = 1;     y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;       char time_str [80];     strftime(time_str, 80, "%Y-%m-%d %H:%M:%S", &y2k);     printf("%s\n", time_str);       return 0; }   //    struct tm { //    int tm_sec;     /* seconds after the minute - [0,59] */ //    int tm_min;     /* minutes after the hour - [0,59] */ //    int tm_hour;    /* hours since midnight - [0,23] */ //    int tm_mday;    /* day of the month - [1,31] */ //    int tm_mon;     /* months since January - [0,11] */ //    int tm_year;    /* years since 1900 */ //    int tm_wday;    /* days since Sunday - [0,6] */ //    int tm_yday;    /* days since January 1 - [0,365] */ //    int tm_isdst;   /* daylight savings time flag */ //    };

/* localtime example */ #include <stdio.h>      /* puts, printf */ #include <time.h>       /* time_t, struct tm, time, localtime */  int main () {   time_t rawtime;   struct tm * timeinfo;    time (&rawtime);   timeinfo = localtime (&rawtime);   printf ("Current local time and date: %s", asctime(timeinfo));    return 0; }           time_t rawtime = gps_point->timestamp;     struct tm* timeinfo;     char time_str [80];     timeinfo = localtime(&rawtime);     strftime(time_str, 80, "%Y-%m-%d %H:%M:%S", timeinfo);     fprintf(outfile, "%s\n", time_str);

C语言localtime()函数：获取当前时间和日期并转换为本地时间       头文件：#include <time.h>       定义函数：struct tm *localtime(const time_t * timep);       函数说明：localtime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法，然后将结果由结构tm 返回。结构tm 的定义请参考gmtime()。此函数返回的时间日期已经转换成当地时区。       返回值：返回结构tm 代表目前的当地时间。       范例 #include <time.h> main(){ char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; time_t timep; struct tm *p; time(&timep); p = localtime(&timep); //取得当地时间 printf ("%d%d%d ", (1900+p->tm_year), (l+p->tm_mon), p->tm_mday); printf("%s%d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); }       执行结果：       2000/10/28 Sat 11:12:22

使用时间函数  然后switch分支就可以了 具体的函数实现有一个给忘了  就是算1970到现在的时间，你man下试试 你直接吧一天当做24×60×60×60  分三段直接输出就可以了

引用 1 楼 zhangxiangDavaid 的回复:百度下，并不难大神，求简单给段代码啊，没接触过，一头雾水啊

百度下，并不难


Question: 浮点数

浮点数格式 http://bbs.csdn.net/topics/390676437


Question: 给刚用分配好的结构体一赋值就出错

仅供参考：//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

引用 6 楼 liehu232 的回复:[quote=引用 2 楼 under_tackle 的回复:] [quote=引用 1 楼 liehu232 的回复:]         p2=(struct stu *)malloc(LENS);     p1->next=p2; 改到循环前面，要不然p1->next一直==NULL 抱歉，我不太清楚。这两句话改到哪个循环前面？[/quote]     while(p1!=NULL)       p1=p1->next; 这里运行完后，p1=NULL 所以要新分配一个结构体。  p2=(struct stu *)malloc(LENS);     p1->next=p2; 把这个移动到这个循环后面[/quote] 应该是p1=(struct stu *)malloc(LENS) p1->next=NULL: 而且后面        p2=(struct stu *)malloc(LENS);     p1->next=p2;     p3=p1;     p1=p2;     p1->next=NULL; 没有意义

引用 2 楼 under_tackle 的回复:[quote=引用 1 楼 liehu232 的回复:]         p2=(struct stu *)malloc(LENS);     p1->next=p2; 改到循环前面，要不然p1->next一直==NULL 抱歉，我不太清楚。这两句话改到哪个循环前面？[/quote]     while(p1!=NULL)       p1=p1->next; 这里运行完后，p1=NULL 所以要新分配一个结构体。  p2=(struct stu *)malloc(LENS);     p1->next=p2; 把这个移动到这个循环后面

楼主这各种不加大括号的习惯最好改一改，要不根本不知道你到底是程序写错了，还是就是只取下面一条语句

while(p1!=NULL) p1=p1->next; printf("请输入员工的员工号:"); 这个while循环判断有点问题，估计你是想移动到最后一个，需要 while(p1->next!=NULL)这个样子。

你的程序刚开始 p1=head;没有问题，然后head=malloc(...)后，head的地址已经变了，但是p1还是指导head刚才的位置，这样p1的位置还是空的，这样引用p1->XXX的任何内容会导致错误。C语言里用指针和地址是经常容易导致错误的地方。

引用 1 楼 liehu232 的回复:p2=(struct stu *)malloc(LENS);     p1->next=p2; 改到循环前面，要不然p1->next一直==NULL 抱歉，我不太清楚。这两句话改到哪个循环前面？


Question: c语言源码判断问题求救。

同意楼上的……

重新新建一个.c文件就行了

你是不是把工程类型设置成了library了？估计你需要设置一下项目属性，将其改为exe吧。

什么意思？不懂呢。我现在还没弄过控制台这些。引用 1 楼 yuelengdihai 的回复:新建一个控制台程序，按步骤来应该不会有问题

c-free，windows 系统下的。怎么办啊。引用 2 楼 galiniur0u 的回复:不知道楼主在什么环境下编译的，我用vs2013是可以正常运行的

不知道楼主在什么环境下编译的，我用vs2013是可以正常运行的

新建一个控制台程序，按步骤来应该不会有问题

你有首先建一个项目或者工程吗？ 然后才是新建C文件。

大哥，对了，请问是什么原因呢？引用 6 楼 qq_30265137 的回复:重新新建一个.c文件就行了

嗯嗯，谢谢赵老师。引用 8 楼 zhao4zhong1 的回复:Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

你这样弄好了？ 引用 6 楼 qq_30265137 的回复:重新新建一个.c文件就行了


Question: printf会改变地址的值吗？

引用 5 楼 赵4老师的回复:其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 老师你所说的什么debug，堆栈，调试我都不会啊，刚大一上学期只学了c语言，假期想自学一下数据结构。。

你运气好，内存被释放却没有重写，你再编译试试

引用 2 楼 galiniur0u 的回复:在Windows下确实需要如2楼方法修改，因为函数结束后L就被释放了。 在Linux我居然编译并且正确运行了。好坑。  错误的程序什么都可能发生，包括得到“期望的”结果。

引用 2 楼 galiniur0u 的回复:在Windows下确实需要如2楼方法修改，因为函数结束后L就被释放了。 在Linux我居然编译并且正确运行了。好坑。 #include<stdio.h> int *kk() { 	int a[2] = { 1, 2 }; 	return a; } int main() { 	int *b; 	b = kk(); 	printf("%d", b[0]); } 那请问一下为什么a没有被释放，可以打印出来。。小白勿喷。。

应该是create函数的锅，struct test L[100];改成struct test ×L = (struct test *)malloc(sizeof(struct test)*n)

引用 4 楼 qq_30265137 的回复:[quote=引用 2 楼 galiniur0u 的回复:] 在Windows下确实需要如2楼方法修改，因为函数结束后L就被释放了。 在Linux我居然编译并且正确运行了。好坑。 #include<stdio.h> int *kk() { 	int a[2] = { 1, 2 }; 	return a; } int main() { 	int *b; 	b = kk(); 	printf("%d", b[0]); } 那请问一下为什么a没有被释放，可以打印出来。。小白勿喷。。[/quote] 我终于弄明白了，如果在printf前面再加个printf栈内存就被覆盖了，而堆就不会，谢谢大家

想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！

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

栈地址为局部变量准备的, 只要函数内部声明局部变量就使用了, 不确定printf内部用了多少,可能覆盖或者不覆盖, 从你的结果来看是覆盖了, 第二个例子不一样, 你传的是参数, 这个栈地址还没有任何改变


Question: 在这样的字符串里冒号’：‘或表格号‘|’能不能作为strchr函数查找位置的字符？

不知道满不满足楼主的需求： 	char *p1; 	char *strsourcefile; 	int i = 0; 	char tmp[100]; 	char *ret = "C:\\Program File\\lengprog(ys)\\test\\Cheadgp.cfm C:\\Program File\\lengprog(ys)\\temp\\陶瓷元件1.sldprt"; 	strsourcefile = ret;  	while (1){ 		if (strsourcefile[0] == ' ' && strsourcefile[2] == ':') 		{ 			memset(tmp, '\0', 100); 			strncpy(tmp, ret, i); 			p1 = ++strsourcefile; 			break; 		} 		strsourcefile++; 		i++; 	} 	printf("0.%s %s\n",tmp, p1);

多找几次, 先找.(点) , 点后找空格

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_PATH 256 char strsourcefile[]="C:\\Program File\\lengprog(ys)\\test\\Cheadgp.cfm C:\\Program File\\lengprog(ys)\\temp\\陶瓷元件                                 1.sldprt"; char s1[MAX_PATH]; char s2[MAX_PATH]; char *p,*q; int main() {     s1[0]=0;     s2[0]=0;     p=strchr(strsourcefile,':');     if (p) {         q=strchr(p+1,':');         if (q) {             strncpy(s1,p-1,__min(q-p-1      ,MAX_PATH-1));s1[MAX_PATH-1]=0;             strncpy(s2,q-1,__min(strlen(q-1),MAX_PATH-1));s2[MAX_PATH-1]=0;         }     }     printf("[%s]\n[%s]\n",s1,s2);     return 0; } //[C:\Program File\lengprog(ys)\test\Cheadgp.cfm] //[C:\Program File\lengprog(ys)\temp\陶瓷元件                                 1.sldprt] //

路径如果有空格，用引用引起来


Question: 指针做形参传递值问题

引用 3 楼 xiaopei1982 的回复:[quote=引用 2 楼 fly_dragon_fly 的回复:] 这个unsigned char *&filename 看不懂吗? filename 是引用, 引用的内容是指针 谢谢，我知道，我就是想通过指针实现为何不行？[/quote]传指针, 只能修改指针指向的内容, 改不了指针本身,

因为不能通过形参指针参数， 修改实参指针自己 指针参数一样是值传递。  C++引用参数才是 引用传递，也就是 地址传递。 C 用指针值传递，可以模拟引用（地址）传递 但是调用端 传递的实参，是个地址（或者说就是指针） 被调函数 形参是个指针 但是如果传入一个能被改变指针值 的指针， 一样要传递指针的地址；形参为二级（或者多级）指针

引用 2 楼 fly_dragon_fly 的回复:这个unsigned char *&filename 看不懂吗? filename 是引用, 引用的内容是指针 谢谢，我知道，我就是想通过指针实现为何不行？

请教各位大侠！！！！


Question: 子函数调用bug，求大神指教

仅供参考：#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }

缓冲区里还留下了\n

引用 4 楼 lgbxyz 的回复:还是缓冲区的问题  #include <stdio.h> #define SPACE ' ' void chline (char, int, int);  int main (void) { 	char ch; 	int m, n; 	 	printf ("请输入您要打印的字符：\n"); 	while ((ch = getchar ()) != '#') 	{ 		printf ("[%c]您制定打印的字符要在哪两列之间输出？\n", ch); 		scanf ("%d %d", &m, &n); 		chline (ch, m, n); 		fflush(stdin); //清空缓冲区  		printf ("请输入您要打印的字符(#号退出)：\n");	 	} 	 	return 0; }  void chline (char ch, int i, int j) { 	int col; 	 	for (col = 1; col <= j; col++) 	{ 		if (col >= i) 		{ 			putchar (ch); 		} 		else 		{ 			putchar (SPACE); 		}  	} 	printf ("\n");  	return; }   嗯，了解了，谢了哈

引用//请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];   好麻烦啊

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。   在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

如一楼，运行输出为什么是第一次输出没有问题，第二次有问题。程序有点臃肿，小白一个，望大神指教！


Question: 如何将10位数据写入两个八位寄存器里面，用C语言编程

取低8位，按位与。。。

typedef unsigned char u8; typedef unsigned short u16 u16 data; DATA_L  =data; DATA_M =((data>>8)&0x3)|(DATA_M&~3)

这个是应用的写入 ，我一直看不懂后面为什么要&0xFF

既然是分成两个8位的寄存器，那就是说按字节截断了，直接数组访问就行了 	unsigned short x = 0x2ee; 	char DATA_L = ((char*)&x)[0]; 	char DATA_M = ((char*)&x)[1];

引用 3 楼 ding_di 的回复:有个地方不懂，data 假如是10位数据，直接赋值给DATA_L  的 D7-D0 ，剩下的D8和D9呢 data>>8将data中的D9和D8右移挪到D1和D0对应的位置,再写入DATA_M中

引用 3 楼 ding_di 的回复:有个地方不懂，data 假如是10位数据，直接赋值给DATA_L  的 D7-D0 ，剩下的D8和D9呢 丢掉了

unsigned short u16_data; u16_data = （需要输入的10位数据）； DATA_L = u16_data; u16_data >>= 8; DATA_M = u16_data;


Question: LINUX 多线程： 关于互斥锁 动态、静态申请内存有啥区别啊

静态的使用简便； 动态的可以设置更多的选项。

互斥锁就2中使用方法，静态动态没有区别，只不过是动态需要你手动释放内存而已  第一种  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  pthread_mutex_lock(&mutex); //do someting pthread_mutex_unlock(&mutex);  第二种  pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL);  pthread_mutex_lock(&mutex); //do someting pthread_mutex_unlock(&mutex);

《Windows核心编程》


Question: 新人提问，在学函数时写了代码，为什么跑不出结果

没调用函数，肯定没有打印咯

明白了，因为下面没有写f()

晕死，你都没调用那个打印的函数，在那个main函数里面


Question: C语言链表问题，求解惑

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

不知道楼主是在什么环境下编译的，我在linux以及vs2013中均运行了该程序，除了(struct test *)malloc(sizeof(struct test *));这种申请内存的方式导致在free过程中报错之外，均可以打印出结果。 请修改内存申请方式L = (struct test *)malloc(sizeof(struct test));去掉里面的*号，因为你申请的是结构体的大小，不是结构体指针的大小。

引用 1 楼 liehu232的回复:MergeList很明显不对，你在仔细看看 还有pnew = (struct test *)malloc(sizeof(struct test *)) 改成pnew = (struct test *)malloc(sizeof(struct test )) 后面多一个* 楼主链表带表头，那就应该是create函数的问题

楼主你的Lc是空的，你要加一句if(Lc==NULL)Lc=PC;这样在第一次执行循环时把LC设置为表头


Question: 用strcat函数的时候出现“段错误”（报错Program received signal SIGSEGV, Segmentation fault.）是怎么回事

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

把楼主的程序稍微改了一下， 1、start=token之后导致两个数组地址相同，start没有结束符，之后的strcat就会将token的地址再次复制一遍。 2、如果想从字符数组第二个开始复制，只需要操作字符指针++，即可。 3、pig[0] = "\0"，这种写法有些小问题，因为pig[0]是字符，而双引号下的"\0"是字符串，最好使用单引号‘\0'，或者直接清空pig，使用memset。 #include <stdio.h> #include <string.h> int main( void ) {     char s[100] = "", pig[100] = "", *token, start[2];      gets( s );     token = strtok( s, " " );     while ( token != NULL ) {         start[0] = token[0];         start[1] = '\0';         strcat( pig, ++token );         strcat( pig, start );         strcat( pig, "ay" );         printf("%s ", pig );         //pig[0] = '\0';         memset(pig, '\0', sizeof(pig));         token = strtok( NULL, " ");     }     return 0; }

strcat( pig, token[1] ); <<---- token 才是地址，token[1]是字符

token[1] 类型是char strcat第二个参数是要const char*


Question: 有arm下或者有没有特别简单的生成二维码的代码么？

楼主，你这个问题 是怎么解决的啊，我现在也被这个问题搞得头大，如果你知道，望给我解答下，谢谢！

引用 3 楼 dongpy 的回复:这个以前做过，用qrencode即可，生成二维码点阵。 编译起来好麻烦， 那个库。

引用 3 楼 dongpy 的回复:这个以前做过，用qrencode即可，生成二维码点阵。 关联的东西太多了。

这个以前做过，用qrencode即可，生成二维码点阵。

zint用过吗？ 貌似跨平台的

ZXing ？


Question: C linux 下 两个 so 中 有同名函数如何使得两个函数都能正常使用？

最近遇到了这么个问题，两个毫不相干的so文件放到项目中出现crash的问题，最终发现还是全局的同名标识符重复，后面同名的被忽略了。最后还是使用dlopen或dlmopen进行动态加载RTLD_LAZY

引用 楼主 mysticboy 的回复:C linux 下 两个 so 中 有同名函数如何使得两个函数都能正常使用？ 装载的时候用于区分项的符号重复了，改一个就是。

费那事儿！ 直接用UE修改其中一个的导出函数名字中的一个字母即可。

我知道LZ是谁了，水银

还可以写两个文件，每个文件里包装成不同的函数。

只能动态加载了。。

引用 1楼liehu232 的回复:动态加载，用哪个就加载那个so文件感谢！

动态加载，用哪个就加载那个so文件


Question: C语言实现8bit数据转成12bit数据

引用 3楼煦风之伤 的回复:求教下面这种可以吗？ unsigned long ALIGN(unsigned long address) {       return (0xCFF&address) } qiu这是向前对齐，我写的那个是向后对齐，正常情况下使用向后对齐。ALIGN_UP()

使用内存对齐， unsigned long ALIGN(unsigned long address) {       return (address + 12 - 1) / 12; }

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  仅供参考：//有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }


Question: 请教一个关于EOF的问题

引用 6 楼 lgbxyz 的回复:[quote=引用 3 楼 u010339971 的回复:] 嗯，谢谢层主。二楼的输入方法我之前用过，无效果，也不知道是怎么回事。会不会是编译器的问题。 不要链验证就不做，就说不好用 [/quote] 这方法不错，关键是C,C++标准，不知道出于什么原因考虑 Io.h conio.h 这两个头文件里面的函数，不是标准库的一部分。 因此 C,C++标准库 里面，只有cook 控制台可用。（一次读取一行） raw 控制台 不可用。 而输入立即执行，需要用到  raw 控制台 的功能（一次读取一个字符）  EOF 实际上是底层IO （包括非缓冲，和缓冲两种）IO定义的 常量。（句柄或者叫文件代号方式操作文件） 但是，也被流式IO 接受了。（Ｃ,C++流） 流式ＩＯ  是对底层ＩＯ的封装 并且，不再暴露非缓冲ＩＯ给你用了

引用 3 楼 u010339971 的回复:嗯，谢谢层主。二楼的输入方法我之前用过，无效果，也不知道是怎么回事。会不会是编译器的问题。 不要链验证就不做，就说不好用

#include <stdio.h> #include <ctype.h> int main (void) { 	char ch; 	int lower_count, upper_count; 	 	while ((ch = getchar()) != EOF) 	{ 		if (isupper(ch)) 			upper_count++; 		if (islower(ch)) 			lower_count++;	 	} 	printf ("您输入的这些字符中，大写字母有%d个，小写字母有%d个。\n", upper_count - 1, lower_count);                       /* upper_count - 1去除了输入的EOF中的字母^Z */ 	 	return 0; }   这个自编的寻找大写字母和小写字母的个数的程序使用EOF配合windows操作系统下的ctrl+z键（即在控制台界面显示^Z），在dev c++编译环境下程序运行成功。

EOF这种判断一般在文件处理时比较常见，而对于输入字符由于EOF属于特殊字符，就需要用到二楼的方法。尽信书不如无书，书中写的只是一个标准，如何理解实现才是关键。

这是一个比较恶心的问题。 我认为主要有2点： 第一点 是2楼说的 EOF 输入方法； 第二点是 输入缓冲区的问题。 getchar()是使用缓冲区的函数，你不按回车或者缓冲区不满他不会执行， 我认为你应该想要使用非缓冲区的方式，应该使用getch(无缓冲无回显)或者getche(无缓冲有回显)， 但是他们不会将EOF识别为EOF宏(-1), 所以最好使用getche函数，但是getche回显EOF有错误(win8 vs2013)， 所以折中的方式是使用getch然后手动回显。   #include <stdio.h> #include <conio.h>  int main(void) { 	int ch; 	int ct = 0;  	while ((ch = getch()) != 0x1A) { 		putchar(ch); 		ct++; 	} 	printf("\n%d characters read\n", ct);  	return 0; }

输入EOF Linux:Ctrl+D Windows:Enter,Ctrl+Z,Enter


Question: c语言中不保存／保存退出函数

addressbook用xml 临时的二进制,bin

“不保存／保存退出”对应“保存到临时文件／保存到默认的addressbook文件退出”，我觉得。


Question: 请问如何将字符编码为UTF8或者UTF16？

1楼正解，VS就用那2个， linux下用iconv函数。

如果只是转换ascill字符,转换到utf8是一样的.如果转换到utf16即unicode,这个是宽字节编码,asicll和中文即gb编码,算多字节编码,即需要直接调用vs的api函数MultiByteToWideChar,多字节转宽字节函数来实现

MultiByteToWideChar   WideCharToMultiByte


Question: 关于命令行参数的打印问题

定义了 UNICODE?  在工程属性里找找，去掉。

引用 2 楼 u011625690 的回复:[quote=引用 1 楼 user-1 的回复:] 定义了 UNICODE?  在工程属性里找找，去掉。 确实有用，非常感谢！！烦请再告知一下，为何这个设置会影响参数的打印呢，我在网上找了一些资料，都是关于这个设置会影响中文字符的显示问题，但是还是没有弄清楚为什么会影响打印长度，谢谢！[/quote]  定义了 UNICODE ，你的 _tmain ( 在 UNICODE 下是 wmain）的第二个参数 _TCHAR *argv[] 实际是 wchat_t *argv[] 。  wchar_t * 不能用 %s 打印。（用啥可以去查 MSDN 里 printf 的文档。）

引用 1 楼 user-1 的回复:定义了 UNICODE?  在工程属性里找找，去掉。 确实有用，非常感谢！！烦请再告知一下，为何这个设置会影响参数的打印呢，我在网上找了一些资料，都是关于这个设置会影响中文字符的显示问题，但是还是没有弄清楚为什么会影响打印长度，谢谢！


Question: 变量的存储空间

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

引用 7 楼 lm_whales 的回复:因为它们没有专门的数据空间储存 随着代码中用途不同，生成不同存在方式的代码 例如 #define ABC 100 ///或者 enum{ABC =100}; int a= ABC;///1）加载时候装入 a这个变量的内存中（外部变量，静态变量等情况）                     ///2) 生成mov 这种指令 ， 100 可能以立即数存在（自动变量） int arr[]={ABC,ABC,ABC};                  //1）100 最大可能是作为数据，写入obj,exe 等文件中，程序加载时候装入                   //2）因为是同一个数，也可能生成填充指令      （静态变量，外部变量等）                      //3)  也可能另外储存，函数执行时复制（函数内部自动存储类型数组） 以上这些情况，都只涉及常量100 而不是 符号常量 ABC； #define 定义的 ABC在编译之前，预编译的时候，已经被替换为100了 enum 常量ABC，在编译时替换为100  a=ABC   arr[i] =ABC  生成mov 这种指令 ， 100 可能以立即数存在（自动变量）注意，不是生成 mov a,ABC这种指令 而是 mov a,100 (应该是 两条指令 mov eax 100；mov a,eax)这种指令 总之，代码里面的ABC值，不论以何种方式存在， 都和符号常量ABC没啥关系，程序中没有任何地方跟ABC有关 都是和ABC的值100 有关系 ABC编译后，是不存在的，早已经替换为100 了 再如 a=ABC -12 ;//这个会 为a=78;这种代码，最终连100都不存在了，变成mov eax,78； mov a,eax 这种指令了。  修正一下，多半是两条指令 mov ，push ，pop 等指令都有可能

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

因为它们没有专门的数据空间储存 随着代码中用途不同，生成不同存在方式的代码 例如 #define ABC 100 ///或者 enum{ABC =100}; int a= ABC;///1）加载时候装入 a这个变量的内存中（外部变量，静态变量等情况）                     ///2) 生成mov 这种指令 ， 100 可能以立即数存在（自动变量） int arr[]={ABC,ABC,ABC};                  //1）100 最大可能是作为数据，写入obj,exe 等文件中，程序加载时候装入                   //2）因为是同一个数，也可能生成填充指令      （静态变量，外部变量等）                      //3)  也可能另外储存，函数执行时复制（函数内部自动存储类型数组） 以上这些情况，都只涉及常量100 而不是 符号常量 ABC； #define 定义的 ABC在编译之前，预编译的时候，已经被替换为100了 enum 常量ABC，在编译时替换为100  a=ABC   arr[i] =ABC  生成mov 这种指令 ， 100 可能以立即数存在（自动变量）注意，不是生成 mov a,ABC这种指令 而是 mov a,100 这种指令 总之，代码里面的ABC值，不论以何种方式存在， 都和符号常量ABC没啥关系，程序中没有任何地方跟ABC有关 都是和ABC的值100 有关系 ABC编译后，是不存在的，早已经替换为100 了 再如 a=ABC -12 ;//这个会 为a=78;这种代码，最终连100都不存在了，变成 mov a,78 这种指令了。

会存在于代码区，是指令的一部分

需要，只不过不需要动态分配。所以一般的书都是说不占空间

其实是需要的……

就相当于普通的常量，由于其值不变，没有必要在内存中开辟专门的空间存储以便存取访问。一般来说，它们是在指令中以立即数的形式存在的，实际上也占据一定的空间，不过是在代码区，不是数据区，而且除了破解软件外，没有正当的办法修改


Question: 两个字符指针变量不能同时申请一个字符指针变量的内存吗？

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

把整个程序贴出来才能找到问题

什么叫不能申请到，返回空指针吗，检查下strlen返回值，strSource是否以\0结尾 另外通常要多分配一个存储\0 检查下是哪出问题了，不然不会如你所说那样

#include<stdio.h> #include<string.h> #include<stdlib.h> int main()  {      char *p="hfkdsjahfdkasj";      char *p1,*p2;      p1 = (char *)malloc(strlen(p));      p2 = (char *)malloc(strlen(p));      if(NULL!=p1)        printf("分配成功\n");      else        printf("失败\n");      if(NULL!=p2)        printf("分配成功\n");      else        printf("失败\n");  }  不要听楼上两个乱说，我照着楼主的试了一下，都成功了啊。 编译如下：

C语言用malloc，最好是分配256字节以上，否则在有些操作系统下会失败。如果要求使用的字节数小于256，直接用 char strsourcefile[256] = {0} 就行了

不是申请内存出了问题。注意要为'\0'预备空间，如下所示 strsourcefile = (char *)malloc(strlen(strSource) + 1); strtargetfile = (char *)malloc(strlen(strSource) + 1);


Question: 新年第一问,请教利用位运算符计算问题

查表求位数。 假设同一类会变，采用数据库存储

引用 1 楼 fly_dragon_fly 的回复:#define msk (0x3F<<3) #define FRUIT 0x1E8 if( cata&msk ==FRUIT) // 水果 这个不行的,我忘记说明了,抱歉 因为分类前6位表示父级分类,有可能是7位表示,也有可能是8位表示 总之位数会变化

把你的数与 111111000做 & 运算， 这样前6位不变，后面的全变成0了，然后通过得到的结果就可以分辨出是什么分类了

//111111101     --甜饼干(前6位与饼干分类编码相同) 	WORD aa = 0x1fd;  	//父级分类 	BYTE a = aa >> 3;  	//次级分类 	BYTE b = ((BYTE)aa)&0x07;


Question: 这个十进制  十六进制 转换没看懂啊

是从二进制角度来看的 2^11相当于1后面11个0, 即, 二进制转成16进制是4个为一组, 11%4=3, 剩下3个0与前面1组成1000就是8, 11/4=2, 组成十六进制两个0, 十六进制得到0x800


Question: cunit可以一次测试多个.c文件吗

使用多进程 参考《Unix编程艺术》


Question: 一个关于c源码选择语句的问题？

谢谢版主大大。引用 3 楼 lianshaohua 的回复:解决了就好。

解决了就好。

嗯嗯，对了。谢谢。引用 1 楼 user-2 的回复:case'2':语句去掉单引号，否则是字符判断1 肯定不等于'1'

case'2':语句去掉单引号，否则是字符判断1 肯定不等于'1'


Question: 问一个算法到底是什么意思求最大值的最小情况

引用 1 楼 user-1的回复:n和k是什么没看明白, 假设人数为ct, mid代表分得1个人分得最大的钱,那么剩下ct-1个人来分money-mid, 显然这ct-1个人中让一个人分得最大是money-mid-(ct-2)这个值需要小于mid, 即mid>money-mid-(ct-2)  ==> 2*mid+ct-2>money 明白了，移项之后明了了很多，3Q


Question: 新手有问题请教关于C的错误

各种排序算法动画演示http://www.webhek.com/misc/comparison-sort/

排序集锦 http://blog.csdn.net/zhangxiangdavaid/article/details/25082013

void Sort(int score, long num[], int n)错了，听说能蹭分

帮结帖＋蹭分

晕，自己发现问题了！


Question: C语言怎么调用动态库

引用 楼主 qq_30587385 的回复:C语言怎么调用动态库，求高手解答 动态库调用是loader的事情和c语言没关系。  至于如何使用动态库的方式是编译器的问题。

查MSDN是Windows程序员必须掌握的技能之一。

Widows 动态库  静态链接 1）  #pragma comment (linker,"动态库名.lib") 2）在VC中可以直接把 .lib加入工程  这二者任选一个即可。 3）要有函数原型，开发动态库的开发者一般会提供头文件，没有的话，自己写函数原型，如果知道的话    动态链接（手动写代码直接链接）  LoadLibrary（） 加载 或者 LoadLibraryEX（） 加载 GetProcAddress 取得导出函数和导出变量地址 FreeLibrary（），FreeLibraryEX（） 卸载动态库 另外： 如果动态库有资源，而 exe 要用，就要处理好资源句柄问题。

或者LoadLibrary（）的方式

大概要加 如下: 动态库中函数的声明   和  #pragma comment (linker,"动态库名.lib") 注意 动态库名.lib  和  动态库名.dll 要在工程目录下。


Question: 大学作业，求帮忙

作业贴一律不回

英文。。。。

英文原文.

英语也是一门计算机语言的说。

shit一样的翻译...

哥，你还不如直接贴英文的上来，看的头晕


Question: 自学新手，关于指针变量与函数的实参/形参传送问题，期望各位大神能带小弟一把！

非常感谢两位大神能给我解惑，跟据 user-2  大神的指点并测试，实参是指针变量时，形参可以是指针变量或数组名，而我原来使用的是指针数组。如果实参是数组名，形参就可是指针数组（实测可行）！user-2  大神提到的内层循环如果改成 x-i-1 ，改完后还是会出现越界问题，内外层都改成 x-1 就不会越界（已实测）。被这个问问题困了两天，非常感谢各位大神的帮助

ta的类型是int** ta[j]的类型是int*，而不是int

两个问题，冒泡法的数组访问会越界，因为有ta[j + 1]，所以双层for循环的终止条件是i和j小于x-1。内层循环的终止条件也可以为x-i-1，可以省去不必要的循环。 第二个问题，函数的形参接收数组时候要写成指针，而不是指针数组。在被调函数中这个指针有可以作为数组来用。 void suijifuzhi(int *temp, int x);	//声明外部随机数生成函数 void maopaomaxtomin(int *ta, int x);	//声明冒泡法排序，由小到大或由大到小  修改后的程序： #include<stdio.h> #include<stdlib.h> #include<time.h>  #define N 10   void main() { void suijifuzhi(int *temp, int x);	//声明外部随机数生成函数 void maopaomaxtomin(int *ta, int x);	//声明冒泡法排序，由小到大或由大到小   int num[N] = {0}; int *p = num;  suijifuzhi(num, N);	///调用随机数生成函数 maopaomaxtomin(p, N);	//调用冒泡函数，实参用指针变量，形参用数组名    //system("pause"); }  void suijifuzhi(int *temp, int x)	//随机数生成函数 { time_t tms; srand((unsigned int)time(&tms)); for (int i = 0; i < x; i++) { temp[i] = rand() % 100; printf("%-4d", temp[i]);  }  }  void maopaomaxtomin(int *ta, int x) { 	for (int i = 0; i < x-1; i++) 	{ 		for (int j = 0; j < x-i-1; j++) 		{ 			if (ta[j]<ta[j + 1])	//大于就行，小于就不行，不知道为什么 			{ 				int temp = ta[j]; 				ta[j] = ta[j + 1]; 				ta[j + 1] = temp; 			} 		} 	}  	printf("\n冒泡法排序后：\n"); 	for (int i = 0; i < x; i++) 	{ 		printf("%-4d", ta[i]); 	} 	printf("\n");  }


Question: 读取exe文件到内存后，对比WinHex打开同样文件，总有几个字节不同？如何处理，为啥会不同，应该一模一样才对？

引用 2 楼 xxxd39 的回复:是存储地址不同。，其他都一样！海 什么存储地址？你是作为文件打开的。

函数原型：  size_t fread(void *buffer, size_t size, size_t count, FILE *stream);  改成： result=fread((void *)buffer,1,lSize,pFile);

是存储地址不同。，其他都一样！海

buffer = (char *)malloc(sizeof(char)*lSize); buffer要不要多一个字节？我也不确定 你只是读取了文件到buffer，怎么看出与WinHex显示的不同？


Question: 关于typedef struct的用法

经过VC6验证可以这么用的： #include <iostream> using namespace std;  typedef struct GNode { 	int x; 	int y; 	struct GNode *next; }GNode;  int main() { 	GNode aNode={5,10,NULL}; 	cout<<aNode.x<<","<<aNode.y<<endl;          return 0; }

引用 1 楼 user-2 的回复:第一个Gnode是结构体名称，后一个是typedef重新定义出来的类型名称。 第一个Gnode要和struct连起来一起用，比如定义一个变量 struct Gnode *p; 这个结构体名称可以省略的，但是你要是在结构体里用到了自己，这个结构体名称就不能省了。 struct Gnode里有一个变量是struct Gnode*，如果省略了struct后面的结构体名称，就不好写了。  谢谢啊，原来第一个gnode是结构体名称 也就是说第一个gnode是初始化这个结构体的时候的名称， 第二个gnode可以理解为重新命名的结构体的别名  谢谢

相当于： struct Gnode{...}; typedef struct Gnode Gnode; 不过一般不这么写，一般可能这样： struct tagGnode{...}; typedef struct tagGnode Gnode; 或者： typedef struct tagGnode  {...} Gnode;  你这本书是国产的还是国外翻译的？如果是国产的可能有误，没验证过这么写是否可以。


Question: C语言access函数返回值的问题

是的  if(!access("C:\\Users\\Administrator\\a.txt",0)) 表示存在  https://msdn.microsoft.com/zh-cn/library/1w06ktdy.aspx


Question: 如何把这段代码改成OMP多线程代码？谢谢

你需要让每次循环是独立的，这样才好用并行运算

引用 6 楼 situjunc 的回复:[quote=引用 5 楼 paschen 的回复:] 你需要让每次循环是独立的，这样才好用并行运算 额，但是这个问题，后面的数据受之前的数据影响，所以怎么独立呢.....[/quote]   http://wenku.baidu.com/link?url=u1gXSZipz8P7yggkOOUcr3crFcvFCvGXi6NksfkrHlgU4FJ9iTPk-4VL1otCqlk6g4gph3dufq2z_uhxm4mHt-S41Y0EY6ffvLOOisllYSO

引用 5 楼 paschen 的回复:你需要让每次循环是独立的，这样才好用并行运算 额，但是这个问题，后面的数据受之前的数据影响，所以怎么独立呢.....

看一下，这个貌似是有难度的 后一次循环 依赖于 前一次循环的计算结果

#pragma omp parallel for

引用 楼主 situjunc 的回复:额，有一个三维数组h[2][100][100]，其实就是两个二维数组h[0][99][99]和h[1][99][99]。 其中h[0][49][49]=100,h[1][49][49]=100。剩下的所有数据初始化为20。执行下面的迭代代码后，就会数据就会改变。其实就是热量散布问题啦..... 现在要怎么把这段顺序改成#pragma omp parallel 这种并行代码呢？谢谢  for (iteration = 0; iteration < 999; iteration++) {         for (i = 1; i < 99; i++){              for (j = 1; j < 99; j++){                  h[next][i][j] = 0.25 * (h[current][i-1][j] + h[current][i+1][j] + h[current][i][j-1] + h[current][i][j+1]);              }         }         current = next; // swap values of current and next         next = 1 - current;     }  恩，这个的确是要用#pragma omp parallel for，但是shared,private和其他部分老出错，并行代码出来的结果总是和顺序代码结果不一样。 所以并行代码要如何写呢？谢谢

引用 1 楼 paschen 的回复:#pragma omp parallel for 恩，的确是用#pragma omp parallel for，但是shared,private和其他部分老出错，并行代码出来的结果总是和顺序代码结果不一样。 版主大大，可以提供一下具体的并行代码吗？谢谢


Question: 通宵没解决，如何 把 二维数组，作为参数 传给 函数，跪求，是否涉及推或者栈的问题，我糊涂了，

定义实参的时候，用new关键字申请，在函数中形参直接用二维指针就行

传递指向这个二维数组的指针

定义一个二级指针指向二维数组，然后吧元素个数也传递过去，然后按照一维数组进行遍历。我的想法，明天起床去试一下，应该可以

引用 38楼赵4老师 的回复:[quote=引用 37 楼 qq20004604 的回复:] 突然想了一个办法。  创建一个类呗，这个类储存了这个二维数组。假如你不需要修改源二维数组的话，通过赋值，将这个二维数组赋值给类。 具体方法如下： 类包含int i; 用于描述有几列数，int j，用于描述有几排。一个指针（例如int*），用于指向储存的二维数组 你先调用一个类方法，用于设置i和j的值。int *mm=new int[i][j]; 然后逐个赋值： for(int i=0;i<x;i++)  //x为二维数组有几行 for(int j=0;j<y;j++)  //j为二维数组有几列 pp.setXY( m[i][j],i,j);   //setXY为给类对象new出来的二维数组的某一个值赋值，具体是哪个，根据参数2和参数3决定，pp是类对象  然后你函数传递该类就行了。虽然麻烦点，但简直万能！（——应该吧？） 最起码你这个类无法包含整个互联网内容。[/quote]那就继续加更多的数据成员～

引用 37 楼 qq20004604 的回复:突然想了一个办法。  创建一个类呗，这个类储存了这个二维数组。假如你不需要修改源二维数组的话，通过赋值，将这个二维数组赋值给类。 具体方法如下： 类包含int i; 用于描述有几列数，int j，用于描述有几排。一个指针（例如int*），用于指向储存的二维数组 你先调用一个类方法，用于设置i和j的值。int *mm=new int[i][j]; 然后逐个赋值： for(int i=0;i<x;i++)  //x为二维数组有几行 for(int j=0;j<y;j++)  //j为二维数组有几列 pp.setXY( m[i][j],i,j);   //setXY为给类对象new出来的二维数组的某一个值赋值，具体是哪个，根据参数2和参数3决定，pp是类对象  然后你函数传递该类就行了。虽然麻烦点，但简直万能！（——应该吧？） 最起码你这个类无法包含整个互联网内容。

可以直接用函数的嵌套塞，现定于一个函数，再在main函数中用

C语言，一切皆指针，而指针无非是一个变量，保存的是地址而已。所以把一切都看成个数，然后用的时候强制转化成想要的类型来用就行。

数组本来就无法当参数传递给函数(结构体里的数组例外),只能以指针的形式传递,而且传递的过程中会丢失部分数组信息(大小)

例如要传array[m][n]，传&array[0][0]、m、n，里面用的时候自己求具体位置。 用sizeof(array[0][0])求出对象长度， 然后哪行哪列慢慢算到要取的数的内存地址，再把对象取出来就行了。 核心依据：数组的内存是连续的。

引用 31 楼 Xiejunyi12 的回复:[quote=引用 27 楼 sholber 的回复:] void f (int (* p) [2][3], int x, int y) {     (* p) [0] [0] = (* p) [1] [1]; }  int main (void) {     int a [2] [3];     f (& a, 2, 3); }  你搞个三维数组干嘛的。。。 int (* p) [2][3] 是三维的[/quote]  谁说的。p明明是指向二维数组int [2][3]的指针。 #include <stdio.h>  typedef int arr [2] [3];  void f (arr * p) {     int x = sizeof (* p) [0] / sizeof (int);     int y = sizeof * p / (x * sizeof (int));          printf ("%d, %d\n", x, y); }  int main (void) {     arr a;     f (& a);          return 0; }

引用 27 楼 sholber 的回复:void f (int (* p) [2][3], int x, int y) {     (* p) [0] [0] = (* p) [1] [1]; }  int main (void) {     int a [2] [3];     f (& a, 2, 3); }  你搞个三维数组干嘛的。。。 int (* p) [2][3] 是三维的

用struct啊，给它包裹住！然后你想传什么？！都可以啊

void xxx(char a[2][3]); ????

引用 25 楼 chengeng_jd 的回复:[quote=引用 24 楼 zhangxiangDavaid 的回复:] 请不要忽略这个warning： warning C4047: “函数”:“int *”与“int [2][6]”的间接级别不同 warning C4024: “array_manu”: 形参和实参 1 的类型不同 确实有warning，请教如何解决比较好。[/quote] 原因在于类型不匹配。 按我说的方法修改即可。

引用 24 楼 zhangxiangDavaid 的回复:请不要忽略这个warning： warning C4047: “函数”:“int *”与“int [2][6]”的间接级别不同 warning C4024: “array_manu”: 形参和实参 1 的类型不同 确实有warning，请教如何解决比较好。

引用 23 楼 chengeng_jd 的回复:[quote=引用 11 楼 zhangxiangDavaid 的回复:] [quote=引用 10 楼 chengeng_jd 的回复:] 传指针数组就是了，然后把2个维度也当参数传。 请具体演示……[/quote] //把传入的一个二维数组的元素都加上1 void array_manu(int *M, int ny, int nx) {     for(int y=0; y<ny; y++)         for(int x=0; x<nx; x++)             *(M+(y*nx)+x)= *(M+(y*nx)+x) +1; }  int main(void) {     //定义一个二位数组，并初始化     int myArray[2][6]= {{1, 2, 3, 4, 5, 6},                         {11, 12, 13, 14, 15, 16}};     for(int y=0; y<2; y++)     {         for(int x=0; x<6; x++)             printf("%d\t", myArray[y][x]);         printf("\n");     }     printf("\n");     array_manu(myArray, 2, 6);     for(int y=0; y<2; y++)     {         for(int x=0; x<6; x++)             printf("%d\t", myArray[y][x]);         printf("\n");     }     return(0); } 执行结果符合预期。[/quote] 请不要忽略这个warning： warning C4047: “函数”:“int *”与“int [2][6]”的间接级别不同 warning C4024: “array_manu”: 形参和实参 1 的类型不同

引用 11 楼 zhangxiangDavaid 的回复:[quote=引用 10 楼 chengeng_jd 的回复:] 传指针数组就是了，然后把2个维度也当参数传。 请具体演示……[/quote] //把传入的一个二维数组的元素都加上1 void array_manu(int *M, int ny, int nx) {     for(int y=0; y<ny; y++)         for(int x=0; x<nx; x++)             *(M+(y*nx)+x)= *(M+(y*nx)+x) +1; }  int main(void) {     //定义一个二位数组，并初始化     int myArray[2][6]= {{1, 2, 3, 4, 5, 6},                         {11, 12, 13, 14, 15, 16}};     for(int y=0; y<2; y++)     {         for(int x=0; x<6; x++)             printf("%d\t", myArray[y][x]);         printf("\n");     }     printf("\n");     array_manu(myArray, 2, 6);     for(int y=0; y<2; y++)     {         for(int x=0; x<6; x++)             printf("%d\t", myArray[y][x]);         printf("\n");     }     return(0); } 执行结果符合预期。

引用 楼主 wykqhyjs 的回复:比如 int a[2][3]  如何 把 a 作为参数传给函数呢，我们主管问 要注意堆栈问题，总之 结果不要出错， 跪求贴点代码  type func(..., int (*p)[3]) {   ... } int (*p)[3] = (int (*)[3])malloc(size); func(..., p);


Question: vs200如何获取当前选定控件的tabindex的值？

格式 ——TAB 键顺序    或CTRL + D


Question: 新手求这题算法

ans=0 for (int i=0;i<n;i++)  {     max1=0     for (int j=0;j<i;j++)     {         for (int h=j+1;j<i;j+)         {             if (max1<a[h]-a[j])                 max1=a[h]-a[j]         }     }     max2=0     for (int j=i;j<n;j++)     {         for (int h=j+1;j<i;j+)         {             if (max2<a[h]-a[j])                 max2=a[h]-a[j]         }     }     if (ans<max1+max2)         ans=max1+max2 } 用i把数据分为两段，每段用上面的算法求最大收益，复杂度O（n^3)1000个数勉强能接受

引用 12 楼 fly_dragon_fly 的回复:直接DP, d[i][j][k] 代表从i天到j天中买k次股票的最大利润 1 ) 初始 d[i][j][k]=0, d[i][i+1][1]=a[i+1]-a[i] 2) 3重循环  i<=k<j                   d[i][j][1]=max(d[i][k][1],d[k][j][1])                   d[i][j][2]=max(d[i][k][2],d[k][j][2],d[i][k][1]+d[k][j][1])  答案为d[0][n-1][2] 智商有限，听不懂a<(*￣▽￣*)/

引用 9 楼 liehu232的回复:[quote=引用 8 楼 o_ollll的回复:][quote=引用 6 楼 liehu232 的回复:] [quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿[/quote] 题目直只说一天可以买一次，没说不可以同一天卖明显我的算法收益高。如果考虑不能同一天卖出，就要两次循环，第二次循环排除第一次的买卖点，就是你的结果了[/quote] 没看清题目，同时只能持有一支股票，那我的算法就不对了

引用 8 楼 o_ollll的回复:[quote=引用 6 楼 liehu232 的回复:] [quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿[/quote] 题目直只说一天可以买一次，没说不可以同一天卖明显我的算法收益高。如果考虑不能同一天卖出，就要两次循环，第二次循环排除第一次的买卖点，就是你的结果了

引用 6 楼 liehu232 的回复:[quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿

的确，想的简单了，不过这不失为一种优化方案，把无用数据去除了， 再用那些O(n^2)的算法也可以降低处理时间.

引用 3 楼 liehu232的回复:for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益

引用 4 楼 user-3 的回复:[quote=引用 2 楼 o_ollll 的回复:] 还是不懂。。。┑(￣Д ￣)┍  比如10    1 10 2 10 1 10 1 20 0 10  怎么弄啊。。  极小数就是比前后两个数都小，极大数就是比前后都大。  10    1 10 2 10 1 10 1 20 0 10  中  1 是极小数，10是极大数，2是极小数，10是极大数，1是极小数，20是极大数。。。。。 居然没有中间数，太特殊了。 这样第一组是10-1 = 9.，第二组，10-2=8，第三组19，第四组10，最高两组是19和10. 也就是选择1买进，20卖出，0买进(0的话怎么买┑(￣Д ￣)┍). 10卖出，获利29[/quote]  那么再来一个例子 10          10 12 11 13 12 14 13 20 1 10          这么明显最大是20-10+10-1，你那个是不是弄错了

引用 2 楼 o_ollll 的回复:还是不懂。。。┑(￣Д ￣)┍  比如10    1 10 2 10 1 10 1 20 0 10  怎么弄啊。。  极小数就是比前后两个数都小，极大数就是比前后都大。  10    1 10 2 10 1 10 1 20 0 10  中  1 是极小数，10是极大数，2是极小数，10是极大数，1是极小数，20是极大数。。。。。 居然没有中间数，太特殊了。 这样第一组是10-1 = 9.，第二组，10-2=8，第三组19，第四组10，最高两组是19和10. 也就是选择1买进，20卖出，0买进(0的话怎么买┑(￣Д ￣)┍). 10卖出，获利29

可以抽像化，把这些点连起来看作曲线， 这道题变成在函数图像中，选取(最多)两段使其相加高度最高，可以想象:    选取点以极小值点做为起点，极大值点做为终点，一次遍历就能把极大极 小值选出来，第二次遍历选最高的两段。这两次遍历应该可以合并， 时间复杂度O(n), 1000ms都太多了.


Question: C语言 蛇形填数 求解释

仅供参考：#include <stdio.h> #define MAXN 100 int m[MAXN+2][MAXN+2]; char d; int x,y,k,n,w; char str[10]; void main() {     while (1) {         printf("Input n(1..%d):",MAXN);         fflush(stdout);         rewind(stdin);         if (1==scanf("%d",&n)) {             if (1<=n && n<=MAXN) break;         }     }     y=0  ;for (x=0;x<=n+1;x++) m[y][x]=1;     y=n+1;for (x=0;x<=n+1;x++) m[y][x]=1;     x=0  ;for (y=0;y<=n+1;y++) m[y][x]=1;     x=n+1;for (y=0;y<=n+1;y++) m[y][x]=1;     for (y=1;y<=n;y++) {         for (x=1;x<=n;x++) {             m[y][x]=0;         }     }     x=1;     y=1;     k=0;     d='D';     while (1) {         k++;         if (k>n*n) break;         m[y][x]=k;         switch (d) {             case 'D':                 if (0==m[y+1][x])  y++;                 else              {x++;d='R';}             break;             case 'R':                 if (0==m[y][x+1])  x++;                 else              {y--;d='U';}             break;             case 'U':                 if (0==m[y-1][x])  y--;                 else              {x--;d='L';}             break;             case 'L':                 if (0==m[y][x-1])  x--;                 else              {y++;d='D';}             break;         }     }     w=sprintf(str,"%d",n*n);     for (y=1;y<=n;y++) {         for (x=1;x<=n;x++) {             printf(" %0*d",w,m[y][x]);         }         printf("\n");     } }

首先当n = 4的时候a[0][2]不等于4 等于8  其次这个程序的填充顺序也不是你理解的那样，他是从右上角开始按照顺时针旋转填充的

想不清楚就单步运行调试程序，一步步看各变量怎么变化


Question: c/c++ fread 问题

if((fp= fopen("./stud.lv","rb")) == NULL)//打开操作不成功 {     printf("The file can not be opened.\n")；    　     exit(1);//结束程序的执行 } 楼主应该先判断一下文件操作符是否已经打开吧。 还有就是如果Windows下，还需要确认stud.lv是不是与执行文件在一个目录下。

检查fopen有没执行成功

fopen打开的文件不存在

引用 5 楼 u010165006 的回复:./stud.lv这个文件名中, .表示的是当前目录, /是目录分隔符，./stud.lv表示当前目录下的stud.lv文件，一般在Linux下才需要这样表示，Windows下面直接文件名就是当前目录下，当前目录就是可执行文件所在的目录。 程序中也可以用函数更改当前目录。

Linux执行命令是按照PATH查找的（这样比较安全，避免当前目录下的同名程序先被执行），所以当前目录下的程序要用./表示。

stream != NULL，错误原因写得清清楚楚

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


Question: 编译出错解决

NULL为指针类型的0，我理解为不指向任何地址。 在定义指针时可以用NULL初始化，NULL在不止一个头文件中有定义，包括stdio.h

addparval  = "";或者addparval  = NULL;

addparval  = NULL;

空字符应该不能这么赋值  试试 *addparval = NVL 试试  PS:忘了 是NUL还是NVL了 。。。。

*addparval  = "", 定位这行出错。


Question: C语言文件存储，程序没错，但是存储后打开文件，年龄和学号是乱码，求大神解决

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

能贴个错误出来看么？

load函数中：printf("输入要写入的文件路径：\n"); 改成 printf("输入要读取的文件路径：\n");

fwrite是以二进制形式写入,楼主可以试试fprintf

就是乱码，我记得除了好像中文会变成乱码，但是计算机进行读取的时候是可以转换回来的。没事的

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: 为什么for循环只进行了一次

是不是=<?for循环的判断条件有错

因为你的l在执行一遍for(;l<5;++l)后没有重置，你在for(;l<5;++l)上一行加上l=0即可


Question: 怎么从网站上抓数据?

引用 15 楼 lgbxyz 的回复:百度是HTTPS协议，需要先进行SSL认证，然后才能通信，这需要使用OpenSSL，认证后使用SSL_read/SSL_write 和server通信 学习了。

https://www.openssl.org/docs/man1.0.2/ssl/  <<Network Security with OpenSSL >>

引用 15 楼 lgbxyz 的回复:百度是HTTPS协议，需要先进行SSL认证，然后才能通信，这需要使用OpenSSL，认证后使用SSL_read/SSL_write 和server通信 该看什么资料?

引用 13 楼 zhao4zhong1 的回复:《http权威指南》 这书讲什么东西的?

换语言，c语言的岗位少的可怜，掌握多门语言是必须的，如脚本语言python。  python的岗位都你c多。

《http权威指南》

引用 8 楼 Evankaka 的回复:[quote=引用 7 楼 csdnxinshou2 的回复:] [quote=引用 6 楼 Evankaka 的回复:] http://blog.csdn.net/evankaka/article/details/46849095 可以看看这里，其实很简单 python介绍本书我python不会。[/quote] python是比较简单的一个语言，网上找个电子书，或借个书来个。一天之内你就可以简单入门了[/quote] 有哪些语言是应该掌握的能不能说下?目前只会C语言和16位汇编语言。谢谢。

引用 7 楼 csdnxinshou2 的回复:[quote=引用 6 楼 Evankaka 的回复:] http://blog.csdn.net/evankaka/article/details/46849095 可以看看这里，其实很简单 python介绍本书我python不会。[/quote] python是比较简单的一个语言，网上找个电子书，或借个书来个。一天之内你就可以简单入门了

引用 6 楼 Evankaka 的回复:http://blog.csdn.net/evankaka/article/details/46849095 可以看看这里，其实很简单 python介绍本书我python不会。

引用 9 楼 csdnxinshou2 的回复:[quote=引用 8 楼 Evankaka 的回复:] [quote=引用 7 楼 csdnxinshou2 的回复:] [quote=引用 6 楼 Evankaka 的回复:] http://blog.csdn.net/evankaka/article/details/46849095 可以看看这里，其实很简单 python介绍本书我python不会。[/quote] python是比较简单的一个语言，网上找个电子书，或借个书来个。一天之内你就可以简单入门了[/quote] 有哪些语言是应该掌握的能不能说下?目前只会C语言和16位汇编语言。谢谢。[/quote] 只会C的话，找工作太受限制了，建议至少也要会C++或JAVA。其它语言如python或javaScrip等t看个人兴趣也可以看下

这东西，你都链接上了，发送要求数据都不知道什么发吗？python标准库有urllib可以获取数据，看你干嘛的了，只是获取数据的话python是方便，如果写什么软件的话另外说了

换个语言，如python， 有现成的接口， python都包含了构造了http头了  只要管recv了。，  收到后，写到一个文件，就可以看到数据了。  但是其本质还是 python帮你构造了http头。  也就说，你也可以用telnet去查看，只不过没有python ,wireshark等爽。

要发送http请求 不发请求，怎么会有数据呢

先学会使用抓包软件比如wireshark

你要通过socket获取网页上的数据，需要模拟http报文向百度发送，先看看怎么模拟http报文吧。直接recv肯定是不行的。

先把你要用的函数把MSDN上的解释读一遍，先明白这个函数是要做什么


Question: 求教,处理文件遇到的问题

strncat 第一个参数需要的是char*， 而不是char，先把这个函数怎么用理解清楚


Question: C语言中memcmp函数可以用来比较两个浮点数大小吗？

memcmp没有整数,浮点数的概念, 只关心字节, 你看一下这个浮点数在内存中的表示

浮点数格式 http://bbs.csdn.net/topics/390676437

有什么问题？？你希望得到什么结果  memcmp返回传值又不是bool，相等返回的是0   要深入了解先把这个函数的功能了解清楚：http://en.cppreference.com/w/c/string/byte/memcmp

解决这个问题需要了解两个方面的知识 1、memcmp函数的意义 2、double数据类型在内存中的表示  ------------- 1、memcmp函数的意义 比较前n个字节的大小。  ------------- 2、double数据类型在内存中的表示 为了更好地理解，下面把double类型的 1.0 和 2.0 在内存中的表示以十六进制的形式列出来 1.0 ==  00-00-00-00-00-00-F0-3F 2.0 ==  00-00-00-00-00-00-00-40  从上面的内存表示可以很容易知道为什么1.0和2.0用memcmp函数比较之后反而是1.0大了。 那么接下来的问题就是1.0和2.0为什么在内存中就是那么表示的。  （1）先将1.0和2.0分别用二进制的科学计数法表示 1.0   ==  1.0乘以（2的0次方） 2.0   ==  1.0乘以（2的1次方）  * 规定 double 在内存中以三个部分存储：符号、阶码、尾数 * 符号占1位、阶码占11位、尾数点52位 * 由于尾数的小数点之前都是数字1，所以规定小数点之前的数字1不必存储，也就是说尾数只需要存储小数点之后的数值即可 * 正数的符号为0  负数的符号为1 * 规定阶码存储时需要加上1023 所以，1.0的阶码0，加上1023之后是1023，二进制表示为  0111 1111 111       2.0的阶码1，加上1023之后是1024，二进制表示为  1000 0000 000  由于 1.0 和 2.0 的符号位、尾数都是0 所以， 1.0 ==  0（符号位） 0111 1111 111（十一位阶码） （此处省略五十二位尾数0）        2.0 ==  0（符号位） 1000 0000 000（十一位阶码） （此处省略五十二位尾数0） 	    写成十六进制的形式为  1.0 == 3F-F0-00-00-00-00-00-00                       2.0 == 40-00-00-00-00-00-00-00  最后，由于一般计算机中内存以小端存储，也就是数值的高字节反而是放在后面的。 所以在内存中的表示为  1.0 == 00-00-00-00-00-00-F0-3F                       2.0 == 00-00-00-00-00-00-00-40


Question: debian7.0 安装的时候出现这个问题如何jiejue

apt-cache search gdb 看下有没有gdb这个包


Question: 求如何用四重循环实现下面 数学表达，百度主管说做对试用期可以过，跪求了！

这是几个不相干的公式，互相没关系 第一个级数 第二个积分 第三个求和 积分可以设法求出原函数，或者转换为定积分，然后可以用数值解法求函数积分、 求和直接求


Question: 新手学C语言，用Dev C++编译出现问题，大神请帮忙看一下

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


Question: Ubuntu 14.04下eclipse调试c程序出现错误

说是不能找到源文件printf. c

引用 1楼user-2 的回复:#include <stdio.h> 了吗？当然。。

#include <stdio.h> 了吗？


Question: Symbol 不懂什么意思

看书吧，书里应该有介绍

右键没找到的

点击右键——转到定义


Question: C语言出现烫烫烫，是指针用错了吧，求老鸟解决~~~~

多谢版主

因为\0是不可显示的字符  for (b = 0; b < SIZE - 1; b++)

多谢大神，但是#define SIZE 7 之后输出是这样： zz[0]=1 zz[1]=2 zz[2]=3 zz[3]=4 zz[4]=5 zz[5]=6 *zz=1 abcdefa     //这里多个a是怎么回事 a b c bcdefg abcdef

#define SIZE 7


Question: 最近想用c做一个简单的酒店信息处理程序，费劲周折，但是达不到预期效果，求大神指教

因为不满足if (flag == 1) ，已经叫你单步调试来看了，我都不知道你预期的效果需要是什么

引用 3 楼 user-1的回复:你自己调试着看哪里和你期望的不一样，我都不知你想得到什么，怎么输入，没具体研究你代码 那个不好意思，我不理解的地方是为什么你说的for循环后面的就无法用上了，因为我不知道怎么改才能使后面的程序实现，是不是我的函数问题

引用 1 楼 user-1的回复:你insert中for循环和后面if语句都没执行到，自己单步调试程序，每一步观察各变量变化  保存就是读写文件操作 请教下该如何修改呢


Question: C语言 位域计算

unsigned int 是4字节，如果你写成char才是1字节  如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止；  你后面有个unsigned int  :0; 也就是4字节中后面部分都不使用了  另外这方面网上也有一些讲解的，可以去网上搜索  结构体 位域

引用 1 楼 user-1 的回复:这里占用4个字节 unsigned int a:4;  unsigned int  :0;   \\（空域，就也是说后面不用了）  这里又占用4个字节：       unsigned int b:4;        unsigned int c:4;        unsigned int d:5;        unsigned int  :0;   这里又是4个字节： unsigned int e:4;    一共12个  unsigned int  :0;   \\（空域，就也是说后面不用了）   是说这int类型的4个字节后面的不用了吗    不是该字节（第一个字节内）后面的不要吗  下面五点我就是看不太理解：位宽之和小于类型的sizeof大小   sizeof大小：是指8个位还是指类型的字节总数  帮解答下 谢谢 新年快乐

1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止； 2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍； 3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式，Dev-C++采取压缩方式； 4) 如果位域字段之间穿插着非位域字段，则不进行压缩； 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。


Question: 一个C语言打印三角形的问题！

楼主应该是这里没有控制好，输入完t之后，再输入n时，scanf将回车当做输入赋值给了n。因此每次循环都运行一次之后才是实际输入n值。 楼主可将scanf("%c",&n);改为scanf("\n%c",&n);或者每次打印之后再进行判断是否t--；

我在学习C++ primer plus这本书，课后习题有一个就是这样。我编的代码有点繁琐，你可以参考一下。   #include <stdio.h>  char lets [26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int FindNumber(char);  int main (void) { 	int ROW, rows, chars, space, up, down; 	char letter, ch;  	while(1) 	{ 		printf ("\n\n请您输入一个大写字母，以便为您建造一个漂亮的字母金字塔^_^\n"); 	    letter = getchar(); 		if (letter >= 'A' && letter <= 'Z') 		{ 			printf ("\n\n\n"); 			ROW = FindNumber(letter); 			 			for (ch = 'A', rows = 1; rows <= ROW; rows++) 			{ 				for (space = 1; space <= ROW - rows; space++) 					printf (" "); 				printf ("%c", ch); 				for (up = 0; up < rows - 1; up++)                                   			 					printf ("%c", ++ch); 				for (down = 0; down < rows - 1; down++) 					printf ("%c", --ch); 				printf ("\n"); 			}     	} 		else 		{ 		 			printf ("童鞋，你输入的怎么不是大写字母呀！请按任意键退出程序。。。。。。。。。。。。。。。。");  			break; 		} 		getchar();  	} 	 	return 0; }  int FindNumber(char ch)			// 此函数实现的功能是在用户输入一个大写字母后，能找出它是26个字母中的第几个字母 { 	int index; 	 	for (index = 0; index < 26; index++) 	{ 		if (ch == lets [index]) 			break; 	} 	return index+1; }

int main() {     int t,i,j,m;     char ch,n;     scanf("%d",&t); 	getchar();     while(t--)     {         scanf("%c",&n); 	getchar();         if(n>='A'&&n<='Z')   加上两个getcgar（）；  我试了可以 你可以试一下         .........................

请问下楼主，有这种需求吗？

引用 1 楼 user-5的回复:打印什么式样的三角形？ 直角  锐角？   A AA AAA 还是     A    AA   AAA  AAAA AAAAA 输入字母或者数字，如输入C，就打印第一行A，第二行ABA，第三行ABCBA的等腰三角形，这个我已经写好了，问题是while（t--），t输入一个数字，控制测试数据有几组，但是总是不能达到t组数据


Question: 对10个数排序的问题

常见的排序方法总结： http://blog.csdn.net/zhangxiangdavaid/article/details/25082013

for(i=0;i<9;i++)     for(j=i+1;j<10;j++) {if(a[j]<a[i]) a[i]=t;a[i]=a[j];a[j]=t; 主要还是交换有问题。还有编程语言不是按行来分割的，是按分号进行判断这一行是否结束。判断这里需要加大括号 if(a[j] < a[i])  {                 t = a[i];                 a[i] = a[j];                 a[j] = t; }

#include<stdio.h> int main(){ 	int j,b,c,d,i,a[10]; 	for(j=0;j<10;j++) 	scanf("%d",&a[j]); 	for(b=0;b<9;b++) 	   for(c=0;c<9;c++){    		if(a[c]>a[c+1]){ 		   	d=a[c]; 			   a[c]=a[c+1]; 			      a[c+1]=d; 		   }    	} 	for(i=0;i<10;i++) 	printf("%d ",a[i]); 	return 0;	 }   你的错误根本在那个判断句，“if(a[j]<a[i])”在第二个for语句中，i的值始终是0；

您好！我稍微改了一下你的代码：  请别忘记给点分，谢谢哈

if(a[j]<a[i]) { t=a[i];a[i]=a[j];a[j]=t;}     } //并且加花括号对

吧a[i]=t换成了t=a[i] 结果还是不对

#include<stdio.h> int main() {     int i,j,t,a[10];     for(i=0;i<10;i++)     {         scanf("%d",&a[i]);     }     for(i=0;i<10;i++)         for(j=0;j<10;j++)         if(a[i]<a[j])     {         t=a[i];         a[i]=a[j];         a[j]=t;     }     for(i=0;i<10;i++)         printf("%5d",a[i]);     return 0; }  比较大小的时候循环有问题你自己看看= =

for(i=0;i<9;i++)//改成(i=0;i<10;i++)     for(j=i+1;j<10;j++)//改成(j=0;j<i-1;j++) {if(a[j]<a[i]) a[i]=t;a[i]=a[j];a[j]=t;     }  为什么这么改自己好好自习想想


Question: 使用数组，指针，函数，还冒泡排序的方式，使输入3个数字按照从大到小排序出来，输入数字后无反应。

数据结构与算法之排序 http://blog.csdn.net/zhangxiangdavaid/article/details/25082013

感谢各位的帮助，非常谢谢，不好意思，这两天新年很忙没时间来看，非常谢谢

#include <stdio.h> int main(int argc, char const *argv[]) {     int a[3],*b[3],i;     void compare(int *b1[],int a1[]);     printf("please enter 3 number:");     for (i = 0; i < 3; i++) {         scanf("%d",&a[i]);  //修改处 输入时如：1 2 3 回车 数间加空格。     }           for (i = 0; i < 3; i++) {         b[i]=&a[i];     }           compare(b,a);          for (i = 0; i < 3; i++) {         printf("%d\n",a[i]);     }     return 0; }   void compare(int *b1[],int a1[]) {     int i,j,t;     for (i = 3; i > 0; i--) {  //修改处          for (j = 0; j < i-1; j++) {             if(a1[j]<a1[j+1]){                 t=*b1[j];   //修改处                  *b1[j]=*b1[j+1];  //修改处                  *b1[j+1]=t;  //修改处              }         }     } }

用空白符结尾时，scanf会跳过空白符去读下一个字符，所以你必须再输入一个数 空白符包括空格，制表符，换行符，回车符和换页符

scanf("%d\n",&a[i]); 改成 scanf("%d",&a[i]);


Question: 用rand得到一个随机数作为创建文件的文件名应该怎么写

sprintf格式化n成字符串，然后fopen建立文件就可以了

没人啊没人啊

利用系统提供的tmp比较好 另外，随机数是有重复的

先用srand初始种子


引用 4 楼 user-1 的回复:只要输入n大于2，你代码貌似是对的  最后prinf中也用 %.2lf 看下 今天原来的代码也能a了，找照你的改也能a，可能那天杭电oj有问题

只要输入n大于2，你代码貌似是对的  最后prinf中也用 %.2lf 看下

引用 1 楼 user-1 的回复:写得有点冗余，不过貌似没什么问题 我 想 知 道 哪 里 有 问 题 ，试了一下，输   出 也 是 对 的

引用 1 楼 user-1 的回复:写得有点冗余，不过貌似没什么问题 a不了 直接max=0； min = 100；可以a

写得有点冗余，不过貌似没什么问题


计算错误，41<=  n^2+n+41<= 2591 考虑对称性，(-x)^2 -x +41 = (x+1)^2+(x+1)+41 这个其实只要检测一半区域就够了

引用 10 楼 lm_whales 的回复:-39<= n<=50,41 =<  n^2+n+41 <= 3041 这个范围的素数很少，筛法的话，非常快 应该不需要查表才对，当然就是直接判断，也没问题才对，不会很慢的  f(n+1) -f(n) = 2(n+1) 这是个二阶等差数列，循环的话，也很快 但是除了打表其他方法都不能ac

引用 4 楼 user-2 的回复:c 的初始值是否应该是false，否则c一直为true 我那个Java的太阳系模型的问题能帮我看看嘛，谢谢了

引用 4 楼 user-2 的回复:c 的初始值是否应该是false，否则c一直为true 还是一样

引用 7 楼 user-2 的回复:你试下这种，我没调试     #include<stdio.h> #include<math.h> int main() { 	int a, b, i, t, j, x; 	bool c = true; 	while (scanf("%d%d", &a, &b) != EOF) 	{ 		if (a == 0 && b == 0) 			break; 		if (a > b) 		{ 			t = a; 			a = b; 			b = t; 		}  		for (i = a; i <= b; i++) 		{ 			x = i * i + i + 41; 			for (j = 2; j <= int(sqrt(x)); j++) 			{ 				if (x % j == 0) 				{ 					c = false; 					printf("Sorry\n"); 					break; 				} 			} 		} 		if (c == true) 			printf("OK\n"); 	} 	return 0; } #include<stdio.h>   #include<string.h>       int main(void)   {       int m, n;       int x[] =        {           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1       };           while (scanf("%d%d", &m, &n), m || n)       {           for (m += 39, n += 39; x[m] && m <= n ; m++);               puts(m > n ? "OK" : "Sorry");       }               return 0;   }    网上的只有这种打表的能a，我也不知道为什么

c 的初始值是否应该是false，否则c一直为true

引用 1 楼 user-2 的回复:for(j = 2;j <= int(sqrt(i));j++) 应该是 for(j = 2;j <= int(sqrt(x));j++) 吧 #include<stdio.h> #include<math.h> int main() { 	int a,b,i,t,j,x; 	bool c = true; 	while(scanf("%d%d",&a,&b) != EOF) 	{ 		if(a == 0 && b == 0) 			break; 		if(a > b) 		{ 			t = a; 			a = b; 			b = t; 		} 		 		for(i = a;i <= b;i++) 		{ 			x = i * i + i + 41; 			for(j = 2;j <= int（sqrt(x)）;j++) 			{ 				if(x % j != 0) 					c = true; 				else 				{ 					printf("Sorry\n"); 					break; 				} 			} 		} 		if(c == true) 		printf("OK\n"); 	} 	return 0; }

引用 1 楼 user-2 的回复:for(j = 2;j <= int(sqrt(i));j++) 应该是 for(j = 2;j <= int(sqrt(x));j++) 吧a不了


Question: 测试GTK+安装的小程序出错，寻求帮助！

http://www.oschina.net/question/100374_57793 这里有说明的，-c是编译，还没链接成可执行文件呢，还有学业学gtk3吧，虽说不等gimp移植到gtk3，gtk2是不会死的


Question: 关于数组越界后还能成功赋值的问题

谢邀，  看了下你写的代码，ans[y]，这种形式是在运行时赋值，编译器是无法提前知道你运行时y的赋值情况，因此编译器是不会检查y是否大于100005的。  另外，数组的访问也可以写为指针形式的访问，如ans[y] ===> *(ans+y), 因此ans+y的地址如果在内存中存在，C语言即可访问，这是C的牛B之处，也是C麻烦之难。

引用 3 楼 xvcksai 的回复:[quote=引用 2 楼 paschen 的回复:] 越界不是编译错误，但是会读写不属于你内存的东西，这可能造成程序运行时崩溃，没出错最多能说明运气好  越界赋值从本质上来讲是不对的？成功赋值只是看概率？ 请问是这个意思吗？[/quote]  这是一种不确定行为，这不是产生编译错误，而是产生运行错误，如果你数组后还有其他重要的数据，赋值就会把他们覆盖了，严重的话会使程序崩溃，并不是成功只是看概率，是没失败不代表正确！

这不是明摆着不可以的吗？

引用 1 楼 ynsenyu 的回复:越界的内存没有分配就可以啊，人家可不管这个越界检查的  那是对还是错的？。。我下次可以这么做吗?

引用 2 楼 paschen 的回复:越界不是编译错误，但是会读写不属于你内存的东西，这可能造成程序运行时崩溃，没出错最多能说明运气好  越界赋值从本质上来讲是不对的？成功赋值只是看概率？ 请问是这个意思吗？

越界的内存没有分配就可以啊，人家可不管这个越界检查的

应用程序的所有内存，都是可用（读写）的 只是只读内存,写入会出错，或者没有作用 其他内存可能不再应用程序可用范围，会发生莫名其妙的错误 但是这些跟编译器确实没啥关系 有关系的是程序员，你不能写这种容易出错，没有保障的程序。 这是你自己的错误，编译器没有义务处理这种逻辑错误。 C的原则是信任程序员，你做的任何事情都是允许的，只要不是语法错误。 你要保证，你的程序是正确的 C++虽然没有完全继承这个逻辑，但是还是继承了相当一部分的。

指针越界 和 犯法一样 一次没被抓住，不等于合法


Question: 一个小的问题，但我怎么也想不明白

Status AddSMatrix(TSMatrix M,TSMatrix T,TSMatrix *P) {    int col,pa,pb,pc;    P->mu=M.mu;    P->nu=M.nu;    pa=0,pb=0,pc=0;    for(col=1;col<=M.mu;col++)    {     while(M.data[pa].i==col&&M.data[pb].i==col)  //打错了，改为M.data[pa].i==col&&T.data[pb].i==col  { if(M.data[pa].j==T.data[pb].j) {    P->data[pc].i=T.data[pb].i;    P->data[pc].j=T.data[pb].j;    P->data[pc].e=M.data[pa].e+T.data[pb].e;    pa++;    pb++;    pc++;  } if(M.data[pa].j>T.data[pb].j) {    P->data[pc].i=M.data[pa].i;    P->data[pc].j=T.data[pb].j;    P->data[pc].e=M.data[pa].e+T.data[pb].e;    pb++,pc++; } if(M.data[pa].j<T.data[pb].j) {    P->data[pc].i=M.data[pa].i;    P->data[pc].j=M.data[pa].j;    P->data[pc].e=M.data[pa].e+T.data[pb].e;    pa++,pc++; } printf("pa=%d,pb=%d\n",pa,pb); printf("P->tu=%d\n",pc);  }      }    P->tu=pc;    printf("P->tu=%d",pc);    return OK; } 具体可参考稀疏矩阵加法_百度的  int AddMtrix(struct TSMtrix A,struct TSMtrix B,struct TSMtrix *C)  函数。

给个建议，如果想不明白不要空想，单步运行调试程序，每一步观察各个变量如何变化，然后就会找到原因

#include<stdio.h> #include<stdlib.h> #define MAXSIZE 1250 #define OK 1 #define ERROR -1 typedef int ElemType; typedef int Status; typedef struct {    int i,j;    ElemType e; }Triple; typedef struct {    Triple data[MAXSIZE+1];    int mu,nu,tu; }TSMatrix; Status InitMatrix(TSMatrix *M) {    int k;    printf("Input mu,nu,tu\n");    scanf("%d,%d,%d",&(M->mu),&(M->nu),&(M->tu));    if(M->mu<=0||M->nu<=0)printf("ERROR");    else    { 	  printf("Please input the elem\n"); 	  for(k=0;k<M->tu;k++) 	  { 		 printf("The row\n"); 		 scanf("%d",&(M->data[k].i)); 		 printf("The col\n"); 		 scanf("%d",&(M->data[k].j)); 		 printf("The value\n"); 		 scanf("%d",&(M->data[k].e)); 	  }    }    return OK; }  Status PrintMatrix(TSMatrix *M) {    int k,j;    for(k=0;k<M->tu;k++)    { 	  printf("(%d,%d,%d)\n",M->data[k].i,M->data[k].j,M->data[k].e);    }    return OK; } Status AddSMatrix(TSMatrix M,TSMatrix T,TSMatrix *P) {    int col,pa,pb,pc;    P->mu=M.mu;    P->nu=M.nu;    pa=0,pb=0,pc=0;    for(col=1;col<=M.mu;col++)    { 	  	 while(M.data[pa].i==col&&M.data[pb].i==col) 		 { 			if(M.data[pa].j==T.data[pb].j) 			{ 			   P->data[pc].i=T.data[pb].i; 			   P->data[pc].j=T.data[pb].j; 			   P->data[pc].e=M.data[pa].e+T.data[pb].e; 			   pa++; 			   pb++; 			   pc++;  			} 			if(M.data[pa].j>T.data[pb].j) 			{ 			   P->data[pc].i=M.data[pa].i; 			   P->data[pc].j=T.data[pb].j; 			   P->data[pc].e=M.data[pa].e+T.data[pb].e; 			   pb++,pc++; 			} 			if(M.data[pa].j<T.data[pb].j) 			{ 			   P->data[pc].i=M.data[pa].i; 			   P->data[pc].j=M.data[pa].j; 			   P->data[pc].e=M.data[pa].e+T.data[pb].e; 			   pa++,pc++; 			} 			printf("pa=%d,pb=%d\n",pa,pb); 			printf("P->tu=%d\n",pc); 		 } 	     }    P->tu=pc;    printf("P->tu=%d",pc);    return OK; }  int main(void) {   TSMatrix M,T,P;   clrscr();   InitMatrix(&M);   InitMatrix(&T);   AddSMatrix(M,T,&P);   printf("The result is");   PrintMatrix(&P);   return 0; }

求完整代码。


Question: 请各位大神帮忙看一下一个小程序，如何提高运算效率，必有重谢！！！

for(k=0;k<15000;k++)//这地方是否有错误？         {             /****/             for(i=0;i<=n-1;i++)             {                 for(j=0;j<=n-1;j++)                 {                     for(k=0;k<8;k++) 改成  for(k1=0;k1<15000;k1++)//这地方是否有错误？         {             /****/             for(i=0;i<=n-1;i++)             {                 for(j=0;j<=n-1;j++)                 {                     for(k=0;k<8;k++) 只要6~7秒就可以了,应该可以更快

感觉你这个从头设计比修改要好

首先从宏观上优化，能用更好的算法就用更好的 然后再从细部优化，你看下你程序是否方便用并行运算，这样可以提高效率 优化了这些还是觉得慢，可以用profier测试一下，看是哪一部分是瓶颈，然后再对这一部分想办法

if(k==0) esum2 = 0.5*s[i][j][0]*s[(i+1)&7][j][5]/t;                         if(k==1) esum2 = 0.5*s[i][j][1]*s[(i+1)&7][j][4]/t;                         if(k==2) esum2 = 0.5*s[i][j][2]*s[i][(j+1)&7][7]/t;                         if(k==3) esum2 = 0.5*s[i][j][3]*s[i][(j+1)&7][6]/t;                         if(k==4) esum2 = 0.5*s[i][j][4]*s[(i-1)&7][j][1]/t;                         if(k==5) esum2 = 0.5*s[i][j][5]*s[(i-1)&7][j][0]/t;                         if(k==6) esum2 = 0.5*s[i][j][6]*s[i][(j-1)&7][3]/t;                         if(k==7) esum2 = 0.5*s[i][j][7]*s[i][(j-1)&7][2]/t; 这个可以改成一次比较


Question: 关于函数指针返回值为字符数组时的问题。

类似于值传递和地址传递的意思吧？我明白了。

不要返回指向局部变量的指针，第一种情况你数组是个局部变量，是在栈上分配的，函数执行完就销毁了；第二种情况，你的指针是指向常量区的字符串，并不是局部变量，所以没有问题

楼上正解。如果楼主了解 堆和栈的区别，这个现象就很好理解了。

补充一下一楼，hello world存储在文字常量区而pcstr指针直接指向该区地址，返回可以打印成功，而acstr[]数组在函数栈内自行开辟一块内存空间并将hello world从文字常量区拷贝出来复制到该栈内，而acstr直接指向该栈地址，当函数调用结束后该栈被销毁所以返回后无法打印

需要理解两点： 1.  char acStr[]="hello world"; 等同于 char acStr[12]="hello world"; 这种类型的字符串在栈区  2. 栈区与全局区的区别


Question: C语言，有个小小对计算机执行程序的基础问题。

引用 4 楼 qq_33447655 的回复:[quote=引用 3 楼 u010165006 的回复:] explorer.exe是Windows程序管理器或者Windows资源管理器，它用于管理Windows图形壳，包括开始菜单、任务栏、桌面和文件管理。删除该程序会导致Windows图形界面无法使用。（360百科） 不用删除，直接打开任务管理器，然后结束任务把它结束掉。电脑桌面会消失，就剩一张桌面壁纸[/quote] 是的，这个explorer.exe有时会出现需要重启的。

引用 3 楼 u010165006 的回复:explorer.exe是Windows程序管理器或者Windows资源管理器，它用于管理Windows图形壳，包括开始菜单、任务栏、桌面和文件管理。删除该程序会导致Windows图形界面无法使用。（360百科） 不用删除，直接打开任务管理器，然后结束任务把它结束掉。电脑桌面会消失，就剩一张桌面壁纸

因为以前Windows 3.1没有后来Windows 95才开始出现的【开始】菜单，没有任务栏，也没有苹果电脑MacOS那样的一个操作面板，所以操作电脑不是很方便，就出现了第三方的图形shell，那个Dashboard是类似苹果电脑的操作面板的，上面除了图标，还有菜单可以分组访问到安装的所有程序。

你说的外壳英语是shell，因为一台电脑，最里面的是硬件裸机，外面一层是操作系统内核，再外面一层是API、系统调用等，最外面一层就是外壳shell。你说的没错，外壳就是人与电脑交互的接口（界面，interface），可以是命令行接口（如DOS、Linux，Linux里面就有几种shell程序），也可以是图形用户界面接口（如Linux的XWindow（KDE、GNome都是），如Windows系统的Explorer，甚至可以用第三方的图形shell代替Windows自带的，如以前Windows 3.1下的Dashboard这样的软件）