c语言中变量的存储位置

本文探讨了C语言中变量的存储位置,包括全局变量、局部变量、静态变量的存储规则。通过实验发现,全局变量按初始化状态存放,静态局部变量存储在静态存储区,而new运算符在堆中分配内存。链表操作揭示了内存分配特点,同时提出了一些未解的问题,如未初始化全局变量间的4个字节区域用途等,邀请读者一起探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编写了一点代码,用来检测c语言中变量在内存中存储位置的检测,环境为minGW+codebloks+win7。

先上代码:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

typedef struct Node
{
    int data;
    Node*next;
}Node;
typedef struct Link_Table
{
    Node*head;
    Node first;
    int* Add(int i)
    {
        Node new_node;
        new_node.data=i;
        new_node.next=first.next;
        first.next=&new_node;
        int x=50;
        return &x;
    }
    void Add_heap(int i)
    {
        Node *new_node=new Node;
        new_node->data=i;
        new_node->next=first.next;
        first.next=new_node;
    }
}Link_Table;
int a=1;
int b=2;
static int c;
static int d;
int j;
int k;
static int l=1;
static int m=4;
int main()
{
    int e;
    int f=10;
    int g=5;
    int h;
    int i;
    static int n;
    static int o=4;

    Link_Table test;
    test.head=&test.first;
    test.first.next=NULL;
    int *x=test.Add(1);
    test.Add_heap(2);
    test.Add_heap(3);

    cout<<"globle,unstatic,inited:"<<endl;
    cout<<&a<<endl;
    cout<<&b<<endl;

    cout<<"globle,static,inited:"<<endl;
    cout<<&l<<endl;
    cout<<&m<<endl;

    cout<<"globle,unstatic,uinited:"<<endl;
    cout<<&j<<endl;
    cout<<&k<<endl;

    cout<<"globle,static,uinited:"<<endl;
    cout<<&c<<endl;
    cout<<&d<<endl;

    cout<<"auto,uinited:"<<endl;
    cout<<&e<<endl;
    cout<<"auto,inited:"<<endl;
    cout<<&f<<endl;
    cout<<&g<<endl;
    cout<<"auto,uinited:"<<endl;
    cout<<&h<<endl;
    cout<<&i<<endl;
    cout<<"auto,static,uninited:"<<endl;
    cout<<&n<<endl;
    cout<<"auto,static,inited:"<<endl;
    cout<<&o<<endl;

    cout<<"List_Table:"<<endl;
    cout<<"addr_test:"<<&test<<endl;
    cout<<"addr_test.head:"<<&(test.head)<<endl;
    cout<<"头节点:"<<endl;
    cout<<"addr_first_Node:"<<&(test.first)<<endl;
    cout<<"addr_firstNode.data:"<<&(test.first.data)<<endl;
    cout<<"addr_firstNode.next:"<<&(test.first.next)<<endl;
    cout<<"first_Node.data:"<<test.first.data<<endl;
    cout<<"first_Node.next:"<<test.first.next<<endl;
    cout<<"Node1:"<<endl;
    cout<<"addr_Node1:"<<test.first.next<<endl;
    cout<<"addr_Node1.data:"<<&(test.first.next->data)<<endl;
    cout<<"addr_Node.next:"<<&(test.first.next->next)<<endl;
    cout<<"Node1.data:"<<test.first.next->data<<endl;
    cout<<"Node1.next:"<<test.first.next->next<<endl;
    cout<<"Node2:"<<endl;
    cout<<"addr_Node2:"<<test.first.next->next<<endl;
    cout<<"addr_Node2.data:"<<&(test.first.next->next->data)<<endl;
    cout<<"addr_Node2.next:"<<&(test.first.next->next->next)<<endl;
    cout<<"Node2.data:"<<test.first.next->next->data<<endl;
    cout<<"Node2.next:"<<test.first.next->next->next<<endl;
    cout<<"Node3:"<<endl;
    cout<<"addr_Node3:"<<test.first.next->next->next<<endl;
    cout<<"addr_Node3.data:"<<&(test.first.next->next->next->data)<<endl;
    cout<<"addr_Node3.next:"<<&(test.first.next->next->next->next)<<endl;
    cout<<"Node3.data:"<<test.first.next->next->next->data<<endl;
    cout<<"Node3.next:"<<test.first.next->next->next->next<<endl;
    cout<<"*x:"<<x<<endl;
    cout<<"x:"<<*x<<endl;
    return 0;
}

这段代码声明了初始化的全局变量,未初始化的全局变量,静态初始化的全局变量,静态未初始化的全局变量·;在主函数内部声明了初始化的局部变量,未初始化的局部变量;静态初始化的局部变量;静态未初始化的局部变量。

同时,为了研究在主函数内调用结构体成员函数的变量情况,写了一个很简单的链表。链表中有两个向链表中添加节点的方法。两个函数都采用了头插法的方式连唯一的区别就在于一个采用了直接定义的方法,另一个则是通过new运算符为新添加的节点分配空间。代码运行结果如下:




通过对以上数据的分析,可以得到以下结果:

(1)全局变量首先按照是否初始化分开存放。在已初始化的部分中,首先存储非静态变量,之后是静态变量;在未初始化的部分中,也是首先存储静态的变量,之后存储静态变量。

(2)局部变量存储在桟中,桟从高地址向低地址延伸。并且非静态局部变量的存储没有是否初始化之分(实际上编译器会将初始化的局部变量处理为声明和复制两部分);而静态局部变量的存储方式与非静态局部变量的存储方式有很大不同。静态局部变量同全局变量一样,存储在静态存储区中。可以看到,静态初始化的局部变量紧接着初始化的静态全局变量存放;静态未初始化的局部变量紧挨着静态未初始化的全局变量存放。

(3)向链表中插入了3个节点,节点1、2由new生成,在堆中分配内存,且北村由低地址向高地址延伸。

(4)节点3是直接声明的,从结果总看似乎与之前在主函数中声明的非静态局部变量存储于同一区域中,并且在结构体成员函数中声明的局部变量在退出成员函数后地址不再有效。因此,应该可以说明在结构体的成员函数中声明的变量仍属于局部变量,在桟中为其分配内存,在成员函数退出后不再有效。

仍然有疑问的几个地方:

(1)从结果中可以看到,已初始化的全局变量中,非静态的与静态的是相邻存放的;然而在未初始化的全局变量中,非静态的与静态的之间有4个字节的区域,不清楚这4个字节的用处是什么;

(2)在链表的成员函数中直接声明的Node的地址与紧邻Node声明的局部变量之间相差了较多空间,不清楚相差的空间的作用是什么;

(3)通过new在堆中生成的两个节点之间相差8个字节,对于这8个字节的用处尚不清楚

以上就是通过这段代码对c语言变量在内存中存储位置的一点研究,欢迎大家讨论交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值