Jay*_*y B 42 c++ arrays null initialization
我最近面临一行代码和四个选项:
Run Code Online (Sandbox Code Playgroud)char fullName[30] = {NULL};
A) 第一个元素被分配一个 NULL 字符。
B) 数组的每个元素都被赋值为 0 ( Zeroes )
C) 数组的每个元素都被赋值为 NULL
D) 数组为空。
我们选择的答案是选项 C,因为虽然数组仅使用单个 初始化NULL,但 C++ 使用NULL.
然而,我们的教授不同意,说答案是A,他说:
所以第一个元素是
NULL,当你显示它时,它会显示第一个元素,也就是NULL。
引文完整地显示了问题;没有提供其他信息。我很好奇哪个是正确的,如果有人能解释为什么所说的答案是正确的。
Hol*_*Cat 36
这个问题定义不明确,但选项 B 似乎是最正确的答案。
结果取决于NULL定义的准确程度,这取决于编译器(更准确地说,取决于标准库实现)。如果定义为nullptr,则代码将无法编译。(我认为没有任何主要的实现会这样做,但仍然如此。)
假设NULL未定义为nullptr,则必须将其定义为具有值的整数文字0(即0、 或0L或类似的东西),这使您的代码等效于char fullName[30] = {0};。
这将用零填充数组,因此选项 B 是正确答案。
通常,当您使用花括号括起来的列表初始化数组时,每个元素都会被初始化。如果您提供的初始值设定项少于元素数量,则其余元素将归零。
关于其余选项:
选项 C 不清楚,因为如果代码编译,则NULL等效于0,因此选项 C 可以认为等效于选项 B。
选项 A 是否有效取决于您如何解释它。如果这意味着其余元素未初始化,那么它是错误的。如果它没有指定剩余元素会发生什么,那么它就是一个有效的答案。
选项 D 完全错误,因为数组不能为“空”。
eer*_*ika 21
Run Code Online (Sandbox Code Playgroud)char fullName[30] = {NULL};
这是永远不应该写的东西。
NULL是一个扩展为空指针常量的宏。一个字符——而不是一个指针——在这里被初始化,所以使用NULL.
碰巧一些空指针常量也是值为 0 的整数文字(例如 0 或 0L),如果NULL扩展到这样的文字,那么尽管滥用NULL. 宏扩展到的确切内容由语言实现定义。
如果NULL相反扩展为一个空指针常量,它不是整数文字,例如nullptr- 这是完全可能的 - 那么程序是格式错误的。
NULL根本不应该用 C++ 编写,即使是初始化指针。它的存在是为了与 C 向后兼容,以便更容易地将 C 程序移植到 C++。
现在,让我们假设NULL在这个特定的 C++ 实现上,它恰好扩展为整数文字。
示例中没有分配任何内容。分配是对预先存在的对象进行的操作。在这里,数组正在初始化。
数组的第一个元素用零字面量初始化。其余元素是值初始化的。两者都导致空字符。因此,整个数组将填充空字符。
一个简单而正确的写法是:
char fullName[30] = {};
Run Code Online (Sandbox Code Playgroud)
除了关于“赋值”的措辞之外,B 和 C 同样接近正确。他们没有提到值初始化,但至少结果是一样的。A 也没有错,虽然它不完整,因为它没有描述其余元素是如何初始化的。
如果将“空”解释为“不包含任何元素”,则 D 不正确,因为该数组包含 30 个元素。如果将其解释为“包含空字符串”,则 D 将是正确答案。
Ast*_*ngs 10
你几乎是正确的。
教授说的不对。确实显示首先完成NULL(当使用某些方法时),但这并没有说明数组其余部分的值,无论如何都可以简单地检查。
[dcl.init/17.5]:: [..]第 i 个数组元素使用 x i进行复制初始化,每个 1 ?一世 ?k,并为每个 k < i 进行值初始化?n. [..]
然而,没有一个选项是严格正确和措辞良好的。
发生的情况是 NULL 用于初始化第一个元素,而其他元素被零初始化。最终结果实际上是选项 B。
问题是,如果在您的平台上NULL定义为类型表达式std::nullptr_t(它不是,但允许),则该示例甚至无法编译!
NULL 是一个指针,而不是一个数字。从历史上看,可以在一定程度上混合和匹配这两件事,但 C++ 近年来试图加强这一点,您应该避免混淆界线。
更好的方法是:
char fullName[30] = {};
Run Code Online (Sandbox Code Playgroud)
最好的方法是:
std::string fullName;
Run Code Online (Sandbox Code Playgroud)