随着工作中琐事越来越多,静下来好好敲代码的时间越来越少,基础知识虽然简单,但常看常新,并记录下来共勉。
一、基础知识点
1. 内存区域中数据管理
在C和C++中,内存分为多个区域,每个区域负责存储不同类型的数据。以下是对不同存储区域的简要说明:
(1)静态区域(Static Memory)
- 存储内容:静态区域用于存储程序的全局变量、静态变量和常量(
const
修饰的变量)。这些变量的生命周期从程序开始到程序结束。 - 存储位置:静态变量和常量存储在静态数据区,通常包括:
- 全局变量:存储在静态数据区中,程序运行时一直存在。
- 静态局部变量:通过
static
关键字声明的局部变量,存储在静态数据区,不会在函数调用结束时销毁。 - 常量:如果常量是全局常量或者在程序中明确作为常量定义,它通常也存储在静态数据区。
(2) 堆(Heap)
- 存储内容:堆是程序运行时动态分配内存的区域。它主要用于存储通过
malloc
、new
等动态内存分配函数分配的内存。堆中的内存需要手动释放(如通过free
、delete
)。 - 存储位置:堆中的内存位置是动态的,且程序可以在运行时随时进行分配和释放。因此,它适合存储大小不固定或者需要在运行时决定存储空间的数据结构(如链表、树等)。
(3) 栈(Stack)
- 存储内容:栈主要用于存储函数的局部变量、函数的返回地址以及函数的调用信息(如函数调用时保存的寄存器等)。当函数被调用时,栈会为该函数分配空间,函数返回时,栈空间会被自动释放。
- 存储位置:栈上的变量具有“自动存储持续性”,即它们的生命周期仅限于函数的调用周期。栈存储的变量通常是临时的、局部的变量。栈的内存分配和释放由编译器自动管理,不需要手动干预。
总结:
- 静态区域:全局变量、静态变量、常量。
- 堆:动态分配的内存(通过
malloc
、new
等)。 - 栈:函数局部变量、函数调用信息。
每个区域的存储方式和管理方式有所不同,栈和堆是由程序运行时进行管理的,而静态区域则在程序启动时分配并在程序退出时释放。
2. 全局变量、静态变量、常量的区别
在C和C++中,全局变量、静态变量和常量有着不同的特性和用途。以下是它们的主要区别:
(1) 全局变量(Global Variables)
- 定义:全局变量是在所有函数外部定义的变量,通常定义在源文件的最外层。
- 生命周期:全局变量的生命周期从程序开始执行到程序结束。
- 作用域:全局变量的作用域是整个程序,任何函数都可以访问和修改全局变量。
- 存储位置:全局变量通常存储在静态数据区(BSS段或数据段),并且在程序开始时被初始化。
- 初始化:如果没有显式初始化,全局变量会被自动初始化为零(对于基本数据类型)。
示例:
int globalVar = 10; // 全局变量void foo() {globalVar = 20; // 可以在函数中访问和修改全局变量
}
(2) 静态变量(Static Variables)
- 定义:静态变量是在函数内部或外部使用
static
关键字声明的变量。对于函数内部的静态变量,它的生命周期与程序的生命周期相同,但它的作用域仅限于函数内部。 - 生命周期:静态变量的生命周期从程序开始执行到程序结束,即使是局部静态变量,它也不会在函数调用结束时销毁。
- 作用域:
- 局部静态变量:仅限于声明它的函数内部,其他函数无法访问。
- 全局静态变量:作用域仅限于声明它的源文件,其他源文件无法访问(这时它是一个文件内部的全局变量,具有“内联”特性)。
- 存储位置:静态变量存储在静态数据区(BSS段或数据段)。
- 初始化:静态变量在程序启动时自动初始化为零,如果显式初始化则使用指定的值。
示例:
void foo() {static int counter = 0; // 静态局部变量counter++;printf("Counter: %d\n", counter);
}
每次调用foo()
时,counter
会保留其上次的值,而不像普通局部变量那样每次进入函数时都会被重新初始化。
(3) 常量(Constants)
- 定义:常量是指值在程序运行时不能修改的变量。常量可以使用
const
关键字来声明,或者使用#define
宏定义。 - 生命周期:常量的生命周期通常与它所在的程序区域相同,通常存储在只读数据区或静态数据区中。
- 作用域:常量的作用域与其声明的位置相关。局部常量仅限于其声明的作用域,而全局常量可以在整个程序中访问。
- 存储位置:常量通常存储在程序的只读数据区。
- 初始化:常量在声明时必须进行初始化,并且值在程序运行过程中不可修改。
示例:
const int MAX_VALUE = 100; // 常量,初始化后不能修改void foo() {// MAX_VALUE = 200; // 错误,常量不能修改
}
区别总结:
特性 | 全局变量 | 静态变量 | 常量 |
---|---|---|---|
定义位置 | 函数外部定义 | 函数内部或外部使用static 关键字声明 | 使用const 关键字或#define 定义 |
生命周期 | 程序从开始到结束 | 程序从开始到结束 | 程序从开始到结束 |
作用域 | 程序中的任何地方都可以访问 | 仅限于函数或源文件 | 仅限于其声明的作用域 |
初始化 | 如果没有初始化,会被自动初始化为零 | 如果没有显式初始化,会自动初始化为零 | 必须在声明时初始化,并且不可修改 |
存储位置 | 静态数据区(BSS段或数据段) | 静态数据区(BSS段或数据段) | 静态数据区或只读数据区 |
是否可修改 | 可修改 | 可修改(局部静态变量,除非为常量) | 不可修改 |
关键点:
- 全局变量:程序中的任何地方都可以访问,生命周期贯穿整个程序。
- 静态变量:生命周期与程序相同,但作用域受限,可以是局部的(函数内部)或全局的(仅在文件内有效)。
- 常量:值不可修改,初始化后不允许更改。