C语言-八道笔试题由浅入深玩转指针_int ( p[10])[20](1)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

图解:

所以相当于只初始化了前三个元素,后面的元素未初始化,默认为0

解析:

a[0] : 二维数组第一行的数组名,在这里是首元素地址,即第一行第一个元素的地址

p[0] >*(p+0)>*p

p是整形指针,解引用向后访问4个字节


五.笔试题5-指针与二维数组
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]);
    return 0;
}

注意:p是数组指针,指向的数组有4个元素

指针-指针得到的是二者之间的元素个数

p[4] = *(p+4)

p[4][2] ==> *(*(p+4)+2)

图解:

&p[4][2]为小地址,&a[4][2]为大地址,小地址减大地址,所以最后结果为-4


-4:
原码:10000000 00000000 00000000 00000100
反码:11111111 11111111 11111111 11111011
补码:11111111 11111111 11111111 11111100

使用%p方式打印:打印的是-4对应的补码 1111 1111 1111 1111 1111 1111 1111 1100 ->结果为:FFFFFFFC

整数在内存中以补码方式存储打印地址和打印无符号整数一样,都是打印内存中补码

使用%d方式打印:打印二进制补码对应的原码,=>  -4


注意:a是二维数组,对应数组指针的类型为:int(*)[5],指向的是有5个元素的一维数组

而p是数组指针,指向的数组只有4个元素,所以会有警告

->可以写成 int(*p)[4] = (int(*)[4])a 消除警告


六.笔试题6-指针与二维数组
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int *ptr1 = (int *)(&aa + 1);
    int *ptr2 = (int *)(*(aa + 1));
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));    // 5 10
	return 0;
}

解析:

&aa:取出二维数组的地址 &aa+1:跳过二维数组

&二维数组应该使用数组指针接收,现在保存到整形指针,所以要强转。

aa:没有单独放在sizeof内部,没有&数组名,所以代表的是二维数组首元素地址,即二维数组第一行的地址

aa+1:跳过一行

*(aa+1) : 相当于拿到了第二行的数组名 等价于 aa[1]

图解:


七.笔试题7-指针与字符指针数组
#include <stdio.h>
int main()
{
    char *a[] = {"work","at","alibaba"};
    char**pa = a;
    pa++;
    printf("%s\n", *pa);
	return 0;
}

解析:

a是数组,元素类型为:char* ,存放的是指向字符串的首字符地址

根据后面初始化的内容确定数组的大小

char** pa = a ; 此处的a是首元素地址,char**类型

--------

char**pa :一颗*说明pa是指针,另一颗*说明pa指向的类型是char*

pa+1:跳过char*

所以从字符a的地址向后打印,遇到\0即停止打印

打印结果为:at


图解:


八.笔试题9-指针与字符指针数组(难)

int main()
{
    char *c[] = {"ENTER","NEW","POINT","FIRST"};
    char**cp[] = {c+3,c+2,c+1,c};
    char***cpp = cp;
    printf("%s\n", **++cpp);
    printf("%s\n", *--*++cpp+3);
    printf("%s\n", *cpp[-2]+3);
    printf("%s\n", cpp[-1][-1]+1);
    return 0;
}

这道题比较难,所以我们分表达式解决!


最最最初的内存布局:


解析:**++cpp

前置++,cpp先自增,


此时cpp

(存放了)指向存放c+2地址的空间(地址)

*cpp->得到c+2的地址

**cpp得到c+2中存放的内容->首字符P的地址


所以从首字符P开始向后打印,打印结果为:POINT


解析:*–*++cpp+3

注意:上面的表达式,cpp发生自增,指向的已经是存放c+2地址的空间

++cpp :前置++,cpp发生自增原来是指向存放c+2地址的空间,变为指向存放c+1地址的空间


*++cpp:拿到存放c+1地址的空间,里面存放的是c+1的地址

–*++cpp;前置–,相当于自减解引用cpp之后的内容,即自减c+1的地址,(地址值是常量)。即把原来空间存放的是c+1的地址变成了存放的是c的地址,即现在拿到的是存放c地址的空间


*–*++cpp : 得到c空间中存放的内容(首字符E的地址)

*–*++cpp+3 :从首字符E的地址向后+3 ,即为E的地址


从E的地址向后打印->打印结果为ER


解析:*cpp[-2]+3


cpp[-2] >*(cpp+(-2) )> *(cpp-2)

*cpp[-2]+3 ==> **(cpp-2) )+3

cpp-2:从指向存放c地址空间又变为了指向存放c+3地址的空间

*(cpp-2):得到cpp现在指向的内容,即c+3的地址

**(cpp-2):得到c+3空间的内容(首字符F的地址)

**(cpp-2)+3 :从首字符F的地址向后+3,即为S的地址


从S的地址向后打印,打印结果为:ST


网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

**(cpp-2):得到c+3空间的内容(首字符F的地址)

**(cpp-2)+3 :从首字符F的地址向后+3,即为S的地址


从S的地址向后打印,打印结果为:ST


网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-ymgivZFD-1713277946723)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值