赞
踩
编译器在编译程序的时候,将程序中的所有元素分成一些部分,各部分构成一个段,段是可执行程序的组成部分。
- 代码段:程序中的可执行部分,是由函数堆叠而成的
- 数据段(数据区、静态数据区、静态区):程序中的数据,
C语言
中的全局变量(全局变量才算程序的数据,局部变量是函数的数据)bss段
(ZI段
(zero initial
)):被初始化为0
,bss段
本质上也是属于数据段。也就是说bss段
就是被初始化为0
的数据段。
本质上来说.data
和bss
都是用来存放C程序
中的全局变量的。区别在于把显式初始化为非零的全局变量存放在.data段
中,把显式初始化为0
或没有显式初始化的全局变量存放在bss段
中。(这也就是为什么C语言
中未显式初始化的全局变量的值为默认为0
)
除程序的可执行部分外,一些特殊类型的数据也会被存放在代码段
C语言
中定义的字符串常量const型
常量:C语言
中const
关键字用来定义常量
- 在单片机的编译器中,将
cosnt
修饰的变量放在代码段实现无法被修改,这是绝对安全的- 在
gcc
中,const
型常量和普通变量一样被放在数据区,由编译器来检查以确保const
型的常量不会被修改(其实是可以通过指针修改的)
#include <stdio.h>
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"
数据段和堆内存几乎拥有完全相同的属性,只是生命周期不一样。数据段伴随程序一生,堆内存从malloc
到free
- 显示初始化为非零的全局变量
- 静态局部变量(也就是
static
修饰的局部变量)
- 普通局部变量分配在栈上,静态局部变量分配在
.data
段
#include <stdio.h>
int a = 10;//.data
void func(void)
{
static int b = 10;//.data
int c = 10;//栈
}
int main(void)
{
return 0;
}
- 显式初始化为零的全局变量
- 未显式初始化的全局变量
#include <stdio.h> #include <stdlib.h> #include <string.h> /*显示初始化的全局变量,储存在.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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。