指针 + 数组 较为复杂凌乱的 【笔试题】

news2025/1/18 19:09:05

2024 - 10 - 10 - 笔记 - 25
作者(Author): 郑龙浩 / 仟濹(CSDN 账号名)

【指针 + 数组】的 各种题型(笔试题)

来自于鹏哥的网课,我做一下笔记

119. 【C语言进阶】笔试题详解(4)_哔哩哔哩_bilibili

① 题
#include <stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    //&a 是整个数组的地址,+1是跳过这个数组,所以该指针指向到了数组后面
    int* ptr = (int*)(&a + 1);
    //*(a + 1): a 为数组的首元素地址(第 0 个元素地址),a + 1 是数组第 1 个元素地址,解引用第 1 个元素地址得出的就是 第 1 个元素
    //ptr - 1: 上面知道了ptr指向的是数组的后边,那么 ptr - 1指向的就是数组的最后一个元素
    printf("%d, %d", *(a + 1), *(ptr - 1) );
    
    return 0;
}

打印结果:

2, 5

② 题

注:结构体大小是按照最大的成员来计算的

//结构体的大小是  4 byte * 5 == 20 byte
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p = (struct Test*)0x100000;
//这里的p是一个结构体指针变量,是可以指向如上这样结构体的一个指针

假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是 20 byte

int main()
{
//结构体指针 + 1 --> 跳过整个结构体
 printf("%p\n", p + 0x1);//0x100000 + 0x1 ==> 0x100000 + 20 ==> 0x100000 + 0x14 ==> 0x100014
    
//长整形 + 1 --> 长整形 + 1(记住,这是一个坑,这里的指针p被强制类型转换为了【无符号长整形】的数据,表示的不是指针了)
 printf("%p\n", (unsigned long)p + 0x1);//0x100000 + 0x1 ==> 1,048,576 + 1 ==> 0x100000 + 0x1 ==> 0x100001
    
//整型指针  + 1 --> 跳过一个int类型的大小
 printf("%p\n", (unsigned int*)p + 0x1);//0x100000 + 0x1 ==> 0x100000 + 4 ==> 0x100000 + 0x4 ==> 0x10004
 return 0;
}

打印结果:

0x100014
0x100001
0x10004

③ 题

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    
    //&a + 1 跳过了整个数组,再将【数组地址】强制类型【元素地址】赋给 ptr1,此时ptr指向数组后边
    int *ptr1 = (int *)(&a + 1);
    
    //a是首元素地址,将元素地址强制转换为【int型的数值】,得出int型的数值 + 1,再强制类型转换为 int*
    int *ptr2 = (int *)((int)a + 1);
    
    //ptr[-1]就是从ptr位置往前走了一个位置
    //从原来a数组的后边位置(可以想成a[5])变成了a[4]
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0;
}

下面进行逐个分析,因为电脑作图不是很方便,所以在纸上写的:

在这里插入图片描述

打印结果:

4,2000000

④ 题

#include <stdio.h>
int main()
{
    
    //在括号中数字用逗号分隔,那么得出的结果为最后一个逗号后边的数
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    
    //p指向首元素地址,所以取出来的值为1
    p = a[0];
    printf( "%d", p[0]);//1
 return 0;
}

打印结果:

1

⑤ 题

int main()
{
    int a[5][5];
    int(*p)[4];
    
    //p为数组指针,指向了a的第一行
    p = a;
    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

这个就要画图理解了, 其实和第 ③ 题还是蛮像的,下面为手绘的图:

在这里插入图片描述

FFFFFC,-4

⑥ 题

int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    //aa第 0 行的地址,&aa表示整个数组的地址
    //+ 1 就是跨过了整个数组,指向了整个数组的后边
    //然后再将二维数组地址类型的地址强制类型转换为一个元素的地址,或者说是一个变量的地址
    //所以ptr1就是指向了aa数组的后边(挨着)
    int *ptr1 = (int *)(&aa + 1);
    
    //aa是第 0 行的地址
    //aa + 1 就是第 1 行的地址
    //*(aa + 1) 就是第 1 行 第 0 个元素的地址
    //ptr2 指向第 1 行 第 0 个元素的地址,也就是&a[1][0]
    int *ptr2 = (int *)(*(aa + 1));
    
    //因为在二维数组中,所有元素的地址都是连续的,所以-1后,打印的元素是都是原本指向位置的前一个
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

打印结果:

10,5

⑦ 题

#include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 //pa指向a的首元素地址
 char**pa = a;
 //指向下一个元素
 pa++;
 printf("%s\n", *pa);//at
 return 0;
}

打印结果:

at

⑧ 题 - 挺复杂的

int main()
{
 char *c[] = {"ENTER","NEW","POINT","FIRST"};
 char**cp[] = {c+3,c+2,c+1,c};
 char***cpp = cp;
    
//cpp指向的是cp的首地址,即cp[0],也就是元素 c + 3 的位置,而cpp中存的是&cp[0]
//++cpp,指向cp[1],也就是元素 c + 2 的位置,而cpp中存的是&cp[1]
//*++cpp,是解引用&cp[1],得出cp[1]
//**++cpp,接上文,解引用cp[1],即解引用 c + 2,或者说是*(c + 2),得出来的是POINT
 printf("%s\n", **++cpp);//POINT

//如果cpp前面没有另一个变量或者常量或者地址,那么前面这些符号*--*++就没有所谓的计算顺序,优先级也不存在了,此时哪个符号离cpp最近先算哪一个
//++cpp cpp指向了cp[2],此时cpp中存储的是 &cp[2]
//*++cpp 相当于对&cp[2]进行解引用,得出来的是cp[2]
//--*++cpp 相当于是--cp[2],也就是相当于是--(c + 1),这里更改了cp数组中存储的地址,将cp[2]的元素--后,c + 1后,cp[2]就是c
//*--*++cpp 相当于 *c,是字符串"ENTER"中的第 1 个字符'E'的地址,如果打印格式为“ %s ”,得出来的是ENTER
//*--*++cpp 相当于*(c + 3),此时是字符串"ENTER"中的第 2 个字符'E'的地址
 printf("%s\n", *--*++cpp+3);//ER

//在理解次行代码之前,要先知道前面的运算已经
//1. 将cp[2]变成 c
//2. 将cpp指向了cp[2],即cpp存 &cp[2]

//cpp[-2] 相当于*( cpp - 2 ),由上可得,此时 cpp 指向的是cp[2],也就是 cpp 中存储的是 &cp[2],那么cpp - 2指向的就是cp[0],也就是cpp - 2表示的地址实际上是&cp[0],所以*cpp[2]可以相当于是cp[0] --> 得出 *cpp[-1] 就是 c + 3
//*cpp[-2] 此时将cpp[-2]进行解引用,其实就是*( c + 3 ),解引用后指向的就是字符串"FIRST"中的字符'F'
//*cpp[-2] + 3 此时指向了常量字符串"FIRST"中的字符'f'
 printf("%s\n", *cpp[-2]+3);

//在理解次行代码之前,要先知道前面的运算已经
//1. 将cp[2]变成 c
//2. 将cpp指向了cp[2],即cpp存 &cp[2]

//cpp[-1][-1] 意思其实就相当于 *(  *(cpp - 1) - 1  ),实际上就是*(  *( &cp[2] - 1) - 1  ),得出来就是*(  *cp[1] - 1  ) <   ==   > *(   c + 2 - 1   ) < == > * (   c + 1   ) 此时意思就是指向了常量字符串"NEW"的常量'N'
//cpp[-1][-1] + 1 就是 * ( c + 1 ) + 1,就是指向了常量'N'的下一个常量,即指向了'E'
 printf("%s\n", cpp[-1][-1]+1);//EW
 return 0;
}

打印结果:

POINT
ER
ST
EW

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

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

相关文章

VUE 开发——Vue学习(三)—— 智慧商城项目

目录 解释各个模块 api接口模块&#xff1a;发送ajax请求的接口模块utils工具模块&#xff1a;自己封装的一些工具方法模块components组件模块&#xff1a;全局通用的组件router路由模块&#xff1a;封装要所有路由views&#xff1a;各个页面assets&#xff1a;各种资源 van…

JAVA软开-面试经典题(7)-字符串常量池

字符串常量池 1.定义&#xff1a;字符串常量池&#xff08;String Constant Pool&#xff09;&#xff0c;用于存放字符串常量的运行时内存结构&#xff0c;其底层的实现为Hashtable。 【注意】 在JDK1.6之前&#xff0c;字符串常量池中只会存放具体的String实例&#xff0c;在…

MySQL基础探秘(3)

前面那篇文章是简单介绍了往数据库中插入数据&#xff0c;以及对数据进行有些改动。 但是&#xff0c;细想下&#xff0c;数据能够无限制&#xff0c;无约束进行插入吗&#xff1f; emm……显然是不行的&#xff0c;不然数据就乱套了&#xff0c;看起来不美观。 所以要对数据…

Axure详细介绍及功能对比,常用版本选择和替代软件分享

Axure是一款专门用于原型设计和交互设计的专业软件&#xff0c;广泛应用于用户界面&#xff08;UI&#xff09;和用户体验&#xff08;UX&#xff09;设计领域。它的主要功能是帮助产品经理、设计师以及开发人员创建具有互动性的原型&#xff0c;以便展示和测试各种应用、网站或…

CST学习笔记(二)Floquet模式激励设置

CST学习笔记&#xff08;二&#xff09;Floquet模式激励设置 在CST中我们常常使用Floquet模式来仿真频率选择表面(FSS)或者超材料等&#xff0c;但是我们设置好Zmax的floquet模式数量后&#xff0c;启动仿真&#xff0c;会发现S参数一栏中有很多我们不想要看的S参数&#xff0…

海南聚广众达电子商务咨询有限公司解锁流量密码

在这个瞬息万变的数字时代&#xff0c;电商行业如同一股不可阻挡的洪流&#xff0c;正以前所未有的速度重塑着商业版图。而在这股浪潮中&#xff0c;抖音电商以其独特的魅力&#xff0c;迅速崛起为一颗璀璨的新星&#xff0c;吸引了无数商家与创业者的目光。海南聚广众达电子商…

【题解】【动态规划01背包问题】—— [NOIP2012 普及组] 摆花

【题解】【动态规划01背包问题】—— [NOIP2012 普及组] 摆花 [NOIP2012 普及组] 摆花题目描述输入格式输出格式输入输出样例输入 #1输出 #1 提示 解法1.二维 d p dp dp1.1.思路解析1.2.AC代码 解法2.一维 d p dp dp2.1.思路解析2.2.AC代码 3.扩展:前缀和优化 [NOIP2012 普及组…

python基础知识(十一)面向过程,面向对象,对象属性,魔法方法,继承,私有权限

目录 面向过程是什么 什么是面向对象&#xff1f; 面向对象的三大特性&#xff1a; 继承 多态 类 对象 self关键字 对象属性 类外面访问属性 类内部获取属性 魔法方法 无参init()方法 有参init()方法 str()方法 del()方法 继承基础 什么是继承 单继承 多继…

Javascript笔试题目(六)

1.如何使用JS实现Promise 对象?请写出具体代码 Promise其实也不难-CSDN博客 Javascript 手写一个Promise_javascript中手写promise ?-CSDN博客 Promise其实也不难-CSDN博客 题目要求我们使用JavaScript实现一个Promise对象。对此我们可以基于Promise/A规范的要求进行实现Prom…

面试-2024年7月16号

面试-2024年7月16号 自我介绍Mysql主从复制是做了一个什么样的集群&#xff1f;在Mysql的使用过程中遇到过哪些问题&#xff1f;mysql迁移具体步骤mysql漏洞修复是怎么做的。mysql的容灾方案&#xff08;灾备恢复机制&#xff09;。redis多节点怎么部署的redis的备份与恢复、迁…

电源中的“冷地”和“热地”

最近硬件同事在弄开关电源相关项目&#xff0c;由于其第一次做开关电源&#xff0c;并不懂冷地和热地的区别&#xff0c;出现示波器探头接地夹夹“热地”导致实验室多次跳闸&#xff0c;最严重时把板子给炸了。为了了解冷地和热地的如何辨别以及为什么热地带电这些知识&#xf…

【从零开发Mybatis】引入XNode和XPathParser

引言 在上文&#xff0c;我们发现直接使用 DOM库去解析XML 配置文件&#xff0c;非常复杂&#xff0c;也很不方便&#xff0c;需要编写大量的重复代码来处理 XML 文件的读取和解析&#xff0c;代码可读性以及可维护性相当差&#xff0c;使用起来非常不灵活。 因此&#xff0c…

JavaEE 多线程第二节 (多线程的简单实现Thread/Runable)

1. 创建线程&#xff08;继承 Thread 类&#xff09;步骤&#xff1a; 继承 Thread 类&#xff1a; 创建一个类并继承 Thread 类&#xff0c;然后重写 run() 方法&#xff0c;在该方法中写入线程执行的代码 class MyThread extends Thread {Overridepublic void run()…

数据恢复超简单!9 个方法任你选!小白也能轻易恢复数据!

在当今数字化的世界中&#xff0c;数据恢复的重要性日益凸显。无论是工作中的重要文档&#xff0c;还是生活中的珍贵照片和视频&#xff0c;一旦丢失&#xff0c;都可能给我们带来极大的困扰。别担心&#xff0c;下面为大家介绍 9 个超简单的数据恢复方法&#xff0c;让小白也能…

C++基础面试题 | 什么是C++中的运算符重载?

文章目录 回答重点&#xff1a;示例&#xff1a; 运算符重载的基本规则和注意事项&#xff1a; 回答重点&#xff1a; C的运算符重载是指可以为自定义类型&#xff08;如类或结构体&#xff09;定义运算符的行为&#xff0c;使其像内置类型一样使用运算符。通过重载运算符&…

它思科技CTO聂玮奇:消除“AI幻觉”,搭建高可靠对话云平台丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 近年来&#xff0c;大模型技术在全球范围内引起了广泛关注和应用热潮。 提到人工智能&#xff0c;很多人会想到它强大的运算能力和广泛的应用场景。如今&#xff0c;语言模型的发展如火如荼&#xff0c;但其中的“幻觉”问题却带…

基于SSM社区医院预约转诊管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

SwiftUI 6.0(iOS 18)自定义容器值(Container Values)让容器布局渐入佳境(上)

概述 我们在之前多篇博文中已经介绍过 SwiftUI 6.0&#xff08;iOS 18&#xff09;新增的自定义容器布局机制。现在&#xff0c;如何利用它们对容器内容进行“探囊取物”和“聚沙成塔”&#xff0c;我们已然胸有成竹了。 然而&#xff0c;除了上述鬼工雷斧般的新技巧之外&…

STM32_实验1_建立新工程

1、使用STM32CubeIDE建立一个新工程 1.1选择时钟源为外部晶振时钟。 1.2选择调试方式为 serial wire&#xff08;串行线&#xff09;。 1.3配置时钟树. 1.4选择以 c 和 h 文件型式管理工程文件。 1.5生成 hex 可执行文件。&#xff08;完成后点击锤子&#xff09; 2.串口输出调…

鸿蒙进入“无人区”:该如何闯关?

按照华为方面的说法&#xff0c;“打造鸿蒙操作系统是三大战役&#xff0c;目前已经完成了底座和体验两大战役&#xff0c;第三大战役则是生态。”生态固然重要&#xff0c;但要让鸿蒙与当今世界主流操作系统抗衡&#xff0c;乃至成为新一代操作系统中的翘楚&#xff0c;其实还…