繁体   English   中英

在C ++中创建指针数组的char *和int *数据类型有什么区别?

[英]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情况的原因是“转换” intint*

(忽略其他答案中提到的常见问题......)

您编写的每个字符串文字( "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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM