Mxode/CSDN-C_Language-2013_2023 huggingface dataset:
user-0 提问: C语言函数作用域问题？

回复:
user: user-1
content: 楼主说的是对着，自己也可以验证下：  #include <stdio.h> #include <iostream> using namespace std; void sum(int a, int b) { 	int i = 15; 	int j = 20; 	a = i; 	b = j; 	printf("%x\n",&a); 	printf("%x\n",&b); 	printf("\n*********************\n"); 	cout<<&a<<endl; 	cout<<&a<<endl;  	printf("sum函数的地址：%x\n",sum); 	cout<<sum<<endl; 	return; } int main(void) { 	int a = 5; 	int b = 10; 	printf("%x\n",&a); 	printf("%x\n",&b); 	printf("\n*********************\n"); 	cout<<&a<<endl; 	cout<<&b<<endl; 	sum(a, b); 	printf("\n*********************\n"); 	cout<<sum<<endl; 	return 0; }

user: user-2
content: 单步跟踪加深理解函数调用栈的原理

user: user-3
content: 你的理解是正确的。

user: user-4
content: 第一，肯定不一样！函数中的变量作用域都只到函数结束，调用时开辟空间，调用完释放！还有你这个函数是没有意义的，采用值传递时，实参只是传递了一个副本给形参，对实参ab没有任何影响！！除非采用指针地址传值或者引用传值（c++）

user: user-5
content: 主函数和sum函数中的变量a和变量b，他们的地址不一样 在函数定义的非静态变量是存在栈区的，函数结束这部分内存被free， 这些变量的作用域是在函数内
user-0 提问: C语言指针问题？

回复:
user: user-1
content: 引用 5 楼 ruying1389279 的回复:[quote=引用 1 楼 q3733353520 的回复:]  int *q;//定义的时候没有初始化，指向的区域（指针本身的值）是未知的 i=5 *q= i//把5存储(赋值)到q指向的内存 printf("%d",*q);打印q指向的内存中存储的值  这样不是业指针吗？好奇的是编译器能通过编译。[/quote] 野指针是指，指针指向了不该指向的区域，当你定义这个指针值的时候，系统会给你分配一块内存来存储它，如果你不初始化，那么它的值就是系统分配给你时这块内存原本的值，它有可能是野指针，有可能不是

user: user-0
content: 看来是这个IDE的问题

user: user-2
content: 6 楼 是正确 的 我在 gcc 上也测试过

user: user-3
content: 我在VS2010上试了下，楼主那样是不能运行的，指针q没有赋值，是个野指针…… 必须先赋地址值。  #include <stdio.h>  int main(void) { 	int *q; 	int i = 5; 	//*q = i; 	q = &i; 	printf("%d\n",*q); 	return 0; }

user: user-0
content: 引用 1 楼 q3733353520 的回复: int *q;//定义的时候没有初始化，指向的区域（指针本身的值）是未知的 i=5 *q= i//把5存储(赋值)到q指向的内存 printf("%d",*q);打印q指向的内存中存储的值  这样不是业指针吗？好奇的是编译器能通过编译。

user: user-4
content: 哈哈，有些事，做了不一定错，但总是这样做，一定会出错。

user: user-5
content: 目测lz打开了优化, 编译器优化后就没问题了

user: user-6
content: 为啥不可以运行？楼上正解

user: user-1
content: int *q;//定义的时候没有初始化，指向的区域（指针本身的值）是未知的 i=5 *q= i//把5存储(赋值)到q指向的内存 printf("%d",*q);打印q指向的内存中存储的值
user-0 提问: 关于直接访问内存地址值

回复:
user: user-1
content: rw从给定的地址中读取内存的值，你用的winio库里的哪个函数啊

user: user-1
content: 引用 11 楼 zhao4zhong1 的回复:https://www.baidu.com/s?wd=WinIO.sys%2064%E4%BD%8D&rsv_spt=1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_t=1792P3lllds0nXKvBKyge625umfFkufwxZUgnvIfDofMukDFdTJBasHwLC0o5u0vklJp&oq=WinIO.sys%E6%9C%8964%E4%BD%8D%E7%89%88%E7%9A%84%E5%90%97%3F&rsv_pq=f0e5a027000054a2&rsv_sug3=4&inputT=23330&rsv_sug4=23330  PBYTE pbLinAddr; HANDLE PhysicalMemoryHandle; pbLinAddr = MapPhysToLin(0xA0000, 65536, &PhysicalMemoryHandle); 该函数将把物理地址范围为0xA0000 - 0xAFFFF的地址空间映射到与应用程序对应的线性地址空间。 返回值为一个与物理地址0xA0000相关的线性地址。如果出现错误，则返回值为NULL。 为什么上面列子MapPhysToLin第一个参数就报错了啊

user: user-0
content: 感谢各位的回复，winio已经可以成功读取到物理地址的值了，稍后会更新上DEMO

user: user-2
content: 什么系统, 做什么用的

user: user-3
content: 你要读物理地址？

user: user-4
content: 嵌入汇编代码是比较本质的方法吧。

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:使用WinIO.sys？  谢谢赵老师提供的，我去看看文档先 ：）

user: user-5
content: 使用WinIO.sys？

user: user-5
content: https://www.baidu.com/s?wd=WinIO.sys%2064%E4%BD%8D&rsv_spt=1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_t=1792P3lllds0nXKvBKyge625umfFkufwxZUgnvIfDofMukDFdTJBasHwLC0o5u0vklJp&oq=WinIO.sys%E6%9C%8964%E4%BD%8D%E7%89%88%E7%9A%84%E5%90%97%3F&rsv_pq=f0e5a027000054a2&rsv_sug3=4&inputT=23330&rsv_sug4=23330

user: user-2
content: 引用 7 楼 nice_fish 的回复:[quote=引用 5 楼 fly_dragon_fly 的回复:] 什么系统, 做什么用的  是这样的一个需求，比较预设的GPIO的值和实际值是否有出入  而GPIO的值是存在内存中的，所以需要从内存地址中读取相应的值出来然后做后续的比较[/quote]不太明白是什么地址, 那地址看起来是64位的, 如果是物理地址, 算起来有19G的,你内存有那么大吗

user: user-5
content: WinIo.h：#ifndef WINIO_H #define WINIO_H  #ifdef WINIO_DLL #define WINIO_API _declspec(dllexport) #else #define WINIO_API _declspec(dllimport) #endif  extern "C" {   WINIO_API bool _stdcall InitializeWinIo();   WINIO_API void _stdcall ShutdownWinIo();   WINIO_API PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle);   WINIO_API bool _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr);   WINIO_API bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);   WINIO_API bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);   WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);   WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);   WINIO_API bool _stdcall InstallWinIoDriver(PSTR pszWinIoDriverPath, bool IsDemandLoaded = false);   WINIO_API bool _stdcall RemoveWinIoDriver(); }  extern bool IsNT; extern HANDLE hDriver; extern bool IsWinIoInitialized;  bool _stdcall StartWinIoDriver(); bool _stdcall StopWinIoDriver();  #endif

user: user-0
content: 引用 4 楼 adlay 的回复:你要读物理地址？   我用的软件是：RwPortableX64V1.6.7   这个当前显示应该就是物理内存的实际值吧？

user: user-0
content: 引用 5 楼 fly_dragon_fly 的回复:什么系统, 做什么用的  是这样的一个需求，比较预设的GPIO的值和实际值是否有出入  而GPIO的值是存在内存中的，所以需要从内存地址中读取相应的值出来然后做后续的比较

user: user-6
content: c语言和汇编都可以解决
user-0 提问: Ｃ程序运行崩溃，面试题，求大神解释

回复:
user: user-1
content: char类型只能存储一个字符

user: user-2
content: 使用了非法内存，你只有一个字符（1B）是申请的，可以合法使用，而后面你使用了多个空间，因此崩溃！

user: user-3
content: 内存没有分配

user: user-4
content: 只分配一个字节，空间不足，应该这样修改：  #include<stdio.h>  int main() {     char a[10];     char* str = (char*)a;      strcpy(str, "hello");     puts(str);      return 0; }

user: user-5
content: 你的str指向了a，a只有一个字节，.....溢出了，可能出错也可能不出错，

user: user-6
content: 程序 正常运行，就打印一个'\0'；

user: user-7
content: 多看看基础知识

user: user-8
content: 你只申请了一个字节，却想使用这一个字节的位置放5个字节，当然不可以

user: user-9
content: 越界、越界、越界！

user: user-10
content: 另外，这里的main函数也是被其它的函数调用的，至于是什么函数LZ就别管了，这个和操作系统相关。

user: user-10
content: 这是一个典型的栈溢出问题。  C语言运行时内存分为2块，堆内存和栈内存。所有的函数在发生调用关系时，会自动在栈内存上进行展开，就是生成一些数据，我们称之为上下文，展开的地址顺序很奇怪，是由高址向低地址空间展开的。  运行时发生函数调用时，栈上会存放一些数据，这些数据分为2个部分。在这里，你可以认为函数调用就是一个超级版本的goto语句，它跳到被调用函数的首地址，等执行完了，再跳回来。  为了完成整个过程，编译器需要建立上下文，比如，传给被调用函数的参数，最重要的是，被调用函数执行完之后，它返回的地址。这些都是数据，存储在栈上。这是第一部分的数据。另一部分数据，则是被调用函数在执行过程中，自己生成的一些临时变量，比如LZ提供的代码中的变量： char a; char* str；  现在我们再看LZ提供的如下代码语句： strcpy(str,"hello");  显然，地址越界了，现在的a 的值应该是'h',然后呢，‘ello’这四个字节就把一些其它的内存覆盖了，最大的可能性就是覆盖了main函数的返回地址。现在，当程序返回后，发现所在的指令地址在一个莫名其妙的地方，如果你的运气不错，这个地方不是可执行区域，那么操作系统会为你捕获这个异常，引发一个访址异常，程序崩溃。如果你的运气比较糟糕，这仍然是一个可执行区域，那么，恭喜你，You have been hacked!

user: user-11
content: buffer overflow

user: user-12
content: 溢出了，不出错才有鬼。
user-0 提问: 关于枚举成员赋值

回复:
user: user-1
content: Semantics     The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted./52/ An enumerator with = defines its enumeration constant as the value of the constant expression.  If the first enumerator has no = , the value of its enumeration constant is 0.  Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant.  (A combination of both forms of enumerators may produce enumeration constants with values that duplicate other values in the same enumeration.) The enumerators of an enumeration are also known as its members.     Each enumerated type shall be compatible with an integer type; the choice of type is implementation-defined.

user: user-2
content: 没有显式赋值的都是前面的加1，如果都没有赋值，从0开始。

user: user-3
content: 默认后面的是按照第一个的值依次加1的

user: user-4
content: 两种情况下输出结果都是一样的，a=0, b=1, 依次加一，因为如果不设定值，第一个枚举值默认为0。  #include <iostream>  using namespace std;  enum ff{     a = 0,     b,     c,     d,     e = 0x7FFFFFFF };   enum ff2{     a2,     b2,     c2,     d2,     e2 = 0x7FFFFFFF };   int main() {     ff t = a;     cout << t <<endl;     t = b;     cout << t <<endl;     t = c;     cout << t <<endl;       ff2 t2 = a2;     cout << t2 <<endl;     t2 = b2;     cout << t2 <<endl;     t2 = c2;     cout << t2 <<endl;      return 0; }

user: user-5
content: 你得亲自试下……

user: user-6
content: 参看：http://blog.csdn.net/vjjjjjta/article/details/6337081

user: user-7
content: 未初始化的枚举值，顺次增加 1， 第一个枚举值，没有初始化的，初始化为 0 已经初始化的，以初始化为准 枚举值，是常量，不能赋值，只能初始化 枚举变量，才可以赋值

user: user-8
content: 依次加1,第一个值默认是0,赋值了什么就变什么
user-0 提问: WH_JOURNALRECORD钩子为什么将记录的信息写不到文件中

回复:
user: user-0
content: 回复赵4老师：         g_hLogHook调试确实是非法的指针，可是已经给g_hLogHook分配内存了。   HHOOK g_hLogHook = NULL;

user: user-1
content: 请检查每个函数的返回值。

user: user-1
content: 使用GlobalAlloc分配内存。并使用GlobalLock
user-0 提问: C语言中关于结构体指针使用->调用成员编译器找不到结构体的情况

回复:
user: user-0
content: 引用 2 楼 JiangWenjie2014 的回复:假设我有一个函数do_some_thing，需要一个参数，并且这个参数是一个结构体，例如struct SomeType，那么这个函数的声明就是void do_some_thing (struct SomeType t); 当编译器看到这个函数时，必须知道struct SomeType的定义是不是？要不然编译不通过，因为不知道这个参数占用多少内存，要不然函数调用的时候怎么把参数传进去？ 现在换种思路，把参数换成指针，就像这样void do_some_thing (struct SomeType *t);当编译器看到这个函数是，发现函数的参数是一个指针，现在编译器不需要知道struct SomeType的定义了，因为在确定的系统中，指针占用的字节数是确定的，32位系统下是4个字节，64位系统下是8个字节，至于指针的类型struct SomeType，编译器是可以忽略的，至少C是这样。  (*vm)-> 这种写法，显然*vm也是一个指针，vm是一个二级指针，因为只有指针才可以用->操作符。 感觉应该不是一个二级指针，因为那个文章中也说，如果改成c++文件，那么就是vm->这种写法，不过这个说法我也没验证，明天可以试试

user: user-1
content: 假设我有一个函数do_some_thing，需要一个参数，并且这个参数是一个结构体，例如struct SomeType，那么这个函数的声明就是void do_some_thing (struct SomeType t); 当编译器看到这个函数时，必须知道struct SomeType的定义是不是？要不然编译不通过，因为不知道这个参数占用多少内存，要不然函数调用的时候怎么把参数传进去？ 现在换种思路，把参数换成指针，就像这样void do_some_thing (struct SomeType *t);当编译器看到这个函数是，发现函数的参数是一个指针，现在编译器不需要知道struct SomeType的定义了，因为在确定的系统中，指针占用的字节数是确定的，32位系统下是4个字节，64位系统下是8个字节，至于指针的类型struct SomeType，编译器是可以忽略的，至少C是这样。  (*vm)-> 这种写法，显然*vm也是一个指针，vm是一个二级指针，因为只有指针才可以用->操作符。

user: user-2
content: 取决于JavaVM的定义了 比如重载了operator-> 又比如typedef xxx* JavaVM
user-0 提问: 关于C语言读取Unicode文档的问题，求教

回复:
user: user-0
content: 非常感谢，我也怀疑文件解析出错

user: user-1
content: 可以1。读的时候忽略这几个字节。 2。下个可以以unicode保存且不带签名的编辑器（我知道用EmEditor可以）

user: user-1
content: 因为windows中txt文件保存为unicode是带签名的，就是在文件开始有几个字节的字符作标记，你用一个二进制查看器看一下就知道了

user: user-0
content: 附图
user-0 提问: 蓝桥杯试题求助（1）

回复:
user: user-1
content: 引用 2 楼 zhao4zhong1 的回复:仅供参考：#include<stdio.h> #define N 1000    //要计算的N long s[N]={1,1},n=N,t=2,a=1,b=0; int main()//雨中飞燕之作 {     for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)         s[a]=(b+=s[a]*t)%10000,b/=10000;     for(printf("%d",s[*s]);--*s>0;) printf("%04d",s[*s]);     return 0; } 表示好难懂。。。

user: user-2
content: 仅供参考：#include<stdio.h> #define N 1000    //要计算的N long s[N]={1,1},n=N,t=2,a=1,b=0; int main()//雨中飞燕之作 {     for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)         s[a]=(b+=s[a]*t)%10000,b/=10000;     for(printf("%d",s[*s]);--*s>0;) printf("%04d",s[*s]);     return 0; }

user: user-3
content: 高精度乘法运算，用字符数组模拟手工乘法就可以了，用到也就是高精度加法。高精度加法应该还是简单的吧
user-0 提问: 关于VS2015写C出现“无法查找或打开 PDB 文件”不断提示的问题

回复:
user: user-1
content: 有时候就应该学会视而不见听而不闻，否则自寻烦恼

user: user-2
content: 我的也是这样，不过可以运行一会儿，然后产生中断出错，已经加载了启用源服务器支持和Microsoft符号服务器，还是找不到，全盘搜了没有.pdb文件

user: user-3
content: 楼主在return 0；前面加上system（“pause”）；

user: user-4
content: 我ctrl+f5之后还有，嘛~无所谓了

user: user-5
content: Ctrl+F5确实可以

user: user-6
content: 在不需要调试系统符号的情况下，有没有pdb无所谓。

user: user-7
content: 直接ctrl+F5就OK

user: user-8
content: ctrl+f5就好了

user: user-9
content: 在return 0前加一行代码，system("pause"); 重新编译运行即可。

user: user-10
content: http://blog.csdn.net/zhao4zhong1/article/details/53078924 老司机找bug的十年心路历程

user: user-11
content: 引用 15 楼 winc_best 的回复:的确啊我和你的情况一模一样 然后按了ctrl+f5 就行了 但是会多个 按任意键继续。。 但是按照我同学说的加个while（1）；就没有这个东西了 楼主知道为什么吗==   楼主是在哪里加个while（1），我也遇到了一样的问题

user: user-12
content: 我也遇到了这种情况，按楼上的方法还是不能调试，楼主是怎样弄好的呢

user: user-13
content: 的确啊我和你的情况一模一样 然后按了ctrl+f5 就行了 但是会多个 按任意键继续。。 但是按照我同学说的加个while（1）；就没有这个东西了 楼主知道为什么吗==

user: user-14
content: 忽略这些，通常对你没有影响

user: user-15
content: 引用 11 楼 hydrogencyanide 的回复:这样试试吧，我是这样弄的 1.菜单栏的“调试”-》“选项”→“选项”菜单中的“调试”→“常规”→把“常规”中的“启用源服务器支持”和它的子项勾选； 2.“选项”菜单中的“调试”→“符号”→把“符号”中的“Microsoft符号服务器”勾选； 3.点击“选项”菜单中的“确定”。  我也是这个出错，我是在调用fseek函数是才发生这个错误的。vs提示是∵fseek.cpp第177行出错。用了您的方法还是不行。我用的vs 2015 社区版

user: user-16
content: 已加载“C:\Windows\SysWOW64\ucrtbased.dll”。无法查找或打开 PDB 文件。 输出不了运行结果怎么办？

user: user-17
content: 这样试试吧，我是这样弄的 1.菜单栏的“调试”-》“选项”→“选项”菜单中的“调试”→“常规”→把“常规”中的“启用源服务器支持”和它的子项勾选； 2.“选项”菜单中的“调试”→“符号”→把“符号”中的“Microsoft符号服务器”勾选； 3.点击“选项”菜单中的“确定”。

user: user-18
content: 再补充一点：VS这样做，在多个项目（互有依赖）同时调试的时候，会比较方便。

user: user-18
content: 1.在Windows中，哪怕你只是一个很小的程序，也会对很多的库有依赖，那些你没见过的DLL，就是程序运行时需要依赖的库；  2.Visual Studio在调试的时候，默认会加载你的程序及其依赖项的所有PDB文件，其结果通常是：你自己程序的PDB能找到，但其依赖项的PDB文件一般是找不到的（比如WINDOWS系统内核），于是你就看到了给出的这个提示；  3.如果VS没有说你自己程序的PDB没找到，那么一般情况下你不用理会那些信息。

user: user-19
content: 找到那个文件，删了
user-0 提问: chart图标的缩放，怎么设置缩放最值

回复:
user: user-1
content: 沉吧。。提错地方就不会有人会吗。。 自己来拣个分。。

user: user-0
content: 还有一个问题 这个只是实验一下 把代码移植到另一个form的TabPage2里面，发现鼠标滚轮缩放不好用了。。。。 想知道为什么和怎么改 我在designer.cs里面加了 this.chart1.MouseWheel += new System.Windows.Forms.MouseEventHandler(chart_MouseWheel); 感觉不执行。。。

user: user-2
content: 这里不是C#版块
user-0 提问: 有个问题请教大牛

回复:
user: user-1
content: 抽象层次的不同：一句顶十句

user: user-2
content: C其实也不能，只是可以大致控制一下 C++如果你当作C用的话，和C的区别不是很大 如果你使用高级特性，那还是不要想太多

user: user-3
content: 楼主的意思是说程序语句对应的汇编代码吗？

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

user: user-5
content: 转成汇编代码后其实机制都是一样的，但c++因为比c抽象层次更多，所以理解起来要更难，所以要学得深，最好搞懂它的内存机制。
user-0 提问: memcpy段错误，

回复:
user: user-1
content: 看不懂时看下一行对应汇编指令或C/CPP源代码，直到能看懂为止。

user: user-0
content: 引用 12楼赵4老师 的回复:进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令查看咯core 文件产生的信息，就是在memcpy的时候进程core掉的。上面的图片是gdb调试的时候打出的信息

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

user: user-1
content: 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

user: user-2
content: NAME        memcpy - copy memory area  SYNOPSIS        #include <string.h>         void *memcpy(void *dest, const void *src, size_t n);  DESCRIPTION        The  memcpy()  function  copies  n bytes from memory area src to memory        area dest.  The memory areas must not overlap.  Use memmove(3)  if  the        memory areas do overlap.  RETURN VALUE        The memcpy() function returns a pointer to dest.  CONFORMING TO        SVr4, 4.3BSD, C89, C99, POSIX.1-2001.

user: user-0
content: 引用 3楼heroesjun 的回复:再贴一点代码，把sGbsinfo结构体类型贴出来看看。第一张图片里面有打印部分的结构体成员

user: user-0
content: 引用 6楼heroesjun 的回复:引用 5 楼 初見的畫面的回复:[quote=引用 2 楼 qq_26238085 的回复:] [quote=引用 1楼ant2012 的回复:]sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？[/quote] 是个char数组，看第一张图就知道了。[/quote]是的，这是一个char类型的数组

user: user-0
content: 引用 4楼faith_locus 的回复:复制字符串你使用strcpy更合适，再有段错误应该是你访问非法内存了。以为在第一张图的时候可以看到sMsgCode是一个20位的字符数组，所以应该

user: user-3
content: 引用 5 楼 初見的畫面的回复:引用 2 楼 qq_26238085 的回复:[quote=引用 1楼ant2012 的回复:]sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？[/quote] 是个char数组，看第一张图就知道了。

user: user-4
content: 引用 2 楼 qq_26238085 的回复:引用 1楼ant2012 的回复:sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？

user: user-5
content: 复制字符串你使用strcpy更合适，再有段错误应该是你访问非法内存了。

user: user-3
content: 再贴一点代码，把sGbsinfo结构体类型贴出来看看。

user: user-0
content: 引用 1楼ant2012 的回复:sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符

user: user-6
content: sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了
user-0 提问: 枚举类型 求指导~

回复:
user: user-1
content: 你这里的枚举是从3开始的

user: user-0
content: 感谢各位大神指导~~~

user: user-2
content: 枚举的本质是整型，一个枚举值，可以看成是整数的别名，sun被显式赋值为2，所以后面的mon、tue依此加一，即3和4。day被赋值为2，而且输出的格式是整型格式”%d“，所以打印结果即2。

user: user-3
content: 实践是检验真理的唯一标准

user: user-4
content: 枚举类型只是整数的马甲。

user: user-5
content: 定义的enum weekday中没有等于2的枚举常量，是从3开始的。 printf("%d")只认识二进制，不管是什么类型的，2就是2，不管它是整数还是枚举类型。
user-0 提问: C语言编写的虚拟串口通信程序出错，显示Open COM Failed，请问是什么原因？

回复:
user: user-1
content: 把分给我吧   串口只能打开一次  必须关掉或者程序被结束后  才能再次打开

user: user-2
content: GetLastError()看看是什么错误

user: user-3
content: 串口open failed还能发数据？有没有单步调，看看数据怎么发的？
user-0 提问: socket  怎样检测TCP连接是否失效？

回复:
user: user-1
content: 心跳包是最有效的方案。

user: user-2
content: tcp协议栈的keepalive是有个陷阱的，比如说 服务端挂了，而你还不停的往这个socket上发数据，因为send是往内核里写数据（缓冲区没满是是不会阻塞的），此时tcp认为该socket还存在数据往来，就认为该连接是有效的。  上次就差点因为这个没把一个关键bug解决，巨坑~~

user: user-0
content: 总结以上所说，检测TCP连接是否有效，最好的方法是进行心跳包检测。检测过程中，网断、服务器断开等情况分别需要检测会出现什么结果。结贴啦

user: user-0
content: 如15楼所说

user: user-3
content: 引用 9 楼 cr945211 的回复:如果网络断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，但是send函数的执行不会使程序终止；如果服务器断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，send函数的执行会提示信号错误，导致程序终止。以上是调试过程中出现的结果，如果连续运行，服务器断开后程序不会终止。 我查到的资料都是这样用setsockopt来设定send和recv的超时。但是理论上应该是：若无错误发生，setsockopt()返回0，否则的话，返回SOCKET_ERROR错误。  你的网络断开是指：直接禁用网卡或拔网线或关闭交换机电源？       //这样操作socket还是一个全法状态的socket，所以发送不会有问题 你的服务器断开 是指：服务器正常退出，客户端正常关闭socket吗？//如果是这样，socket处于关闭或time_wait或close_wait或其他状态，发送会出问题

user: user-0
content: 引用 10 楼 lianshaohua 的回复:强烈建议使用心跳机制，一发一回； 强烈不建议使用keep_alive现在没使用keepalive，用的是心跳包，请看一下9楼的问题，能不能帮我解答下？

user: user-4
content: 看来还真是有陷阱啊，我测试测试 。

user: user-5
content: 引用 11 楼 zhllxt 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 不要管KeepAlive，使用心跳包。  我想问一下赵老师，我在开源的HPSocket中看到检测连接是否正常的代码就是用的KeepAlive，我测试过，这个KeepAlive非常可靠，我觉得完全没有必要再自己定义心跳包来实现检测了。 赵老师说“不要管KeepAlive，使用心跳包。”是有什么我不知道的陷阱在里面吗？[/quote] 换移动互联网你再测一下。

user: user-4
content: 引用 5 楼 zhao4zhong1 的回复:不要管KeepAlive，使用心跳包。  我想问一下赵老师，我在开源的HPSocket中看到检测连接是否正常的代码就是用的KeepAlive，我测试过，这个KeepAlive非常可靠，我觉得完全没有必要再自己定义心跳包来实现检测了。 赵老师说“不要管KeepAlive，使用心跳包。”是有什么我不知道的陷阱在里面吗？

user: user-3
content: 强烈建议使用心跳机制，一发一回； 强烈不建议使用keep_alive

user: user-6
content: 测试

user: user-7
content: setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然

user: user-0
content: 如果网络断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，但是send函数的执行不会使程序终止；如果服务器断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，send函数的执行会提示信号错误，导致程序终止。以上是调试过程中出现的结果，如果连续运行，服务器断开后程序不会终止。 我查到的资料都是这样用setsockopt来设定send和recv的超时。但是理论上应该是：若无错误发生，setsockopt()返回0，否则的话，返回SOCKET_ERROR错误。

user: user-8
content: 自定义心跳包或者启用保活定时机制

user: user-9
content: 最简单也是最常用的维持长连接的方法是： 客户端发送心跳包 靠设置socket的keepalive是不够的

user: user-10
content: 自定义心跳包来监测是否连接正常

user: user-5
content: 参考略微成熟一点的相关开源项目中的相关源代码。

user: user-0
content: 上面写错了 send(sock_fd,senfbuf,len1,0); recv(sock_fd,recvbuf,len2,0);

user: user-0
content: 引用 5 楼 zhao4zhong1 的回复:不要管KeepAlive，使用心跳包。 不停给服务器发数据、接收数据来检测是否处于连接状态。如果服务器断开，还是要继续发送数据、接收数据，以下为将发送、接收设置为超时。但是服务器断开后ret1和ret2一直为0，还是会运行send函数，接着会出现错误；recv函数执行时不会出现错误，但是ret1和ret2不应该都是0啊？异常应该是-1吧。请问这是为什么？  int ret1=setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout)); if(ret1!=-1) {        send(sock,senfbuf,len1,0); }  int ret2=setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(timeout)); if(ret2!=-1) {        recv(sock,recvbuf,len2,0); }

user: user-5
content: 不要管KeepAlive，使用心跳包。
user-0 提问: c语言模拟class遇到个额问题

回复:
user: user-1
content: 有钻研精神很佩服，不过我觉得这个技术非主流，不值得浪费太多时间，不如C++。

user: user-2
content: 我想这个就是用C实习面向对象吧，一个结构体，里面有函数指针

user: user-3
content: C++一个重要特性是析构函数的自动化执行 这个是C所不具备的， 这个特性，对资源的配置与释放，异常安全等方面，很方便 而C差不多要手工处理。 每种语言，编译器，都有它的好处，与不足 用一个语言，去做另一个语言擅长的事情，是很吃力的，当然做得好了，也很有成就感。 喜欢玩，就努力去做吧，不是很喜欢探索的话，还是根据问题不同，选择工具吧

user: user-3
content: 引用 7 楼 Saleayas 的回复:把你的函数指针，定义到其他的结构里面，然后，在这个结构里，使用指针指向他。 定义函数指针的结构就是所谓的虚表。 而这个虚表其实在编译的时候是固定的。 这样，你的构造的时候，虚表的实例指针也是固定的，就可以直接使用 = {} 模式构造了。

user: user-4
content: 把你的函数指针，定义到其他的结构里面，然后，在这个结构里，使用指针指向他。 定义函数指针的结构就是所谓的虚表。 而这个虚表其实在编译的时候是固定的。 这样，你的构造的时候，虚表的实例指针也是固定的，就可以直接使用 = {} 模式构造了。

user: user-5
content: 楼主知不知道GLIB除了GQueue之外还有一个GAsyncQueue，这个就是加锁的GQueue。

user: user-6
content: 面向过程的语言还要封装，为啥不直接用C++，而且结构体并没有private，封装并没有效果，这函数指针谁想用都能用，又有什么意义

user: user-7
content: 何必非要把c弄成c++的样子？

user: user-8
content: 要么用C， 要么用C++， 这不伦不类的算啥。

user: user-5
content: 引用 4 楼 chouxiaoya8100 的回复:[quote=引用 3 楼 JiangWenjie2014 的回复:] 楼主知不知道GLIB除了GQueue之外还有一个GAsyncQueue，这个就是加锁的GQueue。  可以直接使用？ 不需要用任何锁和其配合？  如此说来， GQueue根本就没有必要出现在多线程中， 浪费代码。直接使用CAnsyQueue即可。  我理解的对否？ [/quote] GQueue提供的接口不是线程安全的，GAsyncQueue提供的接口是线程安全的。并不是说多线程代码中就不能用GQueue了，如果一个GQueue对象只在一个线程中维护，那就可以用。你没有GLIB的源码吗，看一下GAsyncQueue类型的定义，它里面就自带锁了。  typedef struct _GAsyncQueue GAsyncQueue;  struct _GAsyncQueue {   GMutex mutex;   GCond cond;   GQueue queue;   GDestroyNotify item_free_func;   guint waiting_threads;   gint ref_count; };  void g_async_queue_push (GAsyncQueue *queue,                     gpointer     data) {   g_return_if_fail (queue);   g_return_if_fail (data);    g_mutex_lock (&queue->mutex);   g_async_queue_push_unlocked (queue, data);   g_mutex_unlock (&queue->mutex); }

user: user-0
content: 引用 3 楼 JiangWenjie2014 的回复:楼主知不知道GLIB除了GQueue之外还有一个GAsyncQueue，这个就是加锁的GQueue。  可以直接使用？ 不需要用任何锁和其配合？  如此说来， GQueue根本就没有必要出现在多线程中， 浪费代码。直接使用CAnsyQueue即可。  我理解的对否？
user-0 提问: 请问数组为什么读取我输入的数据？

回复:
user: user-1
content: 引用 10 楼 u010284226 的回复: scanf_s("%c",s[i],sizeof(s[i]))  引用 10 楼 u010284226 的回复: scanf_s("%c",s[i],sizeof(s[i]))  再把 for(i=0;i<20;++i) 改为 for(i=0;i<20;i++)

user: user-2
content: scanf_s("%c",s[i],sizeof(s[i]))

user: user-3
content: ANSI C中没有scanf_s(),只有scanf()，scanf()在读取时不检查边界，所以可能会造成内存访问越界，例如分配了5字节的空间但是读入了10字节 char buf[5]={'\0'}; scanf("%s", buf); 如果输入1234567890，后面的部分会被写到别的空间上去。 以上代码如果用scanf_s,第二行应改为scanf_s("%s",buf,5),表示最多读取4个字符，因为buf[4]要放'\0' scanf_s最后一个参数是缓冲区的大小，表示最多读取n-1个字符. vc++2005/2008中提供了scanf_s(),在最新的VS2013中也提供了scanf_s()。在调用时，必须提供一个数字以表明最多读取多少位字符。

user: user-4
content: scanf_s是scanf的安全形式。后面必须加上最大存储长度，所以括号内必须再加上一个scanf_s（“%c”，&s[i]，1）才行。你能给我个你编译器的下载地址吗，我也是刚自学c的，但是我下载的编译器都不支持c11，包括scanf_s（）。我一直都是用不加_s的函数。我书上好多都是用的_s的函数，说这个的安全。谢谢啊

user: user-5
content: int main(void) { 	int i; 	char s[10]; 	for (i = 0; i < 10; i++) 		scanf("%c", s + i); 	for (i = 0;i < 10;i++) 		printf("%c", s[i]); 	printf("\n"); 	return 0; }

user: user-6
content: #pragma warning(disable:4996)

user: user-5
content: 引用 5 楼 qq_30446977 的回复:scanf_s是scanf的安全形式。后面必须加上最大存储长度，所以括号内必须再加上一个scanf_s（“%c”，&s[i]，1）才行。你能给我个你编译器的下载地址吗，我也是刚自学c的，但是我下载的编译器都不支持c11，包括scanf_s（）。我一直都是用不加_s的函数。我书上好多都是用的_s的函数，说这个的安全。谢谢啊 微软官网

user: user-0
content: VS2013中不允许使用scanf函数

user: user-7
content: 并且你只输入了19位数，应该使用i++，而不是++i

user: user-7
content: 为什么不用scanf

user: user-0
content: 是为什么没有，打错了！
user-0 提问: 二维数组在调用函数中的声明问题

回复:
user: user-1
content: 第一行什么意思都不知道

user: user-2
content: typedef int arr[][4]; cout << typeid(arr).name() << endl;  //int[0][4]

user: user-3
content: 前面应该定义了arr3x4类型的：  typedef int arr3x4[][4];  引用 楼主 cant_see 的回复: 这里的第一行是不是有问题，看不懂

user: user-4
content: 楼主得把上下文贴全了，看样子 arr3x4 应该是在前面定义了。

user: user-5
content: 第一种没见过，第二种和第三种等价，因为形参中二维数组的第一维长度是没有意义的
user-0 提问: 为什么会访问冲突？

回复:
user: user-1
content: 引用 6 楼 linfengc 的回复:这年头怎么还在搞c啊.  直接c++ primer搞起. stl搞起, boost搞起.  学盖房子也别学怎么烧砖... 不会c的c++程序员，不是好的c++程序员

user: user-1
content: 修改如下：  #include <stdio.h> struct fullname { 	char fname[20]; 	char lname[20]; }; struct bard { 	struct fullname name; 	int born; 	int died; }; struct bard willie; int main(void) { 	scanf("%d", &willie.born); 	scanf("%d", &willie.died); 	scanf("%s", willie.name.fname); 	scanf("%s", willie.name.lname); 	printf("name.fname=%s,name.lname=%s,born=%d,died=%d\n", willie.name.fname, willie.name.lname, willie.born, willie.died); 	return 0; };

user: user-2
content: 话说输入的时候为什么要用换行符呢？ ‘\n’这个东西是干嘛的？

user: user-3
content: 我的编译器能提示这种错误code blocsk.

user: user-4
content: 引用 6 楼 linfengc 的回复:这年头怎么还在搞c啊.  直接c++ primer搞起. stl搞起, boost搞起.  学盖房子也别学怎么烧砖...  c++能用来开发单片机吗？

user: user-5
content: #include <stdio.h>  struct fullname {     char fname[20];     char lname[20]; };  struct bard {     struct fullname name;     int born;     int died; };  struct bard willie; struct bard *pt = &willie;  int main(void) {     scanf("%d\n", &willie.born);     scanf("%d\n", &pt->born);     scanf("%s\n", willie.name.lname);     scanf("%s\n", pt->name.lname);      printf("%s\n", pt->name.lname);      getchar();     return 0; }

user: user-6
content: 这年头怎么还在搞c啊.  直接c++ primer搞起. stl搞起, boost搞起.  学盖房子也别学怎么烧砖...

user: user-7
content: 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

user: user-8
content: 所有的scanf把取地址符号都去掉试试

user: user-9
content: 当然冲突了，lname[2]是一个字符，%s输出一个字符串，printf在输出时，会将这个字符的值转成地址，而且遇'\0'结束，所以会崩溃
user-0 提问: c语言如何实现局部锁？

回复:
user: user-1
content: 上帝为什么不担心有人长生不老呢？

user: user-2
content: lz与其担心锁未释放，为什么不担心内存未释放? 没有智能指针忘记释放怎么办, 锁未释放, 可能线程死锁, 可能直接就看出来了, 内存不释放很蛋疼.  先写 {     xxx_lock(&locker);     xxx_unlock(&locker); } 再在中间写? 没用过纯C, lz要不要加入C++
user-0 提问: 怎么把数字以字母形式输出

回复:
user: user-1
content: 使用递归啊  //函数 void rever_array(int number){ 	if(number/10)rever_array(number/10); 	putchar(number%10+'0'); }

user: user-2
content: 其实已经是字符串了，你想存起来的话，改用sprintf即可。  引用 5 楼 dag617712 的回复:[quote=引用 2 楼 walkiz 的回复:]  printf("%ld", 54445352);  我是想把这几个数字以字母形式输出，这样还是以数字形式啊[/quote]

user: user-3
content: /************************* 将整数以字符形式输出 *************************/ #include <stdio.h>  int main () { 	int num = 12345; 	int arr[100]; 	int i = 0; 	int count = 0; 	do 	{ 		arr[i++] = num % 10;//5  4      3     2    1 		num = num / 10;//1234    123    12    1     0 		count ++;//1  2  3  4  5 	}while(num); //	printf("%d\n",count); 	for(i = count-1; i >= 0; --i) 	{ 		printf("%c",arr[i]); 	} 	printf("\n"); 	return 0; } 不知道你指的是不是这个意思你看下

user: user-4
content: 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

user: user-5
content: 你想把ascii以字符的型式输出可以是可以,得手动分开 char a = 54； char b = 44； char c = 53； char d = 52； printf("%c,%c,%c,%c\n",a,b,c,d); 要是让程序自动分割可能很困难 54445352，可以是54，44，53，52 也可能是54，4，4，5，35，2， 除非本来就有分隔符

user: user-6
content: 引用 11 楼 dag617712 的回复:[quote=引用 10 楼 zhangxiangDavaid 的回复:] RSDT是个啥？  R的ASCII是54，以此类推[/quote] R的ASCII是82

user: user-0
content: 引用 10 楼 zhangxiangDavaid 的回复:RSDT是个啥？  R的ASCII是54，以此类推

user: user-6
content: RSDT是个啥？

user: user-0
content: 引用 8 楼 zhangxiangDavaid 的回复:[quote=引用 7 楼 dag617712 的回复:] [quote=引用 6 楼 dag617712 的回复:] [quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote][/quote] 你要哪种结果？[/quote] 把54445352以RSDT输出

user: user-6
content: 引用 7 楼 dag617712 的回复:[quote=引用 6 楼 dag617712 的回复:] [quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote][/quote] 你要哪种结果？

user: user-0
content: 引用 6 楼 dag617712 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote]

user: user-0
content: 引用 4 楼 zhangxiangDavaid 的回复:你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对

user: user-0
content: 引用 2 楼 walkiz 的回复: printf("%ld", 54445352);  我是想把这几个数字以字母形式输出，这样还是以数字形式啊

user: user-6
content: 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }

user: user-7
content: 把它转换成字符串在输出？或者用楼上的办法更直接

user: user-2
content: printf("%ld", 54445352);

user: user-8
content: 存到数组，或用指针指向它，一个一个打印输出

user: user-9
content: #include<stdio.h>  int main() {     unsigned int n;     scanf("%x",&n);                              // 输入54445352     for(int i=0;i<sizeof n;++i)         putchar(  ( (const char*)&n )[i]  );     // 输出RSDT     putchar('\n');     return 0; }

user: user-10
content: 没法子，因为 字符有256个，ASCII有0～127，128 个所以必须定义好你的数字的意义，才能按照所谓的字符输出 汉字更多
user-0 提问: 求救！！我这个菜鸟看不懂是什么意思

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

user: user-2
content: printf("%c\n", c);

user: user-3
content: 看效果：  #include <stdio.h> int main() { 	char c; 	for (;(c = getchar()) != '\n';) 		printf("%c\n", c); 	return 0; } //zhangxiang //z //h //a //n //g //x //i //a //n //g

user: user-0
content: 好了，打印后面少个东西，谢谢呵

user: user-0
content: 可打印出来的全是换行啊，什么也不显示

user: user-4
content: 打印你输入的字符，遇到回车结束
user-0 提问: 请教，程序异常终止时，malloc分配的堆内存会自动释放吗?xiexie 

回复:
user: user-1
content: 会

user: user-2
content: 引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote]  服务程序是要长期运行的，可能一年365天一直运行着，如果有内存泄露，超过虚拟内存最大限度，程序就会崩溃。

user: user-3
content: 我们程序使用的内存是虚拟内存，使用的时候映射到物理内存上，当程序崩溃以后，系统就收回了映射的部分，所以，不是是自动free掉，而是强制收回了

user: user-4
content: 引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote] 很多时候，内存会泄露，直到内存被耗尽，程序才奔溃

user: user-5
content: 引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote]  问题是很多程序不能随意退出 靠程序退出来解决内存泄漏是下下策

user: user-0
content: 引用 4 楼 zhangxiangDavaid 的回复:程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?

user: user-4
content: 程序都终止了，还有什么可以留下

user: user-0
content: 引用 2 楼 user-6 的回复:不是自动释放, 而是被系统收回. 那有什么区别码？

user: user-6
content: 不是自动释放, 而是被系统收回.

user: user-0
content: 想请教的是栈变量是否会在程序异常终止时，比如出错了，栈变量申请的内存会自动释放吗？
user-0 提问: 在结构体中分配堆，怎么回收？

回复:
user: user-1
content: 有几个问题： 1. 函数内部动态分配空间并返回地址，参数需要时双重指针，因为malloc返回的地址是随机的。 2. 主函数的array是静态分配的，不需要free，函数退出自动收回。 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Teacher { int age; char name[32]; //char* p; }Teacher; int creatArray(Teacher** buf,int num) { Teacher* p = NULL;  p = (Teacher*)malloc(num*sizeof(Teacher)); if(p == NULL) { return -1; } *buf = p;  return 0; } void main() { int i = 0; int num = 3; Teacher* Array ; if(creatArray(&Array,num) != 0) { return; } free(Array); system("pause"); }

user: user-2
content: Teacher Array[4]  ;这里定义了，直接分配到栈的空间去了。所以不能free

user: user-3
content: 定义的函数里面由malloc，根本没有调用，所以不需要free。 局部变量都是在栈里面的，包括数组和变量，也不需要free。 最后如果想要调用malloc的函数，请专门写一个destroy的函数里面去free，在main函数的最后调用一下就可以了。

user: user-4
content: 两个问题 Array是栈内存而不是堆内存,不用释放 而如果你有一个createArray函数申请了堆内存,你必须提供一个destroyArray来释放,两者配套使用 或者用类

user: user-5
content: #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Teacher { 	int age; 	char name[32]; 	//char* p; }Teacher; int creatArray(Teacher** buf,int num) { 	Teacher* p = NULL;  	p = (Teacher*)malloc(num*sizeof(Teacher)); 	*buf = p; 	if(buf == NULL) 	{ 		return -1; 	} 	return 0; } void main() { 	int i = 0; 	int num = 3; 	Teacher* Array ; 	if(creatArray(&Array,num) != 0) 	{ 		return; 	} 	free(Array); 	system("pause"); }

user: user-5
content: Teacher Array[4] ;是在栈中分配内存，main退出会自动释放 你定义了creatArray但在main中没有调用。 应该 void main() { int i = 0; int num = 3; Teacher* Array ; if(creatArray(Array,num) != 0) { return; } free(Array); system("pause"); }
user-0 提问: 一个关于指针的问题

回复:
user: user-1
content: int * func(int var){ 	int static result,*p; 	result=var+1500; 	p=&result; 	return p; }  把函数改成这样 result是局部变量，函数结束的时候，虽然你是返回了reslut的地址，但是reslut已经不存在了， 再指向他就没有意义了，可以让result改成静态的  指针.c:17:2: warning: function returns address of local variable [enabled by default]  不能用return &result不能返回局部变量的地址

user: user-2
content: 为何要执着于返回局部变量的地址？

user: user-3
content: #include <stdio.h>  void fun1(int val, int *result) { 	*result = val + 1500; }   void fun2(int val, int *result) { 	*result = val - 1500; }  int main() { 	int result1, result2; 	int val = 1000;  	fun1(val, &result1); 	fprintf(stderr, "result1 = %d\n", result1);  	fun2(val, &result2); 	fprintf(stderr, "result2 = %d\n", result2); 	fprintf(stderr, "result1 = %d\n", result1); }

user: user-4
content: msvc 引用warning C4172: 返回局部变量或临时变量的地址 clang 引用warning: address of stack memory associated with local variable 'result' returned 不要忽略警告，以为过了编译就万事大吉了

user: user-5
content: 返回局部变量指针的结果不确定性问题。

user: user-6
content: 局部自动变量的值，只在局部可控 其地址也只在局部可用

user: user-7
content: 使用数据改变断点。参考下面： #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }
user-0 提问: 神奇的 int unsigned int 大家帮看下 什么原因(十进制转二进制)

回复:
user: user-1
content: 请楼主亲自打开include\limits.h文件，并逐行看其内容。

user: user-0
content: 这样啊，这个思路貌似蛮难拐弯的~谢谢啦，对这个还有什么建议的吗

user: user-2
content: unsigned int m  m 永远大于等于0,for不会退出。
user-0 提问: 各位大神帮我看看这程序生什么病了。。

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

user: user-2
content: 我也认为是0的问题。 第一次3%2没法整除，接着循环一次就算3%0

user: user-3
content: 修改如下：  #include<stdio.h> #define N 100 int a[N]; int i, ci, sw; int x; int prime(int x, int a[], int w); int main(void) {  	a[0] = 2; 	x = 3; 	ci = 1; 	while (ci < N) { 		if (prime(x, a, sw)) { 			a[ci++] = x; 			sw++; 		} 		x++; 	} 	for (i = 0; i < N; i++) { 		printf("%d", a[i]); 		if ((i + 1) % 5) { 			printf("\t"); 		} 		else { 			printf("\n"); 		} 	} 	return 0; } int prime(int x, int a[], int w) { 	int ret = 1; 	int i; 	for (i = 0; i < w; i++) { 		if (x % a[i] == 0) { 			ret = 0; 			break; 		} 	} 	return ret; }

user: user-4
content: 这个问题应该是除0问题  int a[sw] = {2};  // 初始化数组，第一个元素值为2，其后元素为0，执行sum里的if(x%a[i]==0)时 被除数为0，程序就会抛出异常

user: user-5
content: x%a[i]  a[i] 有为 0 的，产生除 0 的错误
user-0 提问: 帮分析下这个宏，谢谢

回复:
user: user-1
content: VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898 http://bbs.csdn.net/topics/390150105

user: user-2
content: 随便用两个参数带入进去手动把宏展开一下，写下来就明白了。 还不明白的话，换个参数再来几次，很快就会明白的。
user-0 提问: TI NDK编程中UDP socket使用MSG_DONTWAIT flag调用recvfrom无法接收数据，求解如何破？

回复:
user: user-0
content: 自己试验出来了，虽然原理上不太懂，解决方法是： 去掉代码中的设置SOL_BLOCKING的setsockopt函数调用，这个TI NDK自定义的属性似乎影响NDK的底层工作流程，去掉之后无论是否使用MSG_DONTWAIT调用recvfrom都可以成功读取报文。
user-0 提问: 运行时出现乱码

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

user: user-2
content: printf("%c\n", data[i].name);//%c换成%s

user: user-3
content: 乱码截个图。 你是什么环境？换字符集GBK.UTF8试试
user-0 提问: const的问题，我照超书上的为什么还有错

回复:
user: user-1
content: 就很快就好

user: user-1
content: 书上的肯定有错呀

user: user-2
content: 另外，按照你的要求“我的本意是指针作为函数变元时，传递值时，不改变指针的值”，函数声明应该为：  bool siblings(Family* const pmember1, Family* const pmember2) { //…… }  因为 Family const *pmember1 和 const  Family *pmember1 是一样的，都是保护指针指向的对象，Family* const pmember1才是保护指针本身

user: user-2
content: 参数类型为指针类型，你调用时传入 *pmember1,*pmember2 相当于传递了值类型，吧星号去掉就可以了，如下形式：  if(siblings(pmember1,pmember2))      //这里编译时出错，
user-0 提问: 好久没问问题了，研究半天了

回复:
user: user-1
content: 恭喜恭喜恭喜

user: user-0
content: 感谢前辈们的解答 疑惑已经解决了 深切体会了C语言的规则

user: user-2
content: 你看看我这个够不够清晰？  #define UINT_TO_POINTER(v) ((void *)(v)) #define POINTER_TO_UINT(v) ((unsigned int)(v))  struct slist {     struct slist *next;     void *data; };  struct slist *slist_prepend (struct slist *head, void *data) {     struct slist *p = malloc (sizeof (*p));      p->next = head;     p->data = data;      return p; }  struct slist *slist_delete_link (struct slist *head, struct slist *link) {     struct slist *tmp = head, *prev = NULL;      while (tmp) {         if (tmp == link) {             if (prev)                 prev->next = tmp->next;             else                 head = head->next;             tmp->next = NULL;             break;         }          prev = tmp;          tmp = tmp->next;     }      free (link);      return head; }  int main () {     unsigned int i, v;     struct slist *head = NULL;      scanf ("%u", &i);     while (i--) {         scanf ("%u", &v);         head = slist_prepend (head, UINT_TO_POINTER (v));     }      while (head) {         v = POINTER_TO_UINT (head->data);         printf ("%u ", v);         head = slist_delete_link (head, head);     }     putchar ('\n');      return 0; }

user: user-3
content: 修改如下：  typedef struct node { 	int data; 	struct node *next; }Lnode, *Linklist; Linklist Creat() { 	Lnode *p, *s; 	int x; 	Linklist H = (Linklist)malloc(sizeof(Lnode));  //头节点 	H->next = NULL; 	p = H; 	scanf("%d", &x); 	while (x != -1) 	{ 		s = (Linklist)malloc(sizeof(Lnode)); 		s->data = x; 		p->next = s; 		p = s; 		scanf("%d", &x); 	} 	p->next = NULL; 	return H; } void PrintList(Linklist list) { 	if (NULL == list->next) return; 	Lnode *p = list->next; 	while (p->next) 	{ 		printf("%d->", p->data); 		p = p->next; 	} 	printf("%d\n", p->data); } int main(void) { 	Linklist X, Y; 	Lnode *temp; 	//X = (Linklist)malloc(sizeof(Lnode)); 	//Y = (Linklist)malloc(sizeof(Lnode)); 	printf("Enter the A line data :\n"); 	X = Creat(); 	PrintList(X); 	printf("Enter the B line data :\n"); 	Y = Creat(); 	PrintList(Y); 	return 0; } //Enter the A line data: //1 //2 //3 //4 //-1 //1->2->3->4 //Enter the B line data: //9 //8 //7 //6 //-1 //9->8->7->6  节点未释放，注意添加释放函数

user: user-3
content: Lnode是普通类型 Linklist是指针类型
user-0 提问: 请问int *p[][]与int **p1这两个是一样的吗？

回复:
user: user-1
content: int *p[][]中的p是一个二维数组，数组的元素师int型指针，int **p是一个双重指针，它有可能指向一个二维数组，不过数组的元素类型是int，而不是int*

user: user-2
content: //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]

user: user-3
content: 楼主是想说二级指针和二维数组？

user: user-4
content: int *p[][] 通不过编译的
user-0 提问: 能问一个很奇怪的问题吗

回复:
user: user-1
content: 你不可能运行到函数体返回，函数入口时要把所需要东西进行压栈，函数返回时会出栈，这句话表示这个函数运行不到出栈并返回参数给调用者，比如函数中有exit(0);

user: user-2
content: 一般在函数中间直接调用exit退出进程，或者在线程函数中直接退出线程，不过具体要看上下文。最好给个例子。

user: user-3
content: 例如：  int main(int argc, char* argv[]) {     while(1)     {         /* It will never return */     }      return 0; }

user: user-4
content: 线程函数 主循环 ……

user: user-5
content: 永远不会返回的函数，比如  void hello () {     exit (0); }

user: user-6
content: 一般 单片机 运行代码（主程序中）， 这一类的程序，都是无限循环的不出错的话，永不退出，自然也就永不返回了。 操作系统的某一部分，本质上，也是无限循环的，只是可以在用户控制下，退出而已。 实际上，服务器系统，几乎一直在运行，不出问题，不升级系统，100年也还在运行。
user-0 提问: 这是一段多项式的不完整代码，编译没有错误，运行时智能正确显示第一项。求大牛解答？我在vs2013下编译。

回复:
user: user-0
content: 多谢指导，可是自己心急了。

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

回复:
user: user-1
content: x=0x12345678；

user: user-1
content: 大小端，这个有两种看法 某些人把Intel 8086~如今的X86 字节顺序，称为 大端 Big End  motorola 68XXXX 等 芯片，字节顺序，称为小端 Little End  另一些人恰恰相反 总之是两种不同的字节顺序  简单的测试就是  int main(){ union{ int x  char a[4]; }; x=0x12345678 if( a[0] == 0x78)         printf("II");//Intel 格式，TIFF  文件中 II表示 Intel 格式 else         printf("MM");//motorola 格式，TIFF  文件中 MM表示 Motorola格式 return 0; }

user: user-2
content: 引用 11 楼 wangyaninglm 的回复:[quote=引用 4 楼 wang0635 的回复:] int	x = 0x12; if (*(char *)&x == 0x12) 	//小端 else 	//大端  想请问一下，这么写是啥意思？[/quote] 运行时判断大小端

user: user-0
content: 引用 4 楼 wang0635 的回复:int	x = 0x12; if (*(char *)&x == 0x12) 	//小端 else 	//大端  想请问一下，这么写是啥意思？

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

user: user-4
content: 在计算机系统中，我们是以字节为单位的，每个地址单元都对应着一个字节，一个字节为 8bit。但是在C语言中除了8bit的char之外，还有16bit的short型，32bit的long型（要看具体的编译器），另外，对于位数大于 8位的处理器，例如16位或者32位的处理器，由于寄存器宽度大于一个字节，那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x，在内存中的地址为0x0010，x的值为0x1122，那么0x11为高字节，0x22为低字节。对于 大端模式，就将0x11放在低地址中，即0x0010中，0x22放在高地址中，即0x0011中。小端模式，刚好相反。我们常用的X86结构是小端模式，而KEIL C51则为大端模式。很多的ARM，DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

user: user-5
content: 是的，和大小端有关。  #include<stdint.h> #include <stdio.h>  #if defined(_WIN32) || defined(_WIN64) #include <windows.h> #include <winsock2.h> #else #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #endif   union X {     int32_t a;     struct      {         int16_t b;         int16_t c;     }; };   int main() {     union X x;     x.a = htonl(0x20150810);     printf("%x,\n",&x.a);     printf("%x,\n",ntohl(x.a));     printf("%x,%x\n",&x.b,&x.c);     printf("%x,%x\n",ntohs(x.b), ntohs(x.c));       getchar();     return 0; }

user: user-6
content: 只能转成char[] 然后奇偶swap

user: user-7
content: 改代码把 引用x.a = htonl(0x20150810);

user: user-8
content: 这个和处理器有关，大小端

user: user-2
content: int	x = 0x12; if (*(char *)&x == 0x12) 	//小端 else 	//大端

user: user-9
content: 对，这个跟大小端有关。 PowerPC处理器使用大端模式，而Pentuim处理器使用小端模式。

user: user-10
content: 这个是取决于处理器的，没法从vs里设置。

user: user-0
content: 我去。我不是这个版的版主，
user-0 提问: C语言，请问一个被调用函数里面开辟了指针内存，并且返回指针，那么怎么释放它呢？

回复:
user: user-1
content: 4、如何给帖子结帖，结帖如何给分？ 点击帖子左上方的"结帖"按钮，可以进行如下操作： 单独给分结帖：当您的问题得到解答，请给回答者相应的分数，来结束该帖。当您结帖后，系统将返回给您该帖的50%的可用分。 注：结帖人不允许给自己的回复发分。 无满意答案结帖： 当您的问题得不到合适的答案。您可以选择无满意结帖结束这个问题。 注：无满意结帖，系统将回收帖主的悬赏分，且没有任何可用分返还。无满意答复，必须提问满24小时才可以进行操作。 平均给分结帖：当回复过长参与人数过多时候，您可以使用平均给分的功能。 注：技术区不允许平均给分结帖。

user: user-0
content: 怎么给你分数？

user: user-1
content: 引用 4 楼 u014626834 的回复:谢谢！第一次玩C论坛，问题解决了之后怎么做呢？结贴吗？ 嗯，结贴，送我点分数

user: user-0
content: 谢谢！第一次玩C论坛，问题解决了之后怎么做呢？结贴吗？

user: user-1
content: 是的。free会根据指针，找到分配的空间，把它释放掉。

user: user-0
content: 在被调用函数中返回了的话，你的意思是在主函数中对接收的指针free(p1)吗？

user: user-1
content: 什么叫“指针内存”？是不是就是动态分配了一块空间？直接对返回的指针调用free(ptr)即可。
user-0 提问: 基础太差！请教一个c语言基础问题

回复:
user: user-1
content: 理解和讨论之前请先学会如何观察！  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-2
content: 楼上正解

user: user-3
content: char默认是signed，用整数常量128赋值，实际存入的是截断成一个字节的-128，十六进制是0x80。再赋值给a，扩展成整数-128，如果整数是32位的，就是0xffffff80，按无符号数解释，就是十进制的4294967168
user-0 提问: 请C预言功底扎实的朋友帮忙看一个小问题

回复:
user: user-1
content: 引用 5 楼 riscben 的回复:[quote=引用 1 楼 ri_aje 的回复:] 因为 const pSubParaAttribTyp const 的类型是 SubParaAttribTyp* const，所以匹配不上 const SubParaAttribTyp*.  const pSubParaAttribTyp const 里面有两个const，前一个const就是形容这个指针是指向一个const的SubParaAttribTyp结构体的[/quote] 你想当然了，两个 const 都是修饰 pSubParaAttribTyp 类型的，没有一个能够渗透到里面的 SubParaAttribTyp。

user: user-0
content: 引用 3 楼 u010087712 的回复:1、SubParaAttribTyp*和pSubParaAttribTyp确实是一样的，但是const SubParaAttribTyp*  与const pSubParaAttribTyp 并不 2、SubTBL_AAA 和SubTBL_BBB都是const SubParaAttribTyp*类型  我的问题就是第一条不理解 既然SubParaAttribTyp*和pSubParaAttribTyp是一样的 那么const SubParaAttribTyp* 和const pSubParaAttribTyp 为什么不一样？ 就是在各自的前面加个const而已 两个不都是应该指向const的SubParaAttribTyp结构体变量么？

user: user-0
content: 引用 1 楼 ri_aje 的回复:因为 const pSubParaAttribTyp const 的类型是 SubParaAttribTyp* const，所以匹配不上 const SubParaAttribTyp*.  const pSubParaAttribTyp const 里面有两个const，前一个const就是形容这个指针是指向一个const的SubParaAttribTyp结构体的，所以我不太明白为什么和const SubParaAttribTyp*匹配不上

user: user-0
content: 引用 7 楼 ri_aje 的回复:[quote=引用 5 楼 riscben 的回复:] [quote=引用 1 楼 ri_aje 的回复:] 因为 const pSubParaAttribTyp const 的类型是 SubParaAttribTyp* const，所以匹配不上 const SubParaAttribTyp*.  const pSubParaAttribTyp const 里面有两个const，前一个const就是形容这个指针是指向一个const的SubParaAttribTyp结构体的[/quote] 你想当然了，两个 const 都是修饰 pSubParaAttribTyp 类型的，没有一个能够渗透到里面的 SubParaAttribTyp。[/quote]  我再理一理 const pSubParaAttribTyp指的是指针本生是一个const型的，而不是它指向的对象是const型的？ 而const SubParaAttribTyp*指的是它指向的对象是const型的，指针本身不一定是const型的？ 所以两个不能匹配？

user: user-2
content: typedef typedef type-declaration synonym;  The typedef keyword defines a synonym for the specified type-declaration. The identifier in the type-declaration becomes another name for the type, instead of naming an instance of the type. You cannot use the typedef specifier inside a function definition.  A typedef declaration introduces a name that, within its scope, becomes a synonym for the type given by the decl-specifiers portion of the declaration. In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types.  Example  // Example of the typedef keyword typedef unsigned long ulong;  ulong ul;     // Equivalent to "unsigned long ul;"  typedef struct mystructtag {    int   i;    float f;    char  c; } mystruct;  mystruct ms;   // Equivalent to "struct mystructtag ms;"  typedef int (*funcptr)();  // funcptr is synonym for "pointer                            //    to function returning int"  funcptr table[10];   // Equivalent to "int (*table[10])();"

user: user-3
content: 1、SubParaAttribTyp*和pSubParaAttribTyp确实是一样的，但是const SubParaAttribTyp*  与const pSubParaAttribTyp 并不 2、SubTBL_AAA 和SubTBL_BBB都是const SubParaAttribTyp*类型

user: user-4
content: const pSubParaAttribTyp const ReferSubTBL[2]  这个肯定会错啊，SubTBL_AAA、SubTBL_BBB是数组首地址，是个指针。

user: user-1
content: 因为 const pSubParaAttribTyp const 的类型是 SubParaAttribTyp* const，所以匹配不上 const SubParaAttribTyp*.
user-0 提问: 关于fread的一个问题，有图，求教

回复:
user: user-1
content: 大概是端序问题，读完ImageData[i][j]加一句 ImageData[i][j] = _byteswap_ulong(ImageData[i][j]) 试试

user: user-2
content: 是不是没考虑字节序的问题哦，整数 0x12345678 在内存和文件中保存出来是 78 56 34 21

user: user-0
content: 太感谢了。。。问题已经解决。