【C初阶】预处理

前言:在本文中,我将系统的整理一下C语言关于预处理部分的语法,便于整理与回归。

1.预定义符号

在C语言中,C标准提供里一些C预定义符号,在预处理期间完成,可以直接使用。
有如下几个符号:
在这里插入图片描述

2.#define

在这个define情况下,该语句是在预处理期间处理完成的。有下面几种不同的分类:

2.1#define 常量定义

在这里插入图片描述
注:在使用这个常量定义时候,尽量不要在后面带上“;"这个分号(有需要除外)。

2.2#define 宏定义

#define机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏(definemacro)
在这里插入图片描述
注:
1.参数列表的左括号必须与name紧邻,如果两者之间有任何空⽩存在,参数列表就会被解释为stuff的⼀部分。
2.要带上小括号
3.不要使用带有改变参数本身性质的语法
在这里插入图片描述

宏在替换过程中,遵循以下规律:

  1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先被替换。
  2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。
  3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。

注:1.define可以出现其他define符号 2.在define中不能使用递归

2.3 宏与函数区别

在这里插入图片描述

3.4#undef 移除定义

在这里插入图片描述

3.5define与函数的命名约定

在通常情况下,宏一般全部大写命名,函数一般不全大写命名。

3.#与##操作符

#作用:将参数字符串化
##作用:参数字符串化并粘合其右边符号作为一个变量名称

3.1#的代码示例:

把字符串中的参数字符串化

#include<stdio.h>#define my_printf(val,name) printf("the num of " #name " is %d",val);int main()
{int a = 6;my_printf(a, a);return 0;
}

在这里插入图片描述

3.2##的代码示例

造一个贴切返回类型的函数名

#define my_max(type) \
type type##_max(type x,type y)\
{\
return x>y?x:y;\
}\

my_max(int)int main()
{int max = int_max(1, 2);printf("max = %d\n", max);return 0;
}

在这里插入图片描述

4.命名行定义

许多C的编译器提供了⼀种能⼒,允许在命令⾏中定义符号。⽤于启动编译过程。例如:当我们根据同⼀个源⽂件要编译出⼀个程序的不同版本的时候,这个特性有点⽤处。(假定某个程序中声明了⼀个某个⻓度的数组,如果机器内存有限,我们需要⼀个很⼩的数组,但是另外⼀个机器内存⼤些,我们需要⼀个数组能够⼤些。)
在这里插入图片描述

5.条件编译

在编译⼀个程序的时候我们如果要将⼀条语句(⼀组语句)编译或者放弃是很⽅便的。
条件编译用来处理调试性的代码,删除可惜,保留⼜碍事,所以我们可以选择性的编译或者是一些不同版本的代码。

5.1#if

这个跟if基本是一样的,如果if后面结果为真,那么下面这些代码(直到#end)就执行编译,为假就不参与编译。
下面是示例:

int main()
{
#if 1printf("hello world\n");
#endifreturn 0;
}

在这里插入图片描述

这里有个很坑的写法:

#include<stdio.h>
#include<windows.h>#define A 1
int main()
{int a = 1;#if A == aprintf("hello world\n");
#endifsystem("pause");return 0;
}

在这里插入图片描述
明明相等为啥printf不参与编译啊?因为变量a是在预处理之后形成的。
在这里插入图片描述

5.2#ifdef

如果后面的参量名称被定义了,那么ifdef下面(直到#endif)就参与编译。如果没有被定义,ifdef下面(直到#endif)就不参与编译。

#include<stdio.h>
#include<windows.h>#define PAUSEint main()
{#ifdef PAUSEprintf("pause\n");
#endifreturn 0;
}

在这里插入图片描述

5.3#ifndef

如果后面的参量名称没有被定义,那么ifndef下面(直到#endif)就参与编译。如果被定义,ifndef下面(直到#endif)就不参与编译。

#include<stdio.h>
#include<windows.h>#define PAUSEint main()
{#ifndef PAUSEprintf("pause\n");
#endifreturn 0;
}

在这里插入图片描述
所以这里有个很重要的常见用法:就是避免头文件重复包含的问题(参见下面方法2)。

//1.方式1:
#pragma once//2.方式2:
#ifndef ONCE
#define ONCE//...#endif

5.4多个分支条件编译#if #elif #else

与if、else if、else同理

#include<stdio.h>
#include<windows.h>#define A 2int main()
{#if A==1printf("1\n");
#elif A==2printf("2\n");
#elif A==3printf("3\n");
#endifsystem("pause");return 0;
}

在这里插入图片描述

5.5上面所说的可以嵌套使用

#include<stdio.h>
#include<windows.h>#define A 2int main()
{#if A==2
#ifdef Aprintf("ok\n");
#endif
#endifreturn 0;
}

在这里插入图片描述

6.头文件包含

#include”“先搜索本地头文件,找不到再去找库头文件。
#include<>直接去找库头文件.


完。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MQL5学习之RSI指标编写

研究MT5时发现MQL5这个指标编写功能很强大&#xff0c;应该是碾压国内所有的指标系统&#xff0c;不过这个东西相对复杂很多&#xff0c;比通达信公式不知复杂几许&#xff0c;看起来和C语法接近&#xff0c;倒是比较适合自己。试着玩一下&#xff0c;发现还是有点难度的。索性…

Snagit 2024:让你的屏幕活动瞬间变得生动有力 mac/win版

Snagit 2024 屏幕录制与截图软件是一款功能强大的工具&#xff0c;专为现代用户设计&#xff0c;以满足他们在工作、学习和娱乐中对屏幕内容捕捉和分享的需求。这款软件结合了屏幕录制和截图功能&#xff0c;为用户提供了一种高效、便捷的方式来捕捉屏幕上的精彩瞬间。 Snagit…

相关知识1111

一、 店铺编号和相关负责人 1、天猫兄弟、锦格 京东凡越 福林哥 如萍姐 2、京东锦格 天猫凡越 林森 雷佳华 3、天猫从简 京东从简 孔哥 4、抖音锦格 拼多多凡越 鸿哥 不知道哪个店铺编号&#xff1a;0 二、天猫京东聊天界面快捷搜索商品 1、 天猫只能根据标题搜索 2、京东是…

洛谷P1509找啊找啊找GF

题解&#xff1a;这题我们需要考虑两个因素 &#xff0c;既要有钱&#xff0c;也需要有人品&#xff0c;但是呢&#xff0c;还想花最少得时间泡到最多的女生&#xff0c;那么这题我们就要用到以往的二维dp数组&#xff0c;但是真的是二维的吗&#xff1f;不&#xff0c;因为要考…

2024国际元宇宙博览会:阿里元境以元宇宙数字内容助力文旅数字化发展

2月26日&#xff0c;MES2024国际元宇宙博览会在深圳会展中心正式开幕&#xff0c;大会以“向3D出发&#xff0c;元宇宙来袭&#xff0c;电竞娱乐正当时”为主题&#xff0c;聚焦元宇宙产业链&#xff0c;以“汇聚企业创新&#xff0c;助力产业重构&#xff0c;推动行业发展”为…

C++ //练习 10.19 用stable_partition重写前一题的程序,与stable_sort类似,在划分后的序列中维持原有元素的顺序。

C Primer&#xff08;第5版&#xff09; 练习 10.19 练习 10.19 用stable_partition重写前一题的程序&#xff0c;与stable_sort类似&#xff0c;在划分后的序列中维持原有元素的顺序。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim …

IO多路转接

1.select 初识select 系统提供 select 函数来实现多路复用输入 / 输出模型 . select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的 ; 程序会停在 select 这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变 ; select函数模型 select的函…

springboot236基于springboot在线课程管理系统的设计与实现

基于SpringBoot在线课程管理系统的设计与实现 摘要 本文首先介绍了在线课程管理系统的现状及开发背景&#xff0c;然后论述了系统的设计目标、系统需求、总体设计方案以及系统的详细设计和实现&#xff0c;最后对在线课程管理系统进行了系统检测并提出了还需要改进的问题。本系…

【Vue3】解锁Vue3黑科技:探索接口、泛型和自定义类型的前端奇迹

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

volatile 关键字 (一)

volatile 关键字 &#xff08;一&#xff09; 文章目录 volatile 关键字 &#xff08;一&#xff09;如何保证变量的可见性&#xff1f;如何禁止指令重排序&#xff1f; 文章来自Java Guide 用于学习如有侵权&#xff0c;立即删除 如何保证变量的可见性&#xff1f; 在 Java 中…

k8s Pod基础(概念,容器功能及分类,镜像拉取和容器重启策略)

目录 pod概念 Kubernetes设计Pod概念和特殊组成结构的用意 Pod内部结构&#xff1a; 网络共享&#xff1a; 存储共享&#xff1a; pause容器主要功能 pod创建方式 pod使用方式 pod分类 pod的容器分类 基础容器&#xff08;infrastructure container&#xff09;&…

每日五道java面试题之mysql数据库篇(二)

目录&#xff1a; 第一题. 什么是索引&#xff1f;第二题. 索引有哪些优缺点&#xff1f;第三题. 创建索引的原则第四题. 创建索引时需要注意什么&#xff1f;第五题. 使用索引查询一定能提高查询的性能吗&#xff1f;为什么&#xff1f; 第一题. 什么是索引&#xff1f; 索引…