一、内存分区简介
操作系统会用某个手段来完成虚拟内存到物理内存的映射。在运行程序的时候,操作系统会将虚拟内存进行分区。我们写应用程序的,看到的都是虚拟地址。
- 堆:动态申请内存的时候,在堆里开辟内存。
- 栈:主要存放局部变量。
- 静态全局区:
- 未初始化的静态全局区:静态变量或全局变量,没有被初始化的,存在此区。
- 初始化的静态全局区:全局变量、静态变量、赋过初值的,存放在此区。
- 代码区:存放程序的代码
二、变量
- 普通全局变量:
- 定义:在函数外部定义的变量。
- 作用范围:程序的所有地方。
- 除了定义的.c文件下,要在别的.c文件中使用,必须使用extern关键字声明。
- 用extern声明时一定不能赋值。
- 生命周期:程序运行的整个过程中,一直存在,知道程序结束。
- 定义普通全局变量的时候,如果不赋初值,则默认为0。
#include<stdio.h>
int num = 100;//普通全局变量
int main() {
}
- 静态全局变量:
- 定义全局变量的时候,在前面加上static。
- 作用范围:static限定了全局变量的作用范围,使其只能在它定义的.c中生效。
- 生命周期:在程序运行过程一直存在。
- 如果不赋初值,那么默认为0。
#include<stdio.h>
static int num = 100;//静态全局变量
int main() {
printf("%d", num);
}
- 普通局部变量:
- 定义:在函数内部或复合语句中定义,只在该函数内部或复合语句中有效。
- 生命周期:函数或复合语句结束后释放。
#include<stdio.h>
int main() {
int num = 100;
{
num = 20;
int a = 10;
}
}
- 静态的局部变量:
- 定义和作用范围同普通局部变量。
- 生命周期:在第一次调用函数时,开辟空间赋值,函数结束后,不释放,以后再调用函数时,就不再开辟空间,也不赋初值,用的还是第一次那个变量。
#include<stdio.h>
void func();
int main() {
func();
func();
func();
}
void func() {
static int num = 100;
num++;
printf("num:%d %d\n", num, &num);
}
运行结果:
- 变量重名问题(拓展)
- 在同一作用范围内,不允许变量重名。
- 作用范围不同可以重名。
- 局部范围内,重名的变量按照就近原则起作用。
#include<stdio.h>
int num = 100;
int main() {
int num = 200;
printf("num = %d", num);//结果是200,就近原则
return 0;
}