簡體   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