2016-02-10 100 views
0

我有一個結構,根據用戶在運行時的輸入,它將需要一維數組或3D數組。它永遠不會需要兩者。現在,我已經像下面的示例代碼中那樣設置了它,其中單獨的變量可以指向一維數組或3D數組。我想在結構中只有一個變量可以指向一維數組或維數在運行時設置的3D數組。我有C的中級知識,並且是C++的初學者。我願意接受一個基於C++概念的答案,但如果沒有減速(或可以忽略的減速),則與相比只有。如果它是一個3D數組,那麼訪問和更改數組值的for循環是我的代碼中最大的瓶頸。一旦數組被設置,我就不需要改變數組的尺寸或大小。在運行時設置數組維數

有沒有辦法做到這一點,或者我應該解決在我的結構中總是有一個無關的變量?

#include <iostream> 
using namespace std; 

typedef struct { 
    int dim; 
    int *one_d_arr; 
    int ***three_d_arr; 
} Struct; 

int main() { 
    int count = 0; 
    int *arr1 = (int*) malloc(2 * sizeof(int)); 
    arr1[0] = 0; 
    arr1[1] = 1; 
    int ***arr3 = (int***) malloc(2 * sizeof(int**)); 
    for (int i=0; i<2; i++) { 
    arr3[i] = (int**) malloc(2 * sizeof(int*)); 
    for (int j=0; j<2; j++) { 
     arr3[i][j] = (int*) malloc(2 * sizeof(int)); 
     for (int k=0; k<2; k++) { 
     arr3[i][j][k] = count++; 
     } 
    } 
    } 
    Struct s; 
    s.one_d_arr = NULL; 
    s.three_d_arr = NULL; 
    cout << "Enter number of dimensions: "; 
    cin >> s.dim; 
    if (s.dim==1) { 
    s.one_d_arr = arr1; 
    cout << s.one_d_arr[0] << ", " << s.one_d_arr[1] << endl; 
    } 
    else if (s.dim==3) { 
    s.three_d_arr = arr3; 
    cout << s.three_d_arr[0][0][0] << ", " << s.three_d_arr[0][0][1] << endl; 
    cout << s.three_d_arr[0][1][0] << ", " << s.three_d_arr[0][1][1] << endl; 
    cout << s.three_d_arr[1][0][0] << ", " << s.three_d_arr[1][0][1] << endl; 
    cout << s.three_d_arr[1][1][0] << ", " << s.three_d_arr[1][1][1] << endl; 
    } 
    else { 
    cout << "Must enter 1 or 3" << endl; 
    } 
} 
+3

'C/C++'是UB .. –

+2

我想你可能想用用C'new'(而不是'malloc')++。 – pzaenger

+0

所以標籤以'C++'結尾 - 對我來說看起來更像'c'風格。 – 4386427

回答

1

我的建議是在這裏使用兩種不同的類型,而不是一個單一的結構。使用抽象基類,可以使兩個子類符合單個接口,但它們會有不同的基本行爲。一個很簡單的例子:

class ArrayBase { 
    int dim; 

    public: 
    // This function is pure virtual, which means it's impossible to  
    // instantiate an instance of ArrayBase. Any class that inherits from 
    // ArrayBase must implement printArray(). 
    virtual void printArray() = 0; 
} 

class Array1D : public ArrayBase { 
    int* array; 

    void printArray() { 
    // some code to print this one-dimensional array 
    } 
} 

class Array3D : public ArrayBase { 
    int*** array; 

    void printArray() { 
    // some code to print this three-dimensional array 
    } 
} 

之後,當您需要使用陣列,可以動態地分配你需要的類型,就像這樣:

ArrayBase* inputArray; 

// if the user wants a 1D array 
inputArray = new Array1D(); 

// if the user wants a 3D array 
inputArray = new Array3D(); 

// this will call the appropriate function to print the array 
inputArray->printArray(); 

如果你真的想有一個單一類型,使用boost :: any是一種將兩個數組指針壓縮成一個的方法。我不會推薦這種方法,但它會起作用。

+0

我接受了這個答案,因爲它指向我重構我的代碼的好方向。在實現類似的東西之前,我會花一些時間學習類和其他C++容器。謝謝! –

1

有關C/C++指針的多汁的事情之一是指針的存在。一個無效指針可以指向你想要的任何東西,從INTINT ***。 所以,你可以簡單地使用下面的代碼:

#define CAST1(arr) ((int *)arr) 
#define CAST3(arr) ((int ***)arr) 
#define CAST(arr,i) CAST##i(arr) 

typedef struct { 
    int dim; 
    void *arr; 
} Struct; 

int main() 
{ 
    Struct s; 
    cin >> s.dim; 
    int count = 0; 

if (s.dim == 1){ 
    s.arr = malloc(2 * sizeof(int)); 
    CAST(s.arr, 1)[0] = 0; 
    CAST(s.arr, 1)[1] = 1; 
} 
else if (s.dim == 3){ 
    s.arr = malloc(2 * sizeof(int ***)); 
    for (int i = 0; i < 2; i++){ 
     CAST(s.arr, 3)[i] = (int **) malloc(2 * sizeof(int **)); 
     for (int j = 0; j < 2; j++){ 
      CAST(s.arr, 3)[i][j] = (int *)malloc(2 * sizeof(int *)); 
      for (int k = 0; k < 2; k++){ 
       CAST(s.arr, 3)[i][j][k] = count++; 
      } 
     } 
    } 
} 

if (s.dim == 1) { 
    cout << CAST(s.arr, 1)[0] << ", " << CAST(s.arr, 1)[1] << endl; 
} 
else if (s.dim == 3) { 
    cout << CAST(s.arr, 3)[0][0][0] << ", " << CAST(s.arr, 3)[0][0][1] << endl; 
    cout << CAST(s.arr, 3)[0][1][0] << ", " << CAST(s.arr, 3)[0][1][1] << endl; 
    cout << CAST(s.arr, 3)[1][0][0] << ", " << CAST(s.arr, 3)[1][0][1] << endl; 
    cout << CAST(s.arr, 3)[1][1][0] << ", " << CAST(s.arr, 3)[1][1][1] << endl; 
} 
else { 
    cout << "Must enter 1 or 3" << endl; 
} 

system("pause"); 

return 0; 
} 
+0

謝謝,這是很好的知道。但是,根據評論,看起來最好的答案將是對我的編碼概念進行更爲重大的修改。我會等待一個答案,告訴我如何清理我的代碼,但如果沒有出現,我會選擇這個。 –