C语言-预处理

一、C语言编译过程 

预处理、编译、汇编、链接

1:预编译 

将.c 中的头文件展开、宏展开

生成的文件是.i文件

2:编译      

将预处理之后的.i 文件生成 .s 汇编文件

3、汇编

将.s汇编文件生成.o 目标文件

4、链接

将.o 文件链接成目标文件

二、include 

#include<>//用尖括号包含头文件,在系统指定的路径下找头文件

#include "" //用双引号包含头文件,先在当前目录下找头文件,找不到,再到系统指定的路径下找。

注意:include 经常用来包含头文件,可以包含 .c 文件,但是大家不要包含.c因为include包含的文件会在预编译被展开,如果一个.c 被包含多次,展开多次,会导致函数重复定义。

所以不要包含.c 文件。

注意:预处理只是对include 等预处理操作进行处理并不会进行语法检查

这个阶段有语法错误也不会报错,第二个阶段即编译阶段才进行语法检查。

三、define 

定义宏用define 去定义

宏是在预编译的时候进行替换。

1、不带参宏

#define PI 3.14

在预编译的时候如果代码中出现了PI 就用 3.14去替换。

宏的好处:只要修改宏定义,其他地方在预编译的时候就会重新替换。

注意:宏定义后边不要加分号

宏定义的作用范围,从定义的地方到本文件末尾。

如果想在中间终止宏的定义范围

#undef PI //终止PI的作用

2、带参宏   

#define S(a,b) a*b

注意带参宏的形参 a和b没有类型名,

S(2,4) 将来在预处理的时候替换成 实参替代字符串的形参,其他字符保留,2 * 4

3、带参宏和带参函数的区别

带参宏被调用多少次就会展开多少次,执行代码的时候没有函数调用的过程,不需要压栈弹栈。所以带参宏,是浪费了空间,因为被展开多次,节省时间。

带参函数,代码只有一份,存在代码段,调用的时候去代码段取指令,调用的时候要压栈弹栈。有个调用的过程。所以说,带参函数是浪费了时间,节省了空间。

带参函数的形参是有类型的,带参宏的形参没有类型名。

如果功能实现的代码相对简单,并且不需要开辟太多的空间,可以选择使用带参宏,但是大多数情况都会使用函数

四、选择性编译

1、

#ifdef AAA

代码段一

#else

代码段二

#endif

如果在当前.c ifdef 上边定义过AAA ,就编译代码段一,否则编译代码段二 注意和if else语句的区别,if else 语句都会被编译,通过条件选择性执行代码而选择性编译,只有一块代码被编译;

2、

#ifndef AAA

代码段一

#else

代码段二

#endif

和第一种互补。

这种方法,经常用在防止头文件重复包含。

常用于多文件编程中.h的第一行就是#ifndef,最后一行就是#endif

3、#if 表达式

程序段一

#else

程序段二

#endif

如果表达式为真,编译第一段代码,否则编译第二段代码

这种形式一般用于注释多行代码

#if 0

...

#endif

选择性编译都是在预编译阶段干的事情。

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

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

相关文章

es优化实践(es升级带来的大坑)->问题与痛点->优化过程->原理分析->最佳实践

这里分享一个ES2.X升级到ES5.X带来的天坑问题 结论先行 先上结论(最佳实践) es5以后版本 对于某个字段 1.字段用于terms查询,则字段定义为keyword类型, 如果定义为数值类型(number,long,short等)会有严重的性能问题 ,查询耗时会很长2.字段用于range查询,则字段定义为数值类型…

网络协议安全:SYN Flood原理和防御措施,使用hping3实现SYN Flood

「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等12个知识域的一百多个知识点,持续更新。 这一章节我们需要知道S…

【Docker】docker部署lnmp和搭建wordpress网站

环境准备 docker&#xff1a;192.168.67.30 虚拟机&#xff1a;4核4G systemctl stop firewalld systemctl disable firewalld setenforce 0 安装docker #安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像 yum-config-manager --add…

google chromeDriver 地址

#chrome driver 下载地址 https://getwebdriver.com/chromedriver #chrome brower下载地址 https://googlechromelabs.github.io/chrome-for-testing/ centos 安装的dockerFile的部分命令&#xff1a; #安装browser wget https://dl.google.com/linux/chrome/rpm/stable/x86_…

【Web】D^3CTF之浅聊d3pythonhttp——TE-CL请求走私

目录 step0 题目信息 step1 jwt空密钥伪造 step1.5 有关TE&CL的lab step2 TE-CL请求走私 payload1 payload2 step0 题目信息 注意到题目源码前端是flask写的&#xff0c;后端是web.py写的 frontend from flask import Flask, request, redirect, render_templat…

Mac no library called “libcairo-2“ was found

最近在运行ernibe-bot researcher的时候出现了下面的问题&#xff1a; OSError: no library called "cairo-2" was found no library called "cairo" was found no library called "libcairo-2" was found cannot load library libcairo.so.2: …

Java中的访问修饰符有哪些?各有什么作用?

Java中有四种访问修饰符&#xff08;Access Modifiers&#xff09;&#xff0c;它们定义了类、方法、变量和构造函数的访问控制级别。这些修饰符从最宽松的访问级别到最严格的访问级别依次为&#xff1a;public, protected, default&#xff08;没有修饰符时使用的默认访问级别…

C++ 类对象初始化

一、默认初始化 当创建一个类的实例时&#xff0c;如果没有定义构造函数&#xff0c;系统会自动生成一个无参构造函数&#xff0c;并自动初始化成员变量。内置类型的变量&#xff08;如int、double、指针等&#xff09;会被初始化为一个未定义的值&#xff0c;而自定义类型的变…

基于Python的人脸识别系统设计与实现(论文+源码)_kaic

基于Python的人脸识别系统设计与实现 摘 要 随着人工智能的发展,人脸识别系统在我们的生活中越来越被广泛应用。人脸识别系统是指能够从数字图像或视频源中识别人的技术。人脸识别系统可以通过多种方法工作&#xff0c;但是&#xff0c;它们通常是通过将给定图像中的面部特征与…

论文笔记总结

写论文不能只讲概念&#xff0c;一定要结合项目理论实际。》例如某xxx具体的项目例子&#xff0c;不能描述某一个软件的功能。 1.历年真题 2.十段式划分&#xff08;回应子题目&#xff0c;三个子题目&#xff09; 3.论文模板&#xff0c;万能模板 4.具体主题相关 第一个主…

202012青少年软件编程(Python)等级考试试卷(一级)

第 1 题 【单选题】 运行下方代码段&#xff0c;输出是6&#xff0c;则输入的可能是&#xff08; &#xff09;。 a eval(input())print(a)A :8%2 B :8/2 C :3*2 D :3**2 正确答案:C 试题解析: 第 2 题 【单选题】 关于Python变量&#xff0c;下列叙述正确的是&#x…

Rust基本特性补充

虚幻数据PhantomData 实际上&#xff0c;结构体本身也是可以有生命周期的&#xff0c;例如: struct Tmp<a>{index: &a u32 } 上述声明中&#xff0c;虽然index为一个引用&#xff0c;但是这样声明后&#xff0c;相当于告诉编译器&#xff0c;Tmp对象的生命周期会和…

Spring Cloud——LoadBalancer

Spring Cloud——LoadBalancer 一、负载均衡&#xff08;LoadBalance&#xff09;1.LoadBalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 二、LoadBalancer1.Spring RestTemplate as a LoadBalancer Client2.编码使用DiscoveryClient动态获取所有上线的服务列表3.从默认…

《自动机理论、语言和计算导论》阅读笔记:p215-p351

《自动机理论、语言和计算导论》学习第 11 天&#xff0c;p215-p351总结&#xff0c;总计 37 页。 一、技术总结 1.constrained problem 2.Fermat’s lats theorem Fermat’s Last Theorem states that no three positive integers a, b and c satisfy the equation a^n b…

SNMP自动遍历所有节点并GET

echo on setlocal EnableDelayedExpansion SnmpWalk.exe -r:10.253.2.38 -v:2 -t:5 -c:“public_default” > 1.txt REM snmp mib节点遍历前记录设备cpu和内存利用率 SnmpGet.exe -q -r:10.253.2.38 -v:2 -t:5 -c:“public_default” -o:1.3.6.1.4.1.31648.3.15.10.0 >&…

unity中 UnityWebRequest.Post和 UnityWebRequest uwr = new UnityWebRequest两种方法有什么区别

在Unity中&#xff0c;UnityWebRequest.Post 和 UnityWebRequest uwr new UnityWebRequest(...) 是两种不同的方式来创建和发送HTTP POST请求&#xff0c;但它们之间有一些关键的区别和用法上的差异。 1. UnityWebRequest.Post (静态方法) UnityWebRequest.Post 是一个静态方…

PostgreSQL数据类型总结

PostgreSQL数据库相比其他数据库&#xff0c;支持更多的数据类型&#xff0c;包括常用的数值类型、字符串类型、日期/时间类型外&#xff0c;还有几何类型、网络地址类型、xml类型和json类型&#xff0c;且还可以使用CREATE TYPE自行添加数据类型&#xff0c;本文主要介绍Postg…

过渡与动画

单元素/组件过渡 Vue在插入、更新或者移除 DOM 时&#xff0c;提供多种不同方式的过渡效果&#xff08;一个淡入淡出的效果&#xff09; 在条件渲染&#xff08;使用v-if&#xff09;、条件展示&#xff08;使用v-show&#xff09;、动态组件、组件根节点等情形中&#xff0c;可…

python算法题

需求 代码 class Solution:def searchInsert(self, nums: List[int], target: int) -> int:if max(nums) >target:for i in range(len(nums)-1):if nums[i1] > target and nums[i] <target:return i1if max(nums) <target:return len(nums)if min(nums) > …

操作系统(2)——进程线程

目录 小程一言专栏链接: [link](http://t.csdnimg.cn/8MJA9)基础概念线程详解进程详解进程间通信调度常用调度算法 重要问题哲学家进餐问题问题的描述策略 读者-写者问题问题的描述两种情况策略 总结进程线程一句话 小程一言 本操作系统专栏&#xff0c;是小程在学操作系统的过…