在C语言里,指针和数组经常一起出现,很多人觉得数组名就是指针,但其实它们并不是一回事。数组是一段连续的内存空间,而指针是一个保存地址的变量。只是在大多数表达式里,数组名会隐式转换成指向数组首元素的指针,这才让我们能像用指针一样用数组名。

指针和数组的本质关系
声明一个数组时,编译器会分配固定大小的内存。声明一个指针时,只分配一个地址变量。看下面例子:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // 数组名arr转换为指向首元素的指针
printf("%d %dn", arr[0], p[0]); // 都能访问第一个元素
printf("%d %dn", *(arr+1), *(p+1)); // 指针算术都有效
return 0;
}
上面代码中,arr和p在算术运算时表现类似,但类型不同。
数组名作为指针使用的注意事项
1. 数组名不是可修改的左值
指针变量可以自增或重新赋值,但数组名是常量地址,不能做自增操作。
int arr[3] = {0};
int *p = arr;
p++; // 合法,p指向第二个元素
// arr++; // 编译错误,数组名不能作为左值自增
2. sizeof结果不同
对数组名用sizeof得到整个数组字节数,对指针用sizeof只得到指针本身大小。
| 表达式 | 含义 |
|---|---|
| sizeof(arr) | 数组总字节数,如5个int为20 |
| sizeof(p) | 指针变量大小,通常4或8字节 |
3. 作为函数参数会退化
数组作为函数参数传递时,会退化为指针,丢失长度信息。
void foo(int a[]) {
// 这里a实际是int*,sizeof(a)是指针大小
}
4. 取地址的区别
&arr得到的是指向整个数组的指针,类型和&arr[0]不同,但值一样。
int arr[5]; int (*pa)[5] = &arr; // 指向数组的指针 int *pi = &arr[0]; // 指向元素的指针
总结
数组名在表达式中通常当指针用,但它不是指针变量。写代码时要记住不能修改数组名、注意sizeof差异、函数传参会退化。搞清楚这些,就能安全地在指针和数组之间切换,减少Bug。
pointerarrayarray_name修改时间:2026-07-26 18:18:19