在 C++ 中,数组和指针是两个密切相关的概念,但它们有着本质的区别。以下是它们的详细对比:
1. 定义
- 数组:
- 数组是一个连续的内存块,用于存储相同类型的多个元素。
- 数组的大小在编译时确定,且不可改变。
- 数组名是一个常量指针,指向数组的第一个元素。
- 指针:
- 指针是一个变量,用于存储另一个变量的内存地址。
- 指针可以指向任何类型的数据,包括数组、函数、对象等。
- 指针的值可以改变,指向不同的内存地址。
2. 内存分配
- 数组:
- 数组的内存是静态分配的(如果是栈数组)或动态分配的(如果是堆数组)。
- 栈数组的大小必须在编译时确定。
- 指针:
- 指针的内存是动态分配的,通常通过
new
或malloc
分配。 - 指针可以指向任意大小的内存块。
- 指针的内存是动态分配的,通常通过
3. 访问方式
- 数组:
- 数组元素通过下标访问。
- 数组名是一个常量指针,不能修改。
- 指针:
- 指针通过解引用操作符
*
访问指向的值。 - 指针可以修改,指向不同的内存地址。
- 指针通过解引用操作符
4. 大小计算
- 数组:
- 使用
sizeof
可以计算整个数组的大小。 - 示例:
int arr[5]; std::cout << sizeof(arr) << std::endl; // 输出 20(5 个 int,每个 4 字节)
- 使用
- 指针:
- 使用
sizeof
只能计算指针本身的大小,而不是指向的内存块的大小。 - 示例:
int* ptr = new int[5]; std::cout << sizeof(ptr) << std::endl; // 输出 8(指针的大小,64 位系统)
- 使用
5. 函数参数传递
- 数组:
- 数组作为函数参数时,会退化为指针。
- 示例:
void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { std::cout << arr[i] << " "; } } int main() { int arr[5] = {1, 2, 3, 4, 5}; printArray(arr, 5); // 数组退化为指针 return 0; }
- 指针:
- 指针作为函数参数时,直接传递地址。
- 示例:
void printValue(int* ptr) { std::cout << *ptr << std::endl; } int main() { int x = 10; printValue(&x); // 传递指针 return 0; }
6. 总结
特性 | 数组 | 指针 |
---|---|---|
定义 | 连续内存块,存储相同类型元素 | 变量,存储内存地址 |
内存分配 | 静态或动态分配 | 动态分配 |
访问方式 | 通过下标访问 | 通过解引用访问 |
大小计算 | sizeof 计算整个数组大小 | sizeof 计算指针本身大小 |
函数参数传递 | 退化为指针 | 直接传递地址 |
可变性 | 数组名是常量指针,不可修改 | 指针可以修改,指向不同地址 |
7. 示例对比
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;
std::cout << arr[2] << std::endl; // 输出 3(数组访问)
std::cout << *(ptr + 2) << std::endl; // 输出 3(指针访问)
8. 关键点
- 数组名是一个常量指针,指向数组的第一个元素。
- 指针可以指向任意内存地址,灵活性更高。
- 数组和指针在函数参数传递时会退化为指针。
理解它们的区别有助于在编程中正确使用数组和指针。
THE END
暂无评论内容