【问题标题】:c printf function dynamic type determinationc printf函数动态类型判断
【发布时间】:2012-12-27 11:22:11
【问题描述】:

我正在尝试使用 void 指针在 c 中实现一个通用堆栈以指向数据。结构是这样的

struct record{
  void* data;
  struct record* previousRecord; 
};

其中 void 指针数据是指向堆栈位置将保存的数据的指针。如果我实现这样的推送功能

struct record* push(struct record* tos, void* data){
  struct record* newtos = (struct record*)malloc(sizeof(struct record));
  newtos->data = data;
  newtos->previousRecord = tos;
  return newtos;
}

并将几个整数指针和字符串指针压入堆栈,有什么方法可以打印这些指针引用的值。我的问题是,如果我使用 printf 函数,我必须在代码中指定要打印的值的数据类型,但是存储在堆栈中的值只能在运行时确定

【问题讨论】:

    标签: c linked-list stack runtime printf


    【解决方案1】:

    如果您想以正确的格式打印数据,您必须知道它的类型。

    #include <stdio.h>
    
    enum datatype
    {
      DATATYPE_STRING, DATATYPE_INTEGER
    };
    
    struct record
    {
      enum datatype type;
      void *data;
      struct record *next;
    };
    
    void print_record(struct record *p)
    {
      switch (p->type)
      {
        case DATATYPE_STRING:
          printf("%s\n", (char *)p->data);
          break;
        case DATATYPE_INTEGER:
          printf("%d\n", *(int *)p->data);
          break;
      }
    }
    

    【讨论】:

      【解决方案2】:

      有了地址怎么知道数据的类型,可以是字符串也可以是整数地址:

      但是您可以在您的 record 定义中保留一个额外的字段,关于存储在 data part 中的值的类型,如下所示:

      typedef enum { STRING, INT, CHAR} type;
      struct record{
        type t;
        void* data;
        struct record* previousRecord; 
      };
      

      并写一个通用的打印函数:

      int print(struct record  *r){  
      
        switch(r->t){
           case CHAR:     return printf("%c", *((char*)(r->data)));
           case INT:      return printf("%d", *((int*)r->data));        
           case STRING:   return printf("%s", (char*)r->data);        
           default:       return printf("Error");
        }
      } 
      

      Here is a Project/A book 这对于用 C 编写通用代码非常有帮助。

      【讨论】:

      • 我认为您的打印功能不正确。 r-&gt;data 是一个指针,而不是 char 或 int。你需要例如。 *(char*)r-&gt;data 在 CHAR 情况下。
      • @Anonymous 是的,你是对的......而且我使用的 %s 和 %c 格式相同 r->data 错误! ..谢谢匿名! ...你能再检查一次吗(因为包括复杂的类型转换)
      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多