tips图解数组名与指针的关系

在图解前需要先了解一下数组退化为指针的相关内容,下面先陈述数组退化为指针的概念、本质、以及什么情况下数组会退化为指针,什么情况下不会

概念定义

"数组名退化为指针"是C/C++语言中的一个重要特性,指的是数组名在大多数表达式中会自动转换为指向数组首元素的指针。这种转换由编译器自动完成,是一种隐式行为,使得对数组的操作更加灵活方便。

退化的本质

  • 数组名本身代表一块连续的内存空间,用于存储数据
  • 退化发生后,数组名失去其"数组"的身份特征,转变为指向数组首元素的右值指针(类似于const T*类型)
  • 退化后的指针值等于数组首元素的地址(即&arr[0])

发生退化的场景

1. 赋值给指针变量

c 复制代码
int arr[5] = {1, 2, 3, 4, 5};
int* p = arr;// 等价于 int* p = &arr[0]

2. 作为函数参数传递

c 复制代码
// 函数参数中的数组声明实际上等价于指针声明
void func(int param[]) {
		// 等价于 void func(int* param)
		// 此处的param是一个指针,而不是数组
}

int main() {
    int arr[5];
    func(arr);// arr在这里退化为指针进行传递
}

3. 参与算术运算

c 复制代码
arr + 1;// 等价于 &arr[1],指向数组的第二个元素

4. 用于比较运算

c 复制代码
if (arr == &arr[0]) {// 比较结果为true
// 执行相应操作
}

退化的例外场景(数组名不退化)

1. 作为sizeof运算符的操作数

c 复制代码
int arr[5];
printf("%zu", sizeof(arr));// 输出整个数组的大小(例如20,假设int类型占4字节)

2. 作为&(取地址符)的操作数

c 复制代码
int arr[5];
int (*p_arr)[5] = &arr;// &arr是指向整个数组的指针,类型为int (*)[5]
// 注意:&arr的值与arr的值相同,但两者的含义完全不同
// arr + 1跳过一个元素的大小,而&arr + 1跳过整个数组的大小

3. 用于初始化字符数组的字符串字面量

c 复制代码
char str[] = "hello";// str代表整个数组,sizeof(str)结果为6(包含终止符'\0')

图解一维数组(退化情况下)

一维到二维(退化情况下)