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。