预处理详解(二)-- 条件编译 - 头文件包含 - ##和#运算符

目录

  • 一.##和#运算符
    • 1.#运算符(字符串化)
    • 2.##运算符(粘合符)
  • 二.条件编译(很重要)
  • 三.命名约定
    • 1.宏名的命名
    • 2.函数的命名
  • 四.#undef(用于移除一个宏定义)
  • 五.命名行约定
  • 六.头文件被包含的方式
    • 1.本地文件包含
    • 2.库文件包含
    • 3.嵌套文件包含(重复引入了同一个头文件)

在这里插入图片描述

一.##和#运算符

1.#运算符(字符串化)

#运算符将宏的参数变成一个字符串 这里的#并不是#include或#define中的# 在举例子之前,说明一下字符串是有自动连接的特点的

printf("hello""world");
//打印后是helloworld

在这里插入图片描述

#define PRINT(n) printf("the value of" #n "is %d",n); 
int a = 10;
printf("the value of"#a"is""%d",a);
//      the value of a is 10

在这里插入图片描述

2.##运算符(粘合符)

##可以将位于##两边的符号合成一个符号
它允许宏定义从分离的文本片段创建标识符
##又被称为记号粘合

例如:

//求两个数(不同类型的变量)的最大值
//定义了函数模版
#define a_MAX(type) \
type type_##MAX(type x,type y) \
{                            \
  return ((x>y)?x:y);         \
}                              

在这里插入图片描述
##和#算是冷门的知识点

拓展:
offsetof – 宏
计算结构体的成员的偏移量
是相较于首字节地址的偏移量
包含的头文件是 #include<stddef.h>
printf(结构体关键字,结构体成员名);

二.条件编译(很重要)

在编译一条指令时删除又可惜保留有碍事,那么我们可以选择有条件的编译

常见的条件编译指令:

1.单分子的条件编译
#if 常量表达式 //常量表达式由预处理器求值
  //使用      //条件如果为假(0),不参加编译,非0为真,参与编译
  //...
#endif
2.多分支的条件编译(跟ifelse差不多)
#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif
3.判断是否被定义
#define MAX 1 //定义了MAX
#if defined(MAX)//执行
//...
#endif

#ifdef MAX //定义了MAX,执行
//...
#endif

#if !defined(MAX)//这两个都是如果未定义就执行
#ifndef MAX

4.嵌套指令(if else 的嵌套也差不多)
#if defined(OS_UNIX)
   #ifdef OPTION1
   unix_version_option1();
   #endif
     #ifdef OPTION2
     unix_version_option2();
     #endif
#elif defined(OS_MSDOS)
       #ifdef OPTION2
       msdos_version_option2();
       #endif
#endif

三.命名约定

函数的命名和宏的命名非常相似
所以在语言上无法区分两者

1.宏名的命名

宏名全都大写(MAX)

2.函数的命名

函数名不全大写(Add)

四.#undef(用于移除一个宏定义)

#define MAX(a,b) a>b?a:b

int main()
{
	int a = 1;
	int b = 2;
	int ret = MAX(a, b);
    #undef MAX
	//MAX的宏定义被移除了,后面无法运行了
	int c = MAX(a, b);

	return 0;
}

五.命名行约定

许多编译器允许在命令行中定义符号(但是vs不允许,vscode可以),用于启动编译过程

例如:我们根据同一个源文件要编译出一个程序的不同版本时,这个还是有用的。(假定某个程序中声明了某个长度的数组,如果机器内存有限,要一个小的数组,但另一个机器内存大些,我们要一个大点的数组)

int main()
{
  int arr[SIZE];//在命令行改变SIZE的大小,即可改变数组的大小
  int i = 0;
  for(i = 0;i < SIZE;i++)
  {
   arr[i] = i;
  }
  for(i = 0;i < SIZE;i++)
  {
   printf("%d ",arr[i]);
  }
  return 0;
}

六.头文件被包含的方式

1.本地文件包含

#include"filetest"

先在源文件(本工程路径)下查找,编译器再到标准库中去查找,再没找到就编译错误

vs环境下标准头文件的路径:
C:\Program Files (x86)\Microsoft Visual Studio 12.0 \VC\include (vs2013下的路径)

Linux环境下标准头文件的路径:
/usr/include

2.库文件包含

查找标准库下的头文件,就直接到标准库下查找
找不到就编译错误

本地文件包含可以用""吗?
答案是肯定的,但是这样做效率就低些,这样也不易于区分是库文件还是本地文件

3.嵌套文件包含(重复引入了同一个头文件)

//test.c
#include"test.h"
#include"test.h"
#include"test.h"

int main()
{
  //使用
  //...
  return 0;
}
//test.h
test();
//使用
//...

test.h头文件在test.c中被重复(多次)包含,那么test.h中的内容会被拷贝3份到test.c中
如果头文件的工程量比较巨大,这样被多次拷贝,后果将不堪设想
那么怎么解决这个问题呢?
可以使用条件编译

#ifndef __ TEST_H__ //如果没有这个文件为真就执行下面代码
#define __ TEST_H__//定义这个文件
//使用
//...
#endif
// 下次进入 #ifndef 为假(有这个文件了),不进入,一直为假
//只出现一份内容

包含一次头文件,判断一次#ifndef,第二次包含也是如此,如此往复
第一次包含头文件是没定义__TEST_H__的,所以会执行里面的代码,第二次已经定义了__TEST_H__ ,为假,不执行代码了,往后也不执行了

#pragma once
//就可以避免头文件的重复引用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 基于ELM-Adaboost极限学习机结合Adaboost集成学习时间序列预测(股票价格预测) 单变量时间序列单步预测。 ELM(Extreme Learning Machine,极限学习机)和AdaBoost(Adaptive Boosting,自适应提升)都是机…

Disruptor

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;这是我作为学习笔记总结应用篇最后一篇&#xff0c;本章大量的参考了别的博主的文章。 我们今天一起来看一个开源项目 Disruptor。看看我们怎么利用 CPU 和高速缓存的硬件特性&#xff0c;来设计一个对于性能有极限追求的系…

【C#】知识点速通

前言&#xff1a; 笔者是跟着哔站课程&#xff08;Trigger&#xff09;学习unity才去学习的C#&#xff0c;并且C语言功底尚存&#xff0c;所以只是简单地跟着课程将unity所用的C#语言的关键部分进行了了解&#xff0c;然后在后期unity学习过程中加以深度学习。如需完善的C#知识…

Python 后端 Flask 使用 Flask-SocketIO、前端 Vue3 实现长连接 Websocket 通信详细教程(更新中)

Flask 安装 Flask-Socketio Flask-SocketIO 第三方库使 Flask 应用程序可以实现客户端和服务器之间的低延迟双向通信。客户端应用程序可以使用 Javascript、Python、C、Java 和 Swift 中的任何 SocketIO 客户端库或任何其他兼容客户端来建立与服务器的永久连接。 Flask-Socke…

编程语言|C语言——C语言操作符的详细解释

这篇文章主要详细介绍了C语言的操作符&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 一、基础 1.1 算数操作符 - * / % - * / 这些操作符是我们…

【Redis】Redis 生产问题。如何确保缓存和数据库数据的一致性? 常见的缓存更新策略?

目录 缓存穿透 缓存穿透解决办法 缓存击穿 击穿解决办法&#xff1f; 缓存穿透和缓存击穿的区别&#xff1f; 缓存雪崩 雪崩解决办法&#xff1f; 如何确保缓存和数据库数据的一致性&#xff1f; 常见的缓存更新策略&#xff1f; 缓存穿透 定义&#xff1a;缓存穿透说…

[BT]BUUCTF刷题第11天(3.30)

第11天 Web&#xff08;共3题&#xff09; [网鼎杯 2018]Fakebook 打开是一个注册登录页面&#xff0c;包括用户、年龄和博客地址 查看题解知道存在robots.txt 访问http://c1392d44-63c3-4152-bf7e-89513eff1152.node5.buuoj.cn:81/robots.txt&#xff1a; User-agent: * D…

解决MySQL幻读?可重复读隔离级别背后的工作原理

什么是当前读和快照读 当前读&#xff1a;又称为 "锁定读"&#xff0c;它会读取记录的最新版本&#xff08;也就是最新的提交结果&#xff09;&#xff0c;并对读取到的数据加锁&#xff0c;其它事务不能修改这些数据&#xff0c;直到当前事务提交或回滚。"sele…

python统计分析——灵敏度、特异度和ROC曲线

参考资料&#xff1a;python统计分析【托马斯】 1、灵敏度和特异度 灵敏度&#xff1a;也叫作效能。被检验正确识别出来的阳性结果&#xff08;病人中有疾病且检验结果是阳性的概率&#xff09;。 特异度&#xff1a;被检验正确识别出来的阴性结果&#xff08;病人健康且检验结…

mysqldump备份数据库提示ERROR 1064 (42000): You have an error in your SQL syntax

在dos下备份数据库的时候提示上面的错误信息 1 错误详情 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near mysql-v at line 1错误示例图 2 解决办法 通过查资料…

vue2.0脚手架搭建

vue起步 文档 https://v2.cn.vuejs.org/ {{}} 变量、表达式渲染v-html html模板&#xff0c;渲染htmlv-model 绑定值&#xff08;双向绑定&#xff09;v-if 判断v-bind&#xff1a;href"地址" 简写&#xff1a;绑定属性 简写&#xff1a;href&#xff1a;"&qu…

OpenKylin安装Kafka

一、操作系统 openKylin 1.0.1 X86 二、下载安装包 # 安装依赖jdk sudo apt-get update sudo apt-get install default-jdk # 下载kafka mkdir -p /data/software/kafka wget https://archive.apache.org/dist/kafka/2.4.1/kafka_2.13-2.4.1.tgz三、解压安装 # 解压缩Kafka…

腾讯云2核2G服务器优惠价格,61元一年

腾讯云2核2G服务器多少钱一年&#xff1f;轻量服务器61元一年&#xff0c;CVM 2核2G S5服务器313.2元15个月&#xff0c;轻量2核2G3M带宽、40系统盘&#xff0c;云服务器CVM S5实例是2核2G、50G系统盘。腾讯云2核2G服务器优惠活动 txybk.com/go/txy 链接打开如下图&#xff1a;…

【2023】kafka入门学习与使用(kafka-2)

目录&#x1f4bb; 一、基本介绍1、产生背景2、 消息队列介绍2.1、消息队列的本质作用2.2、消息队列的使用场景2.3、消息队列的两种模式2.4、消息队列选型&#xff1a; 二、kafka组件1、核心组件概念2、架构3、基本使用3.1、消费消息3.2、单播和多播消息的实现 4、主题和分区4.…

TypeScript编译器tsc的入门指南

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

货物摆放例题——(求n的所有因子+foreach循环+set集合应用)

这里写目录标题 例题引入题目分析解题方法1.暴力求解2.求n的所有的因子foreach循环 3.利用 set集合 参考文章 例题引入 题目分析 - n个都是 V1 的小正方体---》去拼成一个大的长方体---》满足nLWH - 也就是&#xff0c;在小于等于n的所有数中&#xff0c;任取3个数&#xff08…

vitess执行计划缓存 测试

打开执行计划器缓存&#xff1a; sysbench /usr/local/share/sysbench/oltp_write_only.lua --mysql-host127.0.0.1 --mysql-port15306 --mysql-userroot --mysql-password --mysql-dbcustomer --report-interval10 100s sysbench /usr/local/share/sysbench/oltp_read_only.l…

前端三剑客 —— HTML (上)

前端 前端是什么&#xff1f; 把我们的数据以各种方式&#xff08;如&#xff1a;表格、饼图、柱状图等&#xff09;呈现给用户&#xff0c;我们就可以称之为前端。 做前端需要的工具&#xff1f; notepad、editplus、notepad、VS code、webstorm等&#xff0c;一般用于前端开…

嵌入式硬件中常见的面试问题与实现

1 01 请列举您知道的电阻、电容、电感品牌(最好包括国内、国外品牌) ▶电阻 美国:AVX、VISHAY威世 日本:KOA兴亚、Kyocera京瓷、muRata村田、Panasonic松下、ROHM罗姆、susumu、TDK 台湾:LIZ丽智、PHYCOM飞元、RALEC旺诠、ROYALOHM厚生、SUPEROHM美隆、TA-I大毅、TMT…

数据结构 - 算法效率|时间复杂度|空间复杂度

目录 1.算法效率 2.时间复杂度 2.1定义 2.2大O渐近表示法 2.3常见时间复杂度计算举例 3.空间复杂度 3.1定义 3.2常见空间复杂度计算举例 1.算法效率 算法的效率常用算法复杂度来衡量&#xff0c;算法复杂度描述了算法在输入数据规模变化时&#xff0c;其运行时间和空间…