2014-10-09 131 views
0

我想生成一些樂透號碼,並返回包含這些數字的數組,但我不能再進一步;請幫助如何返回數組C++?

void getLotto(int rad[7]) { 
    int numbers[7]; 

    for (int i = 0; i < 7; i++) { 
     numbers[i] = rand() % 35 + 1; 
    } 

    for (int j = 0; j < 7; j++) { 
     int n = rand() % 35 + 1; 
     if (n == numbers[j]) { 
      numbers[j] = rand() % 35 + 1; 

      return; 
     } 
    } 
} 
+1

難道你不應該填寫rad而不是數字嗎?目前它未被使用。那麼你不需要返回任何東西。 – deviantfan 2014-10-09 00:36:09

+0

@deviantfan如果rad通過引用傳遞,那麼這不僅僅是真的嗎? – Shadow 2014-10-09 00:37:47

+0

數組永遠不會傳值,只是指向數組的指針。 – Galik 2014-10-09 00:39:44

回答

2

數組不能由函數返回。一個常見的事情是動態分配數組並返回指向其第一個元素的指針。這將適用於您的情況,但會產生呼叫者管理內存的要求(delete[]new[]'ed內存)。這就是C++爲我們提供標準數組類的原因:使用並返回std::vector。如果您有C++ 11支持,請返回std::array

0

之後可能會有幫助,使用Fisher–Yates_shuffle

// Fisher–Yates_shuffle 
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 
std::vector<int> FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen) 
{ 
    assert(size < max_size); 
    std::vector<int> res(size); 

    for(std::size_t i = 0; i != max_size; ++i) { 
     std::uniform_int_distribution<> dis(0, i); 
     std::size_t j = dis(gen); 
     if (j < res.size()) { 
      if (i != j) { 
       res[i] = res[j]; 
      } 
      res[j] = 1 + i; 
     } 
    } 
    return res; 
} 

Live example

0

std::vectorstd::array比普通數組更好,但如果你想使用常規的數組,你可以按如下修改功能:

// Arguments: renamed the array, added N (# of array elements) 
void getLotto(int numbers[], size_t N) { 
    //int numbers[7]; // commented out local variable 

    for (int i = 0; i < N; i++) { 
     numbers[i] = rand() % 35 + 1; 
    } 

    for (int j = 0; j < N; j++) { 
     int n = rand() % 35 + 1; 
     if (n == numbers[j]) { 
      numbers[j] = rand() % 35 + 1; 

      return; 
     } 
    } 
} 

int numbers[]的括號表示參數是一個數組,實際傳遞的是指向數組的第一個元素的指針。 getLotto()修改numbers修改傳遞給函數的數組。

第二個參數的類型爲size_t,因爲它是系統用來表示對象大小(如數組)的無符號整型的平臺相關別名。

這不是該函數必須相信numbers實際上有N元素作爲安全的,但你這是怎麼有一個功能修改規則的陣列,而不是像std::vector的容器。

你會調用該函數是這樣的:

size_t N; 
int numbers[N]; 
getLotto(numbers, N); 
0

C++不允許返回整個數組作爲參數傳遞給函數。但是,您可以通過指定數組的名稱而不使用索引來返回指向數組的指針。

如果你想從一個函數返回一個一維數組,你就必須聲明函數返回一個指針,如下面的例子:

int * myFunction() 
{ 
    . 
    . 
    . 
} 

第二點要記住的是,C++不主張將局部變量的地址返回到函數的外部,這樣您就必須將局部變量定義爲靜態變量。

現在,考慮下面的函數,這將產生10張隨機數和使用陣列返回它們和調用此函數如下:

#include <iostream> 
#include <ctime> 

using namespace std; 

// function to generate and retrun random numbers. 
int * getRandom() 
{ 
    static int r[10]; 

// set the seed 
srand((unsigned)time(NULL)); 
    for (int i = 0; i < 10; ++i) 
{ 
r[i] = rand(); 
cout << r[i] << endl; 
} 

    return r; 
    } 

// main function to call above defined function. 
int main() 
{ 
    // a pointer to an int. 
    int *p; 

    p = getRandom(); 
    for (int i = 0; i < 10; i++) 
    { 
    cout << "*(p + " << i << ") : "; 
    cout << *(p + i) << endl; 
    } 

return 0; 
    } 

當上述代碼被編譯在一起,並執行時,它產生的結果東西如下

624723190 
1468735695 
807113585 
976495677 
613357504 
1377296355 
1530315259 
1778906708 
1820354158 
667126415 
*(p + 0) : 624723190 
*(p + 1) : 1468735695 
*(p + 2) : 807113585 
*(p + 3) : 976495677 
*(p + 4) : 613357504 
*(p + 5) : 1377296355 
*(p + 6) : 1530315259 
*(p + 7) : 1778906708 
*(p + 8) : 1820354158 
*(p + 9) : 667126415 
0

有兩種主要的方法來完成這一點。

注意:我不確定你的第二個for循環在做什麼。我猜想的目的是確保數字都是獨一無二的?你可能想看看它,因爲它不是它在做什麼。 爲了這個問題的目的,我把它簡化爲只生成隨機數來填充數組。

第一是把你的代碼,並修復它把生成的數字放入數組中傳遞:

#include <iostream> 

void getLotto(int numbers[7]) { 

    for (int i = 0; i < 7; i++) 
     {numbers[i] = rand() % 35 + 1;} 

    return; 
} 

int main() 
{ 
    srand(time(0)); 
    int lotto_numbers[7]; 
    getLotto(lotto_numbers); 
    for (int i = 0; i < 7; i++) 
     {std::cout<<lotto_numbers[i]<<std::endl;} 
} 

numbers實際上不傳遞作爲int[]而是作爲一個int*指點到陣列。這意味着您對該功能所做的任何更改都會在原始數據中發生更改。
記住,你需要保持跟蹤你的數組越界的現象,因爲陣列可以被定義爲

int lotto_numbers[6] 

這意味着

numbers[7] 

將出界。第二種方法是在堆上創建數組。這意味着你不需要傳入一個數組,但是你可以在函數中實例化它

我實際上不打算在這裏提供代碼。主要是因爲這樣簡單的事情,內存管理比它的價值更麻煩。 (你需要記住在堆上創建的所有東西都需要調用delete[])。

相反,讓使用內存管理的東西建於:

#include <iostream> 
#include <vector> 

std::vector<int> getLotto() { 
    std::vector<int> numbers; 
    numbers.reserve(7); 
    for (int i = 0; i < 7; i++) { 
     //numbers[i] = rand() % 35 + 1; 
     //would work, but is unsafe as you could potentially reference somthing out of range 
     //this is safer: 
     numbers.push_back(rand() % 35 + 1); 
    } 

    return numbers; 
} 

int main() 
{ 
    srand(time(0)); 
    std::vector<int> lotto_numbers = getLotto(); 
    for (auto i = lotto_numbers.begin(); i != lotto_numbers.end(); i++) 
    { 
     std::cout<<*i<<std::endl; 
    } 
} 

矢量處理內存管理你。向量可以被返回,並且返回的向量將仍然指向我們剛纔填充的堆上的已分配內存。我們不需要釋放它,因爲這將在向量超出範圍時自動完成。