【问题标题】:invalid use of void expression in c printf在 c printf 中无效使用 void 表达式
【发布时间】:2019-02-28 20:14:52
【问题描述】:

我正在学习 c。 我有这个结构:

typedef struct mystuff
{
    char* name;
    int      val;
}MyStuff;

我主要调用:

MyStuff fruit1 ={"watermellon", 1};

我将数据传递给 insertLifo:

insertLifo(myQueue, &fruit1);

这是函数

bool insertLifo(LifoQueue queue, void* data)

在函数内部我想打印数据以便调试:

printf("insertLifo()  %s \n", *data);

我收到以下错误:

MemAlloc.c: In function ‘insertLifo’:
MemAlloc.c:42:32: warning: dereferencing ‘void *’ pointer [enabled by default]
  printf("insertLifo()  %s \n", *data);
                                ^
MemAlloc.c:42:2: error: invalid use of void expression
  printf("insertLifo()  %s \n", *data);
  ^

我试过了:

printf("insertLifo()  %p \n", (void*)*data);

还有其他方式。

我想完全了解如何使用指针

【问题讨论】:

  • 你希望它打印什么?
  • 数据的值。在这个例子中是“西瓜”
  • 您的data 的类型为void *,因此表达式*data 的类型为void。对于void 类型的值,您几乎无能为力。但是,您可以将指针转换为不同的指针类型。取消引用这种强制转换的结果可能是有意义的。但是如果你知道要转换成什么类型​​,那么你应该首先声明一个正确类型的指针,这样就不需要转换了。
  • 题外话:后进先出是一个堆栈,而不是队列
  • 我尝试转换为 char* 但没有成功。

标签: c pointers printf


【解决方案1】:

void * 是一个通用指针。它指向的数据类型未知,因此您不能取消引用void *

您应该更改您的函数以接受MyStuff * 并修改printf 调用以打印每个字段。

bool insertLifo(LifoQueue queue, MyStuff* data)
{
    ...
    printf("insertLifo()  name=%s val=%d \n", data->name, data->val);
    ...

【讨论】:

    【解决方案2】:

    您的错误在于您如何声明insertLifo(),因为您错误地声明了第二个参数。应该是:

    bool insertLifo(LifoQueue queue, MyStuff* data)
    

    所以你可以通过引用传递变量。然后,你必须这样做:

    printf("bla bla %s", data->name);
    

    因为%s 格式说明符需要传递char * 类型的参数,就像name 一样。

    但是,正如我在对您的问题的评论中告诉您的那样,我们需要一个完整且可验证的示例才能进行诊断。你没有这样做,所以你得到不完整的回应。请阅读How to create a Minimal, Complete, and Verifiable example

    另一个错误是您可能还需要通过引用传递insertLifo() 的第一个参数,因为您可能需要修改该结构,如果您通过值传递它,它将被复制到函数中,并且您对它所做的任何修改都将在函数返回时丢失。

    最后,你说

    我想完全了解如何使用指针。

    嗯,这完全超出了这个应用程序的范围。 StackOverflow 只是帮助你纠正代码中的一个小问题,而不是教你如何编程。我可以说,许多人终其一生都在试图理解如何使用指针,但从未成功。这取决于很多方面,但你可以做的一件好事是买一本关于 C 的好书。

    【讨论】:

      【解决方案3】:

      为了打印指针地址,shell 使用 %p printf format 而不是用于字符串的 %s

      如果你需要一个字符串 printf 你可以使用以下:

      MyStuff *stuff = (MyStuff*)data;
      printf("insertLifo() data=%p = {name=%s, val=%d} \n", data, stuff->name, stuff->val);
      

      【讨论】:

      • 谢谢。我会仔细研究这两个 cmet,以便完全理解它们。
      • %p 需要一个 void * 指针。您应该将stuff 转换为(void *)stuff 以获得完全的可移植性
      • C++ 是,即static_cast<const void*>(stuff),但C 不是。否则,您总是会转换为 memcmp、memcpy、memmove 等函数。
      • @VictorGubin 这些函数受控制隐式转换的原型影响,而 printf 参数则不受(chqrline 的评论是正确的)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 2014-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      相关资源
      最近更新 更多