数组名与指针之间的区别
[[C]] 是的,数组名和指针在C/C++中是两种不同的概念,尽管它们在某些情况下可以相互转换或表现出相似的行为,但它们的本质是不同的。
![[Example.png]] 比如说这道题就==是错的==
![[typetrans.png]] 传参数时类型是相同的 ![[typetrans2.png]] 注意这里的隐式转化 隐式转化(==退化==)只能转化一层!
1. 数组名(Array Name)
- 本质:数组名是一个常量指针,它代表数组首元素的地址。
- 特点:
- 数组名指向的内存地址是固定的,不能被修改(即不能重新赋值)。
- 数组名包含了数组的大小信息(通过
sizeof
可以获取整个数组的大小)。 - 数组名是一个符号,代表整个数组的内存空间。
- 示例:
c int arr[5] = {1, 2, 3, 4, 5}; printf("%p\n", arr); // 输出数组首元素的地址 printf("%lu\n", sizeof(arr)); // 输出整个数组的大小(字节数)
在上面的例子中: arr
是数组名,它的类型是int[5]
。sizeof(arr)
返回的是整个数组的大小(5 * sizeof(int)
)。
2. 指针(Pointer)
- 本质:指针是一个变量,用于存储内存地址。
- 特点:
- 指针的值可以修改(即可以指向不同的内存地址)。
- 指针的大小是固定的(通常是 4 字节或 8 字节,取决于系统架构)。
- 指针本身不包含所指向内存的大小信息。
- 示例:
c int arr[5] = {1, 2, 3, 4, 5}; int *p = arr; // 指针 p 指向数组 arr 的首元素 printf("%p\n", p); // 输出指针 p 的值(即数组首元素的地址) printf("%lu\n", sizeof(p)); // 输出指针的大小(通常是 4 或 8 字节)
在上面的例子中: p
是一个指针,它的类型是int*
。sizeof(p)
返回的是指针的大小,而不是数组的大小。
3. 数组名与指针的区别
特性 | 数组名 | 指针 |
---|---|---|
本质 | 常量指针,代表数组首元素的地址 | 变量,存储内存地址 |
能否修改 | 不能(常量) | 能(变量) |
大小信息 | 包含整个数组的大小 | 不包含指向内存的大小 |
类型 | 数组类型(如 int[5] ) |
指针类型(如 int* ) |
sizeof 的结果 |
整个数组的大小(字节数) | 指针的大小(通常是 4 或 8 字节) |
4. 数组名退化为指针
在某些情况下,数组名会退化为指针:
- 当数组名作为函数参数传递时,它会退化为指向数组首元素的指针。
- 当数组名用于表达式(如 arr + 1
)时,它会退化为指针。
示例:
void printArray(int *p, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", p[i]);
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr, 5); // 数组名 arr 退化为指针
return 0;
}
在这个例子中,arr
作为函数参数传递时,退化为 int*
类型的指针。
5. 总结
- 数组名和指针是两种不同的数据类型。
- 数组名是一个常量指针,代表数组首元素的地址,且包含数组的大小信息。
- 指针是一个变量,用于存储内存地址,不包含指向内存的大小信息。
- 在某些情况下,数组名会退化为指针,但它们的本质仍然是不同的。