1、数组名和指针的关系
数组名是一个标识符,代表数组的首地址,即数组第一个元素的地址。指针是一个变量,存储某个内存地址的值,并且它可以改变指向不同的内存位置。
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptr = arr; // 数组名 arr 表示数组首元素的地址
printf("arr[0] = %d\n", arr[0]); // 输出 10
printf("*ptr = %d\n", *ptr); // 输出 10
return 0;
}
2、数组名与指针的区别
数组名本质上是一个常量指针,它指向数组的第一个元素。数组名在大多数情况下会被隐式转换为指向数组第一个元素的指针。指针是一个变量,它存储的是另一个变量的内存地址。指针可以被赋值、递增、递减,以及进行各种指针运算。
1)类型
数组名是一个常量指针,不能被重新赋值。
指针是一个变量,可以被重新赋值。
2)内存分配
数组名在声明时会分配一段连续的内存空间。
指针在声明时只会分配存储地址的空间,指向的内存空间需要显式分配。
3)sizeof运算符
sizeof(数组名)返回整个数组的大小(以字节为单位)。
sizeof(指针)返回指针本身的大小(通常是4或8字节,取决于系统)。
4)数组名作为函数参数
当数组名作为函数参数传递时,它会被转换为指向数组第一个元素的指针。
指针作为函数参数传递时,传递的是指针的副本。
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptr = arr;
// 错误:数组名不能作为左值赋值
// arr = ptr; // 编译错误
ptr++; // 合法:指针可以移动到下一个元素
printf("Next element: %d\n", *ptr); // 输出 20
return 0;
}
3、数组名与指针在函数参数中的行为
当数组作为参数传递给函数时,数组名会退化为指针,即传递的是数组首元素的地址。也就是函数中无法获取数组的大小,只能访问数组元素。
#include <stdio.h>
void printArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[3] = {10, 20, 30};
printArray(arr, 3); // 传递数组名,相当于传递指针
return 0;
}
4、使用 sizeof 的区别
数组名中的sizeof(arr)
返回整个数组的大小(字节数)。指针中的sizeof(ptr)
返回指针的大小(通常是8字节)。
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptr = arr;
printf("Size of arr: %zu\n", sizeof(arr)); // 输出 12(3 * sizeof(int))
printf("Size of ptr: %zu\n", sizeof(ptr)); // 输出 8(指针大小)
return 0;
}
5、数组名与指针的访问方式
数组名可以用于指向数组的首地址,类似于指针。数组名可以用于指向数组的首地址,类似于指针。
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptr = arr;
// 使用数组名和指针访问元素
printf("arr[1] = %d\n", arr[1]);
printf("*(ptr + 1) = %d\n", *(ptr + 1)); // 等价于 arr[1]
return 0;
}