第十六章 C预处理器和C库

C的温故而知新:The Last(C Primer Plus第十六、十七章) 想必是后面的内容超出大一课程规定的内容了,后面的文章数据惨的可怜。搜一下就能看见,好多人主张这本书后面几张可以不看。咋讲呢,对于这个观点来说,我本人是不认同的,我呢,粗略的看了看后两章的内容,可能对于初期学习确实作用不大,但是如果想有所提升的话,这两章的内容还是蛮重要的。第十六章讲述了C语言的预处理器和常用库文件。第十七章更是为我们介绍了高级的数据结构,不过毕竟数据结构后面还是会学的。因为现在已经九月份了,时间过得真的很快,我要开始下一步安排了,我们快速地将两章的内容过一遍。 阅读详情

第十六章 C预处理器和C库

define与预处理器的行为

define所定义的宏在被预处理器处理时需要注意一点,就是预处理器知识进行替换,而不会进
行运算.请看一个例子:

#define SQUARE(X) X*X

int main()
{
    int num = 4;
    int ret = 0;

    ret = SQUARE(num+4);
}

上述例子中ret的值是这么计算的ret = num + 4 * num + 4.也就是ret为24,而非我们希望
的64.因为这里预处理器只是字符串替换,不会为我们进行提前运算.如果想得到正确答案,应
该这么定义SQUARE宏:

#define SQUARE(X) (X) * (X)

这也是在使用宏函数时候非常需要注意的一点.

#运算符

在宏定义中#号可以把一个语言符号转换为字符串,具体请看下面的例子.

#define MY_PRINT_1(X) printf("Hello #X")
#define MY_PRINT_2(X) printf("Hello X")

int main(void)
{
    int NewName = 0;
    MY_PRINT_1(NewName);
    MY_PRINT_2(NewName);
}

在上面例子的输出结果中,MY_PRINT_1的结果为Hello NewName.MY_PRINT_2的结果为Hello
X.也就是在MY_PRINT_1中,通过#符号,可以将NewName这个语言符号直接转换为字符串
NewName.这里还需要注意的一点是被转换为字符串符号的NewName,实际上为”New Name” ,这
也是为什么当使用#运算符时,在诸如

#define PSQR(X) printf("The square of " #X "is what\n")

的定义中不需要使用转义\”的原因,因为上面那句话实际上为

printf("The square of" "X" "is what\m")

通过字符串结合,中间的字符串就可以变为”The square of X is what\n”.(具体请看c
primer plus第452页)

##运算符

在宏定义中##运算符把两个语言符号组合成单个语言符号.

#define XNAME(n) X ## n

XNAME(4)

在上例中XNAME(4)实际上为X4,这就是##运算符的作用,能够通过组合生成新的语言符号.

VA_ARGS可变宏

#define PR(X,...) printf("Message" #X ":" __VA_ARGS__)

int main(void)
{
    int x = 48;
    PR(x, "%4d\n", x);
}

上面的例子中printf()的最终参数是 printf(“Message x : %4d\n”, x).其中#X做了字符串
转换,然后使用VA_ARGS来代替了宏定义中的…(省略号)所输入的参数.关于
VA_ARGS,只要理解上面的例子即可.

一些常用的宏定义指令汇总

  1. #undef 取消一个之前已经定义好的宏 比如MAX_INT之前已经定义了,则#undef MAX_INT
    后, 后续的就不存在MAX_INT这个宏了(只针对使用了#undef的本文件)
  2. #ifdef
  3. #else
  4. #endif
  5. #ifndef 常用语避免头文件重复定义,例子:
#ifndef CODER_H
#define CODER_H

...具体内容
...
#endif
  1. #if 特别的在这里有一个新的预处理运算符defined(),若defined的参数被定义过,则返
    回1,否则返回0;
#if defined(IBMPC)
    #include "1.h"
#elif defined(MACPC)
    #include "2.h"
#endif
  1. #elif

有关于函数的可变参数,stdarg.h

函数的可变参数必须按照如下步骤进行:
1. 在函数原型中使用省略号
2. 在函数定义中创建一个va_list类型的变量
3. 用宏将该变量初始化为一个参数列表
4. 用宏访问这个参数列表
5. 用宏完成清理工作
具体例子如下:

double sum(int lim,...)
{
    va_list ap;     // 声明用于存放参数的变量
    double dSum = 0;
    int i;

    va_start(ap,lim);                        //把AP初始化为参数列表
    for(i = 0; i < lim; i++)
    {
        dSum = va_arg(ap,double);  // 访问参数列表中的每一个项目
    }
    va_end(ap);                                  // 清理工作
    return dSum;
}

这里有几点需要注意:
1. va_list类型代表一种数据对象,用于存放参量列表中省略号部分代表的参量.
2. va_start(va_list, argN) 把参数列表复制到va_list变量中.其中argN代表固定参数中
的最后一个固定参数. (使参数列表指针va_list指向函数参数列表中的第一个可选参数
)
3. va_arg()逐个返回参数列表中的项,va_arg(va_list,type)中的type描述va_arg的返回值
类型.
4. va_end()完成清理工作
5. 这里要注意,由于va_arg()不提供后退回先前参数的方法,也就是弹出一个参数后就无法
再通过va_arg()弹出相同位置的参数.所以为了保险起见,我们可以通过va_copy()宏函数
对参数列表进行一次复制,已被不时之需.

C Primer Plus (第六版) 第十六章_编程练习答案 no1.h // 开发一个包含你需要的预处理器定义的头文件 # ifndef NO1_H # define NO1_H //头文件内容 # endif no2.c // 两数的调和平均数这样计算:先得到两数的倒数,然后计算两个倒数的平均值, // 最后取计算结果的倒数.使用 #define 指令定义一个宏 "函数",执行该运算, // 编写一个简单的程序测试该宏 # inc... 阅读详情

相关推荐

C Primer Plus 第六版 第十六章 编程练习

C Primer Plus 第六版 第十六章 编程练习

vo_ai_sen的博客 283

第十六章 C 预处理器和 C 库

文章目录16.1 翻译程序的第一步 16.1 翻译程序的第一步

KaraShok的博客 458

MTK-Display技术解析:从MDP到DDP的架构演进

本文深入解析了联发科(MTK)显示技术从MDP到DDP的架构演进。MDP作为多媒体数据预处理中心,负责格式转换与缩放;而DDP则整合了OVL、COLOR、AAL等模块,并引入CMDQ与场景化模式,实现了从分散处理到统一智能调度的飞跃,旨在提升画质、流畅度并降低功耗。

weixin_29218509的博客 256

《C Primer Plus》第十六章——C预处理器和C库

文章目录C预处理器和C库本章内容翻译程序的第一步明示常量:#define记号重定义常量在#define中使用参数用宏参数创建字符串:#运算符预处理器黏合剂:##运算符变参宏:...和\_ \_VA\_ARGS_ _宏和函数的选择文件包含:#include头文件示例使用头文件其他指令#undef指令从C预处理器角度看已定义条件编译预定义宏#line和#error#pragma泛型选择(C11)内联函数(C99)_Noreturn函数(C11)C库访问C库使用库描述数学库三角问题类型变体tgmath.h库(C9

weixin_46698891的博客 1195

DFT知识点扫盲——DFT scan chain

实际在项目中synccell一般直接上ULVT,既然是SDF,就是带Scan接口的DFF,SN (set negtive)是低置位,RP(reset positive)是高复位,既没有SN也没有RP的就是无复位寄存器。1:定义:满足可测试性设计(DFT),将设计中所有的触发器连接到一条或者若干条链上,称为scan chain,将一个复杂的时序电路转换为简单的组合电路进行测试,这一步是在逻辑综合(DC)中实现。当SE=1当SI=1时,电路进入scan状态,当SI=0时,电路工作在normal状态。

笨蛋大乌龟的博客 4938

HP iLO4报错自救指南:Embedded Flash/SD-CARD故障的3种修复方案(附详细截图)

本文详细解析了HP iLO4出现'Embedded Flash/SD-CARD'故障时的3种修复方案,包括快速恢复、固件级修复和硬件级解决方案。通过Diagnostics诊断和Self-Test报告,帮助运维人员高效解决问题,并提供预防性维护建议,确保服务器远程管理功能的稳定性。

weixin_42522953的博客 512

《C Primer Plus》第十六章 C预处理器和C库

C预处理器在程序执行之前查看程序。根据程序中的预处理器指令,预处理器把符号缩写替换成其表示的内容。 16.1翻译程序的第一步 首先,编译器把源代码中出现的字符映射到源字符集。第二,编译器定位每个反斜杠后面跟着换行符的实例,并删除它们。第三,编译器把文本划分成预处理记号序列、空白序列和注释序列。 16.2明示常量:#define 每行#define(逻辑行)都由3部分组成。第1部分是#define指...

weixin_43784305的博客 417

目前最新NIST随机数测试软件下载、安装、及使用教程

最近由于科研需要,在搞一些随机数的测试的事情,众所周知 随机数测试我们可以使用NIST的软件进行多大15项的随机测试,我也在网上查找了很多大牛的博客,但是都是年代久远,很多的链接现在都是物是人非,都是不能直接使用了,今天顺便抽点时间更新一下这个NIST软件的下载及使用。我们首先讲一下该软件的下载:1.我们直接取NIST的官网(https://csrc.nist.gov/)下载即可 ;链接如下:下载...

Miracle.Zhao的博客 3万+

C Primer Plus: 第十六章 C预处理器和C库

C Primer Plus: 第十六章 C预处理器和C库 预处理是指在进行编译的第一遍扫描之前所做的工作。 预处理器在程序执行之前查看程序。预处理器把符号缩写替换成其表示的内容。预处理器可以包含程序所需的其他文件。 预处理指令在程序正式编译前就由编译器进行的操作,可以在程序中任何位置。 16.1 翻译程序第一步 编译器必须对该程序进行一些翻译处理。 把源代码中出现的字符映射到源字...

budding0828 343

华为OD机试 - 整型数组按照个位数排序(Python/JS/C/C++ 双机位C卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。给定一个非空数组(列表),其元素数据类型为整型,请按照数组元素十进制最低位从小到大进行排序,十进制最低位相同的元素,相对位置保持不变。当数组元素为负值时,十进制最低位等同于去除符号位后对应十进制值最低位。给定一个非空数组,其元素数据类型为32位有

学Java,找哪吒 399

大模型知识边界探索:LLM设计的极限测试

最优化理论是数学中的一个分支,主要研究如何从给定的一组约束条件下找到最优解。目标函数:定义了需要优化的指标,可以是最大化或最小化。约束条件:定义了在优化过程中需要满足的限制条件。无约束优化:目标函数和约束条件都不存在。有约束优化:目标函数存在,但存在约束条件。多目标优化:同时需要优化多个目标函数。极限测试(Ultimate Test)是一种系统性的方法,用于评估大型模型(如LLM)在极端条件下的性能和稳定性。极端数据分布:与模型训练数据分布显著不同的数据集。极端计算资源。

AI天才研究院 433

C Primer Plus:(第十六章)C预处理器和C库

x

qq_42347617的博客 183

Qt Installer Framework 简单使用

qt installer framework 简单使用

qq_42815643的博客 2576

C primer plus第十六章(C预处理器和C库)

#define:#define   宏     替换列表    /*宏与替换列表只发生替换作用(此阶段不进行计算)*/替换列表可能为整个C表达式,如: #define PX printf("Hello,World!"); //有效#运算符(利用宏参数创建字符串):#define PX(x) printf("The square of x is %d.",((x)*(x))); 则...

gunbani4的博客 340

YOLOv8进阶实战:融合SAHI超推理算法,在无人机应用中精准捕捉视频与图片中的微小目标

YOLOv8改进是一种先进的目标检测算法,通过引入辅助超推理算法SAHI推理,使得小目标无法逃避检测。SAHI推理算法结合视频和图片的特点,利用先进的超推理技术,提高了目标检测的准确性和鲁棒性。不仅如此,YOLOv8改进还支持对视频和图片进行实时的目标检测,将检测结果直观地呈现给用户。这一技术的应用范围广泛,可以用于安防领域,提升监控设备的性能和效率;也可以用于无人驾驶领域,实现精准的目标识别和跟踪。总之,YOLOv8改进是一项具有突破性的技术,为目标检测领域带来了重大的进展。

weixin_51988935的博客 808

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

CPrimer Plus第十六章C预处理器和C库总结1

2.预处理器直接替换文本,不进行计算(如调用会展开为而非25)3.重定义规则:仅当新旧定义​​时才允许重定义(如与允许,但与会报错)

qq_44276905的博客 293

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【C Primer Plus第六版 学习笔记】 第十六章 C预处理器和C库

有基础,进阶用,个人查漏补缺

qq_53223504的博客 760

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

CPrimer Plus第十六章C预处理器和C库总结2-qsort函数

这个函数决定了排序的顺序(升序、降序、按特定规则)int (*compar)(const void *, const void *)这是一个​。后面(符合降序:小数在后)。是为了保证函数不会修改原始数据,并且。可以处理任何数据类型的数组。参数(指向要比较的两个元素的指针)前面(符合降序:大数在前)。数组(字符串数组)按字典序升序排序。是指向数组中两个待比较元素的指针。​ 要降序,只需反转比较结果。​ 对任意类型的数组进行排序。的值大),结果是负数,表示。的值小),结果是正数,表示。

qq_44276905的博客 774

C Primer Plus (第五版) 第十六章 C预处理器和C库 编程练习

第十六章 C预处理器和C库开发一个包含您需要使用的预处理器定义的头文件//max.h #ifndef_MAX_H_ #define_MAX_H_ #defineMAX(X,Y)((X)>(Y)?(X):(Y)) #endif2.两个数的调和平均数可用如下方法得到:首先对两数的倒数取平均值,最后再取倒数。使用#define指令定义一个宏“函数”...

weixin_33923148的博客 148

《c primer plus》c语言学习笔记整理(十六)-C预处理器和C库

第十六章 C预处理器和C库 C预处理器: 在程序执行前查看程序,根据程序中的预处理器指令,预处理器把符号缩写替换为器表示的内容。 1.明示常量:#define 指令可以出现在源文件任何地方,其定义从指令出现的地方到该文件末尾有效。预处理器从#开始运行,到后面第一个换行符为止,也就是说,指令的长度仅限于一行。 预处理器不会进行实际的运算,运算的过程在编译进行,它只进行替换 宏定义还可以包含其他...

weixin_45096408的博客 627

C Primer Plus (第五版)中文版——第 16 章 C 预处理器和 C 库

16.1  翻译程序的第一步 对程序作与处理前,编译器会对它进行几次翻译处理: 首先,编译器把源代码中出现的字符映射到源字符集。该过程处理多字节字符和三元字符。 其次,编译器查找反斜线后紧跟换行符的实例并删除这些实例。 接下来,编译器将文本划分成预处理的语言符号序列、空白字符、注释序列。 16.2  明显常量:#define 每个 #define 行(逻辑行)由三部分组成: 第一部分:...

Mr__Gold的博客 357

C Primer Plus 第十六章 课后答案

目录   复习题 1.下面的几组代码由一个或多个宏组成,其后是使用宏的源代码。在每种情况下代码的结果是什么?这些代码是否是有效代码?(假设其中的变量已声明) a. b. c. d. 2.修改复习题1中d部分的定义,使其更可靠 3.定义一个宏函数,返回两值中的较小值 4.定义EVEN_GT(X, Y)宏,如果X为偶数且大于Y,该宏返回1 5.定义一个宏函数,打印两个表达式及其值...

asdgyy的博客 3140

《C Primer Plus》中文版第十六章习题

另外,如果你的实现有time()(第12章讨论过)或类似的函数,可在srand()中使用这个函数的输出来初始化随机数生成器rand()。int类型的参数指定了动态数组中的元素个数,double类型的值用于初始化元素(第1个值赋给第1个元素,以此类推)。2. 两数的调和平均数这样计算:先得到两数的倒数,然后计算两个倒数的平均值,最后取计算结果的倒数。使用较少的元素,并用选定的名字显式初始化数组。需要一个函数来完成转换,该函数接受一个极坐标的结构,并返回一个包含直角坐标的结构(或返回指向该结构的指针)。

weixin_53759045的博客 2223

C语言基础

C语言概述 第一章 C语言概述 第二章 C语言基本概念 第三章 格式化输入\输出 第四章 表达式 第五章 选择语句 第六章 循环 第七章 基本类型 第八章 数组 第九章 函数 第十章 程序结构 第十一章 指针 第十二章 指针和数组 第十三章 字符串 第十四章 预处理器 第十五章 编写大型程序 第十六章 结构、联合和枚举 第十七章 指针的高级应用 第十八章 声明 ...

mxYlulu的博客 406

C和指针

这本书对C的讲解很全面,例子

Duplan的专栏 774
上一篇: 第五章 初始化与清理
下一篇: 第十五章 位操作
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值