C语言:预处理(1)

news2024/11/16 12:03:40

程序的翻译环境和执行环境

在ANSI C的任何一种实现中,存在两个不同的环境:
第一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
第二种是执行环境,它用于实际执行代码。
在这里插入图片描述
翻译环境
在这里插入图片描述
组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库将其需要的函数也链接到程序中。
在这里插入图片描述
执行环境:
程序执行的过程:
1.程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2.程序的执行便开始。接着便调用main函数
3.开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值.
4.终止程序。正常终止main函数;也有可能是意外终止。

预处理详解

预定义符号
__FILE __ //进行编译的源文件
__LINE __ //文件当前的行号
__DATE __ //文件被编译的日期
__TIME __ //文件被编译的时间
__STDC __ //如果编译器遵循ANSI C,其值为1,否则未定义

这些预定义符号都是语言内置的。举个栗子:

printf("file:%s Tine:%d\n”,__FILE____LINE__);

#define
#define定义标识符
语法:
#define name stuff

举些栗子:
#define MAX 1000
#define reg register //为register这个关键字创建一个简短的名字
#define do_forever for( ; 😉 //用更形象的符号替换一种实现
#define CASE break;case //在写case语句的时候自动把break写上
在这里插入图片描述

#define定义宏
#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)
下面是宏的申明方式:
#define name(parament-list) stuff 其中的parament-list是一个由逗号隔开的符号表,它们可能出现在stuff中。

注意:参数列表的左括号必须与name紧邻。如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

例如:

#define square(x) x*x

这个宏接收一个参数x,如果在上述声明后,你把

square(5)

写进程序中,预处理器就会用下面这个表达式替换上面的表达式

5*5

警告,这个宏存在一个问题,观察下面代码段

#define square(x) x*x

int main()
{
   int a=square(5+1);
   printf("%d\n",a);
   return 0;
}

此时传过去后,变成了5+1*5+1,所以答案是11,并不是我们想要的6*6

所以我们可以将该宏定义改进为

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

提示:
所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号。避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。

#define替换规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
1.在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换
2.替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值替换。
3.最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程

注意:
1.宏参数和#define定义中可以出现其他#define定义的变量。但是对于宏,不能出现递归。
2.当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

#的作用
#可以把一个宏参数变成对应的字符串

那么,如何将参数插入到字符串中呢?

#define PRINT(x) printf("the value of "#x" is %d\n",x)

int main()
{
    int c=10;
    PRINT(c);
}

#x == “x”
这里中间的#x是#将x锁定为x,不让它变为传过来的值
此时,变为printf(“the value of” “x” “is %d\n”,x)

##的作用

##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符

例如:

#define CAT(x,y) x##y

int main()
{
   int class20=2022;
   printf("%d\n",CAT(class,20));
}

这里的##就是将x和y连接在一起

带副作用的宏参数:
当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

x+1//不带副作用
x++//带有副作用

MAX宏可以证明具有副作用的参数所引起的问题
例如:

#include <stdio.h>
#define MAX(x,y) ((x)>(y)?(x):(y))
int main()
{
    int a=10;
    int b=11;
    int max=MAX(a++,b++);
    printf("%d\n",max);//12
    printf("%d\n",a);//11
    printf("%d\n",b);//13
}

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

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

相关文章

MySQL 数据库练习题记录01

文章目录前言一、数据库练习题一1.1 表结构1.2 查询所有学生的信息(学号&#xff0c;姓名&#xff0c;性别&#xff0c;班级名称)1.3 查询所有人(包括没有成绩的学生)的课程分数(学号&#xff0c;姓名&#xff0c;性别&#xff0c;班级名称&#xff0c;语文分数&#xff0c;数学…

改进YOLOv5 | 引入密集连接卷积网络DenseNet思想 | 搭建密集连接模块

YOLOv5引入密集连接卷积网络DenseNet思想 CVPR 2017最佳论文 D e n s e N e t DenseNet DenseNet 论文地址:h

SpringBoot快速入门篇

&#x1f49f;&#x1f49f;前言 ​ 友友们大家好&#xff0c;我是你们的小王同学&#x1f617;&#x1f617; 今天给大家打来的是 SpringBoot快速入门篇 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞&#x1f44d; 收藏⭐ 评论&#x1f4c4; 小王的主页…

手写 mini 版 Webpack

目录 1. mini 版 Webpack 打包流程 2. 创建 minipack.js 2.1 需要用到的插件库 2.1.1 babylon —— 解析 JavaScript 语法&#xff0c;生产 AST 语法树 2.1.2 babel-traverse —— 对 AST 进行遍历、转换的工具 2.1.3 transformFromAst —— 将 ES6、ES7 等高级的语法&am…

[Verilog]有限状态机设计举例

有限状态机设计举例 摘要&#xff1a;有限状态机&#xff08;FSM&#xff09;是许多数字系统中用来控制系统和数据流路径行为的时序电路。FSM的实例包括控制单元和时序。 本实验介绍了两种类型的FSM&#xff08;Mealy和Moore&#xff09;的概念&#xff0c;以及开发此类状态机的…

Codeforces Round #837 (Div. 2)

A. Hossam and Combinatorics 题目链接&#xff1a;Problem - A - Codeforces 样例输入&#xff1a; 2 5 6 2 3 8 1 6 7 2 8 3 2 10样例输出&#xff1a; 2 4题意&#xff1a;给定一个有n个元素的数组&#xff0c;然后让我们求出有多少对(i,j)满足|a[i]-a[j]|max|a[p]-q[q]…

Hudi学习01 -- Hudi简介及编译安装

文章目录Hudi简介Hudi概述Hudi特性Hudi使用场景Hudi编译安装安装Maven编译hudi修改pom文件修改源码兼容hadoop3解决spark模块依赖的问题hudi编译命令Hudi简介 Hudi概述 Apache Hudi (Hadoop Upserts Delete and Incremental) 是下一代流数据湖平台。Apache Hudi 将核心仓库和…

并发编程中用到的几种常见锁

没有加锁而造成的数据竞争 任务&#xff1a;使用10个线程&#xff0c;同时对一个count加100000&#xff1b;最后我们期望的结果是100000&#xff1b; 实验代码&#xff1a; #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <ti…

git项目 拉项目 提交 上传 保姆级教程

git 项目拉取提交 下载git https://git-scm.com/ 拉取代码 打开需要存代码的位置 右键 git bash打开git客户端 输入命令 git clone [复制的地址]上传代码 修改代码 方法一&#xff1a;命令行 打开对应的文件夹&#xff0c;右键打开git bash 拉取最新代码&#xff08;选…

React学习07-React扩展知识

setState setState更新状态的2种写法: setState(stateChange, [callback])------对象式的setState stateChange为状态改变对象(该对象可以体现出状态的更改)callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用 setState(updater, [callback])-…

代码随想录算法训练营第九天(字符串)| 28. 实现 strStr(),459.重复的子字符串

代码随想录算法训练营第九天&#xff08;字符串&#xff09;| 28. 实现 strStr()&#xff0c;459.重复的子字符串 28. 实现 strStr() 因为KMP算法很难&#xff0c;大家别奢求 一次就把kmp全理解了&#xff0c;大家刚学KMP一定会有各种各样的疑问&#xff0c;先留着&#xff0…

Qt编写雷达模拟仿真工具2-自定义QGraphicsItem按钮

一、前言 雷达模拟仿真工具&#xff0c;整体结构采用的QGraphicsView框架&#xff0c;场景需要设计一个可点击的自定义按钮出来&#xff0c;在QGraphicsView中一切基础元素点都是基于QGraphicsItem&#xff0c;在QGraphicsItem类中我们可以看到它不继承自QObject&#xff0c;那…

25万美金奖励章鱼加速器2022冬季获胜团队!

全长 1427 字&#xff0c;预计阅读 6 分钟 作者&#xff1a;MiX 2022年12月21日&#xff0c;章鱼加速器2022年冬季 Web3 创业营圆满落幕&#xff0c;61个入营项目中有5个脱颖而出&#xff0c;获得「章鱼未来之星」称号&#xff0c;排名不分先后&#xff0c;他们分别是&#xf…

第五章. 可视化数据分析图表—Seaborn图表(折线图,直方图,条形图,散点图)

第五章. 可视化数据分析图 5.7 Seaborn图表 Seaborn是一个基于Matplotlib的高级可视化效果库&#xff0c;偏向于统计图表&#xff0c;主要针对的是数据挖掘和机器学习中的变量特征选取&#xff0c;相比Matplotlib&#xff0c;他的语法相对简单&#xff0c;但是具有一定的局限性…

Windows下安装oracle19c

oracle 19c 不支持 Windows 7 和 Windows 8 以及 Windows Server 2008&#xff08;GetOverlappedResultEx function 函数不支持 win7&#xff09;&#xff0c;支持 Windows 8.1 以上及 Windows Server 2012 1.下载地址&#xff1a; https://www.oracle.com/database/technolo…

Gnoppix Linux 22.12 发布

导读基于 Kali Linux 的 Linux 滚动发行版 Gnoppix 22.12 带来了 GNOME 43、Linux 内核 6.0 和新的升级。作为传统的现场 CD 发行版 Knoppix 项目的继承者&#xff0c;Gnoppix Linux 是专门为渗透测试和反向工程而设计的。它为网页应用安全和数字权利保护进行了优化。除了对安全…

DNA甲基化重编程为红梨中光诱导的花青素生物合成提供了见解

期刊&#xff1a;Plant Science 影响因子&#xff1a;5.363 发表时间&#xff1a;2022 样本类型&#xff1a;果皮 客户单位&#xff1a;南京农业大学 凌恩生物客户南京农业大学吴俊团队发表在《Plant Science》上的文章“DNA methylatio…

【Ctfer训练计划】——(七)

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门 创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座…

【数据结构】LinkedList与链表

作者&#xff1a;✿✿ xxxflower. ✿✿ 博客主页&#xff1a;xxxflower的博客 专栏&#xff1a;【数据结构】篇 语录&#xff1a;⭐每一个不曾起舞的日子&#xff0c;都是对生命的辜负。⭐ 文章目录✿1.ArrayList的缺陷✿2.链表2.1链表的概念及结构2.2链表的模拟实现MySingleLi…

aws eks 集群container runtime升级容器管理工具的切换

参考资料 https://cloud-atlas.readthedocs.io/zh_CN/latest/kubernetes/debug/crictl.htmlhttps://zhuanlan.zhihu.com/p/562014518 container runtime Low-Level和High-Level容器运行时。runc、lxc、lmctfy、Docker&#xff08;容器&#xff09;、rkt、cri-o。每一个都是为…