C 语言零基础入门教程(二十)

news2024/11/15 8:40:29

C 预处理器

C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。

所有的预处理器命令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。下面列出了所有重要的预处理器指令:
在这里插入图片描述

预处理器实例

分析下面的实例来理解不同的指令。

#define MAX_ARRAY_LENGTH 20

这个指令告诉 CPP 把所有的 MAX_ARRAY_LENGTH 定义为 20。使用 #define 定义常量来增强可读性。

#include <stdio.h>
#include "myheader.h"

这些指令告诉 CPP 从系统库中获取 stdio.h,并添加文本到当前的源文件中。下一行告诉 CPP 从本地目录中获取 myheader.h,并添加内容到当前的源文件中。

#undef  FILE_SIZE
#define FILE_SIZE 42

这个指令告诉 CPP 取消已定义的 FILE_SIZE,并定义它为 42。

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

这个指令告诉 CPP 只有当 MESSAGE 未定义时,才定义 MESSAGE。

#ifdef DEBUG
   /* Your debugging statements here */
#endif

这个指令告诉 CPP 如果定义了 DEBUG,则执行处理语句。在编译时,如果您向 gcc 编译器传递了 -DDEBUG 开关量,这个指令就非常有用。它定义了 DEBUG,您可以在编译期间随时开启或关闭调试。

预定义宏

ANSI C 定义了许多宏。在编程中您可以使用这些宏,但是不能直接修改这些预定义的宏。
在这里插入图片描述
让我们来尝试下面的实例:

实例

#include <stdio.h>
 
main()
{
   printf("File :%s\n", __FILE__ );
   printf("Date :%s\n", __DATE__ );
   printf("Time :%s\n", __TIME__ );
   printf("Line :%d\n", __LINE__ );
   printf("ANSI :%d\n", __STDC__ );
 
}

当上面的代码(在文件 test.c 中)被编译和执行时,它会产生下列结果:

File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8
ANSI :1

预处理器运算符

C 预处理器提供了下列的运算符来帮助您创建宏:

宏延续运算符(\)
一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)。例如:

#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")

字符串常量化运算符(#)
在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表。例如:

#include <stdio.h>
 
#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")
 
int main(void)
{
   message_for(Carole, Debra);
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Carole and Debra: We love you!

标记粘贴运算符(##)
宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记。例如:

#include <stdio.h>
 
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
 
int main(void)
{
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

token34 = 40

这是怎么发生的,因为这个实例会从编译器产生下列的实际输出:

printf ("token34 = %d", token34);

这个实例演示了 token##n 会连接到 token34 中,在这里,我们使用了字符串常量化运算符(#)和标记粘贴运算符(##)。

defined() 运算符
预处理器 defined 运算符是用在常量表达式中的,用来确定一个标识符是否已经使用 #define 定义过。如果指定的标识符已定义,则值为真(非零)。如果指定的标识符未定义,则值为假(零)。下面的实例演示了 defined() 运算符的用法:

#include <stdio.h>
 
#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif
 
int main(void)
{
   printf("Here is the message: %s\n", MESSAGE);  
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Here is the message: You wish!

参数化的宏

CPP 一个强大的功能是可以使用参数化的宏来模拟函数。例如,下面的代码是计算一个数的平方:

int square(int x) {
   return x * x;
}

我们可以使用宏重写上面的代码,如下:

#define square(x) ((x) * (x))

在使用带有参数的宏之前,必须使用 #define 指令定义。参数列表是括在圆括号内,且必须紧跟在宏名称的后边。宏名称和左圆括号之间不允许有空格。例如:

#include <stdio.h>
 
#define MAX(x,y) ((x) > (y) ? (x) : (y))
 
int main(void)
{
   printf("Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Max between 20 and 10 is 20

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/187731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

练手好福利!20个Python实战项目含源代码【2023最新】

高效学习源代码的步骤&#xff1a;1.运行程序&#xff0c;观察表现2.运行源码&#xff0c;断点调试&#xff0c;从头跟一边源码的执行流程&#xff0c;注意函数堆栈3.画类图、流程图&#xff0c;先把遇到的重要类记录下来&#xff0c;表明各个类的关系4.记录问题&#xff0c;把…

Unity XR

一、几个Unity XR Interaction Toolkit学习地址 1.B站视频 https://www.bilibili.com/video/BV11q4y1b74z/?spm_id_from333.999.0.0&vd_source8125d294022d2e63a58dfd228a7fcf63 https://www.bilibili.com/video/BV13b4y177J4/?spm_id_from333.999.0.0&vd_source8…

【对象的比较】java代码实现,详解对象的比较,Comparable接口和Comparator比较器

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#xff0c;&#x1f49e;&#x1f49e;&#x1f49e;今天的我们要学习的知识点是java对象的比较&#xff0c;不是大家现实生活中对象的比较&#xff0c;是java中new一个对象的那个对象&#xff0c;对象的比较到底是什么意思呢&…

24.网络编程(二)

目录 三.TCP通信 3.1 TCP协议特点 3.2 TCP协议通信场景 3.3 TCP通信模型演示 3.4 Socket 3.5 ServerSocket 3.6 注意事项 3.7 案例 3.7.1 TCP通信—单发单收 3.7.2 TCP通信—多发多收 3.7.3 TCP通信—同时接收多个客户端的消息。 3.7.4 TCP通信—使用线程池优化&am…

工业相机和镜头

工业相机和镜头镜头型号数据电源接口定焦镜头的调焦景深景深大小光圈相机、镜头选取参考镜头型号、数据电源接口、定焦镜头的调焦、景深、景深大小、光圈、相机、镜头选取 镜头型号 C&#xff0c;CS系列&#xff1a;相机镜头的C、CS接口非常相似&#xff0c;它们的接口直径、螺…

检索业务:基本数据渲染和排错

采用标签显示商品的数据 <div class"rig_tab"><div th:each"product:${result.getProducts()}"><div class"ico"><i class"iconfont icon-weiguanzhu"></i><a href"/static/search/#">…

5、数据的重构

目录 一、为什么进行数据重构 二、如何进行数据重构 一、为什么进行数据重构 进行数据分析时&#xff0c;有可能会发现数据的结构并不适合直接进行数据分析操作&#xff0c;如下面数据&#xff0c;但通过复制-粘贴-转置等方法操作又太繁琐&#xff0c;数据量小还行&#xff…

C++ 图进阶系列之 kruskal 和 Prim 算法_图向最小生成树的华丽转身

1. 前言 树和图形状相似&#xff0c;也有差异性。树中添加一条或多条边&#xff0c;可成图。图中减小一条或多条边&#xff0c;可成树。形态的变化由数据之间的逻辑关系决定。 图用来描述数据之间多对多关系。树用来描述数据之间一对多关系。 思考如下问题&#xff1f; 如果…

esp32 烧录协议

esp32的rom固化了出场固件。进入烧录模式后&#xff0c;esp32串口输出&#xff1a;给esp32烧录固件的时候&#xff0c;需要和rom的bootloder进行通讯。通讯时&#xff0c;使用 SLIP 数据包帧进行双向数据传输。每个 SLIP 数据包都以 0xC0 开始和结束。 在数据包中&#xff0c;所…

9、Servlet——Request对象

目录 一、get请求和post请求的区别 二、Request对象的应用 1、request主要方法 2、request获取数据 3、设置请求的编码格式 三、解决get请求收参乱码问题 四、解决post请求中文乱码问题 一、get请求和post请求的区别 在Servlet中用来处理客户端请求需要用doGet()方法或…

openGauss数据库源码解析系列文章——备份恢复机制:openGauss全量备份技术

目录 10.1 openGauss全量备份技术 10.1.1 gs_basebackup备份工具 10.1.2 gs_basebackup备份交互流程 本文主要介绍openGauss的备份恢复原理和技术。备份恢复是数据库日常维护的一个例行活动&#xff0c;通过把数据库数据备份到另外一个地方&#xff0c;可以抵御介质类的损…

数据结构与算法-稀疏数组

Java高级系列文章前言 本文章涉及到数据结构与算法的知识&#xff0c;该知识属于Java高级阶段&#xff0c;通常为学习的二阶段&#xff0c;本系列文章涉及到的内容如下&#xff08;橙色框选内容&#xff09;&#xff1a; 本文章核心是教学视频&#xff0c;所以属于个人笔记&a…

深度卷积对抗神经网络 基础 第六部分 缺点和偏见 GANs Disadvantages and Bias

深度卷积对抗神经网络 基础 第六部分 缺点和偏见 GANs Disadvantages and Bias GANs 综合评估 生成对抗网络&#xff08;英语&#xff1a;Generative Adversarial Network&#xff0c;简称GAN&#xff09;是非监督式学习的一种方法&#xff0c;透过两个神经网络相互博弈的方式…

实体对齐(三):RNM

一.摘要 实体对齐旨在将来自不同知识图&#xff08;KG&#xff09;的具有相同含义的实体联系起来&#xff0c;这是知识融合的重要步骤。 现有研究侧重于通过利用知识图谱的结构信息学习实体嵌入来进行实体对齐。这些方法可以聚合来自相邻节点的信息&#xff0c;但也可能带来来…

从软件开发角度看待PCI和PCIe

从软件开发角度看待PCI和PCIe 文章目录从软件开发角度看待PCI和PCIe参考资料&#xff1a;一、 最容易访问的设备是什么二、 地址空间的概念三、 理解PCI和PCIE的关键3.1 地址空间转换3.2 PCI接口速览3.3 PCIe接口速览四、 访问PCI/PCIe设备的流程4.1 PCI/PCIe设备的配置信息4.2…

特斯拉2022全年财报摘要

重点一览一、盈利方面 2022全年营业利润率为16.8%&#xff0c;其中第四季度为16.0% 2022全年GAAP营业利润为137亿美元&#xff0c;其中第四季度为39亿美元 2022全年GAAP净利润为126亿美元&#xff0c;其中第四季度为37亿美元 2022全年非GAAP净利润为141亿美元&#xff0c;其中…

MySQL中的多表联合查询

目录 一.介绍 数据准备 交叉连接查询 内连接查询 外连接 子查询 特点 子查询关键字 all关键字 any关键字和some关键字 in关键字 exists关键字 自关联查询 总结 一.介绍 多表查询就是同时查询两个或两个以上的表&#xff0c;因为有的时候用户在查看数据的时候,需要…

四足机器人发展史及机器人盘点

四足机器人发展史及机器人盘点 本文翻译整理自文章 四足行走机器人发展综述 20世纪初前后 1870 CHebyshev(沙俄)发明了第一个行走机构, 将旋转运动转换为匀速平动运动. - 由于连接机构形似希腊字母λ, 该连杆命名为λ机构. - 可在平面运动, 没有独立的腿部运动 - Rygg(美国…

windows下nodejs下载及环境变量配置,运行vue项目

文章目录1.下载安装node.js2.环境变量配置&#xff08;重点&#xff09;3.切换镜像源切换yarn作为主力命令1.下载安装node.js 1.https://registry.npmmirror.com/binary.html 搜索node&#xff0c;下载对应的版本&#xff0c;安装即可。一路next&#xff0c;路径选择自己想放置…

与string容易混淆的类——StringBuilder

目录 StringBuilder类概述及其构造方法 StringBuilder类的常用方法 StringBuilder类练习 StringBuilder类概述及其构造方法 StringBuilder类概述–我们如果对字符串进行拼接操作&#xff0c;每次拼接&#xff0c;都会构建一个新的String对象&#xff0c;既耗时&#xff0c;…