C_预处理器和C库

本文详细介绍了C语言的预处理器,包括#define定义常量、宏参数、字符串化、粘合运算符以及变参宏。同时讲解了文件包含、预定义宏、条件编译和其他指令,如#undef、#line、#error等。接着讨论了内联函数的使用和C库,特别是数学库和通用工具库中的exit()和atexit()函数。此外,还涵盖了排序函数qsort()和断言库中的assert()及_Static_assert(C11)。最后提到了string.h库中的memcpy()和memmove()函数的用途。
摘要由CSDN通过智能技术生成

一、预处理器

             1) C预处理器在程序执行之前查看程序(故称之为预处理器)

             2) 根据程序中的预处理器指令,预处理器把符号缩写替换成其表示的内容

             3) 预处理器可以包含程序所需的其他文件,可以选择让编译器查看哪些代码

    1.预处理之前

             在预处理之前,编译器必须对该程序进行一些翻译处理

           1.首先,编译器把源代码中出现的字符映射到源字符集

           2.编译器定位每个反斜杠后面跟着换行符的实例,并删除它们

               // “换行符”的意思是通过按下Enter键在源代码文件中换行所生成的字符,而不是指符号表征\n

               // 预处理表达式的长度必须是一个逻辑行

           3.编译器把文本划分为预处理记号序列、空白序列和注释序列(记号是由空格、制表符或换行符分隔的项)

              // 编译器将用一个空格字符替换每一条注释

              // 实现可以用一个空格替换所有的空白字符序列

    2.明示常量: #define

             1) ANSI和后来的标准都允许#前面空格制表符,而且还允许在#和指令的其余部分之间有空格

             2) 指令可以出现在源文件的任何地方其定义从指令出现的地方到该文件末尾有效

             3) 预处理器指令从#开始运行,到后面的第一个换行符为止           

/*   简单的预处理示例    */
#include<stdio.h>

#define TWO 2
#define OW "Consistency is the last refuge of the unimagina\
tive.-Oscar Wilde"               //反斜杠把该定义延续到下一行
#define FOUR TWO*TWO
#define PX printf("X is %d.\n",x)
#define FMT "X is %d.\n"

int main()
{
	int x = TWO;
	PX;
	x = FOUR;     //x = TWO*TWO
	printf(FMT, x);
	printf("%s\n", OW);
	printf("TWO: OW\n");
	return 0;
}

             4) 每行#define(逻辑行)都由三部分组成

               1.第一部分是#define指令本身

               2.第二部分是选定的缩写,也称为宏(宏的名称中不允许有空格,而且必须遵守C变量的命名规则)

                     // 有些宏代表值,这些宏被称为类对象宏

                     // C语言还有类函数宏

                     // 宏的名称只能使用字符、数字和下划线_字符,而且首字符不能是数字

               3.第三部分称为替换列表或替换体

             5) 一旦预处理器在程序中找到宏的实例后,就会用替换体代替该宏(有例外)

             6) 从宏变成最终替换文本的过程称为宏展开

            7) 预处理器不做计算不对表达式求值只进行替换

    3.在#define中使用参数

           1) 在#define中使用参数可以创建外形和作用与函数类似的类函数宏

           2) 类函数宏定义的圆括号可以有一个或多个参数,随后这些参数出现在替换体

           3) 函数调用程序运行时参数的值传递给函数;宏调用编译之前参数记号传递给程序

              例:      #define SQUARE(X) X*X

                         z = SQUARE(2);

/*        带参数的宏       */
#include<stdio.h>

#define SQUARE(X) X*X       //SQUARE是宏标识符,SQUARE(X)中的X是宏参数,X*X是替换列表
#define PR(X) printf("The result is %d.\n",X)

int main()
{
	int x = 5;
	int z;
	printf("x = %d\n", x);        //x = 5
	z = SQUARE(x);
	printf("求值 SQUARE(x): ");
	PR(z);                       //25
	z = SQUARE(2);
	printf("求值 SQUARE(2): ");
	PR(z);                       //4
	printf("求值 SQUARE(x+2): ");
	PR(SQUARE(x + 2));            //17
	printf("求值 100/SQUARE(2): ");
	PR(100 / SQUARE(2));           //100
	printf("x = %d\n", x);        //5
	printf("求值 SQUARE(++x): ");
	PR(SQUARE(++x));               //49
	printf("x = %d\n", x);          //7
	return 0;
}

    4.用宏参数创建字符串: #运算符

           1) C允许在字符串中包含宏参数;在类函数宏的替换体中,#号作为一个预处理运算符,可以把记号转换成字符串

           2) 如果x是一个宏形参那么#x就是转换为字符串"x"的形参名,这个过程称为字符串化

#include<stdio.h>

#define PSQR(x) printf("The square of "#x" is %d.\n",((x)*(x)))

int main()
{
    int y = 5;
    PSQR(y);         //The square of y is 25.
    PSQR(2+4);       //The square of 2+4 is 36.
    return 0;
}

    5.预处理粘合剂:##运算符

           ##运算符可用于类函数宏的替换部分,可用于对象宏的替换部分

#include<stdio.h>

#define XNAME(n) x##n
#define PRINT_XN(n) printf("x"#n"=%d\n",x##n);

int main()
{
    int XNAME(1) = 14;     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值