在c++中初始化指针

Initialization of pointers in c++

本文关键字:指针 初始化 c++      更新时间:2023-10-16

我需要澄清我关于C++中指针初始化基础的概念。根据我的理解,在使用指针放置一些值之前,必须为指针分配一个地址。

int *p;
*p=10; //inappropriate
cout << *p <<"n";

这可能会显示正确的输出(10(,但这可能会在较大的程序中引起问题,因为p最初有垃圾地址,可以是任何&以后也可以在程序中的其他地方使用。所以,我认为这是不正确的,正确的方法是:

int *p;
int x=10;
p=&x;  //appropriate
cout << *p <<"n";

我的问题是,如果上面的理解是正确的,那么同样的理解也适用于char*吗?:

const char *str="hello";  // inappropriate
cout << str << "n";
//OR
const string str1= "hello";
const char str2[6] ="world";
const char *str=str1;  //appropriate
const char *st=str2;  //appropriate
cout << str << st << "n";

请告知

您对字符串的理解是错误的。

让我们以第一行为例:

const char *str="hello";

这实际上是正确的。像"hello"这样的字符串文字被编译器转换为常量数组,和所有数组一样,它可以衰减为指向其第一个元素的指针。所以您要做的是使str指向数组的第一个字符。

然后让我们继续

const string str1= "hello";
const char *str=str1;

这实际上是错误的。std::string对象没有定义要强制转换为const char *的强制转换运算符。编译器会为此给您一个错误。您需要使用c_str函数来获取指向所包含字符串的指针。

最后:

const char str2[6] ="world";
const char *st=str2;  //appropriate

这与声明和初始化str时的第一行没有什么不同。正如你所说,这是"恰当的"。


关于第一个带有"不合适"指针的例子:

int *p;
*p=10; //inappropriate
cout << *p <<"n";

这不仅是"不合适的",还会导致未定义的行为,并可能导致程序崩溃。此外,正确的术语是p的值是不确定的。

当我声明一个指针时

int *p;

我得到一个对象p,其值为地址。任何位置都不会创建int。您需要做的是将p视为是一个地址,而不是int

在这一点上,这并不是特别有用,因为除了nullptr之外,您没有可以分配给它的地址。从技术上讲,这不是真的:p本身有一个地址,你可以用&p获得并将其存储在int**中,甚至可以做一些像p = reinterpret_cast<int*>(&p);这样可怕的事情,但我们忽略它。

要使用int执行某些操作,您需要创建一个。例如,如果你继续申报

int x;

您现在有一个值为整数的int对象,然后我们可以用p = &x;将其地址分配给p,然后通过*pp恢复该对象。


现在,C风格的字符串具有奇怪的语义—最奇怪的是,C实际上根本没有字符串:它总是使用char数组。

字符串文字,如"Hello!",保证(像它们一样操作1(作为位于某个地址的const char的数组存在,并且通过C的奇数转换规则,该数组自动转换为指向其第一个元素的指针。因此,

const char *str = "hello";

将CCD_ 26字符的地址存储在该字符阵列中。申报

const char str2[6] ="world";

工作方式不同;this(像它一样操作1(创建一个全新的数组,并将字符串文字"world"的内容复制到新数组中。

顺便说一句,为了与旧程序兼容,这里有一个过时和不推荐使用的功能,但由于一些被误导的原因,现在人们仍然在新程序中使用它,所以你应该意识到这一点,这是"错误的":你可以破坏类型系统并实际编写

char *str = "hello";

这不应该起作用,因为"hello"const char的数组,但标准允许这种特定于的用法。然而,实际上仍然不允许修改数组的内容。


1:根据"好像"规则,程序只需要表现得就好像我所描述的事情发生了一样,但如果你仔细查看汇编代码,事情发生的实际方式可能会大不相同。