为什么C++变量是指针时不需要正确定义?

2024-05-12

我对 C++ 语言完全陌生(特别是指针,经验主要是 PHP),并且希望对以下内容进行一些解释(我已经尝试寻找答案)。

这两行代码如何能够在我的程序中完成完全相同的工作?第二行似乎违背了我迄今为止所学到和理解的关于指针的一切。

char disk[3] = "D:";

char* disk = "D:";

我如何能够初始化指向内存地址以外的任何内容的指针?不仅如此,在第二行中我也没有正确声明数组 - 但它仍然有效?


在 C 和 C++ 中初始化数组的常用方法是:

int a[3] = { 0, 1, 2 };
Aside: And you can optionally leave out the array bound and have it deduced from the initializer list, or have a larger bound than there are initializers:

int aa[] = { 0, 1, 2 };    // another array of three ints
int aaa[5] = { 0, 1, 2 };  // equivalent to { 0, 1, 2, 0, 0}  

对于字符数组,有一个特殊的规则,允许从字符串文字初始化数组,数组的每个元素都从字符串文字中相应的字符初始化。

您的第一个示例使用字符串文字"D:"因此数组的每个元素将被初始化为该字符串中的一个字符,相当于:

char disk[3] = { 'D', ':', '\0' };

(第三个字符是空终止符 https://en.wikipedia.org/wiki/Null-terminated_string,它隐式存在于所有字符串文字中)。

Aside: Here too you can optionally leave out the array bound and have it deduced from the string literal, or have a larger bound than the string length:

char dd[] = "D:";    // another array of three chars
char ddd[5] = "D:";  // equivalent to { 'D', ':', '\0', '\0', '\0'}  
Just like the aaa example above, the extra elements in ddd that don't have a corresponding character in the string will be zero-initialized.

你的第二个例子之所以有效,是因为字符串文字"D:"将由编译器输出并作为三个字符的数组存储在可执行文件中的某个位置。当可执行文件运行时,包含数组(和其他常量)的段将被映射到进程的地址空间。所以你的char*然后,指针被初始化为指向该数组的位置,无论它位于何处。从概念上讲,它类似于:

const char __some_array_created_by_the_compiler[3] = "D:";
const char* disk = __some_array_created_by_the_compiler;

由于历史原因(主要是constC) 早期不存在,使用非常量是合法的char*指向该数组,即使该数组实际上是只读的,因此 C 和第一个 C++ 标准允许您使用非常量char*指向字符串文字的指针,即使它引用的数组实际上是 const:

const char __some_array_created_by_the_compiler[3] = "D:";
char* disk = (char*)__some_array_created_by_the_compiler;

这意味着尽管看起来你的两个例子并不完全相同,因为这仅适用于第一个:

disk[0] = 'C';

对于第一个示例,它会更改数组的第一个元素。

对于第二个例子,它可能会编译,但结果是未定义的行为 https://en.wikipedia.org/wiki/Undefined_behavior,因为它实际上做的是修改第一个元素__some_array_created_by_the_compiler这是只读的。实际上,可能发生的情况是进程会崩溃,因为尝试写入只读内存页会引发分段错误。

重要的是要理解,C++ 中有很多东西(C 中甚至更多)编译器会很乐意编译它们,但在执行代码时会导致非常糟糕的事情发生。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么C++变量是指针时不需要正确定义? 的相关文章

随机推荐