【带头学C++】----- 三、指针章 ---- 3.8二维数组与数组指针的关系(二,补充)

1.深入了解二维数组

    在上一节3.8中,对于二维数组的笔记中我觉的还缺少一些基础性建设,所以在此进行补充。

(引用千锋教育基础班笔记的一些记录)

arr[1]     =>   *(arr+1)                     第一行第0列的列地址

&arr[1]   =>  &*(arr+1) =>arr+1     第1行的行地址

*(arr+1)  =>  第0行第1列的列地址

arr[1]+2  =>  *(arr+1)+2 =>   第1行第2列的列地址    (参照第一个是第一行,就是第二行其实,数组里面是从0开始,前面还有给第0行,+2就是列地址加2,跳过一个字符的大小,之前有了解过的知道,)

**arr   ==  *(*(arr+0)+0)   ==   arr[0][0]

数组是从0开始的,二维就是从0行0列开始(也就是我们实际问题中的第一个,程序中通常对数组说的第0就是第1。)

2.二维数组和一位数组指针的关系

       在 C/C++ 中,二维数组可以视为一维数组的数组。也就是说,二维数组可以看作由多个一维数组组成的数据结构。因此,我们可以使用一个一维数组指针来表示二维数组。

       具体来说,假设有一个二维数组 int arr[m][n],其中 m 表示行数,n 表示列数,则可以定义一个对应的一维数组指针 int (*p)[n]

       通过指针的运算和解引用操作,我们可以使用一维数组指针来访问二维数组中的元素。例如,*(p+i) 表示第 i 行的一维数组指针,*(*(p+i)+j) 表示第 i 行第 j 列的元素。

       需要注意的是,二维数组和一维数组指针的类型不完全相同。二维数组的类型是 int [m][n],而一维数组指针的类型是 int (*)[n]。因此,在进行类型转换或进行指针运算时,需要确保类型匹配

     二维数组和一维数组指针之间的关系:二维数组是由一维数组组成的,而一维数组指针可以用来表示和操作二维数组。

 int arr[n];                  int *p;    

int arr[n][m];              int (*p)[m];

int arr[n][m][k];           int (*p)[m][k]
n维数组     和      n-1维的数组指针      等价

 3.多维数组的物理存储

      无论是一维数组还是多维数组,它们都以线性的方式进行存储,也就是在物理上是一维存储的。对于多维数组,它们在逻辑上可以被视为具有多个维度的数组

 

用一维的方式去遍历二维的数组 

 

 

指针数组在C/C++编程中是两个非常重要的概念,尽管它们在某些场景下表现相似,但本质上它们是完全不同的两种机制。下面将从多个维度对它们的区别联系进行详细分析。 ### 3.1 概念上的区别 指针是一种变量,它存储的是内存地址,指向某个数据类型(如int、char等)的起始位置。指针本身也有类型,例如`int*`表示指向整型的指针指针可以动态分配内存(如使用`malloc`或`new`),也可以指向任何有效的内存地址。 数组是一种固定大小的数据结构,用于存储相同类型的多个元素。数组名在大多数表达式中会被自动转换为指向其第一个元素的指针。例如,`int arr[5]`定义了一个包含5个整型元素的数组。 ### 3.2 声明语法差异 数组的声明形式为: ```c int arr[10]; // 声明一个包含10个整型元素的数组 ``` 指针的声明形式为: ```c int* ptr; // 声明一个指向整型的指针 ``` 虽然在某些上下文中数组名会被当作指针处理,但它们的本质不同。数组名在表达式中通常会被视为指向第一个元素的指针常量,即不能对数组名进行赋值,如`arr = ptr;`是非法的。 ### 3.3 内存布局访问方式 数组在内存中是连续存储的,每个元素占据固定大小的空间。数组的访问是通过索引实现的,例如`arr[i]`表示访问数组的第i个元素。 指针通过解引用操作符`*`来访问其所指向的内存位置。例如: ```c int a = 10; int* ptr = &a; printf("%d\n", *ptr); // 输出10 ``` 指针还可以进行算术运算,如`ptr++`会使其指向下一个同类型的数据。 ### 3.4 指针数组的联系 尽管指针数组在本质上不同,但在C/C++中,数组名在大多数表达式中会被自动转换为指向其第一个元素的指针。例如: ```c int arr[5] = {1, 2, 3, 4, 5}; int* ptr = arr; // arr被转换为指向arr[0]的指针 printf("%d\n", *ptr); // 输出1 ``` 这种转换使得指针可以像数组一样使用索引访问元素: ```c printf("%d\n", ptr[2]); // 输出3 ``` ### 3.5 数组指针指针数组的区别 - **指针数组** 是一个数组,其元素是指针类型。例如: ```c int* p[5]; // p是一个包含5个int指针数组 ``` - **数组指针** 是一个指向数组指针。例如: ```c int (*p)[5]; // p是一个指向包含5个int元素的数组指针 ``` 它们在内存布局和使用方式上也有所不同。指针数组适合用于存储多个地址,如字符串数组;而数组指针则适合用于操作整个数组,例如作为函数参数传递二维数组。 ### 3.6 使用场景示例 #### 指针数组示例: ```c int a = 1, b = 2, c = 3; int* p[3] = {&a, &b, &c}; printf("%d\n", *p[0]); // 输出1 ``` #### 数组指针示例: ```c int arr[5] = {1, 2, 3, 4, 5}; int (*p)[5] = &arr; printf("%d\n", (*p)[2]); // 输出3 ``` ### 3.7 常见误区 一种常见的误解是“数组是一种特殊的指针”。实际上,数组指针是两个不同的概念。数组是静态分配的连续内存块,而指针是一个变量,可以指向任何有效的内存地址。虽然数组名在表达式中可以被当作指针使用,但这并不意味着数组就是指针。 ### 3.8 总结 | 特性 | 指针 | 数组 | |----------------|--------------------------|------------------------------| | 本质 | 变量,存储内存地址 | 连续内存块,存储多个元素 | | 可变性 | 可以重新赋值 | 数组名不可赋值 | | 内存分配 | 可动态分配 | 静态分配 | | 访问方式 | 通过解引用或索引 | 通过索引 | | 数组关系 | 数组名可转换为指针 | 可被指针指向 | 指针数组在C/C++中各有其独特的用途和优势,理解它们的区别联系对于编写高效、安全的代码至关重要。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小白Erike.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值