我是 C++ 语言的新手,我正在尝试理解指针的概念。
我有一个关于 char 指针的基本问题,
我所知道的是指针是一个存储地址值的变量,所以当我这样写时:
char * ptr = "hello";
根据我的基本知识,我认为=
应该有一个地址分配给指针,但这里我们分配“hello”,它是一组字符。那是什么意思呢?
指针是否指向ptr
存储“hello”的地址?还是它本身存储你好?
我很困惑,希望你们能帮助我。。
提前致谢。
ptr
保存文字"hello"
存储的地址。在这种情况下,它指向一个字符串文字。它是位于静态(最常见的是只读)内存中的不可变字符数组。
您可以ptr
通过重新分配来指出其他内容,但在您这样做之前,修改内容是非法的。(它的类型实际上是const char*
,为了 C 兼容性,不推荐使用转换为char*
(在 C++11 中甚至是非法的)。
因为这个保证,编译器可以自由优化空间,所以
char * ptr = "hello";
char * ptr1 = "hello";
可能会产生两个相等的指针。(即ptr == ptr1
)
指针指向存储“hello”的地址。更准确地说,它指向“hello”中的“h”。
"hello"
是一个字符串文字:一个静态字符数组。像所有数组一样,如果在需要指针的上下文中使用它,它可以转换为指向其第一个元素的指针。
但是,数组是恒定的,因此将其分配给char*
(而不是const char*
)是一个非常糟糕的主意。如果您尝试使用该指针来修改字符串,您将得到未定义的行为(通常是访问冲突)。
编译器将“找到某个地方”它可以放置字符串"hello"
,并且ptr
将具有那个“某处”的地址。
char* text = "Hello!"
可以认为如下:
在程序启动时,您创建一个长度为 7 的字符数组:
{'H','e','l','l','o','!','\0'}
. 最后一个是空字符,表明它后面没有更多字符。[这比保持与字符串关联的计数更有效......对于 32 位整数,计数可能占用 4 个字节,而空字符只是一个字节,如果使用 Unicode 字符串则为两个字节. 另外,与必须同时管理一个字符数组和一个计数变量相比,拥有一个以空字符结尾的单个数组更容易混淆。]
创建数组和创建字符串常量之间的区别在于数组是可编辑的,而字符串常量(或“字符串文字”)不是。尝试在字符串文字中设置值会导致问题:它们是只读的。
然后,每当您调用语句时char* text = "Hello!"
,您都会获取该初始数组的地址并将其粘贴到变量text
中。请注意,如果你有这样的事情......
char* text1 = "Hello!";
char* text2 = "Hello!";
char* text3 = "Hello!";
...那么很可能您正在创建三个单独的数组{'H','e','l','l','o','!','\0'}
,因此这样做会更有效...
char* _text = "Hello!";
char* text1 = _text;
char* text2 = _text;
char* text3 = _text;
大多数编译器足够聪明,只能自动初始化一个字符串常量,但有些编译器只有在您手动打开某些优化功能时才会这样做。
另一个注意事项:根据我的经验,使用delete []
指向字符串文字的指针不会引起问题,但这是不必要的,因为据我所知它实际上并没有删除它。
当您通过为其分配字符串文字来创建新的 char* 时,会发生 char* 被分配文字的地址。所以 char* 的实际值可能是 0x87F2F1A6 (一些十六进制地址值)。char* 指向字符串的开头(在本例中为第一个字符)。在 C 和 C++ 中,所有字符串都以 /0 结尾,这是系统知道它已到达字符串末尾的方式。