2010-11-24 136 views

回答

54

int* test();

,但是這將是 「多C++」 使用向量:

std::vector<int> test();

編輯
我 會澄清一些問題。由於您提到了C++,因此我將使用new[]delete[]運算符,但它與malloc/free一樣。

在第一種情況下,你會寫類似:

int* test() { 
    return new int[size_needed]; 
} 

,但它不是一個不錯的主意,因爲你的函數的客戶端並不真的知道自己在返回數組的大小,雖然客戶端可以通過致電delete[]安全地釋放它。

int* theArray = test(); 
for (size_t i; i < ???; ++i) { // I don't know what is the array size! 
    // ... 
} 
delete[] theArray; // ok. 

更好的簽名會是這樣:

int* test(size_t& arraySize) { 
    array_size = 10; 
    return new int[array_size]; 
} 

而且你的客戶端代碼現在將是:

size_t theSize = 0; 
int* theArray = test(theSize); 
for (size_t i; i < theSize; ++i) { // now I can safely iterate the array 
    // ... 
} 
delete[] theArray; // still ok. 

由於這是C++,`的std :: vector的< T>是一種廣泛使用的解決方案:

std::vector<int> test() { 
    std::vector<int> vector(10); 
    return vector; 
} 

現在,你不必叫delete[],因爲它會通過對象來處理,你可以安全地遍歷它:

std::vector<int> v = test(); 
std::vector<int>::iterator it = v.begin(); 
for (; it != v.end(); ++it) { 
    // do your things 
} 

哪一個更容易,更安全。

+2

我與返回'的std :: VECTOR`去。 – 2010-11-24 08:08:54

+8

個人而言,我認爲如果你不解釋它實際上沒有返回一個數組,那麼回答`int * test();`回答'如何在C++方法中返回一個數組?'[誤]但是一個指針。 – 2010-11-24 09:53:41

2

那麼如果你想從函數中返回你的數組,你必須確保這些值不會被存儲在堆棧上,因爲當你離開函數時它們將會消失。因此,要麼讓你的數組是靜態的,要麼分配內存(或者將它傳入,但是你的初始嘗試是用一個void參數)。對於你的方法我定義它是這樣的:

int *gnabber(){ 
    static int foo[] = {1,2,3} 
    return foo; 
} 
16

我怎樣才能返回一個C++方法的陣列,以及如何我必須聲明呢? int [] test(void); ??

這聽起來像一個簡單的問題,但在C++中有很多選項。首先,你應該更喜歡......

  • std::vector<>,其動態地增長到在運行時遇到然而,許多元件,或

  • std::array<>(導入有C++ 11),它總是存儲在編譯時所指定的數量的元素,

...因爲他們爲您管理內存,以確保正確的行爲,並大大簡化了的東西:

std::vector<int> fn() 
{ 
    std::vector<int> x; 
    x.push_back(10); 
    return x; 
} 

std::array<int, 2> fn2() // C++11 
{ 
    return {3, 4}; 
} 

void caller() 
{ 
    std::vector<int> a = fn(); 
    const std::vector<int>& b = fn(); // extend lifetime but read-only 
             // b valid until scope exit/return 

    std::array<int, 2> c = fn2(); 
    const std::array<int, 2>& d = fn2(); 
} 

創建const引用返回數據的做法有時可以避免複製,但通常您可以只依賴返回值優化,或者 - 對於vector而不是array - 移動語義(隨C++ 11引入) 。

如果你真的想用一個內置陣列(區別於所謂array標準庫類上面提到的),一個辦法是調用者預留空間,並告訴該函數使用它:

void fn(int x[], int n) 
{ 
    for (int i = 0; i < n; ++i) 
     x[i] = n; 
} 

void caller() 
{ 
    // local space on the stack - destroyed when caller() returns 
    int x[10]; 
    fn(x, sizeof x/sizeof x[0]); 

    // or, use the heap, lives until delete[](p) called... 
    int* p = new int[10]; 
    fn(p, 10); 
} 

另一種選擇是包裝在一個結構數組,這 - 不同於原陣列 - 都是合法的值從函數返回:

struct X 
{ 
    int x[10]; 
}; 

X fn() 
{ 
    X x; 
    x.x[0] = 10; 
    // ... 
    return x; 
} 

void caller() 
{ 
    X x = fn(); 
} 

與上面的開始,如果你使用的卡C++ 03你可能想把它推廣到的東西更接近C++ 11 std::array

int* fn() 
{ 
    int* p = new int[2]; 
    p[0] = 0; 
    p[1] = 1; 
    return p; 
} 

void caller() 
{ 
    int* p = fn(); 
    // use p... 
    delete[] p; 
} 

要:

template <typename T, size_t N> 
struct array 
{ 
    T& operator[](size_t n) { return x[n]; } 
    const T& operator[](size_t n) const { return x[n]; } 
    size_t size() const { return N; } 
    // iterators, constructors etc.... 
    private: 
    T x[N]; 
}; 

另一種選擇是有被調用函數在堆上分配內存有助於簡化堆對象的管理,許多C++程序員使用「智能指針」來確保當指向對象的指針離開其作用域時刪除。隨着C++ 11:

std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; }); 
std::unique_ptr<int[]> p(new int[3]); 

如果你被困在C++ 03,最好的選擇是看boost庫可以在您的機器上:它提供boost::shared_array

還有一種選擇是有一些由fn()保留的靜態內存,雖然這不是線程安全的,並且意味着每次調用fn()都會覆蓋任何人看到以前調用的指針。也就是說,簡單的單線程代碼可以方便(快速)。

int* fn(int n) 
{ 
    static int x[2]; // clobbered by each call to fn() 
    x[0] = n; 
    x[1] = n + 1; 
    return x; // every call to fn() returns a pointer to the same static x memory 
} 

void caller() 
{ 
    int* p = fn(3); 
    // use p, hoping no other thread calls fn() meanwhile and clobbers the values... 
    // no clean up necessary... 
} 
9

無法從C++函數返回數組。 8.3.5 [dcl.fct]/6:

功能不應有類型的陣列或函數的返回類型[...]

最常選擇的替代方案是,返回的值該類包含數組的類類型,例如

struct ArrayHolder 
{ 
    int array[10]; 
}; 

ArrayHolder test(); 

還是要返回一個指向靜態或動態分配的數組的第一個元素,文檔必須向用戶表明他是否需要(如果有的話他應該怎麼)解除分配數組返回指針指着。

E.g.

int* test2() 
{ 
    return new int[10]; 
} 

int* test3() 
{ 
    static int array[10]; 
    return array; 
} 

雖然可以參考或返回一個指針數組,這是極其罕見的,因爲它是沒有實際優點的更復雜的語法在任何上述方法。

int (&test4())[10] 
{ 
     static int array[10]; 
     return array; 
} 

int (*test5())[10] 
{ 
     static int array[10]; 
     return &array; 
} 
-1

「我怎樣才能在一個C返回一個陣列++方法和如何必須我聲明它 INT []試驗(無效);???」

template <class X> 
    class Array 
{ 
    X  *m_data; 
    int m_size; 
public: 
    // there constructor, destructor, some methods 
    int Get(X* &_null_pointer) 
    { 
     if(!_null_pointer) 
     { 
      _null_pointer = new X [m_size]; 
      memcpy(_null_pointer, m_data, m_size * sizeof(X)); 
      return m_size; 
     } 
     return 0; 
    } 
}; 

只是INT

class IntArray 
{ 
    int *m_data; 
    int m_size; 
public: 
    // there constructor, destructor, some methods 
    int Get(int* &_null_pointer) 
    { 
     if(!_null_pointer) 
     { 
      _null_pointer = new int [m_size]; 
      memcpy(_null_pointer, m_data, m_size * sizeof(int)); 
      return m_size; 
     } 
     return 0; 
    } 
}; 

例如

Array<float> array; 
float *n_data = NULL; 
int  data_size; 
if(data_size = array.Get(n_data)) 
{  // work with array } 

delete [] n_data; 

例如對於int

IntArray array; 
int  *n_data = NULL; 
int  data_size; 
if(data_size = array.Get(n_data)) 
{ // work with array } 

delete [] n_data;