当前位置:网站首页>【指针训练——八道题】
【指针训练——八道题】
2022-07-06 02:48:00 【Fighting阳!】
`
每一个不曾起舞的日子,都是对生命的辜负。
题目:
笔试题1
int main()
{
int a[5] = {
1,2,3,4,5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));//2 5
return 0;
}
//程序的结果是什么?
a表示这个数组的首地址,&a则是整个数组的地址,故在进行(&a+1)操作的过程中,+1操作跳过了a整个数组,由于a是数组,&a代表数组指针,在赋值ptr的过程,左面是整形指针,右面是数组指针,两边类型有所差异,故用(int*)将(&a+1)强转成整形指针类型,否则会产生警告。故对于*(a+1),a+1为2的地址,(a+1)就是2,ptr-1为5的地址,(ptr-1)就是5。
笔试题2
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;//即p = (struct Test*)0x100000
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
0x表示16进制,0x1代表1,由于p是指针类型,指针+1或者减1代表跳过这个类型的大小,即:
(1)一个整形指针+1代表跳过一个整型
(2)一个结构体指针+1代表跳过一个结构体
(3)一个字符指针+1代表跳过一个字符
(单位:字节)
故p+0x1代表跳过这个结构体(20字节),化成16进制就是14,故p+0x1 为0x100014;(unsigned int)p代表普通整形类型,故+1就代表这个整形数字+1,并不是地址之间的运算,(unsigned int)p+0x1 为0x100001;(unsigned int*)p把结构体类型指针强转成无符号整型的指针,故+1所跳过的步长从20变成了4,即(unsigned int*)p+0x1为0x100004。
笔试题3
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);
return 0;
}
对于ptr1的操作与笔试题1操作相同,ptr1[-1]表示*(ptr1-1),即为4;
对于ptr2的操作,假设a的地址为0x0012ff40,当强转成int类型时,即表示整数0x0012ff40故(int)a+1就代表数字0x0012ff41,再强转成(int*)类型,又变成了地址,即在a原来的地址上向右移动了一个字节大小,故ptr2指向位置如图所示,由于是int*,故解引用时需从ptr2指向的位置开始数直到第四个字节00 00 00 02,,由于是小端存储模式(上篇提到过),故读数需从高地址然后低地址,02 00 00 00,由于地址本是16进制,%x打印即为20000000
笔试题4
int main()
{
int a[3][2] = {
(0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
在此之前,我们需要注意的是逗号表达式的结果为最后面的数字,即a[3][2]的内部数字为:{
1,3,
5,0,
0,0}
a[0],表示矩阵第一行的数组名,故p代表第一行数组名,p[0] = a[0][0] = 1;
笔试题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;
}
由以上代码我们看到,a为int [5[[5],p为int(*)[4],由于类型不匹配,故赋值时会发生警告,但仍然可以运行,通过绘图,我们可以看出p[4][2]与a[4][2]的具体位置,地址-地址等于地址之间相差元素的个数,故以%d形式打印时结果为-4;当以%p打印时,根据-4的原码:10000000000000000000000000000100,
求出反码:111111111111111111111111111111111011,再求出补码:111111111111111111111111111111111100,可化为ff ff ff fc
笔试题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));
return 0;
}
经过几道题的讲解,这道题与前几道类似,主要就是将图化成一行,而不是两行,故得到的结果为10 5
笔试题7
int main()
{
char* a[] = {
"work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
数组名表示首元素地址,当把a赋值给pa时,pa指向了a的地址,由于pa为char**即pa++移动的大小为一个char*大小,故表示如图,pa指向(a+1),*pa代表:
*(a+1)即a[1],即以%s打印a[1],结果为at。
笔试题8
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;
}
作为最后一题出现,势必会很麻烦,因此,我们需要弄清它们之间的关系,即前三行代码之间的关联,如上图。
1)当我们执行第一个printf时,++cpp,则cpp指向了cp[1],即:
故**cpp就是将连线的一点一点解引用,*cpp找到cp[1],
**cpp找到c[2],最终打印POINT;
2)当我们执行第二个printf时,又++cpp,指向cp[2],再解引用,即通过连线找到下一级,即到达cp[2],–cp[2],即cp[2]从指向c[1]变成指向c[0],再解引用,到达ENTER的首地址,再+3,到达ER,即:
3)当我们执行第三个printf时,可变成:
即cpp-2为cp[0]的地址,解引用变成cp[0],再解引用为c[3],c[3]看成数组名,为FIRST首元素F的地址,+3为S的地址,故结果为ST;
4)当我们执行第四个printf时,按照上述找线段的方法,不难找到:
即结果为EW。
总结:
通过以上八道题的训练,囊括了指针核心的运算以及最难理解的部分,不难看出,画图并且画好图才是降伏一切指针关系的最终手段。
边栏推荐
- MySQL winter vacation self-study 2022 11 (7)
- Differences and usage scenarios between TCP and UDP
- [matlab] access of variables and files
- CSP date calculation
- 【若依(ruoyi)】启用迷你导航栏
- [Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 8
- [network security interview question] - how to penetrate the test file directory through
- 原型图设计
- Is there a case where sqlcdc monitors multiple tables and then associates them to sink to another table? All operations in MySQL
- Zhang Lijun: penetrating uncertainty depends on four "invariants"
猜你喜欢
A doctor's 22 years in Huawei
【MySQL 15】Could not increase number of max_ open_ files to more than 10000 (request: 65535)
RobotFramework入门(一)简要介绍及使用
Introduction to robotframework (III) Baidu search of webui automation
ReferenceError: primordials is not defined错误解决
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 24
Network Security Learning - Web vulnerabilities (Part 1)
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 23
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 18
PMP practice once a day | don't get lost in the exam -7.5
随机推荐
[kubernetes series] learn the exposed application of kubernetes service security
SQL table name is passed as a parameter
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 14
07 singleton mode
Crawler (9) - scrape framework (1) | scrape asynchronous web crawler framework
[ruoyi] enable Mini navigation bar
#PAT#day10
2.13 simulation summary
RobotFramework入门(三)WebUI自动化之百度搜索
MySQL winter vacation self-study 2022 11 (8)
Is there a completely independent localization database technology
Microsoft speech synthesis assistant v1.3 text to speech tool, real speech AI generator
Reset nodejs of the system
有沒有sqlcdc監控多張錶 再關聯後 sink到另外一張錶的案例啊?全部在 mysql中操作
Pat 1046 shortest distance (20 points) simulation
550 permission denied occurs when FTP uploads files, which is not a user permission problem
Technology sharing | what if Undo is too big
Looking at the trend of sequence modeling of recommended systems in 2022 from the top paper
Advanced technology management - what is the physical, mental and mental strength of managers
Pat grade a 1033 to fill or not to fill