指针提供了一种用来使用地址的符号方法,可以很有效地处理数组
数组标记实际上是一种变相使用指针的形式
数组名同时也是该数组首元素的地址,如果arr是一个数组,则:
arr == &arr[0];
在C中,对一个指针加1的结果是对该指针增加一个存储单元(storage unit);对于数组,地址会增加到下一个元素的地址,而不是下一个字节
因此在声明指针时必须声明其所指向对象的类型
计算机需要知道存储对象所用的字节数,因此只有地址信息是不够的
1)指针的数值就是其所指向的对象的地址,地址内部表示方式是由硬件决定,很多计算机都是以字节编址的,即对每个内存字节顺序进行编号,对于包含多个字节的数据类型,对象的地址通常指的是其首字节的地址
2)在指针前运用运算符 *就可以得到该指针所指向的对象的数值
3)对指针加1,等价于对指针的值加上它指向的对象的字节大小
arr + 2 == &arr[2] // 相同的地址
*(arr + 2) == arr[2] // 相同的值
数组和指针的密切关系:可以用指针标识数组的每个元素,并得到每个元素的数值;本质上,对同一个对象有两种不同的符号表示方法
* (arr + 2) // arr的第3个元素的值
* arr + 2 // arr的第1个元素的值加2
// 间接运算符(*)的优先级高于+
了解数组和指针的密切关系,编程时可以方便地选择两者中任意一种方法
示例代码:输入年份,显示该年每个月的天数
#include <stdio.h>
#define MONTHS 12
int main(void)
{
int days1[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days2[MONTHS] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year;
int index;
printf("please enter the year(for example 2022): \n");
scanf("%d", &year);
if(year % 4)
{
for(index = 0; index < MONTHS; index++)
{
printf("Month %d has %d days. \n", index + 1, days1[index]); // 数组表示
printf("Month %d has %d days. \n", index + 1, * (days1 + index)); // 指针表示
}
}
else
{
for(index = 0; index < MONTHS; index++)
{
printf("Month %d has %d days. \n", index + 1, days2[index]); // 数组表示
printf("Month %d has %d days. \n", index + 1, * (days2 + index)); // 指针表示
}
}
return 0;
}
运行结果:
示例结果说明:使用数组和指针的运行结果一致;指针和数组时两个等效的方法;可以使用指针标记数组,反之亦然