【【YouCodeMe】c (1)Hello World】http://toutiao.com/group/6481776801059176974/?iid=15906422033&app=explore_article&tt_from=copy_link&... 在这个世界上,不管使用哪种计算机语言,他(她)们第一段代码一定是“hello world!”,为什么学习程序第一句是hello world 而不是其他的语句?下面介绍完这位大牛上面的疑问就解决了。这位大牛是 C 语言的作者Dennis Ritchie,Dennis Ritchie(丹尼斯·里奇)在他的名著 《C 程序设计语言(The C Programming Langupeach)》中第一次引入,传为后世经典,其它语言亦争相效仿,以示致敬。 维基百科链接:丹尼斯.里奇 下面看一下hello world 的源程序是什么样的。 c语言版 #include //因为用到printf库函数,所以要包含printf所在的头文件int main() //程序入口{ printf(“Hello World!”);//向屏幕输出Hello World! return 0; //main函数的返回值} c 版的 #include //程序中因为用到了cout库函数,所以要包含cout所在的头文件 using namespace std; //用到的命名空间int main() //程序的入口,表示计算机从哪里开始执行此程序{cout << 'Hello World!' << endl; //屏幕输出 Hello World! return 0; //main 函数的返回值} 好,我们见到了源码,源码是如何被计算机识别运行的呢?她经历的那些过程? 学过c的大概知道,从源程序到可执行程序经历了四个过程: 预处理->编译->汇编->链接 可是这四个过程到底发生了什么可能并不清楚,因为现在大多数人使用集成开发环境(IDE),它隐藏了很多细节。但是因为IDE减少了环境配置,合并开发流程,便于快速开发,所以使用IDE更适用于初学者。 下面我们来看看每个过程中到底发生了什么 下面以vim编辑器,gcc编译器为例子,给大家展示一下 我们已经在vim编辑器中写好了Hello World的源程序 现在执行预处理命令; gcc -E hello.c -o hello.i //结果会出现下面这么一大坨1 'hello.c'# 1 '' 1# 1 '' 3# 329 '' 3# 1 '' 1# 1 '' 2# 1 'hello.c' 2...................省略N多行int main(){printf('Hello World !');return 0;} 我们会看到在于处理阶段会发生以下内容 预处理器把中的内容读取过来,直接插入到程序文本中。 我们的注释内容不见了。 我们得到另一个C程序,通常是以 .i 作为扩展名。 现在执行编译命令; gcc -S hello.i -o hello.s //编译后的结果是这样的,能看明白吗?.section __TEXT,__text,regular,pure_instructions .macosx_version_min 10, 11 .globl _main .align 4, 0x90_main: ## @main .cfi_startproc## BB#0: pushq %rbpLtmp0: .cfi_def_cfa_offset 16Ltmp1: .cfi_offset %rbp, -16 movq %rsp, %rbpLtmp2: .cfi_def_cfa_register %rbp subq $16, %rsp leaq L_.str(%rip), %rdi movl $0, -4(%rbp) movb $0, %al callq _printf xorl %ecx, %ecx movl %eax, -8(%rbp) ## 4-byte Spill movl %ecx, %eax'hello.s' 34L, 670C 我们会看到编译阶段会发生...... 好像就是把上面的 .i 文件按照一定规则翻译成现在的 .s 文件。 (.s文件是汇编代码) 现在执行汇编命令 gcc -c hello.s -o hello.o Ïúíþ^G^@^@^A^C^@^@^@^A^@^@^@^D^@^@^@^@^B^@^@^@ ^@^@^@^@^@^@^Y^@^@^@<88>^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^^K^@^@^@^B^@^@^U^@^@^@^@^A^@^@^F^A^@^@^@^O^A^@^@^@^@^@^@^@^@^@^@^G^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@_main^@_printf^@^@..............~ ~ ~ ~ 'hello.o' [noeol][converted] 3L, 816C 我们再看看汇编阶段到底发生了什么 将汇编文件翻译成机器指令,并打包成可重定位目标程序的 . O 文件。该文件是二进制文件,字节编码是机器指令。 到这个阶段已经不是人能看得懂得了!反正我是看不懂。 最后链接阶段会发生什么呢? gcc hello.o -o hello úíþ^G^@^@^A^C^@^@<80>^B^@^@^@^O^@^@^@°^D^@^@<85>^@ ^@^@^@^@^@^Y^@^@^@H^@^@^@__PAGEZERO^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^Y^@^@^@Ø^A^@^@__TEXT^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@...........//@符号好像比上面的多了好多^@^@8^@^@^@^K^@^@^@P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^B^@^@^@^B^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@'hello' [noeol][converted] 5L, 8498C 我们在程序中用到了printf函数,printf函数存在一个名为printf.o的预编译好的目标文件中,链接器就是将这个printf.o文件和我们的hello.o文件以某种方式结合在一起,生成一个可执行hello文件,加载到内存中去,有系统去执行。 好,我们学习的第一段程序到此结束了!后续会有更精彩的内容! 有任何建议 ,意见,批评请在评论中或者私信给我哦!
|
|
来自: 山峰云绕 > 《C语言数据结构描述Windows程序设计》