AKATheIronHead 2010-12-27
什么是定义? 什么是声明? 他们之间有什么区别? 这个问题非常重要,这是理解C语言的关键。
举个例子:
(1)int i ; 这是声明
(2)int i = 1; 这才是定义
(3) extern int i ; 这也是声明
什么是定义:
所谓的定义就是(编译器)创建一个对象,并为这个对象分配一快内存并给他取上一个名字,这名字就是偶们说的变量名或者 对 象。
什么是声明:
(1)告诉编译器,这名字语句匹配到一块内存上来。下面代码用到的变量是在别的地方定义的。
(2)告诉编译器,这名字偶预定了,别的地方再也不可以用他来作变量名或者对象名。
他们之间的区别:
(1)定义创建对象并为之分配内存,而声明没有。
(2)定义只可以一次,而声明却可以多次。
上面是从C语言的角度来说的,现在让偶们换种思维方式,从最底层的汇编的角度来看看声明跟定义之间的区别。
让偶们看两个简单的例子,然后对比一下就清楚了。
(1)test1.c
#include <stdio.h>
int a = 1;
int main(void)
{
}
让偶们反汇编看看 gcc -S test1.c
.file "test1.c"
.globl a //这句,因为a定义在函数外部,是全局变量,所以a是一个全局可见的符号。
.data //告诉偶们a是在程序的数据段中,全局变量是放在数据段中,而局部变量是放在栈中。
.align 4 //指示为a分配的地址必须是4字节对齐
.type a, @object
.size a, 4 //a的大小是4个字节
a: //这里才正式给出a的位置
.long 1 //a = 1;
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.4 20100503 (Red Hat 4.4.4-2)"
.section .note.GNU-stack,"",@progbits
test1.s (END)
现在让偶们看看声明
(2) test2.c
#include <stdio.h>
extern int a;
int main(void)
{
}
让偶们反汇编看看。gcc -S test2.c
.file "test2.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.4 20100503 (Red Hat 4.4.4-2)"
.section .note.GNU-stack,"",@progbits
~看到没,有区别把。因为a是只是一个声明而已,编译器并没有给他分配内存。a既不在数据段,也不在bss段中。
以上内容需要熟悉LINUX与GCC的使用。以及汇编的基础。如果内容有不正确的地方,请指出来告诉偶。谢谢。(主页上的个人档案里有偶的联系方式)