分享

c (1)Hello World

 山峰云绕 2017-10-29
【【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文件,加载到内存中去,有系统去执行。
  好,我们学习的第一段程序到此结束了!后续会有更精彩的内容!
  有任何建议 ,意见,批评请在评论中或者私信给我哦!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多