如何区分声明和定义

floor 8

变量和对象不加extern永远是定义,类中的除外.

函数只有函数头是声明,有函数体是定义.
类永远只是声明.类成员函数的函数体是定义.
class C
{
static int x;//这里的x是声明
static const int a;;//这里的a是声明
//非static变量在类定义对象时才分配内存.
C();//这里的函数是声明
};

int C::x;//这个才是定义

const int C::a=11;//这个才是定义

floor 11

"声明"的严谨C++语意,是用以告诉编译器类型及其细节,例如:

class fish6344
{
    //数据成员细节...
    //成员函数细节...
};

上述声明仅告诉编译器有自定义类型fish6344,编译器仅对其进行语汇分析及名字的决议,并无内存实际佔有!

"定义"的严谨C++语意,即内存佔有,编译器将在相对内存地址上为其对象定址!要注意的是,我们不能简单的说:

string s; 

是声明或是定义,应视具体情况而定,原则是,如果有内存的实际占有可确定是定义,否则是声明。例如:

class fish6344
{
   string s1;
   string s2;
};

上述fish6344类是个声明,并无内存占有(未实例化),s1及s2都是string型变量的声明而不是定义,fish6344都没有实体(可以为是虚幻的),哪儿有其成员的内存位置呢?只有实例化fish6344类以后,才会有内存占有。例如:

fish6344 _fish;//在对象实体_fish中有s1及s2的内存占有!

但是上述关于s1及s2的语句放在全局作用域或是另一实体的局部作用域,例如:

#include<iostream>

//全局作用域的:
string s2;//这是定义,s2是实例化的string!

int main()
{
   //Main函数体内的:
   string s1;;//这是定义,s1是实例化的string!

   return 0;
}

二个string语句都是定义,这是典型的类型实例化!

转自:http://bbs.youkuaiyun.com/topics/190026622

<think>好的,我现在需要回答用户关于C语言中声明定义的区别及其必要性的问题。首先,我要确保自己准确理解这两个概念,避免混淆。 根据引用[4],声明是不需要建立存储空间的,比如extern int a;而定义则需要分配内存。我记得声明的作用是告诉编译器变量的存在类型,而定义则是实际分配内存并可能初始化。比如int a;是定义,而extern int a;只是声明,实际存储在其他地方。 接下来,用户问为什么需要区分声明定义。这涉及到编译链接的过程。当多个文件需要使用同一个变量时,声明允许在多个地方引用该变量而不导致重复定义的错误。例如,在文件中声明变量,在源文件中定义,这样其他文件包含文件时不会重复分配内存。 另外,函数声明定义也有类似的情况。函数声明提供原型,让编译器知道函数的存在,而定义则是函数的具体实现。这样可以实现模块化编程,分离接口实现,提高代码的可维护性。 需要确认引用中的内容是否准确。引用[4]提到声明不需要存储空间,而定义需要,这符合我的理解。此外,用户提供的其他引用虽然涉及条件编译输入输出,但可能与当前问题关联不大,但需要确保不引用无关内容。 可能需要注意的误区是,声明可以多次,而定义只能一次。这也是为什么文件中通常使用声明,避免多次定义。另外,在C语言中,函数定义如果没有前面声明,可能在调用时出现隐式声明的问题,导致错误。 总结下来,声明定义的主要区别在于是否分配内存,以及是否允许重复。必要性在于支持模块化、避免重复定义错误、分离接口与实现。需要以清晰的结构呈现这些点,并引用正确的文献。</think>### C语言中声明定义的区别及必要性 #### 一、核心区别 1. **声明(Declaration)** - **作用**:仅告知编译器变量/函数的**存在性****类型信息**,不分配内存空间。 - **语法示例**: ```c extern int a; // 变量声明(引用其他文件中的变量) int func(int x); // 函数声明(原型) ``` - **特点**:可重复多次,用于多文件共享同一变量或函数[^4]。 2. **定义(Definition)** - **作用**:为变量/函数**分配内存空间**,并可能初始化值。 - **语法示例**: ```c int a = 10; // 变量定义(分配内存并初始化) int func(int x) { // 函数定义(具体实现) return x * 2; } ``` - **特点**:同一变量/函数在全局作用域内只能定义一次[^4]。 #### 二、必要性分析 1. **模块化编程** - 通过声明实现**接口与实现分离**。例如,文件(`.h`)包含函数声明,源文件(`.c`)包含定义,便于代码复用维护。 2. **避免重复定义错误** - 若多个文件包含同一变量的定义,链接时会报错`multiple definition`。通过声明(`extern`)可解决此问题[^4]。 3. **优化编译过程** - 编译器仅需声明即可完成语法检查,无需了解具体实现细节,加快编译速度。 #### 三、典型场景对比 | **场景** | 声明 | 定义 | |-----------------------|----------------------------|----------------------------| | 多文件共享全局变量 | `extern int global_var;` | `int global_var = 5;`(仅一处) | | 函数原型与实现分离 | `void print_data();` | `void print_data() { ... }` | #### 四、常见误区 - **隐式声明**:若未声明函数直接调用,C89标准会假设返回`int`类型,可能导致错误(如`warning: implicit declaration`)。 - **重复声明**:声明可多次存在,但需保持类型一致,否则引发编译错误。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值