区分c++中的声明与定义

C++编码过程中,我们经常谈及“定义”和“声明”,二者是编程过程中的基本概念。我们需要使用一个变量、类型(类、结构体、枚举、共用体)或者函数时,我们需要提前定义和声明。定义和声明的过程,就像我们向图书馆借阅书籍一般,需要先完成书籍的印刷,即创造出书籍,这是一个定义的过程,有了书籍,我们需要到图书馆完成借阅的登记手续,这是申明的过程。完成了申明,我们有了使用书籍的权限,就可以尽情的畅游在知识的海洋。如果说书籍是自己委托印刷厂印刷的,那么你无需向他人借阅,即无需声明,可以直接使用书籍。一本书籍只需要印刷一次,但是可以被多人多次借阅,也就是说定义只需要一次,但是声明可以有多次。这里的书籍指代的是“定义”和“声明”作用的对象,即变量、类型和函数。C/C++中,使用一个变量、类型或者函数必须先在使用前完成定义和声明。

定义和声明是容易混淆的概念,但通过上面的类比说明,可以看出:
(1)“定义”和“声明”的本质区别是声明可以出现多次,而定义只能出现一次;
(2)把声明的东西放在头文件,把定义的东西放在源文件(.c或者.cpp文件);
(3)类型的定义应该放在头文件,因为类型不具有外部连接性,不同源文件拥有相同的类型定义不会报编译错误,但头文件不能重复包含。

1.变量的定义与声明

定义变量,指明变量所属类型、名称、分配内存空间与初始化其初始值,如

int a=1;
int a(1);

如果不显示初始化,则按照编译器默认进行初始化。

声明变量,指明变量所属类型与变量名称,如:

extern int a;

有一点需要注意,对于局部变量以及全局静态变量是不能通过extern进行前置申明的,即不能在定义之前通过声明来引用,因为局部变量的作用域是当前代码块,全局静态变量的作用域是当前源文件,都不是全局作用域,所以不能通过extern进行前置声明。全局变量允许在定义之前通过前置声明进行引用。参见如下代码片段。

#include <stdio.h>

extern int a;
extern static int b; //报错
int main()
{
 extern int c; //报错
 printf("a=%d,b=%d,c=%d",a,b,c);
 int c=2;
}
int a=0;
static int b=1;

2.类型的定义与声明

定义类型,指明类型的名称和内容。

struct test{int a;}

或者给已经存在的类型起个别名。

typedef int int32;

注意,类型的作用域是源文件,即类型不具有外部连接性质,因此可以在不同源文件定义相同名称的类型,比如定义同名的类是不会报重定义错误的,这也说明了类型的定义应该放在头文件中,但在同一个源文件定义相同名称的类型则编译器会报重定义错误。

声明类型,只给出类型的名称。

class A;

类型被声明之后,可以用于声明其他的标识符,但不能利用它来定义对象,也不能使用类型的成员。

class A;  //先声明类
void show(A& a); //申明函数
class A  //后定义
{
public:
 int a;
 char b;
};

以上代码没有错误。但如下代码将报错:

class A; //先声明
int main(int argc,char* argv[])
{
 A classA;
 classA.a=5;
 return 0;
}

class A //后定义
{
public:
 int a;
 char b;
};

该程序无法通过编译,原因是类A的所有成员的有效范围均是从定义类的地方开始,故使用未知的构造函数初始化其成员变量是错误的,会报使用未定义的 class “A”错误。

使用类型之前给出其定义式即可,即给出类型的名称和内容,或者利用typedef给一个类型起个别称。虽然说是定义类型,但还是将类型的定义放在头文件,即使被不同的源文件包含,因为类型不具有外部连接特性,所以不会报重定义错误的,这和变量和函数不同,不能将变量和函数的定义放在头文件!切记!这里所说的外部连接与内部连接的区别在于链接器接的时候是否将当前目标文件中的定义与其它目标文件对比,并报告是否有重定义错误。内连接不会进行对比,故不同源文件中定义相同名称的类型是不会报错的。

3.函数的定义与声明

定义函数,指明函数返回类型、函数名称、函数参数和函数体。

int test(char a,int b)
{
 return a+b
}

声明函数,指明函数返回类型,函数名称和函数参数。

int test(char a,int b);
//或者无需给出形参名称,只需要类型即可
int test(char,int);

从上面可以看出,函数定义与函数声明的区别是主要有两点:
(1)函数定义需要给出函数体,即函数的具体实现,函数声明不需要;
(2)函数定义必须给出形参名称,声明可以只给出形参类型。

以上就是区分c++中的声明与定义的详细内容,更多关于c++ 声明与定义的资料请关注我们其它相关文章!

(0)

相关推荐

  • c/c++中变量的声明和定义深入解析

    不管是函数还是变量的声明 ,都是为了告诉编译器我要使用这个变量或者函数了,用于类型检查.在定义 的时候编译器是不会分配任何内存的, 比如下面的函数: 复制代码 代码如下: void func() {      int a ;      int b = 0 ;      a = 0 ;} 当函数执行到int a ;的时候,这是一个声明,编译器不会为其分配内存空间 .当执行到a = 0; 这是一个定义,编译器才会为其分配内存空间.因此声明不一定是定义,定义一定就是定义,还可以包含声明.但是下面的这种

  • c/c++中struct定义、声明、对齐方式解析

    一.定义/声明方式 第一种:仅有结构体名,不定义/声明变量 struct MyStruct { int i: char a[10]; double b; }: 第二种:有结构体名,并声明变量名 struct MyStruct { int i: char a[10]; double b; }structName: 或 struct MyStruct { int i: char a[10]; double b; }: struct MyStruct structName: //可同时定义,如stru

  • 深入分析C++中声明与定义的区别

    首先谈下声明与定义的区别.         声明是将一个名称引入程序.定义提供了一个实体在程序中的唯一描述.声明和定义有时是同时存在的. 如int a; extern int b=1; 只有当extern中不存在初始化式是才是声明.其他情况既是定义也是声明. 但是在下列情况下,声明仅仅是声明: 1:仅仅提供函数原型.如void func(int,int); 2: extern int a; 3:class A: 4:typedef声明 5:在类中定义的静态数据成员的声明 如: class A {

  • 基于C++全局变量的声明与定义的详解

    (1)编译单元(模块)在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作:第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件:第二步,将工程中所有的obj文件进行LINK,生成最终.exe文件.那么,错误可能在两个地方产生:一个,编译时的错误,这个主要是语法错误:一个,链接时的错误,主要是重复定义变量等.编译单元指在编译阶段生成的每个obj文件.一个obj文件就是一个编译单元.一个.cpp(.c)和它相应的.h文件共同组成了一个编译单元.一个工程由很多编译

  • C++编程中变量的声明和定义以及预处理命令解析

    关于C++变量的声明和定义 我们已经知道,一个函数一般由两部分组成:声明部分和执行语句. 声明部分的作用是对有关的标识符(如变量?函数?结构体?共用体等)的属性进行说明.对于函数,声明和定义的区别是明显的,前边已说明,函数的声明是函数的原型,而函数的定义是函数功能的确立.对函数的声明是可以放在声明部分中的,而函数的定义显然不在函数的声明部分范围内,它是一个文件中的独立模块. 对变量而言,声明与定义的关系稍微复杂一些.在声明部分出现的变量有两种情况:一种是需要建立存储空间的(如int a;):另一

  • 区分c++中的声明与定义

    C++编码过程中,我们经常谈及"定义"和"声明",二者是编程过程中的基本概念.我们需要使用一个变量.类型(类.结构体.枚举.共用体)或者函数时,我们需要提前定义和声明.定义和声明的过程,就像我们向图书馆借阅书籍一般,需要先完成书籍的印刷,即创造出书籍,这是一个定义的过程,有了书籍,我们需要到图书馆完成借阅的登记手续,这是申明的过程.完成了申明,我们有了使用书籍的权限,就可以尽情的畅游在知识的海洋.如果说书籍是自己委托印刷厂印刷的,那么你无需向他人借阅,即无需声明,可

  • C语言中函数的声明、定义及使用的入门教程

    对函数的"定义"和"声明"不是一回事.函数的定义是指对函数功能的确立,包括指定函数名,函数值类型.形参及其类型以及函数体等,它是一个完整的.独立的函数单位.而函数的声明的作用则是把函数的名字,函数类型以及形参的类型.个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体.--谭浩强 ,<C程序设计>(第四版),清华大学出版社,2010年6月,p182 这段论述包含了许多概念性错误,这

  • 区分C# 中的 Struct 和 Class

    翻译自 Manju lata Yadav 2019年6月2日 的博文 <Difference Between Struct And Class In C#>,补充了一些内容和示例. 结构体(struct)是类(class)的轻量级版本.结构体是值类型,可用于创建行为类似于内置类型的对象. 比较 结构体和类共享许多特性,但与类相比有以下局限性. 结构体不能有默认构造函数(无参构造函数)或析构函数,构造函数中必须给所有字段赋值. public struct Coords { public doub

  • 探讨C++中不能声明为虚函数的有哪些函数

    常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数. 多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层 函数不属于成员函数,是不能被继承的 2.为什么C++不支持构造函数为虚函数? 这个原因很简单,主要是从语义上考虑,所以不支持.因为构造函数本来就是为了

  • JavaScript中变量声明有var和没var的区别示例介绍

    本文来论述JavaScript中变量声明有var和没var的区别,关于Js中的变量声明的作用域是以函数为单位,所以我们经常见到避免全局变量污染的方法是 (function(){ // ... })(); 在函数内部,有var和没var声明的变量是不一样的.有var声明的是局部变量,没var的,声明的全局变量,所以可以借此向外暴露接口东东. 在全局作用域内声明变量时,有var 和没var看起来都一样,我们知道,声明的全局变量,就是window的属性,究竟是否一样,我们通过ECMAScrpit5提供

  • 浅谈javascript:两种注释,声明变量,定义函数

    JavaScript:单行注释用//呵呵呵呵:多行注释用/*hdhdhdh*/ javascript中区别大小写,定义变量使用关键字var,语法如下:var 变量名,其中变量从编程角度讲,变量是用于存储某种/某些数值的存储器. javascript函数调用: 以上就是小编为大家带来的浅谈javascript:两种注释,声明变量,定义函数全部内容了,希望大家多多支持我们~

  • ES6中箭头函数的定义与调用方式详解

    本文主要介绍的是关于ES6箭头函数的定义与调用方式的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 基本用法: ES6中允许使用"箭头"(=>)定义函数 var f = v => v; 上面代码相当于: var f = function( v ) { return v; } 根据箭头函数有参数和无参数来区分 1.无参数的箭头函数 var f = () => 5; 等同于 var f = function() { return 5}; 2.有参数的箭头函数 v

随机推荐