在下面的代码中,有人可以解释为什么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;
}
答案 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)
实际增量取决于指针的类型
如果ptr
为int
,则增量即ptr + 1
将地址增加4(假设int为4个字节)内存位置,即(如果ptr
为0xFF000005 { {1}}将为0xFF000009)
如果ptr+1
为ptr
,则增量即char
将地址增加1个内存位置(如果ptr + 1
为0xFF000005 ptr
将为0xFF000006)
答案 4 :(得分:0)
sum += *(ptr+i);
这里最初将索引值“i”添加到“ptr”,然后在取消引用数组指针后获取值。它被添加到“总和”
sum += ptr[i];
这里通过数组“ptr”中的索引值“i”直接访问该值。它被添加到“总和”