2010-07-14 103 views
3

我想初始化一個大小爲200的double數組,它的值在C++中從0到199從0到199。 我知道我可以通過一個簡單的For循環來做到這一點,但有沒有辦法只是初始化這樣的雙數組?C++ array question

謝謝

+1

參見[?如何填補不平凡的初始值向量(http://stackoverflow.com/questions/207768 /如何對填充一個矢量與 - 非平凡-初始值)。其他一些選項是(http://www.sgi.com/tech/stl/iota.html)(非標準)和Boost的[counting_iterator](http://www.boost。組織/ DOC /庫/ 1_43_0 /庫/迭代器/ DOC/counting_iterator.html)。 – 2010-07-14 06:41:25

+0

@Matthew:哇,我從來不知道'counting_iterator'。您應該添加該答案作爲答案,否則我會盜取它。 :) – GManNickG 2010-07-14 06:44:41

回答

10

不是真的。 A for循環是您的最佳選擇:

double array[200]; 
for(int i = 0; i < 200; i++) 
    array[i] = static_cast<double>(i); 
+0

可能希望將'static_cast '也放在那些 – 2010-07-14 06:26:47

+0

噢。錯過了。 – Anthony 2010-07-14 06:37:45

+0

+1環路不是唯一的選擇,因爲其他答案已被證明。但我更喜歡閱讀一個簡單的循環(特別是在正確命名的init函數內),然後使用其他解決方案。 也許除了C++ 0x std :: generate + lamda版本這是OK ...當它可用時,這是... 但我仍然更喜歡_explicit_循環。 – 2010-07-14 07:19:50

1

如果數組的所有值都相同,則可以輕鬆完成。但是價值觀彼此不同,所以我不認爲你直接這樣做。

double array[200]; 

for(int i=0 ; i<200 ; i++) { 
    array[i] = (double)i; 
} 
+2

當'i = 200'時,你的代碼會導致無效的內存訪問,因爲它會寫入'array [200]'。將賦值賦給'array [i]'到它所屬的'for'語句的主體中! – 2010-07-14 06:37:16

+0

另外,'array [0]'沒有被寫入並且保持未初始化。 – 2010-07-14 06:45:33

+0

我不認爲如何C++的機制。如果它從左邊解析句子,則不存在任何無效的存儲器訪問。 for循環結束,直到來到「array [i] =(double)i」 – onurbaysan 2010-07-14 06:55:00

0

初始化數組的值的唯一方法是在聲明的點(如果初始化比陣列的所有其它元件都被初始化爲0以下;

double arr[5] = {0, 1, 2}; // arr = [0.0 ,1.0 ,2.0 ,0.0 ,0.0] 

否則,沒有辦法。初始化值,你就會有循環陣列之上

所以你可以做的是:

double arr[] = {0, 1, 2, 3, /* ... */, 199}; 

雖然在大多數情況下,循環會更好

+0

作爲循環表示法的另一個優點是可以在編譯時解決這個問題。缺點是這是一個痛苦寫... – paercebal 2010-07-14 06:20:08

+0

@paercebel,當然,它是在編譯時完成的事實是* only *的優勢。至於寫它,我會用腳本生成一次,以免冒錯誤。 – Motti 2010-07-14 07:05:37

2

anthony-arnold,但與C++載體(或列表,或雙端隊列):

std::vector<double> array ; 
array.reserve(200) ; // only for vectors, if you want 
        // to avoid reallocations 

for(int i = 0; i < 200; i++) 
    array.push_back(i) ; 
7

下面是與std::generate方式:

template <typename T> 
class nexter 
{ 
public: 
    nexter(T start = T()) 
     : value_(start) 
    { 
    } 

    T operator()() 
    { 
     return value_++; 
    } 

private: 
    T value_; 
}; 

int main() 
{ 
    double data[200]; 
    std::generate(data, data + 200, nexter<double>()); 
} 

如果你使用的C++ 0x,你可以跳過仿函數:

int main() 
{ 
    double data[200]; 
    double next = 0.0; 
    std::generate(data, data + 200, [&next]() { return next++; }); 
} 
+0

嚴格地說,我認爲'for_each'實際上並不是想要改變元素。另外,如果你想忽略一個參數,就不要命名它。最後,如果你要使用函子,不妨使用'std :: generate'。 :) – GManNickG 2010-07-14 06:32:30

+0

@GMan - 謝謝,我忘了'std :: generate' - 更新了我的示例,並且還給出了一個使用C++ 0x lambdas的示例。 – 2010-07-14 06:39:18

+1

@RSamuel:+1不錯,C++ 0x解決方案到目前爲止可以說是最清潔的。 (如果只有標準庫使用該死的範圍而不是迭代器!)對於-1不是我的記錄。 – GManNickG 2010-07-14 06:41:34

7

使用counting_iterator

const int SIZE = 200; 
double array[SIZE]; 
std::copy(counting_iterator<int>(0), counting_iterator<int>(SIZE), array); 
+0

恕我直言,':: std:; copy'應該寫成要求目標開始和結束,並且源代碼開始而不是其他方式。無論哪種方式,您都可以獲得緩衝區溢出,但是當溢出僅在讀取而不是寫入時難以利用。 – Omnifarious 2010-07-14 06:59:05

+0

@Omnifarious:更好,但同時要求;)但我同意讀取溢出不太可能導致問題。 – 2010-07-14 09:26:29

+0

像GMan我不知道這個小奇蹟。這麼簡單,如此有用! – 2010-07-14 09:27:02

0

如果200是一個固定常數,你不想運行時開銷,我看基本上有兩種解決方案。

對於C解決方案,您可以通過預處理器解決它。在認爲Boost已經爲這樣的事情預處理了for循環。這將有利於在編譯時完成,根本沒有運行時間開銷。

雖然常量200本身對於所有編譯器/預處理器來說可能有點大,但是大多數現代應該能夠處理這個問題。

對於C++解決方案,我認爲您可以使用template元編程來完成。具有template參數中的元素數量的遞歸類型可以做到這一點。但對於常量來說,編譯時間開銷可能會很大。

+0

有趣的選項,但都不可能比循環更容易調用。特別是模板遞歸很難理解 – Elemental 2010-07-14 11:10:06

+0

@Elemental:取決於誰更簡單。如果你有例如一個通用的宏,那麼調用端就變得非常簡單,就像'double A [] = INIT_DARRAY(200);'。當然,實現這樣一個宏並不簡單,但這實際上是硬幣的另一面。而這樣的宏是否隱藏了一個真正的宏Boost定義或遞歸模板在這方面並不重要。 – 2010-07-14 11:35:13

+0

夠公平,更簡單是一個觀點 – Elemental 2010-07-15 07:38:18

0

我認爲for-loop是您的案例最簡單和最合適的解決方案。如果你只想知道做一個更多的方式,你可以使用std::transform

#include <vector> 
#include <algorithm> 

double op_increase (double i) { return static_cast<double>(static_cast<int>(i)+1); } 

int main() 
{ 
    std::vector<double> x(200); // all elements were initialized to 0.0 here 
    std::transform(x.begin(), x.end()-1, x.begin()+1, op_increase); 

    return 0; 
}