hello world
计算机如何实现hello world
hello.c
include<stdio.h>
void main()
{
printf("Hello World!");
}
在你的c编译器里,编译执行后,就会出现一个控制台,显示“Hello World!”(windows系统)。
多么神奇啊,那计算机是如何实现的呢?
其实,从源代码到可执行文件一共涉及到了四个步骤,分别是:)
- 预处理(Prpressing)
- 编译(Compliation)
- 汇编(Assembly)
- 链接(Lingking)
那我们来看一下这四个步骤分别干了什么:)
-
预处理
也可以叫做预编译,预编译过程主要处理那些源代码文件当中的以“#”开始的预编译指令。比如“#Include”、“#define”等,主要处理的规则如下:
- 将所有的“#include”删除,并且展开所有的宏定义。
- 处理所有条件预编译指令,比如“#if”、“#ifdef”、“elif”、“#else”、“#endif”。
- 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件还可能包含其他文件。
- 删除所有的注释“//”和“/**/”。
- 添加行号和文件名的标识,比如#2 "hello.c"2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
- 保留所有的#pragma编译器指令,因为编译器必须要使用它们。
经过预编译后的源代码会产生一个以 .i 结尾的文件
-
编译
编译过程就是对第一步完成的预编译后的文件进行一系列的词法分析,语法分析,语义分析及优化后,生成相应的汇编代码文件。这个过程是整个程序构建的核心过程,设计一些编译原理的知识,我也不太懂。
最终,.i 文件会生成 .s文件。
-
汇编
汇编器是将汇编代码变成机器可以执行的指令,每一个汇编语句几乎都对应一个机器指令。所以汇编器的汇编过程相对于编译器来说相对简单,没有复杂的语法,也没有复杂的语义,更没有指令的优化。只是根据汇编指令和机器指令的对照表一一翻译即可。
最终,.s文件变为 .o文件。
-
链接
链接是一个很复杂的过程,有静态链接和动态链接,这是我们主要学习的部分。以后会持续的更新。在这里先简要的描述一下,链接的过程:):
静态链接
hello.c中有printf函数的声明和定义吗?没有吧。它是c语言标准库中的一个函数。我们尽管拿来用就好了。对于一个在本文件中没有声明和定义的函数,计算机怎么做呢?
这个时候,链接器就登场了。链接器会根据你引入的头文件找到具体的函数在哪,是windows的API函数,还是c语言的标准库函数,还是你自己定义的函数。
注意:这里的函数其实已经一个二进制的文件了。
找到这些函数后,链接器就将这些函数的二进制代码插入到引用它的地方。就像一个拼图,需要什么就拼接什么。
这样导致的结果就是,静态链接的程序很大。并且不利于维护。所以就有了以后的动态链接。
动态链接
动态链接是现在应用的最多的形式了。相比于静态链接是在一个完整的可执行程序启动之前拼接,动态链接则是在一个不是相对完整的可执行程序启动之后再进行拼接。
因为不管是Windows,还是linux,还是其他的一些系统,都留给我们很多的API,我们实现的大多数程序都利用了大量的API函数,干脆我们也不自己拼接了,我们之间把程序发布出去,等到程序执行的时候,由操作系统完成拼装不是很好。磁盘空间,网络带宽都得到了很好的利用。
那也许就有人问了,等到程序执行是再链接,那启动速度不是很慢吗?相比于静态链接来说,确实很慢。但是在动态链接的其他方面的优点衬托下,这点时间上的劣势,完全可以忽略不记。
参考书籍《程序员的自我修养》
相关阅读
学习任何语言,第一个程序都是hello world。 刚开始学习java的小伙伴,我建议还是用记事本编写代码,这样可以下打下更好的基础。 首先
全文约1500字,阅读大约需要5分钟现在我们开始一个“HelloWorld”项目,从此刻开始我们的Android开发之旅。*以下操作基于Android Stu
Excel 宏编程-第一个Hello World程序,实战演示!
先看大屏幕,我要演示的效果就是点击hello按钮,运行我们的宏,输出Hello World!第一步 首先进入开发工具页签,点击宏,创建一个的宏,我起的
今天装修宅小编为大家推荐一张动态hello kitty淘宝店铺收藏图片,大家喜欢的话可以在淘宝店铺装修中使用,用于引导买家收藏自己的淘
Informatica基础系列(一)——Helloworld
目录: Informatica基础系列(零)——前言 Informatica基础系列(一)——Helloworld Informatica基础系列(二)——更新策略转换