为什么C ++变量不需要定义正确时,它的指针? [英] Why C++ variable doesn't need defining properly when it's a pointer?

查看:206
本文介绍了为什么C ++变量不需要定义正确时,它的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是完全新的C ++语言(尤其是三分球,经验主要是在PHP),他会喜欢一些解释以下(我试过寻找问题的答案)。

是如何code两线能够在我的程序做同样的工作吗?第二行似乎去反对一切我已经学会&放;到目前为止,了解有关指针。

字符盘[3] =D:

的char *磁盘=D:

我怎么能初始化一个指向不是一个内存地址其他什么吗?不仅如此,在第二行我不声明数组或者正确 - 但它仍然工作


解决方案

要初始化C和C ++的数组通常的方法是:

  int类型的[3] = {0,1,2};


旁白:你可以选择离开了数组边界,并把它从初始化列表推断,还是有较大的束缚之外还有初始化:

 INT AA [] = {0,1,2}; //三个整数另一个数组
INT AAA [5] = {0,1,2}; //相当于{0,1,2,0,0}


有关字符数组有字符串中从相应的字符被初始化的特殊规则,允许阵列从一个字符串进行初始化,与阵列的每个元素字面

您第一个例子使用字符串文字 D:这样的阵列中的每个元素将被初始化为从该字符串的字符,相当于:

 字符盘[3] = {'D',':','\\ 0'};

(第三个字符是空终结,这是隐式present在所有字符串)。


旁白:这里也可以选择离开了数组边界,并把它从字符串字面推测,或者具有比字符串长度较大的约束:

字符DD [] =D:; //三个字符另一个数组
炭DDD [5] =D:; //相当于{'D',':','\\ 0','\\ 0','\\ 0'}

就像上面的 AAA 例如, DDD 多余的元素没有在字符串中的相应字符将进行零初始化。

您第二个例子工程,因为字符串文字 D:将是由编译器输出和地方保存在执行为三个字符数组。可执行文件时运行包含阵列(和其他常量)将被映射到进程的地址空间的段。所以,你的的char * 指针然后初始化为指向数组中的位置,只要出现这种情况是。从概念上讲它类似于:

 为const char __some_array_created_by_the_compiler [3] =D:;
为const char *磁盘= __some_array_created_by_the_compiler;

由于历史原因(大部分是常量在C初期不存在),它是合法使用非const 字符* 来指向数组,即使数组实际上是只读的,所以C和第一个C ++标准允许你使用一个非const 的char * 指针指向一个字符串,即使它指的是阵列真的是const的:

 为const char __some_array_created_by_the_compiler [3] =D:;
字符*磁盘=(字符*)__ some_array_created_by_the_compiler;

这意味着,尽管显示你的两个例子是不完全一样的,因为这是只允许第一个:

 磁盘[0] ='C';

有关即行的第一个例子,它改变所述阵列的第一个元素

对于第二个示例可能编译,但它会导致未定义行为,因为它实际上做的是修改的 __ some_array_created_by_the_compiler 这是只读的第一个元素。在实践中究竟会发生很可能是该进程会崩溃,因为试图写入内存的只读页面会引发分割故障。

要明白,有很多用C事情是很重要++(甚至更多C),编译器会很乐意进行编译,但会导致执行code当发生非常糟糕的事情。

I'm completely new to the C++ language (pointers in particular, experience is mainly in PHP) and would love some explanation to the following (I've tried searching for answers).

How are both lines of code able to do exactly the same job in my program? The second line seems to go against everything I've learnt & understood so far about pointers.

char disk[3] = "D:";

char* disk = "D:";

How am I able to initialize a pointer to anything other than a memory address? Not only that, in the second line I'm not declaring the array properly either - but it's still working?

解决方案

The usual way to initialize an array in C and C++ is:

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}

For arrays of characters there is a special rule that allows an array to be initialized from a string literal, with each element of the array being initialized from the corresponding character in the string literal.

Your first example uses the string literal "D:" so each element of the array will be initialized to a character from that string, equivalent to:

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

(The third character is the null terminator, which is implicitly present in all string literals).

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.

Your second example works because the string literal "D:" will be output by the compiler and stored somewhere in the executable as an array of three chars. When the executable is run the segment that contains the array (and other constants) will be mapped into the process' address space. So your char* pointer is then initialized to point to the location of that array, wherever that happens to be. Conceptually it's similar to:

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

For historical reasons (mostly that const didn't exist in the early days of C) it was legal to use a non-const char* to point to that array, even though the array is actually read-only, so C and the first C++ standard allow you to use a non-const char* pointer to point to a string literal, even though the array that it refers to is really const:

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

This means that despite appearances your two examples are not exactly the same, because this is only allowed for the first one:

disk[0] = 'C';

For the first example that is OK, it alters the first element of the array.

For the second example it might compile, but it results in undefined behaviour, because what it's actually doing is modifying the first element of the __some_array_created_by_the_compiler which is read-only. In practice what will probably happen is that the process will crash, because trying to write to a read-only page of memory will raise a segmentation fault.

It's important to understand that there are lots of things in C++ (and even more in C) which the compiler will happily compile, but which cause Very Bad Things to happen when the code is executed.

这篇关于为什么C ++变量不需要定义正确时,它的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆