进阶指针(五)—— 指针笔试题

news2024/12/25 0:40:37

图片来源于网络

✨博客主页:小钱编程成长记
🎈博客专栏:进阶C语言
🎈相关博文:进阶C语言(一)、进阶C语言(二)、进阶C语言(三)、进阶指针(四)

进阶指针(五)—— 指针笔试题

  • 笔试题1:
  • 笔试题2:
  • 笔试题3:
  • 笔试题4:
  • 笔试题5:
  • 笔试题6:
  • 笔试题7:
  • 笔试题8:
  • 总结

笔试题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;
}
//程序的结果是什么?
  1. &a + 1:&a是一个数组的地址,类型是int( * )[5],+1时跳过一个数组的大小。
  2. int* ptr = (int*)(&a + 1);:然后int( * )[5]类型的地址又被强转成了int*类型的地址,赋给ptr。
  3. *(a+1) 是首元素地址+1,然后再解引用。
  4. *(ptr-1) 是ptr-1,然后再解引用。
    在这里插入图片描述
  5. 所以结果是2,5在这里插入图片描述

笔试题2:

//由于还没学习结构体,这里告知结构体的大小是20个字节(在x86(32位)环境下)
#include <stdio.h>

struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p的值为0x100000(0x开头的数字是16进制的数字)。如下表达式的值分别为多少?
//已知,结构体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;
}
  1. p+0x1:p是结构体类型的指针,p+0x1跳过一个结构体的大小,结构体Test的大小是20字节,又因为一个地址对应内存中的一字节空间, 地址是以十六进制的形式打印的,所以p+0x1为0x100000+20 == 0x100000+0x16(十进制的20==十六进制的14)

  2. (unsigned long)p+0x1:结构体类型的指针p被强转为unsigned long类型的值,由地址变成了常数,+0x1和+1效果一样。

  3. (unsigned int*)p + 0x1:结构体类型的指针p被强转为unsigned int*类型的指针,+0x1跳一个过unsigned int类型的大小。

  4. %p:是以地址的 形式(地址的长度和进制类型) 打印。
    %x:以十六进制的形式打印
    %#x, "0x%x":以十六进制的形式打印,并显示出十六进制的数据标志。

    在这里插入图片描述

  5. 结果为:0x100014,0x100001,0x100004
    在这里插入图片描述

笔试题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);

	return 0;
}
  1. (int*)(&a+1):一个数组的地址,+1跳过一个数组的大小。最后再将int( * )[4]类型的地址强转为int*类型的地址。

  2. (int*)((int)a+1):首元素地址a被强转为int类型的数据,然后再+1。最后再将int类型的(int)a+1强转为int*类型的地址。

  3. ptr1[-1] == *(ptr1-1)
    在这里插入图片描述

在这里插入图片描述
4. 结果为:4,2000000
在这里插入图片描述

笔试题4:

#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;
}

在这里插入图片描述
逗号表达式的结果是最后一个表达式的结果。
在这里插入图片描述
2. 结果为:1
在这里插入图片描述

笔试题5:

#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];//数组指针
	p = a;//类型不同,不太合适,但非要这样写也行。a-->int(*)[5],  p-->int(*)[4]
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}
  1. p = a:类型不同,不太合适,但非要这样写也行。a–>int( * )[5], p–>int( * )[4]

在这里插入图片描述2. 指针相减的差值的绝对值是指针间元素的个数。
2. %p是打印地址,认为内存中存储的-4的补码就是地址。
3. %d是以十进制的形式打印。
在这里插入图片描述

笔试题6:

#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\n", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}
  1. (int*)(&aa+1):aa是二维数组的数组名,&aa+1是跳过一个二维数组的大小。最后int ( * )[2][5]类型的(&aa+1)强转成(int * )类型。

  2. (int*)(*(aa+1))
    第一种理解方式:aa+1是二维数组的首元素地址+1,也就是第一行数组的地址+1,跳过第一行数组的大小。因为aa的类型是int ( * )[5],是一个数组的地址,所以+1后,得到的aa+1的类型也是int ( * )[5],是一个数组的地址, 解引用时访问的空间大小是有5个int类型元素的数组的大小,得到第二行数组,也就是二维数组的第二个元素aa[1],但aa[1]又是第二行的数组名,除了两个例外,aa[1]表示第二行数组的首元素地址。最后被强转为int * 类型的地址。
    在这里插入图片描述
    第二种理解方式:因为 (aa+1) == aa[1] ,并且没有sizeof(),也没有&,所以aa[1]就是第二行数组的首元素地址==&aa[1][0]。最后再强转为int
    类型,因为第二行数组的首元素地址也是int类型的,所以强转前后类型并没有发生变化。

  3. *(ptr1-1), *(ptr2-1):因为ptr1和ptr2都是int*类型的地址,所以-1时跳过一个int类型的大小。

  4. 结果是10,5
    在这里插入图片描述

笔试题7:

//阿里笔试题
#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}
  1. char* a[] = {"work","at","alibaba"};字符串作为表达式时结果是首字符地址,所以数组中存放的都是字符串的首字符地址。

  2. char* *pa = a;:a是指针数组的首元素地址,指针数组的首元素是work的首字符地址,所以a是work的首字符地址的地址。用二级指针pa接收。

  3. pa++:因为pa存放的是char * 类型的数据的地址,所以 pa++ 时跳过一个char * 类型的大小。
    在这里插入图片描述

  4. *pa:*pa指向at,是at的首字符地址。

  5. %s:打印字符串,从这个地址开始解引用打印,遇到\0停止(\0不打印)。

  6. 结果是at
    在这里插入图片描述

笔试题8:

#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;
}
  1. char* c[] = {"ENTER","NEW","POINT","FIRST"};:数组c中放的是四个字符串的首字符地址。指针指向字符串,本质上指向的是字符串的首字符

  2. c+3:c是指针数组的首元素地址,也就是ENTER的首字符地址的地址,存放在二级指针中。所以+3是跳过3个ENTER的首字符地址的大小。

  3. char***cpp = cp;:cp是二级指针数组cp的数组名,在这里表示首元素地址,表示c+3的地址。因为c+3的类型是char**,所以要用c+3的地址要存放在三级指针中。
    在这里插入图片描述

  4. cpp前置++或–后,cpp本身也会发生改变

  5. **++cpp:前置++,先++,后使用,跳过1个char * * 类型的大小,然后两次解引用得到char*类型的指针,指向POINT。
    在这里插入图片描述

  6. *--*++cpp+3:cpp先前置++,再 * 解引用,得到char * * 类型的地址c+1。然后前置 --,再 * 解引用,得到char * 类型的地址,最后再跳过3个char类型的大小,指向ENTER中的E。
    在这里插入图片描述

  7. *cpp[-2]+3cpp[-2] == *(cpp - 2),cpp先往后退2个char * * 类型的大小,然后 * 解引用,得到char * * 类型的c+3,再解引用,得到char * 类型的地址。最后跳过3个char类型的大小,指向FIRST中的S。
    在这里插入图片描述

  8. cpp[-1][-1]+1cpp[-1][-1] == * ( * (cpp - 1) - 1),cpp先往后退1个char * * 类型的大小,再 * 解引用,得到char * * 类型的c+2。然后后退1个char * 类型的大小,在解引用,得到char*类型的地址。最后跳过1个char类型的大小,指向NEW中的E。
    在这里插入图片描述

  9. %s:打印字符串,从这个地址开始解引用打印,遇到\0停止(\0不打印)。
    在这里插入图片描述

总结

这篇文章我们通过做一些指针笔试题更加深入的理解了指针。
大家有什么问题可以在评论区多多交流,如果文章有错误的地方,欢迎在评论区指正。感谢大家的阅读!大家一起进步!

点赞收藏加关注,C语言学习不迷路!
图片来源于网络

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

问题即机会,中国充电服务商加速向上

10月4日&#xff0c;能链智电与香港特别行政区引进重点企业办公室&#xff08;简称&#xff1a;“引进办”&#xff09;达成合作&#xff0c;成为首批重点引进企业。 引进办是香港特区政府引进世界各地高潜力重点企业来港的窗口&#xff0c;从这则消息可以看出&#xff0c;新能…

OpenCV 13(模版匹配和霍夫变换)

一、模版匹配 所谓的模板匹配&#xff0c;就是在给定的图片中查找和模板最相似的区域&#xff0c;该算法的输入包括模板和图片&#xff0c;整个任务的思路就是按照滑窗的思路不断的移动模板图片&#xff0c;计算其与图像中对应区域的匹配度&#xff0c;最终将匹配度最高的区域…

三相PWM整流器有限集模型预测电流控制Simulink仿真模型

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

正点原子嵌入式linux驱动开发——U-boot移植

uboot的移植并不是说从零开始将uboot移植到所使用的开发板或者开发平台上。这个对于我们开发者来说基本是不可能的&#xff0c;这个工作一般是半导体厂商做的&#xff0c;半导体厂商负责将uboot移植到他们的芯片上&#xff0c;因此半导体厂商都会自己做一个开发板&#xff0c;这…

平台项目首页——左侧菜单栏实现(三)

这里写目录标题 一、页面布局设计二、左侧菜单栏设计1、注意2、使用组件1、导入组件2、注册组件3、使用组件 3、用户信息代码设计4、左侧菜单代码设计5、用户信息——注销登录和切换项目功能实现 三、嵌套路由实现1、配置home的嵌套路由&#xff08;子路由&#xff09;2、home中…

Python-将常用库写入到一个Python程序里面,后续使用直接导入这个文件即可,就相当于导入了所有的库,就不用每次都写一堆的import了

sys.path.append(rD:\Backup\Documents) # 上方代码中的这一句 是我的常用库 所在的文件路径 当然&#xff0c;文件名建议写英文&#xff08;比如&#xff1a;Common_use_lib.py&#xff09;&#xff0c; 不要写&#xff1a;常用库... 我这里只是演示使用&#xff0c;方便理…

机器学习笔记 - 基于pytorch、grad-cam的计算机视觉的高级可解释人工智能

一、pytorch-gradcam简介 ​Grad-CAM是常见的神经网络可视化的工具,用于探索模型的可解释性,广泛出现在各大顶会论文中,以详细具体地描述模型的效果。Grad-CAM的好处是,可以在不额外训练的情况下,只使用训练好的权重即可获得热力图。 1、CAM是什么? CAM全称Class Activa…

GitHub工具之云资产管理

文章目录 0x01 介绍0x02 软件架构0x03 下载地址0x04 更新记录0x05 实现功能0x06 使用截图1、云存储工具-资产列表2、云存储工具-阿里云3、云存储工具-七牛云4、云存储工具-腾讯云5、云存储工具-亚马逊6、云存储工具-京东云7、云存储工具-金山云8、云存储工具-其他9、云存储工具…

java项目中git的.ignore文件设置

在Git中&#xff0c;ignore是用来指定Git应该忽略的故意不被追踪的文件。它并不影响已经被Git追踪的文件。我们可以通过.ignore文件在Git中指定要忽略的文件。 当我们执行git add命令时&#xff0c;Git会检查.gitignore文件&#xff0c;并自动忽略这些文件和目录。这样可以避免…

AT9110H-单通道低压 H桥电机驱动芯片

AT9110H能够驱动一个直流有刷电机或其它诸如螺线管的器件。输出驱动模块由PMOSNMOS功率管构成的H桥组成&#xff0c;以驱动电机绕组。AT9110H能够提供高达12V1A的驱动输出。 AT9110H是SOP8封装&#xff0c;且是无铅产品&#xff0c;符合环保标准。 AT9110H具有一个PWM (IN1/IN2…

【SWAT水文模型】SWAT水文模型建立及应用第七期:SWAT模型检验

SWAT水文模型检验 方式1&#xff1a;参数带回至ArcSWAT方式1.1&#xff1a;文件替换方式1.2&#xff1a;手动修改方式1.3&#xff1a; 方式2&#xff1a;于SWAT CUP中确定检验期结果方式2.1&#xff1a;率定期径流数据验证方式2.2&#xff1a;率定期检验期径流数据验证 总结参考…

九章云极DataCanvas公司完成D1轮融资

近日&#xff0c;九章云极DataCanvas公司完成总融资额3亿元D1轮融资。中国电子集团旗下中电智慧基金、华民投、中国太平旗下太平创新、浙江东方旗下东方嘉富等央国企旗下投资机构&#xff0c;以及卓源资本等专注人工智能赛道的知名财务投资机构参与本轮融资。 九章云极DataCan…

智慧驿站:为城市带来全新智慧公厕未来形态

随着城市发展和科技进步的不断推进&#xff0c;智慧公厕逐渐成为城市规划和公共设施建设的重要组成部分。而集合了创意的外观设计、全金属结构工艺、智慧公厕、自动售货、共享设备、广告大屏、小型消防站、小型医疗站&#xff0c;并能根据需要而灵活组合的智慧驿站成为其中重要…

Spring AOP 中被代理的对象一定是单例吗?

今天我们来思考这样一个问题&#xff1a;在 Spring AOP 中&#xff0c;被代理的对象是单例的吗&#xff1f;当我们每次获取到代理对象的时候&#xff0c;都会重新获取一个新的被代理对象吗&#xff1f;还是被代理的对象始终是同一个&#xff1f; 为什么要思考这个问题&#xf…

2023,社交进入大变革时代

社交赛道的发展似乎没有终局&#xff0c;尤其AIGC这一概念出现之后&#xff0c;社交有可能将迎来全新场景。那么在技术的助推下&#xff0c;社交赛道是否有可能跑出下一个超级APP&#xff1f;如何看待2023年的社交赛道变革&#xff1f;不妨来看看本文的解读。 2023社交还有新故…

springboot-admin整合及使用

0. 官方文档及示例 官方文档 示例代码:Spring-Boot-Admin-Demo 1. 概述 Spring Boot Admin(SBA)是一个开源的社区项目&#xff0c;用于管理和监控 Spring Boot 应用程序。应用程序可以通过 http 的方式&#xff0c;或 Spring Cloud 服务发现机制注册到 SBA 中&#xff0c;然…

读书笔记——C++高性能编程(一至三)

《C高性能编程》作者&#xff1a;费多尔.G.皮克斯 版本&#xff1a;2022年11月第1版 第一章.性能基础 描述了吞吐量&#xff0c;功耗&#xff0c;实时应用性能的含义。 阐述了“虽然几乎不可能提前预测最佳优化&#xff0c;但是可以确定某些设计决策将使后续优化变得非常困难…

SSCI及SCI撰写|立足于审稿进行论文修改

一、回复审稿意见视角下的论文改进 &#xff08;一&#xff09;常见审稿意见分类&#xff08;改进向&#xff09; 意见分类研究主题方面真实案例研究主题研完没有提供新的信息This is clearly a students paper Although it is adequately written it offers no new informat…

Python Parser 因子计算性能简单测试

一直以来&#xff0c;Python 都在量化金融领域扮演着至关重要的角色。得益于 Python 强大的库和工具&#xff0c;用户在处理金融数据、进行数学建模和机器学习时变得更加便捷。但作为一种解释性语言&#xff0c;相对较慢的执行速度也限制了 Python 在一些需要即时响应的场景中的…

【nvm】Node Version Manager(NVM)安装配置以及使用(WIN版)

NVM 包管理工具 安装 访问NVM-Windows的GitHub页面&#xff1a;点击nvm-setup.exe。 根据提示进行下一步&#xff0c;文件位置选择自定义位置 验证安装是否成功 nvm version 。如果成功&#xff0c;它将显示NVM的版本号。 使用 nvm list available查看所有的可以被下载…