我最近刚开始学习C,如果我的问题很基本或不清楚,我很抱歉。
我正在将3个命令行值传递给我的程序。(类型、长度、VAL)。使用这些值,我想在类型为type和长度为length的堆上创建一个数组,并将所有元素初始化为VAL
float 8 4:将创建一个包含8个元素的float数组,每个元素的值为4。
char 4 65:将创建一个包含4个元素的char数组,每个元素的值都为"a"。
确定长度是直接的。但我很难确定如何初始化指向数组和VAL的指针。
以下是我迄今为止的尝试(没有成功)。我正在初始化一个char指针,但我知道这是不正确的,因为我可能需要一个float或int指针。我还使用了一个基于TYPE的第一个字符的switch语句,对我来说这似乎很棘手。
int main (int argc, char *argv[]){
int LENGTH;
char *ptr;
LENGTH = atoi ( argv[2] );
switch( *argv[1] ){
case 'f':
printf("Type is floatn");
ptr = (float *)malloc(LENGTH * sizeof(float));
break;
case 'c':
printf("Type is charn");
ptr = (char *)malloc(LENGTH * sizeof(char));
break;
case 'i':
printf("Type is intn");
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的情况下,如何创建指针或初始化值?我可能完全从错误的方向看待这个问题,所以任何建议都将不胜感激。
感谢
以下是修改后的代码,以满足您的要求(请参阅下面的注释):
#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 datan", argv[0]);
return 1;
}
LENGTH = atoi ( argv[2] );
switch( *argv[1] ){
case 'f':
printf("Type is floatn");
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]: %lfn", i, ((float *)ptr)[i]);
break;
case 'c':
printf("Type is charn");
ptr = (char *)malloc(LENGTH * sizeof(char));
memset(ptr, (char)atoi(argv[3]), LENGTH);
for(i = 0; i < LENGTH; i++)
printf("[%d]: %cn", i, ((char *)ptr)[i]);
break;
case 'i':
printf("Type is intn");
ptr = (int *)malloc(LENGTH * sizeof(int));
memset(ptr, (int)atoi(argv[3]), LENGTH);
for(i = 0; i < LENGTH; i++)
printf("[%d]: %dn", i, ((int *)ptr)[i]);
break;
default:
printf("Unrecognized typen");
break;
}
if(ptr == NULL)
return 1;
free ( ptr );
return 0;
}
不过,正如其他人指出的那样,这样做毫无意义。之所以使用类型是为了了解两件事:
- 数据的大小
- 如何介入
您在这里试图实现的是对操作系统工作的笨拙尝试。
需要明确的是:内存是一个连续的存储,当它被分配时,操作系统会将其标记为"已分配"(通过malloc(3)
等函数)。当它这样做时,程序必须知道数据的类型,才能知道要读取什么(指针只是一个地址),以及如何解释它(int
s的存储方式与float
s不同)。
如果你真的有兴趣学习这些东西(数据是如何存储的,计算机是如何更普遍地工作的,并且是在比C#更低的水平上),我建议你阅读:
MIPS组装教程(来自谷歌的第一个相关答案,任何MIPS asm课程都可以)
x86汇编,第6版。如果你有钱的话。
此外,如果您想测试MIPS程序集,mars是一个工作正常(免费)的MIPS程序集中模拟器。
我很高兴看到人们仍在努力学习C.
当在C中想要一个可以容纳不同类型的变量时,需要使用一个联合,比如:
typedef union {
float f;
int i;
char c;
} arg_type;
然后,声明为arg_type argument;
的变量将足够大,可以容纳并集的最大成员。它们像结构成员一样被访问,例如:
argument.f = 0.0;
argument.c = 'n';
argument.i = 12;
但是,您需要跟踪存储在其中的类型,因为编译器不知道您使用了哪种类型。一旦定义了并集,就可以进行
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字符形式并保存解析更容易,直到您想要使用特定类型为止。
用C编写这样的通用内容很困难。C++更合适。但如果你在C中需要它,那么我要做的就是声明3个不同的指针,float*,int*,char*。我会分配并初始化与用户输入相对应的一个。不过,请记住,在整个程序中,您需要携带一些变量来标记所选类型,并在需要使用数组时使用if
语句。