在纯C中打印void类型

时间:2009-01-27 09:22:53

标签: c printf type-conversion void

我有像

这样的功能
void printMe (void *i)
{
    printf("%d", i);
}

我想传递一个无效指针并将其打印到屏幕上。 上面的例子很好,如果i是整数,浮点数或双精度数,但如果我是一个char则崩溃。 C中没有像我通常在C ++中使用的那样重载。 所以问题是这个,我们可以在C中创建一个函数来打印它作为参数的元素,如果是的话,这是怎么可能的,因为它现在完全无法实现。

4 个答案:

答案 0 :(得分:24)

Q1:所以问题是这样,我们可以用C创建一个函数来打印它的参数元素

答:不是你想要的方式。您必须将信息传递给函数,告诉它您传递的数据类型。

Q2:如果是,这怎么可能,因为此时它完全没有我。

答:因为无法做到,所以无法解决。没有与void *关联的元数据,编译器或运行时可以使用它来确定它们指向的类型。你需要

  1. 传递包含
    的结构 指针和有关什么的信息 指针指向(例如 枚举)。
  2. 传递一个额外的参数 有关指针的信息 指向
  3. 因为代码是唯一可以打印的地方是我指向的地址。

    void指针指向原始数据,printf假定您知道要打印的数据类型,它没有智能,也无法为您“弄清楚”。

    就这么简单。

    你可以做的是将类型信息传递给函数,但最终你会得到一些非常类似于printf的东西,你可以在其中传递一个格式化字符串,其中包含有关以下方案中数据的类型信息。

    希望这有帮助。

    另外。 。 。 “ C中没有超载,就像我通常在C ++中使用

    一样

    即使在c ++中,重载也发生在编译时,这里编译器无法知道将哪些数据传递给该函数,所以即使你习惯了重载,它也不会像这样工作(例如使用printf尝试同样的事情,但用C ++编译器编译它,你会得到完全相同的结果)。 实际上试试

    cout << i;
    

    在上面的函数中,它将给出我指向的地址,而不是i的“值”。 你需要在你获得它的价值

    之前施展我并将它去除它
    cout << *(int*)i;
    

    因此,为了使上述工作在C ++中,您需要有许多重载函数(或模板函数,这实际上是相同的,除了编译器为您推送函数),例如重载函数

    printMe(int i){...}
    printMe(double d){...}
    printMe(char c){...}
    printMe(char* string){...}
    

    在c中,您只需要为这些函数指定特定名称

    printInt(int i){...}
    printDouble(double d){...}
    printChar(char c){...}
    printString(char* string){...}
    

答案 1 :(得分:7)

首先,您要打印指针,而不是它指向的指针。要打印实际内容,您需要将*i传递给printf,而不是i

如果你真的想这样做,一个解决方案是:

void printMe (void *p, int typ) {
    switch(typ) {
        case TYP_INT: printf("%d", *((int*)p)); break;
        case TYP_CHR: printf("%c", *((char*)p)); break;
        /* and so on ... */
    }
}

答案 2 :(得分:0)

  

所以问题是这个,我们可以用C创建一个函数来打印它的参数元素

是的,我们可以。这样的函数已经是标准库的一部分 - 它被称为printf;)

由于C中没有编译时函数重载,因此必须以某种方式在运行时提供参数类型。 printf格式字符串可用于执行此操作,因此在已有可用解决方案时,实际上没有理由构建自己的包装函数。

答案 3 :(得分:0)

如果您尝试打印指针值,正确的用法为printf("%p", i);。 'd'说明符用于整数,'p'用于指针。你有责任让这些变得正确,如果把它们混淆就会发生坏事。

我不知道为什么这会导致char *而不是int *,并且你可能会遇到其他问题。如果它仍然以%p失败,那么其他东西就搞砸了。看看你是否可以安装某种内存监视器软件来检查悬空指针或双重释放()s,因为在那一点上,智能钱已经破坏了内存。