使用参数为void的函数交换2个字符串指针**

时间:2013-08-20 17:00:30

标签: c pointers

以下代码无法编译:

void swap(void **p, void **q) {
  void *tmp;
  tmp = *p;
  *p = *q;
  *q = tmp;
}

int main(void) {
  char *s[] = {"help" , "please"};
  swap(&s[0], &s[1]);
  return 0;
}

虽然这段代码编译并运行得很好:

void swap(void **p, void **q) {
  void *tmp;
  tmp = *p;
  *p = *q;
  *q = tmp;
}

int main(void) {
  char *s[] = {"help" , "please"};
  swap((void **) &s[0], (void **) &s[1]);
  return 0;
}

为什么需要施法?

3 个答案:

答案 0 :(得分:3)

是的,除了已经存在的答案之外,指出void **char **不同:您的代码调用未定义的行为,因为指针不兼容类型。这是你真正想要的:

void swap(void *p1, void *p2, size_t size)
{
    unsigned char buf[size];
    memcpy(buf, p1, size);
    memcpy(p1, p2, size);
    memcpy(p2, buf, size);
}

并称之为:

const char *s[] = { "help", "please" }; // also note the use of `const' for string literals
swap(&s[0], &s[1], sizeof(s[0]));

答案 1 :(得分:1)

第一个代码中的指针分配错误不一致。在C类型的字符串文字是char[N]其中N是字符数。请注意,大多数表达式char[N]很容易衰减到char*

根据您的声明char *s[] = {"help" , "please"};s[i]的类型为char*(行为char[N]已堕入char*)。

当您通过&s[i]时,您将传递与char**不兼容的void**。第二个代码有效,因为您在函数调用中将其转换为void**

void*可以分配任何地址类型,但必须为void**分配void*类型变量的地址。

如果您只有字符串数组,那么在第一版交换函数中,您可以将void替换为char,然后您就可以不进行类型转换。

答案 2 :(得分:0)

由于传递函数的内容,该转换使示例编译。

char *var[];在许多方面与char **var;

相同

话虽如此,您正在向函数传递一个引用/地址数组成员之一(s[0])。

另一个更突出的问题是,该函数接受void指针,并传递字符指针(没有转换)。