【问题标题】:How to dereference a void pointer inside strlen?如何取消引用strlen中的空指针?
【发布时间】:2019-09-14 17:07:25
【问题描述】:

我编写了一个与符号无关的函数以十六进制格式打印char 字符串。

void print_char2hex(void* cp) {

    const char *arr = (char *) cp;

    size_t i;

    for(i = 0; i < strlen( arr ); i++) {
        printf("%02X ", 0xFF & arr[i]);
    }
}

为什么下面的代码不能编译?

void print_char2hex(const void *cp) {

    size_t i;

    for (i = 0; i < strlen( * (const char *) cp ); i++) {
        printf("%02X ", 0xFF & cp[i]);
    }
}

这是错误信息:

passing argument 1 of strlen makes pointer from integer without a cast [-Wint-conversion]

【问题讨论】:

  • 您将 $cp$ 类型转换为 $const char*$,然后将取消引用的值传递给 $strlen$。基本上,您试图将 $const char$ 传递给 $strlen$。删除取消引用。
  • 此外,无法取消引用指向 void(也不是索引)的指针
  • @RandomPerfectHashFunction 你打算在那里使用反引号......
  • @AnttiHaapala 是的,我没有看到下面的 $cp[i]$。这也需要在索引之前进行类型转换。反引号是什么意思?
  • 反引号是`字符(也称为重音);它分隔内联code blocks

标签: c pointers dereference


【解决方案1】:

strlen 需要 char*。您正在传递char。通过删除取消引用更改为:strlen( (const char *) cp )

printf 语句也有问题。你也需要在那里投cp。改为:printf("%02X ",0xFF &amp; ((const char*)cp)[i]);

另外一点是,在循环头中对strlen 进行函数调用会影响性能。也许优化器可以修复它,但为了确保最好为此使用额外的一行。

size_t len = strlen( (const char *) cp );
for(i = 0; i < len ; i++) {

如果你问我,它看起来也更清楚。

【讨论】:

  • 在上一个代码示例中,您的意思是size_t len = strlen( (const char *) cp );
  • 能否进一步解释((const char*)cp)[i],因为事实证明我马上就得到了(const char *) cp,但我缺少一些关于为什么(const char *)cp[i] 不够用的信息。
  • @OneArb 因为那将等于(const char *)(cp[i]),这是不同的。
  • 我可以阅读什么来理解差异,因为我知道“我不知道”,但我不知道“我不知道什么”。
  • @OneArb 归结为运算符优先级和关联性。这并不比x*y+z*w(x*y)+(z*w) 相同的事实更奇怪。
【解决方案2】:

如何在 strlen 中取消引用 void 指针?

strlen(const char *) 内,不需要取消引用。只需传递cp

void print_char2hex(const void *cp) {
  size_t len = strlen(cp);
  ...

然而strlen() 不需要。

void print_char2hex(const void *cp) {
  const unsigned char *p = cp;
  while (*p) {
    printf("%02X ", *p++);
  }
}

【讨论】:

  • 使用*p != '\0'的意义何在? stackoverflow.com/questions/32153715/…
  • @OneArb while (*p) 在功能上与while (*p != '\0') 相同。编码到您小组的编码标准。如果没有,代码清晰。
【解决方案3】:

0xFF &amp; 是不必要的,较短的解决方案是:

void print_char2hex(const void *cp) {
  const unsigned char *p = cp;
  while (*p != '\0') {
    printf("%02X ", (const unsigned char) *p++);
  }
}

【讨论】:

    猜你喜欢
    • 2013-02-20
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多