【问题标题】:C pointers arthmetic for arrays数组的 C 指针算术
【发布时间】:2023-01-30 16:50:30
【问题描述】:

我正在阅读 K&R 中关于数组运算的部分,遇到了一些奇怪的事情。我发布了整个段落作为上下文,但我主要关注粗体部分:

如果pq 指向同一数组的成员,则==!=<>= 等关系可以正常工作。例如,如果 p 指向比 q 更早的数组成员,则 p < q 为真。任何指针都可以有意义地与零进行相等或不相等的比较。但是对于不指向同一数组成员的指针的算术或比较行为是未定义的。 (有一个例外:数组末尾之后的第一个元素的地址可用于指针运算。)

我在这里得到了一些答案(C pointer arithmetic for arrays),但我有以下疑问:

我对此有疑问,因为以下代码似乎可以在取消引用和比较的情况下使用,而不会引发任何异常或错误:

#include <stdio.h>
    
int main() {
    int a[5] = { 1, 2, 3, 4, 5 };
    int b[5] = { 1, 2, 3, 4, 5 };
    int *p = &a[7];
    int *q = &b[3];
    printf("%d\n", p);
    printf("%d\n", q);
    printf("%d\n", q > p);// relational from different arrays
    printf("%d", *p); // dereferencing also seems to work
}

有人能帮忙吗?

代码应该抛出错误

【问题讨论】:

  • "But the behavior is undefined for arithmetic or comparisons with pointers that do not point to members of the same array." undefined 表示未定义。使用一个编译器似乎有效的东西可能无法使用另一个编译器......一个样本量不是进行评估的良好基础。
  • “下面的代码似乎有效......没有抛出任何异常或错误:”这是未定义行为的最糟糕结果。当魔多大军已经准备好追捕你时,它会产生你可能安全的错觉。

标签: arrays c pointers


【解决方案1】:

您的代码在多个地方有未定义的行为,但 C 语言没有定义在未定义行为的情况下会发生什么:任何事情都可能发生。不会抛出任何异常或错误,程序可能会崩溃、产生意外结果或似乎工作并产生预期结果……任何事情都会发生,没有什么可以期待的。

这些地方有未定义的行为:

  • int *p = &amp;a[7]; 您计算的是a 数组中超出数组末尾的不存在元素的地址,而不是末尾之后的元素。
  • printf("%d ", p);你传递了一个指向int的指针,其中printf需要一个int。你应该写printf("%p ", (void *)p);
  • printf("%d ", q);同上
  • printf("%d ", q > p); 使用未初始化为有效表达式的 p 的值
  • printf("%d", *p);取消引用无效指针p

【讨论】:

    【解决方案2】:

    您正在处理未定义的行为。 这意味着您不能依赖它——它可能有一天会很好地工作,而在另一天可能根本不起作用。 但无论如何 - 你不能相信它。

    这就是为什么未定义的行为有时如此危险的原因 - 它可能会正常工作,直到有一天在没有预先警告的情况下可怕地失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多