声明(declaration),定义(definition),以及初始化(initialization)

c++中的一个重要思想是类型。但无论是自定义的类型还是自带的基本类型,对于变量和函数的声明,定义,及初始化都是必不可少的。今天读完了《C++primer》中对于变量和基本类型的描述,似懂非懂的感受让我有些不爽,那末,就来总结一下声明,定义,以及初始化吧。

下面就来看看这三个概念:

声明(declaration):Type_name Variable_name1,Variable_name2...例:int a,b,c...(《c++面向对象程序设计》)

由此可见,声明的作用有两点:1、应该为变量分配多大的储存空间。2、应该用那种方式将变量的值表示为一连串的1,0。这两点也是类型的重要作用,即提供编译器实现变量所需的两部分信息。

定义(definition):确定变量和函数的类型,标识符,以及规定函数的作用。

对于函数体的实现进行解释,如下代码:

int func1()
{
       return 1;
}

int func2()
{
      return 2;
}
其中 return 1;以及return 2;这两个语句就是对函数func1,和func2的定义,分别让我们知道了func1将要返回1,func2将要返回2,这便是定义,what is called definition.

但是这里提出了一个问题:int func1(声明)int func1{....;}(定义)这之间有什么区别呢?既然在定义中有了int func1,是不是就不需要声明?如下代码应该能够解释清楚这个问题:

int func1()
{
     return 1;
}

int main()
{
     func1();
     func2();    //程序运行到这里就会出错,告诉我们func2()没有被声明。
     return 0;
}

int func2()
{
     return 2;
}

在这段程序里,func1在一开始就被定义了,而func2却是在末尾被声明的,为什么func1可以通过编译,而func2不行呢?这里是因为C++在进行编译时是从上到下的顺序,所以运行到注释处func2尚未被声明,即使func2被定义了,但没有在main()之前被声明,所以编译器不知道func2是什么,不能通过。这样,定义与声明的区别应该就大致明了了。

初始化(initialization):即给对象一个初始值(不然对象的值是系统给变量的位置值,是随机的,不安全),但这里要强调,初始化!=赋值。(赋值:将对象原有的值擦除,再给一个新的值进去。初始化:创建变量并给他赋初值)初始化分为两种:

1、复制初始化(copy-initialization)

int ival(1024)

2、直接初始化(direct-initialization)

int ival=1024

这两种情形下对象ival都被初始化为1024,但直接初始化的语法更为灵活且效率更高。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在讨论完这三个区别微妙的概念后,也清楚了变量的内存分配也应该是在声明过后完成的。

以上就是,声明、定义、以及初始化这三者的联系与区别。


### C++ 中 `extern` 关键字的作用 在 C++ 编程中,`extern` 是一种用于声明外部链接的存储类说明符。其主要功能是在多个源文件之间共享全局变量或函数。通过使用 `extern`,可以在不重新定义的情况下访问其他编译单元中的变量。 #### 声明定义的区别 当在一个文件中定义了一个全局变量时,默认情况下该变量具有外部链接(external linkage),意味着它可以在程序的不同部分被引用。但是,在另一个文件中要使用这个变量,则需要先对其进行声明: ```cpp // FileA.cpp int globalVar = 10; ``` 为了能够在第二个文件中使用 `globalVar` 变量,应该这样声明: ```cpp // FileB.cpp extern int globalVar; void printGlobal() { std::cout << "Value of globalVar: " << globalVar << '\n'; } ``` 这里的关键在于区分 **定义** **声明** 的概念。定义创建并分配内存给对象;而声明只是告诉编译器某个名字的存在及其类型[^1]。 #### 使用 `extern` 定义初始化的全局变量 如果希望延迟到链接阶段才指定实际地址,也可以仅声明而不立即提供初始值: ```cpp // Header.h #ifndef HEADER_H_ #define HEADER_H_ extern double pi; // Only declaration, no definition here. #endif // HEADER_H_ ``` 然后在某一个 `.cpp` 文件里真正定义此变量: ```cpp // Implementation.cpp #include "Header.h" double pi = 3.14159265358979323846; // Definition with initialization. ``` 这种方式允许不同模块之间的解耦合设计,并有助于减少重复代码的可能性。 #### 处理多文件项目中的命名冲突 为了避免潜在的名字空间污染问题以及防止意外覆盖同名实体的情况发生,通常建议将所有公共接口封装于特定名称的空间内。对于那些确实需要跨文件使用的符号来说,仍然可以通过显式的 `extern` 来控制可见性生命周期管理[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值