代码段(.text)、数据区(.data)和bss段

一、三个常用段

编译器在编译程序的时候,将程序中的所有元素分成一些部分,各部分构成一个段,段是可执行程序的组成部分。

  1. 代码段:程序中的可执行部分,是由函数堆叠而成的
  2. 数据段(数据区、静态数据区、静态区):程序中的数据,C语言中的全局变量(全局变量才算程序的数据,局部变量是函数的数据)
  3. bss段(ZI段zero initial)):被初始化为0bss段本质上也是属于数据段。也就是说bss段就是被初始化为0的数据段。

本质上来说.databss都是用来存放C程序中的全局变量的。区别在于把显式初始化为非零的全局变量存放在.data段中,把显式初始化为0或没有显式初始化的全局变量存放在bss段中。(这也就是为什么C语言中未显式初始化的全局变量的值为默认为0

二、代码段

除程序的可执行部分外,一些特殊类型的数据也会被存放在代码段

  1. C语言中定义的字符串常量
  2. const型常量:C语言const关键字用来定义常量
  • 在单片机的编译器中,将cosnt修饰的变量放在代码段实现无法被修改,这是绝对安全的
  • gcc中,const型常量和普通变量一样被放在数据区,由编译器来检查以确保const型的常量不会被修改(其实是可以通过指针修改的)

测试代码

#include 

int main(void)
{
    char *p = "WHUT2020";

    *(p + 6) = '1';
    *(p + 7) = '8';

    printf("p = %s\n", p);
    return 0;
}

测试结果

在这里插入图片描述
在上述代码中,本意是想将*p替换为WHUT2018,却引发了段错误,这是因为C语言中定义的字符串是一个常量,并不是变量,是被放在代码段的,是不允许被修改的,实质上等同于const char *p = "WHUT2020"

三、数据段(.data)

数据段和堆内存几乎拥有完全相同的属性,只是生命周期不一样。数据段伴随程序一生,堆内存从mallocfree

  1. 显示初始化为非零的全局变量
  2. 静态局部变量(也就是static修饰的局部变量)
  • 普通局部变量分配在栈上,静态局部变量分配在.data
#include 

int a = 10;//.data
void func(void)
{
    static int b = 10;//.data
    int c = 10;//栈
}
int main(void)
{
    return 0;
}

四、bss段

  1. 显式初始化为零的全局变量
  2. 未显式初始化的全局变量

五、样例

#include 
#include 
#include 

/*显示初始化的全局变量,储存在.data段*/
char str[] = "WHUT2018";

int main(void)
{
    /*局部变量,储存在栈上*/
    char str2[] = "WHUT2018";

    /*字符串常量,存储在代码段*/
    char *p1 = "WHUT2020";

    /*存储在malloc申请的堆内存中*/
    char *p2 = (char *)malloc(sizeof(str2));  
    if(!p2)
    {
        printf("MALLOC ERROR.\n");
        return -1;
    }
    memset(p2, 0, 10);
    strcpy(p2, "WHUT2018");
    free(p2);
}

你可能感兴趣的:(C语言)