[英]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.