C语言程序运行需要的两大环境《C语言进阶》

目录

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

翻译环境分为两部分,编译+链接

第一步:预编译(预处理)

第二步,编译

第三步:汇编

关于运行环境分为四点:

关于链接库


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

ANSI C(标准C) 的任何一种实现中,存在两个不同的环境。
*第1种是翻译环境。 在这个环境中源代码被转换为可执行的机器指令。
在编译器中(以VS2019为例),我们写的C语言代码都是文本的信息(各种字符串,数据,结构体等),站在人类的角度,我们能够理解,但是计算机不行,代码需要翻译成计算机呢能够识别的指令:二进制指令

*第2种是执行环境。它用于实际执行代码。
代码经过翻译环境后生成的二进制指令代码,由执行环境来执行生成。

代码编译时生成可执行程序时的步骤:

1. 组成一个程序的每个源文件通过编译过程分别转换成目标代码( object code )。
2. 每个目标文件由链接器( linker )捆绑在一起,形成一个单一而完整的可执行程序。
3. 链接器同时也会引入标准 C 函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。
简述来说:
每一个源文件(.c),都单独经过编译器进行编译,生成目标文件(.obj),目标文件和链接库再通过链接器的处理(这个过程就叫链接),就生成了可执行程序(.exe)。
如下图

翻译环境分为两部分,编译+链接

  

编译本身也分为几个阶段:预处理 , 编译 ,汇编。

 接下来我们用一个简单的代码,源文件名(test.c),使用gcc这个编辑器,给大家演示整个过程;

第一步:预编译(预处理)

预编译的指令是:gcc 源文件.c -E - 源文件名 + .i 

1. 预处理 选项 gcc - E test.c - o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在 test.i文件中,具体内容可看下图。

如下面的代码:

源文件文件名 :test.c

#include<stdio.h>

//定义全局变量,赋值2023
int year = 2023;
#define M 100
int main()
{
	int a = M;
	printf("%d\n", M);

	return 0;
}

1.输入指令gcc test.c -E -test i

终端输出:


2.观察test.c和test .i的内容


 3.在test.i文件中查看

我们发现,在test.i整个代码的末尾,才是我们源代码的内容,那前面的几百行代码又是什么呢,是头文件<stdio.h>的整个内容包含进来了。同时细心的同学发现,test.i中没有了注释,也没有了宏定义的符号M了,所以预处理的作用是:

  1. 注释的删除
  2. #include<stddio.h>头文件的包含
  3. #define 符号的替换
  4. 文本操作
  5. 所以的预处理指令都是在预处理阶段处理的

第二步,编译

编译指令:gcc -S 源文件.c / gcc -S 源文件名 + .i

编译 选项 gcc - S test.c
编译 选项 gcc -S test.i   (编译时,这两个文件都可以输入指令中,都会生成文件test.s)
编译完成之后就停下来,结果保存在 test.s 中。
我们输入  gcc - S test.c 为例

1.输入指令gcc -S test.c / gcc -S test.i

终端输出:


2.生成了test.s文件的内容并展示test.s文件的内容

 


3.总结:

上面黄圈部分就是test.s的内容,里面就是汇编指令。编译的作用是:把c语言代码翻译成汇编指令 。编译的方式是通过:语法分析,词法分析,语义分析,符号汇总等方式。总的来说,编译就是把我们的c语言代码拆解分析,然后翻译成汇编指令给下一步汇编的动作。

第三步:汇编

汇编指令:gcc -c 源文件.c / gcc -c 源文件名 + .s

汇编 gcc - c test.c
汇编完成之后就停下来,结果保存在 test.o 中。

 1.输入指令gcc -c test.c / gcc-c test.s

终端输出:


 

2.生成了test.o的目标文件

但是你会发现这是test.o目标文件存放的二进制文件,编译器是不支持显示的的,如果仍要打开,如下图;


 


 3. 总结:

1.目标文件中存放的是二进制的指令

2.汇编是把汇编指令翻译成二进制指令

顺便提一下:Linux下gcc编译产生的目标文件test.o,可执行程序test都是按照ELF的这种文件格式存储的 

最后,以上过程完成了编译,之后到链接过程

链接指令:gcc 源文件名.o -o 新文件名 

对目标文件进行链接。可生成一个可执行文件

 1.输入指令:gcc test.o -o vskkk

输出终端:


2,对vskkk的内容进行查看

 但是文件还是二进制的指令无法查看。


3.总结:

链接的作用是:

1.合并线段

2.符号表的合并和重定位

 


关于运行环境分为四点:

运行环境相较于翻译环境就好理解的多了,通俗理解有以下几点:

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

关于链接库

我们知道再写C语言代码时,只要加上头文件 #include<stdio.h> ,就可以直接使用库函数了,比如scanf(),printf(),那为什么可以直接使用呢?原因是我们把这些库函数都已经提前编译好,打包好放在静态库中,可以直接提供给我们,比如我们熟悉的scanf函数,如下图的打红圈内容,标记部分后缀以LIB结尾的,就是静态库(.LIB),库函数的静态库和目标文件在链接器中发生链接生成可执行程序。程序就可以运行啦。


以上就是全部内容了,希望能帮助到大家,如果可以,也希望大家给博主点点赞支持一下,谢谢。如果有错误的地方,希望大家能在评论区批评指出,我会进行订正的。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言第七课----------函数的定义及使用--------C语言重要一笔

作者前言 个人主页::小小页面 gitee页面:秦大大 一个爱分享的小博主 欢迎小可爱们前来借鉴 __________________________________________________________ 目录 1.函数是什么 2. 库函数 3. 自定义函数 4. 函数参数 5. 函数调用 6. 函数的嵌套调用和链式访问 7. 函数的声…

海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131679108 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

物联网如何为智慧城市提供动力

智慧城市可以创造一个基础设施顺畅、效率提升的乌托邦&#xff0c;改善城市地区的生活质量&#xff0c;促进当地经济发展。 其影响意义重大&#xff0c;预计到 2024 年智慧城市基础设施的收入将超过 1000 亿美元。 从改善公共交通到解决犯罪问题和提高能源效率——应有尽有&am…

Fatdog64 Linux 814发布

导读Fatdog64 Linux是一个小型、桌面、64位的Linux发行版。 最初是作为Puppy Linux的衍生品&#xff0c;并增加了一些应用程序。该项目最新的版本&#xff0c;Fatdog64 814&#xff0c;是8xx系列的最后一个版本&#xff0c;未来的版本将转向9xx基础。 尽管它是该系列的最后一个…

【Ranking】50 Matplotlib Visualizations, Python实现,源码可复现

详情请参考博客: Top 50 matplotlib Visualizations 因编译更新问题&#xff0c;本文将稍作更改&#xff0c;以便能够顺利运行。 1 Ordered Bar Chart 有序条形图有效地传达项目的排名顺序。但是&#xff0c;将图表上方的指标值相加&#xff0c;用户将从图表本身获得准确的信息…

网络安全合规与标准的主要发展方向

网络安全合规就是避免违反网络安全有关的法律、法规、规章、合同义务以及任何安全要求&#xff0c;标准在网络安全合规工作中扮演着重要的角色。 一、标准在网络安全合规体系中的地位作用 网络安全合规体系包括网络安全有关的法律、法规、规章、其他规范性文件、及合同义务等…

[java安全]TemplatesImpl在Shiro550反序列化

文章目录 【java安全】TemplatesImpl在Shiro550反序列化Shiro的原理Shiro反序列化产生演示攻击过程payload使用key加密 构造不含数组的GadGets简单调用链 改造cc6为CommonsCollctionsShiro完整POC触发Shiro550漏洞进阶POC总结 【java安全】TemplatesImpl在Shiro550反序列化 Sh…

24.实现线性拟合和相关系数(matlab程序)

1.简述 1. 基本语法 1.1 corr函数基本语法 语法 说明 rho corr(X) 返回输入矩阵X中每对列之间的两两线性相关系数矩阵。 rho corr(X, Y) 返回输入矩阵X和Y中每对列之间的两两相关系数矩阵。 [rho, pval] corr(X, Y) 返回pval&#xff0c;一个p值矩阵&#xff0c…

OceanBase 压测时为什么冻结阈值在变化?

本文从源码角度分析了 OceanBase 压测中冻结阈值动态变化的原因&#xff0c;并给出运维建议。 作者&#xff1a;张乾 外星人2号&#xff0c;兼任五位喵星人的铲屎官。 本文来源&#xff1a;原创投稿 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转…

Vue3组合式API+TypeScript写法入门

文章目录 前言1.reactive2.ref3.props4.computed5.emit6.watch总结 前言 参考Vue3官网. 本篇以组合式API为例, 但不包含setup语法糖式写法. 原本打算结合class-component, Vue3不推荐就不用了: OverView|Vue Class Component. 而且是不再推荐基于类的组件写法, 推荐单文件组件…

NetSuite ERP顾问的进阶之路

目录 1.修养篇 1.1“道”是什么&#xff1f;“器”是什么&#xff1f; 1.2 读书这件事儿 1.3 十年计划的力量 1.3.1 一日三省 1.3.2 顾问损益表 1.3.3 阶段课题 2.行为篇 2.1协作 2.2交流 2.3文档管理 2.4时间管理 3.成长篇 3.1概念能力 3.1.1顾问的知识结构 …

【idea】idea全局设置Maven配置

Idea版本&#xff1a;2021.1.1 1、点击File->Close project 2、点击Customize->All settings 3、设置Maven

Vue 项目增加版本号输出, 可用于验证是否更新成功

webpack 1. vue.config.js 中增加以下配置, 此处以增加一个日期时间字符串为例, 具体内容可以根据自己需求自定义 // vue.config.js module.exports {chainWebpack(config) {config.plugin(define).tap(args > {args[0][process.env].APP_VERSION ${JSON.stringify(new …

Vue中TodoLists案例_删除

与上一篇Vue中TodoList案例_勾选有三个文件变化了 App.vue&#xff1a;添加了一个deleteTodo根据id删除方法&#xff0c;传递给儿子组件MyList <template><div id"root"><div class"todo-container"><div class"todo-wrap"…

浅谈小程序开源业务架构建设之路

一、业务介绍 1.1 小程序开源整体介绍 百度从做智能小程序的第一天开始就打造真正开源开放的生态&#xff0c;我们的愿景是&#xff1a;定义移动时代最佳体验&#xff0c;建设智能小程序行业标准&#xff0c;打破孤岛&#xff0c;共建开源、开放、繁荣的小程序行业生态。百度…

脑电信号处理与特征提取——三. 脑电实验设计的原理与实例(古若雷)

三、脑电实验设计的原理与实例 被试间设计的实验结果也有可能是人员不同造成的&#xff0c;所以建议被试内设计。

Web前端开发概述(二)

&#x1f60a;Web前端开发概述&#xff08;二&#xff09; &#x1f47b;前言&#x1fa81;前端开发背景&#x1f50d;当下前端开发要求&#x1f526;Web前端开发技术&#x1f3ad;HTML&#x1f3ad;CSS&#x1f3ad;JavaScript&#x1f3ad;HTML DOM&#x1f3ad;BOM&#x1f…

JVM面试题总结

一.请简述对象的创建过程 对象的new字节码执行指令如下图 首先0指令new出一片内存空间&#xff0c;然后进行对象的初始化&#xff0c;初始化完成前变量都是初始值如m0 然后创建连接&#xff0c;t指向对象。 二.DCL单例要不要加volatile&#xff1f; DCL单例就是要懒汉式从创建…

软工导论知识框架(一)软件工程学概述

本贴为B站大连工业大学老师的网课笔记&#xff0c;教材为张海藩第6版&#xff0c;适用于考研和期末复习。 导图比较拥挤&#xff0c;看不清可以单独保存或者放大页面。 一.软件&#xff1a; 软件指的是计算机程序、文档运行程序必须的数据、方法与规则。 方法指的是软件开发…

Java之集合的排序方式(Comparable和Comparator的基本使用以及区别)

文章目录 一、Comparable接口&#xff1a;1. 代码示例&#xff1a;2. 运行结果&#xff1a;3. 案例分析&#xff1a; 二、Comparator接口&#xff1a;1. 代码示例&#xff1a;2. 运行结果&#xff1a;3. 案例分析&#xff1a; 三、Comparable和Comparator对比&#xff1a;1. 接…