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; }