C primer plus 学习笔记 第16章 C预处理器和C库

简介: C primer plus 学习笔记 第16章 C预处理器和C库

  第16章 C预处理器和C库

16.1 翻译程序的第一步

预处理之前,编译器对程序进行一些翻译处理。

1,将源代码出现的字符映射到源字符集。

2,将物理行转换成逻辑行

printf(“That's wond\

erful!\n");

转成

printf(“That's wonderful!\n");

3,编译器把文本划分成预处理记号序列、空白序列和注释序列。

编译器将用一个空格 替换每一条注释。

int /*这看起来不像是一个空格*/ fox;

将变成

int fox;

16.2 明示常量: #define

可以使用#define定义明示常量(符号常量)...//const更好

 

每行#define 由3部分组成

#define + 宏  + 替换列表

预处理器在程序中找到宏就会用替代体 替代该宏。

16.2.1 记号

可以把宏的替换体看作是记号型字符串。C预处理器记号是宏定义的替换提中单独的”词”。

16.2.2 重定义常量 (通常不需要也不要这样做)

16.3 在#define中使用参数

使用参数 用#define创建类似函数的 类函数宏。 //但并不是函数,所谓的类函数只是简单的替换16

#define MEAN(x,y) (((x) + (y))/2)

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

例子:

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

使用

PSQR(8);

输出:

The square of X is 64.

C允许字符串包含宏参数,

 

#include<stdio.h>
#define PSQR(x) printf("The square of " #x " is %d.\n", ((x)*(x)))
 
int main(void)
{
int y = 5;
PSQR(y);
PSQR(2+4);
return 0;
}

16.3.2 预处理器粘合剂:##运算符

##运算符把两个记号合并成一个记号:

#define XNAME(n)  x## n

然后

XNAME(4)将会展开为x4

16.3.3 变参宏:...和__VA__ARGS__

#define PR(...) printf(__VA_ARGS__)

 

16.4 宏和函数的选择

似乎没必要使用宏替代函数。

16.5 文件包含:#include

预处理器发现#include指令时,会查看后面的文件名并把文件内容包含到当前文件中。

相当于把 被包含的文件的全部内容输入到源文件#include指令所在的位置。

#include指令有两种形式:

#include<stdio.h>

#include"mystuff.h"

 

16.5.2 使用头文件

头文件最常用的形式如下:

明示常量

宏函数

函数声明

结构模板定义

类型定义

 

16.6 #undef

“取消“ 已定义的#define指令

#define LIMIT 400

#undef LIMIT //取消了之前的定义,现在可以重新定义LIMIT

 

16.6.2 从C预处理器角度看已定义

 

16.6.3 条件编译

1.#ifdef 、#else和#endif指令

条件编译示例:

#ifdef MAVIS  //如果已经define 了 MAVIS

 #include"hores.h"

 #define STABLES 5

#else   //否则

 #include"cow.h"

 #define STABLES 15

#endif  //条件编译结束

 

2.#ifnde指令似

#ifndef 和#ifdef指令类似

但ifndef指令判断的时后面的标识符是否是未定义的。

使用多个头文件时,#ifndef 可以防止重复编译、重复包含

 

#ifndef NAMES_H_

#define NAMES_H_

//...name.h的具体内容,函数原型,明示常量等。

...

#endif

//注:#pragma once 也可以防止重复包含。

 

16.6.4  预定义宏

16.6.5 #line和#error 重置行号 和 发出错误消息

16.6.6 #pragma

#pragma c9x on //使用C9X 标准(C99)

 

16.6.7 泛型选择

C11新增了一种表达式:泛型选择表达式。可根据表达式的类型选择一个值。

#ifndef NAMES_H_

例:

_Generic(x, int:0, float:1, double:2, default:3)

_Generic是C11的关键字,他后面的括号的第一项是一个表达式(例子种是x),后面是类型+:+值(如 float:1)

 

16.9 内联函数   //可能会加快调用函数的速度

定义:

inline static void eatline()

{

while(getchar() !='\n')

 continue;

}

 

int main()

{

...

eatline();

}

16.8 _Noreturn函数(C11)

_Noreturn函数说明符,表示完成函数后不返回主调函数(No return)

 

16.9 C库

16.9.1 访问C库

1.自动访问

2.文件包含 #include

3.库包含

16.9.2 使用库 描述

阅读(库函数)文档的关键是看懂函数头

 

16.10 数学库 (math.h)

 

16.11 通用工具库

通用工具库包含各种函数,包括随机数生成,查找,排序等。

相关文章
|
6月前
|
编译器 C++
C++语言预处理器学习应用案例
【4月更文挑战第8天】C++预处理器包括条件编译、宏定义和文件包含等功能。例如,条件编译用于根据平台选择不同代码实现,宏定义可简化常量和变量名,文件包含则用于整合多个源文件。示例中展示了如何使用`#ifdef`等指令进行条件编译,当`DEBUG`宏定义时,`PRINT_LOG`会打印调试信息,否则不执行。
53 1
|
搜索推荐 数据挖掘 PyTorch
Py之albumentations:albumentations库函数的简介、安装、使用方法之详细攻略续篇
Py之albumentations:albumentations库函数的简介、安装、使用方法之详细攻略续篇
Py之albumentations:albumentations库函数的简介、安装、使用方法之详细攻略续篇
|
6月前
|
TensorFlow 算法框架/工具
【tensorflow】- 知识点补充
【tensorflow】- 知识点补充
|
编译器 C++
C进阶:预处理(下)
C进阶:预处理(下)
82 0
|
6月前
|
C语言
【C语言进阶篇】你真的了解预处理吗? 预处理详细解析
【C语言进阶篇】你真的了解预处理吗? 预处理详细解析
73 0
|
自然语言处理 编译器
C进阶:预处理(上)
C进阶:预处理
65 0
|
编译器 C语言 C++
C语言编程—预处理器
预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。
|
Linux C语言 C++
【C进阶】——预处理详解(一)
【C进阶】——预处理详解(一)
86 0
|
编译器 Linux C++
【C进阶】——预处理详解(二)
【C进阶】——预处理详解(二)
130 0
|
编译器 C++
c++入门篇之C++ 预处理器
预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。 所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。

相关实验场景

更多
下一篇
无影云桌面