[英]What is difference between char* and int* data type to create array of pointers in C++?
在为int
数据类型创建指针数组时,以下代码可以正常工作:
int var[] = {10, 100, 200, 1000};
int *ptr[] = {&var[0], &var[1], &var[2], &var[3]};
在为char
数据类型创建指针数组时,以下是合法的:
char *names[] = {"Mathew Emerson", "Bob Jackson"};
但是,如果我为int
数据类型创建一个指针数组,如下所示:
int var[] = {10, 100, 200, 1000};
int *ptr[] = {var[0], var[1], var[2], var[3]};
我收到编译器错误。 我理解为什么我在上面的int
数据类型数组声明方法中得到一个编译错误,因为var [i]不是对指针必须指向的变量的引用,即它的地址,但不应该我在我的char
指针数组的声明中也会得到相同逻辑的错误。
它在char
数组指针中可以接受的原因是什么?
“ 字符串值 ”是指针指向的某个地址,还是只是一个const字符串值。
char *names[] = {"Mathew Emerson", "Bob Jackson"};
在C ++中不合法。 字符串文字的类型为const char[]
因此将其存储为char*
是违法的,因为它违反了const-correctness。 一些编译器允许它仍然作为C的遗留编译,因为字符串文字具有char[]
类型,但它不是标准C ++。 如果你打开编译器上的警告,你应该得到一些东西
main.cpp: In function 'int main()':
main.cpp:5:53: warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
char *names[] = {"Mathew Emerson", "Bob Jackson"};
如果你想要一个字符串数组,那么我建议你使用std::string
类的
std::string names[] = {"Mathew Emerson", "Bob Jackson"};
原因
char *names[] = {"Mathew Emerson", "Bob Jackson"};
“作品”是因为字符串文字是数组,所以它们隐含地衰减为指针
{"Mathew Emerson", "Bob Jackson"}
变
{ address_of_first_string_literal, address_of_second_string_literal}
然后用于初始化数组中的指针。
int *ptr[] = {var[0], var[1], var[2], var[3]};
无法工作,因为var[N]
是对数组中int
的引用,而不是指针。
“Mathew Emerson”是const char*
类型 - 它已经是一个指针,因此你可以直接将它存储在一个指针数组中。 你需要&
int情况的原因是“转换” int
到int*
。
(忽略其他答案中提到的常见问题......)
您编写的每个字符串文字( "Mathew Emerson"
, "Bob Jackson"
,......)稍后需要在编译代码中存储一些位置。
好像你已经写过某个地方了
char const[] MathewEmerson = { 'M', 'a', /*...*/, 'o', 'n', 0 };
所以你可以构造你的char const *数组,然后:
char const* names[] = { &MathewEmerson[0], /*...*/ };
至于数组,数组本身的地址和它的第一个元素是相同的,并且数组被隐含地转换为指针,你可以改为编写
char const* names[] = { MathewEmerson, /*...*/ };
如果您使用字符串文字,所有这些都是隐含的。
同样,你可以写:
int *ptr[] = {var, &var[1], &var[2], &var[3]};
(注意: var
,而不是第一项的&var[0]
)如果我们走得更远,甚至:
int *ptr[] = {var, var + 1, var + 2, var + 3};
结果总是一样的。 可读性,一种变体与另一种变体的可理解性? 好吧,另一个话题......
你对这个代表的解释包含了你的误解: "Mathew Emerson"
这是一个字符数组,它们将作为程序引导的一部分在只读存储器中实例化。 这个字符数组称为String Literal ,特别是:
窄多字节字符串文字。 未加前缀的字符串文字的类型是
const char[]
NathanOliver的回答正确地描述了你的编译器没有足够高的警告级别,所以它允许const char[]
衰减成char*
。 这非常糟糕,因为:
尝试修改字符串文字会导致未定义的行为:它们可能存储在只读存储(例如.rodata)中或与其他字符串文字结合[1]
然而,这样做是完全合法和合乎逻辑的: const char *names[] = {"Mathew Emerson", "Bob Jackson"}
希望能够为您澄清发生了什么,以便您理解使用String Literal 正在与一个指针。 你的代码: int *ptr[] = {var[0], var[1], var[2], var[3]}
然后是非法的,因为var[0]
是一个int&
而不是一个int*
。 这样做也是违法的: char* ptr = {names[0][0], names[0][1], names[0][2], names[0][3]}
这里的问题再次出现是因为我正在使用char&
s而不是char*
s。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.