【问题标题】:how to take input in c(not in c++) irrespective of datatype? I want to have a generic variable which can store any kind of datatype variable [closed]无论数据类型如何,如何在c(不是c ++)中输入?我想要一个可以存储任何类型数据类型变量的通用变量[关闭]
【发布时间】:2013-03-31 19:57:30
【问题描述】:

实际上,我想要一个变量,它可以接收各种值,无论是 int、float 还是 char。谁能告诉我一种方法来做到这一点。但程序应该是 C 语言(而不是 C++)。

【问题讨论】:

  • 最佳实践取决于您将如何使用它们以及处理方式因变量类型而异。
  • 考虑使用动态类型的编程语言来实现应用程序的这一部分,并在 C 中实现对性能至关重要的部分。起初可能很难混合使用不同的编程语言对于一个单一的应用程序,但当你学会了它,这将是一个真正的祝福。

标签: c types type-systems


【解决方案1】:

将输入读取为文本字符串(字符数组)。然后分析一下:

  • 它是一个有效的整数字符序列吗?如果是这样,请将其转换为整数(以适合它的为准:signed charshortintlonglong long 或相同的unsigned 变体)
  • 它是浮点数的有效字符序列吗?如果是这样,请将其转换为 floatdoublelong double)
  • 否则它是一个字符串(除非你想有一个单一的字符类型)

完成后,将转换后的值放入相应的联合成员中并设置类型:

typedef struct
{
  int Type; // tells which one of the below holds the value
  union
  {
    signed char sc;
    unsigned char uc;
    short s;
    unsigned short us;
    int i;
    unsigned ui;
    long l;
    unsigned long ul;
    long long ll;
    unsigned long long ull;
    float f;
    double d;
    long double ld;
    char* str;
    char ch;
  } Value;
} tValue;

请注意,看起来像整数的东西可能不适合最大的整数类型,在这种情况下,您可以选择将其转换为浮点值,可能会丢失精度。否则你可能会说这是一个错误并适当地处理它。

另外,在转换浮点数时,您可能应该先从较大的类型开始 (long double),然后尝试下一个较小的类型(double 然后float),看看这两种情况下的值是否相同,在这种情况下,您可以选择较小的类型。

【讨论】:

  • 嗨,Alexey,Thnx 4 你的回应。我也知道它可以通过 void 指针完成,然后进行类型转换,但我想要的是在链表数据中输入任何类型的内容,而不使用 c 中的 void 指针。问我的问题就像你需要在链表中输入任何类型的输入,无论是 int、float 还是 char,但之前不知道它的类型,另一个条件是不使用 void 指针。
  • 我的回答中没有指向void 的指针。
【解决方案2】:

C 是一种强大的静态类型语言,因此在您所要求的意义上,您不能拥有动态变量。我猜你可以有一个 void 指针 (void*) 来指向任何东西,但这真的不是推荐的方法(你怎么知道要取消引用它是什么?)。

【讨论】:

  • 嗨乌托邦,Thnx 4 你的回应。我也知道它可以通过 void 指针完成,然后进行类型转换,但我想要的是在链表数据中输入任何类型的内容,而不使用 c 中的 void 指针。问我的问题就像你需要在链表中输入任何类型的输入,无论是 int、float 还是 char,但之前不知道它的类型,另一个条件是不使用 void 指针。
  • 正如我所提到的,C 是一种强大的静态类型语言,这意味着它需要在编译时了解每个变量的类型。其他人提到使用联合,这可能是根据您的要求的最佳解决方案,但您仍然需要了解它实际存储的数据类型才能正确提取它。您可以将数据存储为一个结构,其中包含数据的联合和类型的标志,然后在获取数据时解析该标志并检索正确的值,但每次检索都会导致大量代码膨胀。
【解决方案3】:

您应该始终使用对您的应用程序有意义的类型,但如果您真的需要“无类型”数据元素,您可以使用 void * 来实现,然后通过类型转换来使用它传递给它的任何内容:

void *myvar = malloc(100);  // set up typeless element

*(int *)myvar = 10;         // cast to an int and save an int
printf("%d\n", *(int *)myvar);  // print as an int

*(float *)myvar = 10.25;    // cast to a float and save a float
printf("%f\n", *(float *)myvar); // print as a float

【讨论】:

  • 使用max(sizeof(int), sizeof(float)) 可能比使用任意 100 更好。
  • 嗨迈克,Thnx 4 你的回应。我也知道它可以通过 void 指针完成,然后进行类型转换,但我想要的是在链表数据中输入任何类型的内容,而不使用 c 中的 void 指针。问我的问题就像你需要在链表中输入任何类型的输入,无论是 int、float 还是 char,但之前不知道它的类型,另一个条件是不使用 void 指针。
  • @Mayank - 字面上 no 类型知识(意味着只是将“任何东西”保存到变量中)没有办法在 C 中执行此操作。您需要进行类型转换或设置一个指示类型的标志。
【解决方案4】:

使用 void 指针存储变量的地址并进行类型转换以获取“每种”类型的返回值。联合你仍然必须事先知道你要使用什么类型。 要在宏中使用,请查找 gcc typeof

【讨论】:

  • 嗨阿巴苏,Thnx 4 你的回应。我也知道它可以通过 void 指针完成,然后进行类型转换,但我想要的是在链表数据中输入任何类型的输入,而不使用 c 中的 void 指针。问我的问题就像你需要在链表中输入任何类型的输入,无论是 int、float 还是 char,但之前不知道它的类型,另一个条件是不使用 void 指针。
【解决方案5】:

您的问题有两个答案。一种是使用 unions(如果您仅限于 int、char 和 float)。另一种是致命的void *类型。它们都不是好的编码习惯。 也许你应该改变问题:)

union {
  int i;
  char c;
  float f;
} u;

【讨论】:

  • “它们都不是好的编码实践”[需要引用]
  • 根据 jsf 编码标准 (4.20) 和 MISRA 工会应该被禁止。 void * 也消除了类型安全性,并且您很容易在单词后出现类型错误。虽然在 c 中你需要在某些特定情况下使用它们
  • 嗨 Beehorf,Thnx 4 你的回应。我也知道它可以通过 void 指针完成,然后进行类型转换,但我想要的是在链表数据中输入任何类型的内容,而不使用 c 中的 void 指针。问我的问题就像你需要在链表中输入任何类型的输入,无论是 int、float 还是 char,但之前不知道它的类型,另一个条件是不使用 void 指针。
猜你喜欢
  • 2013-07-12
  • 2019-11-24
  • 2020-11-10
  • 2021-11-18
  • 2021-04-21
  • 2019-08-09
  • 2019-07-11
  • 2012-07-22
  • 1970-01-01
相关资源
最近更新 更多