[英]Iterating through const char* array
我有一個非常簡單的const char數組的例子和一個應該打印出來的函數(遍歷所選的一個)。 與我的所有期望相反,它正在迭代所有這些,而不僅僅是作為參數傳遞的那個。
#include <iostream>
const char* oranges[] = {
"ORANGE",
"RED ORANGE"
};
const char* apples[] = {
"APPLE"
};
const char* lemons[] = {
"LEMON"
};
void printFruit(const char** fruit){
int i =0;
while (fruit[i] != '\0'){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
}
int main (int argc, const char * argv[])
{
printFruit(oranges);
return 0;
}
我期望的結果是作為參數給出橙色函數printFruit將打印ORANGE和RED ORANGE,同時我打印所有定義的水果(來自其他數組),如下所示:
---------------------
ORANGE
---------------------
RED ORANGE
---------------------
APPLE
---------------------
LEMON
對不起我的無知,但為什么會這樣?
你在這里有UB。 你的病情
while (fruit[i] != '\0')
永遠不會滿足,因為沒有等於\\0
元素。
所有數組都在內存中一個接一個地放置。 你的i
永遠在增加。 在i = 1
你在oranges
的第一個字符串。 在i = 2
你在第二個元素上。
在那之后, i
變成了3.因為在oranges
之后,在你的媽媽的謊言apples
陣列,你的指針開始指向它,應用程序打印APPLE
。 在i = 4
,指針位於lemons
數組上,應用程序打印LEMONS
。 之后,你有效地走出了自己的記憶,這對我來說會導致崩潰。
要解決此問題,您需要在每個數組中顯式添加一個空元素,例如
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0
};
你正在檢查fruit[i] != '\\0'
。 這是錯誤的,因為fruit[i]
是char *
,而不是char。 此外,您的向量不會終止。 您可能想檢查fruit[i] != 0
,或*fruit[i] != '\\0'
。 在第一種情況下,您需要終止這樣的向量:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0 // or NULL
};
在第二:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
""
};
恕我直言,你最好知道你正在處理多少元素。 壞消息是一個簡單的字符指針數組不會告訴你(它不是std::vector
)所以你將無法在printFruit
函數中發現它。
然而,好消息是它可以在編譯時使用,因此您不必擔心找到它的開銷。 以下顯示了我的意思:
void printFruit(const char** fruit, int fruitSize){
int i =0;
while (i < fruitSize){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
}
int main (int argc, const char * argv[])
{
// The second parameter can be worked out by the compiler.
printFruit(oranges, sizeof(oranges)/sizeof(const char*) );
return 0;
}
既然您正在使用C ++,我強烈建議您使用其中一種標准集合類型,例如vector
因為它們在邊界檢查,內存分配等方面更安全。
const char* oranges[] = {
"ORANGE",
"RED ORANGE"
};
const char* apples[] = {
"APPLE"
};
const char* lemons[] = {
"LEMON"
};
在記憶中會看起來像
“ORANGE”“RED ORANGE”“APPLE”“LEMON”
while (fruit[i] != '\0'){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
當你到達“LEMON”的“大陣列”結束時將結束
為了使你的代碼工作你需要內存看起來像“ORANGE”“RED ORANGE”0“APPLE”0“LEMON”0所以
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0
};
const char* apples[] = {
"APPLE",
0
};
const char* lemons[] = {
"LEMON"
,0
};
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
"\0"
};
您的陣列一個接一個地位於內存中,因此它會繼續打印其他數據,因為while
條件為false
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.