Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的声明或定义_C_Declaration_Definition - Fatal编程技术网

C语言中的声明或定义

C语言中的声明或定义,c,declaration,definition,C,Declaration,Definition,发件人: 如果extern关键字和 如果存在初始化值,则 语句可以是声明 或者一个定义。这取决于 编译器来分析 规划和决定 我无法完全理解这句话关于C的含义。例如,它是否意味着: int i; 不一定是一个声明,因为我一直假设到现在,但可以是一个定义,以及定义和声明的定义在同一网页上,没有双关语的意图 简言之,上述陈述如下: A.只是一个声明,或者 B声明+定义 参考: 收到的答复摘要: 假设它在文件范围内,这是一个“暂定定义”。根据6.9.2/2外部对象定义: 具有不带初始值设定项的文件作用

发件人:

如果extern关键字和 如果存在初始化值,则 语句可以是声明 或者一个定义。这取决于 编译器来分析 规划和决定

我无法完全理解这句话关于C的含义。例如,它是否意味着:

int i;
不一定是一个声明,因为我一直假设到现在,但可以是一个定义,以及定义和声明的定义在同一网页上,没有双关语的意图

简言之,上述陈述如下: A.只是一个声明,或者 B声明+定义

参考:

收到的答复摘要:


假设它在文件范围内,这是一个“暂定定义”。根据6.9.2/2外部对象定义:

具有不带初始值设定项的文件作用域的对象的标识符声明,以及 如果没有存储类说明符或存储类说明符为static,则构成 暂定定义。如果翻译单元包含一个或多个暂定定义 标识符,并且翻译单元不包含该标识符的外部定义 该行为与翻译单元包含该转换单元的文件范围声明完全相同 标识符,复合类型在翻译单元末尾,带有初始值设定项 等于0

这意味着在翻译单元中也应包含以下内容:

int i = 42;
因为那个声明有一个显式的初始值设定项,所以它是变量i的定义

就声明是否在块范围内而言,标准规定了以下6.2.2/2标识符链接:

标识符的每个声明都带有 没有链接表示唯一的实体

第6段如下: 标识符没有链接:。。。A. 对象的块作用域标识符 声明时没有存储类 说明符extern


因此,在块范围内,声明也将是一个定义。

C标准说

标识符的定义是该标识符的声明:对于对象,导致为该对象保留存储

定义包含声明,也就是说,每个定义都必须是一个声明,所以这样说没有意义

int i;

这不是一个声明。这是一个声明,碰巧也是一个定义。或者,它是一个定义,因此是一个声明。

在变量上下文中:

变量声明是描述该变量外观的语句。因此:

extern int x;
在全局范围内转换为:在代码的某个地方,有一个名为x的变量,它具有int和extern类型的链接。在你提到x之前,必须有一个声明。函数声明也是如此

定义是创建此变量实例的语句。因此:

int x;
在全局作用域中,创建具有外部链接的int类型的单个变量。所以,如果你把这一行放在一个头文件中,每个翻译单元,包括这个头文件,都会试图创建它自己的x的副本,这是不可取的——这就是为什么我们只在头文件中声明。函数也是如此:如果提供函数体,它就是一个定义

此外,从形式上讲,每个定义都是一种声明,因为它还必须指定此变量/函数的外观-因此,如果给定范围中已经存在定义,则不需要任何其他声明即可使用它。

来自C99规范:

具有不带初始值设定项的文件作用域的对象的标识符声明,以及 如果没有存储类说明符或存储类说明符为static,则构成 暂定定义。如果翻译单元包含一个或多个暂定定义 标识符,并且翻译单元不包含该标识符的外部定义 该行为与翻译单元包含该转换单元的文件范围声明完全相同 标识符,复合类型在翻译单元末尾,带有初始值设定项 等于0

因此,在这种情况下,没有初始值设定项的简单声明可以是声明。

因为C使用以下术语:

一个定义创造了一些占用某种内存的东西。它还描述了一些事情。这意味着定义也是一种声明

声明只是描述了一些东西。其思想是编译器需要知道如何构建使用其他地方定义的东西的代码。随后,链接器将使用链接到某物


声明允许您编译代码并在以后作为单独的步骤链接它。

假设它在块而不是文件范围内…?@crypto:更新了答案以涵盖块范围声明。感谢您提供详细的答案。我选择了巴瓦尔
ious的回答更直接。@crypto:要记住的细节是看到int i;可能会给人一种印象,我被初始化为0-但可能不是这样。我现在在摘要中添加了这一点,如果不正确,请编辑它。您是否可以将您的答案附加到Michael的答案,因为您引用的是C99标准的同一部分?规范中的引用是关于编译器行为的。这意味着声明的这种特殊情况可能最终成为一个定义。ITYM是定义的最后一个词。然而,记住并非所有声明都是定义,这是一个好主意。
int x;