[英]Using an array in a for loop - C++
我想設置一個測試條件來確定數組的大小,然后在for
循環中遍歷數組的每個值。
以這個數組為例
std::string expenses[] = {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
方括號是空的,其中有10個元素。 您將如何為此創建一個for
循環,而不創建一個單獨的變量,該變量的int為10?
使用countof
宏,其聲明如下:
#define countof(a) (sizeof(a)/sizeof((a)[0]))
所以你可以說:
for (i = 0; i < countof(expenses); i++) ...
正如每個人都指出的那樣,您必須要有足夠的經驗來了解數組和指針之間的區別。 如果您傳遞expenses
指示,當然, countof
是虛假的。
如果您打算遍歷每個元素(在同一范圍內 ),那么“黑暗”是正確的:
#include <string>
#include <iostream>
int main()
{
std::string expenses[] = {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
std::cout<< "NumEls = " << sizeof(expenses) / sizeof(expenses[0]) << std::endl;
}
產生10的輸出,並且用for
循環替換cout
將允許測試字符串,例如
for (int i=0; i< (sizeof(expenses)/sizeof(expenses[0])); i++)
{
std::cout<< "The " << i << "th string is : " << expenses[i] << std::endl;
}
請注意,這將產生“ 0th”,“ 1th”等。
* 警告 *
反映問題中給出的意見,我們的答案似乎不完整,沒有提到sizeof(POINTER)
不會為您提供有用的信息-或至少對此沒有用。 因此,如果您想使用:
myFunction (std::string someArray[])
{
for( all the strings in someArray )
{
std::cout << someArray[i];
}
}
那么您將發現自己無法做到。
相反,您可以使用:
myFunction (std::string someArray[], int sizeOfArray)
{
for(int i=0; i<sizeOfArray; i++)
{
std::cout<< someArray[i];
}
}
但這完全符合您的問題(不存儲單獨的int)
*輸入std :: vector *
一個更簡單的解決方案是使用std :: vector
使用向量允許使用諸如myVector.size()
類的函數調用,並且在使用最新(C ++ 11)編譯器/編譯器選項的情況下,也可以根據向量的大小自動循環。
向量可以很高興地傳入和傳出函數,如果要更改向量,對向量的引用也是一種簡單的方法-請參考答案:
inputFunction (std::vector<string> &expenses, budget &info)
{
for (int i=0; i< expenses.size(); i++)
{
std::cout<< "Enter your expense for " << expenses[i] << ": ";
// Operation to store input as needed
}
}
附帶說明一下,您似乎想將費用名稱的string
鏈接到費用值? 如果是這樣,請考慮使用map 。 在這種情況下,您可能需要考慮std::map<std::string, float>
。
*使用std :: map *
在使用地圖時,您可能需要一個迭代器。 一個例子可能是這樣的:
void input(const std::vector<std::string> &exp, std::map<std::string, float> &map)
{
for (int i=0; i<exp.size(); i++)
{
float tempFloat;
std::cout<< "Please enter the amount for " << exp[i] << ": ";
std::cin >> tempFloat;
map.emplace(exp[i], tempFloat);
}
};
在main()
,
std::map<std::string, float> myMap;
input(myVec, myMap);
for (std::map<std::string, float>::iterator it=myMap.begin(); it!=myMap.end(); it++)
{
std::cout << "myMap values -> " << it->first << " = " << it->second << std::endl;
}
這將使用從myMap.begin()
並在地圖的最后一個條目處結束的迭代器輸出您擁有的每個對。
emplace(...)
構造一個對,然后將其添加到地圖中。 您應該注意不要使用insert
,它需要一組不同的參數,並且不太可能是您想要的。
輸出由每個映射對的first
和second
值iterator->first
和iterator->second
引用。 在這種情況下,這些是存儲在map
中的string
和float
。
我的直接傾向是告訴您使用向量而不是數組。 使用向量,您可以很容易地獲得大小,並且(更好)通過使用基於范圍的for
循環來避免獲得大小:
std::vector<std::string> expenses {"housing", "utilities", "household expenses", "transportation", "food", "medical", "insurance", "entertainment", "clothing", "misc"};
// print out the strings, one per line:
for (auto const &s : expenses)
std::cout << s << "\n";
如果確實需要使用數組而不是向量,則可以使用函數模板來計算大小:
template <class T, size_t N>
size_t size(T (&array)[N]) {
return N;
}
for (int i=0; i<size(expenses); i++)
std::cout << expenses[i] << '\n';
與普通宏( (sizeof(x)/sizeof(x[0]))
)相比,此模板函數的主要優點是它的類型很強-試圖傳遞指針而不是數組的任何嘗試都不會編譯(並且考慮到數組名稱衰減到指針的難易程度,這一點很重要)。
如果您有C ++ 11,則可以使用標准庫中的std::begin
和std::end
來完成(大致)相同:
for (auto s = std::begin(expenses); s != std::end(expenses); ++s)
std::cout << *s;
請注意,盡管在C ++ 11中添加了std::begin
和std::end
,但是您可以使用類似於上面的size
模板的代碼為C ++ 98/03編譯器創建相似的模板。
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
這些也可以與標准算法一起使用,因此您可以執行以下操作:
std::copy(begin(expenses), end(expenses),
std::ostream_iterator<std::string>(std::cout, "\n"));
再次注意,我們避免直接處理計數或在數組中創建下標,而只處理數組中的迭代器以及這些迭代器引用的項。
您可以使用sizeof(expenses) / sizeof (expenses[0])
。 請注意,您不需要括號,但我更喜歡。
很多人都提到過(sizeof(expenses)/ sizeof(expenses [0]))技巧,但是如果您要走這條路線,在C ++中,有一種使用模板化函數的更好的方法:
/* returns # of items in array, or will error out at compile time if you try to pass it a pointer instead of an array */
template<typename T, int size> unsigned int array_size(T(&)[size]) {return size;}
這樣比較安全,因為如果不小心傳入了一個指針而不是一個數組,它將給您一個編譯時錯誤。 (sizeof()版本會編譯,然后在運行時執行意外的操作,這是不希望的)
兩種可能性。 如果要在定義它的相同范圍內對其進行迭代,則可以簡單地使用基於范圍的for循環:
for(auto& expense : expenses)
{
std::cout << expense << std::endl;
}
如果您希望能夠將其傳遞給函數,則必須做一些丑陋的事情才能將其放入std :: array中,然后可以在任何地方使用上面的range循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.