在C语言中,数组名本质上是一个指向数组首元素的指针。因此,通过指针来引用数组是非常自然和常用的操作。这里我们将探讨几种使用指针来引用和操作数组的方法。
1. 声明并初始化数组
首先,我们声明并初始化一个数组:
int arr[] = {1, 2, 3, 4, 5};
2. 使用数组名作为指针
由于数组名可以被视为指向其首元素的指针,我们可以直接使用数组名来访问数组中的元素,就像使用指针一样:
int secondElement = *(arr + 1); // 使用指针算术访问第二个元素
printf("%d\n", secondElement); // 输出 2
这里,arr + 1
表示指向数组第二个元素的指针,然后我们通过解引用(*
)这个指针来获取它的值。
3. 指针变量指向数组
(1)声明
我们也可以声明一个指针变量,并将其初始化为指向数组的首元素:
int *ptr = arr;
(2)访问
虽然可以通过指针和下标两种方式访问数组元素,但它们是等价的。
int a = array[2]; // 通过下标访问
int b = *(array + 2); // 通过指针访问,等价于a
对于使用指针和数组下标的选择:
系统在使用数组下标对数组成员变量进行访问时,开销比较大,指针的访问效率是远远大于数组名的访问效率的。但是只有在指针正确访问时,才比下标法更有效率,下标法更加容易理解,在可读性方面,也更加的具有优势,具体怎么选择,也没有一定的说法。
(3)遍历
现在,ptr
指向 arr
的第一个元素。我们可以使用 ptr
来遍历数组:
for (int i = 0; i < 5; i++) {
printf("%d ", *(ptr + i));
}
// 输出: 1 2 3 4 5
4. 指针和数组名的区别
虽然数组名和指针在很多情况下可以互换使用,但它们之间有一个重要的区别:数组名在表达式中会被转换成指向其首元素的指针,但它本身并不是一个指针变量。你不能修改数组名让它指向另一个地址(即你不能给数组名赋值),但你可以修改指针变量让它指向另一个地址。
5. 指针算术
在C语言中,指针算术是基于指针所指向的数据类型的。如果你有一个指向 int
的指针,并且你增加了这个指针的值(比如 ptr++
),那么它实际上会向前移动 sizeof(int)
个字节。这使得使用指针遍历数组变得非常方便。
p++; // p现在指向array[1]
*p = 10; // 将array[1]设置为10
6.数组指针的见怪不怪
(1)通过指针下标访问数组对应元素
int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("%d",p[2]);
(2)数组名和指针进行算术
int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("%d",*(p+2));
printf("%d",*(arr+2));
(3)*p++和*arr++
for(int i=0;i<5;i++){
printf("%d ",*p++);
}
*p++是可以正常遍历数组的。
for(int i=0;i<5;i++){
printf("%d ",*arr++);
}
*arr++使用数组名直接遍历是不可行的,因为arr是一个常量指针,而p是一个指针变量。
(4)指针和数组名的sizeof
int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("sizeof arr is %d\n",sizeof(arr));
printf("sizeof p is %d\n",sizeof(p));
printf("sizeof int is %d\n",sizeof(int));
printf("sizeof int* is %d\n",sizeof(int *));
printf("sizeof char* is %d\n",sizeof(char *));
输出为:
sizeof arr is 20
sizeof p is 8
sizeof int is 4
sizeof int* is 8
sizeof char* is 8
arr代表的是数组内所有元素占用的总的字节数,即为4*5=20;
p、int *、char *都是指针,在操作系统中指针变量即为地址,用8个字节表示;
int为整型变量,用8个字节表示。
7. 注意事项
- 确保不要越界访问数组,这可能会导致未定义行为。
- 当使用指针遍历数组时,要记得数组的长度,以避免访问不存在的内存区域。
- 指针和数组虽然密切相关,但它们在C语言中有不同的用途和限制。