链表小技巧 & 常见问题
链表小技巧 & 常见问题
使用宏定义简化malloc
1 |
|
使用头节点
头节点是链表中的一个特殊节点,通常位于链表的最前端。它并不存储有效数据,而是一个辅助节点,用于简化链表操作,例如:
1 | // 没有使用头节点 |
使用头节点可以让链表的操作(如插入、删除、遍历)更加统一,不需要特别处理空链表的情况或操作链表头节点本身。
比如,插入一个新节点到链表的头部,没头节点的情况下,如果链表为空,插入操作就需要特判。而有了头节点,插入头节点的操作可以直接写成相同的逻辑,无论链表是否为空:
1 | // 无头节点 |
同样,在没有头节点的链表中,如果要删除链表的头节点,我们需要单独处理删除操作;但有了头节点后,删除头节点就变得和删除其他节点一样,统一处理:
1 | // 无头节点 |
常见问题
不能定义名字为 read
的函数
judge 上已经有定义好的 read
函数,不少同学在本地写代码时因为重复定义了名为 read
的函数而导致无法 AC
。
文件相关函数综述
在一般情况下,下面中“推荐使用”部分的几个函数已经可以满足当前所有的文件输入输出需求。
如果你愿意了解更多,可以向下查看。
注:以下函数参数列表中
char*
可以大致理解为字符串FILE*
可以大致理解为文件为了便于理解,省略了大部分
const
修饰符,并人为修改了一些参数类型。
推荐使用:
fopen(char* filename, char* mode)
和fclose(FILE* stream)
- 打开和关闭文件的函数。前者返回一个
FILE
类型的指针,后者接受一个FILE*
类型的指针并关闭它。 - 是文件读入的基础函数。
- 一般来说
fopen
的mode
参数只需要使用"r"
(读入)与"w"
(写入)两种。 - 在程序未尾使用
fclose
来输出/输入文件可以让你的程序更可靠。推荐使用。 fopen
在失败时返回NULL
(空指针),fclose
则返回EOF
。
- 打开和关闭文件的函数。前者返回一个
fscanf(FILE* stream, char* format,...)
和fprintf(FILE* stream, char* format,...)
- 和基础输入输出
scanf
、printf
的用法和行为都几乎一样。 - 需要结合
fopen
函数使用。 - 在读到文件末尾时,
fscanf
返回EOF
。
- 和基础输入输出
fgets(char* str, int num, FILE* stream)
和fputs(char* str, FILE* stream)
- 读入一整行字符串,不会因为空格停止读入。与
gets
函数相似。 - 读入的最大长度为
num
。
- 读入一整行字符串,不会因为空格停止读入。与
在读到文件未尾时,
fgets
返回 空指针 NULL。请注意:如果混用
fscanf
和fgets
,fgets
可能会读入fscanf
当作分隔符而没有读入的换行符。fputs
函数与puts
函数相似,输出一整个字符串。
可以使用,但是需要额外注意:
freopen(char* filename, char* mode, FILE* stream)
- 将参数传入的流重定向到文件流。
- 如果
stream
是stdin
,则重定向后可以用标准输入输出的方式(如scanf
,gets
)来读写文件。 freopen
失败时返回 空指针 NULL。- 由于操作系统的差别,不应该 在使用
freopen
打开文件后再次使用freopen
返回标准输入输出。 freopen
可以作为调试时的选择之一。
fgetc(FILE* stream)
和fputc(char character, FILE* stream)
- 与
getchar
和putchar
相似,从文件里读入或输出单一字符。 - 在读到末尾时,
fgetc
返回EOF
。 getc
和putc
函数和这两个函数行为上没有区别,但是为了防止混淆,此处不予列出。
- 与
基本不会使用到:
fread(void* ptr, size_t size, size_t count, FILE* stream)
和fwrite(void* ptr, size_t size, size_t count, FILE* stream)
- 从文件中读入或输出一整块数据。
- 在读到末尾时,
fread
仍然会返回已读入数据的数量(依照size
参数计算)。 - 需要通过
ferror
,feof
等判断是否读完。 - 除非你知道自己在做什么,否则不应该使用这两个函数。
- 这两个函数的文件读写速度高于其他函数,在对性能有高要求时可以考虑。
fflush(FILE* stream)
- 如果输出流中有缓存的未输出数据,将其写入对应的文件。
- 可以配合
fwrite
等函数工作。 - 一般来说不会用到。
- 错误时返回
EOF
。
不推荐使用:
feof(FILE* stream)
和ferror(FILE* stream)
- 可以用来判断文件是否读取完毕,或是找出文件读取时的错误。
- 经测试在 Windows 系统和 Linux 系统上的行为有区别。
- 除非你知道自己在做什么,否则不应该使用这两个函数。
ftell
,fseek
,fgetpos
,fsetpos
和rewind
- 文件读取或写入时操作写入位置的函数。
- 可以配合
fread
和fwrite
使用。 - 除非你知道自己在做什么,否则不应该使用这五个函数。