先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
正文
📕 学习格言:博观而约取,厚积而薄发
🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! 🌹
文章目录
在我们学习指针之后,应该在实际应用中去理解和掌握它,毕竟实践才是检验真理的唯一标准,我们以后在找工作的过程中免不了会遇到与指针相关的试题,本篇文章可以帮助我们提前了解一些常见的指针考点。在学习这篇文章之前可以根据需要对
指针进行简要复习。
注:本篇文章所有代码均在X86环境下运行。
笔试题1
#include <stdio.h>
int main()
{
int a[5] = { 1,2,3,4,5 };
int\* pa = (int\*)(&a + 1);
//&a取的是整个数组的地址,&a的类型为数组指针类型int(\*)[5],(int\*)是将其强制转换为int\* 类型的指针,使其与pa的指针类型相同
printf("%d %d", \*(a + 1), \*(pa-1));//输出结果为 2 5
return 0;
}
解析:
int* pa = (int*)(&a+1)
中&a取的是整个数组的地址,(&a+1)
的类型为数组指针类型int(*)[5]
,指向的地址跳过一个a数组的大小,(int*)
是将其强制转换为int* 类型的指针,使其与pa的指针类型相同。
由上图可知*(a + 1)
得到的值为2,*(pa-1)
得到的值为5。
笔试题2
#include <stdio.h>
struct stu {
int num;
char\* pcname;
short sdata;
char ch[2];
short sarr[4];
}\* ps;//p是一个结构体指针变量
//已知,结构体stu类型的变量大小是20个字节
int main()
{
ps = (struct stu\*)0x100000;//强制类型转换为struct stu\*
printf("%p\n", ps + 0x1);//00100014
printf("%p\n", (unsigned long)ps + 0x1);//00100001
printf("%p\n", (unsigned long\*)ps + 0x1);//00100004
return 0;
}
解析:
本题考察的是指针±整数指针的变化,ps = (struct stu*)0x100000
中ps是结构体指针变量,凡是放在指针变量中的都被当成地址处理,0x100000被强制类型转换为struct stu*
类型的指针,放在ps中,此时0x100000就被当成地址处理。
ps + 0x1
中,0x1
是十六进制数字1,转换成十进制也是1。所以ps+0x1
就是ps+1,意思是ps向后走struct stu*类型的字节大小,如char*
类型的指针+1就是向后走1个字节,因为char
占1个字节;int*
类型的指针+1就是向后走4个字节,因为int
类型占4个字节。而题中ps是struct stu*
类型,+1就是向后走20个字节。20转换成十六进制为0x14,0x100000+0x14=0x100014。
(unsigned long)ps + 0x1
是将结构体指针变量ps强制类型转换为unsigned long
类型,ps+1就是向后走1个字节,unsigned long
是无符号长整型,整型+1就是+1,所以为0x100001。
(unsigned long*)ps + 0x1
是将无符号长整形ps强制类型转换为unsigned long*
类型,ps+1就是向后走4个字节,因为unsigned long
类型大小为4个字节,最后为0x100004。
%p–输出的是地址,0x表示数字是十六进制,地址往往以十六进制的形式输出,在X86环境下,地址由4个字节组成,转换为地址后,该代码输出结果为00100014 00100001 00100004。
笔试题3
#include <stdio.h>
int main()
{
int a[4] = { 1,2,3,4 };
int\* ptr1 = (int\*)(&a + 1);
int\* ptr2 = (int\*)((int)a + 1);
printf("%x %x", ptr1[-1], \*ptr2);//输出结果为 4 20000000
return 0;
}
解析:
%x- - -以十六进制输出。
(int*)(&a + 1)
中&a
取得是整个数组的地址,它的类型为int(*)[4],&a+1
跳过一个数组的大小,即跳过16个字节,再强制类型转换为(int*)
。ptr[-1]
即*(ptr-1)
,所以输出为4。
(int*)((int)a + 1)
中((int)a+1)
是将a强制类型转换为int
类型后+1,a是数组名,代表着数组首元素的地址。将数组中的元素转换成十六进制后为a[]={0x00000001,0x00000002,0x00000003,0x00000004}
,VS中采用的是小端存储,在内存中表示如下图。假设一个数的地址以十六进制表示为0x00000015,强制类型转换成整型之后为21,21+1=22,22转换成十六进制为0x00000016,所以强制类型转换成整型之后再+1相当于地址向后移动了1个字节。因此
((int)a + 1)
表示a的地址向后移动了1个字节,所以在*ptr2
中,从a的位置向后读4个字节,即00000002,因为是小端存储,在读取时就以小端的方式读,所以结果为20000000。
笔试题4
#include <stdio.h>
int main()
{
int a[3][2] = { (0,1),(2,3),(4,5) };
//逗号表达式:按照从左到右依次计算,整个表达式的结果为最后一个表达式的值。
//int a[3][2] = { 1,3,5 };
int\* p;
p = a[0];
//a[0],在二维数组中,把每一行都看成一维数组的时候,a[0]是第一行的数组名,数组名表示首元素的地址,即a[0]=&a[0][0]
printf("%d", p[0]);//输出结果为 1
//p等于a[0],p[0]等于\*(&a[0][0]+0),即数组第一个元素的值。
return 0;
}
解析:
int a[3][2] = { (0,1),(2,3),(4,5) }
中含有逗号表达式(逗号表达式:按照从左到右依次计算,整个表达式的结果为最后一个表达式的值)。计算之后得到数组为int a[3][2] = { 1,3,5 }
,p = a[0]
将a[0]赋值给整型指针变量p,在二维数组中,把每一行都看成一维数组的时候,a[0]表示第一行的数组名,数组名表示首元素的地址,即a[0]=&a[0][0]。p[0]
中p等于a[0],p[0]等于*(p+0)
等于*(&a[0][0]+0)
,即数组第一个元素的值1。
笔试题5
#include <stdio.h>
int main()
{
int arr[5][5];
int(\*p)[4];
p = arr;
printf("%p %d\n", &p[4][2] - &arr[4][2], &p[4][2] - &arr[4][2]);//输出结果为 FFFFFFFC -4
return 0;
}
解析:
本题考察的是指针-指针。int(*p)[4]
是数组指针类型,p = arr
中arr
是二维数组数组名,数组名就是首元素的地址,在二维数组中首元素地址就是第一行的地址即&arr[0]
,&arr[0]
用int(*)[5]
类型数组指针接收,将int(*)[5]
类型赋给int(*)[4]
类型,可以编译,虽然不会报错但是有警告,因为p是int(*)[4]
类型,p+1
的时候向后走4个整型,具体可见下图:
p[4][2]
可以写成*(*(p+4)+2)
,位置如上图所示,指针和指针相减的绝对值是元素之间的个数,&p[4][2] - &arr[4][2]
是低地址-高地址,得到的是-4。
-4的原码、反码和补码如下表所示:
原码、反码、补码 | 值 |
---|---|
原码 | 10000000000000000000000000000100 |
反码 | 11111111111111111111111111111011 |
补码 | 11111111111111111111111111111100 |
用%d打印的时候打印的是原码。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-Dc8kWrfY-1713340011962)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!