sbi*_*sbi 824
甲声明引入的标识符和描述了它的类型,无论是类型,对象,或功能.声明是编译器接受对该标识符的引用所需的.这些是声明:
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
Run Code Online (Sandbox Code Playgroud)
甲定义实际实例化/实现此标识符.这是链接器将引用链接到这些实体所需的内容.这些是与上述声明相对应的定义:
int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};
Run Code Online (Sandbox Code Playgroud)
可以使用定义来代替声明.
可以根据需要随时声明标识符.因此,以下内容在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);
Run Code Online (Sandbox Code Playgroud)
但是,它必须只定义一次.如果您忘记定义已在某处声明和引用的内容,则链接器不知道链接引用的内容和抱怨缺少的符号.如果您多次定义某些内容,则链接器不知道将哪些定义链接引用并抱怨重复的符号.
由于辩论什么是C++中的类声明与类定义不断出现(对其他问题的答案和评论),我将在此处粘贴C++标准的引用.
在3.1/2,C++ 03说:
声明是一个定义,除非它是一个类名声明[...].
3.1/3然后举几个例子.其中包括:
[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b [...]
struct S; // declares S
—end example
概括起来:C++标准认为struct x;是一个声明和struct x {};一个定义.(换句话说,"前向声明"用词不当,因为C++中没有其他形式的类声明.)
感谢litb(Johannes Schaub)在他的一个答案中挖出了实际的章节和经文.
Mic*_*fik 167
从C++标准3.1节:
一个声明引入名称转换翻译单元或redeclares先前声明引入的名称.声明指定了这些名称的解释和属性.
下一段说明(强调我的)声明是一个定义,除非......
...它声明了一个函数而没有指定函数的主体
void sqrt(double); // declares sqrt
Run Code Online (Sandbox Code Playgroud)
...它在类定义中声明了一个静态成员
struct X
{
int a; // defines a
static int b; // declares b
};
Run Code Online (Sandbox Code Playgroud)
...它声明了一个类名
class Y;
Run Code Online (Sandbox Code Playgroud)
...它包含extern没有初始值设定项或函数体的关键字
extern const int i = 0; // defines i
extern int j; // declares j
extern "C"
{
void foo(); // declares foo
}
Run Code Online (Sandbox Code Playgroud)
......或者是一个typedef或using声明.
typedef long LONG_32; // declares LONG_32
using namespace std; // declares std
Run Code Online (Sandbox Code Playgroud)
现在有一个重要原因,为什么理解声明和定义之间的区别很重要:一个定义规则.从C++标准的3.2.1节:
任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义.
pli*_*nth 131
声明:"某处,有一个foo."
定义:"......就在这里!"
Joh*_*itb 44
C++中有一些有趣的边缘情况(其中一些也在C中).考虑
T t;
Run Code Online (Sandbox Code Playgroud)
这可以是定义或声明,具体取决于类型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".
Run Code Online (Sandbox Code Playgroud)
在C++中,使用模板时,还有另一种边缘情况.
template <typename T>
struct X {
static int member; // declaration
};
template<typename T>
int X<T>::member; // definition
template<>
int X<bool>::member; // declaration!
Run Code Online (Sandbox Code Playgroud)
最后一个声明不是定义.它是静态成员的明确特化的声明X<bool>.它告诉编译器:"如果要实例化X<bool>::member,那么不要从主模板中实例化成员的定义,而是使用在别处找到的定义".要使其成为定义,您必须提供初始化程序
template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.
Run Code Online (Sandbox Code Playgroud)
ada*_*ost 33
宣言
声明告诉编译器存在程序元素或名称.声明将一个或多个名称引入程序.声明可以在程序中多次出现.因此,可以为每个编译单元声明类,结构,枚举类型和其他用户定义的类型.
定义
定义指定名称描述的代码或数据.必须先声明名称才能使用它.
Ste*_*sop 21
从C99标准来看,6.7(5):
声明指定一组标识符的解释和属性.标识符的定义是该标识符的声明:
从C++标准,3.1(2):
声明是一个定义,除非它声明一个函数而没有指定函数的主体,它包含extern说明符或者链接规范,既不是初始化器也不是函数体,它在类声明中声明了一个静态数据成员,它是一个类名声明,或者是typedef声明,using声明或using-directive.
然后有一些例子.
有趣的是(或者没有,但我对此感到有些惊讶),typedef int myint;是C99中的一个定义,但只是C++中的一个声明.
Mar*_*Gil 15
来自wiki.answers.com:
术语声明(在C中)表示您正在告诉编译器类型,大小和函数声明的情况,任何变量的参数的类型和大小,或程序中用户定义的类型或函数.没有空间保留在内存中声明的情况下,任何变量.但是,编译器知道在创建此类型的变量的情况下要保留多少空间.
例如,以下是所有声明:
extern int a;
struct _tagExample { int a; int b; };
int myFunc (int a, int b);
Run Code Online (Sandbox Code Playgroud)
另一方面,定义意味着除了声明所做的所有事情之外,空间也在内存中保留.你可以说"定义=声明+空间保留"以下是定义的例子:
int a;
int b = 0;
int myFunc (int a, int b) { return a + b; }
struct _tagExample example;
Run Code Online (Sandbox Code Playgroud)
见答案.
leg*_*s2k 12
因为我没有看到与C++ 11相关的答案.
声明是一个定义,除非它声明一个/ n:
enum X : int;template<typename T> class MyArray;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" { ... };class C { static int x; };struct Point;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
Run Code Online (Sandbox Code Playgroud)
定义 :
extern int a; // Declaration
int a; // Definition
a = 10 // Initialization
int b = 10; // Definition & Initialization
Run Code Online (Sandbox Code Playgroud)
定义将变量与类型相关联并分配内存,而声明仅指定类型但不分配内存。当您想在定义之前引用变量时,声明更有用。
*不要将定义与初始化混淆。两者都不同,初始化赋予变量值。请参阅上面的示例。
下面是一些定义的例子。
int a;
float b;
double c;
Run Code Online (Sandbox Code Playgroud)
现在函数声明:
int fun(int a,int b);
Run Code Online (Sandbox Code Playgroud)
注意函数末尾的分号,所以它表示它只是一个声明。编译器知道程序中的某个地方将使用该原型定义该函数。现在,如果编译器得到一个像这样的函数调用
int b=fun(x,y,z);
Run Code Online (Sandbox Code Playgroud)
编译器会报错说没有这个函数。因为它没有该函数的任何原型。
请注意两个程序之间的区别。
方案一
#include <stdio.h>
void print(int a)
{
printf("%d",a);
}
main()
{
print(5);
}
Run Code Online (Sandbox Code Playgroud)
在此,print 函数也被声明和定义。由于函数调用是在定义之后进行的。现在看下一个程序。
方案二
#include <stdio.h>
void print(int a); // In this case this is essential
main()
{
print(5);
}
void print(int a)
{
printf("%d",a);
}
Run Code Online (Sandbox Code Playgroud)
这是必不可少的,因为函数调用在定义之前,所以编译器必须知道是否有任何这样的函数。所以我们声明了将通知编译器的函数。
定义 :
定义函数的这部分称为定义。它说明在函数内部做什么。
void print(int a)
{
printf("%d",a);
}
Run Code Online (Sandbox Code Playgroud)
要理解名词,让我们首先关注动词。
宣布- 正式宣布;宣布
定义- 清楚而完整地展示或描述(某人或某物)
所以,当你声明一些东西时,你只需告诉它是什么。
// declaration
int sum(int, int);
Run Code Online (Sandbox Code Playgroud)
这一行声明了一个被调用的 C 函数sum,它接受两个类型的参数int并返回一个int. 但是,您还不能使用它。
当您提供它的实际工作方式时,这就是它的定义。
// definition
int sum(int x, int y)
{
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
350630 次 |
| 最近记录: |