【C语言】指针练习篇(下),深入理解指针---指针练习题【图文讲解,详细解答】

 欢迎来CILMY23的博客喔,本期系列为【C语言】指针练习篇(下),深入理解指针---指针练习题【图文讲解,详细解答】,图文讲解指针练习题,带大家更深刻理解指针的应用,感谢观看,支持的可以给个赞哇。

前言

作为指针系列的番外练习篇,本篇主要以指针练习题为主,本期博客将上期未写的二维数组开头,并且以做题的视角带入,进行深刻理解指针练习题中不同用法区别。 

二、指针,数组笔试题 

 2.3二维数组

	int a[3][4] = { 0 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a[0][0]));printf("%d\n", sizeof(a[0]));printf("%d\n", sizeof(a[0] + 1));printf("%d\n", sizeof(*(a[0] + 1)));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(*(a + 1)));printf("%d\n", sizeof(&a[0] + 1));printf("%d\n", sizeof(*(&a[0] + 1)));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a[3]));

x86环境结果如下:

x64环境结果如下:

2.3解析:

     printf("%d\n", sizeof(a));

a单独放在sizeof后面,计算的是整个数组的大小,大小3*4*4 = 48字节
    printf("%d\n", sizeof(a[0][0]));

a [0][0],表示的是数组第1行第1列元素,元素是0,计算大小是整型,大小为4字节
    printf("%d\n", sizeof(a[0]));

a[0] 表示的是数组第一行的数组名,单独放在sizeof后面,计算的是一个一维数组的大小,大小为4*4 = 16字节
    printf("%d\n", sizeof(a[0] + 1));

a[0] 表示的是数组第一行的数组名,因为并没有单独放在sizeof后面,所以数组名表示数组首元素的地址,也就是a[0][0]的地址, a[0] + 1  == *(a+0) + 1 是第一行第二个元素的地址,是地址,大小就为4/8字节
    printf("%d\n", sizeof(*(a[0] + 1)));

 根据上面解释,解引用后得到的解释第一行第二个元素,数据类型是整型,所以大小为4字节
    printf("%d\n", sizeof(a + 1));

 a并没有单独放在sizeof后面,没有&,所以表示数组首元素的地址,即a[0],+1后就表示a[1]的地址,是地址就为4/8字节
    printf("%d\n", sizeof(*(a + 1)));

根据上面所说,得到的就是a[1]所对应的元素,计算的是整个一维数组的大小,数据类型是int,所以大小为4*4 = 16字节
    printf("%d\n", sizeof(&a[0] + 1));

&a[0]表示将第一行的数组地址取出来,+1就是跳过整个数组,表示的是a[1]的地址,是地址大小为4/8字节
    printf("%d\n", sizeof(*(&a[0] + 1)));

同上所述,解引用后计算的是a[1]整个数组的大小,大小为4*4=16字节
    printf("%d\n", sizeof(*a));

a是数组首元素的地址,也就是数组第一行(a[0])的地址,解引用计算的是 a[0],计算的是一个一维数组的大小,大小为4*4 = 16。

*a == *(a+0) == a[0]
    printf("%d\n", sizeof(a[3]));

因为sizeof是根据类型推断的,所以它不会实际访问,在这里a[3]  == a[0],所以大小为4*4 = 16

三、指针运算笔试题

 3.1

#include<stdio.h>int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1));return 0;
}

结果如下:

 解析:

&a 表示取出整个数组的地址,+1后表示指向五后面的地址,将其整体转换成int *类型存入,ptr指针变量中,所以ptr此刻指向的是五的末尾,(a+1),a是数组名,并没有单独放在sizeof后面,也没有&操作符,所以表示数组首元素地址,+1指向数组第二个元素的地址,解引用得到2,ptr - 1,跳过的是指针类型,ptr的指针类型是int * 类型,所以跳过4个字节,指向五的前面,解引用得到5,所以答案为2,5

3.2

#include<stdio.h>
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结构是啥?
struct Test
{int Num;char* pcName; short sDate; char cha[2];short sBa[4];}*p = (struct Test*)0x100000;int main()
{printf("%p\n", p + 0x1);printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0;	
}

结果:

解析:考点是指针加减整数,不懂的可以看入门篇http://t.csdnimg.cn/n6szR

第一个,p+0x1 ,首先0x1,转换成十进制是加1,p是指针变量,加一跳过一个指针类型的大小,p的指针类型是结构体类型,大小为20,故答案是0x100014(原先的十六进制加二十)

第二个, p不是指针,所以p如果加1,就是简单的值相加,故原先的十六进制加1,答案为0x100001

第三个,p是unsigned int*类型的指针变量,指针变量+1,跳过一个unsigned int*类型大小,故加4,0x100004

3.3

#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p;p = a[0];printf("%d", p[0]);return 0;
}

解析:

因为数组中是有逗号表达式,所以从左到右依次计算,但是整个表达式的结果是最后一个一个表达式的结果,故数组中的值是{1,3,5};

所以 int a[3][2] = { 1,3,5} 

所以打印结果为1

3.4

//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>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;}

结果如下:

解析:考点为指针减指针,不懂的可以看入门篇http://t.csdnimg.cn/n6szR

int (*p)[4]是一个数组指针,如果把a放入p中,就相当于用p给a数组划分区域了。

它们中间相差四个元素,相减完得到-4.

如果用%p打印-4,就打印地址,就是用二进制表示-4,%d就是直接打印-4

FFFFFFFC,-4

3.5

#include <stdio.h>
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;
}

结果如下: 

 解析:

&aa + 1,aa是数组名,放在&后面,表示取出整个数组的地址,+1表示指向10的末尾的地址,将其转换成int * 类型,放入ptr1

(aa + 1) aa是数组名,没有单独放在sizeof后面,也没有&操作符,所以表示数组首元素地址,aa[0]. +1后表示a[1]的地址。将其解引用后,就表示a[1]。将其存入ptr2 减一后指向的位置就是5.

所以答案就为10和5

aa分布图如下:

3.6

#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" }; char** pa = a;pa++;printf("%s\n", *pa); return 0;
}

结果如下:

  

解析:

char* a[]  是一个指针数组,当中存放的是w a a的地址,我们用一个二级指针pa来指向a这个数组,pa++后指向的是中间区域,解引用后得到的就是at

3.7

#include <stdio.h>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;}

结果如下:

 

解析: 

    printf("%s\n", **++cpp);

**++cpp,此刻cpp先加后用,cpp指向cp的第二个元素,也就是c+2的位置,解引用第一层,获得p的地址,再解引用后,得到POINT

    printf("%s\n", *-- * ++cpp + 3);

* -- *++ cpp + 3  首先看++cpp,指向C+2这个位置,++cpp后,指向c+1这个位置,解引用后,再--,指向E这个位置,解引用后+3,指向的是T后面E前面,所以打印ER

    printf("%s\n", *cpp[-2] + 3);

cpp[-2] == *(cpp-2),所以此刻cpp指向的位置是C+3,解引用后得到F所指向的位置,+3后指向S的前面,最后打印,得到ST
    printf("%s\n", cpp[-1][-1] + 1);

cpp[-1][-1] === *(*(cpp -1) -1), cpp指向的位置是c+1,减一后指向c+2,解引用后指向p,然后减一,指向N,最后解引用再+1,指向E前面,所以打印EW

图如下所示

感谢各位同伴的支持,本期指针练习篇(下)就讲解到这啦,如果你觉得写的不错的话,可以给个赞,若有不足,欢迎各位在评论区讨论。    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/470134.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业计算机服务器中了mkp勒索病毒怎么办?Mkp勒索病毒解密处理

随着网络技术的不断发展&#xff0c;企业的生产运营也加大了步伐&#xff0c;网络为企业的生产运营提供了强有力保障&#xff0c;但网络是一把双刃剑&#xff0c;给企业带来便利的同时也为企业带来了严重的数据威胁。春节期间&#xff0c;云天数据恢复中心接到很多企业的值班人…

CCF编程能力等级认证GESP—C++2级—20231209

CCF编程能力等级认证GESP—C2级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)小杨做题小杨的 H 字矩阵 参考答案单选题判断题编程题1编程题2 …

嵌入式中全面解析 SPI 通信协议方法

SPI 的英文全称为 Serial Peripheral Interface&#xff0c;顾名思义为串行外设接口。SPI 是一种同步串行通信接口规范&#xff0c;主要应用于嵌入式系统中的短距离通信。该接口由摩托罗拉在20世纪80年代中期开发&#xff0c;后发展成了行业规范。 SPI 是一种高速的、全双工的…

第三十回 张都监血溅鸳鸯楼 武行者夜走蜈蚣岭-python可接受任意数量参数的函数

武松回到孟州城&#xff0c;来到张都监后花园墙外&#xff0c;这是一个马院&#xff0c;问清楚后槽张团练他们三人还在鸳鸯楼吃酒&#xff0c;直接一刀杀了。武松从后门这里爬过墙&#xff0c;来到了厨房&#xff0c;将两个还在服侍的丫环杀了。 武松认得路&#xff0c;蹑手蹑…

Photoshop 中的“彩蛋”

在 Photoshop 中隐藏了几个“彩蛋” Easter Eggs&#xff0c;是开发者留下的小秘密或玩笑功能&#xff0c;也许是他们在紧张的开发过程中的一种自我调节吧&#xff0c;就如复活节彩蛋一样&#xff0c;同样也可以给 Photoshop 的用户们带来一点小“惊喜”。 这些彩蛋通常以有趣的…

C语言—数组一维(含冒泡排序)

1.用数组存储10个整型数&#xff0c;通过键盘输入一个数&#xff0c;找出该数在数组中的下标值&#xff1b; /*1.用数组存储10个整型数&#xff0c;通过键盘输入一个数&#xff0c;找出该数在数组中的下标值&#xff1b;*/#include <stdio.h>int main(void) {int nums[…

Java实现贫困地区人口信息管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 人口信息管理模块2.2 精准扶贫管理模块2.3 特殊群体管理模块2.4 案件信息管理模块2.5 物资补助模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 人口表3.2.2 扶贫表3.2.3 特殊群体表3.2.4 案件表3.2.5 物资补助表 四…

详解Python中的str.format方法

字符串的内置方法大致有40来个&#xff0c;但是一些常用的其实就那么20几个&#xff0c;而且里面还有类似的用法&#xff0c;区分度高比如&#xff1a;isalpha,isalnum,isdigit&#xff0c;还有一些无时不刻都会用到的split切分&#xff0c;join拼接&#xff0c;strip首尾去指定…

深度学习的新进展:探索人工智能的未来

文章目录 &#x1f4d1;引言深度学习技术概述计算机视觉领域的深度应用自然语言处理的深度革命跨领域应用的深度拓展深度学习的挑战与未来展望结语 &#x1f4d1;引言 在科技日新月异的今天&#xff0c;深度学习作为人工智能领域的一颗璀璨明珠&#xff0c;正在引领着技术创新…

Nvidia 推出了本地版聊天 Chat with RTX;OpenAI联创Karpathy宣布离职专注个人项目

&#x1f989; AI新闻 Nvidia 推出了本地版聊天 Chat with RTX 摘要&#xff1a;英伟达最近发布了名为“Chat with RTX”的Demo版个性化AI聊天机器人&#xff0c;适用于Windows平台&#xff0c;需要Nvidia的30系/40系显卡&#xff0c;显存至少为8GB&#xff0c;系统配置包括1…

极市平台 | 16个图像分类方向开源数据集资源汇总(附下载链接,建议收藏!)

本文来源公众号“极市平台”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;16个图像分类方向开源数据集资源汇总&#xff08;附下载链接&#xff09; 本文汇总了16个图像分类相关的开源数据集&#xff0c;均附有下载链接。要构建…