程序环境和预处理

ops/2024/12/29 6:11:48/

程序环境和预处理

  • 1.程序环境
    • 1.1如何从test.c到test.exe
    • 1.2.翻译环境
      • 1.2.1翻译过程
      • 1.2.2详细过程
    • 1.3.运行环境
  • 2.预处理
    • 2.1 预定义符号
    • 2.2 define
      • 2.2.1 define定义标识符
      • 2.2.2 define定义宏
      • 2.2.3 带副作用的宏参数
      • 2.2.4 宏和函数的对比
    • 2.3 #undef
    • 2.4 命令行定义
    • 2.5 条件编译
    • 2.6 文件包含
      • 2.6.1 头文件被包含的方式:
      • 2.6.2 嵌套文件包含

1.程序环境

当我们在使用编译器的时候,编译器的背后是如何运行的工作的?

1.1如何从test.c到test.exe

在这里插入图片描述

在ANSI C的任何一种实现中,存在两个不同的环境。
第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
第2种是执行环境,它用于实际执行代码

1.2.翻译环境

1.2.1翻译过程

在这里插入图片描述

1>组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
2>每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
3>链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中

1.2.2详细过程

1.翻译环境
在这里插入图片描述

1.3.运行环境

程序执行的过程:
1>程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2>程序的执行便开始。接着便调用main函数。
3>开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
4> 终止程序。正常终止main函数;也有可能是意外终止

2.预处理

2.1 预定义符号

FILE //进行编译的源文件
LINE //文件当前的行号
DATE //文件被编译的日期
TIME //文件被编译的时间
STDC //如果编译器遵循ANSI C,其值为1,否则未定义

在这里插入图片描述

2.2 define

2.2.1 define定义标识符

defined是预处理命令,他的功能只是替换,不用做任何的运算
不要在define语句后面加 “ ;”,否则有可能会出现语法错误

在这里插入图片描述

#define MAX 1000
#define reg register
//为 register这个关键字,创建一个简短的名字
#define do_forever for( ; ; )
//用更形象的符号来替换一种实现
#define CASE break;case 
//在写case语句的时候自动把 break写上。
// 如果定义的 stuff过长,可以分成几行写,
//除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \date:%s\ttime:%s\n" ,\__FILE__,__LINE__ ,\__DATE__,__TIME__ )

在这里插入图片描述

2.2.2 define定义宏

1.相关定义
在这里插入图片描述
在这里插入图片描述
2.下面观察下面一段代码
在这里插入图片描述
这里发现与我们的预想结果不一样,本来以为a+1=6,然后56等于30。但是这里却等于10,这是因为define是预处理命令,只把a+1替换到和b替换到了xy的位置,结果为6+1*5,由于这里存在运算符优先级的问题,所以后面乘法先进行了计算。

解决办法:都加上括号,保证其优先级

在这里插入图片描述
3.替换规则
在这里插入图片描述
在这里插入图片描述
4.#和##
1>#的作用
在这里插入图片描述
观察这段代码,发现有许多重复的地方,希望可以通过一个函数那样的方式进行替换,直接带入参数即可,但是函数显然不能满足。这就可以试一试宏定义。
在这里插入图片描述
这里需要解释两点,第一点就是字符串具有自动连接功能

第二点就是#的功能:将宏参数a变为对应的字符串
在这里插入图片描述

在这里插入图片描述
2>##的作用
在这里插入图片描述
在这里插入图片描述

2.2.3 带副作用的宏参数

在这里插入图片描述

在这里插入图片描述

2.2.4 宏和函数的对比

在这里插入图片描述

宏的缺点:当然和函数相比宏也有劣势的地方:

  1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序
    的长度。
  2. 宏是没法调试的
  3. 宏由于类型无关,也就不够严谨。
  4. 宏可能会带来运算符优先级的问题,导致程容易出现错。

在这里插入图片描述
在这里插入图片描述

2.3 #undef

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 命令行定义

许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
例如:当我们根据同一个源文件要编译出不同的一个程序的不同版本的时候,这个特性就有点用处。(假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,此次在命令行编译数组size大小为10;若机器内存够用,需要很大的数组时候,就在命令行编译数组size大小为100等等更大;可根据需求灵活调整)

2.5 条件编译

在编译程序时候,我们可以通过条件编译语法,选择编译这条语句或者放弃编译这条语句
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常见的条件编译指令


1.
#if 常量表达式//...
#endif
//常量表达式由预处理器求值。
如:
#define __DEBUG__ 1
#if __DEBUG__//..
#endif
2.多个分支的条件编译
#if 常量表达式//...
#elif 常量表达式//...
#else//...
#endif
3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
4.嵌套指令
#if defined(OS_UNIX)#ifdef OPTION1unix_version_option1();#endif#ifdef OPTION2unix_version_option2();#endif
#elif defined(OS_MSDOS)#ifdef OPTION2msdos_version_option2();#endif
#endif

2.6 文件包含

2.6.1 头文件被包含的方式:

在这里插入图片描述
在这里插入图片描述

2.6.2 嵌套文件包含

在这里插入图片描述
comm.h和comm.c是公共模块。
test1.h和test1.c使用了公共模块。
test2.h和test2.c使用了公共模块。
test.h和test.c使用了test1模块和test2模块。
这样最终程序中就会出现两份comm.h的内容。这样就
出现了这样一种情况,一个文件包含了多个相同的头文件,这就会导致在预处理的时候进行多次展开该头文件,造成代码冗余,编译更加复杂,那么该如何解决这个问题呢?如何确保该文件只被编译一次呢?--------条件编译.
在这里插入图片描述


http://www.ppmy.cn/ops/145848.html

相关文章

安全筑堤,效率破浪 | 统一运维管理平台下的免密登录应用解析

在信息技术迅猛发展的今天,企业运维管理领域正面临着前所未有的复杂挑战。统一运维管理平台作为集中管理和监控IT基础设施的核心工具,其安全性和效率至关重要。免密登录作为一种新兴的身份验证技术,正逐渐成为提升运维管理效率和安全性的重要…

不同操作系统下安装Node.js及配置环境的详细步骤

以下是在不同操作系统下安装Node.js及配置环境的详细步骤: 一、Windows系统 下载Node.js安装包 访问Node.js官方网站(https://nodejs.org/)。在网站上可以看到有两个版本可供下载:LTS(长期支持版)和Curren…

git自动压缩提交的脚本

可以将当前未提交的代码自动执行 git addgit commitgit squash Git 命令安装指南 1. 创建脚本目录 如果目录不存在,创建它: mkdir -p ~/.local/bin2. 创建脚本文件 vim ~/.local/bin/git-squash将完整的脚本代码复制到此文件中。 3. 设置脚本权限…

无人机图传模块原理及作用

在当今科技飞速发展的时代,无人机已经成为了各个领域的热门工具,从航拍爱好者的创意拍摄到专业的农业植保、测绘勘察等工作,无人机都发挥着重要作用。而在无人机众多的组成部分中,图传模块无疑是极为关键的一个,它让无…

GitLab 将停止为中国区用户提供服务,60天迁移期如何应对? | LeetTalk Daily

“LeetTalk Daily”,每日科技前沿,由LeetTools AI精心筛选,为您带来最新鲜、最具洞察力的科技新闻。 GitLab作为一个广受欢迎的开源代码托管平台,近期宣布将停止服务中国大陆、澳门和香港地区的用户提供服务。根据官方通知&#x…

Ubuntu下PyTorch开发环境配置

文章目录 前言安装Anaconda配置Python环境安装Pytorch开发IDE最后 前言 你好,我是醉墨居士,今天在Ubuntu上配置一下PyTorch开发环境,同时记录一下我的经历,希望能够让你快速完成开发环境的配置,节约宝贵的时间 安装A…

虾皮开的很高,还有签字费。

大家好,我是二哥呀。 虾皮在去年之前,还是很多大厂人外逃的首选项,因为总部在新加坡,比较有外企范,但去年就突然急转直下,队伍收紧了不少。 作为东南亚电商市场的领头羊,市场覆盖了新加坡、马…

QT集成IntelRealSense双目摄像头2,集成OpenGL

上一篇文章写了如何把IntelRealSense摄像头的SDK集成到QT项目,并成功采集数据,在没有用OpenCV的情况下完成色彩数据,以及深度数据的显示。 具体地址:https://blog.csdn.net/qujia121qu/article/details/144734163 本次主要写如何…