在C中对指针进行类型转换

use*_*762 15 c pointers casting

我知道指向一种类型的指针可能会被转换为另一种类型的指针.我有三个问题:

  1. 在指点指针时应该记住什么?
  2. 结果指针可能会出现什么异常/错误?
  3. 什么是避免异常/错误的最佳做法?

Rin*_*g Ø 11

编写良好的程序通常不会使用很多指针类型转换.例如,可能需要对malloc使用ptr类型转换(声明(void *)malloc(...)),但在C中甚至不需要(虽然有些编译器可能会抱怨).

  int *p = malloc(sizeof(int)); // no need of (int *)malloc(...)
Run Code Online (Sandbox Code Playgroud)

但是在系统应用程序中,有时您希望使用技巧来执行二进制或特定操作 - 而C(一种接近机器结构的语言)很方便.例如,假设您要分析double的二进制结构(遵循IEEE 754实现),并且使用二进制元素更简单,您可以声明

  typedef unsigned char byte;
  double d = 0.9;
  byte *p = (byte *)&d;
  int i;
  for (i=0 ; i<sizeof(double) ; i++) { ... work with b ... }
Run Code Online (Sandbox Code Playgroud)

你也可以使用union,这是一个例子.

更复杂的利用可能是模拟C++多态,需要在某处存储"类"(结构)层次结构以记住什么是什么,并执行指针类型转换以使例如父类"类"指针变量为在某个时候指向派生类(另请参阅C++链接)

  CRectangle rect;
  CPolygon *p = (CPolygon *)&rect;
  p->whatami = POLY_RECTANGLE; // a way to simulate polymorphism ...
  process_poly ( p );
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,也许最好直接使用C++!

在开发开始之前,指针类型转换将被仔细地用于作为程序分析一部分的确定情况.

指针类型分类潜在的危险

  • 在没有必要时使用它们 - 这容易出错并使程序复杂化
  • 指向可能导致访问溢出的不同大小的对象,错误的结果......
  • 指向两个不同结构的指针s1 *p = (s1 *)&s2;:依赖于它们的大小和对齐可能会导致错误

(但公平地说,熟练的C程序员不会犯上述错误......)

最佳实践

  • 只有在你需要它们的时候才使用它们,并对这部分进行评论,以解释为什么它是必要的
  • 知道你在做什么 - 再一个熟练的程序员可能会毫不犹豫地使用大量的指针类型转换,即不要试图看,它可能在这样的系统/版本/操作系统上工作,并且可能不适用于另一个