我正在学习C,我正在学习各种功能。所以,我读到当我实现自己的函数时,我必须在main()之前声明它。如果我错过了声明,编译器将收到一条错误信息。
正如我正在研究这个例子(发现数字是否为素数)
#include <stdio.h>
void prime(); //function prototype(declaration)
int main()
{
int num,i,flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n",num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n",num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d",&n);
return n;
}
我注意到声明了一个函数prime(),但是在main中调用了函数input(),并且函数input()在底部实现。好的,我认为这是一个错误,我将名称从prime更改为输入。
但是如果我删除声明并且我没有放任何,那么程序编译时没有错误它运行顺利。 (我在Ubuntu中编译并运行它)
所以我的问题是,是否有必要声明一个没有参数的void函数?
答案 0 :(得分:4)
如果在使用地点之前没有函数的前向声明,编译器将为您创建隐式声明 - 使用签名int input()
- 它将采用您调用的函数的名称,它将假设函数返回int
并且它可以接受任何参数(如注释中所述的Bartek)。
对于此函数,隐式声明与真实声明匹配,因此您没有问题。但是,你应该总是小心这一点,并且你应该总是更喜欢前向声明而不是隐含声明(无论它们是否相同)。所以,不要只是向前声明void prime()
函数(假设你将在某处使用它),你还应该有int input()
的前向声明。
要了解如何传递任意数量的参数,请考虑以下事项:
#include <stdio.h>
// takes any number of the arguments
int foo();
// takes no arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// both works
// However, this will print junk as you're not pushing
// any arguments on the stack - but the compiler will assume you are
foo();
// this will print 1, 2, 3
foo(1, 2, 3);
// works
bar();
// doesn't work
// bar(1, 2, 3);
return 0;
}
// definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
所以,在你正在描述函数参数的函数的定义中。但是,该函数的声明告诉编译器不要对参数进行任何检查。
答案 1 :(得分:1)
不声明原型并依赖于默认参数/返回类型提升是危险的并且是旧C的一部分。在C99及以后在没有首先提供函数的声明或定义的情况下调用函数是非法的即可。
我的问题是,是否有必要声明一个没有参数的void函数?
是。为此,您必须将void
放在函数括号中。
void foo(void);
声明类似
的功能void foo();
表示它可以使用任意数量的参数。
答案 2 :(得分:0)
如果未使用prime,则省略声明。
代码不会编译为C ++,因为编译器会抱怨函数input
被使用但未声明。 C编译器可能会发出警告,但C更放松并且输入的隐式声明为int input()
,这意味着您可以将任何值传递给输入并输入返回一个int。
在使用该函数之前始终提供函数声明是一种很好的风格。只有当你这样做时,编译器才能看到你是否传递给很少,很多或错误输入的参数以及如何正确处理返回值(可能是short或char而不是int)。