这是我的代码:
#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;
}
我得到的错误是:
hello.c:11:5: error: called object type 'int' is not a function or function pointer
sum(x,size);
~~~^
答案 0 :(得分:12)
您在此处更改了sum
的含义:
int sum = 0;
从现在开始,在声明它的范围内,sum
是int
,这变得无稽之谈:
sum(x,size); /* Wat? sum is an int!!! */
不要这样做,你的代码将编译。编译完成后,您可以担心停止递归。
答案 1 :(得分:11)
如果为同一名称空间中的不同实体定义两个相同名称的单独标识符,它们可能会重叠。 C11
标准,章节§6.2.1陈述,
如果标识符指定同名的两个不同实体 空间,范围可能会重叠......
参考脚注:为什么在这种情况下,sum
都在同一个名称空间
因此,一旦您重新定义标识符与其他类型,
....如果是这样,一个实体的范围(内部范围)将结束 严格地在另一个实体的范围之前(外部范围)。在内部范围内,标识符指定在内部范围内声明的实体;在外部范围内声明的实体在内部范围内是隐藏(并且不可见)。
这意味着,在您的情况下,在内部函数sum()
中,当您定义int sum
时,基本上您正在隐藏函数 sum
。重新定义后,sum
是函数范围中int
类型的标识符。因此,在函数sum()
内,您无法调用sum()
,因为它现在是int
类型。
但是,FWIW,sum()
(或者更确切地说,在main()
之外)对sum()
的调用应该是有效的,因为此时int sum
将是int sum
超出范围。
解决方案:将sum()
变量名更改为其他名称。
感谢 @pmg 进行更正
编辑:
正如前面提到的in the other answer by @juanchopanza,在更改 shadowing 变量名后,您的程序将进行编译,一旦您运行它,您将面临infinite recursion由于无条件调用sum()
内的return
。您需要添加一些 break 条件以结束递归(C11
)。
脚注:
参考sum()
,章节§6.2.3,名称空间,我们可以说,有单独的名称空间< / em>用于各种类别的标识符,例如1)标签名称2)结构,联合和枚举的标签,3)结构或联合的成员和4)所有其他标识符。
因此,在这种特殊情况下,函数int sum
和sum()
定义将驻留在同一名称空间中,用于sum
函数范围 < / p>
答案 2 :(得分:6)
范围很重要
sum
具有全局范围。变量sum()
是本地的,具有本地范围。
冲突是因为您在sum()
内拨打sum()
。现在在函数int sum()
{
int sum = 0;
sum = 10;
printf("%d\n",sum);
}
内部,您有2个同名且不同类型的对象,因此出错。
如果您有类似
的内容sum
然后你的代码就好了。由于变量sum()
是函数sum()
的局部变量,因此它是函数 .form-group {
width:100%;
}
.input-group {
width:100%;
}
中唯一具有该名称的对象。
而不是担心这个更好地重命名变量并确保变量名称和函数名称不同
答案 3 :(得分:4)
您需要将int sum = 0
更改为int y = 0
,您的程序也会因为sum(x,sum)
答案 4 :(得分:2)
只需将总和功能中的变量总和名称更改为总计
#include <stdlib.h>
#include <stdio.h>
int sum(int,int);
int sum(int x, int size) {
int total = 0;
printf("%p\n", &x);
printf("%p\n", &size);
printf("%p\n", &total);
sum(x,size);
return 0;
}
int main() {
sum(2,4);
return 0;
}
答案 5 :(得分:1)
变量和函数具有相同的名称,这就是为什么它在引用函数和变量的同时导致错误的原因