C中棘手的指针算法:** k

时间:2019-02-20 01:57:51

标签: c pointers

假设k是指向C中整数的指针。

对于表达式** k,当我们尝试在赋值运算符(“ =”)的右侧对其求值时,该值是否非法?

这是我的想法:

** k实际上是*(* k)。当我们取消对k的引用时,我们得到一个整数值。然后,我们尝试取消引用整数,这是非法操作。

但是我的教科书说,右侧的这种表达实际上是合法的。

为什么呢?

2 个答案:

答案 0 :(得分:5)

C 2018标准在第6.5.3.2节第2段中指出:“一元*运算符的操作数应具有指针类型。”如果k是指向整数的指针,则*k是一个整数,不是指针类型,因此它不能是一元*运算符的操作数。因此,诸如x = **k之类的表达式违反了此规则。

第6.5.3.2 2条中的规则是一个约束,这意味着需要合格的编译器才能为其生成诊断消息,并且C标准未定义行为。

从技术上讲,C编译器除了发布诊断消息外,还可以接受表达式并根据需要进行定义。我不知道有谁这样做,而且没有普通的编译器这样做。

很有可能字符**k可能会出现在较大的表达式中,而它们不能同时充当一元*运算符,例如x = y**k中的等效于{{1 }},其中第一个x = y * *k是二进制乘法运算符。您应该显示课本中显示的精确文本

答案 1 :(得分:0)

除了标准所说的以外,从根本上取消引用int毫无意义。假设编译器愿意假设int可以直接转换为指针(BIG假设)。编译器会假定它是哪种类型的指针?唯一安全的假设是void*。并且取消引用void*毫无意义,因为即使分配给已知类型,指针的类型仍然很重要:

  unsigned int n = 0xFFFFFFFF;
  void *pN = &n;
  unsigned int fromIntPtr = *(unsigned int*)pN;
  unsigned int fromCharPtr = *(unsigned char*)pN;
  printf("%X\n", fromIntPtr);
  printf("%X\n", fromCharPtr);

输出:

FFFFFFFF
FF

由于缺少一种指针,编译器可能可以根据LHS表达式来推断unsigned int*。那是1)愚蠢的推论和2)C并没有真正推论类型。 (将类型化的RHS转换为不同类型的LHS值是不推断的:))