#include <stdio.h>
int main(void){
int i;
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // p指向a[0]
for(i = 0; i < 5; i++){
printf("a[%d] = %d *(a + %d) = %d | p[%d] = %d *(p + %d) = %d\n", i, a[i], i, *(a + i), i, p[i], i, *(p + i));
}
for(i = 0; i < 5; i++){
printf("a[%d] = %p a + %d = %p | &p[%d] = %p p + %d = %p\n", i, &a[i], i, (a + i), i, &p[i], i, (p + i));
}
}
运行结果:
#include <stdio.h>
int main(void){
int i;
int a[5] = {1, 2, 3, 4, 5};
int *p = &a[2]; // p指向a[2]
for(i = 0; i < 5; i++){
printf("a[%d] = %d *(a + %d) = %d\n", i, a[i], i, *(a + i));
}
puts("----------------------------------------------------------");
for(i = -2; i < 3; i++){
printf("p[%d] = %d *(p + %d) = %d\n", i, p[i], i, *(p + i));
}
puts("----------------------------------------------------------");
puts("----------------------------------------------------------");
for(i = 0; i < 5; i++){
printf("a[%d] = %p a + %d = %p \n", i, &a[i], i, (a + i));
}
puts("----------------------------------------------------------");
for(i = -2; i < 3; i++){
printf("&p[%d] = %p p + %d = %p\n",i, &p[i], i, (p + i));
}
}
运行结果:
数组正确指向数组中的元素
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // p指向a[0]
数组错误指向数组中的元素
int a[5] = {1, 2, 3, 4, 5};
int *p = a[2]; // 无法赋值
因为:a[2]的类型是int,而p的类型是int *,两者不同,不能相互赋值!
在以下两种情况下,数组名不会被视为指向其实元素的指针。
- 作为 sizeof 运算符的操作数出现时
sizeof(数组名)不会生成指向起始元素的指针的长度,而是生成数组整体的长度。 - 作为取址运算符 & 的操作数出现时
& 数组名不是指向起始元素的指针的指针,而是指向数组整体的指针。
如果在指向数组内元素的指针p + i 前写上指针运算符 *,会变成什么情况呢?
因为 p + i 是指向 p 所指元素后第 i 个元素的指针,所以在其前加上指针运算符后得到的 *(p + i)就是该元素的别名。因此,如果p指向a[0],那么表达式 *(p + i)就表示a[i]本身。
总结:
- 指针 p 指向数组中的元素e时,
指向元素 e 后第 i 个元素的 *(p + i),可以写为p[ i ]。
指向元素 e 前第 i 个元素的 *(p - i),可以写为p[-i]。 - 数组a的元素个数为n时,构成数组a的元素是a[0]到a[n-1],共“n个”。但是,指向数组元素的指针,则可以是&a[0]到&a[n],共“n + 1”个。之所以会出现这种情况,是因为在对遍历数组元素的结束条件(是否达到了末尾)进行判定时,如果可以利用指向末尾元素后一个元素的指针的话将会非常方便。
- Type* 型指针 p 指向 Type型数组 a 的起始元素a[0]时,指针 p 的行为就和数组 a 本身一样。
- 数组的下标表示位于起始元素后的第几个元素的位置,因此必须从0开始。
注意:
- 虽然可以为指针加上整数,但是指针之间相减是不可以的。
- 指针之间做减法是可以的。
数组正确的赋值示例
int *p
int x[5];
p = x; // 正确的赋值
数组错误的赋值示例
int a[3]
int b[3];
a = b; // 错误的赋值
赋值表达式的左操作数不可以是数组名。
准确来说是 不可使用赋值运算符改变指向数组起始元素的指针。