void func() {assert(0);}
int main () {void func();}
上述代码没有调用func(),或者至少没有达到断言。虽然我不是非常需要知道,但我只是好奇,这里发生了什么?
void func() {assert(0);}
int main () {void func();}
你正在声明一个名为func
的函数原型,该函数不返回任何值且不接受参数。这是函数调用和函数原型之间微妙差别之一。请注意,在main
上面的那行代码:void func() {assert(0);}
,它对于这是原型还是调用没有影响。你可以删除它,代码仍然会执行相同的操作——也就是什么都不做。
这也告诉你可以重新声明函数原型。甚至可以这样:
int main() {
void blah();
void blah();
void blah();
void blah();
}
而且代码仍然会像以前一样——什么都不做。
如果省略void
,它将调用该函数。
此外,请注意,对于带参数的函数,以下内容:
int main() { func(4); }
如果你在函数前面加上void
,像这样:
它就不会转变成原型。
int main() { void func(4); }
它只会产生一个语法错误。
正如其他人指出的那样,这行代码
void func();
在C和C++中,main
内部被视为函数原型而不是对函数func
的调用。如果愿意,您可以在函数内部声明函数原型,但实际上很少这样做。
事实上,这种写法是合法的,但会给程序员带来各种问题。例如,如果您将代码重新编写为
(void) func();
func
的调用,其返回类型被显式地转换为void
,以表示“我不关心这个返回值”。换句话说,这组括号将声明变成了语句。Object myObject();
Object myObject(137);
Object myObject;
创建对象而不调用构造函数。
在尝试声明一个对象并调用它的构造函数时,语言存在一个令人不安的边缘情况,称为“最恼人的解析”。例如,下面的代码是合法的C++代码,但它是一个函数声明而不是变量声明:
set<int> mySet(istream_iterator<int>(cin), istream_iterator<int>());
istream_iterator<int>
作为参数的对象。为了解决这个问题,在C++中你需要写成:set<int> mySet(istream_iterator<int>(cin), (istream_iterator<int>()));
如上所述,额外的括号可以将语句从函数原型强制区分为声明。
希望这有帮助!
即使不必要,您也可以声明函数。这就是您所做的,重新声明了该函数。
main()
函数内声明一个本地函数 void func()
。
void
语句告诉编译器这是一个声明而不是函数调用。因此,去掉 void
,你的函数就会被调用。