变量和函数名称的范围

Kor*_*gay 8 c scope

这是我的代码:

#include <stdlib.h>
#include <stdio.h>

int sum(int,int);

int sum(int x, int size) {
    int sum = 0;
    printf("%p\n", &x);
    printf("%p\n", &size);
    printf("%p\n", &sum);
    sum(x,size);
    return 0;
}

int main() {
    sum(2,4);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

而我得到的错误是:

hello.c:11:5: error: called object type 'int' is not a function or function pointer
sum(x,size);
~~~^
Run Code Online (Sandbox Code Playgroud)

jua*_*nza 12

你改变了sum这里的含义:

int sum = 0;
Run Code Online (Sandbox Code Playgroud)

从现在开始,在声明它的范围内,sum是一个int,这变得无稽之谈:

sum(x,size); /* Wat? sum is an int!!! */
Run Code Online (Sandbox Code Playgroud)

不要这样做,你的代码将编译.编译完成后,您可以担心停止递归.


Sou*_*osh 11

如果为同一名称空间中的不同实体定义两个具有相同名称的单独标识符,则它们可能会重叠.C11标准,章节§6.2.1陈述,

如果标识符指定同一名称空间中的两个不同实体,则范围可能会重叠....

请参阅脚注:为什么在这种情况下,两者sum都在同一名称空间中

因此,一旦您使用其他类型重新定义标识符,

....如果是这样,一个实体(内部范围)的范围将严格地在另一个实体(外部范围)的范围之前结束.在内部范围内,标识符指定在内部范围内声明的实体; 在外部作用域中声明的实体在内部作用域内是隐藏的(并且不可见).

这意味着,基本上,在你的情况下,在你的内部函数中sum(),当你定义时int sum,基本上你正在影响函数 sum.重新定义后,sumint函数范围内的类型标识符.因此,在函数内部sum(),您无法调用,sum()因为它int现在是一个类型.

然而,FWIW,调用sum()main()(或者说,外界sum()本身)应该是有效的,因为在这一点上,int sum会超出范围.

解决方案:int sum变量名称更改为其他名称.

感谢@pmg进行更正

编辑:

正如@juanchopanza在另一个回答中提到,在更改了阴影变量名后,你的程序将编译,一旦你运行它,你将面临无限递归,因为无条件调用sum()内部sum()本身.您需要添加一些中断条件来结束(return从)递归.


脚注:

参考C11,章第6.2.3节,命名空间,我们可以说,有单独的命名空间为各种类别标识符,例如1)标签名称2)结构,联合和枚举的标签,3)结构的成员或工会和4)所有其他标识符.

因此,在这种特殊情况下,函数sum()int sum定义将驻留在相同的名称空间中,用于sum()函数范围

  • 原样,它基本上只是无偿的标准行情+最后两段. (2认同)

Gop*_*opi 6

范围很重要

  1. sum此处的函数名称具有全局范围.
  2. 变量sum是本地的,具有本地范围.

  3. 冲突是因为sum()你内心的呼唤sum().现在在函数内部,sum()你有2个同名和不同类型的对象,因此出错.

如果你有类似的东西

int  sum()
{
   int sum = 0;
   sum = 10;
   printf("%d\n",sum);
}
Run Code Online (Sandbox Code Playgroud)

然后你的代码就没事了.因为变量sum是函数的局部变量sum(),所以它是函数中唯一sum()具有该名称的对象.

而不是担心这更好地重命名变量,并确保变量名称和函数名称是不同的