Question: C语言二维数组，指针偏移

a原本数据类型是 int [3][2],当对a进行算数运算时，转换成指针数据类型是int （*）[2]，因此a加1，指针偏移量是2 * sizeof （int)  一般是8字节，其中2是二维数，4是int字节大小。如果看成矩阵，即第二行首址

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

a 是数组首地址 a+1是一维数组a[1]的首地址

引用 5 楼 Mutable714 的回复:请问四楼，为什么a+1会指向第二个一维数组@cysccnu  这是C编译器定好的规则，你也可以把这个3行2列的数组看成是三个字符串，每个字符串含2*4(int为4个字节)个字符，a指向第一个字符串，a+1就指向第二个字符串，实质上字符串数组也确实是这样排列的，只不过这里的元素是int，编译器按4个字节为单位来处理，而对于字符串，编译器按单个字节来处理。

引用 1 楼 lin5161678 的回复:a不是指 a[0][0] a+1 也不会是 a[1][0] a++当然不行 会有error  这点东西都是稍微看看书就能弄懂的+1

引用 5 楼 Mutable714 的回复:请问四楼，为什么a+1会指向第二个一维数组@cysccnu  c语言语法就是如此，编译器也是如此编译，就像英语的语法一样 int a[4]   是4个int类型的数组，a+1代表数组中第二个元素，即a[1]，步距为一个int类型的长度，4字节 int a[4][4]  是4个int a[4]类型的数组，a+1代表数组中第二个元素，即a[1][0]，步距为一个int a[4]类型的长度，16字节 你要知道这里面有个步距的概念（姑且这么理解吧，具体术语是啥我也不知道）  如果这么说你还无法理解，那你就想想char a[4]和int a[4]，前者步距为1字节，后者步距为4字节

int (*a)[10]; /* 二维数组相当于两个一维数组,第一个一位数组存放的是第二维每个数组的首地址！ 因此对于*a说每一个元素占用空间是对应位置第二维所有元素的占用空间之和！ 如果是int型 第二维共十个元素，则在tc中 *a每个元素占20字节 而第二维每个元素占2字节 那么a+1世界上是在原地址基础上偏移20字节 */

请问四楼，为什么a+1会指向第二个一维数组@cysccnu

数组a[3][2]在内存中其实是按三个一维数组排列的，a是数组首地址，所以a+1指向第二个一维数组，也就是a[1][0]。a是数组名，不能用来赋值，所以不能用a++，可以用a+1


Question: C语言在linux下

可以试试：strace LoanPutFile  进行追踪，例如：strace ps输出： execve("/bin/ps", ["ps"], [/* 57 vars */]) = 0 brk(0)                                  = 0x809b000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7766000 access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory) open("/usr/lib/mpi/gcc/openmpi/lib/tls/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/usr/lib/mpi/gcc/openmpi/lib/tls/i686/sse2", 0xbfd83cc0) = -1 ENOENT (No such file or directory) open("/usr/lib/mpi/gcc/openmpi/lib/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 。。。。还有很多

执行一下看看，或者就反编译喽

将某路径文件发送到另一路径？（远程传输） 看打印信息和cmd参数 猜测的

楼上两位的反编译恐怕做不到，最多也就是反汇编。用man LoanPutFile看这个命令有没有说明。

反编译？  拍照-显示-截图 lz顺便再打个码吧


Question: expected specifier-qualifier-list before 'gts_char_t'

没错误  我在vs2010上运行了下  无错

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

gts_char_t 在哪里出现的？


Question: 一到数据结构的题，不允许使用比较，删除重复元素

引用 9 楼 zhao4zhong1 的回复:谁说实数无法异或来着？ #include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2   赵老师厉害，我刚学的异或老师说不能对实数比较，看来还是要自己操作下才知道，马克了

引用 8 楼 zxh707wk 的回复:http://bbs.sjtu.edu.cn/bbstcon?board=C&reid=1394963935  原来过一遍hash不算比较，这题太坑了

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

引用 6 楼 zxh707wk 的回复:[quote=引用 4 楼 Philipyexushen 的回复:] [quote=引用 2 楼 zxh707wk 的回复:] 数组存值？   能否具体点?不是很懂[/quote]实数不行，用链表试试？[/quote]  引用 6 楼 zxh707wk 的回复:[quote=引用 4 楼 Philipyexushen 的回复:] [quote=引用 2 楼 zxh707wk 的回复:] 数组存值？   能否具体点?不是很懂[/quote]实数不行，用链表试试？[/quote]  可是还是存在比较吧

引用 4 楼 Philipyexushen 的回复:[quote=引用 2 楼 zxh707wk 的回复:] 数组存值？   能否具体点?不是很懂[/quote]实数不行，用链表试试？

类型为实数，显然浮点数没办法使用位运算来判断的

引用 2 楼 zxh707wk 的回复:数组存值？   能否具体点?不是很懂

引用 1 楼 u014609356 的回复:使用位运算异或  我也想过这个。。。可是这个算不算比较啊

数组存值？

使用位运算异或


Question: 问个问题 比较急

http://blog.csdn.net/fangxiao_jun/article/details/5804668  你要的例子, 新建2个console工程, 代码粘贴进去, 2个工程的return 0;前面加上system("pause");  server和client互相发送了一个字符串.  注意: 显示"this is server"的是client 而显示this is client的是server

引用 15 楼 zhao4zhong1 的回复:楼主如果觉得9楼的例子代码还不够简单的话，建议趁早改行。 行数 | 文件  589 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C  325 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C  137 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H   74 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C  恩 我根本不懂你给我的是什么！ 我接触的挺少的，也没打算从事c的工作，基础就是大学里学的c还有数据结构。问这个真的是出于个人兴趣，想知道到底怎么实现的，以我的水平，可能看起来有些吃力！我就是想要个最最简单的实例！然后自己在它基础上研究一下！    可以给我一个简单的实例么？ 比如就两个程序，a程序负责数据，b程序负责操作。 我通过b程序输入一个数，然后调用a把数保存在文件里！ 有点表述不清楚，但就是像数据库的服务程序一样！ a是一直在运行的，b执行的时候可以直接就用a！  先感谢！

引用 16 楼 jiangbai333 的回复:[quote=引用 15 楼 zhao4zhong1 的回复:] 楼主如果觉得9楼的例子代码还不够简单的话，建议趁早改行。 行数 | 文件  589 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C  325 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C  137 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H   74 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C  恩 我根本不懂你给我的是什么！ 我接触的挺少的，也没打算从事c的工作，基础就是大学里学的c还有数据结构。问这个真的是出于个人兴趣，想知道到底怎么实现的，以我的水平，可能看起来有些吃力！我就是想要个最最简单的实例！然后自己在它基础上研究一下！    可以给我一个简单的实例么？ 比如就两个程序，a程序负责数据，b程序负责操作。 我通过b程序输入一个数，然后调用a把数保存在文件里！ 有点表述不清楚，但就是像数据库的服务程序一样！ a是一直在运行的，b执行的时候可以直接就用a！  先感谢！ [/quote]  并不一定要用服务，可以写一个隐藏界面的程序a，然后是b和c，就行，写服务程序跨度太大，最简单的无界面程序，就是win32应用程序，不是控制台程序，在wMain里面实现代码，运行只有进程，没有界面

楼主不会 点9楼给出的链接，下载两个ISO文件，然后使用虚拟光驱软件Daemon Tools先后加载这两个ISO文件，运行其中的setup,exe，将MSDN98安装到D:\MSDN98下。 然后打开 D:\MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C D:\MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C D:\MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H D:\MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C 文件看，或用VC6打开 D:\MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\MAKEFILE 编译链接调试。 的话，还是趁早知难而退，洗洗睡去吧。

另外，赵老师的意思是，让你自己看csdn给的例子。

进程间通信。百度一下，一大把吧。最简单的，写到剪切板都OK。

引用 17 楼 zhao4zhong1 的回复:[quote=引用 16 楼 jiangbai333 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] 楼主如果觉得9楼的例子代码还不够简单的话，建议趁早改行。 行数 | 文件  589 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C  325 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C  137 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H   74 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C  恩 我根本不懂你给我的是什么！ 我接触的挺少的，也没打算从事c的工作，基础就是大学里学的c还有数据结构。问这个真的是出于个人兴趣，想知道到底怎么实现的，以我的水平，可能看起来有些吃力！我就是想要个最最简单的实例！然后自己在它基础上研究一下！    可以给我一个简单的实例么？ 比如就两个程序，a程序负责数据，b程序负责操作。 我通过b程序输入一个数，然后调用a把数保存在文件里！ 有点表述不清楚，但就是像数据库的服务程序一样！ a是一直在运行的，b执行的时候可以直接就用a！  先感谢！ [/quote] 要求自己做得多一些，要求别人做得少一些。 这样做虽然让自己受累了，但同时让自己有更多机会提高。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  [/quote] 不是我不做！ 是我真不知道第一步该怎么迈！ 就像学完指针我就可以自己看链表了，学完一维数组我就可以自己写二维数组了！ 但是这个到底是怎么回事儿，我真不知道！ 学指针的时候就几行基本代码，但至少让我知道是怎么回事儿 我才能再往下学！ 我不是要求别人做什么！只是想得到些指导！ 可能以你的水平，你觉得跟我列几个文件我自己去看就足够了，但想必你是从事过多年代，码开发的工作了，但我的水平真达不到！

引用 16 楼 jiangbai333 的回复:[quote=引用 15 楼 zhao4zhong1 的回复:] 楼主如果觉得9楼的例子代码还不够简单的话，建议趁早改行。 行数 | 文件  589 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C  325 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C  137 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H   74 | MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C  恩 我根本不懂你给我的是什么！ 我接触的挺少的，也没打算从事c的工作，基础就是大学里学的c还有数据结构。问这个真的是出于个人兴趣，想知道到底怎么实现的，以我的水平，可能看起来有些吃力！我就是想要个最最简单的实例！然后自己在它基础上研究一下！    可以给我一个简单的实例么？ 比如就两个程序，a程序负责数据，b程序负责操作。 我通过b程序输入一个数，然后调用a把数保存在文件里！ 有点表述不清楚，但就是像数据库的服务程序一样！ a是一直在运行的，b执行的时候可以直接就用a！  先感谢！ [/quote] 要求自己做得多一些，要求别人做得少一些。 这样做虽然让自己受累了，但同时让自己有更多机会提高。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！

6楼正解，或者看UNP（Unix Network Programming）卷2,重点讲述IPC的

设计一个服务器进程, 设计多个客户端进程, 客户端进程通过IPC和服务器进程交互.

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98 再参考： MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.DSP MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\MAKEFILE MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SIMPLE.C MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.C MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\SERVICE.H MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\CLIENT.C MSDN98\SAMPLES\VC98\SDK\WINBASE\WINNT\SERVICE\README.TXT

还有个简单的方法，调用FreeConsole函数。不过程序启动时会闪一下console窗口，然后就没了。

搜索IPC编程。

写一个数据库读写程序，其他程序读内存共享或者用封包查询

你说的是服务程序吧。可以搜索和服务程序有关的。 或者去找找“守护进程”，或许就是你想要的

1 服务类程序跟普通程序一样的 2 进程间通信可以用共享内存来实现


Question: 高手们，怎样把开源库的错误码给其他人？

自己封装错误码，在头文件中用宏或者枚举的方式定义所有的错误码，再做好错误码和函数返回值的注释，这就可以很清楚的知道返回值的意义了

既然屏蔽了A，就自己定义错误码吧，只要把问题描述清楚了就行，把错误码返回给客户让客户明白错误原因

和用户协商好？或者统一重新定义


Question: 程序开O3优化和不开O3优化的困惑

编译器优化？肯定存在和板子冲突的某种优化


Question: 求教

引用 9 楼 qq_25942099 的回复:[quote=引用 1 楼 user-6 的回复:] 调试！！！！   VC6.0   怎么才能调试[/quote] 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

引用 1 楼 user-6 的回复:调试！！！！   VC6.0   怎么才能调试

引用 7 楼 qq_25942099 的回复:[quote=引用 2 楼 robertbo 的回复:] 自己debug跟踪一下结果就出来了，楼主得补一下基础知识  int b[N]={9,1,4,2,3,6,5,8,7},i; printf("%4d",b[i]); 这块i还没有初始化呢怎么就是用了呢   有啊，for 里面不是赋值么[/quote]  看错了

引用 2 楼 robertbo 的回复:自己debug跟踪一下结果就出来了，楼主得补一下基础知识  int b[N]={9,1,4,2,3,6,5,8,7},i; printf("%4d",b[i]); 这块i还没有初始化呢怎么就是用了呢   有啊，for 里面不是赋值么

问题楼上都说了，以后注意在使用变量前看看是否需要初始化

粗略目测是i的问题，在函数内定义的局部变量编译器是不会自动初始化为0的（全局变量会初始化为0），因此i的值是一个随机数，那么b[i]则会出现访问越界的现象，于是崩溃 改正方法，将i赋值，并保证此值不会让b[i]访问越界

void main() { int b[N]={9,1,4,2,3,6,5,8,7},i; printf("%4d",b[i]);  b[i]中的i没有赋值

调试！！！！


Question: C语言fopen打开文件问题（莫名其妙的问题）

我猜是不是要E:\\file

是你理解错了，一点也不莫名其妙 FILE * 本身不是 NULL，其指向的结构体中某字段可以是 NULL，因为你还没使用它呢

楼主研究FILE结构体的成员的值有何意义？ 用fread,fwrite,fseek,ftell这些函数通过指向FILE结构体的指针能操作文件不够用？  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

看了楼上一堆人的回答还是没懂lz你想问啥

不明白你在问什么问题的飘过

文件指针的值不是有吗 有什么问题?

楼主去学一下C语言下FILE结构的声明吧，网上搜一搜也可以找到相关的资料；建议了解一下即可。


Question: 一个数组打印的方法，请高手们帮实现

#include <stdafx.h> #include <stdio.h> #include <Windows.h> #include <stdlib.h> #include <memory.h>  bool sprintRight(int *pSrc, 	int *pTarget, 	const int width, 	/*const int height,*/ 	unsigned ¤tRow, 	unsigned ¤tCol, 	unsigned ¤tSize, 	const int indicator) { 	bool bRet = true; 	for (int iCol = currentCol; iCol <= width; ++iCol) 	{ 		unsigned pos = (currentRow - 1)* width + iCol -1; 		if(pSrc[pos] != indicator) 		{ 			pTarget[currentSize] = pSrc[pos]; 			pSrc[pos] = indicator; 			printf("%d, ", pTarget[currentSize]); 			currentSize++; 			currentCol++; 		} 		else 		{ 			bRet = false; 			break; 		} 	}  	currentCol -= 2; 	currentRow++; 	return bRet; }  bool sprintLeftDown(int *pSrc, 	int *pTarget, 	const int width, 	const int height, 	unsigned ¤tRow, 	unsigned ¤tCol, 	unsigned ¤tSize, 	const int indicator) { 	bool bRet = true; 	while (currentRow <= height) 	{ 		unsigned pos = (currentRow-1) * width + currentCol-1; 		if (pSrc[pos] != indicator) 		{ 			pTarget[currentSize] = pSrc[pos]; 			pSrc[pos] = indicator; 			printf("%d, ", pTarget[currentSize]); 			currentSize++;  			currentRow++; 			currentCol--; 		} 		else 		{ 			bRet = false; 			break; 		} 	} 	currentRow--; 	return bRet; }  bool sprintLeft(int *pSrc, 	int *pTarget, 	const int width, 	/*const int height,*/ 	unsigned ¤tRow, 	unsigned ¤tCol, 	unsigned ¤tSize, 	const int indicator) { 	bool bRet = true; 	while (currentCol > 0) 	{ 		unsigned pos = (currentRow-1) * width + currentCol-1; 		if (pSrc[pos] != indicator) 		{ 			pTarget[currentSize] = pSrc[pos]; 			pSrc[pos] = indicator; 			printf("%d, ", pTarget[currentSize]); 			currentSize++; 			currentCol--; 		} 		else 		{ 			bRet = false; 			break; 		} 	} 	currentRow--;// for sprintTop 	currentCol++; 	return bRet; } bool sprintTop(int *pSrc, 	int *pTarget, 	const int width, 	unsigned ¤tRow, 	unsigned ¤tCol, 	unsigned ¤tSize, 	const int indicator) { 	bool bRet = true; 	while (currentRow > 0) 	{ 		unsigned pos = (currentRow-1) * width + currentCol-1; 		if (pSrc[pos] != indicator) 		{ 			pTarget[currentSize] = pSrc[pos]; 			pSrc[pos] = indicator; 			printf("%d, ", pTarget[currentSize]); 			currentSize++; 			currentRow--; 		} 		else 		{ 			bRet = false;  			break; 		} 	} 	currentCol++; 	currentRow++; 	return bRet; } void  convertMatrix(int width, int height, int* matrix, int *result_size, int** result) { 	size_t totalsize = width * height; 	int *pTarget = (int *)malloc(totalsize * sizeof(int)); 	* result = pTarget; 	int indicator = 0;//present the invalid value 	for (size_t i = 0; i < totalsize; ++i) 	{ 		pTarget[i] = indicator; 	}  	unsigned currentSize = 0;//of pTarget 	unsigned currentRow = 1;//of matrix 	unsigned currentCol = 1;//of matrix 	bool bRet1 = true, bRet2 = true, bRet3 = true, bRet4 = true; 	bool bGoOn = true; 	while ((currentSize < totalsize) 		&& bGoOn) 	{ 		//bRet1234: reach a border or not 		bRet1 = sprintRight(matrix, pTarget, width,currentRow, currentCol, currentSize, indicator); 		bRet2 = sprintLeftDown(matrix, pTarget, width, height,currentRow, currentCol, currentSize, indicator); 		bRet3 = sprintLeft(matrix, pTarget, width, currentRow, currentCol, currentSize, indicator); 		bRet4 = sprintTop(matrix, pTarget, width, currentRow, currentCol, currentSize, indicator); 		bGoOn = bRet1 || bRet2 || bRet3 || bRet4; 	}  	*result_size = currentSize; } int main() { 	int res_size; 	int* res; 	int _width; 	scanf("%d", &_width);  	int _height; 	scanf("%d", &_height);  	int *_matrix = (int*) malloc(_width * _height * sizeof(int)); 	int _matrix_i; 	for(_matrix_i = 0; _matrix_i < _width * _height; _matrix_i++) 	{ 		int _matrix_item; 		scanf("%d", &_matrix_item);  		_matrix[_matrix_i] = _matrix_item; 	}  	convertMatrix(_width, _height, _matrix, &res_size, &res); 	printf("\n"); 	int res_i; 	for(res_i=0; res_i < res_size; res_i++) 	{  		printf("%d ", res[res_i]);  	} 	free(_matrix); 	free(res); 	system("pause"); 	return 0; }

仅供参考：#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");     } }


Question: 如何查看编译过程中某个头文件的查找路径？

问题已经解决了。原因是用-I指定的搜索路径顺序对Include_next有影响，导致在搜索include_next指定的头文件时，使用了非编译器路径。  举个例子：  A、B、C三个目录下分别有一个文件：  A/a.h #ifndef A_A_H #define A_A_H  #include "a_aux.h"  #endif  B/a_aux.h #ifndef B_A_AUX_H #define B_A_AUX_H  #include_next "a.h"  #endif  C/a.h #ifndef C_A_H #define C_A_H  #pragma message("1111111111111111111")  #endif  另外有个一个与A、B、C并列的main.c文件： #include "a.h"  int main() { return 0; }  编译命令： gcc main.c -I./A -I./B -I./C ./C/a.h:5: 附注：#pragma message：1111111111111111111 说明B/a_aux.h中#include_next "a.h"，在下一个含有a.h目录C中找到了a.h  编译命令：gcc main.c -I./B -I./A -I./C 无打印，说明B/a_aux.h中#include_next "a.h"没找到C中的a.h，找到的仍然是A中的a.h，因为-I选项指定了A在B目录之后，是B目录的下一个含有a.h文件的目录，于是选择了A中的a.h  从上面的现象看，貌似#include_next并不是从搜索路径列表的第一条开始计算next的基准，而是从当前文件所在目录（上例中的B目录）作为基准找到下一个含有a.h的目录。这好像与#include_next的含义有些不符，还没搞懂。

友情帮顶了，看看再说

增加gettimeofday的声明可以解决找不到声明的warning.  gettimeofday的问题是我遇到的问题之一，是为了说明include_next没有包含到编译器的头文件，其实还有其他问题，例如结构struct timezone，也报找不到定义；  还有MAXPATHLEN找不到定义，这个是定义在编译器的sys/param.h中，项目的一个头文件sys/param_aux.h通过include_next方式包含了编译器的sys/param.h

引用 2 楼 walter2001 的回复:谢楼上回答。我遇到的问题，能查看依赖的所有头文件还不够，最好能知道头文件搜索路径的顺序。 具体问题是项目自己的一个头文件sys/time.h中使用include_next包含了交叉编译器的sys/time.h，但实际编译的时候，并没有包含交叉编译器的sys/time.h文件，导致gettimeofday函数找不到定义。 在你调用gettimeofday的源文件的开头加一句 extern int gettimeofday(struct timeval *, struct timezone *);  试试看。

gcc -M 选项和 -MM选项  [root@JiangWenjie-VM FileTran]# ls byteorder.c  list.c  main.c    protocol.c  recver.c  sender.c  timer.c  types.c byteorder.h  list.h  Makefile  protocol.h  recver.h  sender.h  timer.h  types.h [root@JiangWenjie-VM FileTran]# gcc -MM main.c  main.o: main.c types.h sender.h recver.h [root@JiangWenjie-VM FileTran]# gcc -M main.c  main.o: main.c types.h /usr/include/stdint.h /usr/include/features.h \   /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \   /usr/include/gnu/stubs.h /usr/include/gnu/stubs-32.h \   /usr/include/bits/wchar.h /usr/include/sys/socket.h \   /usr/include/sys/uio.h /usr/include/sys/types.h \   /usr/include/bits/types.h \   /usr/lib/gcc/i386-redhat-linux/4.1.2/include/stddef.h \   /usr/include/bits/typesizes.h /usr/include/time.h /usr/include/endian.h \   /usr/include/bits/endian.h /usr/include/sys/select.h \   /usr/include/bits/select.h /usr/include/bits/sigset.h \   /usr/include/bits/time.h /usr/include/sys/sysmacros.h \   /usr/include/bits/pthreadtypes.h /usr/include/bits/uio.h \   /usr/include/bits/socket.h \   /usr/lib/gcc/i386-redhat-linux/4.1.2/include/limits.h \   /usr/lib/gcc/i386-redhat-linux/4.1.2/include/syslimits.h \   /usr/include/limits.h /usr/include/bits/posix1_lim.h \   /usr/include/bits/local_lim.h /usr/include/linux/limits.h \   /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \   /usr/include/asm/socket.h /usr/include/asm/sockios.h \   /usr/include/arpa/inet.h /usr/include/netinet/in.h \   /usr/include/bits/in.h /usr/include/bits/byteswap.h \   /usr/include/unistd.h /usr/include/bits/posix_opt.h \   /usr/include/bits/confname.h /usr/include/getopt.h /usr/include/fcntl.h \   /usr/include/bits/fcntl.h sender.h recver.h /usr/include/stdio.h \   /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \   /usr/include/gconv.h \   /usr/lib/gcc/i386-redhat-linux/4.1.2/include/stdarg.h \   /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \   /usr/include/stdlib.h /usr/include/alloca.h /usr/include/string.h [root@JiangWenjie-VM FileTran]#


Question: 好不容易在win8上安装了vc++6.0,但是这个运行结果怎么回事，求大神指教，是兼容性还是其他问题

刚试过，中文逗号是和你一样的情况。

你在命令行里输入的1，8 的逗号是中文的，要输入英文的逗号才可以。 也就是命令行状态下不要开启中文输入法。

scanf("%d%d",&a,&b);//输入两个用空格间隔的整数

win8下不要用VC6了，如果仅仅是学C/C++，推荐c-free，如果学习VC，可以装VS，推荐2010及以上版本

除非是万不得已，比如维护旧项目，否则早点放弃vc6吧。

前辈请问为什用vc++6.0打开初始界面选择“文件——打开”的时候会突然停止工作呢，一直是这样，是因为在win8上的兼容性问题吗，已经将兼容性改为兼容win8了，还请前辈指教，谢谢！

运行结果的问题，1楼是正解，VC停止运行的问题，是VC6.0在WIN8上的必然结果，既然选择在Win8上用VC6.0，就应该默默忍受VC6.0崩溃


Question: C语言能不能做类似JS的网页脚本语言？

引用 20 楼 zhao4zhong1 的回复:细胞虽然不能编程，但不妨碍由细胞构成的人能编程！ 有时候为了纠正由各种细胞构成的人编程出的错，需要改造其身上某些部位的若干相关的细胞。

细胞虽然不能编程，但不妨碍由细胞构成的人能编程！

C主要用来系统编程。

最简单的纯C语言做的WEB页面：  1.使用C语言调用系统API监控80端口；  2.凡是有连接80端口的，按照HTTP协议，返回一个HTTP头以及主体：<html>Hello World!</html>。  打完收工。

虚拟机中的汇编语言是C/C++编的。

SQL语言是C/C++编的。

语言都有自己适合的一块领域，在 web 开发中 java/asp.net/php 都比 c++ 更适合。 c++ 做 web 后台开发还可勉为其难（现在恐怕也没人这么用了），做前端脚本语言恐怕不行吧。 在 html5 中，默认的脚本语言是 JavaScript，这已经成为标准。

引用 12 楼 Raffin 的回复:[quote=引用 9 楼 luciferisnotsatan 的回复:] JS用虚拟机，部署方便。不同的服务器只要一次性装完对应的虚拟机就行了。 C要编译不同的平台版本才能部署。  不同的语言有不同的用途，何必要通吃呢？不然直接用汇编来写代码，用什么C呀。  虚拟机要安装一个软件，这个软件不跨平台。 如果你要C跨平台，开发一个类似的“C虚拟机”不就行了。  语言作用都是类似的，同样的功能就应该用同样的语法。 汇编和C的关系，和C和JAVA，C#的关系不一样。[/quote]  那这还叫C么？微软开发了个基于。net的C++/CLR，除了用作native C++和.net粘合剂外，没什么人会用这东西作为开发语言。因为，用这个C++变种，还不如直接用C#。  为什么你觉得汇编会不一样的？为什么不能开发一个汇编编译器，创建一个汇编语言变种，然后把这个变种翻译成对应CPU汇编？  同样的道理，做WEB你打算用数据库么？为什么要用数据库，用SQL语言？干嘛不直接用C语言写个数据管理的库（这里不是指用C来开发一个数据库，而是一组动态库，静态库），提供各种函数来实现SQL做的事。

引用 楼主 Raffin 的回复:讨论下C语言的应用吧，除了开发底层驱动外，还被应用到哪里比较多？ 在开发大型应用程序尤其是WEB程序时，C语言好像不像JAVA有能够快速开发的框架和工具。 大型应用程序？多大型？你即便淘宝，人家JAVA的功夫也都是放在自己改操作系统，自己剪虚拟机，高精尖的也都是放在C层面，跟你那什么Spring,Hibernate这些乱七八糟框架没半毛钱关系。  人家都是倾向于C做底层，上边再粘DSL之类的。比如搭个lua虚拟机，很简单，但你立马就能用lua写脚本了。再比如，ngix是基于C的，再写个模块，粘上lua，立马你也能用lua写web程序了

引用 9 楼 luciferisnotsatan 的回复:JS用虚拟机，部署方便。不同的服务器只要一次性装完对应的虚拟机就行了。 C要编译不同的平台版本才能部署。  不同的语言有不同的用途，何必要通吃呢？不然直接用汇编来写代码，用什么C呀。  虚拟机要安装一个软件，这个软件不跨平台。 如果你要C跨平台，开发一个类似的“C虚拟机”不就行了。  语言作用都是类似的，同样的功能就应该用同样的语法。 汇编和C的关系，和C和JAVA，C#的关系不一样。

引用 6 楼 sinservice 的回复:我刚写了一个 这么屌

我刚写了一个

引用 1 楼 zhao4zhong1 的回复:js是C/C++编的。  大神你是从事什么工作的？

引用 2 楼 wangliangffaflgh 的回复:C语言其实可以做WEB开发，可以写CGI程序，但是这种技术已经比较老了 给你个链接关注下http://blog.sina.com.cn/s/blog_793598f80102v4mw.html  CGI我知道，原来也是用C语言写的。 但是CGI后来被SERVLET取代了，从代码上讲确实CGI比较麻烦。 我比较在意的是为什么没人用C语言去开发一些方便好用的工具，比如JSP和SERVLET。

C语言做底层硬件开发，嵌入式开发应用开始蛮多的

js是C/C++编的。

C语言除了搞硬件开发、系统开发，主要就是用来开发其它语言的，你可以随便说一门语言，不管C#、JAVA以及各种脚本语言python、Javascript、lua、以及各种标记语言HTML、XML、CSS，几乎都是跑在C语言的头上，由C语言来解析、解释、执行。

最近再用，poco c++库。开打速度很快。有很多框架。什么，json xml http tcp 加解密 smtp 等常用功能框架都有的。


Question: argv[argc] = NULL，为什么这么设计？

引用 23 楼 yangyunzhao 的回复:[quote=引用 4 楼 hhhhhhhhhhkkkkkkkkkk 的回复:] argv[argc] == NULL并不非法，c中一个字符串总以\0(就是NULL)结尾。argv[argc]就是最后一个字符NULL。这么设计的原因是方便循环等等。例如你想遍历字符串中的字符，可以这样写: for(int i=0;argv[i];i++){//做一些事} 与 for(int i=0;argv[i]==NULL;i++){//做一些事} 的效果一致。 argv不是字符数组，而是字符串数组。数组的元素是字符串！[/quote] 靠，没注意原来这是个字符串数组。我就说楼主怎么问这么基础的问题，感谢老兄提醒。不过我说的原因还是适用于这个，就是方便循环。

argv[argc]//this argument doesn`t exist in stack of function

老大，别沉啊

可以以指针的方式遍历argv，如果发现所指为NULL，表示所有的参数处理完了。

引用 22 楼 a627088424 的回复:[quote=引用 19 楼 my_live_123 的回复:] 可以认为是一种安全机制吧，防止越界访问；也可能是方面代码的编写，而不局限于用argc限制数组大小 还真没有想过这个问题，c99也没有给出说明，只是提到此规则！不过一般的程序不用关心，对argv数组的设置有启动程序负责完成的，一般的用户只是使用这个数组 我就是突然“爱思考”了下，所以就跑了问问了，求大神赐教[/quote] 问倒喽，继续发扬此精神

引用 4 楼 hhhhhhhhhhkkkkkkkkkk 的回复:argv[argc] == NULL并不非法，c中一个字符串总以\0(就是NULL)结尾。argv[argc]就是最后一个字符NULL。这么设计的原因是方便循环等等。例如你想遍历字符串中的字符，可以这样写: for(int i=0;argv[i];i++){//做一些事} 与 for(int i=0;argv[i]==NULL;i++){//做一些事} 的效果一致。 argv不是字符数组，而是字符串数组。数组的元素是字符串！

引用 19 楼 my_live_123 的回复:可以认为是一种安全机制吧，防止越界访问；也可能是方面代码的编写，而不局限于用argc限制数组大小 还真没有想过这个问题，c99也没有给出说明，只是提到此规则！不过一般的程序不用关心，对argv数组的设置有启动程序负责完成的，一般的用户只是使用这个数组 我就是突然“爱思考”了下，所以就跑了问问了，求大神赐教

没用过这写法，貌似下标超范围了

引用 16 楼 a627088424 的回复:[quote=引用 15 楼 a627088424 的回复:] [quote=引用 14 楼 paschen 的回复:] http://zhidao.baidu.com/link?url=RuxLmlrJAU8olHzwFhiMBJ5SG6dkcdQpBOyRvP7Z4EgNB0qtBFhmjqRxSgyup8GZ7HdnvZM3YuXFJwGm238c74CMFLIz0WjBjyLDqTOqs67  这个贴子可以使argc为0 他写的格式有点乱  其中execlp作用可以参见：http://baike.baidu.com/link?url=8LlIRn1qp8HvRVKWt4owK9pZBg0PUNcEiNsRcpiU2v8gwQ0QfyeObWHyHAEjvEM6ZxeC_NC4OpCekT0hXQ0Qz_ 我用gcc测试了那样会出错o  [/quote]  [/quote] 他那个帖子是因为他execlp执行错误，才会执行printf的，结果是1，

引用 15 楼 a627088424 的回复:[quote=引用 14 楼 paschen 的回复:] http://zhidao.baidu.com/link?url=RuxLmlrJAU8olHzwFhiMBJ5SG6dkcdQpBOyRvP7Z4EgNB0qtBFhmjqRxSgyup8GZ7HdnvZM3YuXFJwGm238c74CMFLIz0WjBjyLDqTOqs67  这个贴子可以使argc为0 他写的格式有点乱  其中execlp作用可以参见：http://baike.baidu.com/link?url=8LlIRn1qp8HvRVKWt4owK9pZBg0PUNcEiNsRcpiU2v8gwQ0QfyeObWHyHAEjvEM6ZxeC_NC4OpCekT0hXQ0Qz_ 我用gcc测试了那样会出错o  [/quote]

引用 14 楼 paschen 的回复:http://zhidao.baidu.com/link?url=RuxLmlrJAU8olHzwFhiMBJ5SG6dkcdQpBOyRvP7Z4EgNB0qtBFhmjqRxSgyup8GZ7HdnvZM3YuXFJwGm238c74CMFLIz0WjBjyLDqTOqs67  这个贴子可以使argc为0 他写的格式有点乱  其中execlp作用可以参见：http://baike.baidu.com/link?url=8LlIRn1qp8HvRVKWt4owK9pZBg0PUNcEiNsRcpiU2v8gwQ0QfyeObWHyHAEjvEM6ZxeC_NC4OpCekT0hXQ0Qz_ 我用gcc测试了那样会出错o

弄起来真好玩。

引用 1 楼 q3733353520 的回复:argc 为参数个数  argv为参数数组    对于一个数组  char a[10]; 能用 a[10] = 'a'吗？  (⊙o⊙)哦，我问题掉了个=号： argv[argc] == NULL，为何如此设计，有什么原因吗？

引用 12 楼 user-11 的回复:哦 找到原因了  因为 argc 可以是0 对于这种情况 argv[0] 总不能是一个野指针  argc 可以是0？ 真的？举个例子

引用 10 楼 user-11 的回复:[quote=引用 9 楼 a627088424 的回复:] [quote=引用 7 楼 user-11 的回复:] [quote=引用 3 楼 wbx779139218 的回复:] 楼上说的不错，argc是main函数接受的参数个数，argv则是一个字符串数组 argv[argc]是非法的（但是argv[argc-1]）可以） 这样做的目的。。。个人觉得这样写是想把最后一个字符串设为NULL而防止访问错误，不过有argc在，所以没有必要这样做汗 不是非法的  argv[argc] shall be a null pointer. 标准文档里面是这样写的  题主问的是 为什么要这样规定[/quote] 嗯，有什么好的理由，还是历史遗留[/quote] 标示 argv什么时候结束的  虽然 argc 也有表示argv有多少个有效数据 但是 有时候 argc 的值会被修改  比如 -- argc  这时候 可以用argv[ i ] != NULL 来检查是不是有效传入参数[/quote] argc有被修改的可能性，难道argv[argc]就没有被修改的可能性吗？如果两个都被修改了，不就不知道有多少个参数了，除非最开始就用另外的一个新的变量保存个数


Question: malloc和free问题

free Deallocates or frees a memory block.  void free( void *memblock );  Function Required Header Compatibility  free <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  None  Parameter  memblock  Previously allocated memory block to be freed  Remarks  The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors.  After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again.  When the application is linked with a debug version of the C run-time libraries, free resolves to _free_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* MALLOC.C: This program allocates memory with  * malloc, then frees the memory with free.  */  #include <stdlib.h>         /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h>  void main( void ) {    char *string;     /* Allocate space for a path name */    string = malloc( _MAX_PATH );    if( string == NULL )       printf( "Insufficient memory available\n" );    else    {       printf( "Memory space allocated for path name\n" );       free( string );       printf( "Memory freed\n" );    } }   Output  Memory space allocated for path name Memory freed   Memory Allocation Routines  See Also   _alloca, calloc, malloc, realloc, _free_dbg, _heapmin

第一个用法完全错了  别说释放内存  有时候 程序崩溃都是完全正常的事情   第二个可以那样用 这种做法是 const 的范例使用方式了

引用 1 楼 zmlovelx 的回复:第一个最好用free p[]; 不过内置类型的用free p也是可以的 第二个，只是部分限定，其内部还是有办法绕过修改的。别闹  你以为这是 new / delete? free 是函数好不好 ()  不能省略

第一个不能完全释放吧，会泄露的。 第二个可以写点小代码试试。

中括号我只在c++中delete p[]释放数组空间的时候看到啊。C语言中free也有这样的用法吗？ 第二个修改能跟我讲讲怎么实现吗？


Question: 《linux程序设计》中strptime函数例子有问题

#define _XOPEN_SOURCE


Question: 关于结构体函数的调用问题（有些难度）

引用 24 楼 weiran2009 的回复:[quote=引用 21 楼 bear234 的回复:] "我自认为自己大学时C语言还不错，然而工作才发现自己是多么的天真" "还有对cleanup函数的引用怎么那么复杂 (void (*)(void*))cleanup ，完全没见过啊"    呃，如果再告诉你我大学时计算机2、3、4级一次性通过年年辅导同学通过2级通过率100%阁下一定觉得更可笑了……[/quote]   计算机等级考试 == 0  计算机等级考试就是写99乘法口诀表的水平....... 我没有嘲笑你的意思   只不过你这两句话放在一起真的让我笑了~~~~~~~  如果你不是专门搞代码的  算我没说  否则，你还不需要看一些书然后亲自编一些东西才行

引用 24 楼 weiran2009 的回复:[quote=引用 21 楼 bear234 的回复:] "我自认为自己大学时C语言还不错，然而工作才发现自己是多么的天真" "还有对cleanup函数的引用怎么那么复杂 (void (*)(void*))cleanup ，完全没见过啊"    呃，如果再告诉你我大学时计算机2、3、4级一次性通过年年辅导同学通过2级通过率100%阁下一定觉得更可笑了……[/quote] 计算机几级通过之后能写出如下程序： #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.

引用 21 楼 bear234 的回复:"我自认为自己大学时C语言还不错，然而工作才发现自己是多么的天真" "还有对cleanup函数的引用怎么那么复杂 (void (*)(void*))cleanup ，完全没见过啊"    呃，如果再告诉你我大学时计算机2、3、4级一次性通过年年辅导同学通过2级通过率100%阁下一定觉得更可笑了……

《c和指针》里讲到怎么解析函数指针，你查阅下相关章节！

引用 15 楼 weiran2009 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解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 感谢前辈的指点，不过工作中还是要以解决问题为主，我现在采取的方法是：不理解就背下来，我看了网上推荐王爽《汇编语言》不错，我空余时间会看到。但不知道您说的多用小脑、少用大脑没有理解……有什么暗喻吗？[/quote] 你只需要实际按Alt+8进入汇编窗口，再按几次F11单步过一遍任何一个带参数的C函数调用过程对应的几条汇编指令，并理解这几条汇编指令都对哪些地址处的哪些字节值做了哪些修改一次，相信你以后就不会再到论坛来问有关函数参数传递的问题而是自己通过这个方法观察了。 理解和讨论之前请先学会如何观察！

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

引用 7 楼 weiran2009 的回复:[quote=引用 1 楼 luciferisnotsatan 的回复:] 如果是(int)cleanup， 知道这种是强转么？  (void (*)(void*))cleanup 这个是吧cleanup像转为一个指向一个参数为void*, 返回值为void的函数指针。  void anim_and_exit( void (*f)(void*,int), void(*e)(void*) ) 接受两个函数指针。  google下函数指针你就知道了 我看了C Primer Plus第14章讲到了函数指针，但问题在于：不仅这个例程比书上要复杂，并且函数调用的参数不明：您看： 函数原型： void cleanup( DataBlock *d )  void generate_frame( DataBlock *d, int ticks )  而调用是这样的： bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))cleanup ); 如此一来，函数cleanup的形参 DataBlock *d， 以及generate_frame函数的形参 DataBlock *d, int ticks都怎么传递值的呢？这和书里面和网上讲解的相差很大……[/quote] bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,                             (void (*)(void*))cleanup );这个调用中，相当于执行了c]bitmap.fAnim = generate_frame, c]bitmap.animExit = cleanup, 你想要知道generate_frame函数的形参 DataBlock *d, int ticks怎么传递值，你只需要查看 CPUAnimBitmap::fAnim 是怎么使用的就行了，例如CPUAnimBitmap*   bitmap = *(get_bitmap_ptr());         bitmap->fAnim( bitmap->dataBlock, ticks++ );

引用 10 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解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 感谢前辈的指点，不过工作中还是要以解决问题为主，我现在采取的方法是：不理解就背下来，我看了网上推荐王爽《汇编语言》不错，我空余时间会看到。但不知道您说的多用小脑、少用大脑没有理解……有什么暗喻吗？

dataBlock = d;  放[code]里没标红，你看 就是我说的标红部分

引用 8 楼 weiran2009 的回复:完整的CPUAnimBitmap结构体 struct CPUAnimBitmap {     unsigned char    *pixels;     int     width, height;     void    *dataBlock;     void (*fAnim)(void*,int);     void (*animExit)(void*);     void (*clickDrag)(void*,int,int,int,int);     int     dragStartX, dragStartY;      CPUAnimBitmap( int w, int h, void *d = NULL ) {         width = w;         height = h;         pixels = new unsigned char[width * height * 4];         dataBlock = d;         clickDrag = NULL;     }           void anim_and_exit( void (*f)(void*,int), void(*e)(void*) ) {         CPUAnimBitmap**   bitmap = get_bitmap_ptr();         *bitmap = this;         fAnim = f;         animExit = e;         // a bug in the Windows GLUT implementation prevents us from         // passing zero arguments to glutInit()         int c=1;         char* dummy = "";         glutInit( &c, &dummy );         glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );         glutInitWindowSize( width, height );         glutCreateWindow( "bitmap" );         glutKeyboardFunc(Key);         glutDisplayFunc(Draw);         if (clickDrag != NULL)             glutMouseFunc( mouse_func );         glutIdleFunc( idle_func );         glutMainLoop();     }   从标红的这几处代码猜测，在回调animExit时，会把初始化CPUAnimBitmap对象时传的 d，作为参数传给cleanup。

引用 5 楼 ri_aje 的回复:这是 cuda 改过的 c 语言，(void (*)(void*))cleanup 就是强制类型转换，(...) 里面的是目标类型。 __global__ 还有 <<<...>>> 等都是 cuda 自己的私货，根本不是标准 c 的东西。  想必阁下也是看过《CUDA实战》的GPU前辈吧，我看到main函数开头两句话很有意思：     CPUAnimBitmap  bitmap( DIM, DIM, &data );     //结构体实例data里面有CPUAnimBitmap的数据类型        data.bitmap = &bitmap; // data.bitmap又引用了自己含有引用自己地址的CPUAnimBitmap数据类型bitmap的地址  感觉绕来绕去挺麻烦的，前辈可以指点一二吗？

引用 7 楼 weiran2009 的回复:[quote=引用 1 楼 luciferisnotsatan 的回复:] 如果是(int)cleanup， 知道这种是强转么？  (void (*)(void*))cleanup 这个是吧cleanup像转为一个指向一个参数为void*, 返回值为void的函数指针。  void anim_and_exit( void (*f)(void*,int), void(*e)(void*) ) 接受两个函数指针。  google下函数指针你就知道了 我看了C Primer Plus第14章讲到了函数指针，但问题在于：不仅这个例程比书上要复杂，并且函数调用的参数不明：您看： 函数原型： void cleanup( DataBlock *d )  void generate_frame( DataBlock *d, int ticks )  而调用是这样的： bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))cleanup ); 如此一来，函数cleanup的形参 DataBlock *d， 以及generate_frame函数的形参 DataBlock *d, int ticks都怎么传递值的呢？这和书里面和网上讲解的相差很大……[/quote] 所以用了强转，就和memset一样，void *memset(void *s, int ch, size_t n); 第一个参数是void *，只不过用这个函数你不用显示强转第一个参数。  (void (*)(void*))cleanup bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))cleanup );  cleanup就是个函数的起始地址，然后强转就是把这个地址看成(void (*)(void*))来用，至于anim_and_exit能不能用对这个cleanup，就是具体问题具体分析了。对于这个anim_and_exit，它回调cleanup时是不是传个DataBlock结构给你，你就要自己去看说明文档/相关代码了。   对于编译器来说，你强转什么都没问题。至于能不能运行，会不会有问题，那是另一件事了 bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))main ); bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))0 );

引用 6 楼 user-9 的回复:楼主可以看一下c陷阱与缺陷。。。 以我现在的能力，感觉还是看看基础的好，是不是《C和指针》更适合我呢？

完整的CPUAnimBitmap结构体 struct CPUAnimBitmap {     unsigned char    *pixels;     int     width, height;     void    *dataBlock;     void (*fAnim)(void*,int);     void (*animExit)(void*);     void (*clickDrag)(void*,int,int,int,int);     int     dragStartX, dragStartY;      CPUAnimBitmap( int w, int h, void *d = NULL ) {         width = w;         height = h;         pixels = new unsigned char[width * height * 4];         dataBlock = d;         clickDrag = NULL;     }      ~CPUAnimBitmap() {         delete [] pixels;     }      unsigned char* get_ptr( void ) const   { return pixels; }     long image_size( void ) const { return width * height * 4; }      void click_drag( void (*f)(void*,int,int,int,int)) {         clickDrag = f;     }      void anim_and_exit( void (*f)(void*,int), void(*e)(void*) ) {         CPUAnimBitmap**   bitmap = get_bitmap_ptr();         *bitmap = this;         fAnim = f;         animExit = e;         // a bug in the Windows GLUT implementation prevents us from         // passing zero arguments to glutInit()         int c=1;         char* dummy = "";         glutInit( &c, &dummy );         glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );         glutInitWindowSize( width, height );         glutCreateWindow( "bitmap" );         glutKeyboardFunc(Key);         glutDisplayFunc(Draw);         if (clickDrag != NULL)             glutMouseFunc( mouse_func );         glutIdleFunc( idle_func );         glutMainLoop();     }      // static method used for glut callbacks     static CPUAnimBitmap** get_bitmap_ptr( void ) {         static CPUAnimBitmap*   gBitmap;         return &gBitmap;     }      // static method used for glut callbacks     static void mouse_func( int button, int state,                             int mx, int my ) {         if (button == GLUT_LEFT_BUTTON) {             CPUAnimBitmap*   bitmap = *(get_bitmap_ptr());             if (state == GLUT_DOWN) {                 bitmap->dragStartX = mx;                 bitmap->dragStartY = my;             } else if (state == GLUT_UP) {                 bitmap->clickDrag( bitmap->dataBlock,                                    bitmap->dragStartX,                                    bitmap->dragStartY,                                    mx, my );             }         }     }      // static method used for glut callbacks     static void idle_func( void ) {         static int ticks = 1;         CPUAnimBitmap*   bitmap = *(get_bitmap_ptr());         bitmap->fAnim( bitmap->dataBlock, ticks++ );         glutPostRedisplay();     }      // static method used for glut callbacks     static void Key(unsigned char key, int x, int y) {         switch (key) {             case 27:                 CPUAnimBitmap*   bitmap = *(get_bitmap_ptr());                 bitmap->animExit( bitmap->dataBlock );                 //delete bitmap;                 exit(0);         }     }      // static method used for glut callbacks     static void Draw( void ) {         CPUAnimBitmap*   bitmap = *(get_bitmap_ptr());         glClearColor( 0.0, 0.0, 0.0, 1.0 );         glClear( GL_COLOR_BUFFER_BIT );         glDrawPixels( bitmap->width, bitmap->height, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->pixels );         glutSwapBuffers();     } };

引用 1 楼 luciferisnotsatan 的回复:如果是(int)cleanup， 知道这种是强转么？  (void (*)(void*))cleanup 这个是吧cleanup像转为一个指向一个参数为void*, 返回值为void的函数指针。  void anim_and_exit( void (*f)(void*,int), void(*e)(void*) ) 接受两个函数指针。  google下函数指针你就知道了 我看了C Primer Plus第14章讲到了函数指针，但问题在于：不仅这个例程比书上要复杂，并且函数调用的参数不明：您看： 函数原型： void cleanup( DataBlock *d )  void generate_frame( DataBlock *d, int ticks )  而调用是这样的： bitmap.anim_and_exit( (void (*)(void*,int))generate_frame,   (void (*)(void*))cleanup ); 如此一来，函数cleanup的形参 DataBlock *d， 以及generate_frame函数的形参 DataBlock *d, int ticks都怎么传递值的呢？这和书里面和网上讲解的相差很大……

引用 12 楼 weiran2009 的回复:[quote=引用 5 楼 ri_aje 的回复:] 这是 cuda 改过的 c 语言，(void (*)(void*))cleanup 就是强制类型转换，(...) 里面的是目标类型。 __global__ 还有 <<<...>>> 等都是 cuda 自己的私货，根本不是标准 c 的东西。  想必阁下也是看过《CUDA实战》的GPU前辈吧，我看到main函数开头两句话很有意思：     CPUAnimBitmap  bitmap( DIM, DIM, &data );     //结构体实例data里面有CPUAnimBitmap的数据类型        data.bitmap = &bitmap; // data.bitmap又引用了自己含有引用自己地址的CPUAnimBitmap数据类型bitmap的地址  感觉绕来绕去挺麻烦的，前辈可以指点一二吗？[/quote] 我没看过 cuda 的东西，一直用的 opencl。不过 bitmap <--> data 互指的这种结构很常见，根 cuda 没有直接关系，普通的 c 编程中也能用，这种对偶关系就好像你和你朋友互相知道对方的地址一样，这样找到任何一个就能够比较容易的找到另一个了。

才查两本书就不查了？

楼主可以看一下c陷阱与缺陷。。。


Question: 求一个整数i的二进制

理解和讨论之前请先学会如何观察！

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

itoa 函数

假设一个数字32bit长度，就是从0-31，(1 << j)  这个不就是只有第j位为1，其余都是0，所以((1 << j) & i就可以取出i的第j位


Question: 请问下VC6下载哪个SDK才能编译WINDOWS核心编程第四版的源码？

当然是SDK6啦。


Question: 如何将无符号整形变量的5~7bit 置为二进制的'101'

思路： 让你的这个数 & a 其中a为5到7位是0，其他位全是1 再将结果 & b 其中b是5-7位分别是101，其他位是0

我想应该这样： a = (a & 0xFF1F) | 0x00A0 把这三位先清零 再或上101 不知道还有没有其他更好的法子。。。

仅供参考#include <stdio.h>  #define WIRTE_UINT(des ,x ,pos ,len)  (                                   \     (des)                                                                 \     &                                                                     \        ~(                                /* 除要修改的位为0，其余都为1 */ \             (                                                             \                 (1<<(len))-1             /* 长度为len位的1             */ \             )                                                             \             <<(32-(pos)-(len))           /* 左移32-(pos)-(len)位       */ \         )                                                                 \     |                                                                     \         (                                                                 \             (x)                                                           \             <<(32-(pos)-(len))                                            \         )                                                                 \ ) #define READ_UINT(src ,pos ,len)      (                                   \     (                                                                     \         (                                                                 \             (unsigned)(src)                                               \         )                                                                 \         >>(32-(pos)-(len))               /* 逻辑右移32-(pos)-(len)位   */ \     )                                                                     \     &                                                                     \     (                                                                     \         (1<<(len))-1                     /* 长度为len位的1             */ \     )                                                                     \ )  int main()                              //                1111111111222222222233 {                                       //bit   01234567890123456789012345678901     unsigned int des = 0x661;           //      00000000000000000000011001100001     unsigned int r;      des = WIRTE_UINT(des ,3 ,28 ,2);    //      00000000000000000000011001101101     printf("des==0x%08X\n",des);     r = READ_UINT(des ,28 ,2);     printf("r==%d\n",r);     return 0; } //des==0x0000066D //r==3

引用 2 楼 akirya 的回复:x &= 1010000 呃 写错了。 看 #1

x &= 1010000

可以用mask的方法来做吧，对于UINT变量a a = (a | 0x000000E0) & 0xFFFFFFBF


Question: 求助，有没有什么C/C++的方法，可以直接把数据流程图映射为可执行模块。

LabView、UML、……属于企图使用“图形符号拖拽”代替“纯文本脚本语言”编程的系统。  推荐使用Source Insight软件维护大型（比如源代码超过5万行）项目。

@赵4老师 还是不是很明白呀，可能我层次还不够，完全不知道你说的是什么意思。

请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  意思是你程序结构看上去再合理，再简洁，也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错，更方便修改，出错了更容易找到哪里出错和具体出错的原因，更容易改正错误。  试对比 图书馆（对图书的分类够结构化了吧） 和 搜索引擎（可看作是扁平化任何结构数据，仅支持全文检索） 哪个处理信息更方便、更高效。  所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。  结构越复杂，越难修改，越难除错。 有时（甚至大多数时候），看上去越合理、越简洁的代码，运行起来性能越差，出错时查找原因越难，找到出错原因后改正越费劲。  程序员要做的不是尽力避免错误，而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误，“快速的失败”远胜过“预防错误”。Fred George

再次证明图形符号拖拽式编程是一个神话！


Question: 谁能帮我分析一下下面的红色标注的代码的作用，为什么不要这一段代码会出错，它后面的代码为什么不能够运行下去。如果要运行需要其它的文件吗？

命令行参数个数不是4的时候，后续argv[n]的值都不确定。


Question: “驱动程序提供的例程”这句话中 “例程”具体是什么意思？

驱动提供的API

一段处理程序这个叫法听过没？你可以简单理解为函数调用！由于执行这段程序片不具有进程或线程上下文，因此不能称作进程或线程！

“例菜”是啥意思？

routine: 可理解为函数

routine

可以更简单的理解为一个回调函数.

常用的可供调用的子程序。

相当于接口，或者更形象点，相当于BIOS的中断。

routines的中译吧 没什么特别意思


Question: 请教用汉字替换数字，写好的程序不知道哪里出了问题，求指点

#include "stdafx.h" #include<stdio.h> #include<stdlib.h> #include<cstring> #include"locale"//这个头文件里有setlocale函数 void Convert(wchar_t *a);  int main() { 	setlocale(LC_ALL, "chs");//设置语言为中文，否则文件中存在的中文会变成乱码 	FILE *fp; 	wchar_t str[30]; 	char *p; 	if ((fp = fopen("D:\\file_test.txt", "r")) == NULL){//以只读打开 		printf("打开文件失败!\n"); 		exit(0); 	} 	fgetws(str, 30, fp); 	for (int i = 0; i<30; i++){ 		if (str[i] >= 48 && str[i] <= 57) 		{ 			Convert(&str[i]); 		} 	} 	fclose(fp);  	if ((fp = fopen("D:\\file_test.txt", "w")) == NULL){//以只写打开 		printf("打开文件失败!\n"); 		exit(0); 	} 	fwprintf(fp, str); 	fclose(fp); 	return 0; } void Convert(wchar_t *a) { 	switch (*a){ 	case L'1': 		*a = L'一'; 		break; 	case L'2': 		*a = L'二'; 		break; 	case L'3': 		*a = L'三'; 		break; 	case L'4': 		*a = L'四'; 		break; 	case L'5': 		*a = L'五'; 		break; 	case L'6': 		*a = L'六'; 		break; 	case L'7': 		*a = L'七'; 		break; 	case L'8': 		*a = L'八'; 		break; 	case L'9': 		*a = L'九'; 		break; 	} }

汉字占两个或多个字节，怎么可能直接替换


Question: 网络流量控制

to u011391040 您好  “http://bbs.pediy.com/showthread.php?t=173871” 这个上面貌似没有讲关于流量控制的吧!

网络流量查看比较简单，可以通过winpcap提供的借口或者原始套接字实现，流量控制可以通过ndis驱动或者wpfwang驱动来实现，可以参考http://bbs.pediy.com/showthread.php?t=173871。


Question: 一道算法题 2013蓝桥杯预选赛 地宫取宝的问题

我也遇到相似的情况，希望我的回答对你有帮助


Question: 求大神帮做一个计算器，有点特殊要求都在正文里，麻烦了

引用 4 楼 rourou0618 的回复:67	100	C:\Users\James\OneDrive\Documents\未命名1.cpp	[Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]  第67行有这种错误求解 是warning啦,查查deprecated这个词是什么意思

仅供参考：/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

你去看看编译原理吧，能用到里面的语法分析，推荐用LR(1)来实现，这个能够第一时间发现错误。

我写了一个简单的，那个选作没做，而且就做了大概，但是能用， 代码在 http://www.skysq.com/read-160.html 还是有bug，不想改了


Question: 开心的小明。。。求算法思路，望大神指点一下，谢谢

引用 8 楼 Raffin 的回复:补充下，先根据j1到jk排序 然后计算v1到vk，取最接近价格总和的，如果v1加到v(n-1)超过了价格总和，则跳过v(n-1)，继续累加vn，直到遍历到k。  物品1：重要度3，价格500，乘积1500 物品2：重要度4，价格100，乘积400 物品3：重要度1，价格1000，乘积1000 物品4：重要度4，价格300，乘积1200 物品5：重要度2，价格400，乘积800  排序后是物品1，物品4，物品3，物品5，物品2，假设总价格不能超过1000元。 按照这个排序，价格分别是500元，100元，1000元，300元，400元。 那么最优解就是500+100+300，即900元，也就是物品1，物品4和物品5，重要度*价格乘积最大，达到3500。  我当时做这道题的时候也是这么想的，但是发现实际中不能这么做，因为有可能会出现以下情况： 剩余钱数：1000 物品1：重要度4，价格1000，乘积4000 物品2：重要度5，价格400，乘积2000 物品3：重要度5，价格500，乘积2500 排序应该是物品1>物品3>物品2 按你的方法是购买物品1 但明显应该购买物品3+物品2利益最大  所以还是老老实实应用单纯形法好了。。。

引用 1 楼 user-7 的回复:这不是典型的线性规划吗, 最常用的算法应该是单纯形法 就是这样！

引用 9 楼 qq_25645261 的回复:[quote=引用 8 楼 Raffin 的回复:] 补充下，先根据j1到jk排序 然后计算v1到vk，取最接近价格总和的，如果v1加到v(n-1)超过了价格总和，则跳过v(n-1)，继续累加vn，直到遍历到k。  物品1：重要度3，价格500，乘积1500 物品2：重要度4，价格100，乘积400 物品3：重要度1，价格1000，乘积1000 物品4：重要度4，价格300，乘积1200 物品5：重要度2，价格400，乘积800  排序后是物品1，物品4，物品3，物品5，物品2，假设总价格不能超过1000元。 按照这个排序，价格分别是500元，100元，1000元，300元，400元。 那么最优解就是500+100+300，即900元，也就是物品1，物品4和物品5，重要度*价格乘积最大，达到3500。  我当时做这道题的时候也是这么想的，但是发现实际中不能这么做，因为有可能会出现以下情况： 剩余钱数：1000 物品1：重要度4，价格1000，乘积4000 物品2：重要度5，价格400，乘积2000 物品3：重要度5，价格500，乘积2500 排序应该是物品1>物品3>物品2 按你的方法是购买物品1 但明显应该购买物品3+物品2利益最大  所以还是老老实实应用单纯形法好了。。。[/quote]  是这样的，多谢提醒。 那你看这样行不行，算出重要度/价格最高的，然后排序（也就是性价比最高的）。

从现实角度来看，怎么会有人买个东西弄的这么蛋疼，肯定强迫症患者晚期0.0

引用 6 楼 Raffin 的回复:首选需要对所有物品的重要度*价格的乘积进行排序，由于你并没有明确每样东西的价格和重要度，所以我假设j1到jk是按照重要度*价格降序排列的。 这时问题变成j1到jk要尽可能的多，并且价格总和不能超过某个值（本题里是30000）。 j1到jk要尽可能的多的同时还要压制价格，那么每样东西的数量只可能是1，因为数量多并不能帮助你提升重要度*价格的总和。 这时你只要计算v1+v2+……vn，让他最接近30000就行了（注意这里的v1是j1到jk排序后的j1里的v1）。 好像单样物品价格很高时这么算有问题，加上这件物品价格会超，如果去掉这件物品又不是最优解。希望有高人修正补充。

顶一下

这是01背包吧，多了个要记录选择物品 下午回过一直不成功

百度：“背包问题”。完结。

这不是典型的线性规划吗, 最常用的算法应该是单纯形法


Question: 这个栈销毁代码有没有危险

单处理器下没问题

malloc和free对应才能行。

引用 2 楼 zhao4zhong1 的回复:CPU的内存保护机制对次有例外确保其没有危险。 对此

怎么会不停free的?

保证不会在这个情况做*top的话那没啥问题

CPU的内存保护机制对次有例外确保其没有危险。

栈不是用数组做的吗，为什么还需要循环释放呢，直接找到起始地址 free 一下就行了吧。


Question: 在pthread中，joinable的thread如果不使用thread_join等待其自然结束 占用的资源比使用后少

你创建了PTHREAD_CREATE_JOINABLE的线程，却不用pthread_join.既然不用join就创建detach线程吧。 要joinable线程要调用pthread_join之后才会回收资源。还有一个问题就是你用的pthread的win32版本，可能效果会不一样，它是用windows的线程模型实现的，join等待就需要让线程进入等待状态，会使用内核对象。  最好试试linux的pthread,开多个线程.还是要说一下,joinable本来就是要用来等待的，却不等待，用法本身就有问题。  http://linux.die.net/man/3/pthread_create   Only when a terminated joinable thread has been joined are the last of its resources released back to the system. When a detached thread terminates, its resources are automatically released back to the system: it is not possible to join with the thread in order to obtain its exit status. Making a thread detached is useful for some types of daemon threads whose exit status the application does not need to care about. By default, a new thread is created in a joinable state, unless attr was set to create the thread in a detached state

个人认为, 是否join线程与内存消耗多少没什么关系. 你的实验多多少少说明了这个问题. 我想官方说线程需要join是有原因的,个人在实验C++标准库提供的std::thread类时,发现如果不等线程完成, 就关闭应用, 调试时会弹出错误对话框. 为防止出现这种情况, 我都会detach那些不去等待的线程.


Question: 在解决离散型问题，基本GA和基本PSO算法的比较？

百度搜相关关键字。

请问，pso优化pts算法降低系统峰均比，程序怎么写，跪求大神。万分感激。

引用 5 楼 user-3 的回复:[quote=引用 4 楼 u013599381 的回复:] [quote=引用 1 楼 user-3 的回复:] 我研究过, 1.GA是比较复杂的，PSO相对简单 2.PSO可能陷入局部最优（特别是对于多峰函数），GA能找到全局最优。 3.PSO收敛速度会快一些，毕竟它简单，不像GA要交叉、变异 综合以上，推荐你好好研究GA-PSO，将交叉和变异的思想引入到PSO中，这样能综合两者的优点！  谢谢亲~这么详细的介绍~现在在研究一个和TSP相近的离散组合优化问题，初试PSO算法，加入了交叉操作，却发现多次迭代得出的结果还不如GA，特别容易陷入局部最优。按编的情况来说，原以为pso是该更快更好的得到结果的。。。所以很困惑……看来初学者还有很长的路要走啊！[/quote] PSO就是能容易陷入局部最优，有个好的粒子找到最好解后，大家都往它那儿跑。。所以就容易陷入。 可以有3种混合思想来改进 1.混沌粒子群 2.免疫粒子群 3.遗传粒子群（交叉可以采用实数交叉，把变异也一起引入，这样效果会大大改变）[/quote]  谢啦~这三种思想会尝试加入的！继续研究和实验，以后再和您交流啦~

引用 4 楼 u013599381 的回复:[quote=引用 1 楼 user-3 的回复:] 我研究过, 1.GA是比较复杂的，PSO相对简单 2.PSO可能陷入局部最优（特别是对于多峰函数），GA能找到全局最优。 3.PSO收敛速度会快一些，毕竟它简单，不像GA要交叉、变异 综合以上，推荐你好好研究GA-PSO，将交叉和变异的思想引入到PSO中，这样能综合两者的优点！  谢谢亲~这么详细的介绍~现在在研究一个和TSP相近的离散组合优化问题，初试PSO算法，加入了交叉操作，却发现多次迭代得出的结果还不如GA，特别容易陷入局部最优。按编的情况来说，原以为pso是该更快更好的得到结果的。。。所以很困惑……看来初学者还有很长的路要走啊！[/quote] PSO就是能容易陷入局部最优，有个好的粒子找到最好解后，大家都往它那儿跑。。所以就容易陷入。 可以有3种混合思想来改进 1.混沌粒子群 2.免疫粒子群 3.遗传粒子群（交叉可以采用实数交叉，把变异也一起引入，这样效果会大大改变）

引用 1 楼 user-3 的回复:我研究过, 1.GA是比较复杂的，PSO相对简单 2.PSO可能陷入局部最优（特别是对于多峰函数），GA能找到全局最优。 3.PSO收敛速度会快一些，毕竟它简单，不像GA要交叉、变异 综合以上，推荐你好好研究GA-PSO，将交叉和变异的思想引入到PSO中，这样能综合两者的优点！  谢谢亲~这么详细的介绍~现在在研究一个和TSP相近的离散组合优化问题，初试PSO算法，加入了交叉操作，却发现多次迭代得出的结果还不如GA，特别容易陷入局部最优。按编的情况来说，原以为pso是该更快更好的得到结果的。。。所以很困惑……看来初学者还有很长的路要走啊！

第一张图是GA-PSO的。。

基于GA-PSO算法求解TSP问题的最短总距离为463.6541km,而用GA求解最短总距离为624.7155km，距离缩短了161.0614km,进而缩短了交通的费用，从而我们可以知道GAPSO算法比GA算法的寻优能力更强，所找到的解更好； 其次，我们从两个图的最终规划路线果来看，发现GA-PSO算法规划的路线比较平稳，没有特别长的路线，而在GA规划的路线中，发现了好几条较长的路线，并且路线之间的交叉是有好几个，然后GA-PSO只有一个，这就说明了，GA-PSO所找到规划路线，远远优胜于GA规划的路线。


Question: 为什么窗口总是不显示？

楼主是叫大家帮他猜一猜. 我猜:代码内部是不是出现死循环了!

无图无真相，没码没办法； 求看看具体代码。

请查看窗口的消息响应函数的执行出现了问题。我想应该是这样的。。。

把代码发来看看

Setting a Breakpoint on a Message Received by a Windows Function You can set message breakpoints to stop the debugger when a particular WndProc function message is received.  Note   Message breakpoints work only on x86- or Pentium-based systems.  To set a breakpoint on a message   From the Edit menu, click Breakpoints.  The Breakpoints dialog box appears.  Click the Messages tab.   In the Break At WndProc text box, type the name of the Windows function.  If you are setting a breakpoint during a debug session, the list contains the exported functions in your project.   In the Set One Breakpoint For Each Message To Watch list box, select the message.   To set another breakpoint, press ENTER, and then repeat steps 3 and 4.  The Breakpoints list displays the currently active breakpoints.  Click OK to set the breakpoints.  Note If you interrupt execution while Windows or other system code is running, the results can be unpredictable.


Question: 请求告知这个警告的原因

没写强转，就是隐式转换。但从字符指针到整数的隐式转换，将产生警告。

#include <stdio.h>  int main() { 	int i; 	int n=0; 	char s[20]="3264"; 	for (i = 0;s[i] && s[i] >= '0' && s[i] <= '9'; ++i) 		n = n * 10 + (s[i] - '0'); 	printf("%d", n); 	return 0; }

好奇异的程序 数组s未初始化； 对数组成员进行诡异的赋值

s[20] = "3264"; s[20]只是一个字符的位置，而且还是越界的，你赋值给它一个字符串是要闹哪样？

数组不能整体赋值，具体请看三楼，还有其他的回答。 编译应该会出错，不是警告。

s[20] = ’3‘（单引号），这样才是正确的，因为第每一个元素是char型的  另外，s[20]是指的里面的21个元素，而你的申请的s只有20个元素，从s[0]到s[19]  如果想复制字条串，用strcpy_s  如果觉得麻烦，建议用标准模板库里的string，这样就非常方便了

char s[20]; s[20] = "3264";  越界了。而且s[20]是char类型，却赋了个字符串给它。  如果你想复制字符串的话，用strcpy

如果楼主弄明白了，请告诉我一声，顺便也给点分。

int main(void) {     int n, i; 	char s[] = {'3','6','2','4'};      n = 0;     for (i = 0; s[i] >= '0' && s[i] <= '9' ; ++i)         n = n * 10 + (s[i] - '0');     printf("%d", n);  	system("pause");     return 0; } 你看这样行不

char s[20]="3264";  //数组的初始化语句应该是这样，不能分开变成你代码里的两条语句。


Question: 大哥们来练手吧


Question: 大家新年快乐,有个问题请教一下

http://bbs.csdn.net/topics/380157851       if(!(strcmp(DataMark,"00010000"))) {_cls();putstr("dd1");_bioskey(0); recordno = 0; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00010100"))) {                                  recordno = 0; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00010200"))) {                                  recordno = 0; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00010300"))) {                                  recordno = 0; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00010400"))) {                                  recordno = 0; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00150000"))) {                                  recordno = 0; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00290000"))) {                                  recordno = 0; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"003D0000"))) {                                  recordno = 0; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00020000"))) {_cls();putstr("dd2");_bioskey(0); recordno = 1; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00020100"))) {                                  recordno = 1; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00020200"))) {                                  recordno = 1; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00020300"))) {                                  recordno = 1; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00020400"))) {                                  recordno = 1; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00160000"))) {                                  recordno = 1; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"002A0000"))) {                                  recordno = 1; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"003E0000"))) {                                  recordno = 1; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00050000"))) {_cls();putstr("dd3");_bioskey(0); recordno = 2; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00050100"))) {                                  recordno = 2; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00050200"))) {                                  recordno = 2; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00050300"))) {                                  recordno = 2; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00050400"))) {                                  recordno = 2; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00190000"))) {                                  recordno = 2; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"002D0000"))) {                                  recordno = 2; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00410000"))) {                                  recordno = 2; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00060000"))) {_cls();putstr("dd4");_bioskey(0); recordno = 3; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00060100"))) {                                  recordno = 3; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00060200"))) {                                  recordno = 3; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00060300"))) {                                  recordno = 3; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00060400"))) {                                  recordno = 3; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"001A0000"))) {                                  recordno = 3; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"002E0000"))) {                                  recordno = 3; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00420000"))) {                                  recordno = 3; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00070000"))) {_cls();putstr("dd5");_bioskey(0); recordno = 4; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00070100"))) {                                  recordno = 4; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00070200"))) {                                  recordno = 4; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00070300"))) {                                  recordno = 4; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00070400"))) {                                  recordno = 4; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"001B0000"))) {                                  recordno = 4; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"002F0000"))) {                                  recordno = 4; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00430000"))) {                                  recordno = 4; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00080000"))) {_cls();putstr("dd6");_bioskey(0); recordno = 5; fieldno  =  0; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00080100"))) {                                  recordno = 5; fieldno  =  1; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00080200"))) {                                  recordno = 5; fieldno  =  2; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00080300"))) {                                  recordno = 5; fieldno  =  3; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00080400"))) {                                  recordno = 5; fieldno  =  4; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"001C0000"))) {                                  recordno = 5; fieldno  =  9; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00300000"))) {                                  recordno = 5; fieldno  = 10; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"00440000"))) {                                  recordno = 5; fieldno  = 11; len = 10; KKflag = 1;} else if(!(strcmp(DataMark,"04000401"))) {_cls();putstr("dd7");_bioskey(0); recordno = 0; fieldno  = 12; len = 12; KKflag = 1;} else if(!(strcmp(DataMark,"04000402"))) {                                  recordno = 0; fieldno  = 13; len = 12; KKflag = 1;} else if(!(strcmp(DataMark,"04000403"))) {                                  recordno = 0; fieldno  = 14; len = 50; KKflag = 1;} else                                    {                                                                         KKflag = 0;}

我记得有个玩意儿叫数据库。

看程序的人都已经崩溃了。

谢谢user-4 确实屏蔽下面一段就没事.......... 如果要改,怎样改好呢?

1) 应该不是else if本身的问题. 2) 你的程序应该改改,这样写程序会让很多人崩溃.


Question: 关于switch的循环，求帮助

引用 2 楼 neverthinkaboutit 的回复:如楼上的... while(1)		 //永真循环 { 	scanf("%d", &choose);			//接受输入数据 	if(choose > 5 || choose < 0)		//判断输入是否合法 	{ 		printf("input error, please input again.!");		 		continue;		//本次结束，进入下次循环，再输入 	} 	switch(choose) 	{ 		case 0:return 0;		//如果为零则退出,结束输入，结束条件 		case 1:... 		case 2:... 			... 		default:... 	} } 好的我试试，谢谢

引用 1 楼 a1193561652 的回复:do {     scanf(...);     switch(choose);     case...     case...     case... }while(choose>5)试试do...while循环。 好的，我试试，谢谢。

用goto语句应该也可以把


Question: 谁帮我看一下，错在哪，谢谢

不知道。只知道这个                    执行部分—loop函数 **********************************************************/ void setup（） {   loop函数呢。。。

不清楚，我看不出来


Question: 使用Loadimage出现问题，找了很长时间，求解答

easyx难道没有自带的使用函数loadimage的例子代码供码农们参考吗？

还是有问题，请大神们帮着再看一下

#include"stdafx.h"  #include <graphics.h> #include<conio.h>   void main() { 	user-3(330,455); 	setbkcolor(BLACK); 	cleardevice();  	loadimage(NULL,D:\\1.jpg,330,455,false);  	getch(); 	closegraph();  }   正在编译... 1>022300.cpp 1>e:\程序\022300\022300\022300.cpp(14) : error C2065: “D”: 未声明的标识符 1>e:\程序\022300\022300\022300.cpp(14) : error C2143: 语法错误 : 缺少“)”(在“:”的前面) 1>e:\程序\022300\022300\022300.cpp(14) : error C2017: 非法的转义序列 1>e:\程序\022300\022300\022300.cpp(14) : error C2017: 非法的转义序列 1>e:\程序\022300\022300\022300.cpp(14) : error C2059: 语法错误 : “数字上的错误后缀” 1>e:\程序\022300\022300\022300.cpp(14) : error C2059: 语法错误 : “)” 1>生成日志保存在“file://e:\程序\022300\022300\Debug\BuildLog.htm” 1>022300 - 6 个错误，0 个警告 ========== 生成: 成功 0 个，失败 1 个，最新 0 个，跳过 0 个 ==========

HBITMAP hbitmap; hbitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),"图片/aa.bmp",IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);  参数分别表示:     HINSTANCE---------包含所需要图片的实例的句柄。     LPCSTR--------------图片所在路径及文件名。     UINT-------------------图片类型。     int-----------------------图片宽度。     int-----------------------图片高度。     UINT-------------------load flags

LoadImage The LoadImage function loads an icon, cursor, or bitmap.  HANDLE LoadImage(   HINSTANCE hinst,   // handle of the instance containing the image   LPCTSTR lpszName,  // name or identifier of image   UINT uType,        // type of image   int cxDesired,     // desired width   int cyDesired,     // desired height   UINT fuLoad        // load flags );   Parameters hinst  Handle to an instance of the module that contains the image to be loaded. To load an OEM image, set this parameter to zero.  lpszName  Handle to the image to load.  If the hinst parameter is non-NULL and the fuLoad parameter does not include LR_LOADFROMFILE, lpszName is a pointer to a null-terminated string that contains the name of the image resource in the hinst module.   If hinst is NULL and LR_LOADFROMFILE is not specified, the low-order word of this parameter must be the identifier of the OEM image to load. The OEM image identifiers are defined in WINUSER.H and have the following prefixes: Prefix Meaning  OBM_ OEM bitmaps  OIC_ OEM icons  OCR_ OEM cursors     If the fuLoad parameter includes the LR_LOADFROMFILE value, lpszName is the name of the file that contains the image.   uType  Specifies the type of image to be loaded. This parameter can be one of the following values: Value Meaning  IMAGE_BITMAP Loads a bitmap.  IMAGE_CURSOR Loads a cursor.  IMAGE_ICON Loads an icon.    cxDesired  Specifies the width, in pixels, of the icon or cursor. If this parameter is zero and the fuLoad parameter is LR_DEFAULTSIZE, the function uses the SM_CXICON or SM_CXCURSOR system metric value to set the width. If this parameter is zero and LR_DEFAULTSIZE is not used, the function uses the actual resource width.  cyDesired  Specifies the height, in pixels, of the icon or cursor. If this parameter is zero and the fuLoad parameter is LR_DEFAULTSIZE, the function uses the SM_CYICON or SM_CYCURSOR system metric value to set the height. If this parameter is zero and LR_DEFAULTSIZE is not used, the function uses the actual resource height.  fuLoad  Specifies a combination of the following values: Value Meaning  LR_DEFAULTCOLOR The default flag; it does nothing. All it means is "not LR_MONOCHROME".  LR_CREATEDIBSECTION When the uType parameter specifies IMAGE_BITMAP, causes the function to return a DIB section bitmap rather than a compatible bitmap. This flag is useful for loading a bitmap without mapping it to the colors of the display device.  LR_DEFAULTSIZE Uses the width or height specified by the system metric values for cursors or icons, if the cxDesired or cyDesired values are set to zero. If this flag is not specified and cxDesired and cyDesired are set to zero, the function uses the actual resource size. If the resource contains multiple images, the function uses the size of the first image.   LR_LOADFROMFILE Loads the image from the file specified by the lpszName parameter. If this flag is not specified, lpszName is the name of the resource.  LR_LOADMAP3DCOLORS Searches the color table for the image and replaces the following shades of gray with the corresponding 3D color:    Color Replaced with   Dk Gray,  RGB(128,128,128) COLOR_3DSHADOW   Gray,  RGB(192,192,192) COLOR_3DFACE   Lt Gray,  RGB(223,223,223) COLOR_3DLIGHT   LR_LOADTRANSPARENT Retrieves the color value of the first pixel in the image and replaces the corresponding entry in the color table with the default window color (COLOR_WINDOW). All pixels in the image that use that entry become the default window color. This value applies only to images that have corresponding color tables.  If fuLoad includes both the LR_LOADTRANSPARENT and LR_LOADMAP3DCOLORS values, LRLOADTRANSPARENT takes precedence. However, the color table entry is replaced with COLOR_3DFACE rather than COLOR_WINDOW.   LR_MONOCHROME Loads the image in black and white.  LR_SHARED Shares the image handle if the image is loaded multiple times. If LR_SHARED is not set, a second call to LoadImage for the same resource will load the image again and return a different handle. Do not use LR_SHARED for images that have non-standard sizes, that may change after loading, or that are loaded from a file.  Windows 95 and Windows 98: The function finds the first image with the requested resource name in the cache, regardless of the size requested.   LR_VGACOLOR Uses true VGA colors.    Return Values If the function succeeds, the return value is the handle of the newly loaded image.  If the function fails, the return value is NULL. To get extended error information, callGetLastError.  Remarks When you are finished using the bitmap, cursor, or icon, you can release its associated memory by calling one of the functions in the following table.   Resource Release function  Bitmap DeleteObject  Cursor DestroyCursor  Icon DestroyIcon    The system automatically deletes these resources when the process that created them terminates, however, calling the appropriate function saves memory and decreases the size of the process's working set.   Windows CE: The cxDesired and cyDesired parameters must be zero for IMAGE_BITMAP.   Windows CE does not support stretching and shrinking of icons.   The fuLoad parameter must be zero (==LR_DEFAULTCOLOR).   If you are targeting a platform that does not support mouse cursors, you cannot specify the SM_CXCURSOR and SM_CYCURSOR values in the cxDesired and cyDesired parameters, and you cannot specify IMAGE_CURSOR for the uType parameter.  If you are targeting a platform that supports mouse cursors, you can specify SM_CXCURSOR and SM_CYCURSOR in the cxDesired and cyDesired parameters, and IMAGE_CURSOR in the uType parameter.   QuickInfo   Windows NT: Requires version 4.0 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT.  See Also Resources Overview, Resource Functions, CopyImage,GetSystemMetrics,LoadBitmap, LoadCursor, LoadIcon

写文件路径字符串 类似  "C:\\Windows\\web\\bliss.m\bmp"


Question: 下面这段代码，为什么保存后，再读取，除了最后一个录入的其他都是乱码。

虽然没能解决我的问题，还是谢谢各位的回答，以下是我在网上找来的答案，希望能给其他有类似问题的提供参考： void open_file(struct book *arr,char *p)//打开文件 { while(count<BOOKS&&fread(arr+count,sizeof(struct book),1,fp)==1) count++; }

楼主添加几个记录，然后打开相应的文件查看，看看里面的内容，我打开之后就出现乱码 （我是换了一下头文件，让程序运行，"stdjar.h"哪有？） 之前也写了一个类似这样的程序，也出现过这个问题。 请楼主细心看看，对比一下： 1.写入一个或几个记录，保存退出，打开看看文件中的记录是什么样的 2.再次运行，再添加一个或几个记录，保存，对比文件中的记录格式是不是一致 我写的那个是读取文件记录多了一个'\n',导致格式不一致，然后就乱码了！

引用 2 楼 zhao4zhong1 的回复:推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 fopen(...,"wb"); fseek fwrite fclose  fopen(...,"rb"); fseek fread fclose我感觉也是这个读取和写入有问题，这位老师的回答我也能大概看明白，可是写不出来，新手对fseek不是很了解，望大神能把这两个代码写出来，万分感谢。


Question: void loadimage(IMAGE *,LPCTSTR,int,int,bool）

表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串

如果你的工程是多字节字符集，LPCTSTR就是const char * 如果你的工程是Unicode字符集，LPCTSTR就是const wchar_t * 总之这个参数就是需要传入一个字符串的意思


Question: 问几个算法复杂度的问题

引用 4 楼 FancyMouse 的回复:>其实这些定理是不是在离散数学里面说明的 不是。本身是解析数论的东西，但是这几个结论直接拿来用就是了。  >至于那个原文。。。就是我一开始说的那个几句话- - 你转述的就已经不是原文了。  引用 4 楼 FancyMouse 的回复:>其实这些定理是不是在离散数学里面说明的 不是。本身是解析数论的东西，但是这几个结论直接拿来用就是了。  >至于那个原文。。。就是我一开始说的那个几句话- - 你转述的就已经不是原文了。     这是原文。。。。不知道中文版的翻译有没有跑偏。。。

引用 2 楼 FancyMouse 的回复:>比如：Eratosthenes的算法为什么时间复杂度是NloglogN? 筛是因为n(1/2+1/3+1/5+1/7+...)，里面是所有质数的倒数和。这个有Mertens定理说括号里是O(loglogn)的（而且是确界）。  >为什么要这样表示呢 因为就是那个结果  >难道在算法分析的情况中，这种情况不用分类讨论的吗？ 你原来那个题不看原文不好说。但是一般做算法的时候只看数据足够大的时候的表现。  >怎么才能更好地学好算法分析呢？ 静下心来看数学，不要忘了写代码。  额，其实这些定理是不是在离散数学里面说明的，但是我不是一名计算机专业的学生，是不是要先学离散数学学这些就快一点的？至于那个原文。。。就是我一开始说的那个几句话- -，我也摸不着头脑

学一学数学。


Question: 请教一下各位学习C语言的平台问题？

用VS当然比较好

我都试过,还是推荐vc++ 2010

引用 3 楼 hxl199109 的回复:vc++ 6.0 版本有点老，开始还是挺适合的，VS太大了，是集成了多种开发语言的IDE，还是比较 方便的 谢谢推荐。

引用 2 楼 zhao4zhong1 的回复:http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装 谢谢老师的回答

引用 1 楼 user-5 的回复:gcc 或 clang 吧。 另外 c++ 和 c 不是先后关系，如果你的最终目的是学 c++，不需要先学 c 的，实际上不学可能反而更好一些。 感谢回答。


Question: return之后，函数里的语句还要继续执行吗？

return (*p)++;  == int res = *p; (*p)++; return res;

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

执行了，这个语句就是return的一部分。但return语句之后（也就是分号以后）的语句则不再执行。

无论软硬件，后门是肯定有的，斯若登都知道。  所以有自主论！

引用 18 楼 u013585046 的回复:CPU、编译器、调试器也不能迷信，眼睛有时也会欺骗人！  真相是如此扑朔迷离， 所以有远见卓识的人就更显珍贵！ 不可知论！

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

因为return (*p)++; 是一个语句，编译器会把这个语句翻译成多行汇编代码，所以这些汇编代码会整体执行。 相当于是把 *p 的值放到寄存器中返回（返回值通常放到寄存器中），然后把原来内存地址中对应的值自增1。如果你想利用这个自增的值，你只能用*p来取得，而不能从寄存器的返回值中取，因为返回值是原来的值。

会的，具体自己写个程序试一下就知道了！！

会执行的！ ++在return之前完成的

补充一下：  楼主可以看一下这篇经典的文章：http://bbs.csdn.net/topics/370153775  里面提到了像++这种运算符产生的作用什么时候体现出来

这个问题不用纠结，直接一个跨号就解决了

函数返回的值是*p的值。 同时， 传入的参数值会加1. int param = 10; int res = fun(¶m); 结果是res = 10, param = 11; 可以尝试一下。

扑哧…… ++什么时候成了语句

++会在分号之前完成，会执行的

当然会执行了

会执行的，如楼上的回答。 语句：return (*p)++; (*p)++是一个表达式，其值为(*p)，执行完++操作了，将（*p）的值返回。 一个小例程测试一下 #include <stdio.h>  int fun(int *p) { 	return (*p)++; }  int main() { 	int x = 1; 	int y = fun(&x); 	printf("x = %d,y = %d\n", x, y); 	return 0; }

会的，具体自己写个程序试一下就知道了！！

执行的，因为会执行完return的整条语句，楼主可以写了测试一下，看*p的值有没变化就知了

会执行到分号


Question: C语言中的linked list segmentation fault求教

参考代码： http://pan.baidu.com/s/17yIcQ

再定义一个 node* previous = nullptr，每次 current = current->next 之前，让 previous = current。当 current 满足条件时，此时的 previous 就是提供插入位置的节点。 不知道 insertNode 是怎么调用的，一般都是接受链表头节点指针吧，这样 lptr 应该是 node* 才对，不需要二重指针。  free 是释放资源，要是能确定资源确实不需要了，就可以释放。主楼的这个插入函数，插入链表的节点明显要活的比插入函数本身长才行，肯定不能再函数退出前释放掉的。

你的逻辑比较混乱。 //如果当前结点数据的next data比d大，在当前结点之后加入         if ((*current)->next->data >= d)         {             newnode->next = (*lPtr)->next;             (*current)->next = newnode;             break;         }  这部分如果current是空 或者current->next为空，就segmentation fault，使用前要先判断是否为空     free(newnode)  你刚才为节点申请的内存，最后释放了，那插入链表中的节点，以后访问就是非法访问了

多谢回复。 针对您提的第二个问题， 如果是在当前指针判断，那么如何在当前指针使用时调用上一个指针的next（我是不会用才这样的）？另外我不确定×lptr和current的用法是否重复。。最后的free的话，函数结束了难道不该free吗？  我C语言只接触了一个月，因为时间关系基础不怎么好。以前会点Python。现在看到指针啊，malloc什么的头都是大的。。

链表为空的时候，current 应该是 null 吧，循环直接访问其数据不就挂了吗。  free(newnode); 以后新建的节点就不存在了，不是白插入了吗。 楼主的插入逻辑有点奇怪，总是用当前节点的下一个节点来判断，多此一举啊，直接用当前节点判断同时保持上一个节点指针多好啊。


Question: 关于C语言中指针变量的命名及赋值的问题

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

顶楼上的，楼主可以看看！

参考一下——http://blog.csdn.net/u012421456/article/details/20296865  ——http://blog.csdn.net/u012421456/article/details/21803797


Question: gets()函数疑问

引用 3 楼 user-2 的回复:楼上的兄弟，我觉得楼主理解的没啥问题。反而是你说了一大通没听明白你到底在说什么。。。  You are fucking right,我错了,楼主想得对

就算char *p之后不远处真有个'\0'字符,之前读到的内容也都是垃圾值,char *p的第一个字符是字符串'abc'的地址而不是字符'a'. char p[40]就不同,40个单元里面存的是确确实实的字符'abc'等

gets(p)表示从p的地址开始读取字符直到遇到'\n'为止,然后gets(p)函数会把换行符替换成'\0' 如果你这样写 char * p="abc"; 那么指针p的内容是字符串'abc'的地址,之后能不能遇到换行符全凭运气,所以是行不通的,虽然gets()的原型是 char * gets(char * s) 但并不是说指针p可以随便声明,char *p和char p[40]的区别在这道题上就体现出来了 char *p与char p[40]既有相同点又有不同之处


Question: 无法解析的外部命令，看看我这缺的是什么.lid

新建的时候，我就设置为win32项目——控制台应用程序——在向导里点的是空项目——然后新建了c++文件

不知道楼主新建工程时的工程设置是啥，该代码在控制台下测试能输出正确结果，应该是你工程设置或者编译环境的问题

无法解析的什么命令，为什么不写完整。 估计是工程类型没设对


Question: 数组方面的一个程序问题，求指导？

感谢指导，还要自己多去思考才行。。。。 学的太死了。。

*(*board + i)和**board+i是一样的吧，都是先board+1然后在**。

兄弟，你知道数组和指针的区别吗?你的根本问题在这里。 数组不是指针。你弄明白这句话就懂了，不要求答案，自己证明的才是自己的。

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

**board就是board[0][0]，也就是1啊。。。 书上的原话真是lz说的那样？- -

楼主不妨试下输出**board的值，该值是数组中第一个元素的值，也就是1 把这个值放到循环中，加上i的值（i=0,1,2,3,4,5,6,7,8） 就会得到（board:1,2,3,4,5,6,7,8,9）

这样是可以的啊。  #include <stdio.h> int main(void) { 	char board[3][3] = { 		{'1', '2', '3'}, 		{'4', '5', '6'}, 		{'7', '8', '9'} 	}; 	 	 	for(int i = 0; i < 9; i++) 		printf("board: %c\n", **board + i); 	return 0; }


Question: 编译通过但是无输出？

1.if判断中的等号不对 2.数组的数组名就是数组的地址，为什么要再申请数组的指针呢？ 3.s[0]只是一个字符，用%c格式输出