9.指针和数组例题
例1:(整型数组,sizeof)
例2:(字符数组,sizeof)
例3:(字符数组,strlen)
例4:(字符串,sizeof)
例5:(字符串,strlen)
printf("%d\n", sizeof(&p+1));
&p是指针,它指向的值的类型是char*,因此&p+1跳过的是一个char*的对象
&p与字符串没有关系,&p是p空间的地址
例6
例7
例8
练习:
&a取出的是数组的地址,类型为 int(*)[5],+1则跳过整个数组
然后强制转换类型为 int*,此时 -1 再解引用就是往回移动一个整型
该练习考察的是不同类型后面+1的结果:
指针+1跳过该指针类型的大小(字节),例如int*类型+1跳过4个字节,该结构体指针+1跳过20个字节
整型类型+1就是+1
当前机器存储方式为小端存储,即低地址存放低位,高地址存放高位,整型以16进制的形式存放
问1:&a是取出整个数组的地址,+1就是跳过整个数组,再强制转换为 int* 类型指针, ptr[-1] 等于 *(ptr1-1),对它解引用操作就是往回移动一个整型,得到一个16进制的整型04 00 00 00
问2:a是首元素地址,将a转为int类型+1,就是在a的地址上+1,跳过一个字节。再强转为 int* 类型解引用,就是往后访问一个 int长度(四个字节)的内容,为00 00 00 02
此处有坑,二维数组的初始化应该是{{ },{ },{ }},而这里大括号里面是小括号,为逗号表达式,表达式的结果为表达式中的后者,这里初始化的实际内容为{1,3,5},p[0]为第一行数组的首元素的地址&a[0][0],根据数组的初始化,结果为 1 。
a[5][5]为五行五列的二维数组,p为 int(*)[4] 类型的指针数组,a为二维数组的首元素地址,类型为int(*)[5],将该地址赋给p,p每+1-->p[1]-->*(p+1),就跳过4个整型,这里将p[ ][ ]也看作二维数组,p[4][2]则为第五行数组的第三个元素
指针减去指针得到的是指针之间的元素个数,低地址减去高地址得到的值是负的,由图可知两者相差4个整型,相减以%d打印结果为 -4。
以%p的形式打印, -4 在内存中是以补码的形式存在,因此需要求原码再转换成16进制得到结果。
a是一个指针数组,里面存放的是对应字符串的地址,而pa中存放的是a数组首元素的地址,pa++就是在a中往后移动一个元素,对该元素解引用则得到字符串“at"