嵌入式面试八股文(七)·#ifndef#define#endif的作用、以及内存分区(全局区、堆区、栈区、代码区)
目录
1. 头文件中的#ifndef / #define / #endif的作用是什么?
2. 内存分区:全局区、堆区、栈区、代码区简单描述?
2.1 代码区(Text Segment):
2.2 全局区(Data Segment):
2.3 堆区(Heap):
2.4 栈区(Stack):
3. C语言各数据类型的取值范围?
1. 头文件中的#ifndef / #define / #endif的作用是什么?
#ifndef:用于判断指定的标识符是否已经被定义。如果该标识符未定义,则执行下面的代码块,否则跳过。
#ifndef MACRO_NAME// 如果没有定义 MACRO_NAME,则编译以下内容
#endif
#define:用于定义指定的标识符,通常用于定义宏。在条件编译中,一般用来定义一个标识符,以便在后面的代码中进行条件判断,通常用于定义一个标识符,用来标记某些代码块已经被处理过。通过定义宏来确保头文件只被包含一次。
#define MACRO_NAME
#endif:用于结束条件编译的代码块。
三者常用写法:
#ifndef MY_HEADER_H // 如果没有定义 MY_HEADER_H
#define MY_HEADER_H // 定义 MY_HEADER_H,表示头文件已经包含// 头文件内容,如结构体、函数声明等#endif // 结束条件编译块
工作原理:
第一次包含:
- 当编译器处理一个头文件时,它遇到 #ifndef MY_HEADER_H。
- 如果 MY_HEADER_H 没有被定义,则会进入条件编译块,并定义 MY_HEADER_H(通过 #define MY_HEADER_H)。
- 然后,编译器继续编译头文件的内容。
第二次及之后的包含:
- 如果该头文件在其他地方被再次包含,编译器会再次遇到 #ifndef MY_HEADER_H。
- 由于宏 MY_HEADER_H 已经被定义,条件 #ifndef MY_HEADER_H 会失败,编译器跳过头文件的内容,不会重复定义和包含相同的内容。
2. 内存分区:全局区、堆区、栈区、代码区简单描述?
2.1 代码区(Text Segment):
作用:存放程序的机器指令,也就是程序的执行代码。
特点:是只读的,防止程序在运行时修改自己的指令。
通常由操作系统在程序加载时分配,加载到内存中。
大小固定,一般在程序编译时就确定。
2.2 全局区(Data Segment):
作用:存放程序中的全局变量、静态变量和常量。
特点:已初始化的全局变量:如在程序中显式赋初值的全局变量,会存放在该区域。
未初始化的全局变量:存放在一个叫做BSS(Block Started by Symbol)区的区域,程序启动时会自动初始化为零。
全局变量在整个程序的生命周期内存在,直到程序结束。
全局区在程序运行期间不会被改变大小。
2.3 堆区(Heap):
作用:用于动态分配内存。程序运行时可以向堆区申请内存空间(例如,通过 malloc、new 等动态内存分配函数)。
特点:内存的分配和释放由程序员管理(或者通过垃圾回收机制,如在某些高级语言中)。
堆区内存大小可以动态变化,根据程序的需要增加或减少。
如果没有及时释放堆区内存,可能导致内存泄漏。
堆区通常位于全局区和栈区之间。
2.4 栈区(Stack):
作用:存放局部变量、函数参数和函数调用时的返回地址等。
特点:自动管理:栈的内存分配和释放由操作系统自动完成。函数调用时会自动分配栈空间,函数执行完后会自动释放。
栈内存的分配遵循“后进先出”的原则(LIFO),即最后被压入栈的变量最先被弹出。
栈区的大小通常有限,过多的函数调用可能会导致栈溢出。
栈区的内存是临时的,函数返回后,栈中的局部变量会被销毁。
简单来说:
- 代码区:存储程序的代码,通常是只读的。
- 全局区:存储全局变量和静态变量。
- 堆区:用于动态分配内存,由程序员手动管理。
- 栈区:存储局部变量和函数调用的相关信息,由操作系统自动管理。
3. C语言各数据类型的取值范围?
关键字 | 位数 | 表示范围 | stdint关键字 | ST关键字 |
char | 8 | -128 ~ 127 | int8_t | s8 |
unsigned char | 8 | 0 ~ 255 | uint8_t | u8 |
short | 16 | -32768 ~ 32767 | int16_t | s16 |
unsigned short | 16 | 0 ~ 65535 | uint16_t | u16 |
int | 32 | -2147483648 ~ 2147483647 | int32_t | s32 |
unsigned int | 32 | 0 ~ 4294967295 | uint32_t | u32 |
long | 32 | -2147483648 ~ 2147483647 | ||
unsigned long | 32 | 0 ~ 4294967295 | ||
long long | 64 | -(2^64)/2 ~ (2^64)/2-1 | int64_t | |
unsigned long long | 64 | 0 ~ (2^64)-1 | uint64_t | |
float | 32 | -3.4e38 ~ 3.4e38 | ||
double | 64 | -1.7e308 ~ 1.7e308 |
千题千解·嵌入式工程师八股文详解_时光の尘的博客-CSDN博客