上一讲指针链接:
指针第二部分(指针变量的定义、初始化、使用)---- 2021.1.29
“ * ”与“ & ”
“ * ”与“ & ”这两个符号是我们在使用指针时会频繁使用到的两种符号。
首先通过“ * ”符号取指针变量所指向的那块内存的内容,进而我们对那块内存区域进行操作。
“ & ”符号是对其那块被操作的内存区域取地址,也就是获取地址编号赋值给我们定义的指针变量。
上述说的两点,大家应该都清楚。但是我想借这个概念说一下表达式的数据类型匹配问题。
举个例子,有一个表达式 int *p = &a;
众所周知,上述表达式其实可以以另一种形式表示,也是为了让大家更好的理解,如下所示。
int *p;
int a;
p = &a;
在上一讲中,我们已经知道了p是一个变量,那么这个变量的数据类型是int *
类型。那表达式右边的变量是a,这个变量的数据类型是int
类型。那我此时想问,&a
这个整体是什么数据类型?
接下来我先给大家引入一个概念,在使用时,对一个表达式取*
,就会对表达式降一级*
,如果对表达式取&
,就会对表达式加一级*
。
那这句话怎么理解呢?
在上述例子中,由于a
变量是int
类型的,那么根据上面的概念,对表达式取&
,则需要对表达式加一级*
,所以最终&a整体的数据类型为int*
类型,正好与表达式左边的p
变量的数据类型相同,最终也实现了表达式两边的数据类型匹配问题。
然后再举两个例子。
第一个例子:*p = 100;
等式右边,顾名思义,是int
类型的。那么左边的变量p
是int*
类型的,由上述概念可知,对一个表达式取*
,就会对表达式降一级*
,所以等式左边最终的*p
整体的数据类型为int
类型。
第二个例子:
int *p;
int **q;
q = &p;
等式左边,变量q
的数据类型为int**
类型,右边变量p
的数据类型为int*
类型,然后由概念可知,对表达式取&
,则会对表达式加一级*
,所以最终&p
的数据类型为int**
类型,表达式两边匹配。
指针的步长
在说这个指针步长之前我想让大家了解下指针变量的大小。
举个例子,如下图所示。
解释如下:
- 我们定义了三个指针变量p1,p2,p3。并且这三个指针变量的数据类型都不同,图中我也用红框标出来了。
- 主要是打印三个指针变量的字节大小,其中使用到了sizeof函数。
- 最终结果发现,三个变量的字节大小都相同。那是因为,在上一讲也提到了,指针变量主要是用来存放地址编号的,并且我们此时的编译器是32位的,所以得出一个结论,不管什么类型的指针,大小只和系统的编译器类型有关。如果是使用64位编译器,那么结果自然而然就会变成8。
那么如果我们定义了一个双指针会怎样,结果还会一样吗?如下图所示。
结果显而易见,是一样的,因为双指针也还是指针变量,只要是指针变量就只会存放地址编号也就是地址。所以也就印证了上述的解释中的那个结论。
那我们思考一个问题,既然无论是什么类型的指针变量所能容纳的字节大小都一样,那为啥还会有这么多的数据类型呢,比如int*
,char*
,short*
,double*
等等。
举个例子,如下图所示。
解释如下:
- 由图中可知,我们定义了一个整型变量,格式是16进制的。
- 然后分别定义了三个指针变量p1,p2,p3。并且分别对其num整型变量进行取地址操作。
- 图中进行了强制转换操作。至于为什么,拿其中一个例子来讲
char* p1 = (char*)#
等式左边p1
的数据类型为char*
类型,那么num
变量的数据类型为int
类型,并且由之前可知,为了表达式的数据类型匹配,所以进行&
操作时,需要对表达式升一级*
,所以&num
整体的数据类型为int*
类型。那么众所周知,int*
和char*
类型不匹配,所以才会对等式右边进行强制转换。将int*
替换成char*
类型。
- 打印时我们采用
%x
格式输出,这个符号主要是输出16进制的int
类型。 - 最终结果大家可以看到,三个变量的输出却不一样。这是为什么呢?接下来就正式引入步长的概念。首先char类型输出结果为04,short类型输出结果为0304,int类型输出结果为01020304。大家可能会发现这和我们定义的指针变量本身的类型有关。
char *p
取一个字节
short *p
取两个字节
int *p
取4个字节
所以其实我们可以将这个步长理解为宽度,也就是通过*
取指针变量的所指向的那块内存空间的内容时,取得内存的宽度(步长)和指针变量本身的类型有关。
那么求取指针变量的步长的操作可以通过sizeof函数实现。例如char *p
可以等价为sizeof(char)
。
步长:sizeof
(将指针变量与指针变量最近的*
抹掉,剩下的类型)
再举个例子
int **p;//即sizeof(int *) = 4;
至于步长的概念,我们在之后的数组指针或者指针数组还会提到,大家不理解也可以,到时候也会再详细讲解。
结束语
如果觉得这篇文章还不错的话,记得点赞 ,支持下!!!