理解指针deference和数组索引之间的区别

时间:2017-05-23 10:14:21

标签: c arrays pointers dereference

在下面的代码中,有人可以解释为什么sum += *(ptr+i);sum += ptr[i];相同吗?

我知道sum += *(ptr+i);取消引用内存地址然后对数字求和?

但在sum += ptr[i];中没有任何尊重......

#include <stdio.h>
#include <stdlib.h>

int main() {
    int len, i, sum;
    printf("Enter how many numbers you want to sum:");
    scanf("%d", &len);
    int* ptr;
    ptr = (int*)malloc(sizeof(int) * len);
    for(i=0; i < len; i++) {
        printf("Enter a number:");
        scanf("%d", ptr+i);
    }
    for(i=0; i < len; i++) {
    //sum += *(ptr+i);
      sum += ptr[i];    
    }
    printf("The sum is %d", sum);
    return 0;
}

5 个答案:

答案 0 :(得分:1)

只是因为这就是语言的运作方式。是的,[]索引操作符实际上取消引用其左侧的指针,它必须这样做以获取值。

在一般情况下,a[b]相当于*(a + b)

这会带来像

这样的有趣经典
printf("%c\n", 4["foobar"]);

以上打印a,因为*(4 + "foobar")*("foobar" + 4)相同,即"foobar"[4]

答案 1 :(得分:1)

根据定义(C标准,6.5.2.1数组下标)

  

2后缀表达式后跟方括号[]中的表达式   是数组对象元素的下标。该   下标运算符[]的定义是E1 [E2]与...相同   (*((E1)+(E2)))。由于适用于的转换规则   binary +运算符,如果E1是数组对象(等效于指针   到数组对象的初始元素),E2是一个整数,   E1 [E2]表示E1的第E2个元素(从零开始计数)。

因此这三个陈述

sum += *(ptr+i);
sum += ptr[i];    
sum += i[ptr];    

是等价的。

考虑到程序具有未定义的行为,因为变量sum未初始化。:)为避免溢出,最好将其声明为

long long int sum = 0;
// ...
printf("The sum is %lld\n", sum);

答案 2 :(得分:0)

  

但在sum += ptr[i]中没有尊重

仅在未使用解引用运算符*的意义上没有解除引用。但是,取消引用仍然存在,因为C中的索引运算符[]等同于*:这两个在所有情况下都是完全可互换的。当您看到x[i]时,您可以将其重写为*(x+i),反之亦然。

将附加的重新引用重写为索引表达式的能力导致C语法中可读性最差的结构之一 - 将x[i]重写为i[x]的能力。

答案 3 :(得分:0)

ptr[i]评估为*(ptr + i) 实际增量取决于指针的类型

如果ptrint,则增量即ptr + 1将地址增加4(假设int为4个字节)内存位置,即(如果ptr为0xFF000005 { {1}}将为0xFF000009)

如果ptr+1ptr,则增量即char将地址增加1个内存位置(如果ptr + 1为0xFF000005 ptr将为0xFF000006)

答案 4 :(得分:0)

sum += *(ptr+i);这里最初将索引值“i”添加到“ptr”,然后在取消引用数组指针后获取值。它被添加到“总和”

sum += ptr[i];这里通过数组“ptr”中的索引值“i”直接访问该值。它被添加到“总和”