Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.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 Extern声明在同一范围内遵循非Extern声明 #包括 外部INTX; int main() { int x; x=1; printf(“%d”,x); } #包括 int main() { 外部INTX; int x; x=1; printf(“%d”,x); }_C_Variables_Extern - Fatal编程技术网

C Extern声明在同一范围内遵循非Extern声明 #包括 外部INTX; int main() { int x; x=1; printf(“%d”,x); } #包括 int main() { 外部INTX; int x; x=1; printf(“%d”,x); }

C Extern声明在同一范围内遵循非Extern声明 #包括 外部INTX; int main() { int x; x=1; printf(“%d”,x); } #包括 int main() { 外部INTX; int x; x=1; printf(“%d”,x); },c,variables,extern,C,Variables,Extern,我正在学习extern关键字,有人告诉我extern这个词用于声明变量,编译器不会为此变量分配。 但是当我写两个代码时,第一个代码正常运行,第二个代码出错。 请帮我解释一下为什么会有这种差异。谢谢。同一范围内有冲突的声明 当extern intx时出现在函数外部,它在文件范围内声明x。然后,当intx出现在函数内部,它声明了一个新的x实例,该实例与先前的extern int x无关。这是C语言允许的,因此编译器不会对此抱怨 当extern intx时出现在函数内部,它在块范围内声明x。然后,当i

我正在学习
extern
关键字,有人告诉我
extern
这个词用于声明变量,编译器不会为此变量分配。 但是当我写两个代码时,第一个代码正常运行,第二个代码出错。 请帮我解释一下为什么会有这种差异。谢谢。

同一范围内有冲突的声明 当
extern intx时出现在函数外部,它在文件范围内声明
x
。然后,当
intx
出现在函数内部,它声明了一个新的
x
实例,该实例与先前的
extern int x无关。这是C语言允许的,因此编译器不会对此抱怨

extern intx时出现在函数内部,它在块范围内声明
x
。然后,当
intx出现在它之后,它试图在同一范围内声明不同的
x
。这是C标准不允许的,因此编译器会报告一个错误

extern
关键字在这里并不特别相关。错误是由相同标识符的两个冲突声明引起的。例如:

#include <stdio.h>

int main()
{
    extern int x;
    int x;
    x = 1;
    printf("%d", x);
}
关于声明的规则 由于C语言的发展历史,有关C语言声明的规则存在一些不规范之处。在文件范围内考虑这些声明:

char c;
int main(void)
{
    char d;

    int c; // Allowed, new declaration in new scope.
    int d; // Not allowed, conflicting declaration in same scope.
}
第一个声明做(或不做)几件事:

  • 它表示
    x
    int
    的标识符
  • 它表示
    x
    具有外部链接,这意味着可以(在对象模块链接期间)引用在其他地方声明的名为
    x
    的对象
  • 它不定义
    int
第二次声明:

  • 它表示
    x
    int
    的标识符
  • 它表示
    x
    具有外部链接(因为对于没有存储类说明符(如
    static
    external函数)的对象,external是默认的声明)
  • 它定义了一个
    int
    。(这实际上是一个暂定的定义,但我们在此不讨论。)
这两个声明都表示
x
int
的标识符,并且具有外部链接。它们之间的区别是第一个不定义对象(它只是说
x
是在其他地方定义的对象的名称),第二个定义了
int
(因此它是在其他地方定义的)。因此,这些声明不冲突,是允许的

另一方面,考虑函数中的这些声明。然后它们在块范围内

然后
extern intx
与上面的含义相同:
x
是一个标识符,具有在别处定义的对象的外部链接

但是
intx具有不同的含义。它不是说
x
有外部(或内部)链接,而是说
x
没有链接,因为块范围中的声明默认没有链接。这就产生了冲突,因为C 2018 6.7 3规定,除了带有特定条件的
typedef
名称和标签外,没有链接的标识符不得在同一范围内声明多次(以及名称空间,此处未提及)

范围 C有四种作用域:

  • 文件作用域用于函数之外的声明,并持续到正在编译的源文件的末尾
  • 块作用域用于函数内的声明,并持续到块结束(下面讨论)
  • 函数原型作用域用于函数原型参数中的声明。(例如,在
    void foo(int n,float a[n][n]);
    n
    a
    具有函数原型范围。)
  • 功能范围用于
    goto
    语句中使用的标签
复合语句是
{
}
中声明和语句的列表。每个复合语句都是一个块,它为声明创建一个新的作用域。一个函数的主体是一个复合语句,它是一个块,它可能有额外的复合语句在其中,每个语句都开始一个新的作用域

块也是由
switch
if
do
while
for
语句创建的,但它们对于前四个语句基本上不重要,因为只有
for
语句提供了进一步声明的机会。例如,在
For
语句中,您可以编写
For(int x=3;x<20;++x)
,这将创建
x
的一个新实例,因为
For
语句启动一个新块。

在同一范围内有冲突的声明 当
extern intx时出现在函数外部,它在文件范围内声明
x
。然后,当
intx
出现在函数内部,它声明了一个新的
x
实例,该实例与先前的
extern int x无关。这是C语言允许的,因此编译器不会对此抱怨

extern intx时出现在函数内部,它在块范围内声明
x
。然后,当
intx出现在它之后,它试图在同一范围内声明不同的
x
。这是C标准不允许的,因此编译器会报告一个错误

extern
关键字在这里并不特别相关。错误是由相同标识符的两个冲突声明引起的。例如:

#include <stdio.h>

int main()
{
    extern int x;
    int x;
    x = 1;
    printf("%d", x);
}
关于声明的规则 关于C声明的规则由于t而存在一些不规则之处
extern int x;
int x;