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

时间:2022-01-25 16:35:59

While creating an array of pointers for int data type the following code works:

在为int数据类型创建指针数组时,以下代码可以正常工作:

int var[] = {10, 100, 200, 1000};
int *ptr[] = {&var[0], &var[1], &var[2], &var[3]};

While creating an array of pointers for char data type the following is legal:

在为char数据类型创建指针数组时,以下内容是合法的:

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

But if I create an array of pointers for int data type as follows:

但是如果我为int数据类型创建一个指针数组,如下所示:

int var[] = {10, 100, 200, 1000};
int *ptr[] = {var[0], var[1], var[2], var[3]};

I get a compiler error. I understand why I am getting a compilation error in the above method of declaration for array of int data type, as var[i] is not a reference to a variable to which a pointer must point to i.e. its address, but shouldn't I also get error by the same logic in the declaration of my char array of pointer.

我收到编译器错误。我理解为什么我在上面的int数据类型数组声明方法中得到一个编译错误,因为var [i]不是对指针必须指向的变量的引用,即它的地址,但不应该我在我的char指针数组的声明中也会得到相同逻辑的错误。

What is the reason that its is acceptable in char array of pointers?

它在char数组指针中可以接受的原因是什么?

Is " a string value " an address of something to which a pointer can point to or is it just a const string value.

“字符串值”是指针指向的某个地址,还是只是一个const字符串值。

4 个解决方案

#1


7  

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

Is not legal in C++. A string literal has the type of const char[] so it is illegal to store it as a char* as it violates const-correctness. Some compilers allow this to still compile as a legacy from C since string literals have the type char[] but it is not standard C++. If you turn up the warnings on your compiler you should get something along the lines of

在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"};

If you want an array of strings then I suggest you use a std::string like

如果你想要一个字符串数组,那么我建议你使用std :: string之类的

std::string names[] = {"Mathew Emerson", "Bob Jackson"};

The reason

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

"works" is that since the string literals are arrays they implicitly decay to pointers so

“作品”是因为字符串文字是数组,所以它们隐含地衰减为指针

{"Mathew Emerson", "Bob Jackson"}

Becomes

{ address_of_first_string_literal, address_of_second_string_literal}

and then those are used to initialize the pointers in the array.

然后用于初始化数组中的指针。

int *ptr[] = {var[0], var[1], var[2], var[3]};

Cannot work because var[N] is a reference to the int in the array and not a pointer.

无法工作,因为var [N]是对数组中int的引用而不是指针。

#2


1  

"Mathew Emerson" is of type const char* - it is already a pointer, thus you can directly store it in an array of pointers. The reason you need & for the int case is to "convert" int to int*.

“Mathew Emerson”是const char *类型 - 它已经是一个指针,因此你可以直接将它存储在一个指针数组中。你需要和int情况的原因是“转换”int到int *。

#3


1  

(Ignoring the const-ness problem as mentioned in other answers...)

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

Each string literal you write ("Mathew Emerson", "Bob Jackson", ...) requires some storage location in the compiled code later.

您编写的每个字符串文字(“Mathew Emerson”,“Bob Jackson”,......)稍后需要在编译代码中存储一些位置。

It is as if you had written somewhere

就好像你曾在某处写过一样

char const[] MathewEmerson = { 'M', 'a', /*...*/, 'o', 'n', 0 };

So you you could construct your char const* array then as:

所以你可以构造你的char const *数组,然后:

char const* names[] = { &MathewEmerson[0], /*...*/ };

As for arrays, the address of the array itself and its first element is the same, and arrays are implicitely converted to pointers, you can write instead

至于数组,数组本身的地址和它的第一个元素是相同的,并且数组被隐含地转换为指针,你可以改为编写

char const* names[] = { MathewEmerson, /*...*/ };

All this is done implicitely for you, if you use string literals.

如果您使用字符串文字,所有这些都是对您有意义的。

Similarly, you could have written:

同样,你可以写:

int *ptr[] = {var, &var[1], &var[2], &var[3]};

(note: var, not &var[0] for the first item) and if we go further, even:

(注意:var,而不是第一项的&var [0])如果我们走得更远,甚至:

int *ptr[] = {var, var + 1, var + 2, var + 3};

The result always would have been the same. Readability, understandability of one variant vs another? Well, another topic...

结果总是一样的。可读性,一种变体与另一种变体的可理解性?好吧,另一个话题......

#4


1  

Your misconception is wrapped up in your interpretation of what is represented by: "Mathew Emerson"

你对你所代表的内容的解释包含了你的误解:“Mathew Emerson”

This is an array of characters that will be instantiated in read only memory as part of your program's bootstrapping. This array of characters is called a String Literal, specifically a:

这是一个字符数组,将作为程序引导的一部分在只读存储器中实例化。这个字符数组称为String Literal,特别是:

Narrow multibyte string literal. The type of an unprefixed string literal is const char[]

窄多字节字符串文字。未加前缀的字符串文字的类型是const char []

NathanOliver's answer correctly describes that your compiler doesn't have the warning level turned up high enough so it is allowing the, const char[] to decay into a char*. This is very bad because:

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

Attempting to modify a string literal results in undefined behavior: they may be stored in read-only storage (such as .rodata) or combined with other string literals[1]

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

It would have been completely legal and logical to do this however: const char *names[] = {"Mathew Emerson", "Bob Jackson"} Hopefully that clarifies for you what's happening well enough for you to understand that working with a String Literal is working with a pointer. Your code: int *ptr[] = {var[0], var[1], var[2], var[3]} is then illegal because, var[0] is an int& not an int*. It would be similarly illegal to do: char* ptr = {names[0][0], names[0][1], names[0][2], names[0][3]} Again the problem here would be that I was working with char&s not char*s.

然而,这样做是完全合法和合乎逻辑的: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。

#1


7  

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

Is not legal in C++. A string literal has the type of const char[] so it is illegal to store it as a char* as it violates const-correctness. Some compilers allow this to still compile as a legacy from C since string literals have the type char[] but it is not standard C++. If you turn up the warnings on your compiler you should get something along the lines of

在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"};

If you want an array of strings then I suggest you use a std::string like

如果你想要一个字符串数组,那么我建议你使用std :: string之类的

std::string names[] = {"Mathew Emerson", "Bob Jackson"};

The reason

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

"works" is that since the string literals are arrays they implicitly decay to pointers so

“作品”是因为字符串文字是数组,所以它们隐含地衰减为指针

{"Mathew Emerson", "Bob Jackson"}

Becomes

{ address_of_first_string_literal, address_of_second_string_literal}

and then those are used to initialize the pointers in the array.

然后用于初始化数组中的指针。

int *ptr[] = {var[0], var[1], var[2], var[3]};

Cannot work because var[N] is a reference to the int in the array and not a pointer.

无法工作,因为var [N]是对数组中int的引用而不是指针。

#2


1  

"Mathew Emerson" is of type const char* - it is already a pointer, thus you can directly store it in an array of pointers. The reason you need & for the int case is to "convert" int to int*.

“Mathew Emerson”是const char *类型 - 它已经是一个指针,因此你可以直接将它存储在一个指针数组中。你需要和int情况的原因是“转换”int到int *。

#3


1  

(Ignoring the const-ness problem as mentioned in other answers...)

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

Each string literal you write ("Mathew Emerson", "Bob Jackson", ...) requires some storage location in the compiled code later.

您编写的每个字符串文字(“Mathew Emerson”,“Bob Jackson”,......)稍后需要在编译代码中存储一些位置。

It is as if you had written somewhere

就好像你曾在某处写过一样

char const[] MathewEmerson = { 'M', 'a', /*...*/, 'o', 'n', 0 };

So you you could construct your char const* array then as:

所以你可以构造你的char const *数组,然后:

char const* names[] = { &MathewEmerson[0], /*...*/ };

As for arrays, the address of the array itself and its first element is the same, and arrays are implicitely converted to pointers, you can write instead

至于数组,数组本身的地址和它的第一个元素是相同的,并且数组被隐含地转换为指针,你可以改为编写

char const* names[] = { MathewEmerson, /*...*/ };

All this is done implicitely for you, if you use string literals.

如果您使用字符串文字,所有这些都是对您有意义的。

Similarly, you could have written:

同样,你可以写:

int *ptr[] = {var, &var[1], &var[2], &var[3]};

(note: var, not &var[0] for the first item) and if we go further, even:

(注意:var,而不是第一项的&var [0])如果我们走得更远,甚至:

int *ptr[] = {var, var + 1, var + 2, var + 3};

The result always would have been the same. Readability, understandability of one variant vs another? Well, another topic...

结果总是一样的。可读性,一种变体与另一种变体的可理解性?好吧,另一个话题......

#4


1  

Your misconception is wrapped up in your interpretation of what is represented by: "Mathew Emerson"

你对你所代表的内容的解释包含了你的误解:“Mathew Emerson”

This is an array of characters that will be instantiated in read only memory as part of your program's bootstrapping. This array of characters is called a String Literal, specifically a:

这是一个字符数组,将作为程序引导的一部分在只读存储器中实例化。这个字符数组称为String Literal,特别是:

Narrow multibyte string literal. The type of an unprefixed string literal is const char[]

窄多字节字符串文字。未加前缀的字符串文字的类型是const char []

NathanOliver's answer correctly describes that your compiler doesn't have the warning level turned up high enough so it is allowing the, const char[] to decay into a char*. This is very bad because:

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

Attempting to modify a string literal results in undefined behavior: they may be stored in read-only storage (such as .rodata) or combined with other string literals[1]

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

It would have been completely legal and logical to do this however: const char *names[] = {"Mathew Emerson", "Bob Jackson"} Hopefully that clarifies for you what's happening well enough for you to understand that working with a String Literal is working with a pointer. Your code: int *ptr[] = {var[0], var[1], var[2], var[3]} is then illegal because, var[0] is an int& not an int*. It would be similarly illegal to do: char* ptr = {names[0][0], names[0][1], names[0][2], names[0][3]} Again the problem here would be that I was working with char&s not char*s.

然而,这样做是完全合法和合乎逻辑的: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。