编译预处理和动态储存分配
目录
1. 编译预处理
C 语言中的预处理器是一种特殊的程序,它可以在源代码被编译之前对源代码进行修改和处理,通常以 "#" 开头的指令称为预处理指令,例如:
#include <stdio.h>
#define PI 3.14159
#ifdef DEBUG
printf("Debugging Mode...\n");
#endif
预处理指令主要有以下几种:
- #include:用于将外部文件的内容包含到当前文件中。
- #define:用于定义符号常量、函数宏、条件编译等。
- #ifdef 和 #endif:用于条件编译,让某段代码只在符号已经被定义时才编译。
- #pragma:用于控制编译器的行为,例如关闭警告、优化等。
预处理器可以让 C 程序中的代码更加灵活和易于维护,可以大幅提高代码的可读性和可维护性。
2. 动态储存分配
C 语言中的动态储存分配允许程序在运行时动态地申请内存,并返回一个指向该内存区域的指针。常用的函数有 malloc()、calloc()、realloc() 等。
- malloc 函数
malloc() 函数原型如下:
void *malloc(size_t size);
它用于在内存区域中申请一段大小为 size 的空间。该函数返回的是所申请的内存空间的第一个字节的地址。如果空间不足,或者不能满足申请,该函数将返回 NULL。需要注意的是,malloc() 申请的内存空间会包含随机的垃圾数据,申请之后需要手动初始化。
- calloc 函数
calloc() 函数原型如下:
void *calloc(size_t n, size_t size);
它用于在内存区域中申请 n 个大小为 size 的连续空间。calloc() 的行为与 malloc() 类似,不同的是 calloc() 会初始化内存空间,将其所有位都设置为零。如果空间不足或者不能满足申请,该函数也会返回 NULL。
- realloc 函数
realloc() 函数原型如下:
void *realloc(void *ptr, size_t size);
它用于修改之前申请的内存空间大小,然后返回一个新的指针。如果新的空间大小比之前的小,那么 realloc() 将释放一部分原来的内存;如果新的空间大小比之前大,那么 realloc() 将增加内存空间,并保留原有的内容。需要注意的是,如果 realloc() 失败,将返回 NULL,同时原指针将保持不变。
动态储存分配可以灵活地处理数据,但也容易引发内存泄漏、溢出等问题。因此,在使用动态储存分配时一定要注意内存的释放和管理。