这是我的代码:
#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
.重新定义后,sum
是int
该函数范围内的类型标识符.因此,在函数内部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()
函数范围
范围很重要
sum
此处的函数名称具有全局范围.变量sum
是本地的,具有本地范围.
冲突是因为sum()
你内心的呼唤sum()
.现在在函数内部,sum()
你有2个同名和不同类型的对象,因此出错.
如果你有类似的东西
int sum()
{
int sum = 0;
sum = 10;
printf("%d\n",sum);
}
Run Code Online (Sandbox Code Playgroud)
然后你的代码就没事了.因为变量sum
是函数的局部变量sum()
,所以它是函数中唯一sum()
具有该名称的对象.
而不是担心这更好地重命名变量,并确保变量名称和函数名称是不同的