最近在阅读C和指针及Linux的学习过后,对一些很简单的程序也觉得奇妙了起来,想到最初学的一个程序 打印hello world,现在看来,如果开始深究其原理,也不是一个简单的程序
#include <stdio.h> int main() { printf("hello world!"); return 0; }
打开vs,习惯性的打下#include <stdio.h> int main() ,咱们是否有想过,为什么要打下这一个预处理令,以及一个函数?
#include <stdio.h>代表什么?我相信还是有大部分人知道,这是在调用一个标准IO的库,可是其实现原理是什么?在看《C与指针》的时候了解一些。#include #define被称作预处理令,他们是由预处理器解释的,说人话就是 预处理器读取源代码,然后把修改过的源代码交给编译器。在这个例子中预处理器用stdio.h的函数库头文件内容替换第一条#include指令。其结果就像是把stdio.h的内容逐字写到那个位置,这可以延申到我们自己的库 比如#include "myio.h",其结果就像是把myio.h的内容逐字写到那个位置,
对于int main来说,涉及到函数调用,寄存器,函数堆栈(可以顺带了解一下静态储存类型以及自动变量),我们都知道main函数是由另外一个函数调用的。函数调用就涉及到函数栈帧的创建和销毁(ebp,esp两个寄存器),这里不细说说一下静态储存类型和自动变量。变量的储存类型基于其声明的位置,如果在代码块之外(一对{ }称作代码块)声明,总是储存在静态内存中,不属于堆栈的内存,这类变量被称作静态变量,静态变量在运行前创建,在程序存在期间始终存在。而在代码块当中被声明的变量称作自动变量,自动变量储存在堆栈中,当程序执行离开该代码块时,其变量被销毁。有没有什么办法把自动变成静态呢?有,关键词static让变量储存类型从自动变成静态,但是,改变存储类型不改变作用域
#include <stdio.h> int main() { int a = 0; { static a = 1; } printf("%d",a); return 0; }
相信这个图能很好解释一下作用域不改变。
现在大家都在想,就这?这不是结束了吗?还想搞出什么花?
你错了,还真没结束
对于printf你能说你了解它吗?大家都知道,他是打印而已啦。但你知道,printf有返回值吗?或许你知道。但你知道一般这种返回值称作什么吗?它叫做“副作用”,或许你觉得很陌生,但是a++你熟悉吗?a++利用的就是这个性质。
而在Linux系统下呢?hello world很容易打印出来吗?
这是把hello world!写入一个有或者无的文件里面,还没学到这里所以先不给大家细说了。