IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C预处理器和C库(C语言学习笔记) -> 正文阅读

[C++知识库]C预处理器和C库(C语言学习笔记)

本章主要内容:

  • 预处理指令——#define、#include、#ifdef、#else、#endif、#ifndef、#if、#elif、#line、#error、#pragma;

  • 关键字—— _Generic、 _Noreturn、 _Static _assert;

  • 函数/宏——sqrt()、atan()、atan2()、exit()、atexit()、assert()、memcpy()、memmove()、va_start()、va_arg()、va_copy()、va_end();

  • C预处理器的其他功能;

  • 通用选择表达式;

  • 内联函数;

  • C库概述和一些特殊用途的方便函数。

1.翻译程序的第一步

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

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

该过程处理多个字节字符和三字序列——字符扩展让C更加国际化。

b.第二,编译器定位每个反斜杠后面跟着换行符的实例,并删除他们。

?//例如把下面两个物理行(physical line)转换成一个逻辑行(logical line);
?printf("hello\
?        world!\n");
?printf("hello world!\n");

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

由于预处理表达式的长度必须是一个逻辑单元,所以这一步为预处理做好了准备工作。一个逻辑行可以是多个物理行。

c.第三,编译器把文本划分成预处理记号序列、空白序列和注释序列(记号是由空格、制表符或换行符分隔的项,详见2.1节)。

注意:编译器将用一个空格字符替换每一条注释,而且实现可以用一个空格替换所有的空白字符序列(不包括换行符)。

d.最后,程序已经准备好进入预处理阶段,预处理查找一行中以#号开始的预处理指令。

2.明示常量:#define

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

#define指令常被用来定义明示常量(mainfest constant)(也叫符号常量),但是该指令还有许多其它用途。

?/* preproc.c -- 简单的预处理示例 */
?#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(void)
?{
? ? ?int x = TWO;
? ? ?
? ? ?PX;
? ? ?x = FOUR;
? ? ?printf(FMT, x);
? ? ?printf("%s\n", OW);
? ? ?printf("TWO: OW\n");
? ? ?
? ? ?return 0;
?}
??

预处理器指令从#开始运行,到后面的第一个换行符为止,指令的长度仅限于一个逻辑行。

每行#define(逻辑行)都由3部分组成。

  • 第一部分是#define指令本身。

  • 第二部分是选定的缩写,也称

    1. 类对象宏(object-like macro) -- 代表值

    2. 类函数宏(function-like macro)

    3. 宏的名称必须遵循C变量的命名规则

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

宏展开(macro expansion)

预处理器在程序中找到宏的实例后,就会用替换体代替该宏;从宏变成最终替换文本的过程称为宏展开

唯一例外是双引号中的宏不进行宏展开。

2.1记号

从技术角度来看,可以把宏的替换体看作是记号(token)型字符串,而不是字符型字符串。C预处理器记号是宏定义的替换体中单独的“词”。

用空白把这些词分开。

?#define FOUR 2*2

该宏定义有1个记号: 2*2序列。

?#define SIX 2 * 3

该宏定义有3个记号: 2、*、3。

替换体中有多个空格时,字符型字符串和记号型字符串的处理方式不同。

?#define EIGHT 4 * 8

如果预处理器把该替换体解释为字符型字符串,将用4 * 8替换EIGHT。即,额外的空格是替换体的一部分。如果预处理器把该替换体解释为记号型字符串,则用三个的记号4 * 8(分别由单个空格分隔)来替换EIGHT

C编译器处理记号的方式比预处理器复杂。由于编译器理解C语言的规则,所以不要求代码中的空格来分隔记号。例如, C编译器可以把2*2直接视为3个记号,因为它可以识别2是常量, *是运算符。

(未完,待更新)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 11:51:13  更:2021-12-07 11:51:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:47:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码