#### 代码段 ####
/*
代码段:存放函数代码,字符串常量。只读,不可更改
*/
#include <stdio.h>
int main(void)
{
char buf[] = "123456"; //栈变量
char buf1[] = "123456";
printf("buf address = %p \n",buf);
printf("buf1 address = %p \n",buf1);
char *p1 = "123456"; //指向代码段变量
char *p2 = "123456";
printf("p1 address = %p \n",p1);
printf("p2 address = %p \n",p2);
/*
buf address = 0x7fffc87b58b0
buf1 address = 0x7fffc87b58a0
p1 address = 0x400687
p2 address = 0x400687
p1 和 p2 都是指向了同一个字符串(存放再代码段的字符串),所以p1和p2的大小一样
而buf 和buf1是在栈内开辟的新空间存放两个字符串(栈内存上),所以buf和buf1不相等
*/
return 0;
}
#### 其他内存段 ####
/*
4,只读段:const修饰的变量,生命周期伴随整个程序,作用域:代码块作用域
5,文件映射区:打开的文件(动态文件)存放的地方
6,OS内核映射区:每个进程都必须需要一个内核映射区
7,data段(数据段):非0的全局变量和static修饰的非0的局部变量,生命周期伴随整个程序,作用域:创建后(全局)一直可以使用,代码块(局部)作用域
static修饰的全部变量,改变的是连接属性,变成了内链接,只能本文件使用。
函数默认是外链接,整个工程(很多.c文件),static修饰的函数,可以改变函数
的链接属性,使之成为内链接,使函数仅能再本文件使用
注意:
C程序:编写,编译(编译和链接两步),单纯执行编译,就已经是二进制文件,但是没有顺序,链接的目的就是让这些二进制文件有序
8,.bss段:不初始化的全剧变量和不初始化的static修饰的局部变量,或者初始化为0的全剧变量,static修饰的局部变量
*/
/*
有操作系统下的C语言程序:
你自己写的C程序,是不能运行的,依赖于操作系统给你提供的引导代码,将程序>加载进虚拟内存。引导代码不是自己写的,是操作系统帮忙实现的。在程序位进行编译之前
,.data段就已经完成了赋值,而且.bss段进行清0
无操作系统下的C程序(典型例子就是单片机)
写好的C程序,必须放到固定的地址才可以执行。这些固定的地址,由手册提供。
注意:
这块有个概念:地址无关码和地址有关码。一般来说操作系统提供引导代码的都是
地址无关码,而无操作系统下的程序,大多数是地址有关码(仅仅是大多数)
*/
#include <stdio.h>
int func_static(void)
{
static int a = 1;
a++;
return a;
}
char *func_string(void) //代码段
{
char *p = NULL;
p = "123";
return p;
}
extern int g_a;
//extern int g_b;
extern func_quanju();
//extern int g_c = 22;//warning: ‘g_c’ initialized and declared ‘extern’
//注意:声明时不能有初始化语句,因为会把次认作为定义。注意定义和
声明的区别
int g_d = 0;//定义一个全剧变量,如果没有初始化,则默认是0(不初始化的全局变量再.bss段,而.bss段内数据全被写0);注意:当有局部定义时,局部定义优先(强龙不压地头蛇
)
void func_g(void)
{
g_d = 33;
}
int main()
{
#if 1
func_g();//调用子函数,子函数里使用全剧变量
printf("g_d = %d \n",g_d);
static int g_d = 44;//局部变量,并且存储位置发生了变化。存在了数据段
printf("g_d = %d \n",g_d);
#endif
// printf("g_c = %d \n",g_c);
printf("g_b = %d \n",func_quanju());
printf("g_a = %d \n",g_a);
printf("p = %s \n",func_string());
#if 0
int num = 3, ret = 0;
while (num--)
{
ret += func_static();
//2 5 9
//2:ret = ret +func_static() = 0+2
//5:ret = ret +func_static() = 2+3
//9:ret = ret +func_static() = 5+4
//注意:static修饰的局部变量只初始化一次,多次调用维持上次的结>果不变;也就是说,子函数func_static()函数中a = 1;只被初始化了一次,第二次执行子
函数时,a初始值已经时2,执行a++ 返回3
printf("ret = %d \n",ret);
}
#endif
return 0;
}
创建第二个.c文件
int g_a = 24;
int g_b = 24;
int g_c = 24;
//static int g_a = 24;//error: ld returned 1 exit status 错误:链接错误;因为static修饰后改变链接属性,改为内链接,不能通过声明被其他.c文件调用;
int func_quanju()
{
g_b = 12;
return g_b;
}