当前位置: 首页 > news >正文

自定义数据类型

前言:小伙伴们又见面啦,今天这篇文章,我们来谈谈几种自定义数据类型。

 


 

目录

一.都有哪些自定义数据类型

二.结构体

结构体内存对齐

1.如何对齐

 2.为什么要对齐

3.节省空间和提升效率的方法

(1)让占用空间小的成员尽量集中在一起

(2)修改默认对齐数

三.位段

 1.什么是位段

2.位段的的内存分配

 3.位段的跨平台问题

四.枚举

1.枚举类型的定义

2.枚举的优点

五.联合体

1.联合体的定义

 2.联合体的使用

 3.联合体大小的计算

六.总结


一.都有哪些自定义数据类型

我们在C语言的基础中已经了解到了结构体,是一种对多种数据集中管理的一种自定义数据类型。

除此之外,我们还有另外三种:-

  • 位段
  • 枚举
  • 联合

接下面我们就开始对这四种数据类型逐一展开讲解。


二.结构体

在我们前边的文章《C语言基础之——结构体》中我们已经对结构体展开了细致的讲解,所以在这篇文章中我们不再重复讲解

那么在这篇文章中,我们来谈谈结构体类型的大小

我们知道任何一种数据类型都有它所占用的内存大小,但是结构体类型却是多种数据类型的整合

那小伙伴们是否知道结构体类型该如何计算大小呢???

来看例子:

#include<stdio.h>
struct Str1
{char a;char b;int c;
};
struct Str2
{char a;int b;char c;
};
int main()
{int num1 = sizeof(struct Str1);int num2 = sizeof(struct Str2);printf("%d\n", num1);printf("%d\n", num2);
}

小伙伴们可以猜一猜,Str1 和 Str2的内存大小会是多少呢???

有的小伙伴可能会说:啊,都是两个char类型和一个int类型,那大小不就是6呗

那到底是不是6呢???我们来看结果:

哇塞,天差地别不仅不是6,而且两个数还不一样

 这是为什么呢???

事实上,对于结构体,有结构体内存对齐这样一个概念。


结构体内存对齐

1.如何对齐

 我们先来看对齐的规则:

1.第一个成员放在与结构体变量偏移量为0的地址处。

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。

  • 博主所使用的VS2019的默认对齐数为8
  • Linux中没有默认对齐数,对齐数就是成员变量本身的大小

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4.如果出现嵌套结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

什么意思呢,下面我们根据例子来具体讲解:

struct Str1
{
    char a;
    char b;
    int c;
};

首先来看这个结构体,它的第一个成员变量a为char型, 大小为1个字节,放在结构体变量偏移量为0的地址处,即从0开始存放

然后第二个成员变量b也是char类型,大小为1个字节,从第二个成员变量开始我们要根据最大对齐数进行对齐将1与8相比,肯定是1较小,所以对齐数为1所谓对齐数,就是这个成员变量所存放的空间的前边所占用的空间个数需要是对齐数的整数倍,要对齐到1的整数倍的位置,我们现在只占用了一个字节,1是1的整数倍数,那自然就是从第二个字节开始存放,占用一个字节。

最后来看第三个成员变量c为int类型,大小为4个字节,则其对齐数为4那么我们要对齐到4的整数倍的位置但是现在我们只有两个字节的位置被占用,2不是4的整数倍数,所以我们还需要浪费两个字节来实现对齐到4的倍数的位置,所以要从标号为4的位置存放四个字节。

这样一来我们就得到了我们的结果,8个字节

下边我们继续来看一个例子:

struct Str2
{
    char a;
    int b;
    char c;
};

第一个为char型,放在0处。

第二个为int型,对齐数为4,现在只占用了一个字节,不是4的整数倍,所以要浪费3个字节,从标号为4的位置开始,占用四个字节。

第三个为char型,对齐数为1,8是1的整数倍,所以直接从标号为8的位置开始,占用一个字节。

这个时候出问题了,这不是才9个字节吗,那结果为什么是12个字节呢???

这时候来看我们规则的第三条: 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

我们上述结构体的最大对齐数为int型的4但是现在我们只占用了9个字节,并不是4的整数倍所以我们还得浪费3个字节,达到12个字节,才是我们最终的结果。

下面我们来看最后一个例子:

struct Str3
{
    double a;
    char b;
    int c;
};

struct Str4
{
    char a;
    struct Str3 s3;
    double c;
};

我们来计算Str4这样一个嵌套结构体的大小。

经过我们上边的学习,已经能够很容易的算出,Str3的大小为16个字节。下边我们来计算Str4。

第一个为char型,放在地址为0的位置,占用一个字节。

第二个为struct Str3结构体类型,大小为16个字节,那么根据我们的规则4,嵌套的结构体对齐到自己内部的最大对齐数的整数倍处,那么Str3内部的最大对齐数为double类型的8,所以要是8的倍数很显然1并不是8的倍数,所以要浪费7个字节,从标号为8的位置开始,占用16个字节。

第三个为double类型,大小为8个字节,对齐数为8,前边刚好占用了24个字节,是8的整数倍,所以我们就从标号为24的位置开始,占用8个字节。

 

这样,我们总共就是占用了32个字节。 

到这里,我们就讲完了通过结构体内存对齐的规则来计算结构体大小的知识。

那么小伙伴们是否有个疑惑,我们为什么就非得对齐呢?


 2.为什么要对齐

我们通过查阅大量的资料,最终得出以下两点:

1.平台原因(移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定的类型的数据,否则就会抛出硬件异常。

数据结构(尤其是栈)应该尽可能的在自然边界上对齐。

原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存访问仅需要一次访问。

总体来说: 

结构体的内存对齐是拿空间来换取时间的做法。牺牲空间来换取效率

那么有没有什么办法能够帮助我们即能够提升效率,又能节省空间呢???


3.节省空间和提升效率的方法

(1)让占用空间小的成员尽量集中在一起

struct Str1
{
    char a;
    char b;
    int c;
};
struct Str2
{
    char a;
    int b;
    char c;
};

就比如还是我们这两个结构体,成员变量一模一样,但是大小却不一样,但是Str1的空间是小于Str2的,所以,第一种方法就是:让占用空间小的成员尽量集中在一起。 

(2)修改默认对齐数

我们知道,默认对齐数这个规则对我们的空间占用影响很大,那我们便可以通过修改默认对齐数的方法来实现节省空间和提升效率

那么默认对齐数该如何修改呢???

通过#pragma这个预处理指令来改变。

#include<stdio.h>
#pragma pack(1)//将默认对齐数修改为1
struct Str1
{char a;char b;int c;
};
#pragma pack()//恢复默认对齐数的原值
struct Str2
{char a;int b;char c;
};
int main()
{int num1 = sizeof(struct Str1);int num2 = sizeof(struct Str2);printf("%d\n", num1);printf("%d\n", num2);
}

我们通过#pragma pack()这个指令,可以将默认对齐数修改为()内的值,比如我们上述代码修改为1, 修改之后,默认对齐数就固定为1每个数据都对齐到1的整数倍,同时也要记得及时恢复默认对齐数的原值,确保只有这一块的结构体我们需要修改,以免发生错误

来看结果:

 

除此之外,我们还有第三种方法,那就是——位段。 


三.位段

讲完了结构体的内存分配情况之后,我们就得紧接着来谈谈结构体实现位段的能力。

 1.什么是位段

位段的出现,是为了让结构体更加节省空间

位段的声明和结构体是类似的,有两处不同:

  • 位段的成员必须是int、unsigned int 、signed int或char类型
  • 位段的成员名后边有一个“冒号”和一个数字

来看例子:

struct Str1
{
    char a : 3;
    char b : 4;
    char c : 5;
    char d : 4;
};

 位段的位,指的是二进制的位数,char a : 3,表示a这个数据占用3个bit位

如果不用位段,我们这个结构体就是4个字节的大小,但是使用位段之后来看:

只用到了3个字节,节省了空间。

 这种情况适用于能够知道创建的数据大概会占用多少的空间

2.位段的的内存分配

 那么我们上述结构体通过位段实现的8个字节的空间又是怎么来的呢???

位段开辟空间是一步一步来的,如果是int型,就会先开辟4个字节给你用,如果不够,那就再开辟一个char同样。

我们很清楚,一个字节是8个bit位,那么a、b、c、d分别为3、4、5、4个bit位3 + 4 = 7 < 8,所以a和b共用一个字节剩下一位不够c用,那就丢掉,再开辟一个。存入c之后剩余3位,不够d用,便继续丢掉,在开辟,最终一共开辟3个字节

虽然位段能够帮助我们节省一大部分的空间,但这并不代表着我们可以随便的使用位段

因为其涉及着很多的不确定因素,不能跨平台,所以注重可移植性的程序应避免使用位段。 

 3.位段的跨平台问题

  1. int位段被当成有符号数还是无符号数是不确定的。
  2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32)
  3. 位段中的成员在内存中从左向右分配还是从右往左分配标准尚未定义。
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段的剩余位时,是舍弃剩余的位还是利用是不确定的。

对于第4条,我们上边的代码已经能够验证,在当前的VS2019编译器下是直接舍弃。


四.枚举

枚举,顾名思义也就是一一的列举。

把我们可能需要用到的数据一一列举出来。

一周的七天;

一年的月份;

一年的四季

这些都能够写成一个枚举类型来一一列举,下面我们就来看看枚举的具体用法。

1.枚举类型的定义

定义枚举常量要用到enum

enum Season
{
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
};

这样我们就定义出来一个简单的季节枚举。

值得注意的是,每个枚举常量之间都用逗号隔开最后一个枚举常量后边不用跟任何符号,而且枚举常量一般都用其英文的大写字母表示。 

在枚举类型中,枚举常量都表示一个常数从第一个枚举常量开始,代表0,此后逐个递增,因此枚举常量都是int类型

#include<stdio.h>
enum Season
{SPRING,SUMMER,AUTUMN,WINTER
};
int main()
{printf("%d\n", SPRING);printf("%d\n", SUMMER);printf("%d\n", AUTUMN);printf("%d\n", WINTER);return 0;
}

结果如下:

 

枚举常量不能在枚举类型外修改,但是可以在其定义时修改,并且会影响到后边的值

#include<stdio.h>
enum Season
{SPRING,SUMMER = 100,AUTUMN,WINTER
};
int main()
{printf("%d\n", SPRING);printf("%d\n", SUMMER);printf("%d\n", AUTUMN);printf("%d\n", WINTER);return 0;
}

例如我们将SUMMER改为100那么AUTUMN和WINTER也会在此基础上累加

 我们现在也已经了解到,枚举其实也是一种定义常量的方式,那我们前边也学过#define同样可以定义常量,那么为什么非要用枚举类型呢???

2.枚举的优点

  1. 增加代码的可读性和可维护性。
  2. 和#define定义的标识符比较,枚举有类型检查,更加严谨。
  3. 便于调试。
  4. 使用方便,一次可以定义多个常量。

五.联合体

1.联合体的定义

联合也是一种特殊的自定义类型。

这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以也叫共用体)

#include<stdio.h>
union Un
{int a;char b;
};
int main()
{union Un un;printf("%d\n", sizeof(un));printf("%p\n", &un);printf("%p\n", &(un.a));printf("%p\n", &(un.b));return 0;
}

 来看,我们输出一下这个联合体的大小、地址以及其成员的地址:

 能够看出,联合体的大小确实是int型的4个字节,且成员变量的地址都相同,这就说明它们共用同一块内存空间。

 2.联合体的使用

用来判断编译器的大小端存储:

#include<stdio.h>
int check_sys()
{union Un{int a;char b;}u;u.a = 1;return u.b;//返回1表示小端,返回0表示大端
}
int main()
{int ret = check_sys();if (ret == 1)printf("小端\n");elseprintf("大端\n");return 0;
}

既然共用一块空间,那么我们就可以通过不同类型的字节数来进行大小端的判断

得出我们当前编译器为小端存储

对于联合体的具体使用,我们指出一个方向:当成员变量不需要同时使用时,可以使用联合体

 3.联合体大小的计算

  • 联合体的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍时候,就要对齐到最大对齐数的整数倍。
#include<stdio.h>
union Un
{int a;char b[5];
};
int main()
{printf("%d\n", sizeof(union Un));return 0;
}

来看这个联合体,它的大小是多少?5吗???

并不是,而是8

因为最大对齐数为4,5不是4的整数倍,所以就要浪费3个字节达到8。 

六.总结

关于自定义数据类型的讲解到这里就结束啦。

今天的文章也是相当的长啊,快累死博主我了呜呜呜~~~

 

最后还是希望文章能够帮助到大家,不要忘记一键三连哦!!!

我们下期再见!!! 

相关文章:

自定义数据类型

前言&#xff1a;小伙伴们又见面啦&#xff0c;今天这篇文章&#xff0c;我们来谈谈几种自定义数据类型。 目录 一.都有哪些自定义数据类型 二.结构体 结构体内存对齐 1.如何对齐 2.为什么要对齐 3.节省空间和提升效率的方法 &#xff08;1&#xff09;让占用空间小的成员…...

产品团队的需求验证和确认

需求核实过程是确保软件满足特定的规格要求&#xff0c;而验证则侧重于软件是否达到了最终用户的期望和需求。 如果你正在开发一种医疗产品&#xff0c;这种区别也可能在法规和标准中有所体现&#xff0c;例如&#xff1a; 820.30(f)&#xff1a;设计验证应确认设计的成果符合…...

【JVM】类加载的过程

文章目录 类的生命周期加载验证准备解析初始化简要概括 类的生命周期 一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期将会经历加载 &#xff08;Loading&#xff09;、验证&#xff08;Verification&#xff09;、准备&#xf…...

Golang 结构化日志包 log/slog 详解(四):分组、上下文和属性值类型

上一篇文章讲解了 log/slog 包中的自定义日志属性字段和日志级别&#xff0c;本文讲解下分组、上下文和属性值类型 分组输出 slog 支持将字段放在组中并且可以给分组指定名称。如何展示分组的内容&#xff0c;取决于使用的 handler&#xff0c;例如 TextHandler 使用点号分隔…...

小白学Python:提取Word中的所有图片,只需要1行代码

#python# 大家好&#xff0c;这里是程序员晚枫&#xff0c;全网同名。 最近在小破站账号&#xff1a;Python自动化办公社区更新一套课程&#xff1a;给小白的《50讲Python自动化办公》 在课程群里&#xff0c;看到学员自己开发了一个功能&#xff1a;从word里提取图片。这个…...

pip修改位于用户目录下的缓存目录

默认 pip 缓存目录&#xff1a; Windows: C:\Users\${用户名}\AppData\Local\pip\cache Linux: ~/.cache/pip 一、修改方式 1.命令方式 pip config set global.cache-dir "D:\kwok\data\pip-cache" 2.配置文件方式 ① Windows&#xff1a; C:\Users\${用…...

更新、修改

MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129334507?spm1001.2014.3001.5502 语法: update 表名 列名该列新值, 列名该列新值, ... where 记录匹配条件; 说明&#xff1a;update 更新、修改 set 设置 …...

山西电力市场日前价格预测【2023-09-25】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-25&#xff09;山西电力市场全天平均日前电价为442.30元/MWh。其中&#xff0c;最高日前电价为720.46元/MWh&#xff0c;预计出现在19: 00。最低日前电价为276.06元/MWh&#xff0c;预计…...

从collections库的Counter类看items()方法和enumerate()方法

下面的代码是针对文件的词频统计&#xff0c;使用了collections库及其Counter类 import collections def count_word_frequency(text): words text.lower().split() word_counts collections.Counter(words) return word_counts def count_fileword_frequency(fi…...

2023-09-24 LeetCode每日一题(LRU 缓存)

2023-09-24每日一题 一、题目编号 146. LRU 缓存二、题目链接 点击跳转到题目位置 三、题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存i…...

《计算机视觉中的多视图几何》笔记(10)

10 3D Reconstruction of Cameras and Structure 本章主要描述了如何利用2张图片来恢复相机的参数以及物体在三维空间中的形状。 文章目录 10 3D Reconstruction of Cameras and Structure10.1 Outline of reconstruction method10.2 Reconstruction ambiguity10.3 The proje…...

【一、虚拟机vmware安装】

安装虚拟机 下载 官方下载地址&#xff1a;https://www.vmware.com/cn.html 大概流程就是&#xff0c;最重要的事最后一步...

uniapp 离线打包 plus.runtime.install 安装页面不弹起

uniapp 离线打包 plus.runtime.install 安装页面不弹起 updateVersion(webview : any, eventTitle : string, eventContent : string) {const loading plus.nativeUI.showWaiting(准备下载);var dtask plus.downloader.createDownload(eventContent,{method: GET,timeout: 5…...

Docker 自动化部署(保姆级教程)

Docker 自动化部署 1. jenkins 介绍1.1 参考链接&#xff1a;1.2 jenkins 概述1.3 jenkins部署项目的流程 2. jenkins 安装2.1 基于docker 镜像2.2 启动 jenkins 后端服务2.3 登录 jenkins 服务后端 3. jenkins自动化部署开始3.1 下载需要的插件3.2 创建任务3.2.1 描述3.2.2 配…...

北工大汇编题——分支程序设计

题目要求 信息检素程序设计&#xff1a;在数据区&#xff0c;有9个不同的信息&#xff0c;编号 0-8&#xff0c;每个信息包括20 个字符。从键盘接收 0-8 之间的一个编号&#xff0c;然后再屏幕上显示出相应编号的信息内容&#xff0c;按“q”键退出 完整代码 DATAS SEGMENTn0…...

贴片电容耐压值选取和特性(包含实际电路和PCB)

一、一般电容的特性 ①容值大的电容&#xff0c;一般通低频率&#xff1b;  ②容值小的电容&#xff0c;一般通高频率。   注&#xff1a;详细请看这位博主的篇文章&#xff1a; 大电容为什么虑低频小电容为什么又虑高频?(个人整理) 二、贴片电容的耐压选取 ①贴片电容有2…...

【云原生】kubernetes中pod(进阶)

目录 一、资源限制 业务cpu 内存 1.1CPU 资源单位 1.2 内存 资源单位 示例1 示例2&#xff1a; 二、健康检查&#xff1a;又称为探针&#xff08;Probe&#xff09; 2.1探针的三种规则 2.2 Probe支持三种检查方法 2.3示例 示例1&#xff1a;exec方式 示例3&#xf…...

Cesium 问题:获取高度值,高度值又是相对于谁来说的

文章目录 问题分析 问题 今天在开发中&#xff0c;甲方提出一个这样的问题&#xff0c;你的高度是怎么算出来的&#xff0c;对此&#xff0c;我只知道使用并不知道怎么来的&#xff0c;因此特意查了一番资料&#xff0c;希望帮助到大家 分析 在 Cesium 中&#xff0c;我们可以使…...

第三、四、五场面试

第三场 共享屏幕做题&#xff08;三道简单题&#xff09; 替换空格成%20&#xff08;双指针&#xff09; 删除升序链表中的重复元素&#xff08;指针&#xff09;有效的括号&#xff08;栈&#xff09; 第四场、第五场 自我介绍 项目拷打 整个项目架构rpc模块的情况分析的数…...

力扣-290.单词规律

Idea 先建立一个hashmap&#xff0c;记录s串中的每个单词以及对应的下标再建立一个hashmap&#xff0c;记录pattern串中相同字母以及对应的下标遍历pattern串时&#xff0c;遇到不同字母存到pat表中&#xff0c;同时将下标对应的s中的单词存入到查重test集中&#xff0c;因为如…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...