当前位置: 首页 > news >正文

C++自学笔记---数组和指针的异同点

数组和指针的异同点

0. 复习一下:指针运算符 * 和 &

我们前两篇有讲过这两个运算符,& 是取地址运算符,* 是解引用运算符。这两个运算符是理解指针的关键,因为它们分别代表了获取变量地址访问指针指向的值这两个基本操作。那么在理解数组和指针之前,我们先把这两个符号的意义记在心里。

#include <iostream>
using namespace std;int main() {int a = 10;int* ptr = &a;cout << "变量 a 的值: " << a << endl;cout << "变量 a 的地址: " << &a << endl;cout << "指针 ptr 存储的地址: " << ptr << endl;cout << "*ptr的值:"<< *ptr <<endl;return 0;
}

运行结果

  • a 是一个整型变量,值为 10。
  • &a 获取变量 a 的内存地址。
  • ptr 是一个指向整型的指针,它存储了 a 的地址。
  • *ptr解引用 ptr,获取 ptr 指向的内存地址中的值(即 a 的值),为10。

1. 数组和指针的的异同点

数组和指针都与内存地址相关:数组名本质上是一个指向数组首元素的指针。指针也可以指向数组中的某个元素。但是数组名数组名本身是一个常量指针,不能重新赋值为其他地址。指针变量可以重新赋值,指向不同的地址。也就是说,数组名只能指向数组的首元素,指针可以指向数组中的任意元素。
我们可以通过这个例子来理解一下这个特性:

#include <iostream>
using namespace std;int main() {// 定义一个数组int arr1[] = {1, 2, 3, 4, 5};int arr2[] = {6, 7, 8, 9, 10};// 数组名是常量指针,指向数组的首元素int* arr_ptr = arr1;  // arr1 是数组名,指向 arr1 的首元素// 尝试修改数组名的地址(会报错)// arr1 = arr2;  // 错误:数组名是常量指针,不能重新赋值cout << "arr_ptr 第一次指向的数组元素: ";for (int i = 0; i < 5; i++) {cout << arr_ptr[i] << " ";}cout << endl;// 普通指针可以重新赋值arr_ptr = arr2;  // 正确:普通指针可以重新赋值,现在指向 arr2 的首元素// 输出数组元素cout << "arr1 的元素: ";for (int i = 0; i < 5; i++) {cout << arr1[i] << " ";}cout << endl;cout << "arr2 的元素: ";for (int i = 0; i < 5; i++) {cout << arr2[i] << " ";}cout << endl;cout << "arr_ptr 第二次指向的数组元素: ";for (int i = 0; i < 5; i++) {cout << arr_ptr[i] << " ";}cout << endl;return 0;
}

指针可以被重新赋值
这个例子中,指针和数组名都是可以通过自增自减来遍历数组的。

2.指针和数组在函数中的是如何应用的?

数组在函数中会被退化为指针:当数组作为函数参数时,传递的是数组的首地址。由于数组和指针在内存中的表示方式相似,C++ 允许数组名直接作为指针使用。
具体可以参考这个例子:

#include <iostream>
using namespace std;// 函数声明
void printArray(int a[], int size);  // 数组作为参数!!!!重要!!!!
void printPointer(int* p, int size); // 指针作为参数int main() {// 定义一个数组int arr[] = {1, 2, 3, 4, 5};int size = sizeof(arr) / sizeof(arr[0]);// 调用函数,数组退化为指针printArray(arr, size);// 定义一个指针,指向数组int* p = arr;// 调用函数,传递指针printPointer(p, size);return 0;
}// 数组作为参数的函数实现
void printArray(int a[], int size) {cout << "数组中的元素: ";for (int i = 0; i < size; i++) {cout << a[i] << " ";}cout << endl;
}// 指针作为参数的函数实现
void printPointer(int* p, int size) {cout << "指针指向的元素: ";for (int i = 0; i < size; i++) {cout << p[i] << " ";}cout << endl;
}

在这里,实参arr[ ],其实传递到函数printArray(int a[], int size)中,其实只是传递了a[0]的地址,也就是*a。

3. 数组与指针:不同写法,相同意义

在C++中,数组和指针的访问方式虽然形式不同,但本质上都是通过指针偏移来访问数组的第 i 个元素。例如,a[i]、i[a]、*(a + i) 和 *(i + a) 这些写法虽然形式不同,但它们的语义是相同的,都是访问数组的第 i 个元素。
数组中的第i个元素

4. 函数之间多维数组的传递

在C++中,多维数组可以通过指针传递给函数。由于多维数组在内存中是连续存储的,传递时需要指定数组的维度信息,以便函数能够正确地访问数组元素。
代码示例

#include <iostream>
using namespace std;// 函数声明
void print2DArray(int arr[][3], int rows);  // 传递二维数组int main() {// 定义一个二维数组int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};// 调用函数,传递二维数组print2DArray(arr, 2);return 0;
}// 函数实现:打印二维数组
void print2DArray(int arr[][3], int rows) {cout << "二维数组的内容:" << endl;for (int i = 0; i < rows; i++) {for (int j = 0; j < 3; j++) {cout << arr[i][j] << " ";}cout << endl;}
}

当传递给 print2DArray 函数时,数组名 arr 会退化为指向其首元素的指针(即 int*)。由于是多维数组,函数参数需要指定数组的列数(如 int arr[][3]),以便函数能够正确地访问数组元素。在 print2DArray 函数中,通过双重for循环访问二维数组的每个元素。由于数组在内存中是连续存储的,函数可以通过指针运算正确地访问每个元素。多维数组的传递:需要指定数组的列数,以便函数能够正确地访问数组元素。数组名退化为指针:多维数组在传递时,数组名会退化为指向其首元素的指针。


http://www.mrgr.cn/news/97300.html

相关文章:

  • 【计算机网络】Linux配置SNAT/DNAT策略
  • Android学习总结之算法篇五(字符串)
  • Java基础-设计模式详解
  • [项目总结] 在线OJ刷题系统项目技术应用(上)
  • 燕山大学计算机网络实验(包括实验指导书)
  • 7B斗671B:扩散模型能否颠覆自回归霸权?
  • 网络编程—TCP/IP模型(TCP协议)
  • 通过Postman和OAuth 2.0连接Dynamics 365 Online的详细步骤
  • Java 进化之路:从 Java 8 到 Java 21 的重要新特性
  • 数据库原理
  • (二)输入输出处理——打造智能对话的灵魂
  • AI Agent开发大全第二十课-如何开发一个MCP(从0开发一个MCP Server)
  • 250405-VSCode编辑launch.json实现Debug调试Open-WebUI
  • Android学习总结之应用启动流程(从点击图标到界面显示)
  • STM32F103C8T6实现 SG90 180 °舵机任意角度转动
  • 【蓝桥杯】算法笔记3
  • JJJ:generic netlink例程分析
  • Flask+Vue构建图书管理系统及Echarts组件的使用
  • 第3课:状态管理与事件处理
  • 高级:分布式系统面试题精讲