Definition(定义) and Declaration(声明)

原创 2006年06月06日 14:25:00

要弄懂这两者,没啥困难。可是,至少有半数以上的C书没能分清。有的书在某一章节里把这个问题说清楚了,可在其它章节里却乱说一气。真是无奈。

这两者都是对实体Object的操作。

对于任何一个实体,Definition必须有一次,也只能有一次。Declaration可以有0次,也可以有任意次。

Definition是真正产生实体,即为其分配存储空间。Declaration并不产生实体,事实上,被Declaration的实体必须是已经存在的。

譬如在源文件A里定义了一个外部的(即在任一函数外面的)整数数组:

       int   iArray[100];

编译器为其分配了400Bytes(如果你用的是32位编译器,每个整数占4Bytes)的空间。

如果你希望另一个源文件B里也能访问这个数组,你必须在文件B的头部对其做外部声明:

       extern     int    iArray[];

这是C专家编程里给出的例子。这例子举得好。你可能已经注意到声明里少了100。书里说得很明白:由于并未在声明中为数组分配内存,所以并不需要提供关于数组长度的信息。

这问题太简单了。你只需记住:对每个实体,定义数必须是1,声明数是0-N。如果你的代码不是这样,那就有Bugs。或者出错不能运行,或者得到的不是你预想的结果。

我以为,从结构化观点看,extern声明无非是把该数组的作用域从文件A扩展到文件B而已。

还有一种声明更为常见,就是结构、联合等的声明。与上述的不一样。许多书里说的是结构、联合的定义,我说的是声明。仍然是C专家编程里的例子。

struct      veg { int weight, price_per_lb; };

struct      veg onion, radish, turnip;

第一句声明了一个名为veg的结构类型,里面含两个int型成员。第二句定义了三个veg类型的结构变量。

我说是声明,按上面的说法,是不分配空间。在这里,这么说,恐怕会有点问题。不分配空间,也就是说,第一个语句不编译出任何代码。对于上面的两个语句,这样说能解释得通。但是,如果我在声明了结构类型后,想动态而不是静态生成结构变量,那在运行时如何按这不存在的东西去生成实体呢?

我没看过含结构类型声明的源代码编译后的目的码,不知道里面有没有与结构类型声明相关的代码。我猜想,这段代码是肯定有的。只是它不是用来运行的,而是用来复制的。你可以把它叫做模板,用来生成实体的模板。运行代码和模板代码可能放在不同的地方。

这个仅仅是猜想而已。曾几次把这猜想写在BBS上,很可惜,没人反对。因为没人反对,也就没法得到验证。

可以把结构类型的声明和结构变量的定义写在一起:

struct      veg { int weight, price_per_lb; } onion, radish, turnip;

在这种格式中,类型veg可以省略。但是不省略的好处是,你可以在以后再按veg定义第四、第五个结构变量。

       C专家编程里说得很好,结构类型的声明和结构变量的定义,还是分开写好。

相关文章推荐

C++: 关于function的declaration与definition的关系(函数声明和定义的关系)(并附一篇转载文章)

以下材料都来源于C++ primer 5th edition 1(Chap 6):重要概念(有时问题想不明白可以带着这个概念再去思考) A function is a block of code wi...

小谈声明(Declaration)与定义(Definition)

小谈声明(Declaration)与定义(Definition)   声明(Declaration)用于说明每个标识符的含义,而并不...
  • BigLeo
  • BigLeo
  • 2011年09月27日 12:43
  • 731

What is the difference between a definition and a declaration?

原帖: http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-dec...

(Effective C++)第四章 设计与声明(Design and declaration)

6.1 条款18:让接口容易被正确使用,不易被误用(Make interfaces easy to use correctly and hard to use incorrectly) 条款13表明...
  • wzhwho
  • wzhwho
  • 2011年10月15日 20:03
  • 468

正确使用#include和前置声明(forward declaration)

当我往工程里加一个类,而且那个类又与工程里的类相关,如有那个类型的成员变量。情况如下//////A.h///////////class A{.......};////////B.h//////////...
  • danforn
  • danforn
  • 2011年01月04日 11:00
  • 1254

property declaration 属性声明

property declaration 属性声明 为实例变量指定属性(attributes)的途径, 可让编译好器生成 无泄漏和线程安全的访问实例变量的方法. @property 就是对...

OCJP(310-065)精选笔记之-变量声明 (Variable Declaration)

Java里有两种类型的变量 主数据类型变量(Primitive):8种引用变量(Reference variables):可以指向声明某个类型或者其子类型(compatible type)的的任何对...

C++中的前置声明(Forward Declaration)

今天写模块类文件的一个收获是,在定义头文件时,能依赖前置声明的就不要依赖定义,同时在适当的情况下应该用类型的前置声明来减少头文件的导入。例如,在头文件中定义类的一个指针成员时,该指针是工程中另外定义的...
  • vc2014
  • vc2014
  • 2013年03月26日 13:51
  • 763

Effective Modern C++ 条款9 用别名声明(alias declaration)代替typedef

Effective Modern C++ 条款9

错误: 隐式声明函数‘init_MUTEX’ [-Werror=implicit-function-declaration]

在新版本的linux内核中,init_mutex已经被废除了,新版本使用sema_init函数。查了一下早期版本的定义:平台:X86 32位内核:2.6.30定义:Linux/include/linu...
  • ce123
  • ce123
  • 2012年07月23日 21:33
  • 13937
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Definition(定义) and Declaration(声明)
举报原因:
原因补充:

(最多只允许输入30个字)