C语言中定义变量的内存分配顺序问题_电气自动化网
首页 资讯 应用 高压 设计 行业 低压 电路图 关于

单片机

旗下栏目: PLC 嵌入式 单片机 DCS

C语言中定义变量的内存分配顺序问题

单片机 | 发布时间:2018-06-01 | 人气: | #评论# | 本文关键字:C语言,C,变量,内存
摘要:对于c语言中大家都知道所有的变量都必须是先定义后使用的,但是但是,对于好多人而言,基本上没有人(不管是老手还是菜鸟)来注意自己的编译器和操作系统对这个东西是如何处理的:

对于c语言中大家都知道所有的变量都必须是先定义后使用的,但是但是,对于好多人而言,基本上没有人(不管是老手还是菜鸟)来注意自己的编译器和操作系统对这个东西是如何处理的:

1,如果全是一样的类型,比如全是int(char,double,float),编译器会如何分配呢??是从大到小还是从小到大,,

2, 数组的分配方式和基本类型一样吗??编译器又是如何处理的??

3, 如果是基本类型和数组混合呢??

4,倘使是不同的操作系统呢,??它又有什么不同呢??

好了,接下来,我们大家一起看一看吧!!

(注意:下面我们的程序都是在:dev-C++ 5.11,  win7,32位的系统下运行的结果)

1.全是一样的类型

  1. #include<stdio.h>  

  2. #include<conio.h>  

    int main(){  

  3.       

  4.     int a;  

  5.     int b;  

  6.     int c;  

  7.       

  8.     printf("a is ip:%p\n", &a);  

  9.     printf("b is ip:%p\n", &b);  

  10.     printf("c is ip:%p\n", &c);  

  11.       

  12.     printf("nihao, mingtian");  

  13.       

  14.     getch();  

  15.     return 0;  

  16. }  

好,接下来我们看一看结果!


由图可知,我们的编译器和系统给它们分配的时候是,先找了一块空闲区,确定了之后,然后将高地址给了第一个定义的变量,将次高地址给了第二个变量,其他依次类推,可以得出,我们的地址分配是从高到底的!!


下面这个是全是char类型时候的分配情况,所以说我们上面的总结是正确的!

当然我相信,就是全部换成float,double也是一样得

2, 数组的话

  1. #include<stdio.h>  

  2. #include<conio.h>  

  3. int main(){   

  4.     char a[3];  

  5.     printf("a[0]'s is ip:%p\n", &a);  

  6.     printf("a[0] is ip:%p\n", &a[0]);  

  7.     printf("a[1] is ip:%p\n", &a[1]);  

  8.     printf("a[2] is ip:%p\n", &a[2]);  

  9.     printf("a[3] is ip:%p\n", &a[3]);    

  10.     printf("nihao, mingtian");   

  11.     getch();  

  12.     return 0;  

  13. }  

可以看到结果:


大家可以很清楚的看到,我们的编译器和操作系统对其的分配方式

还是同样的道理,先找空闲区,然后将数组里的第一个元素分到了底地址处,将第二个分配到了次底地址处,后面的同理,所以我们可以总结一下:对于数组,分配方式是从低到高,跟基本类型的分配方式不一样,

此时,我们大家再来看一个例子:

  1. #include<stdio.h>  

  2. #include<conio.h>  

  3. int main(){  

  4.     char a[3];  

  5.     char b[2];  

  6.     printf("a[0]'s is ip:%p\n", &a);  

  7.     printf("a[0] is ip:%p\n", &a[0]);  

  8.     printf("a[1] is ip:%p\n", &a[1]);  

  9.     printf("a[2] is ip:%p\n", &a[2]);  

  10.     printf("a[3] is ip:%p\n\n\n", &a[3]);  

  11.     printf("b[0] is ip:%p\n", &b[0]);  

  12.     printf("b[1] is ip:%p\n", &b[1]);  

  13.     printf("b[2] is ip:%p\n", &b[2]);  

  14.     printf("nihao, mingtian");  

  15.     getch();  

  16.     return 0;  

  17. }  

  18. 大家看结果:


请大家务必牢记:这里经常被好多人不重视:

现在我们也能清晰的看到:对于两个数组,我们可以将其看作两个基本类型,他们的内存分配遵从从高到低,所以我们可以看到a[0]的地址比b[0]高,

然后他们具体的位置取决于自己数组的大小,也就是说对于先定义a数组,然后再定义b数组的情况,现将整个a数组放在了高地址,将整个b数组放在了相对的次高地址

然后,具体对数组内部的东西进行分配处理,内部其实也就是我们上面说的分配从低到高

大家可能会很有疑惑为什么a[0],b[2]的地址是一样的??

大家不妨自己想一想,其实也很简单:

先定义a数组,整体放在了高地址处,而对于数组内部a[0]放在了相应的底地址处(0022febd)

而对于数组b,整体放在了底地址处,同理数组内部b[2]也就放在了相对于b[0](0022febb)处的高位,也就是(0022febd)

但是,但是,但是,大家一定要清楚,此时我们的是C,所以我们的编译器此时是对b[2]是不分配的内存的,如果我们非要取出东西或探究地址,那也只能在b[1]地址(0022febc)的相对下一个,也就是a[0]的地址了

3:混合(基本类型和数组)

#include<stdio.h>  

  1. #include<conio.h>  

  2. int main(){  

  3.     int a;  

  4.     char b[2];  

  5.     int c;  

  6.     printf("a is ip :%p \n", &a);  

  7.     printf("b[0] is ip:%p\n", &b[0]);  

  8.     printf("b[1] is ip:%p\n", &b[1]);  

  9.     printf("b[2] is ip:%p\n", &b[2]);  

  10.     printf("c is ip :%p\n", &c);  

  11.     printf("nihao, mingtian");  

  12.     getch();  

  13.     return 0;  

  14. }  

运行结果如下:


同样的:我们分析还是将数组当做基本类型对待

所以a变量在内存地址最高位,b数组在内存地址次高位,c其次,

当a确定了位置(0022febc)后,也就确定了b[0](0022feba),因为数组是从低到高,b[1]是(0022febb),b[2]是(0022febc)(注意b[2]应该不存在,也就是没有为其分配内存,所以也就是b[1]的位置相对下一个,也就是a的地址处),同理也就确定了C的地址(0022feb4)

至于为什么是b4,而不是b9,大家如果有兴趣的话可以看看我的另外一篇博客

关于内存结构体共用体在linux/window下的分配情况:

好好,接下来我们来看看linux下是如何做的:

我们也可以很清楚的看到,里面的三个变量的类型是一样的,都是int

结果如下:

同样的,大家可以看到,变量a先定义,但是a的地址还低(0x7ffc4fb9c134)

然后定义变量b,b的地址比a要高一点(0x7ffc4fb9c138

然后依次c,地址为(0x7ffc4fb9c13c

所以,我们可以同样总结,在linux(我的是ubuntu kylin 14.04)下,一般来说,对于基本变量的分配是从低地址到高地址的

当然不管是window还是linux下,

定义  :   int   a, b, c;

int  a;

int  b;

int  c;

上面两个都是一样的!!!!分配方式是并不影响的

2, linux下的数组


可以看到上面是对数组的检验:

结果如下:

好啦,我们可以分析结果,首先根据a[0],a[1],a[2]的地址的大小,知道对于数组也是如window,是从低到高的

而如果我们将两个数组都当做基本类型,大家注意,这里可就跟上面不一样了,从高到低的,


责任编辑:变量
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。