我需要澄清有关C ++中指针初始化基础知识的概念。根据我的理解,在使用指针输入一些值之前,必须为指针分配一个地址。
int *p;
*p=10; //inappropriate
cout << *p <<"\n";
这可能会显示正确的输出(10),但这可能会导致较大的程序出现问题,因为p最初有垃圾地址,可以是任何&amp;以后可能会在程序的其他地方使用。所以,我认为这是不正确的,正确的方法是:
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";
请咨询
答案 0 :(得分:5)
您对字符串的理解不正确。
让我们以第一行为例:
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";
这不仅“不合适”,而且会导致undefined behavior并且实际上崩溃您的程序。另外,正确的术语是p
的值不确定。
答案 1 :(得分:1)
当我声明指针
时int *p;
我得到一个对象p
,其值为地址。在任何地方都不会创建int
。您需要做的是将p
视为是一个地址而不是是int
。
此时,这不是特别有用,因为除了nullptr
之外,您没有可以分配给它的地址。好吧,从技术上讲,这不是真的:p
本身有一个地址,您可以使用&p
将其存储在int**
中,甚至可以执行像p = reinterpret_cast<int*>(&p);
这样的恐怖事件,但是让我们忽略它。
要对int
执行某些操作,您需要创建一个。例如如果你继续宣布
int x;
您现在有一个int
对象,其值为整数,然后我们可以使用p
将其地址分配给p = &x;
,然后通过p
从*p
恢复对象char
。
现在,C样式字符串有奇怪的语义 - 最奇怪的是C 实际上根本没有字符串:它始终使用 "Hello!"
数组
字符串文字,如const char
,保证(像他们一样行动 1 )作为位于某个地址的const char *str = "hello";
数组,以及C的奇数转换规则存在,此数组自动转换为指向其第一个元素的指针。因此,
h
将const char str2[6] ="world";
字符的地址存储在该字符数组中。声明
"world"
工作方式不同;这个(行为 1 就像它一样)创建一个全新的数组,并将字符串文字char *str = "hello";
的内容复制到新数组中。
顺便说一下,这里有一个过时的和不赞成使用的功能,以便与遗留程序兼容,但由于一些误导的原因,人们现在仍然在新程序中使用它,所以你应该意识到它并且它是“错的”:你'允许打破类型系统并实际写
"hello"
这不应该有效,因为const char
是@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape)
OR
and (max-device-width : 1024px)
and (orientation : portrait){
}
的数组,但标准允许此特定的用法。但是,您实际上仍然不允许修改数组的内容。
1:通过“仿佛”规则,程序只需按照我所描述的那样行为就像事件发生一样,但是如果你偷看汇编代码,事情发生的实际方式可能是非常不同。