内存分区
一、c/c++中内存分区:
程序代码区: 存放函数代码(二进制代码)
堆区(heap): 动态内存 在代码执行过程中由程序员分配和释放
栈区(stack): 局部变量和函数 在代码执行过程中由系统自动分配和释放
全局(静态)变量区 : 全局变量和静态变量
二、细谈分区
static:主要用于修饰链接属性,使其成为内部的。
static可以用于修饰局部变量,也可以用于修饰全局变量。
(1) 局部变量
定义在函数内部的变量叫做局部变量
局部变量只在本函数中有效,本函数外不能使用。
如果局部变量定义在子函数中,那么只能在子函数中使用,该子函数调用完,系统为该子函数中的局部变量分配的内存空间就会被释放。同理,如果局部变量定义在main函数中,那么只能在main中使用,main执行完后,系统为其中局部变量分配的内存空间就被释放。主函数也不能使用其他函数定义的变量。
(2)静态局部变量
用static修饰的局部变量称为静态局部变量,如果不用static修饰,存储在栈区,如果用static修饰,则存储在全局(静态)变量区
静态局部变量与局部变量的不同:
程序如下:
- #include<stdio.h>
- void Fun()
- {
- int a = 0;
- a++;
- printf("%d ", a);
- printf("\n");
- }
- void StaticFun()
- {
- static int a = 0;
- a++;
- printf("%d ", a);
- printf("\n");
- }
- int main()
- {
- printf("局部变量后结果:\n");
- for (int i = 0; i < 5; i++)
- {
- Fun();
- }
- printf("静态局部变量后结果:\n");
- for (int i = 0; i < 5; i++)
- {
- StaticFun();
- }
- return 0;
- }
运行结果:
上面的程序运行结果我们可以看出:Fun()函数用的是局部变量,而StaticFun()函数用的是静态局部变量。
局部变量每次调用结束后就会被释放,而静态局部变量即使整个函数调用结束后会也不会被释放。而是一直存在于程序运行的整个过程中,直到整个程序运行结束后才会被释放。
那是不是意味着静态局部变量每调用一次,就重新定义一次?
事实是:静态局部变量仅在第一次函数调用时定义并初始化,以后再次调用时,不需要重新定义和初始化,而是保留上一次函数调用结束后的值。即StaticFun()函数中的static int a=0只执行一次。
注意:
局部变量未初始化,默认值为随机值,静态局部变量未初始化,默认值为0。
区别主要源于它们存储空间不同。局部变量是在栈中,而静态局部变量是在全局(静态)区。
只要是在全局(静态)区中,未初始化,系统默认都为0。
(3)全局变量
定义在函数外部的变量叫做全局变量。
全局变量可以被整个c程序中所有函数所共用。
不同函数中可以定义同名的变量,但它们作用范围不同,代表不同的对象,互不干扰。需要注意的是,如果它们作用范围有所重叠,命名就不能相同。如果在同一范围内,它们命名相同,局部变量起作用,全局变量不起作用。
不建议使用全局变量
①全局变量在整个执行过程中都占内存,而局部变量仅在需要时才开辟存储单元。
②全局变量降低了函数的通用性,会使程序各函数之间关系变得复杂。
(4)静态全局变量
全局变量本身在全局(静态)区,但是仍然可以用static修饰。
a、全局变量加上static修饰更安全。
因为不加static的全局变量,看起来只能在本文件中使用,实际其他文件只需要一个extern对该全局变量进行一下声明,就可以将该全局变量的作用范围扩展到该文件中,这会使得程序很不安全。但是被static修饰后的全局变量,其他文件就算通过extern也不能访问该全局变量。
b、解决重名问题
一个项目中有很多文件时,重名不可避免。如果全局变量加上static修饰,这些全局变量就属于各自的.c文件了,它们是相互独立的。从而有效防止并解决全局变量重名问题。
(5)函数
头文件:存放对外函数的声明
源文件:存放函数的实现
主函数
头文件 #include"max.h"
max.h函数的源文件:
程序运行结果:
这种情况下,函数 int Max()还是有可能被其他文件利用extern声明被引用,如果不想被引用,可以在int Max()
前面加上static 则不会被外部引用。
程序不能成功运行
三、对比图
一、c/c++中内存分区:
程序代码区: 存放函数代码(二进制代码)
堆区(heap): 动态内存 在代码执行过程中由程序员分配和释放
栈区(stack): 局部变量和函数 在代码执行过程中由系统自动分配和释放
全局(静态)变量区 : 全局变量和静态变量
二、细谈分区
static:主要用于修饰链接属性,使其成为内部的。
static可以用于修饰局部变量,也可以用于修饰全局变量。
(1) 局部变量
定义在函数内部的变量叫做局部变量
局部变量只在本函数中有效,本函数外不能使用。
如果局部变量定义在子函数中,那么只能在子函数中使用,该子函数调用完,系统为该子函数中的局部变量分配的内存空间就会被释放。同理,如果局部变量定义在main函数中,那么只能在main中使用,main执行完后,系统为其中局部变量分配的内存空间就被释放。主函数也不能使用其他函数定义的变量。
(2)静态局部变量
用static修饰的局部变量称为静态局部变量,如果不用static修饰,存储在栈区,如果用static修饰,则存储在全局(静态)变量区
静态局部变量与局部变量的不同:
程序如下:
- #include<stdio.h>
- void Fun()
- {
- int a = 0;
- a++;
- printf("%d ", a);
- printf("\n");
- }
- void StaticFun()
- {
- static int a = 0;
- a++;
- printf("%d ", a);
- printf("\n");
- }
- int main()
- {
- printf("局部变量后结果:\n");
- for (int i = 0; i < 5; i++)
- {
- Fun();
- }
- printf("静态局部变量后结果:\n");
- for (int i = 0; i < 5; i++)
- {
- StaticFun();
- }
- return 0;
- }
运行结果:
上面的程序运行结果我们可以看出:Fun()函数用的是局部变量,而StaticFun()函数用的是静态局部变量。
局部变量每次调用结束后就会被释放,而静态局部变量即使整个函数调用结束后会也不会被释放。而是一直存在于程序运行的整个过程中,直到整个程序运行结束后才会被释放。
那是不是意味着静态局部变量每调用一次,就重新定义一次?
事实是:静态局部变量仅在第一次函数调用时定义并初始化,以后再次调用时,不需要重新定义和初始化,而是保留上一次函数调用结束后的值。即StaticFun()函数中的static int a=0只执行一次。
注意:
局部变量未初始化,默认值为随机值,静态局部变量未初始化,默认值为0。
区别主要源于它们存储空间不同。局部变量是在栈中,而静态局部变量是在全局(静态)区。
只要是在全局(静态)区中,未初始化,系统默认都为0。
(3)全局变量
定义在函数外部的变量叫做全局变量。
全局变量可以被整个c程序中所有函数所共用。
不同函数中可以定义同名的变量,但它们作用范围不同,代表不同的对象,互不干扰。需要注意的是,如果它们作用范围有所重叠,命名就不能相同。如果在同一范围内,它们命名相同,局部变量起作用,全局变量不起作用。
不建议使用全局变量
①全局变量在整个执行过程中都占内存,而局部变量仅在需要时才开辟存储单元。
②全局变量降低了函数的通用性,会使程序各函数之间关系变得复杂。
(4)静态全局变量
全局变量本身在全局(静态)区,但是仍然可以用static修饰。
a、全局变量加上static修饰更安全。
因为不加static的全局变量,看起来只能在本文件中使用,实际其他文件只需要一个extern对该全局变量进行一下声明,就可以将该全局变量的作用范围扩展到该文件中,这会使得程序很不安全。但是被static修饰后的全局变量,其他文件就算通过extern也不能访问该全局变量。
b、解决重名问题
一个项目中有很多文件时,重名不可避免。如果全局变量加上static修饰,这些全局变量就属于各自的.c文件了,它们是相互独立的。从而有效防止并解决全局变量重名问题。
(5)函数
头文件:存放对外函数的声明
源文件:存放函数的实现
主函数