欢迎来CILMY23的博客喔,本篇为【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注+收藏。
前言
欢迎来到本篇博客,上一篇我们详细介绍C语言中的编译和链接阶段,在C语言中,编译和链接是将源代码转换为可执行文件的关键过程。本期我们将深入了解这个过程中的预处理阶段。
上一篇博客链接:
文章目录
一、预定义符号
C语言设置了⼀些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的
//__FILE__ //进行编译的源文件
//__LINE__ //文件当前的行号
//__DATE__ //文件被编译的日期
//__TIME__ //文件被编译的时间
//__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
例如:
#include<stdio.h>
int main()
{
printf("%s\n", __FILE__);
printf("%d\n", __LINE__);
printf("%s\n", __DATE__);
printf("%s\n", __TIME__);
//printf("%d", __STDC__);
return 0;
}
由于Visual Studio 2019编译器不遵循ANSI C,是未定义的。所以我们注释掉该行,如果是在gcc编译器,则__STDC__就为1
结果如下所示:
二、#define定义常量
#define定义常量的语法如下:
#define name stuff
#define name stuff
将创建一个名为 name
的符号常量,其为 stuff
。
因为在预处理阶段,文件会将#define展开和删除,所以我们可以通过gcc编译器来观察
gcc test.c -E -o test.i
C1,C2和Num都被替换了
那在使用#define的时候,我们需要注意几个点
1.用来省略for循环判断部分的时候,循环条件的判断恒为真,这个循环是死循环
例如:
#define forever for(;;)
2.最好不用加分号
例如:
#define MAX 1000;
#define MAX 1000
会将MAX替换成1000;这样会导致在语句后本来就有分号的情况下,替换后导致多出了一个分号
出现语法错误
三、 #define 定义宏
#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏 (definemacro)
常规解释:
在C语言中,定义宏(Macro)指的是使用
#define
预处理指令为一个标识符(通常是一个常量、函数或代码片段)定义一个符号名称,以便在代码中多次使用,并在预处理阶段进行替换。宏可以是简单的标识符或者带参数的宏。通过定义宏,可以使代码更具有可读性和可维护性,同时也可以减少代码中的重复性内容,方便后续的修改和维护。定义宏可以用于创建常量、简化复杂表达式、定义函数等。
下面是宏的声明方式:
#define name( parament-list ) stuff
其中的 parament-list 是⼀个由逗号隔开的符号表,它们可能出现在stuff中。
注意:
参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
例如:
#include<stdio.h>
#define SQUARE( x ) x * x
int main()
{
int a = SQUARE(5);
printf("%d\n", a);
return 0;
}
这个宏接收一个参数 x
如果在上述声明之后,你把SQUARE( 5 ); 置于程序中,预处理器就会用下面这个x*x表达式替换上面的表达式
但是这个宏存在一定的问题
假设我们传入的是5+2
SQUARE(5+2);
那么这个式子就会被替换成5+2*5+2
#define SQUARE( 5 + 2 ) 5 + 2 * 5 + 2
原意我们是想把这个式子,算成7*7,但是结果却是十七,
那为了解决这个问题,我们就加括号
#define SQUARE( x ) ((x) * (x))
这样才能正确计算表达式的值
所以对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的 操作符或邻近操作符之间不可预料的相互作用。
四、 带有副作用的宏参数
当宏参数在宏的定