您的位置:首页 > 编程语言 > C语言/C++

【纠错】关于变量定义和声明的区别

2014-11-14 00:00 513 查看
《C语言深度剖析》以及网上很多资料(http://hi.baidu.com/kingcham/item/8f52370c91dc4920a0312dc7)(http://www.cnblogs.com/wangliang651/archive/2009/04/06/1430098.html)(当然,基本都是抄的深度剖析那本书),都有如下介绍:

下面哪个是声明,哪个是定义?

(A)int   i;
(B)extern int  i;


《C语言深度剖析》给的答案是:A是定义,B是声明。

我的答案是:A是声明,B也是声明。

B是声明毫无疑问,个人觉得A也是声明,以下是我的理由:

1、C语言创始人写的书《The C programming language second Edition》 A.8有说明:声明(declaration)用于说明每个标识符的含义,而并不需要为每个标识符预留存储空间。预留存储空间的声明称为定义(definition)。

根据最后一句话,可确定,定义是声明的一种。

for(int i=0;i<9;i++)

{

以上这段话请读十遍;

}

2、接下来看代码:

#include<stdio.h>
void main()
{
int a;
}


就上面的int
a;用ARMv8交叉工具链编译及反汇编后代码如下:

aarch64-apm-linux-gnu-gcc -g -O0 int.c -o int

aarch64-apm-linux-gnu-objdump -alDS int>int.txt

0000000000400560 <main>:
main():
/home/zql/LearnC/int.c:5
#include<stdio.h> void main() { int a; }
400560: d65f03c0 ret
...


请问:inta;有分配存储空间吗?如果没有,为什么还说inta;是定义?

用X86下编译器编译及反汇编后代码如下:

0000000000400448 <main>:
main():
/home/zql/LearnC/int.c:3
#include<stdio.h>
void main()
{
400448:   55                      push   %rbp
400449:   48 89 e5                mov    %rsp,%rbp
/home/zql/LearnC/int.c:5
int a;
}
40044c:   c9                      leaveq
40044d:   c3                      retq
40044e:   90                      nop
40044f:   90                      nop

[/code]

请问:inta;有分配存储空间吗?如果没有,为什么还说inta;是定义?

3、再看int a=1;的情况:

#include<stdio.h>
void main()
{
int a=1;
}


armv8工具链编译及反汇编后:

0000000000400560 <main>:
main():
/home/zql/LearnC/int.c:3
#include<stdio.h>
void main()
{
400560:   d10043ff    sub sp, sp, #0x10
/home/zql/LearnC/int.c:4
int a=1;
400564:   52800020    mov w0, #0x1                    // #1
400568:   b90003e0    str w0, [sp]
/home/zql/LearnC/int.c:5
}
40056c:   910043ff    add sp, sp, #0x10
400570:   d65f03c0    ret
...


以下是x86版本:

0000000000400448 <main>:
main():
/home/zql/LearnC/int.c:3
#include<stdio.h>
void main()
{
400448:   55                      push   %rbp
400449:   48 89 e5                mov    %rsp,%rbp
/home/zql/LearnC/int.c:4
int a=1;
40044c:   c7 45 fc 01 00 00 00    movl   $0x1,0xfffffffffffffffc(%rbp)
/home/zql/LearnC/int.c:5
}
400453:   c9                      leaveq
400454:   c3                      retq
400455:   90                      nop
400456:   90                      nop
400457:   90                      nop
400458:   90                      nop
400459:   90                      nop
40045a:   90                      nop
40045b:   90                      nop
40045c:   90                      nop
40045d:   90                      nop
40045e:   90                      nop
40045f:   90                      nop


我对x86汇编不很熟悉,所以拿ARMv8汇编举例说明,但这不会影响C语言的定义。

4、C语言创始人写的书应该是权威吧?请不要拿谭浩强的书来说事。

《The C programming language second Edition》A 8.6有这么一段话:

As other examples, the declarations (看一下其他声明的例子)
int i, *pi, *const cpi = &i;
const int ci = 3, *pci;
declare an integer i and a pointer to an integer pi. The value of the constant pointer cpi may not be changed; it will always point to the same location, although the value to which it refers may be altered.
The integer ci is constant, and may not be changed (though it may be initialized, as here.) The type of pci is ``pointer to const int,'' and pci itself may be changed to point to another place, but the value to which it points may not be altered by assigning through pci.

上面说,看一下其他声明的例子,其中包括const int ci=3,

以上几个例子说明:

1、int a;没有分配存储空间

2、int a=1;分配了存储空间

所以int a;仅仅是声明,而inta=1;不仅仅是声明,也是定义。

欢迎有不同意见的同学留言讨论。

参考资料:

1、The C programming language second Edition (http://103.2.211.229/videoplayer/The_C_Programming_Language.pdf?ich_u_r_i=dbc101a0839c0caed679934172e59845&ich_s_t_a_r_t=0&ich_e_n_d=0&ich_k_e_y=1345108907751363522410&ich_t_y_p_e=1&ich_d_i_s_k_i_d=4&ich_u_n_i_t=1

2、《C语言深度剖析》陈正冲
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言