我们可以通过研究编译器为我们生成的汇编代码来了解一些c/c++语言的细节,让编译器为我们生成汇编代码可以通过这个命令来实现:
调用函数、栈
C语言并没有规定参数入栈的顺序。不过,大多数的c编译器都是参数从右往左入栈,并且通常情况下,栈是往内存的低地址方向增长的,也就是说,先压栈的内容放在高地址区域,后压栈的内容放在低地址区域。
变量的声明和定义
“声明”仅仅是告诉编译器某个标识符是:变量(什么类型?)还是函数(函数签名是什么?)。要是在后面的代码中出现该标识符,编译器就知道如何处理。最重要的一点:声明变量不会导致编译器为这个变量分配空间。
“定义”变量意味着不告诉编译器变量的类型,而且编译器同时必须为变量分配空间。变量定义的同时还可以初始化变量。
这里给出若干原则:
#1,带有初始化的语句是定义
#2,带有extern的语句是声明(除非对变量进行初始化)
#3,没有初始化也没有extern的语句是“暂时定义”(tentative definition)(关于这个暂时定义,是c语言特有的,c++里面没有这个概念,相反,c++推行“只定义一次”原则)
编译和链接
编译程序要做的事情之一就是把所有需要确定地址的符号记录下来,然后链接程序在找到他们的定义点之后通过计算给予合适的地址。当所有符号都有确定的地址时,链接程序就能够产生可执行文件。
外部变量的链接性质
和内部变量不同,外部变量被存放在数据段(内部变量如果是非静态变量这是存放在栈中)。外部变量的好处是可以被多个函数访问,这些函数可以分步在不同的c代码文件中,但是给我们带来方便的同时也会带来麻烦(比如全局空间的名字冲突问题),那么有没有一个办法是的一个变量既可以像外部变量那样放在数据段,又不会被其他文件的代码看到呢?为此c语言有一个关键字:static,它能够把外部变量的链接性质改为“内部的”(其他代码文件的函数访问不到经过static修饰的外部变量)。
静态内部变量
静态内部变量编译器在数据段为他分配空间,从而他的声明周期是整个程序的运行时间,但这些变量同时又是某个函数的内部变量(只能被自身所在的函数访问)。
。。。。。。
使用头文件
哪些东西该放在头文件里呢:
#1,函数原型的声明
#2,全局变量的声明
#3,自定义的宏和类型(typedef)
这些东西不应该放在头文件中:
#1,全局变量和函数定义:全局变量只能定义一次,函数的情形也是这个道理。
#2,static变量和static函数:static变量如果和某个全局变量一样,那么全局变量声明和static变量定义之间,后者优先。于是本来应该访问一个全局变量的代码最后存取的却是一个由头文件定义的、毫无用处的static变量。
静态库
在unix平台下命令nm可以查看目标代码文件、可执行文件、库文件的符号表数据的命令。
字符串
模板
函数模板并不是真正的函数,所以我们不能把函数模板的声明和定义分开来放在不同的文件里。