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

What is difference between char* and int* data type to create array of pointers in C++?

本文关键字:C++ 创建 数组 指针 int 数据类型 区别 什么 char      更新时间:2023-10-16

在为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

"字符串值"是指针可以指向的某物的地址,还是只是一个常量字符串

char *names[] = {"Mathew Emerson", "Bob Jackson"};

在C++是不合法的。 字符串文本具有const char[]的类型,因此将其存储为char*是非法的,因为它违反了常量正确性。 一些编译器允许它仍然编译为 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"};

"works"是,由于字符串文字是数组,它们隐式衰减到指针,所以

{"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"

这是一个字符数组,将在只读内存中实例化,作为程序引导的一部分。此字符数组称为字符串文本,特别是:

窄多字节字符串文本。不带前缀的字符串文本的类型是const char[]

NathanOliver的回答正确地描述了您的编译器没有将警告级别调得足够高,因此它允许const char[]衰减成char*。这是非常糟糕的,因为:

尝试修改字符串文字会导致未定义的行为:它们可能存储在只读存储(如.rodata)中或与其他字符串文字组合[1]

但是,这样做是完全合法和合乎逻辑的: const char *names[] = {"Mathew Emerson", "Bob Jackson"} 希望这能为您澄清正在发生的事情,足以让您了解使用字符串文本就是使用指针。你的代码: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&而不是char*