复撸C系列开篇-Hello World

发布时间:2016-12-7 3:54:50 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"复撸C系列开篇-Hello World",主要涉及到复撸C系列开篇-Hello World方面的内容,对于复撸C系列开篇-Hello World感兴趣的同学可以参考一下。

一直以来想写技术博客,但迟迟未行动,如今终于下定决定,还是来写一写,顺便巩固一下自己的知识。 废话不多说,就参照《C语言程序设计(第2版)》,从头过一遍吧。 1.Hello World 一开头,基本是每个程序员都熟悉的第一个程序: #include <stdio.h> int main() { printf("Hello world!\n"); return 0; } 也许很多人会觉得:这没什么啊,不就一句向控制台打印一句Hello world 吗?但我想的是通过这个去了解更多的东西,因为很多人(包括我)在写了很久程序之后,才明白了什么叫“语言”,什么叫“库”,C语言本身是没有任何的“printf”给你用的。 那第一句 "#include <stdio.h>"  表明: 我要引入一个名叫 "stdio.h"这样的文件库,里面有一个叫"printf"的函数。 第二句"int main()"  表明: 这是程序的入口,为何要用"main"做入口?因为编译器就这么找的,游戏规则你得遵守,你要是高兴,完全可以自己写个编译器,规定一个名叫“fuck you”的函数入口。 第三句”printf("Hello world!\n")“, 表示调用了一个名叫printf的函数,传给它一个字符串指针,当然你得明白,这里是常量字符串指针。 那我们来研究下printf()是如何实现的。 在这句上打个断点,然后执行: 跟进去: 这尼玛是个鸟? 这么简单一句里面还这么复杂? 我们一个个的来看,可以看见”Hello world\n“传进来了。 ”va_list“ 是个毛?  这玩意实际上就是个  char * 的指针,暂且不管其他两个 buffing 和 retval,来看下面有个宏 "va_start",找到它的定义: 我擦,这又是毛? 跟进去再看看 这个很明白,就是取个地址而已。 这个?尼玛跟天书一样,又是减又是位运算的,一开始我也不懂,后面网上搜了下别人的讲解才知道,这个是保证内存对齐的玩意,很高端,至今我还有点迷糊,不过不用过分纠结。反正就是计算它大小 我们回到刚才这句: 这句可以简单理解为: arglist = (va_list)(&format) + sizeof(format)         取传进来字符串指针的地址,再加一个sizeof(char*) ? 这是搞鸡毛?我理解了很久,才初步推断这是函数调用时把参数压栈,然后这样那首参数地址加一下第一个参数的大小,自然也就得到了第二个参数的地址(也就是我们写: printf("This num is : %d",n) 这个n的地址), 不知这样理解对否? 还请高手指教。 那这意思明了了,就是arglist现在只想后面不定参数的第一个参数。 再往下,这句 再跟进去: OK,了解了这是给stdout加个锁,至于什么是锁我想不用多说,了解点多线程的都知道的。 那传进来的stdout,我们再看看它到底是个什么鸟,虽然一直听,我想自己去研究的貌似还挺少。 跟过去: 再进__iob_fun( )  再跟: 噢,Bitch,终于找到你了,是个FILE的数组,这里_IOB_ENTRIES设了上限是20,可以看见有三个初始就有的大家经常听见的“stdin”,“stdout”,"stderr"。 找到FILE的定义: 就这么个玩意。说到这里我想说一下,有很多初学者认为这个语言屌,那个语言妙,其实说白了还不就是一些基本的东西组成的,再往下就是二进制了。所以与其纠结于XX语言好,XX语言妙,不如探究下本质,我也是因为想从本质上去发现语言,才有了写文的初衷。 扯回来,这里我们大概知道怎么回事了,printf一进来就把输出流锁住,然后进到这里来: 这里做一些初始的检查工作之类的,暂且不管。 主要看这一句: 撸进去: 我草?这是个毛,里面这么混乱,printf里面这么屌它妈妈知道吗? 暂且不要过于纠结这么多参数以及略长的函数以及复杂的循环,我们找找主要的, 到这里: 终于,这个传进来的"Hello World\n"开始起作用了,真麻烦啊。。。。 可以看见它在扫描 format这个字符串 ,也就是“Hello Wordl\n”,一直扫到末尾"\0"结束符。中间还有很多的杂七杂八的判断之类的,什么语言区啦,状态啦,然后麻痹的一长串恶心的switch case ,终于来到这句: 往里面写,也就是把当前扫描到的往 stdout这个buf里写,因为这里没有带什么“%s%d”之类的,所以处理过程还是相对比较简单。 噼里啪啦写完了之后: 返回 往里面写了多少个字符。OK,这个函数执行完了,临时的buffing里面已经有了内容。 最后_ftbuf 把buffing的内容填充到stdout里面去,至此,终于差不多完了。 之前我们锁了stdout,有锁当然就要解锁: 然后返回写入的字符 : 然后刚才调用的函数传的参数弹栈,也就是“Hello World\n”这个常量字符串指针变量弹出来,回到mian函数: 最后返回0,OK,至此我们的Hello World便完成了。 这里 只讲到了va_list  va_start 没有说 va_arg,因为初篇只有“Hello World\n”这么个简单的字符串,所以没有提及复杂的处理,后面会讲到。 初次写作,还请大家批评指正。 ps.转载的话(估计也没人转 ,有人看没有都是一回事╮(╯_╰)╭),还是注明个出处吧? 

上一篇:机器学习9树回归
下一篇:lyrics of <The message> in Grandmaster Flash and the Furious Five song

相关文章

相关评论