C 中的数组下标和指针算术给出不同的结果

问题描述 投票:0回答:1

当使用数组下标语法尝试获取位于数组内部的值的地址时,我得到了不同的内存地址(无效的地址),而不是使用指针算术,这确实产生了预期的(正确的)内存地址。 这是为什么?

此代码是使用 gcc C99 和 C11 编译的,标志:-Wall -O0。

#include <stdio.h>

int main() {
    unsigned int arg = 0;
    char         arr[5] = {'a', 'b', 'c', 'd', 'e'};
    char*        arrp   = arr + 2;
    char*        pos_1  = arrp - arg - 1;
    char*        pos_2  = &arrp[-arg - 1];
    printf("arr:  %p\narrp: %p\npos_1:%p\npos_2:%p\n", arr, arrp, pos_1, pos_2);
    return 0;
}

结果:

arr:  0x7fff31035a73
arrp: 0x7fff31035a75
pos_1:0x7fff31035a74
pos_2:0x800031035a74
如您所见,

pos_2
无效。

但是当使用常量

0
而不是变量
arg
时,我也得到了
pos_2
的正确内存地址...

#include <stdio.h>

int main() {
    char         arr[5] = {'a', 'b', 'c', 'd', 'e'};
    char*        arrp   = arr + 2;
    char*        pos_1  = arrp - 0 - 1;
    char*        pos_2  = &arrp[-0 - 1];
    printf("arr:  %p\narrp: %p\npos_1:%p\npos_2:%p\n", arr, arrp, pos_1, pos_2);
    return 0;
}

这会导致:

arr:  0x7ffc270c4ed3
arrp: 0x7ffc270c4ed5
pos_1:0x7ffc270c4ed4
pos_2:0x7ffc270c4ed4

这是正确的(第二次编译)。

arrays c pointers memory-address
1个回答
1
投票

由于

arg
unsigned
-arg - 1
会生成一个值为
unsigned
UINT_MAX
0u - 1
“环绕”并成为可能的最大
unsigned
) - 这几乎超出了范围任何数组。

另一方面,

-0 - 1
是使用
int
完成的,结果是
-1

© www.soinside.com 2019 - 2024. All rights reserved.