定义和声明之间有什么区别?


857

两者的含义使我难以理解。


91
@Lasse:不是。一个定义既定义又声明;-)
Steve Jessop

13
坦白说,我在学习时遇到了很多麻烦,因此我没有找到明显的名字。我对含义没有任何疑问,只是将哪些名称与含义相关联。
David Thornley 2009年

6
不过,这并不是一个重复的问题,因为它询问的是C / C ++,而另一个问题通常询问的是所有语言,或者没有。它只是有重复的答案(因为在另一个问题中,有些答案选择忽略除C和/或C ++之外的所有语言)。
史蒂夫·杰索普

5
@DavidThornley我使用这个技巧:定义给出了给定变量或函数的更好描述。为了记住这一点,我记得“定义”一词的中间与“更细”一词相似。:)
Marco Leogrande,2012年

4
这个问题多少令人惊讶。只是说明这种语言有多少被误解了,这些误解是如何经常传播的。真的很伤心。
Lightness Races in Orbit

Answers:


858

声明引入的标识符和描述了它的类型,无论是类型,对象,或功能。声明是编译器需要接受对该标识符的引用的内容。这些是声明:

extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations

定义实际实例化/器具该标识符。这是链接器将链接引用链接到那些实体所需要的。这些是与上述声明相对应的定义:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

可以在定义的地方使用定义。

可以根据需要多次声明标识符。因此,以下内容在C和C ++中是合法的:

double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);

但是,必须定义一次。如果忘记定义已在某处声明和引用的内容,则链接器将不知道将引用链接到什么内容,并且会抱怨缺少符号。如果定义不止一次,则链接器将不知道要将引用链接到哪个定义中,并抱怨重复的符号。


由于关于C ++中的类声明和类定义的争论一直在不断出现(在其他问题的答案和注释中),因此我将在此处粘贴C ++标准的引号。
在3.1 / 2,C ++ 03表示:

声明是定义,除非它是类名声明。

3.1 / 3然后给出一些例子。其中:

[示例:[...]
结构S {int a; int b; }; //定义S,S :: a和S :: b [...]
结构S; //声明S
-结束示例

概括起来:C ++标准认为struct x;是一个声明struct x {};一个定义。(换句话说,“前向声明”是不正确的用词,因为C ++中没有其他形式的类声明。)

感谢litb(Johannes Schaub)在他的答案之一中挖掘了实际的章节。


2
@未知:您的编译器因您复制错误的sbi代码而损坏。例如,N1124中的6.7.2(2):“引用同一对象或函数的所有声明都应具有兼容的类型;否则,行为是未定义的。”
史蒂夫·杰索普

4
@Brian:“ extern int i;” 说我在某个地方是个int,不用担心。“我!” 表示i是一个int,其地址和范围在此处确定。
David Thornley 2009年

12
@布莱恩:你错了。extern int i是声明,因为它只是引入/指定iextern int i每个编译单元中可以有任意多个。int i但是,这是一个定义。它表示该转换单元中整数的空间,并建议链接器i将此实体的所有引用链接到该实体。如果您定义的定义多于或少于这些定义之一,则链接器将发出投诉。
2009年

4
int i;文件/全局作用域或函数作用域中的@Brian 都是C和C ++中的定义。在C中,因为它分配存储,在C ++中,因为它没有外部说明符或链接规范。这些相当于同一件事,即sbi所说的:在两种情况下,此声明都指定该范围内所有对“ i”的引用都必须链接到的对象。
史蒂夫·杰索普

4
@未知,当心您不能在范围内重新声明成员:struct A { double f(int, double); double f(int, double); };当然是无效的。虽然允许在其他地方。在某些地方您可以声明事物,但也不能定义它们:void f() { void g(); }有效,但不能定义以下内容:void f() { void g() { } };。关于模板,定义是什么,声明有微妙的规则-请当心!+1虽然是个不错的答案。
Johannes Schaub-litb

168

从C ++标准第3.1节开始:

一个声明介绍名称到由先前的声明引入了一个翻译单元或redeclares名称。声明指定这些名称的解释和属性。

下一段指出(强调我的意思)声明是一个定义,除非...

...它在不指定函数主体的情况下声明了一个函数:

void sqrt(double);  // declares sqrt

...它在类定义中声明了一个静态成员:

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

...它声明了一个类名:

class Y;

...它包含extern没有初始化程序或函数体的关键字:

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

...或为typedefor using陈述式。

typedef long LONG_32;  // declares LONG_32
using namespace std;   // declares std

现在,出于重要原因,理解声明和定义之间的区别非常重要:“ 一个定义规则”。从C ++标准的3.2.1节开始:

任何变量,函数,类类型,枚举类型或模板的翻译单元均不得包含一个以上的定义。


“在类定义中声明静态成员”-这是正确的,即使静态成员已初始化,对吗?我们可以举个例子struct x {static int b = 3; };吗?
RJFalconer 2014年

@RJFalconer你是对的;初始化并没有必然把一个声明为定义(相反的是人们可能预期;当然,我发现这个惊人的)。除非b另外声明,否则对示例的修改实际上是非法的const。请参阅stackoverflow.com/a/3536513/1858225daniweb.com/software-development/cpp/threads/140739/…
Kyle Strand

1
这对我来说很有趣。根据您的回答,似乎在C ++中,声明也是一个定义(带有例外),而在C标准中,它是从另一个角度来表达的(C99,第6.7节,声明):“ 标识符的定义是该标识符的声明:[后接不同情况的标准]”。我想有不同的观察方式。:)
Victor Zamanian

声明是为了让编译器接受一个名称(告诉编译器该名称是合法的,引入该名称的目的不是拼写错误)。定义是名称及其内容的关联位置。链接器使用该定义将名称引用链接到名称内容。
Gab是好人2016年

137

声明:“在某个地方,存在一个foo。”

定义:“ ...就在这里!”


3
声明是为了让编译器接受一个名称(告诉编译器该名称是合法的,引入该名称的目的不是拼写错误)。定义是名称及其内容的关联位置。链接器使用该定义将名称引用链接到名称内容。
Gab是好人2016年

46

在C ++中有一些有趣的极端情况(在C中也有一些)。考虑

T t;

根据类型T是什么,可以是定义或声明:

typedef void T();
T t; // declaration of function "t"

struct X { 
  T t; // declaration of function "t".
};

typedef int T;
T t; // definition of object "t".

在C ++中,使用模板时,还有另一种情况。

template <typename T>
struct X { 
  static int member; // declaration
};

template<typename T>
int X<T>::member; // definition

template<>
int X<bool>::member; // declaration!

最后的声明不是定义。这是的静态成员的显式专业化的声明X<bool>。它告诉编译器:“如果要实例化X<bool>::member,则不要实例化主模板中成员的定义,而要使用在其他地方找到的定义”。要定义它,您必须提供一个初始化程序

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.

35

宣言

声明告诉编译器程序元素或名称存在。声明将一个或多个名称引入程序。声明可以在程序中多次出现。因此,可以为每个编译单元声明类,结构,枚举类型和其他用户定义的类型。

定义

定义指定名称描述的代码或数据。必须先声明一个名称,然后才能使用它。


嗯,难道您甚至可以在每个编译单元中定义类和枚举吗?至少我将类定义放入标头中,并将其全部包含在内。嗯,class foo {}; 一个类定义,不是吗?
2009年

1
是。但是,“ foo类”;是一个声明。它告诉编译器foo是一个类。“类foo {};” 是一个定义。它告诉编译器foo类到底是什么。
David Thornley

1
类成员名称是个例外,可以在声明它们之前使用它们。
Johannes Schaub-litb

1
是的,这就是我的意思。因此,您可以执行以下操作:struct foo {void b(){f(); } void f(); },即使尚未声明f也是可见的。也可以使用以下代码:struct foo {void b(int = bar()); typedef int bar; };。在“所有函数体,默认参数,构造函数ctor-initializers”中进行声明之前就可以看到它。不在返回类型中:(
Johannes Schaub-litb

1
@litb:在声明之前不可见,只是标识符的使用移到了声明后面。是的,我知道,在很多情况下效果都是一样的。但是,并非所有情况都如此,这就是为什么我认为我们应该使用精确的解释。-糟糕,等等。在默认参数中可见吗?好吧,这肯定会破坏我的理解。该死!<
pouts

22

根据C99标准6.7(5):

声明指定一组标识符的解释和属性。标识符的定义是对该标识符的声明:

  • 对于一个对象,导致为该对象保留存储;
  • 对于功能,包括功能主体;
  • 对于枚举常量或typedef名称,是标识符的(唯一)声明。

根据C ++标准3.1(2):

声明是一个定义,除非它在不指定函数主体的情况下声明函数,它包含extern说明符或链接规范,并且既不包含初始化程序也不包含函数体,它在类声明中声明一个静态数据成员,它是一个类名声明,或者是typedef声明,using-声明或using-伪指令。

然后有一些例子。

有趣的是(或者不是,但是我对此有些惊讶)typedef int myint;是C99中的一个定义,但是只有C ++中的一个声明。


@onebyone:关于typedef,这是否意味着可以在C ++中重复但不能在C99中重复?
sbi

这让我感到惊讶,就单个翻译部门而言,是的,确实存在差异。但是很明显,typedef可以在C99中的不同翻译单元中重复。C没有像C ++这样的明确的“一个定义规则”,因此它确实有允许的规则。C ++选择将其更改为声明,但是一个定义规则列出了它适用于哪些类型的内容,而typedefs不是其中之一。因此,即使typedef是定义,在ODR下的C ++中也可以按其措辞重复。似乎不必要地挑剔。
史蒂夫·杰索普

...但是我想ODR中的列表实际上列出了可能具有定义的所有内容。如果是这样,则该列表实际上是多余的,仅对您有所帮助。
史蒂夫·杰索普

std的ODR定义对类定义有何看法?它们必须重复。
2009年

2
@sbi:ODR表示“(1)任何一个翻译单元不得包含一个以上任何...类类型的定义”和“(5)程序中可以有一个以上的类类型定义...每个定义出现在不同的翻译单元中”,然后有一些额外的要求,即“定义相同”。
史蒂夫·杰索普

17

从wiki.answers.com:

术语“声明”(在C语言中)表示您要告诉编译器有关类型,大小的信息,如果是函数声明,则是告诉程序的任何变量的参数的类型和大小,或程序中用户定义的类型或函数。没有空间保留在内存中声明的情况下,任何变量。但是,编译器知道在创建此类型的变量的情况下要保留多少空间。

例如,以下是所有声明:

extern int a; 
struct _tagExample { int a; int b; }; 
int myFunc (int a, int b);

另一方面,定义意味着除了声明所做的所有事情之外,空间还保留在内存中。您可以说“ DEFINITION = DECLARATION + SPACE RESERVATION”是以下定义示例:

int a; 
int b = 0; 
int myFunc (int a, int b) { return a + b; } 
struct _tagExample example; 

参见答案


3
这也是错误的(尽管比其他方法更接近):struct foo {};定义,而不是声明。的声明foostruct foo;。因此,编译器不知道为foo对象保留多少空间。
2009年

1
@Marcin:sbi说“编译器知道在创建此类型的变量的情况下要保留多少空间”并不总是正确的。struct foo;是一个声明,但它不会告诉编译器foo的大小。我要补充一下,这struct _tagExample { int a; int b; };是一个定义。因此,在这种情况下,将其称为声明是令人误解的。当然,它是一个,因为所有定义都是声明,但是您似乎暗示它不是定义。它是_tagExample的定义。
史蒂夫·杰索普

1
@Marcin Gil:这意味着“答案” Wiki并不总是准确的。在这里,我不得不为错误信息投下赞成票。
David Thornley 2009年

1
我们了解到引用的adatapost是正确的,但(IMO)并未真正回答该问题。Marcin引用的是错误的。引用标准是正确的,并且可以回答问题,但是很难使标准成对。
史蒂夫·杰索普

1
@David Thornley-没问题:)这就是这个网站的意思。我们选择并验证信息。
Marcin Gil

13

C ++ 11更新

由于我看不到与C ++ 11相关的答案,所以这里是一个。

声明是定义,除非声明a / n:

  • 不透明的枚举- enum X : int;
  • 模板参数-T intemplate<typename T> class MyArray;
  • 参数声明-xy输入int add(int x, int y);
  • 别名声明- using IntVector = std::vector<int>;
  • 静态断言声明- static_assert(sizeof(int) == 4, "Yikes!")
  • 属性声明(实现定义)
  • 空声明 ;

上面的列表从C ++ 03继承的其他子句:

  • 函数声明- 添加int add(int x, int y);
  • 包含声明或链接说明符的外部说明符- extern int a;extern "C" { ... };
  • 类中的静态数据成员-x inclass C { static int x; };
  • 类/结构声明- struct Point;
  • typedef声明- typedef int Int;
  • 使用声明- using std::cout;
  • 使用指令- using namespace NS;

模板声明是声明。如果模板声明定义了函数,类或静态数据成员,则它也是定义。

我发现从标准中区分声明和定义的示例有助于我理解它们之间的细微差别:

// except one all these are definitions
int a;                                  // defines a
extern const int c = 1;                 // defines c
int f(int x) { return x + a; }          // defines f and defines x
struct S { int a; int b; };             // defines S, S::a, and S::b
struct X {                              // defines X
    int x;                              // defines non-static data member x
    static int y;                       // DECLARES static data member y
    X(): x(0) { }                       // defines a constructor of X
};
int X::y = 1;                           // defines X::y
enum { up , down };                     // defines up and down
namespace N { int d; }                  // defines N and N::d
namespace N1 = N;                       // defines N1
X anX;                                  // defines anX


// all these are declarations
extern int a;                           // declares a
extern const int c;                     // declares c
int f(int);                             // declares f
struct S;                               // declares S
typedef int Int;                        // declares Int
extern X anotherX;                      // declares anotherX
using N::d;                             // declares N::d


// specific to C++11 - these are not from the standard
enum X : int;                           // declares X with int as the underlying type
using IntVector = std::vector<int>;     // declares IntVector as an alias to std::vector<int>
static_assert(X::y == 1, "Oops!");      // declares a static_assert which can render the program ill-formed or have no effect like an empty declaration, depending on the result of expr
template <class T> class C;             // declares template class C
;                                       // declares nothing

6

定义:

extern int a;      // Declaration 
int a;             // Definition
a = 10             // Initialization
int b = 10;        // Definition & Initialization

定义将变量与类型相关联并分配内存,而声明仅指定类型但不分配内存。当您想在定义之前引用变量时,声明会更有用。

*不要将定义与初始化混淆。两者不同,初始化为变量赋值。参见上面的例子。

以下是一些定义示例。

int a;
float b;
double c;

现在函数声明:

int fun(int a,int b); 

注意函数末尾的分号,因此它说这只是一个声明。编译器知道在程序中的某个位置将使用该原型定义功能。现在,如果编译器得到函数调用,则如下所示

int b=fun(x,y,z);

编译器将抛出一个错误,指出没有该函数。因为它没有该功能的任何原型。

注意两个程序之间的区别。

程序1

#include <stdio.h>
void print(int a)
{
     printf("%d",a);
}
main()
{
    print(5);
}

在此,还将声明和定义打印功能。由于函数调用是在定义之后进行的。现在看下一个程序。

程序2

 #include <stdio.h>
 void print(int a); // In this case this is essential
 main()
 {
    print(5);
 }
 void print(int a)
 {
     printf("%d",a);
 }

这很重要,因为函数调用先于定义,因此编译器必须知道是否存在任何此类函数。因此,我们声明了将通知编译器的函数。

定义:

定义函数的这一部分称为“定义”。它说明了该函数内部的操作。

void print(int a)
{
    printf("%d",a);
}

2
int a; //declaration; a=10; //definition这是完全错误的。当谈论自动存储持续时间对象(在函数定义内声明的对象,未使用另一个存储类说明符(例如extern)声明的对象)时,它们始终是定义。
Joey Pabalinas

要理解的主要区别是,声明是说“某物存在于具有这些特征(类型等)的地方”,而定义是说“我是在声明具有这些特征的东西,在此还将其实例化为好。” 由于您不能像这样向前声明自动存储持续时间对象,因此它们将始终是定义。
Joey Pabalinas

除了我总是会忘记的一些怪异的typedef异常情况外,经验法则是,所有定义都是声明。考虑一下;当实例化某些东西时,还需要告诉编译器该东西存在并且其特征正确吗?
Joey Pabalinas

根据您的第一条评论更新了答案。但是我不同意这种评论“当实例化某些东西时,还需要告诉编译器该东西存在”。实例化时,我们并不总是指定lhs的类型。例如:a = 10。我们此处未指定任何“特征”。
SRIDHARAN

4

定义表示实际编写的函数,声明表示简单的声明函数,例如

void  myfunction(); //this is simple declaration

void myfunction()
{
 some statement;    
}

这是功能myfunction的定义


1
那类型和对象呢?
2013年

4

经验法则:

  • 一个声明告诉编译器如何解释在内存中变量的数据。每次访问都需要这样做。

  • 一个定义保留内存,使现有的变量。必须在第一次访问之前进行一次。


2
这仅适用于对象。那类型和功能呢?
Lightness Races in Orbit

4

要理解名词,让我们先关注动词。

宣布 -正式宣布;宣布

定义 -清晰,完整地显示或描述(某人或某物)

因此,当您声明某物时,您只需告诉它是什么

// declaration
int sum(int, int);

该行声明一个C函数sum,该函数接受两个类型的参数int并返回int。但是,您还不能使用它。

当您提供它的实际工作原理时,这就是它的定义。

// definition
int sum(int x, int y)
{
    return x + y;
}

3

要了解声明和定义之间的区别,我们需要查看汇编代码:

uint8_t   ui8 = 5;  |   movb    $0x5,-0x45(%rbp)
int         i = 5;  |   movl    $0x5,-0x3c(%rbp)
uint32_t ui32 = 5;  |   movl    $0x5,-0x38(%rbp)
uint64_t ui64 = 5;  |   movq    $0x5,-0x10(%rbp)
double   doub = 5;  |   movsd   0x328(%rip),%xmm0        # 0x400a20
                        movsd   %xmm0,-0x8(%rbp)

这仅仅是定义:

ui8 = 5;   |   movb    $0x5,-0x45(%rbp)
i = 5;     |   movl    $0x5,-0x3c(%rbp)
ui32 = 5;  |   movl    $0x5,-0x38(%rbp)
ui64 = 5;  |   movq    $0x5,-0x10(%rbp)
doub = 5;  |   movsd   0x328(%rip),%xmm0        # 0x400a20
               movsd   %xmm0,-0x8(%rbp)

如您所见,没有任何变化。

声明与定义不同,因为声明仅提供编译器使用的信息。例如,uint8_t告诉编译器使用asm函数movb。

看到:

uint def;                  |  no instructions
printf("some stuff...");   |  [...] callq   0x400450 <printf@plt>
def=5;                     |  movb    $0x5,-0x45(%rbp)

声明没有等效的指令,因为它没有要执行的内容。

此外,声明告诉编译器变量的范围。

可以说,声明是编译器用来建立变量的正确用法以及某些内存属于某个变量的时间的信息。


2

您能否用最笼统的术语陈述一下,即声明是没有分配存储空间的标识符,而定义实际上是从声明的标识符分配存储空间的?

一个有趣的想法-在类或函数与类型信息链接之前,模板无法分配存储。那么模板标识符是声明还是定义?由于未分配存储空间,因此应该是一个声明,而您只是在“模板化”模板类或函数。


1
您的定义本身并不是错误的,但是对于函数定义,“存储定义”总是显得笨拙。关于模板:这template<class T> struct foo;是模板声明,这也是template<class T> void f();。模板定义以相同的方式镜像类/函数定义。(请注意,模板名称不是类型函数名称。可以在此处看到的地方是无法将模板作为另一个模板的type参数传递。如果要传递模板而不是类型,则需要模板模板参数。 )
sbi

同意“存储定义”很尴尬,尤其是在函数定义方面。声明为int foo(),定义为int foo(){//此处有一些代码。我通常需要用我熟悉的概念来包裹我的小脑筋-“存储”是至少可以直接让我知道的一种方法::)

2

在此处找到类似的答案:C中的技术面试问题

一个声明提供了一个名称的程序; 一个定义提供了一个实体的程序内的唯一的描述(例如类型,实例和功能)。声明可以在给定范围内重复,它在给定范围内引入名称。

声明是一个定义,除非:

  • 声明在不指定函数体的情况下声明了一个函数,
  • 声明包含一个外部说明符,没有初始化器或函数体,
  • 声明是没有类定义的静态类数据成员的声明,
  • 声明是一个类名定义,

定义是声明,除非:

  • 定义定义一个静态类数据成员,
  • 定义定义非内联成员函数。

1

这听起来真的很俗气,但这是我一直保持直觉的最好方式:

声明:图片Thomas Jefferson发表讲话……“我在此声明此源代码中存在此FOO!”

定义:想象一本字典,您正在查找Foo及其实际含义。


1

声明为编译器提供了符号名称。定义是为符号分配空间的声明。

int f(int x); // function declaration (I know f exists)

int f(int x) { return 2*x; } // declaration and definition

1

根据GNU C库手册(http://www.gnu.org/software/libc/manual/html_node/Header-Files.html

在C语言中,声明仅提供有关函数或变量存在并给出其类型的信息。对于函数声明,可能还会提供有关其参数类型的信息。声明的目的是允许编译器正确处理对声明的变量和函数的引用。另一方面,定义实际上是为变量分配存储空间或说明函数的功能。


0

使用extern存储类时,声明和定义的概念将成为一个陷阱,因为定义将位于其他位置,并且您在本地代码文件(页面)中声明变量。C和C ++之间的区别是,在C中,声明通常在函数或代码页的开头进行。在C ++中不是那样。您可以在自己选择的地方声明。


1
这使声明与定义混淆,这是错误的。
2015年

0

我最喜欢的示例是“ int Num = 5”,这里您的变量是1.定义为int 2.声明为Num,并且3.实例化为5。我们

  • 定义对象的类型,它可以是内置的,也可以是类或结构。
  • 声明一个对象的名称,因此已经声明了具有名称的任何内容,包括变量,函数等。

类或结构允许您更改以后使用对象时定义对象的方式。例如

  • 可以声明一个没有明确定义的异构变量或数组。
  • 在C ++中使用偏移量,可以定义一个没有声明名称的对象。

当我们学习编程时,这两个术语经常会混淆,因为我们经常同时做这两个事情。


我不明白为什么这么多人支持sbi的答案。我确实赞成bjhend的回答,它比我的回答好,简洁,准确且及时得多。我很伤心地看到,我是在4年这样做的第一人。
Jason K.

0

可执行文件生成的阶段:

(1)预处理器->(2)转换器/编译器->(3)链接器

在第2阶段(翻译器/编译器)中,代码中的声明语句告诉编译器我们将来将要使用的这些东西,您以后可以找到定义,其含义是:

译者确保:什么是什么?手段申报

(3)阶段(链接器)需要定义绑定事物

链接器确保:哪里是什么?手段定义


0

K&R(第二版)中散布着一些非常清晰的定义。它有助于将它们放在一个地方并作为一个地方阅读:

“定义”是指创建或分配变量的位置;“声明”是指声明变量性质但未分配存储空间的地方。[p。33]

...

区分外部变量的声明及其定义很重要。声明声明变量的属性(主要是其类型);定义也会导致存储被搁置。如果线路

int sp;
double val[MAXVAL]

出现在任何函数之外,它们定义外部变量spval,导致存储被搁置,并且还充当该源文件其余部分的声明。

另一方面,线条

extern int sp;
extern double val[];

为源文件的其余部分声明一个数组spint并声明valdouble数组(其大小在其他位置确定),但是它们不会创建变量或为其保留存储空间。

在组成源程序的所有文件中,外部变量的定义必须只有一个。...数组大小必须通过定义指定,但在extern声明时是可选的。[pp。80-81]

...

声明指定对每个标识符的解释;它们不一定保留与标识符关联的存储。保留存储的声明称为定义。[p。210]


-1

声明是指为变量指定名称和类型(在变量声明的情况下),例如:

int i;

或为没有主体的函数提供名称,返回类型和参数类型(在函数声明的情况下),例如:

int max(int, int);

而定义是指为变量赋值(在变量定义的情况下),例如:

i = 20;

或向功能提供/添加主体(功能)称为功能定义,例如:

int max(int a, int b)
{
   if(a>b)   return a;
   return b;  
}

许多时间的声明和定义可以一起完成:

int i=20;

和:

int max(int a, int b)
{
    if(a>b)   return a;
    return b;    
} 

在上述情况下,我们定义并声明变量ifunction max()


定义的实际平均值,如果将值/主体分配给变量/函数,而声明方法则为变量/函数提供名称,类型
Puneet Purohit 2013年

您可以定义某些东西而无需为其分配值。
Lightness Races in Orbit

1
就是这样:int x;
Lightness在Orbit比赛中的竞赛

它是变量x而不是定义的声明
Puneet Purohit

2
不,两者都是。您将定义与初始化混淆了。
Lightness Races in Orbit 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.