目录:
(1):数组名的理解
(2):使用指针访问数组
(3):一维数组传参的本质
(4):冒泡排序
(5):二级指针
(6):指针数组
(7):指针数组模拟二维数组
(1):数组名的理解:
1——1引入:
在深入理解指针1,2中使用指针访问数组时,有这样的代码:
我们这里使用&arr[0]的方式拿到了第一个元素的地址,但是数组名本质就是数组到首元素的地址。
从这一组的代码测试来看:打印数组名和数组首元素的地址是一样的
得到结论:数组名就是数组首元素的地址。
1——2:数组名代表是整个数组的两个特例:
了解了这一点时让我们来看这个案例:
输出结果是:40。如果arr是数组首元素的地址的话,应该输出是4 \ 8才对,为什么是40呢?
注:数组名是数组首元素的地址不假,但是有两个例外。
1:sizeof(数组名):在sizeof中单独放数组名,这里数组名表示整个数组,计算的是整个数组的大小,单位是字节。
2:&数组名:这里的数组名也表示整个数组。取出的是证书组队地址
(除此之外,任何地方使用的数组名,都表示数组首元素的地址)
1——3:地址的加1比较:
接下来我们再来看这个代码
三个打印的结果又一样了
当给他们后面都加1时:这时可以看出不同了。
(1)&arr[0] +1 和 arr + 1地址都跳过了4个字节的大小====>因为他们都是首元素的大小,
+1就是跳过一个元素
(2)1:而&arr +1,加了28,28是16进制的数据,转化为10进制是40个字节====>因为&arr是数组的地址,+ 1 的操作就是跳过了一个数组的大小。
地址+1:跳过多少个字节和什么有关系呢?——指针类型
(2)使用指针访问数组:
访问数组内容:
方法1:最原始的方法,
方法2:用指针访问数组内容:
循环中 pa+i代表的是下标为i这个元素的地址
(变式1)
让p++的方式,也可以把数组打印出来。
(变式2)
自己输入也是可以的
(变式3)在输入时直接让p自己++
在打印时要让p重新指向arr的第一个元素,因为在输入结束后p指向了数组末尾的元素,若不使p回归,则会指向数组的第11个元素====>随机值.
(变式4)
arr是数组的首个元素的地址, int*p=arr存入了arr的地址
arr的类型是int*,p的类型也是int*=====>p等价于arr,这种写法也可行的
(变式5)
这种方式可以打印出来===>这种操作为什么可行呢?
实际上,编译器在属组访问元素的时候
arr[ i ]会被转移成 *(arr+i)这种方式,数组在真正访问内存时要转化为指针的形式
(3)一维数组传参的本质
了解了之前的知识,我们知道数组是可以传递给函数的,我们之前都是在函数的外部计算数组的元素个数,那么在将数组传给函数之后,在函数的内部计算数组的长度可行吗?
可以看到图中的代码,我们在main函数中计算的sz1:计算出来数组长度是10
而在函数text中计算的长度是sz2,原因是什么呢?
数组再传参的过程中,传递的是数组首元素的地址,而图中sz2的sizeof计算的是首元素的大小除下表为1的元素的大小 4 / 4=1.从而得出了1的结果===>函数内部是无法求数组的元素个数的
因为数组传参传递的是首元素的地址,同样可以用指针来接收传来的参数,
本质是指针,但是初学时写成数组的形式会更容易理解。
总结:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
(4)冒泡排序:
冒泡排序的核⼼思想就是:两两相邻的元素进⾏⽐较。
主函数如下所示:
Printf与bubble_sort分别是创建的两个函数:一个负责打印结果,一个负责排序
我们先来看排序函数bulle_sort
在图中我们首先创建了一个循环处理趟数:若有n个数字,趟数就是n-1,变量i代表是第几趟;
随后进入第1个循环,在每个循环中,我们要在这一趟中给数组排序
第二个循环就是负责数组进行排序:j就代表下标为j的元素;
第二个循环中sz-1-i的含义:每次比较后就会少一个元素:也就是说排序一次后就有一个元素到了该到的位置,不需要在进行排序了。
例如第一趟中i=0;sz-1-i=9,还剩余9趟,在第一趟的第二个循环中要走9趟,第一趟结束,进入第二趟:i=1;已经有一个数到达了该到的位置,sz-1-i=8,只需要在进行8趟排序即可。
现在这个排序函数我们已经了解了
但这个版本若数组本身就是正序排列,依旧要循环n-1趟——耗时大
(优化版):该版本设置了一个标志:若次趟数列已经是有序数列:直接跳出
主函数和打印函数没有改变,和上一个版本一样
在这个版本中设置了一个标志:flag,
首先假设此数组已经是有序数组,flag=1。
在进入第二层循环后,看到红色方框中if的判断条件若满足此条件时进入,进入就说明该次循环中数组无序====>将flag置为0(代表数组无序)若未进入第二趟数组,flag还是1
if(flag==1) break;若flag=1,则证明这一趟没有交换已经有序了。跳出第二个循环
(5)二级指针:
指针变量也是变量,是变量就有地址,那么指针变变量应该存放在哪里呢
图中int**paa:int*代表ppa指向的pa是int*类型的,而后面的*代表:ppa是指针变量。
二级指针变量是用来存放一级指针变量的地址的。
对二级指针解引用是先通过二级指针找到一级指针,再对一级指针进行解引用操作,找到的是一级指针指向的变量。
(6):指针数组
指针数组是指针还是数组呢?对于这个问题,可以用类比的方法:
整形数组:存放整形的数组;
字符数组:存放字符的数组===>重点是数组
指针数组就是存放指针的数组。(指针数组的每个元素都是用来存放地址(指针)的)
指针数组的每个元素都是地址,又可以指向一块区域。
(7)指针数组模拟二维数组
标签:arr,元素,地址,数组名,理解,深入,数组,指针 From: https://blog.csdn.net/2402_88547413/article/details/143940093