我有一个结构,根据运行时的用户输入,它将需要一维数组或三维数组。它永远不需要两者兼得。现在,我在下面的示例代码中进行了设置,使用可以指向一维数组或三维数组的单独变量。我想在结构中只有一个可以指向一维数组或三维数组的变量,其中维度是在运行时设置的。我有C的中级知识,并且是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;
}
}
答案 0 :(得分: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是将两个数组指针压缩成一个的一种方法。我不推荐这种方法,但它会起作用。
答案 1 :(得分:1)
关于C / C ++指针的一个有趣的事情是存在 void 指针。 void 指针可以指向您想要的任何内容,从 int 到 int ***。 所以你可以简单地使用以下代码:
#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;
}