目录
十二、内存管理
188. (malloc函数)用于(动态分配内存), malloc 函数在(堆)上动态分配内存,接受⼀个参 数,表示需要分配的内存大小(以字节为单位)。
189. malloc 函数返回(分配的内存块的指针),如果内存分配成功, malloc 函数返回⼀个指向分配的内存块的指针。
190. malloc 函数返回(NULL)表示(内存分配失败),内存分配失败可能是因为(系统内存不 足)。
191. ( calloc 函数)用于(分配并初始化内存), calloc 函数在(堆)上分配内存,并将分配的内存块(初始化为0),接受两个参数,第⼀个参数表示需要分配的元素个数,第二个参数表示每个元素的大小(以字节为单位)。
192. calloc 函数将(分配的内存块数据设置为0),这意味着分配的内存块中的每个字节都被设置 为0。
193. malloc 函数返回(void*类型)的指针,需要(强制类型转换)为所需的类型。
194. realloc 函数用于(改变已分配内存块的大小),可以扩大或缩小内存块。
195. free 函数用于(释放动态分配的内存),释放内存后,指针应该设置为(NULL),以避免 (悬挂指针)。
196. 内存泄漏是指(分配的内存没有被释放),长时间运行的程序中的内存泄漏会导致(系统资源耗尽)。
197. 悬挂指针是指(指向已释放内存的指针),访问悬挂指针会导致(未定义行为)。
十三、文件操作
198. (文件):存储在外部存储介质(如硬盘、U盘)上的数据的集合。(文件是数据持久化存储的主要方式。)
199. (文件的类型):
🤞 • 文本文件:以ASCII码形式存储,可直接用文本编辑器打开查看。(例如:.txt、.c、.h文件。)
• 二进制文件:以二进制形式存储,不能直接用文本编辑器打开,需要特定的程序才能解析。(例如:.exe、.jpg、.mp3文件。)
200. (文件指针):指向文件结构体(FILE)的指针,用于操作文件。(文件指针是文件操作的核心。)
201. (FILE类型):C语言标准库中定义的结构体类型,包含了文件操作所需的信息。(FILE结构体定义在stdio.h头文件中。)
202. (fopen函数):用于打开文件,返回文件指针。(函数原型: FILE *fopen(const char *filename, const char *mode); )
🤞 • filename :要打开的文件名(包含路径)。
• mode :打开模式,指定文件的打开方式。(例如:"r", "w", "a", "rb", "wb", "ab", "r+",
"w+", "a+"。)
203. (fopen函数的返回值):
🤞 • 成功打开文件,返回指向该文件的文件指针。
• 打开文件失败,返回NULL。(需要判断fopen函数的返回值是否为NULL,以确定文件是
否成功打开。)
204. (fopen函数的打开模式):
🤞 • "r"(只读):只能从文件中读取数据,文件必须存在。
• "w"(只写):只能向文件中写入数据,如果文件存在则覆盖,不存在则创建。
• "a"(追加):只能向文件中追加数据,如果文件不存在则创建。
• "rb"(只读二进制):以二进制模式打开文件,只能从文件中读取数据,文件必须存在。
• "wb"(只写⼆进制):以二进制模式打开文件,只能向文件中写入数据,如果文件存在
则覆盖,不存在则创建。
• "ab"(追加二进制):以二进制模式打开文件,只能向文件中追加数据,如果文件不存
在则创建。
• "r+"(读写):可以从文件中读取数据,也可以向文件中写入数据,文件必须存在。
• "w+"(读写):可以从文件中读取数据,也可以向文件中写入数据,如果文件存在则覆
盖,不存在则创建。
• "a+"(读写):可以从文件中读取数据,也可以向文件中追加数据,如果文件不存在则
创建。
205. (fclose函数):用于关闭文件,释放文件资源。(函数原型: int fclose(FILE *fp); )
🤞 • fp :要关闭的文件指针。
206. (fclose函数的返回值):
🤞 • 成功关闭文件,返回0。
• 关闭文件失败,返回EOF(-1)。(需要判断fclose函数的返回值是否为0,以确定文件是否成功关闭。)
207. (fprintf函数):用于向文件中写入格式化数据。(函数原型: int fprintf(FILE *fp, const char *format, ...); )
🤞 • fp :要写入的文件指针。
• format :格式化字符串,类似于printf函数的格式化字符串。
• ... :要写入的数据。
208. (fscanf函数):用于从文件中读取格式化数据。(函数原型: int fscanf(FILE *fp, const char *format, ...); )
🤞 • fp :要读取的文件指针。
• format :格式化字符串,类似于scanf函数的格式化字符串。
• ... :用于存储读取数据的变量的地址。
209. (fputc函数):用于向文件中写入⼀个字符。(函数原型: int fputc(int char, FILE *fp); )
🤞 • char :要写入的字符。
• fp :要写入的文件指针。
210. (fgetc函数):用于从文件中读取⼀个字符。(函数原型: int fgetc(FILE *fp); )
🤞 • fp :要读取的文件指针。
211. (fputs函数):用于向文件中写入⼀个字符串。(函数原型: int fputs(const char *str, FILE *fp); )
🤞 • str :要写入的字符串。
• fp :要写入的文件指针。
212. (fgets函数):用于从文件中读取一行字符串。(函数原型: char *fgets(char *str, int n, FILE *fp); )
🤞 • str :用于存储读取的字符串的字符数组。
• n :最多读取的字符数(包括'\0')。
• fp :要读取的文件指针。
213. (fread函数):用于从文件中读取指定字节数的数据。(函数原型: size_t fread(void *ptr, size_t size, size_t count, FILE *fp); )
🤞 • ptr :用于存储读取数据的内存空间的地址。
• size :每个数据项的大小(以字节为单位)。
• count :要读取的数据项的个数。
• fp :要读取的文件指针。
214. (fwrite函数):用于向文件中写入指定字节数的数据。(函数原型: size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp); )
🤞 • ptr :要写入的数据的内存空间的地址。
• size :每个数据项的大小(以字节为单位)。
• count :要写入的数据项的个数。
• fp :要写入的文件指针。
215. (fseek函数):用于改变文件的读写位置。(函数原型: int fseek(FILE *fp, long offset, int origin); )
🤞 • fp :要操作的文件指针。
• offset :偏移量(以字节为单位)。
• origin :起始位置。(SEEK_SET:文件开头,SEEK_CUR:当前位置,SEEK_END:
文件末尾。)
216. (ftell函数):用于获取文件的当前读写位置。(函数原型: long ftell(FILE *fp); )
🤞 • fp :要操作的文件指针。
217. (rewind函数):用于将文件的读写位置移动到文件开头。(函数原型: void rewind(FILE *fp); )
🤞 • fp :要操作的文件指针。
218. (feof函数):用于判断文件是否结束。(函数原型: int feof(FILE *fp); )
🤞 • fp :要判断的文件指针。
• 返回值:如果文件结束,返回非零值,否则返回0。
219. (ferror函数):用于判断文件是否发生错误。(函数原型: int ferror(FILE *fp); )
🤞 • fp :要判断的文件指针。
• 返回值:如果文件发生错误,返回非零值,否则返回0。
220. (perror函数):用于输出错误信息。(函数原型: void perror(const char *s); )
🤞 • s :要输出的错误信息的前缀。
221. (remove函数):用于删除文件。(函数原型: int remove(const char *filename); )
🤞 • filename :要删除的文件名(包含路径)。
222. (rename函数):用于重命名文件。(函数原型: int rename(const char *oldname, const char *newname); )
🤞 • oldname :旧的文件名(包含路径)。
• newname :新的文件名(包含路径)。
(文本文件读写示例):
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char str[100];
// 打开⽂件
fp = fopen("test.txt", "w+");
if (fp == NULL)
{
perror("Error opening file");
return 1;
}
// 写⼊字符串
fprintf(fp, "This is a test string.\n");
fputs("Another line of text.\n", fp);
// 移动到⽂件开头
rewind(fp);
// 读取字符串
while (fgets(str, sizeof(str), fp) != NULL)
{
printf("%s", str);
}
// 关闭⽂件
fclose(fp);
return 0;
}
(二进制文件读写示例):
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
int data[5] = {1, 2, 3, 4, 5};
int read_data[5];
// 打开⽂件
fp = fopen("data.bin", "wb+");
if (fp == NULL)
{
perror("Error opening file");
return 1;
}
// 写⼊数据
fwrite(data, sizeof(int), 5, fp);
// 移动到⽂件开头
rewind(fp);
// 读取数据
fread(read_data, sizeof(int), 5, fp);
// 输出数据
for (int i = 0; i < 5; i++)
{
printf("%d ", read_data[i]);
}
printf("\n");
// 关闭⽂件
fclose(fp);
return 0;
}
223. (文件操作的注意事项):
🤞 • 打开文件后⼀定要关闭文件,释放文件资源。
• 打开文件时要检查fopen函数的返回值,确保文件成功打开。
• 读取文件时要检查feof函数和ferror函数的返回值,确保文件没有结束或发生错误。
• 写入文件时要检查ferror函数的返回值,确保文件没有发生错误。
• 使用fopen函数打开文件时,要根据实际需求选择合适的打开模式。
• 文件路径要正确,可以使用绝对路径或相对路径。
• 文件操作可能会发生错误,要做好错误处理。
224. (文件操作的错误处理):
🤞 • 使用perror函数输出错误信息。
• 使用exit函数终止程序运行。
• 在程序中添加错误处理代码,例如:
FILE *fp = fopen("test.txt", "r");
if (fp == NULL)
{
perror("Error opening file");
exit(1);
}
225. (文件操作的总结):
🤞
• 文件操作是C语言程序设计的重要组成部分。
• 掌握文件操作的相关函数和注意事项,可以编写出能够持久化存储数据的程序。
• 文件操作可能会发生错误,要做好错误处理。
十四、预处理
226. 对象宏用于定义(常量),对象宏只是简单的(文本替换),在编译之前进行。
227. #undef 用于(取消宏定义),如果需要取消之前定义的宏,可以使用 #undef 指令。这可以 避免宏名冲突或在特定代码段禁用宏。
228. 条件编译指令包括( #ifdef 、 #ifndef 、 #else 、 #endif ),这些指令允许根据(条件)选择性地编译代码,常用于处理平台差异、调试开关等。
229. #ifdef 用于(判断宏是否已定义),如果指定的宏已经定义,则编译 #ifdef 和 #else 之间的代码;否则,编译 #else 和 #endif 之间的代码。
230. #ifndef 用于(判断宏是否未定义),如果指定的宏尚未定义,则编译 #ifndef 和 #else 之间的代码;否则,编译 #else 和 #endif 之间的代码。
231. #else 用于(提供备选代码块), #else 指令必须与 #ifdef 或 #ifndef 指令配对使用,用于在条件不满足时编译另⼀段代码。
232. #endif 用于(结束条件编译块),每个 #ifdef 、 #ifndef 、 #if 指令都必须以#endif 指令结束。
233. #if 指令允许使用(常量表达式)进行条件编译,只有当常量表达式的值为非零时,才编译 #if 和 #else 之间的代码。
234. #elif 指令是 #else 和 #if 的组合,允许在多个条件之间进行选择,提供(多个备选代码块)。
235. #line 指令用于(改变行号和文件名),这主要用于(调试)目的,可以使编译器报告的错误 信息指向不同的位置。
236. #error 指令用于(生成编译错误),当编译器遇到 #error 指令时,会产生⼀个错误信息并终止编译,常用于(检查编译时错误)。