繁体   English   中英

为什么(void **)类型可以赋值给(void *)或(int *)?

[英]why (void **) type can be assigned to (void *) or (int *)?

这是我的C代码:

int main()
{
    void * ptr_void;
    void ** ptr_2void;
    ptr_void = ptr_2void;
    return 0;
}

我只是想知道为什么这段代码有效? 我已经(void *)分配了(void *) (void **) ,编译器甚至在没有警告的情况下传递它。 这种类型看起来不匹配。 以下代码(void **)分配给(int *)也有效。

int main()
{
    int * ptr_int;
    void ** ptr_2void;
    ptr_int = ptr_2void;
    return 0;
}

任何人都能弄清楚什么是(void *)东西?

void指针的类型转换为隐式指向任何其他数据类型的指针。 编译器不会显示任何警告。 类似地,从任何类型的指针到void *类型转换也可以在没有警告的情况下工作。

除了void指针之外,如果您尝试隐式地从一种指针类型转换为另一种指针类型,则编译器将发出警告。

例如,考虑下面给出的代码,它会给你警告“ assignment from incompatible pointer type ”。

  int *intptr;
  void *voidptr;
  void **vvptr;
  int intval=123;
  voidptr=&intval;
  vvptr=voidptr;
  intptr=vvptr; 

导致警告的代码行是intptr=vvptr; 因为intptr是一个integer pointervvptr是一个void **类型的指针。 它们都不是void *指针,因而是一个警告。

为了避免此警告,您必须显式地将void **类型转换为int *类型。 如果更改行intptr=vvptr; to intptr=(int *)vvptr; 然后编译器不会显示警告。

区分转换演员是很重要的。

转换将一种类型的值转换为另一种类型的值。 强制转换是显式指定转换的运算符(由括号中的类型名称组成)。 转换可以是显式的(由强制转换运算符指定)或隐式转换。 大多数指针转换需要一个强制转换操作符 涉及void*指针转换是例外。

任何指向对象的类型(或指向不完整的类型)的值都可以转换为void*并返回其原始类型; 保证结果指针与原始指针的比较相等。

在赋值中(或者将参数传递给函数或在return语句中),可以隐式地执行到void*的转换,而不使用强制转换运算符。

在您的第一个代码示例中:

void * ptr_void;
void ** ptr_2void;
ptr_void = ptr_2void;

允许赋值是因为void**可以在void**转换的情况下转换为void* 这里没有什么特别的void** ; 指向任何东西的指针可以在没有强制转换的情况下转换为void* void*是通用指针类型; void** 不是通用的指针指针类型,实际上没有通用的指针指针类型。)

在您的第二个代码示例中:

int * ptr_int;
void ** ptr_2void;
ptr_int = ptr_2void;

转让无效 ; 这是违反约束的行为 int*void**之间没有隐式转换,因为这两种类型都不是void* 任何符合要求的C编译器都必须为赋值发出诊断消息。 在某些情况下,诊断可能是一个警告,编译器可能会生成隐式转换,就像您编写了一个强制转换一样。 在其他情况下,编译器可能需要其他选项才能使其诊断此违规。

请注意,上述内容不适用于函数指针。 任何函数指针类型都可以转换(使用强制转换)到任何其他函数指针类型,将函数指针转换为void* ,反之亦然,具有未定义的行为(尽管某些编译器可能支持)。

void**void*是不同的类型。 int*void**也是不同的类型。 但正如Barmar所说, any data pointer type can be cast to/from void*. 这意味着您可以将int*void* ,但是您无法将int*void** ,因为void**没有相同的特殊属性。

gcc应该发出警告:

warning: assignment from incompatible pointer type [enabled by default]

     ptr_int = ptr_2void;

看到这个问题: 传递给void **而不是void *会让编译器抱怨类型,为什么?

void *是一种可以隐式转换为任何对象指针类型的类型。 void **不是 - 所以虽然你可以将char *分配给void *,但你不能对char **和void **做同样的事情。

原因是它们是不兼容的类型:char **指向char *,void **指向void *,因此它们的基类型不匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM