C语言局部变量在内存栈中的顺序

来源:互联网 发布:tomcat怎么改端口号 编辑:程序博客网 时间:2024/05/16 13:53

首先总结规则,详细分析见下面:
规则1:内存由低到高优先分配给占位8字节、4字节、2字节、1字节的数据类型
数据类型占位说明:
8字节:double、longlong int
4字节:int、float、long int、unsigned int
2字节:short 、unsigned short
1字节:char 、unsigned char
例如,分别定义下列变量,内存地址中由低到高分别为:
double < int < short < char
规则2:同总占位的类型按定义变量的先后顺序内存地址会增加
规则3:在规则2前提下,定义数组不会和同总数据类型混占内存
下面看示例程序:

示例程序1#include <stdio.h>int main(int argc, const char *argv[]){    char char_a;    short short_a;    int int_a;    float float_a;    double double_a;    unsigned int uint_a;    long int lint_a;    long long int dlint_a;    printf("  &char_a : %p\n",&char_a);    printf(" &short_a : %p\n",&short_a);    printf("   &int_a : %p\n",&int_a);    printf(" &float_a : %p\n",&float_a);    printf("&double_a : %p\n",&double_a);    printf(" &unsigned_int_a : %p\n",&uint_a);    printf("     &long_int_a : %p\n",&lint_a);    printf("&long_long_int_a : %p\n",&dlint_a);    return 0;}测试结果1:*不同机器显示的内存地址会略有不同*  &char_a : 0xbfa844af &short_a : 0xbfa844ac   &int_a : 0xbfa8449c &float_a : 0xbfa844a0&double_a : 0xbfa84488 &unsigned_int_a : 0xbfa844a4     &long_int_a : 0xbfa844a8&long_long_int_a : 0xbfa84490

**分析:有结果可知变量下内存中的分布为(从低地址到高地址,()中为它们所占字节):
double(8)、long long int(8)、int(4) 、float(4)、unsigned int(4)、long int(4)、short(2)、char(1)
这里可以佐证规则1.**

示例程序2#include <stdio.h>int main(int argc, const char *argv[]){    char char_a;    short short_a;    int int_a;    float float_a;    double double_a;    unsigned int uint_a;    long int lint_a;    long long int dlint_a;    char char_b;    short short_b;    int int_b;    float float_b;    double double_b;    unsigned int uint_b;    long int lint_b;    long long int dlint_b;    printf("  &char_a : %p\n",&char_a);    printf("  &char_b : %p\n",&char_b);    printf(" &short_a : %p\n",&short_a);    printf(" &short_b : %p\n",&short_b);    printf("   &int_a : %p\n",&int_a);    printf("   &int_b : %p\n",&int_b);    printf(" &float_a : %p\n",&float_a);    printf(" &float_b : %p\n",&float_b);    printf("&double_a : %p\n",&double_a);    printf("&double_b : %p\n",&double_b);    printf(" &unsigned_int_a : %p\n",&uint_a);    printf(" &unsigned_int_b : %p\n",&uint_b);    printf("     &long_int_a : %p\n",&lint_a);    printf("     &long_int_b : %p\n",&lint_b);    printf("&long_long_int_a : %p\n",&dlint_a);    printf("&long_long_int_b : %p\n",&dlint_b);    return 0;}测试结果2:*不同机器显示的内存地址会略有不同*  &char_a : 0xbfde982e  &char_b : 0xbfde982f &short_a : 0xbfde982a &short_b : 0xbfde982c   &int_a : 0xbfde9808   &int_b : 0xbfde9818 &float_a : 0xbfde980c &float_b : 0xbfde981c&double_a : 0xbfde97e8&double_b : 0xbfde97f8 &unsigned_int_a : 0xbfde9810 &unsigned_int_b : 0xbfde9820     &long_int_a : 0xbfde9814     &long_int_b : 0xbfde9824&long_long_int_a : 0xbfde97f0&long_long_int_b : 0xbfde9800

分析:这里由int的两个变量a和b之间夹了float、unsigned int等变量,可以佐证规则2

测试案例3#include <stdio.h>int main(int argc, const char *argv[]){    char char_b[4];    int int_b[4];     char char_a;    short short_a;    int int_a;    printf("  &char_a : %p\n",&char_a);    printf(" &short_a : %p\n",&short_a);    printf("   &int_a : %p\n",&int_a);    printf("   &int_b : %p\n",int_b);    printf("  &char_b : %p\n",char_b);    return 0;}测试结果3*不同机器显示的内存地址会略有不同*  &char_a : 0xbf8fdcc7 &short_a : 0xbf8fdcc4   &int_a : 0xbf8fdcc0   &int_b : 0xbf8fdcb0  &char_b : 0xbf8fdcc8
测试案例4#include <stdio.h>int main(int argc, const char *argv[]){    char char_a;    short short_a;    int int_a;    int int_b[4];     char char_b[4];    printf("  &char_a : %p\n",&char_a);    printf(" &short_a : %p\n",&short_a);    printf("   &int_a : %p\n",&int_a);    printf("   &int_b : %p\n",int_b);    printf("  &char_b : %p\n",char_b);    return 0;}测试结果4*不同机器显示的内存地址会略有不同*  &char_a : 0xbfebf947 &short_a : 0xbfebf944   &int_a : 0xbfebf940   &int_b : 0xbfebf930  &char_b : 0xbfebf948

**分析:案例3和4可以说明数组类型会在规则1的前提下,满足规则3.
对于char类型变量,数组变量会存到高地址
对于int类型变量,数组变量会存到低地址
跟数组定义在前后没有关系**

测试案例5#include <stdio.h>int main(int argc, const char *argv[]){    double b[4];    double a;    printf("  &double_a : %p\n",&a);    printf("  &double_b : %p\n",b);    return 0;}测试结果:*不同机器显示的内存地址会略有不同* &double_a : 0xbfa3b688 &double_b : 0xbfa3b668测试案例6#include <stdio.h>int main(int argc, const char *argv[]){ double a;    double b[4];    printf("  &double_a : %p\n",&a);    printf("  &double_b : %p\n",b);    return 0;}测试结果:*不同机器显示的内存地址会略有不同* &double_a : 0xbfd3bda8 &double_b : 0xbfd3bd88

**分析:由案例5和6可知、
对于double类型变量,数组变量会存到低地址内存上,非数组变量会先对存到较高内存上,而与它们定义的先后没有关系

总结分析:由上面的结果(1和2的测试)也可以看到,在占位不同的数据类型相邻的内存会自动对齐占位较高的内存。对齐方式是在高位占有自己数据大小的空间.**

在数组方面还有short、unsigned int等没有测试,测试方法和案例5、6的方法一样,感兴趣的读者自行验证……

因本人时间和水平有限,文中如有错讹、不当之处,敬请大神斧正。

阅读全文
0 0
原创粉丝点击