如何处理类型在运行时确定的数组的声明和分配?

时间:2012-08-24 08:32:10

标签: c malloc type-conversion

假设我在磁盘上有五个二进制文件。这五个文件以二进制格式编码数字序列,除了它们都有不同的类型。假设它们是SHORT INT,INT,LONG,FLOAT和DOUBLE。我们将让文件中也存储不同数量的数字。

现在假设我有一个程序在执行时会询问用户

  

输入您要加载的文件名:

用户可以选择这五个文件中的一个。我希望程序将这些文件加载​​到一个数组中,以便进行进一步的计算。

我们可以假设存在两个函数:一个返回一个整数值,该值对文件的类型(即SHORT INT,INT,LONG,FLOAT或DOUBLE)进行编码(称之为“getfiletype”),另一个返回文件中的数字(例如,1000,9338,8131,0等)(称之为“getfilesize”)。实际的条目数可能是数十亿的数字。如果可能的话,在程序中我想为数组使用相同的名称(比如“数组”),它保存用户选择的任何文件的值。这样我可以拥有像

这样的块
N=getfilesize("pickedfile.dat");
for(i=0 ; i<N ; i++ ) {
    doublearray[i]==2.0*(double)array[i]+7.12;
}

可以转换数组。在这里,我引入了一个名为“doublearray”的新数组来保存转换后的值。然后,这个双数组将被写入DOUBLE格式的文件或在写入其他格式之前转换。

我该怎么办?彻底糊涂了。

2 个答案:

答案 0 :(得分:2)

您的程序可以创建一个静态(或全局)void *数组,该数组将由最新调用getfiletype()或getfilesize()填充。然后你必须适当地施放它(正如你在你的例子中专门做的那样)。假设您已经解决了文件数据方面的加载问题。

虽然这种方法在使用方面并不是非常干净(依赖静态或全局会限制您执行不同对话的选项 - 特别是当前的情况,您必须确保以顺序方式运行)。 / p>

更清洁的API可能就是这样的:

enum TypeEnum { SHORT_INT, INT, LONG, FLOAT, DOUBLE };
void* getfiledata(char *filename, unsigned int *size, TypeEnum *type);
#define GET_DATA_AND_CAST(filename, array, array_size) \
    do { \
        TypeEnum type; \
        void* arr = getfiledata(filename, array_size, &type); \
        switch(type) { \
            case SHORT_INT: \
                array = (short*)arr; break; \
            case INT: \
                array = (int*)arr; break; \
            case LONG: \
                array = (long*)arr; break; \
            case FLOAT: \
                array = (float*)arr; break; \
            case DOUBLE: \
                array = (double*)arr; break; \
            default: \
                // ASSERT \
        } \
    } while(0)

然后您可以像:

一样使用它
void process_doubles(void *array) {
    double to_conv[];
    unsigned int size;
    GET_DATA_AND_CAST("pickedfile.dat", to_conv, &size);

    for(i=0; i<size; ++i ) {
        doublearray[i] = 2.0 * to_conv[i] + 7.12;
    }
}

恕我直言C ++会使这更好(因为你可以使用模板),但由于这个问题只用C标记我只是在C中呈现选项。

答案 1 :(得分:1)

您可以使用void *指针存储指向任何数据类型的指针。

int num_elements = getfilesize();
size_t element_size;
switch (getfiletype()) {
    case SHORT_INT: element_size = sizeof(short int); break;
    ...
}
void *array = malloc(num_elements * element_size);

...

void process_doubles(void *array) {
    for(i=0 ; i<getfilesize("pickedfile.dat") ; i++ ) {
    doublearray[i] = 2.0 * ((double *) array)[i] +7.12;
}

请注意,您需要在指向它之前强制转换数组指针