| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 数组和指针 -> 正文阅读 |
|
[数据结构与算法]数组和指针 |
首先看一维数组的定义和使用 int array[5] = {1, 2, 3, 4, 5}; array是具有5个整型元素的一维数组,5个元素连续存放在以数组名array为起始的内存空间中。 用数组名访问: 访问数组array中的元素,可以直接用数组名访问,例如array[0]代表数组中的第一个元素,array[3]代表数组中的第4个元素; array和array[0]的地址是一样的,都代表这个数组的起始地址。
运行结果:
用指针方式访问: 定义一个指针int *p = array; p指向了数组array(也可以通过p = &array[0]来进行赋值),此时*p的值为array中第一个元素的值,访问第4个元素可以通过*(p+3)进行;也可以通过p[0]或p[3]访问数组。
运行结果如下:
从一维数组的访问上来说,无论通过array[3]还是p[3]的形式访问,编译器都转换成类似于 array+3或p+3的地址,然后通过指针的方式访问。 需要注意的是p作为指针变量是可以进行自加之类的运算,但是array的自加运算或赋值都是非法的,这是因为array在编译后就是一个确定的值,永远指向数组array,不能再次被改变,这个特性类似于const指针(int *const p = array,p不能再次被赋值)。例如: array++ 此时编译器会报下面错误:
下面讨论一维数组作为函数参数的情况: 由于数组名也是指针,所以函数的入参应该也是指针的形式。入参有两种形式: 一种是 f(int *p),另一种是f(int p[]) 从下面的示例中可以发现,上面两种形式没有任何区别,怀疑编译器会把 *p和p[]视为等同,甚至对于入参p[],中括号中写成几都会被编译器所忽略,例f(int p[3])
运行结果?分别为1和3 上面例子中,showArray函数的定义和声明中的参数都不一致,也没有报任何错误。 在数组中有一种特殊的数组是指针数组,指针数组中的每个元素都是指针。例: int *p[5]? ?定义了一个包含5个元素的指针数组p,数组p中的每一个元素都是指针,指向一个int的整型值。 下面例子验证了数组只是指针的一种异化情况,也就是编译器在处理array[2]完全是按照指针来处理的。
程序的运行结果为:
上面例子中指针p指向了一个整型变量,但是却使用了类似数组的形式取元素,此时仍然能够正确的得到整型变量的值。? 延伸到二维数组上,例如定义a[2][3],当用a[0][0]来取值时在编译器看来?a是一个指向指针的指针,a[0]先取到了第1个行向量的首地址,行向量相当于一个一维数组,含有3个元素;然后a[0][0]是接着取这个行向量的第一个元素。对于a[1][1]来讲,a[1]指的是第二个行向量的地址,a[1][1]取得是第二个行向量的第二个元素。 下面例子验证了二维数组的情形
运行结果为
所以数组只是一种利用指针构造的数据结构。 用指针访问二维数组: 从上面的讲解中,不免思考数组名a到底是一个什么样的指针?首先有一点是明确的,这个指针的类型是int型,即指针指向的是一个int型的数据;那么它是 int *p吗,显然不是,如果是这样,那么p[0]就能直接取到数组的值,但明显指向这个数组名的指针p的p[0]指向的应该是第一个行向量的首地址;那么是int **p指针吗,也不是,因为此时p[1]指向的p[0]的下一个位置即p + 4,而正确定义的指针p的p[1]指向的应该是下一个行向量的首地址,即p+12(因为每个行向量中包含3个int型元素)。 所以可以得出,正确定义的指针p,要满足:p[0]取到的是第一个行向量的地址,p[1](也就是p++)指向的是下一个行向量的首地址。所以我们引出这个指针数组的定义: int (*p)[3]? = a; 首先p是一个指针,它指向一个具有3个int型元素的数组。这时p++就是 p[0]+12,如果用sizeof得到大小的话可以发现它占据的是12个字节的空间。 另外一种角度,对比int a[2][3] 和int (*p)[3],其实对于指针的定义就是把a[2]替换成了(*p),所以*p发挥的作用和a[0] 或 a[1]是一样的,只是用一个变量p来指向不同的数组地址。*p = a[0],那么p = &a[0]; (这个一维数组的情况是一样的,在一维中,int a[2]; int *p; p = &a[0];)而&a[0]等同于数组名a。
运行结果为
作为函数入参: 和一维数组的情况一样,二维数组作为函数入参可以直接用数组名,也可以用数组指针。 int showArray2D(int array[2][3])? 或?int showArray2D(int array[1][3]) 或?int showArray2D(int array[][3])? 但不能是改变列的大小例: int showArray2D(int array[2][2]),因为此时array指向的不再是3个含有元素的行向量,编译器会报如下错误: error: cannot convert 'int (*)[3]' to 'int (*)[2]' 指针形式传参如下,即指明了二维数组的类型: int showArray2D(int (*p)[3]) 下面是具体示例:
总结: 牢记数组也是指针,不同维数的数组对应不同的指针。 推广到3维数组也是类似的情况,例如 int array[2][2][3] = {{{1, 2, 3}, {4, 5 ,6}}, {{-1, -2, -3}, {-4, -5, -6}}};? 对应的指针定义就是一个指向具有2行3列的二维数组指针,即:int (*p)[2][3]; |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 18:27:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |