c语言堆和栈的小问题和程序在vc6和GCC下遇到的不同区别
2016-06-27 19:40
302 查看
question one
首先,看看这结果是什么?
结果是 100,200
好的,我再将注释全部消去;
结果又是什么呢?
结果是100 ,43984126
也就是后面的*v2 出现了一堆乱码。
这又是为什么呢?
malloc 和new 语句创建的内存空间存放在堆
局部变量存放在栈上,malloc是从堆区申请空间,函数结束后不会自动释放,如果不人为地释放的话,要等到程序结束后,系统才会自动回收
但是关键的是第一次的程序,输出是正常的
那为什么呢,如果局部变量失效了,为什么第一次可以呢
而且为什么加了GetNumber3之后就不行了~
GetNumber3看代码其实什么也没做对吧~~
返回值也没有赋值出去~
之前成功的输出了100 200
那到底是怎么影响的呢~~
要从代码中看到内存数据的变化~
程序的内存开辟区域有三类
静态存储区,堆,栈
静态变量存放在静态存储区~
malloc 和new 语句创建的内存空间存放在堆
局部变量存放在栈上
代码都是放在栈空间执行的,所以局部变量都是在栈上开辟的
GetNumber3 其实的作用就是覆盖了栈空间
在没有GetNumber3的时候,printf 执行时,获取v2时,栈空间中V2上的值还是100
比如程序的执行顺序是1 2 3 4 5 6 7 8 9 10
在3处调用了函数GetNumber2
函数返回后 那么v2指向的地址是4(值200的地址)~
此时函数回到3继续执行接下来的代码,
在printf的情况下,代码执行获取v1 和v2指向的值,此时4中的值还是200
所以输出的是100 200
如果先遇到了GetNumber3那么,GetNumber3的程序代码执行之后就覆盖了4的地址~
这时候再执行printf,获取v2指向的值的时候,就成了随机数~
其实也不是随机数,而是此时4上的值,不过已经被GetNumber3的代码段覆盖了而已!
函数保留原来的数据,也是有条件的
局部变量跨作用域是很危险的哈~
question two
这里的输出应该是什么呢?
6 5 4 3?or 0 0 0 0;
不,结果是5 4 3 2.
我们将所有的n都分别输出看看,会发现,5 4 3 2 1 0;
将注释消去,发现n是6;
也就是说
滞后自增,会在整个语句之后起到作用,在printf语句中也是一样的。
很奇怪,在vc6.0环境下,输出结果完全不同 是
0 0 0 0和6 5 4 3 2 1
Visual C++6.0用的是vc编译器,DEV-C++用的是mingw-gcc编译器。两个东西不同的。要说标准,肯定是gcc比较符合c++标准。但是要说效率,在windows平台上,gcc的效率还是比不上vc的
Visual C++6.0很多Ansi C和C++的标准都不支持,因为太老了,是96年开发的,而C语言新的标准是99年定的,因此,很多新的东西都不支持,这是第一。第二,VC6是Ms开发的,MS的编译器都比较一般;DEV-C++其内核是GNU的。
gcc执行流程 源文件→预处理→编译→汇编→链接→可执行文件
#include"stdio.h" #include"stdlib.h" int * getnumber() { int *a; int*a=(int*)malloc(sizeof(int)); *a=100; return a; } int * getnumber2() { int a=200; return &a; } int getnumber3() { return 0; } int main() { int *v1=getnumber(); int *v2 =getnumber2(); //getnumber3(); printf("%d,%d",*v1,*v2) ; }
首先,看看这结果是什么?
结果是 100,200
好的,我再将注释全部消去;
#include "stdio.h" #include "stdlib.h" int * getnumber() { int *a; int*a=(int*)malloc(sizeof(int)); *a=100; return a; } int * getnumber2() { int a=200; return &a; } int getnumber3() { return 0; } int main() { int *v1=getnumber(); int *v2 =getnumber2(); getnumber3(); printf("%d,%d",*v1,*v2) ; }
结果又是什么呢?
结果是100 ,43984126
也就是后面的*v2 出现了一堆乱码。
这又是为什么呢?
malloc 和new 语句创建的内存空间存放在堆
局部变量存放在栈上,malloc是从堆区申请空间,函数结束后不会自动释放,如果不人为地释放的话,要等到程序结束后,系统才会自动回收
但是关键的是第一次的程序,输出是正常的
那为什么呢,如果局部变量失效了,为什么第一次可以呢
而且为什么加了GetNumber3之后就不行了~
GetNumber3看代码其实什么也没做对吧~~
返回值也没有赋值出去~
之前成功的输出了100 200
那到底是怎么影响的呢~~
要从代码中看到内存数据的变化~
程序的内存开辟区域有三类
静态存储区,堆,栈
静态变量存放在静态存储区~
malloc 和new 语句创建的内存空间存放在堆
局部变量存放在栈上
代码都是放在栈空间执行的,所以局部变量都是在栈上开辟的
GetNumber3 其实的作用就是覆盖了栈空间
在没有GetNumber3的时候,printf 执行时,获取v2时,栈空间中V2上的值还是100
比如程序的执行顺序是1 2 3 4 5 6 7 8 9 10
在3处调用了函数GetNumber2
函数返回后 那么v2指向的地址是4(值200的地址)~
此时函数回到3继续执行接下来的代码,
在printf的情况下,代码执行获取v1 和v2指向的值,此时4中的值还是200
所以输出的是100 200
如果先遇到了GetNumber3那么,GetNumber3的程序代码执行之后就覆盖了4的地址~
这时候再执行printf,获取v2指向的值的时候,就成了随机数~
其实也不是随机数,而是此时4上的值,不过已经被GetNumber3的代码段覆盖了而已!
函数保留原来的数据,也是有条件的
局部变量跨作用域是很危险的哈~
question two
#include"stdio.h" int main() { int n=0; printf("%d %d %d %d\n",n++,n++,n++,n++,n++,n++); }
这里的输出应该是什么呢?
6 5 4 3?or 0 0 0 0;
不,结果是5 4 3 2.
#include"stdio.h" int main() { int n=0; printf("%d %d %d %d %d %d\n",n++,n++,n++,n++,n++,n++); //printf("%d",n); }
我们将所有的n都分别输出看看,会发现,5 4 3 2 1 0;
将注释消去,发现n是6;
也就是说
滞后自增,会在整个语句之后起到作用,在printf语句中也是一样的。
很奇怪,在vc6.0环境下,输出结果完全不同 是
0 0 0 0和6 5 4 3 2 1
Visual C++6.0用的是vc编译器,DEV-C++用的是mingw-gcc编译器。两个东西不同的。要说标准,肯定是gcc比较符合c++标准。但是要说效率,在windows平台上,gcc的效率还是比不上vc的
Visual C++6.0很多Ansi C和C++的标准都不支持,因为太老了,是96年开发的,而C语言新的标准是99年定的,因此,很多新的东西都不支持,这是第一。第二,VC6是Ms开发的,MS的编译器都比较一般;DEV-C++其内核是GNU的。
gcc执行流程 源文件→预处理→编译→汇编→链接→可执行文件
相关文章推荐
- 一步一步跟我学易语言之第二个易程序菜单设计
- C#中sizeof的用法实例分析
- 浅析C语言中的sizeof
- 深入sizeof的使用详解
- C语言中的sizeof操作符用法及和strlen的区别
- c语言中malloc、realloc与calloc 的区别以及联系
- C++中new与delete、malloc与free应用分析
- sizeof()的简单介绍
- FCK编辑器(FCKEditor)添加新按钮和功能的修改方法
- ecshop后台编辑器替换成ueditor编辑器
- jquery可定制的在线UEditor编辑器
- 10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
- C语言中的malloc使用详解
- C语言中sizeof()与strlen()函数的使用入门及对比
- 基于Sizeof与Strlen的区别以及联系的使用详解
- 浅析C/C++中被人误解的SIZEOF
- PHP网页 Ewebeditor 编辑器嵌入方法
- kindSoft在线网页编辑器简单的配置参数介绍
- dedecms5.5 最新版ckeditor编辑器整合教程
- javascript 在线文本编辑器实现代码