关于C语言的定义于声明

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的使用。以及汇编的基础。如果内容有不正确的地方,请指出来告诉偶。谢谢。(主页上的个人档案里有偶的联系方式)

相关推荐