我最近开始学习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语句,对我来说这看起来非常hacky。
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,我该如何创建指针或初始化值?我可能完全从错误的方向看这个问题,所以任何建议都会非常感激。
由于
答案 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;
}
然而,正如其他人指出的那样,这样做毫无意义。使用类型的原因是要知道两件事:
你在这里想要实现的是笨拙的尝试来完成操作系统的工作。
要明确:内存是一个连续的存储,操作系统将其标记为“已分配”(通过malloc(3)
等函数)。当它这样做时,程序必须知道要知道要读取什么的数据类型(指针只是一个地址),以及如何解释它(int
s的存储方式与{{float
不同。 1}} s是)。
如果你真的有兴趣学习这些东西(如何存储数据,计算机的工作方式如何,以及最低级别而不是C#),我建议你阅读:
MIPS assembly tutorial(谷歌的第一个相关答案,任何MIPS asm课程都可以)
x86 Assembly, 6th ed.如果你有钱的话。
另外,如果你想测试MIPS程序集,mars是一个MIPS程序集模拟器,它运行正常(并且是免费的)。
我很高兴看到人们仍在努力学习C.
答案 2 :(得分:1)
用C语言写这些通用的东西很困难.C ++更合适。但是如果你需要它在C中,那么我要做的是声明3个不同的指针,float *,int *,char *。我将分配并初始化与用户输入相对应的那个。但请记住,您需要携带一些变量来标记整个程序中所选类型的内容,并在需要使用数组时使用if
语句。