指针对于不少人来说:是多么一个难的代名词呀!!当然这个里面也包括笔者!所以……笔者对于指针满满的后怕!但是也有着更多的期待!毕竟阴影是用来打破的!后怕打破了,也就是龙腾虎跃的时候了!!下面进入正题:
笔者将用代码+解析的方式来带领大家走进:指针!!
第一题!
#include <stdio.h> int main() { int arr[3][2] = { (0,1),(2,3),(4,5) }; int* p; p = arr[0]; printf("%d\n", p[0]); //1 return 0; }
注意,笔者的代码是在vs2022 的x86环境下进行演示的!请注意细节,若是在vs2022的x64环境下,出现不一样或者一样的结果!但结果都是正确的!(笔者亲测,在vs2022中x64的环境下,笔者讲解的部分指针笔试题解析,有着不一样的结果!但都是正确的!!)
若是有老铁能直接看懂,并且能够跟答案对上号,那么这篇博客,这位老铁就没有看的必要了,下面内容主要是对上面的代码的讲解!并不做其他的内容!但若是有兴趣,可以进一步欣赏!
下面进入讲解部分:
1.首先对于数组:int arr[3][2] = { (0,1),(2,3),(4,5) }; 笔者在这里面,小小的考验一下读者:对于前面所讲述的逗号表达式,是否已经忘记??在这儿强调一下!!所以上述数组初始化后实际初始化的内容为:1,3,5,因此整个数组初始化后内容为:int arr[3][2] = { 1,3,5,0,0,0}!笔者在刚刚接触到这个数组时候,也是巧妙地被……栽坑里面了!!
2.对于数组: arr[3][2] = { 1,3,5,0,0,0}
int *p :整型指针,arr[0] 为第一行的数组名,arr[0]没有单独放在sizeof内部,也没有进行&arr[0], 所以,数组名表示首元素的地址,即元素1的地址!p=arr[0],指的意思为:p=&arr[0][0],所以指向元素1, 对于: p[0]指: *(p+0)—》*p ;指向第一个元素1,即打印结果为1!!
代码的运行结果为:
第二题:
#include <stdio.h> int main() { int a[5][5]; int(*p)[4]; p = a; printf("%p %d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); //FFFFFFFC -4 return 0; }
对于这个题目,感觉很有难度!!若是读者能够自己看懂!已经很算是大佬级别人物!!下面请看笔者解析!
首先,笔者先进行简单提示一下:指针(地址)减去指针(地址)计算的是两个指针之间的元素个数!!
1.对于:int(*p)[4] ;p是一个指针,它能指向一个数组,4个元素,每个元素都为int (整型)!p=a;将a赋值给p, a是数组名,表示数组首元素的地址!即为第一行的地址!a的类型为:int (*)[5]是一个指针数组,而p 的类型为: int (*)[4]; 与a的类型不一样,会发生警告!!
2.int (*p) [4] : 指向4个元素,每个元素为int 类型!p+1, p+2, p+3,p+4,在图上分别标注出来:
p[4][2]相当于: *(*p+4)+2) ; 整型的数组指针:解引用的时候,有权利访问4个字节!
3.随着数组下标的增长,地址由低到高!
对于:&p[4][2] - &a[4][2] 以%d打印时候:小地址减去大地址!(之间的元素个数为4个)所以结果为-4!!
&p[4][2] - &a[4][2] 以%p打印时候:
-4的原码为:1000000000000000000000000000000100
反码为: 111111111111111111111111111111111111011
补码为: 111111111111111111111111111111111111100
但是以%p的形式打印,并不讲究原码,反码,补码的问题!但是由于在内存中存放的是补码!所以将:补码: 111111111111111111111111111111111111100当作了地址来进行打印!
4个二进制位为一个16进制位!而且4个1为一个F,所以上面划算后的结果为:FFFFFFFC!!
代码的运行结果为:
简简单单的两个指针笔试题解析!已经讲完!若各位老铁有不同的意见,请及时练习笔者!!