以下哪个声明是标准和首选?
int x = 7;
或者
int x(7);
int x(7);
不是在C中声明和初始化变量的有效方式;
我建议你买一本好书来学习 C 并使用一个好的编译器。
您已将此问题标记为 C 和 C++,但两者的答案并不完全相同。
在 C 中,int x(7);
根本行不通。它甚至不会编译。由于这种形式在 C 中根本不起作用,因此首选形式是int x = 7;
.
在 C++ 中,int x(7);
可以工作——但你必须小心,因为这种形式会导致“最麻烦的解析”;如果括号中的任何内容都可以解释为类型而不是值,则这将被解析为声明一个名为x
返回 an的函数,而不是使用括号中指定的值int
定义 an 。int
同样,如果您将括号留空:int x();
您最终会得到一个函数声明。
C++ 确实有另一种形式:int x{7};
. 有人称之为“通用初始化”。它确实消除了任何歧义——像T id { x };
where T
is a type这样的任何东西都必须是 a 的定义,id
并x
作为初始化程序。然而,有些人不喜欢这个,因为它引入了一些不同的语义——例如,在这种情况下禁止“缩小”转换,因此您不能盲目地更改现有代码以使用新形式。例如:
int x(12.34); // no problem
int y{ 12.34 }; // won't compile -- double -> int is a narrowing conversion
正如我上面显示的那样,这不太可能发生在文字上,但类似于:
void f(double x) {
int y(x);
// ...
...更有可能——但仍然不允许。
不幸的是,“回到”C 风格的初始化也不能解决所有可能的问题。至少在理论上,它确实复制初始化而不是直接初始化,因此您正在初始化的类型必须具有可用于执行此初始化的复制构造函数。例如:
class T {
T(T const &) = delete;
public:
T(int) {}
};
int main() {
T t = 1;
}
这不是官方允许的,因为它应该做的是用于T(int)
创建一个临时T
对象,然后用于从该临时对象T(T const &)
复制构造t
。由于我们已经删除了复制构造函数,因此(官方)不能使用它。这可能会特别令人困惑,因为几乎所有编译器通常都会在根本不使用复制构造函数的情况下完成这项工作,因此代码通常会编译并工作得很好——但是当你打开编译器尝试遵循的模式的那一刻尽可能接近标准,代码根本不会编译。
有些人发现“统一初始化”的变化如此令人反感,以至于他们建议完全不要使用它。就个人而言,我更喜欢使用它并简单地确保我没有进行任何缩小转换(或者如果无法避免缩小转换,则使用显式转换)。
在 c 种语言中,您通常使用 int x = 7;
一般来说
int x = 7;
是标准方式,也是 C 语言中唯一的方式。
但是,在 C++ 中,您可以使用 x(7) 来初始化 int,例如构造函数初始化程序列表,在这种情况下,您必须为正在以这种方式初始化的每个变量调用“构造函数”。对于原语,您可以使用 x(7) 语法来执行此操作。