在C中创建和初始化用户定义类型的数组

时间:2012-12-11 22:50:24

标签: c arrays pointers malloc command-line-arguments

我最近开始学习C,所以如果我的问题非常基本或不清楚,请道歉。

我将3个命令行值传递给我的程序。 (TYPE,LENGTH,VAL)。使用这些值我想在TYPE类型和长度为LENGTH的堆上创建一个数组,并将所有元素初始化为VAL。例如,

float 8 4:将创建一个包含8个元素的float数组,每个元素的值为4.

char 4 65:将创建一个包含4个元素的char数组,每个元素的值都为“A”。

确定长度是直截了当的。但我正在努力确定如何初始化指向数组和VAL的​​指针。

以下是我到目前为止所尝试的内容(未成功)。我正在初始化一个char指针,但是我知道这是不正确的,因为我可能需要一个float或int指针。我也使用基于TYPE的第一个字符的switch语句,对我来说这看起来非常h​​acky。

int main (int argc, char *argv[]){

        int LENGTH;
        char *ptr;

        LENGTH = atoi ( argv[2] );


        switch( *argv[1] ){
                case 'f':
                        printf("Type is float\n");
                        ptr = (float *)malloc(LENGTH * sizeof(float));
                        break;
                case 'c':
                        printf("Type is char\n");
                        ptr = (char *)malloc(LENGTH * sizeof(char));
                        break;
                case 'i':
                        printf("Type is int\n");
                        ptr = (int *)malloc(LENGTH * sizeof(int));
                        break;
                default:
                        printf("Unrecognized type");
                        break;
        }

        while( i < arrayLength ){
                *ptr[i] = *argv[3];
                i++;
        }

        free ( ptr );

        return 0;
}

我还可以看到问题的初始化元素的问题。初始值取决于TYPE,因此需要转换。

我想知道的是,如果事先不知道TYPE,我该如何创建指针或初始化值?我可能完全从错误的方向看这个问题,所以任何建议都会非常感激。

由于

3 个答案:

答案 0 :(得分:2)

如果想要一个可以容纳不同类型的C变量,你需要使用类似的联合:

typedef union {
    float f;
    int i;
    char c;
} arg_type;

然后,声明为arg_type argument;的变量将足以容纳联盟的最大成员。可以像结构成员一样访问它们,例如:

argument.f = 0.0;
argument.c = '\n';
argument.i = 12;

但是,您需要跟踪您在那里存储的类型,因为编译器无法知道您使用了哪种类型。一旦定义了union,你就可以

char var_type = 'f';
arg_type *p = mallocLENGTH * sizeof(arg_type);
p[0].f = atof(argv[i])

尽管如此,确保你的方法是正确的,这是一种痛苦。例如:

argument.f = 1234.56;
putchar(argument.c);

将编译,但其行为未定义。将内容保留为argv字符形式并保存解析通常更容易,直到您想要使用特定类型。

答案 1 :(得分:2)

以下是修改后的代码(请参阅下面的注释):

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // for memset()

int main (int argc, char *argv[]){

        int LENGTH;
        int i;

        void *ptr = NULL;

        if(argc < 4)
        {
            fprintf(stderr, "Usage: %s type len data\n", argv[0]);
            return 1;
        }

        LENGTH = atoi ( argv[2] );


        switch( *argv[1] ){
                case 'f':
                        printf("Type is float\n");
                        ptr = (float *)malloc(LENGTH * sizeof(float));
                        for(i = 0; i < LENGTH; i++)   // Cannot use memset in that case: memset(3) only works with integers.
                            ((float *)ptr)[i] = (float)atof(argv[3]);
                        for(i = 0; i < LENGTH; i++)
                            printf("[%d]: %lf\n", i, ((float *)ptr)[i]);
                        break;
                case 'c':
                        printf("Type is char\n");
                        ptr = (char *)malloc(LENGTH * sizeof(char));
                        memset(ptr, (char)atoi(argv[3]), LENGTH);
                        for(i = 0; i < LENGTH; i++)
                            printf("[%d]: %c\n", i, ((char *)ptr)[i]);
                        break;
                case 'i':
                        printf("Type is int\n");
                        ptr = (int *)malloc(LENGTH * sizeof(int));
                        memset(ptr, (int)atoi(argv[3]), LENGTH);
                        for(i = 0; i < LENGTH; i++)
                            printf("[%d]: %d\n", i, ((int *)ptr)[i]);
                        break;
                default:
                        printf("Unrecognized type\n");
                        break;
        }

        if(ptr == NULL)
            return 1;

        free ( ptr );

        return 0;
}

然而,正如其他人指出的那样,这样做毫无意义。使用类型的原因是要知道两件事:

  1. 数据的大小
  2. 如何解释它
  3. 你在这里想要实现的是笨拙的尝试来完成操作系统的工作。

    要明确:内存是一个连续的存储,操作系统将其标记为“已分配”(通过malloc(3)等函数)。当它这样做时,程序必须知道要知道要读取什么的数据类型(指针只是一个地址),以及如何解释它(int s的存储方式与{{float不同。 1}} s是)。

    如果你真的有兴趣学习这些东西(如何存储数据,计算机的工作方式如何,以及最低级别而不是C#),我建议你阅读:

    1. MIPS assembly tutorial(谷歌的第一个相关答案,任何MIPS asm课程都可以)

    2. x86 Assembly, 6th ed.如果你有钱的话。

    3. 另外,如果你想测试MIPS程序集,mars是一个MIPS程序集模拟器,它运行正常(并且是免费的)。

      我很高兴看到人们仍在努力学习C.

答案 2 :(得分:1)

用C语言写这些通用的东西很困难.C ++更合适。但是如果你需要它在C中,那么我要做的是声明3个不同的指针,float *,int *,char *。我将分配并初始化与用户输入相对应的那个。但请记住,您需要携带一些变量来标记整个程序中所选类型的内容,并在需要使用数组时使用if语句。