目录
数组
一、整形数组
1、a代表了整个数组的大小,四个整形的元素,大小一共16字节。
2、a+0代表的第一个元素的地址,我们可以知道在32位系统下占用4个字节。
3、*a代表的是解引用后的数组首元素,大小是一个整形,4个字节大小。
4、a+1代表的是第二个元素的地址,占用4个字节大小。
5、a[ 1 ] 代表的是数组第二个元素,一个整形4个字节大小。
6、&a代表整个数组的地址,但是地址仍然是四个字节大小。
7、*&a先取地址再解引用,就等于是a,所以代表整个数组大小,16字节。
8、&a+1中&a代表整个数组的地址,+1跳过整个数组,但是还是一地址,仍然是4个字节。
9、&a [ 0 ] 是代表了第一数组元素的地址,4个字节。
10、&a [ 0 ] + 1 代表的第一个元素的地址+1,也就是第二元素的地址,4个字节大小。
知识点:地址不分贵贱,都是统一的大小,在32位系统下,都是4个字节大小。
&数组名是代表了整个数组的地址。
*& 一个取地址一个解引用就相当于抵消了。
2、字符数组
sizeof
1、第一个代表整个数组的大小,里面总共6个元素,char类型,所以6个字节大小。
2、arr+0 代表的是第一个元素的地址,4个字节大小。
3、*arr 解引用数组名代表了第一个元素的大小,char类型1个字节大小。
4、arr[ 1 ] 代表了第二个元素的大小,1个字节大小。
5、&arr 代表了整个数组的地址,4个字节大小。
6、&arr +1 跳过整个数组的地址,但是还是一个地址,4个字节大小。
7、&arr [ 0 ] + 1 第一个元素的地址+1,第二个元素的地址,4个字节。
strlen
1、由于strlen遇到 ‘\0’ 才会停下,但是这种的字符数组系统不会补充 ‘\0’ 而自己又没给,所以什么时候停下是未知的,因此是一个随机值。
2、arr+0 是是从第一元素的地址开始计算,但是没有 ‘\0’ 所以停止时机未知,也是个随机值。
3、*arr 是里面的第一个元素 ‘a’ ,计算的时候会按照 ‘a’ 的ASCII码值97来当做地址进行计算,这里会访问异常报错。
4、arr [ 1 ] 理由同上。
5、&arr 取的是整个数组的地址,但是开始也是从第一个元素地址开始,没有 ‘\0’,所以也是一个随机值。
6、&arr + 1 跳过整个数组,开始计算,不知道什么时候遇到 '\0',所以也是随机值。
7、&arr [ 0 ] + 1 取的是第二元素的地址开始计算,理由同上,也是随机值。
知识点: strlen是遇到 ‘\0’ 才会停止的,但是数组中没有给,所以停下来是不可知的。
strlen给的如果是解引用的数据,比如传的是‘a’,他会转化成对应的ASCII码值97,然后计算这个97地址的长度,所以系统会报错。
3、字符串数组
sizeof
1、系统在计算这种字符串的数组的时候,会自动在末尾补充 ‘\0’ ,sizeof也会将它计算在内,所以arr 计算的时候还会+1 ,所以结果是7个字节。
2、代表的第一个元素的地址,4个字节大小。
3、*arr 代表第一个元素,1个字节大小。
4、arr [ 1 ] 代表了第二个元素,1个字节。
5、&arr 代表整个数组的地址,4个字节。
6、&arr +1 第二元素的地址,4字节。
7、&arr[ 0 ] + 1 代表了第二个元素地址,4个字节大小。
strlen
1、arr 从第一个开始数,数到最后一个,长度为6。
2、arr + 0 从第一个元素的地址开始数,长度为6。
3、*arr 是里面的第一个元素 ‘a’ ,计算的时候会按照 ‘a’ 的ASCII码值97来当做地址进行计算,这里会访问异常报错。
4、arr [ 1 ] 理由同上。
5、&arr 取的是整个数组的地址,但是开始也是从第一个元素地址开始,长度为6。
6、&arr + 1 跳过整个数组,开始计算,不知道什么时候遇到 '\0',所以是随机值。
7、&arr [ 0 ] + 1 取的是第二元素的地址开始计算,少一个元素,长度为5。
4、指针指向常量字符串
sizeof
1、p指向的是一地址,地址4个字节。
2、p+1指向第二个元素的地址,4个字节。
3、解引用得到第一元素,1个字节。
4、p[ 0 ] 得到得到第一元素,1个字节。
5、&p得到指针的地址,4个字节。
6、&p+1 得到指针后面一个地址,4个字节。
7、&p[ 0 ] + 1 得到第二个元素的地址,4个字节。
strlen
1、指针指向的是第一个元素地址,strlen从第一个元素的地址开始计算,6个元素长度为6。
2、p+1 从第二元素开始计算,长度为5.
3、*arr 是里面的第一个元素 ‘a’ ,计算的时候会按照 ‘a’ 的ASCII码值97来当做地址进行计算,这里会访问异常报错。
4、同上。
5、取到的是指针的地址,不知道什么时候才有 ‘\0’ 让strlen停下,因此是随机值。
6、取到的是指针后面的地址,不知道什么时候才有 ‘\0’ 让strlen停下,因此是随机值。
7、取到的是第二个元素的地址,从第二元素开始计算得到长度5。
指针
笔试题1
答案:2 5
解析:(a+1)得到的第二个元素的地址,解引用得到第二个元素 2。
指针ptr指向的是整个数组的地址+1,也就是整个数组后面的地址,然后指针-1倒回来一个元素,所以指向的是5的地址,解引用得到5。
笔试题2
答案:0x100014 0x100001 0x100004
解析:因为整个结构体因为内存对齐算得占用20个字节,+1等于加上一个结构体占用的大小,所以+20,换算成16进制为14。 而第二个是一个整数类型,+1加上的就是一个数字1。 第三个加+1,但是前面把他强制类型转换为一个指针类型,一个地址4个字节大小,+1的话就加4个字节。
笔试题3
答案:0x4 0x02000000
解析:前面说过,&a+1跳过整个数组的地址,而ptr[-1]和*(ptr-1)等价,所以打印的是元素2的地址,由于博主用的是vs2022,是小端存储模式
由于前面的0都是无效位,可以省略,所以可以写成0x4。
在这里把数组第二个元素的地址强制类型转化为了int类型
所以最终解引用打印出来的就是0x02000000
笔试题4
答案:1
解析:因为里面是三个逗号表达式,实际上只算最后的一个表达式,所以数组中实际的元素只有三个{1,3,5},实际上的数组应该是这样子
指针指向第一行第一元素,解引用得到 1
笔试题5
答案:FFFFFFFFFFFFFFFC -4
解析:因为数组是五个一行,而指针中存储的是四个一行。所以&p[4][2] - &a[4][2]是第18个元素减去22个元素,差值是-4。而%p按地址打印,差值在存储时:
原码:10000000 00000000 00000000 00000100
反码:111111111 111111111 111111111 111111011
补码:111111111 111111111 111111111 111111100
由于这是二进制,而打印时是16进制,所以换成十六进制就是FFFFFFFFFFFFFFFC
笔试题6
答案:10 5
解析:&aa+1跳过的是整个数组,取到数组后面的地址,然后指针ptr-1是退回一个元素,所以指向的的是元素是10。
&(aa+1)跳过的是一行的地址,取到第二行第一个元素6的地址。指针-1退回一个元素,指向的元素是5。
笔试题7
答案:at
解析:a代表第一个字符串首元素的地址,因为数组是指针数组,用指针指向里面的元素的地址时就需要用到二级指针pa,pa++指向第二个字符串首元素的地址,所以打印出来是at
笔试题8(前方高能)
答案:POINT ER ST EW
解析:
整个关系如图
第一个:先cpp++然后双重解引用,拿到的是c+2,c+2中存放的指针指向的是POINT。
第二个:这里先++再解引用拿到c+1的地址,然后--,注意这里不是在cp挪位置,而是在c里挪位置,所以--之后指向了c的位置,然后解引用拿到ENTER第一个字母的地址,然后+3。从第四个元素开始输出,所以输出ER
第三个:*cpp[-2] =*(*(cpp-2)),所以获取到的是c+3中的指针,指向的是FIRST,然后再+3,得到的是
第四个:cpp[1][1] = *(*(cpp-1)-1),所以这里获取到的就是指向NEW第一个字母的指针,在+1的话就是指向E(图中误写为NWE),所以打印出来就是EW。
感谢各位的观看!