C++学习笔记----10、模块、头文件及各种主题(二)---- 预处理指令

        使用#include预处理指令来包含头文件的内容。还有一些预处理指令。下面列表展示了一些常用的预处理指令:

预处理指令

功能

通用场景

#include [file]

[file]文件名的内容插入到指令位置的代码中

几乎总是用于包含头文件以便代码可以使用定义在其它地方的功能

#define [id] [value]

每个标识符[id]出现的地方都用[value]替换

常用于C定义常数或宏。c++对于常数与大部分类型的宏提供了更好的方法。宏可能会危险,所以要小心使用。

#undef [id]

使前面使用#define定义的[id]失效

如果定义的标识符只要求在限定范围的代码中使用。

#if [expression]

#elif [expression]

#else

#endif

基于给定表达式的结果有条件包含代码块

常用于提供特定平台的特定代码

#ifdef [id]

#endif

#ifndef [id]

#endif

基于特定标识符是否使用#define定义有条件地包含代码。#ifdef [id]与#if defined(id)等价,#ifndef [id]与#if !defined(id)等价

最常用于保护循环包含。以#ifndef开头的头文件检查是否有标识符的定义,接着用#define指令定义该标识符。头文件以#endif结束。这防止文件被包含多次。

#elifdef [id]

#elifndef [id]

#elifdef [id]与#elif defined(id)等价,#elifndef [id]与#elif !defined(id)等价

其它功能的缩写。

#pragma [xyz]

控制特定编译器的行为。[xyz]是编译器依赖的。大部分编译器支持once来防止头文件包含多次

#error [message]

使编译以给定的信息停止。

如果用户想在不支持的平台上编译代码,可用于停止编译。

#warning [message]

使编译器发出给定警告信息,但是编译继续。

在不影响编译结果的情况下用于显示警告给用户。

1、预处理宏

        可以使用C++预处理指令书写宏,看起来像小函数。举例如下:

#define SQUARE(x) ((x) * (x)) // No semicolon after the macro definition!int main()
{println("{}", SQUARE(5));
}

        宏是C的产物,与inline函数很像,但是不进行类型检查,预处理只是单纯地将对其的调用进行替换。预处理器不执行真实的函数调用语法检查。这种行为可能产生不可预知的结果。例如,考虑如果用2+3而不是5来调用SQUARE宏会发生什么,像这样:

println("{}", SQUARE(2 + 3));

        你想让SQUARE计算出25,它确实这么做了。然而,如果你漏掉了宏定义中的一些括号,看起来像这样?

#define SQUARE(x) (x * x)

        现在对SQUARE(2+3)的调用生成了11,而不是25!记住宏只是单纯地替换而不进行函数调用语法的检查。这就意味着宏体中的x被替换为了2+3,变成如下的语句:

println("{}", (2 + 3 * 2 + 3));

        遵守运算的优先级顺序,这行代码行执行乘法,接着是加法,生成11而不是25!

        宏也有性能影响。假定调用SQUARE宏如下:

println("{}", SQUARE(veryExpensiveFunctionCallToComputeNumber()));

        预处理器替换如下:

println("{}", ((veryExpensiveFunctionCallToComputeNumber()) *
(veryExpensiveFunctionCallToComputeNumber())));

        现在调用了昂贵的函数两次--另一个避免使用宏的原因。

        宏在排错时也会出问题,因为你写的代码不是编译器看到的代码,或者说是在debugger中显示的代码(因为预处理器的查找替换行为)。由于这些原因,应该避免使用宏,要使用内联函数。讲这么多就是因为确实有一些代码还在使用宏。需要理解、阅读并维护这样的代码。

        注意:大部分编译器可以输出预处理源码到文件或标准输出。可以使用这个我来观察预处理器怎么预处理你的代码。例如,在微软Visual C++中可以使用/P开关。GCC中使用-E开关。

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

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

相关文章

基于STM32的自动化植物浇灌系统教学

引言 随着城市化进程的加快,越来越多的人开始关注家庭园艺与植物养护。基于STM32的自动化植物浇灌系统可以帮助用户在忙碌的生活中顺利管理植物的水分需求。本教学文章将指导您如何利用STM32构建一个简单实用的植物浇灌系统,实现自动浇水功能。 环境准备…

美格智能5G车规级通信模组: 5G+C-V2X连接汽车通信未来十年

自2019年5G牌照发放开始,经过五年发展,我国5G在基础设施建设、用户规模、创新应用等方面均取得了显著成绩,5G网络建设也即将从基础的大范围覆盖向各产业融合的全场景应用转变。工业和信息化部数据显示,5G行业应用已融入76个国民经…

【CRM系统选型指南:国内八大主流工具比较】

本文将对十大主流CRM系统进行比较:纷享销客、Zoho CRM、Pipedrive、简信CRM、HubSpot CRM、八百客CRM、金蝶CRM、浪潮CRM、销售易CRM 本文将深入评比2024年主流的CRM系统,帮助你了解各系统之间的主要区别、优缺点以及当前的发展趋势。通过详细的比较和分…

node.js的exports使用误区解释

exports和module.exports指向同一个对象,最终共享的结果,以module.exports指向的对象为准。 exports 和 module.exports 使用误区 使用require()导入的模块,使用的永远是module.exports指向的对象 实例1 exports.age 23 module.exports {n…

Maven项目的基础配置:利用IDEA将SpringBoot的项目打包成war文件

文章目录 引言Maven项目的聚合与继承(依赖管理)把项目打包成war包其他打包配置引言 利用IDEA将SpringBoot的项目打包成war文件Maven项目的聚合与继承(依赖管理)Maven项目的聚合与继承(依赖管理) 把项目打包成war包 利用IDEA将SpringBoot的项目打包成war文件:要配置启动…

Nuxt.js 应用中的 nitro:config 事件钩子详解

title: Nuxt.js 应用中的 nitro:config 事件钩子详解 date: 2024/11/2 updated: 2024/11/2 author: cmdragon excerpt: nitro:config 是 Nuxt 3 中的一个生命周期钩子,允许开发者在初始化 Nitro 之前自定义 Nitro 的配置。Nitro 是 Nuxt 3 的服务器引擎,负责处理请求、渲…

51c大模型~合集14

我自己的原文哦~ https://blog.51cto.com/whaosoft/11603879 # LLM 结构化数据生成原理 如何结合人工规则让 LLM 输出符合 JSON 格式的数据。 目前 LLM(Large Language Model)从文本补全到内容创作,都展示出了强大的生成能力。然而通过 L…

CSRA的LINUX操作系统24年11月2日下午上课笔记

压缩和解压缩:zip 、gzip、bz、xz # zip 压缩 # 压缩文件夹 # 解压缩 # unzip -v 查看压缩包中的内容 # bzip2 dir1/* :将dir1中的所有文件压缩 # gzip # 压缩文件夹 # 解压缩 tar 归档命令: # 创建tar包 tar -c*f # 释放tar包 tar -xf[c] # c …

MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符

一、问题 MyBatis 返回 Map 或 List时,时间类型数据,默认为LocalDateTime Springboot 响应给前端的LocalDateTime,默认含有’T’字符,如何统一配置去掉 二、解决方案 1、创建配置类,对ObjectMapper对象进行定制&am…

数据结构算法篇--递归(c语言版)

目录 1.递归 1.1求阶乘: 1.2.斐波那契数 1.3. 求幂 1.递归 在C语言中,递归是一种函数调用自身的方法,用来解决一些具有重复性质的问题。例如,计算阶乘、斐波那契数列等问题都可以通过递归实现。 递归在书写的时候&#xff0…

在vue3的vite网络请求报错 [vite] http proxy error:

在开发的过程中 代理proxy报错: [vite] http proxy error: /ranking/hostRank?dateType1 Error: connect ETIMEDOUT 43.xxx.xxx.xxx:443 网络请求是http的: // vite.config.ts import { Agent } from node:http;server: {host: 0.0.0.0,port: port,open: true,https: false,…

西南科技大学C++作业1——组合依赖关系实验代码

目录 一、实现效果预览 二、实验要求 三、实现代码 book.h book.cpp borrow.h borrow.cpp library.h library.cpp student.h student.cpp main.cpp 一、实现效果预览 二、实验要求 作业1:类与类关系设计(组合或依赖) 目 的: 1) 巩固类的定义,成员变量、成员方…

GPIO子系统中Controller驱动源码分析

往期内容 本专栏往期内容: Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体Pinctrl子系统中c…

【系统架构设计师】六、UML建模与架构文档化

在20世纪70年代,陆续出现了面向对象的建模方法,UML(统一建模语言)的出现,以融合了多种面向对象建模方法,简介的图形和符号,直观的表示和强大的表示能力,得到了工业界与学术界认可。它…

【实用技能】在 SQL Server 中使用 LIMIT 子句的替代方案

在数据库管理中,有效限制查询结果对于优化性能和确保检索相关数据至关重要。许多 SQL 数据库系统(例如 MySQL 和 PostgreSQL)都使用LIMIT子句来指定查询返回的记录数。但是,SQL Server 不支持该LIMIT子句,而是选择诸如…

Apache-Hive数据库使用学习

前期准备 Hadoop-分布式部署(服务全部在线) Mysql-node1节点部署(确认安装正常) apache-hive -node1节点部署(需要与MySQL元数据联动存储) 参考博客: Hadoop Hadoop集群搭建-完全分布式_hadoop完…

Webserver(3.2)锁

目录 互斥量死锁未解锁重复加锁多个锁 读写锁案例 互斥量 接上一章&#xff0c;卖票存在线程安全问题。 #include<stdio.h> #include<pthread.h> #include<unistd.h> int tickets1000;//局部变量就是每个人卖100张&#xff0c;全局变量就是一起卖100张&…

105. UE5 GAS RPG 搭建主菜单

在这一篇&#xff0c;我们将实现对打开游戏显示的主菜单进行搭建&#xff0c;主菜单将显示游戏主角&#xff0c;游戏名称和进入游戏和退出游戏两个按钮。 搭建菜单场景 我们将主菜单设置为一个单独的场景&#xff0c;前面可以显示对应的UI控件&#xff0c;用于玩家操作&#…

语义分割——U-Net

U-Net是继FCN之后又一个经典的语义分割网络模型&#xff0c;并且也是很多后续语义分割模型的“祖宗”。这个网络模型是2015年提出来的&#xff0c;它具有一个非常对称的结构&#xff0c;很像字母“U”&#xff0c;所以被称作U-Net。U-Net被广泛应用于医学影像领域&#xff0c;如…

AI之硬件对比:据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D

AI之硬件对比&#xff1a;据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D 目录 Nvidia的显卡 Nvidia的5090/5080/4090/4080&#xff1a;据传传英伟达Nvidia RTX 5090后续推出32GB版且RTX 5080后续或推出24GB版 RTX 5090相较于RTX 4090&…