簡體   English   中英

在for循環中使用數組-C ++

[英]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 ,它需要一組不同的參數,並且不太可能是您想要的。

輸出由每個映射對的firstseconditerator->firstiterator->second引用。 在這種情況下,這些是存儲在map中的stringfloat

我的直接傾向是告訴您使用向量而不是數組。 使用向量,您可以很容易地獲得大小,並且(更好)通過使用基於范圍的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::beginstd::end來完成(大致)相同:

for (auto s = std::begin(expenses); s != std::end(expenses); ++s)
    std::cout << *s;

請注意,盡管在C ++ 11中添加了std::beginstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM