程序环境与预处理详解

从平面到立体:一张图看懂MOSFET、FinFET到GAAFET的演变史(附结构对比图) 本文深入解析了半导体晶体管从平面MOSFET到三维FinFET,再到全环绕栅极GAAFET的技术演进历程。通过结构对比图和物理原理分析,揭示了每一次创新如何解决短沟道效应等关键挑战,推动芯片性能提升。特别关注GAAFET作为最新技术突破的架构特点和性能优势。 阅读详情

目录

一、程序环境

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

 2.编译&链接

2.1翻译环境

2.2 环境细化分析(环境可以自选,这里选用的是Linux)

 2.3运行环境

二、预处理

1.预处理分析

1.1预定义符号

 1.2#define定义标识符

1.3#define定义宏

1.4#define替换规则

 2.#和##使用

2.1#使用

3.宏相关

3.1宏与函数对比

3.2命名约定

3.3 #undef

 3.4命令行定义

 3.5条件编译

3.7文件查找 

4.预处理指令


一、程序环境

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

在ANSI  C的任何一种实现中,存在两个不同的环境

(1)一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令(二进制指令)

(2)另一种是执行环境,它用于实际执行代码

 2.编译&链接

2.1翻译环境

一个简单例子  :

源文件---------->(通过)编译器 ---------->目标文件(后缀  .obj)

目标文件+链接器 ---------->可执行程序(后缀   .exe)

 

 

2.2 环境细化分析(环境可以自选,这里选用的是Linux)

 2.3运行环境

程序执行过程中:

(1)程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成,在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存完成

(2)程序的执行便开始,接着使用调试main函数

(3)开始执行程序代码,这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址,程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值

(4)终止程序,正常终止main函数,也可能意外终止

二、预处理

1.预处理分析

1.1预定义符号

__FILE__            //进行编译的源文件
__LINE__           //文件当前的符号
__DATE__         //文件被编译的日期
__TIME__         //文件被编译的时间
__STDC__        //如果编译器遵循ANSI C标准,其值为1,否的话为未定义

 

#include<stdio.h>
int main()
{
    
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("file:%s line=%d date :%s time:%s i=%d \n", 
__FILE__,
 __LINE__,
 __DATE__,
 __TIME__, i);
    }
    return 0;
}

 

运行结果:

 写入文件(代码日记)

#include<stdio.h>
int main()
{
    FILE* pf;
    pf = fopen("example", "w");
    if (pf == NULL)
    {
        perror("fopen");
    }
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        fprintf(pf,"file:%s line=%d date :%s time:%s i=%d \n", 
__FILE__, 
__LINE__, 
__DATE__, 
__TIME__, i);
    }
    fclose(pf);
    pf = NULL;
    return 0;
}

运行结果:

 1.2#define定义标识符

语法:
   #define  name  stuff

使用例:

(1)#define MAX 100

(2)#define  reg register     //建立一个字节能记得住的名称

 (3)#define  do_forever for(;;)   //更换一种符号实现

(4)#define CASE break;case  //相当于省去了每次写break

(5)#define DEBUG+PRINT  printf("file:%s\tline:%d\tdate:%s\ttime:%s\n", __FILE__, __LINE__, __DATE__, __TIME__)

预处理前后对于宏的作用 

 

 

 宏在预处理时做了替换,系统直接进行

用宏时,尽量不要在宏定义的后面加上分号(;)

1.3#define定义宏

宏的申明方式:

#define name(parament_list)  stuff

其中的parament_list 是一个由逗号隔开的符号表,它们可能是出现在stuff中

注意:

name 旁边的括号必须是紧邻的

如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分

使用例:

#define SQUARE(x)  x*x

此时的宏参数是x 

但是当前的宏不是很稳定,容易发生变化,

得出的结果并不是我们想要的36,而是11,这就是宏当前执行的不稳定 所以这里改进就需要做好优先级的运算(加上括号)

 宏又是如何执行的呢?宏是直接带入考虑算数的优先级进行

1.4#define替换规则

(1)在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号,如果是,他们首先是替换

(2)替换文本随后被插入到程序中原来文本的位置,对于宏,参数名被他们的值所替换

(3)最后,再次对结果文本进行扫描,是否包含#define定义符号,如果还有就重复上述操作

注意:

 (1)宏参数和#define定义可以出现其他#define定义的符号,但是对于宏,不能出现递归

 (2)当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索

 2.#和##使用

2.1#使用

使用例:

#include<stdio.h>
#define PRINT(N)  printf("the value of "#N" is %d\n",N)
int main()
{
    int a = 10;
    PRINT(a);

    int b = 20;
    PRINT(b);
    return 0;
}

使用例解释:

printf("the value of "#N" is %d\n",N)  宏定义:

"the value of "前半段的字符串

" is %d\n"后半段字符串

#N代表的就是“N”,也是字符串,只是用#写

3.宏相关

3.1宏与函数对比

在较小型计算工作中不用函数解决问题

原因:
(1)用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多

此时宏比函数更胜一筹(规模与速度)

(2)相比之下更好的是宏不需要特定的类型

所以函数只能在类型合适的表达式上使用,反之这个宏怎么可以适用于整型、常整型等等

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

(1)。每次使用宏的时候,一份宏定义的代码将插入到程序中,除非宏比较短,否则可能大幅度增加程序的长度。

(2)宏是不能调试的

(3)宏由于类型无关,也就不够严谨

(4)宏可能会带来运算符优先级的问题,导致程序容易出现错误

所以宏有些地方也是不能实现的,但是函数可以

3.2命名约定

一般来讲函数的宏的使用语法很相似,所以语言本身没法帮我们区分二者

习惯性命名:

把宏名全部大写

函数名不要全部大写

3.3 #undef

命令解释:移除一个宏定义

#undef NAME

 

通过#undef使用移除前面宏定义的M在这里就不在起作用了

 3.4命令行定义

许多c的编译器提供一种能力,允许在命令行中定义符号,用于启动编译过程

例如:当我们根据同一个源文件要编译出一个程序不同版本的时候,这个特点有点用处

命令行定义:在编译的时候就将其指定值放入

 3.5条件编译

在编译一个程序的时候如果条件可以就进行编译,简单点说就像在我们使用if函数的时候,可以选择性放弃,但是与if不完全相同,大家谨慎理解

 注意:ifdef 使用的是定义__DEBUG__,条件可以编译,可以自己来改变条件,决定是否想要编译,如果将#define 屏蔽ifdef就不能执行了

(1)

#if  常量表达式

//...

#endif

//常量表达式由预处理器求值

如:

#define __DEBUG__ 1

#if __DEBUG__

//...

#endif

(2)多个分支的条件编译

#if 常量表达式

//...

#elif 常量表达式

//...

#else

//...

#endif

(3)判断是否被定义

#if  definedsymbol)

#ifdef  symbol

 

#if  !define(symbol)   //否定

#ifndef symbol   //否定

//结束时后面与前面一样加 #endif

(4)#if  defined(OS_UNIX)

              #ifdef OPTION1

                        unix1();

              #endif

              #ifdef OPTION2

                        unix2();

              #endif

#elif defined(OS_MSDOS)

//...

#else

//..

#endif

3.6文件包含

文件包含里面是有头文件#include,多次包含头文件,拷贝的次数过多

所以在这里文件包含在当前部分编译器会给#pragma once在写头文件时,仅包含一次头文件

#pragma once

 

int ADD(int x,int y)

另一种方法:也是所有c编译器都可以使用的

#ifndef  __TEST_H__

#define __TEST_H__

int ADD(int x,int y);

#endif

3.7文件查找 

<>和""的区别是查找的策略不同

#include<stdio.h>

<>查找策略:直接去库函数目录小找

#include"test.h"

""查找策略:优先在当前文件下找,找不到后在库函数目录下查找 

4.预处理指令

#error

#pragma

#line

有意向的可以了解

装上大模型翅膀,程序员入职新公司如何快速上手代码(老员工如何选择大模型编程如虎添翼) 入职新公司,尤其是行业知识不懂的,面对前人堆积的屎山代码,各种文档又缺少的,有些技术自己又不懂的,如何快速上手代码,特别是借助AI大模型事半功倍的上手项目代码。进入新公司,我做的第一件事就是收集情报。我主动向同事们索要项目的相关资料,包括项目介绍文档、功能说明文档和业务流程图等。通过仔细阅读这些资料,可以对项目的背景和架构有了初步的了解。同时要逮住机会就向同事们请教项目的迭代历程和技术选型背后的考量。有时他们三言二语,可以为自己节省很多探索时间。在了解了项目的基本情况后,可以开始深入探究项目的业务流程。 阅读详情

相关推荐

Windows Server 2019整机备份与异机还原实战:从虚拟机到物理机的完整迁移指南

本文详细介绍了Windows Server 2019整机备份与异机还原的实战操作,涵盖从虚拟机到物理机的完整迁移流程。通过环境准备、备份策略设计、具体操作步骤及迁移后优化等内容,帮助用户实现系统环境的无缝迁移,特别适用于服务器硬件升级、数据中心迁移等场景。

weixin_30555125的博客 133

linux 线程属性参数分析(优先级,调度策略,栈大小以及其他)

1首先我们通过几个函数来了解pthread_attribute吧 /******** 属性结构体: struct attribute { int detachstate; int schepolicy; struct sched_param schedparam; //调度策略优先级 int inheritsched; int scope; size_t guardsize; //线程栈末尾的警戒区缓冲大小 void* stackaddr; //线程站地址 size_t stacksiz

陌上花开缓缓归以的博客 772

如何安装PyFluent

PyFluent 是PyAnsys生态系统的一部分, 允许您在所选的 Python 环境中结合使用 Fluent 与其他 PyAnsys 库和外部 Python 库一起使用。PyFluent 实现了客户端-服务器体系结构。它使用谷歌遥控器 过程调用或 gRPC 接口,用于启动或连接正在运行的 Fluent 进程作为服务器。但是,您只需要与 Python 交互接口。可以使用 PyFluent 以编程方式创建、交互和控制 Fluent 会话,用于创建您自己的自定义工作区。

B_etter_Man的博客 2926

巧用可变参数宏、编译器内置宏和printf输出调试信息

前言:我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除,而一旦需要再次调试的时候,这些语句又不得不一条条的加上,这给我们带来了很大的不便,浪费了我们很多的时间,也造成了调试的效率低下。所以,很多人会选择使用宏定义的方式来输出调试语句。比如,定义一个宏开关:#define _

大道至简,持之以恒 1万+

分享一下使用Xilinx FPGA驱动MIPI DSI LCD屏的心路历程

分享一下调试用Xilinx FPGA驱动MIPI DSI LCD屏的心路历程,看到的朋友们,可以避免继续踩坑。

haoxingheng的专栏 5015

解密m3u8视频合并:从猫抓插件到本地文件修改全流程

本文详细解析了m3u8视频合并的全流程,特别针对加密视频片段提供了解决方案。从使用猫抓插件捕获m3u8文件地址,到利用N_m3u8DL-CLI工具自动下载、解密并合并ts片段,手把手教你处理AES-128加密等常见问题,最终生成完整的本地MP4文件,适合需要备份或处理流媒体资源的用户。

weixin_29290947的博客 1363

c++新特性实验(1)预处理

1.参考资料 1.1 C++ C++17 标准文档(正式) : https://www.iso.org/standard/68564.html C++ 标准文档(草案) : http://www.open-std.org/JTC1/SC22/WG21/docs/standards#14882 C++最新资讯,资料 : https://ww...

banyinlve3147的博客 449

中山大学_数据科学与计算机_预推免

前言 2019 年 9 月中旬是中山大学预推免时间,本人没能进到夏令营,但是最后在预推免上岸也算不幸中的万幸。 记忆不一定准确,但希望能帮到他人。 想看 流程 的可以直接看总结,正文部分有本人心路历程。 预推免 中山大学的预推免大致可以分为 报道,机试,面试 三大部分,而且尤其是面试,所有人加起来总时长 3 天,幸运的是,本人被安排在第一天的下午第一场,上午就是机试,报道,机试,面试,无缝衔接。 ...

一把健 5208

C语言程序环境和预处理详解

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

hy____123的博客 2276

腾讯文档API逆向分析:不用Selenium也能批量导出的黑科技

本文揭秘了如何通过Python逆向分析腾讯文档的隐藏API,实现无需Selenium即可批量导出在线表格的高效方法。详细解析了API调用流程、Cookie维护及异常处理技巧,相比传统方案性能提升显著,适用于大量文档导出的自动化场景。

h9j8k7l6m5n的博客 1202

腾讯云智后台开发实习面试全纪录(已offer)

腾讯云智后台开发实习面经

wenwenaier的博客 5906

程序环境和预处理详解

_DATE__//文件被编译的日期__TIME__文件被编译的时间__FILE__ //进行编译的源文件__LINE__//文件当前的行号__STDC__编译器符合ANSI C标准的,被定义为1我们可以打印出来看一下int main()return 0;for (i = 0;i < SIZE;for (i = 0;i < SIZE;

weixin_70764294的博客 1724

复旦微FMSH_Procise安装全流程详解:从环境配置到实战避坑指南

通过本文的全流程解析+实战技巧,开发者可快速掌握Procise在复旦微芯片开发中的核心应用。未来随着AKConv轻量级架构(参考往期文章)等创新技术的融入,国产芯片开发生态将更加完善。立即关注本专栏,获取最新多镜像切换指南与Linux SDK实战教程!扩展阅读复旦微在线升级BOOT.BIN全解析H7-TOOL实现复旦微脱机烧录(注:本文实验环境为Windows 10 x64 + FMQL45T-CORE开发板,部分操作可能因版本更新调整)立即行动下载本文配套配置文件:[GitHub链接]加入技术交流群。

QQ_778132974的博客 3240

【C/C++】详解程序环境和预处理(什么是程序环境?为什么要有程序环境?如何理解程序环境?)

本文主要是认识与学习C/C++中的程序环境和预处理。

weixin_45031801的博客 2924

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

程序环境和预处理(详解)

1. 程序的翻译环境和执行环境 在ANSI C的任何一种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。(二进制的指令) 第2种是执行环境,它用于实际执行代码。 2. 详解编译+链接 2.1 翻译环境 组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。【.obj】 每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。 链接器同时也会引入标准C函数库中任何被该程序所用到..

qq_60021974的博客 457

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

详解C语言预处理&程序环境

预定义符号这些预定义符号都是语言内置的。比如:__FILE__//进行编译的源文件__LINE__//文件当前的行号__DATE__//文件被编译的日期__TIME__//文件被编译的时间__STDC__//如果编译器遵循ANSI C,其值为1,否则未定义如:printf__FILE____LINE__// 第一个就会打印源文件的路径;

菜菜成长为后端开发大佬 920

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【C C++】详解程序环境和预处理(什么是程序环境?为什么要有程序环境?如何理解程序环境

⭐ 程序环境:是指将源文件(code.c / code.cpp)转换为程序的过程三、 为什么要有程序环境?⭐如果没有程序环境编译器(gcc / g++)就无法识别我们所写的C/C++代码也无法将源代码转换成可执行程序。四、如何理解程序环境?

2401_89308094的博客 1074

【C语言】程序环境预处理 -- 详解

程序环境预处理

Elena's Blog 980

C语言的程序环境和预处理详解

本篇文章对各种预处理指令进行了详解,有#define、条件编译等等。我们平常写的代码都是通过编译器来运行的。我们有没有想过编译器是怎么将代码转化为各种指令最后输出结果呢?这篇文章会详细解释编译器的运行的整个过程的细节,希望会对你有所帮助。

weixin_67596609的博客 1736

详解C程序环境和预处理

本文章将详解C语言的翻译环境和执行环境,并且介绍C程序的运行过程,在此基础上,介绍#define/#if等预处理指令和宏的讲解和应用等等。

ZZZCCC的博客 410

程序环境和预处理(详解版)

程序环境和预处理(详解版)

月亮夹馍干的博客 1167
上一篇: 快速了解文件操作
下一篇: 模拟atoi函数
学习自省
博客等级 码龄5年 284粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值