2010-05-14 45 views
2

我的問題是在代碼中,但基本上我想知道如何/如果我可以做兩條註釋掉的線?我知道我可以在構造函數中完成,但我不想!如何初始化一個數組中的數組而不分別執行每個元素? (C++)

struct foo 
{ 
    int b[4]; 
} boo; 

//boo.b[] = {7, 6, 5, 4}; // <- why doesn't this work? (syntax error : ']') 
//boo.b = {7, 6, 5, 4}; // <- or else this? (syntax error : '{') 

boo.b[0] = 7; // <- doing it this way is annoying 
boo.b[1] = 6; // : 
boo.b[2] = 5; // : 
boo.b[3] = 4; // <- doing it this way is annoying 

boo.b[4] = 3; // <- why does this work! 

(使用:C++,Visual Studio 2005中)

+1

這是另一種場合,可以宣傳即將推出的C++ 11標準的統一初始化語法...... – sbi 2010-05-14 15:51:08

回答

8

您只能使用初始化的定義:

struct foo 
{ 
    int b[4]; 
}; 
foo boo = { 7, 6, 5, 4 }; 

在最後一個問題: '爲什麼boo.b[4] = 3工作?'答案是它是未定義的行爲,並且UB允許相當多的不同情況。編譯器和運行時環境都不需要診斷它,並且在很多情況下,結果將覆蓋內存中的下一個元素。這可能與下面的代碼進行測試:

// Test 
foo boo; 
int x = 0; 
boo.b[4] = 5; 
std::cout << x << std::endl; 

注意:這是不確定的行爲,因此無論該測試的結果是,這是不正確的,不能被認爲是一個可重複的測試。

+0

更具體地說,引用超出數組邊界的元素的能力是合法的。行爲將取決於該內存位置是否屬於另一個變量。所以在這種情況下,確切的行爲是不確定的,因爲'5'可能會或可能不會覆蓋'x'的值。但是,如果你已經安排在結構的末尾分配額外的內存,那麼這樣的數組訪問就沒問題。因此,您有時可能會看到以1字節數組字段結尾的消息標頭的結構定義,該字段實際上只是可變長度多字節數據的開頭。 – 2010-05-14 16:12:27

1

如果你確實需要它被初始化後,寫入該結構的成員,它看起來像你的價值觀是遵循一個簡單的模式(啓動7和減量的一個),這意味着std::generate()std::generate_n()可以做的工作,太:

#include <algorithm> 
class DecrementFrom { 
     int val; 
public: 
     DecrementFrom(int start) : val(start) {} 
     int operator()() { return val--; } 
}; 

std::generate_n(foo.b, 4, DecrementFrom(7)); 
1

嚴格地說,用於初始化一個結構裏的數組的語法是:

struct foo 
{ 
    int b[4]; 
}; 
foo boo = { { 7, 6, 5, 4 } }; 

但是,根據C標準的6.7.8.17,如果不提供它,編譯器將隱式跟蹤適當的範圍。

相關問題