( )> [ ] > -> ++ > -- > . > * (优先级比较)
tips
1. (全是笔者个人自己总结,仅供参考,随意取用)
2.
3. 地址唯一标识一块内存空间
4. printf%s打印字符串的话只要给一个起始地址就OK了,然后它就会沿着这个地址不断往下走,直到碰到\0停止。要打印字符串的话,最简单不过了,只要给个起始地址就行了。
5. 数组名就是首元素的地址,地址/指针/内存编号三个概念完全等价
6. 数组名就是首元素的地址,这个无论怎么强调都不过分
7. const也可以去修饰数组,反正道理都是一样的
8. %p打印地址
9. 两个十六进制数相减的结果别傻乎乎的认为是十进制的数,也是十六进制的。
10. 对于整型数组没有办法一次性打印所有数据,必须通过循环的方法,因为没有结束的标志
字符指针
1. 对字符char变量取地址把它放进指针变量时,这就是一个字符指针变量。它指向的内容是字符,这个是我们之前就已经知道的字符指针。
2. 上面是一种写法:让字符指针指向字符变量。但是还有一种使用方式:char* p = "hello"。当常量字符串出现在代码里面的时候,它就代表着字符串第一个字符的地址。
3. 字符串本身与数组是非常相似的。因为字符串常量本来也就是在内存里面连续存放,那么这样的话就与数组没有区别了,把它理解成数组没有任何问题,只是不能修改。
4. 常量字符串无法被修改,因此如果char* p = "hello"这样子就会非常危险,*p是不被允许的,于是用const修饰,const char* p = "hello"。
5. 因为常量字符串是无法被修改的,也根本是无法被改动的,既然这样的话,有必要存两份吗?没必要,反正都一模一样,你也不能被改,我也不能被改。因此,如果相同字符串常量被用多份,出现了许多次,事实上在内存面不会存很多份,只需要存一份就可以了。
6. 内存除了之前讲过的栈区堆区静态区,其实还有其他的区,比如说只读数据\常量区等等都还是有的,我们学语言先关注几个比较常用的大区:栈区堆区静态区,后期其他的会慢慢渗透,字符串常量实际上是放在内存里面的只读数据区的,但现在也许不用管那么多,反正就是说在内存里面,那么肯定是有它的内存地址。
指针数组(存放指针/地址的数组)
如:
根据优先级关系,变量名先与[ ]结合,就表示是一个数组;先与*结合,就表示是一个指针变量。
1. 有整型数组存放整型,字符数组存放字符,那指针数组顾名思义就是存放指针的数组,也可以理解成是存放地址的数组,比如说char* arr[10]。再次强调一下:指针=地址=内存编号。等价着来看
2. 指针数组可以把原先在内存当中物理上不连续存放的东西它们的某些地址某种程度上又连续了
可以把指针数组想象成美国海军一样,里面有着一艘一艘的航母(指针/地址),一旦需要,可以直接到内存的某个空间去访问/执行操作
数组指针(存放数组地址/指向数组的指针)
根据优先级关系,变量名先与[ ]结合,就表示是一个数组;先与*结合,就表示是一个指针变量。
1. 指针数组是存放指针的数组。那什么是数组指针呢?那我们就回忆一下之前学的:字符指针~存放字符变量地址的指针~指向字符的指针~char*;整型指针~存放整型变量地址的指针~指向整型的指针~int*;浮点型指针,也有float*与double*,也是指向浮点型的指针。
那么好了,类比一下就知道了:数组指针就是存放数组地址的指针~指向数组的指针。
2. 那我到底该怎么写呢?int* pa[10] = &arr?发现这样明显是不对的,左边这不就是指针数组了吗?这时候发现pa不能与屁股后面的[10]结合在一起,因为如果结合在一起的话,那么就是一个数组了,而我现在在讨论数组指针。为了表示它是一个指针,首先与*结合,这样就说明它是一个指针。int (*p)[10]=&arr,这样子就对了。首先,与*结合,这就说明p 是一个指针,那么这个指针到底指向哪边的?向外一看,指向[10]这样一个东西,指向数组,10个int元素的数组。
指针数组与数组指针
1 根据优先级,变量名先与[ ]结合就表示是一个数组;先与*结合就表示是一个指针变量。
数组的类型是如:int [10],char [18]...... (就是构造类型)
2 数组名的类型:(就是指针变量的类型)
&arr的类型
数组指针的使用
1. 那么当我对数组指针解引用操作(利用其指向的内存地址以及其后的势力范围找到内存条里面的数据)的时候,你知道的势力范围老大嘞,一下子就找到了整个数组的数据,一揽子打尽。当然,对于这个数组我也可以在其里面再去访问每一个元素,如:(*p)[ i ]。但是是个正常人都知道,这样很别扭,不如用首元素的地址➕偏移量。 那这个数组指针是不是很鸡肋啊,也不见得。这个数组指针本来就对一维数组很不友好,对于一维数组来说,很少用这玩意儿,一般在二维数组用。
2. 二维数组而言,其第一个元素(首元素)就是第一行,第二行就是第二个元素......在二维数组里面,一行是一个元素,一行是一个元素。因此:二维数组是一维数组的数组,把一维数组当成一个元素,相当于是存放一维数组的一维数组。
因此:二维数组数组名 -> 首元素的地址 -> 其首元素就是第一行整个数组 -> 二维数组数组名就是数组指针
利用数组指针打印二维数组:
在创建数组那个代码里面,有三个需要说明的东西:元素个数,元素类型,数组名称。因此把数组名和元素个数拿走不看,剩下的就说明是数组每个元素的类型了。如int arr[10];拿走arr[10]剩下int,这个int就代表数组的元素类型。那道理也是一样,如int (*parr3[10])[5],当我把数组的名字与数组的元素个数拿走的时候,剩下的就是数组每个元素的数据类型,那我把parr3与[10]拿走,就剩下int (*)[5],这个就是数组每个元素的类型,因此我发现这个数组是数组指针数组。
3. 对数组指针解引用得到的就是整个数组,可以下标访问
一维数组传参
二维数组传参
一级指针传参
二级指针传参
传参其实就是在形参与实参中间划条等号