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 通用工具库

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

相关文章
|
域名解析 监控 网络协议
分享40个主机域名PHP源码,总有一款适合你
分享40个主机域名PHP源码,总有一款适合你
569 1
|
8月前
|
缓存 安全 网络安全
解锁网站速度与安全:CDN 使用指南及免费平台推荐
在互联网时代,网站的速度和安全性至关重要。CDN(内容分发网络)通过全球缓存节点提升访问速度、降低延迟,并提供安全防护。本文详解CDN的作用与适用场景,推荐几款免费CDN平台,如阿里云、鸟盾安全CDN等,助您选择合适的CDN服务,保障网站性能与安全。
|
12月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
326 0
|
11月前
|
机器学习/深度学习 人工智能 算法
强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用
本文探讨了强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用,通过案例分析展示了其潜力,并讨论了面临的挑战及未来发展趋势。强化学习正为游戏AI带来新的可能性。
904 4
|
SQL 监控 数据库
SQL语句性能分析技巧与方法
在数据库管理中,分析SQL语句的性能是优化数据库查询、提升系统响应速度的重要步骤
|
10月前
|
人工智能 C语言
一则有意思的AI错误
本文记录了豆包AI在回答关于C语言内存分配问题时的错误过程。首次询问时,AI给出了错误的回答;经过两次追问和纠正后,AI才给出正确的答案。文中附有提问过程的完整截图和相关代码,分析了问题的原因,并探讨了AI在处理这类问题时的局限性。
303 0
|
机器学习/深度学习 算法 数据挖掘
使用MICE进行缺失值的填充处理
在我们进行机器学习时,处理缺失数据是非常重要的,因为缺失数据可能会导致分析结果不准确,严重时甚至可能产生偏差。处理缺失数据是保证数据分析准确性和可靠性的重要步骤,有助于确保分析结果的可信度和可解释性。
754 2
|
数据采集 存储 数据挖掘
使用Python读取Excel数据
本文介绍了如何使用Python的`pandas`库读取和操作Excel文件。首先,需要安装`pandas`和`openpyxl`库。接着,通过`read_excel`函数读取Excel数据,并展示了读取特定工作表、查看数据以及计算平均值等操作。此外,还介绍了选择特定列、筛选数据和数据清洗等常用操作。`pandas`是一个强大且易用的工具,适用于日常数据处理工作。