【C语言入门】解锁核心关键字的终极奥秘与实战应用(二)

目录

一、sizeof

1.1. 作用

2.2. 代码示例

二、const

2.1. 作用

2.2. 代码示例

三、signed 和 unsigned 

3.1. 作用

3.2. 代码示例

四、struct、union、enum

4.1. struct(结构体)

4.1.1. 作用

4.1.2. 代码示例

4.2. union(联合体)

4.2.1. 作用

4.2.2. 代码示例

4.3. enum(枚举类型)

4.3.1. 作用

4.3.2. 代码示例

五、typedef

5.1. 作用

5.2. 代码示例


接着上一篇【C语言入门】解锁核心关键字的终极奥秘与实战应用(一)-CSDN博客继续分析核心关键字。

一、sizeof

1.1. 作用

  • 数据类型sizeof 可以直接作用于基本数据类型(如 intcharfloatdouble 等)以及用户定义的数据类型(如结构体、联合体等)。

  • 变量sizeof 也可以作用于变量,此时它返回的是该变量类型所占的内存大小,而不是变量的值。

  • 编译时计算sizeof 的计算是在编译时进行的,而不是在运行时。意味着它不会增加程序的运行时间开销。

  • 括号:在使用 sizeof 时,通常建议将其操作数放在括号中,以避免潜在的解析歧义。例如,sizeof(int) 而不是 sizeof int

  • 指针:当 sizeof 作用于指针时,它返回的是指针类型本身所占的内存大小,而不是指针所指向的数据的大小。

2.2. 代码示例

示例1:基本数据类型

#include <stdio.h>  int main() {  printf("Size of int: %zu bytes\n", sizeof(int));  printf("Size of char: %zu bytes\n", sizeof(char));  printf("Size of float: %zu bytes\n", sizeof(float));  printf("Size of double: %zu bytes\n", sizeof(double));  return 0;  
}
  • 运行结果:

sizeof 被用来计算基本数据类型 intcharfloat, 和 double 的大小,并将结果打印出来。

示例2:变量 

#include <stdio.h>  int main() {  int a = 10;  char b = 'c';  printf("Size of variable a (int): %zu bytes\n", sizeof(a));  printf("Size of variable b (char): %zu bytes\n", sizeof(b));  // 或者直接使用变量类型  printf("Size of type of variable a: %zu bytes\n", sizeof(int));  printf("Size of type of variable b: %zu bytes\n", sizeof(char));  return 0;  
}
  • 运行结果:

sizeof 被用来计算变量 a 和 b 的大小,分别是 int 类型和 char 类型。注意,sizeof(a) 和 sizeof(int) 返回的是相同的结果。

示例3:指针 

#include <stdio.h>  int main() {  int *ptr = NULL;  printf("Size of pointer: %zu bytes\n", sizeof(ptr));  // 注意:sizeof(*ptr) 将返回 ptr 所指向的 int 类型的大小  printf("Size of type pointed to by ptr: %zu bytes\n", sizeof(*ptr));  return 0;  
}
  • 运行结果: 

 

sizeof(ptr) 返回的是指针 ptr 本身所占的内存大小,而 sizeof(*ptr) 返回的是 ptr 所指向的 int 类型的大小。

示例4:结构体 

#include <stdio.h>  struct MyStruct {  int a;  char b;  double c;  
};  int main() {  struct MyStruct s;  printf("Size of struct MyStruct: %zu bytes\n", sizeof(struct MyStruct));  printf("Size of variable s of type struct MyStruct: %zu bytes\n", sizeof(s));  return 0;  
}
  • 运行结果:  

sizeof 被用来计算结构体 MyStruct 的大小。注意,结构体的大小可能会因为内存对齐(padding)而大于其成员大小的总和。

二、const

const 关键字在C/C++等编程语言中用于定义常量,即其值在初始化后不能被修改的变量。使用 const 可以提高代码的可读性和安全性,因为它明确了哪些变量是不应该被修改的。

2.1. 作用

1. 定义常量const 修饰的变量必须在声明时初始化,之后其值就不能被改变了。

2. 类型安全:通过 const,编译器可以在编译时检查对常量的非法修改,从而提高代码的类型安全性。

3. 作用域const 常量的作用域取决于其声明位置。在函数内部声明的 const 常量具有局部作用域,而在文件范围或全局范围内声明的 const 常量则具有相应的全局作用域。

4. 指针与 const

  • const 指针:指向常量的指针,不能通过该指针修改所指向的值。
  • 指向 const 的指针:指针本身是常量,不能改变其指向的地址,但可以修改所指向的值(如果所指向的不是 const)。
  • 指向 const 的 const 指针:既不能改变指针的指向,也不能通过指针修改所指向的值。

5. 与 #define 的区别const 定义的常量有类型,可以进行类型检查;而 #define 定义的常量是简单的文本替换,没有类型信息。

2.2. 代码示例

示例1:基本常量

#include <stdio.h>  int main() {  const int MAX_VALUE = 100; // 定义常量 MAX_VALUE  printf("MAX_VALUE: %d\n", MAX_VALUE);  // MAX_VALUE = 200; // 这将导致编译错误,因为 MAX_VALUE 是常量  return 0;  
}

运行结果:  

 

示例2:const 指针

#include <stdio.h>  int main() {  const int a = 5;  int b = 10;  const int *ptr1 = &a; // ptr1 指向常量 a,不能通过 ptr1 修改 a 的值  int *ptr2 = &b;       // ptr2 指向变量 b,可以通过 ptr2 修改 b 的值  // *ptr1 = 20;        // 这将导致编译错误,因为 ptr1 指向的是常量  *ptr2 = 20;           // 这将修改 b 的值为 20  printf("a: %d, b: %d\n", a, b);  return 0;  
}

运行结果: 

示例3:指向 const 的指针

#include <stdio.h>  int main() {  int a = 5;  const int *ptr = &a; // ptr 指向变量 a,但 ptr 被声明为指向 const,因此不能通过 ptr 修改 a 的值  // ptr = &b;         // 假设 int b; 已声明,这将是合法的,但前提是 ptr 没有被声明为指向 const 的 const 指针  // *ptr = 10;        // 这将导致编译错误,因为 ptr 指向的值被视为常量  printf("a: %d\n", a);  return 0;  
}

运行结果:  

 

示例4:指向 const 的 const 指针

#include <stdio.h>  int main() {  const int a = 5;  const int *const ptr = &a; // ptr 是指向 const 的 const 指针,既不能改变 ptr 的指向,也不能通过 ptr 修改所指向的值  // ptr = &b;               // 这将导致编译错误,因为 ptr 是指向 const 的 const 指针  // *ptr = 10;             // 这也将导致编译错误,因为 ptr 指向的值被视为常量  printf("a: %d\n", a);  return 0;  
}

运行结果:   

通过 const 关键字,我们可以定义在程序执行期间其值不应改变的变量,从而提高代码的可读性和健壮性。

三、signed 和 unsigned 

在C/C++等编程语言中,signed 和 unsigned 关键字用于定义整数类型的符号性。signed 表示有符号数,可以表示正数、负数和零;而 unsigned 表示无符号数,只能表示非负数(即零和正数)。

3.1. 作用

1. 有符号数(signed)

  • 默认情况下,整数类型(如 intshortlong)都是有符号的。
  • 有符号数使用最高位作为符号位,0 表示正数,1 表示负数。
  • 有符号数的取值范围包括负数、零和正数。

2. 无符号数(unsigned)

  • 无符号数不使用符号位,因此可以表示更大的正数范围。
  • 无符号数的取值范围从0开始,一直到该类型能表示的最大正数。
  • 在声明变量时,可以使用 unsigned 关键字来指定无符号类型,如 unsigned intunsigned shortunsigned long 等。

3. 类型转换

  • 当有符号数和无符号数进行运算时,有符号数可能会被隐式转换为无符号数,可能会导致意外的结果。
  • 为了避免这种情况,应该显式地进行类型转换,确保运算的正确性。

4. 溢出

  • 当整数超出其类型的取值范围时,会发生溢出。
  • 对于有符号数,溢出可能导致结果变为负数或另一个正数。
  • 对于无符号数,溢出会导致结果从最大值回绕到0。

3.2. 代码示例

示例1:基本的有符号和无符号整数


#include <stdio.h>  int main() {  signed int a = -10;       // 有符号整数,值为-10  unsigned int b = 20;      // 无符号整数,值为20  printf("Signed int a: %d\n", a);  printf("Unsigned int b: %u\n", b);  // 有符号和无符号整数相加(注意可能的溢出和类型转换)  int sum_signed = a + b;   // 结果为10(有符号运算)  unsigned int sum_unsigned = a + b; // 结果取决于系统,但通常为一个大正数(无符号运算)  printf("Sum (signed): %d\n", sum_signed);  printf("Sum (unsigned): %u\n", sum_unsigned);  return 0;  
}

运行结果:

示例2:类型转换和溢出

#include <stdio.h>  
#include <limits.h>  int main() {  unsigned int u_max = UINT_MAX; // 无符号整数的最大值  int s_max = INT_MAX;           // 有符号整数的最大值  printf("Unsigned int max: %u\n", u_max);  printf("Signed int max: %d\n", s_max);  // 溢出示例  unsigned int u_overflow = u_max + 1; // 结果为0(无符号溢出)  int s_overflow = s_max + 1;          // 结果为INT_MIN(有符号溢出)  printf("Unsigned overflow: %u\n", u_overflow);  printf("Signed overflow: %d\n", s_overflow);  // 类型转换示例  unsigned int u = 10;  int s = -5;  // 当有符号数和无符号数进行运算时,有符号数可能会被隐式转换为无符号数  unsigned int result = u + s; // 结果可能不是预期的5,而是一个大正数  printf("Result of u + s (unsigned): %u\n", result);  // 为了避免这种情况,应该显式地进行类型转换  unsigned int result_correct = u + (unsigned int)s; // 仍然可能不是5(因为s是负数),但避免了隐式转换的陷阱  int result_signed = (int)u + s; // 正确的结果为5(因为先将u转换为有符号数,再进行运算)  printf("Corrected result (unsigned to signed): %u\n", result_correct);  printf("Corrected result (signed): %d\n", result_signed);  return 0;  
}

 运行结果:

在进行有符号和无符号整数的运算时,应该特别小心类型转换和溢出的问题,以避免意外的结果。在实际编程中,应该根据具体的需求选择合适的整数类型,并确保运算的正确性。

四、struct、union、enum

在C/C++等编程语言中,structunion 和 enum 是用于定义复合数据类型的关键字。它们允许程序员将多个不同类型的数据组合在一起,或者定义一组命名的整型常量。

4.1. struct(结构体)

struct 关键字用于定义结构体,它是一种用户自定义的数据类型,可以包含多个不同类型的数据成员。结构体通常用于表示具有多个属性的实体,如人、车等。

4.1.1. 作用

  • 结构体定义使用 struct 关键字,后跟结构体标签(可选)和大括号内的成员列表。
  • 结构体成员可以是任何有效的数据类型,包括基本数据类型、指针、数组、甚至其他结构体。
  • 结构体变量可以通过点运算符(.)访问其成员。
  • 结构体可以嵌套定义,即一个结构体成员可以是另一个结构体类型。

4.1.2. 代码示例

#include <stdio.h>  // 定义一个结构体类型 Person  
struct Person {  char name[50];  int age;  float height;  
};  int main() {  // 创建一个结构体变量  struct Person person1;  // 给结构体成员赋值  snprintf(person1.name, sizeof(person1.name), "Alice");  person1.age = 30;  person1.height = 5.5;  // 打印结构体成员的值  printf("Name: %s\n", person1.name);  printf("Age: %d\n", person1.age);  printf("Height: %.1f\n", person1.height);  return 0;  
}
  • 运行结果:

4.2. union(联合体)

union 关键字用于定义联合体,它是一种特殊的数据结构,允许在相同的内存位置存储不同的数据类型。联合体的大小等于其最大成员的大小,且所有成员共享同一块内存。

4.2.1. 作用

  • 联合体定义使用 union 关键字,后跟联合体标签(可选)和大括号内的成员列表。
  • 联合体成员可以是任何有效的数据类型。
  • 联合体变量通过点运算符(.)访问其成员,但一次只能存储一个成员的值,因为所有成员共享内存。
  • 联合体通常用于节省内存或实现多态。

4.2.2. 代码示例

#include <stdio.h>  // 定义一个联合体类型 Data  
union Data {  int i;  float f;  char str[20];  
};  int main() {  // 创建一个联合体变量  union Data data;  // 给联合体成员赋值(注意:同时只能有一个成员有效)  data.i = 100;  printf("Integer: %d\n", data.i);  data.f = 3.14;  printf("Float: %.2f\n", data.f);  snprintf(data.str, sizeof(data.str), "Hello");  printf("String: %s\n", data.str);  // 注意:同时访问多个成员可能会导致未定义行为  // 例如:printf("Integer after string: %d\n", data.i); // 未定义行为  return 0;  
}
  • 运行结果:

4.3. enum(枚举类型)

enum 关键字用于定义枚举类型,它是一种用户定义的类型,由一组命名的整型常量组成。枚举类型使得代码更加清晰易读,并限制了变量的取值范围。

4.3.1. 作用

  • 枚举定义使用 enum 关键字,后跟枚举标签(必须)和大括号内的枚举成员列表。
  • 枚举成员可以是任何有效的标识符,它们自动被赋予一个整型值,从0开始递增(除非显式指定)。
  • 枚举变量可以通过赋值或使用枚举成员来初始化。
  • 枚举类型通常用于表示一组相关的常量,如颜色、状态等。

4.3.2. 代码示例

#include <stdio.h>  // 定义一个枚举类型 Color  
enum Color {  RED,  GREEN,  BLUE,  YELLOW = 3, // 显式赋值  PURPLE    // 自动赋值为4(因为YELLOW=3,所以PURPLE=4)  
};  int main() {  // 创建一个枚举变量  enum Color favoriteColor = GREEN;  // 打印枚举变量的值(注意:打印的是整型值)  printf("Favorite color: %d\n", favoriteColor);  // 使用枚举成员进行比较  if (favoriteColor == RED) {  printf("You like red!\n");  } else if (favoriteColor == GREEN) {  printf("You like green!\n");  } else {  printf("You like some other color.\n");  }  return 0;  
}
  •  运行结果:

在上面的示例中,展示了如何使用 structunion 和 enum 来定义复合数据类型,并展示了如何初始化和使用这些类型的变量。这些特性使得C/C++等编程语言非常灵活和强大,能够处理各种复杂的数据结构和常量集合。

五、typedef

typedef 是 C/C++ 语言中的一个关键字,它允许程序员为现有的数据类型定义一个新的名称(别名)。这样做的好处是,它可以使代码更加清晰易读,特别是当处理复杂的数据类型(如结构体、联合体、指针等)时。

5.1. 作用

  • typedef 的基本语法是 typedef existing_type new_type_name;,其中 existing_type 是已经存在的数据类型,new_type_name 是想要定义的新名称。
  • 使用 typedef 定义的别名,就像使用任何基本数据类型一样,可以用于变量声明、函数参数、返回值类型等。
  • typedef 经常与结构体(struct)和联合体(union)一起使用,以简化对这些复合数据类型的引用。
  • 还可以为指针类型定义别名,这在处理函数指针和复杂数据结构时特别有用。

5.2. 代码示例

示例1:为结构体定义别名:

#include <stdio.h>  // 定义一个结构体类型  
struct Point {  int x;  int y;  
};  // 使用 typedef 为结构体类型定义别名  
typedef struct Point Point;  int main() {  // 使用别名创建结构体变量  Point p1;  // 给结构体成员赋值  p1.x = 10;  p1.y = 20;  // 打印结构体成员的值  printf("Point p1: (%d, %d)\n", p1.x, p1.y);  return 0;  
}
  • 运行结果:

typedef struct Point Point; 实际上有点冗余,因为当 struct 标签(Point)和 typedef 定义的别名相同时,可以直接在 typedef 中定义结构体,如下所示:

typedef struct {  int x;  int y;  
} Point;

 示例2:为指针类型定义别名:

#include <stdio.h>  // 定义一个函数类型  
typedef int (*FuncPtr)(int, int);  // 定义一个函数,该函数符合 FuncPtr 类型的签名  
int add(int a, int b) {  return a + b;  
}  int main() {  // 使用别名创建函数指针变量  FuncPtr fp = add;  // 通过函数指针调用函数  int result = fp(3, 4);  // 打印结果  printf("Result: %d\n", result);  return 0;  
}
  • 运行结果:

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

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

相关文章

如何确认Linux嵌入式系统的触摸屏对应的是哪个设备文件?如何查看系统中所有的输入设备?输入设备的设备文件有什么特点?

Linux嵌入式系统的输入设备的设备文件有什么特点&#xff1f; 在 Linux 中&#xff0c;所有的输入设备&#xff08;如键盘、鼠标、触摸屏等&#xff09;都会被内核识别为 输入事件设备&#xff0c;并在 /dev/input/ 目录下创建相应的 设备文件&#xff0c;通常是&#xff1a; …

ESP32-c3实现获取土壤湿度(ADC模拟量)

1硬件实物图 2引脚定义 3使用说明 4实例代码 // 定义土壤湿度传感器连接的模拟输入引脚 const int soilMoisturePin 2; // 假设连接到GPIO2void setup() {// 初始化串口通信Serial.begin(115200); }void loop() {// 读取土壤湿度传感器的模拟值int sensorValue analogRead…

Hive:窗口函数(1)

窗口函数 窗口函数OVER()用于定义一个窗口&#xff0c;该窗口指定了函数应用的数据范围 对窗口数据进行分区 partition by 必须和over () 一起使用, distribute by经常和sort by 一起使用,可以不和over() 一起使用.DISTRIBUTE BY决定了数据如何分布到不同的Reducer上&#xf…

【react-redux】react-redux中的 useDispatch和useSelector的使用与原理解析

一、useSelector 首先&#xff0c;useSelector的作用是获取redux store中的数据。 下面就是源码&#xff0c;感觉它的定义就是首先是createSelectorHook这个方法先获得到redux的上下文对象。 然后从上下文对象中获取store数据。然后从store中得到选择的数据。 2、useDispatc…

java异常处理——try catch finally

单个异常处理 1.当try里的代码发生了catch里指定类型的异常之后&#xff0c;才会执行catch里的代码&#xff0c;程序正常执行到结尾 2.如果try里的代码发生了非catch指定类型的异常&#xff0c;则会强制停止程序&#xff0c;报错 3.finally修饰的代码一定会执行&#xff0c;除…

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…

The Simulation技术浅析(三):数值方法

The Simulation ,通常涉及使用数值方法对物理、工程或金融等领域的问题进行建模和求解。数值方法是解决复杂数学问题的关键技术,常见的数值方法包括 有限差分法(FDM)、有限元法(FEM) 和 蒙特卡洛方法(Monte Carlo Method)。 1. 有限差分法(FDM) 有限差分法是一种用于…

深度学习-98-大语言模型LLM之基于langchain的代理create_react_agent工具

文章目录 1 Agent代理1.1 代理的分类1.2 ReAct和Structured chat2 代理应用ReAct2.1 创建工具2.1.1 嵌入模型2.1.2 创建检索器2.1.3 测试检索结果2.1.4 创建工具列表2.2 初始化大模型2.3 创建Agent2.4 运行Agent3 参考附录1 Agent代理 Agent代理的核心思想是使用语言模型来选择…

小试牛刀,AI技术实现高效地解析和转换多种文档格式

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据、人工智能领域创作者。目前从事python全栈、爬虫和人工智能等相关工作&#xff0c;主要擅长领域有&#xff1a;python…

WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果

WPF进阶 | WPF 动画特效揭秘&#xff1a;实现炫酷的界面交互效果 前言一、WPF 动画基础概念1.1 什么是 WPF 动画1.2 动画的基本类型1.3 动画的核心元素 二、线性动画详解2.1 DoubleAnimation 的使用2.2 ColorAnimation 实现颜色渐变 三、关键帧动画深入3.1 DoubleAnimationUsin…

自制虚拟机(C/C++)(三、做成标准GUI Windows软件,扩展指令集,直接支持img软盘)

开源地址:VMwork 要使终端不弹出&#xff0c; #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") 还要实现jmp near 0x01类似的 本次的main.cpp #include <graphics.h> #include <conio.h> #include <windows.h> #includ…

tomcat核心组件及原理概述

目录 1. tomcat概述 1.1 概念 1.2 官网地址 2. 基本使用 2.1下载 3. 整体架构 3.1 核心组件 3.2 从web.xml配置和模块对应角度 3.3 如何处理请求 4. 配置JVM参数 5. 附录 1. tomcat概述 1.1 概念 什么是tomcat Tomcat是一个开源、免费、轻量级的Web服务器。 Tomca…

docker gitlab arm64 版本安装部署

前言&#xff1a; 使用RK3588 部署gitlab 平台作为个人或小型团队办公代码版本使用 1. docker 安装 sudo apt install docker* 2. 获取arm版本的gitlab GitHub - zengxs/gitlab-arm64: GitLab docker image (CE & EE) for arm64 git clone https://github.com/zengxs…

LabVIEW在电机自动化生产线中的实时数据采集与生产过程监控

在电机自动化生产线中&#xff0c;实时数据采集与生产过程监控是确保生产效率和产品质量的重要环节。LabVIEW作为一种强大的图形化编程平台&#xff0c;可以有效实现数据采集、实时监控和自动化控制。详细探讨如何利用LabVIEW实现这一目标&#xff0c;包括硬件选择、软件架构设…

python算法和数据结构刷题[1]:数组、矩阵、字符串

一画图二伪代码三写代码 LeetCode必刷100题&#xff1a;一份来自面试官的算法地图&#xff08;题解持续更新中&#xff09;-CSDN博客 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 面试经典 150 题 - 学习计…

【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙

目录 1. 梯度基本计算 2. 控制梯度计算 3. 梯度计算注意 4. 小节 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活…

C++基础day1

前言&#xff1a;谢谢阿秀&#xff0c;指路阿秀的学习笔记 一、基础语法 1.构造和析构: 类的构造函数是一种特殊的函数&#xff0c;在创建一个新的对象时调用。类的析构函数也是一种特殊的函数&#xff0c;在删除所创建的对象时调用。 构造顺序&#xff1a;父类->子类 析…

深入理解linux中的文件(上)

1.前置知识&#xff1a; &#xff08;1&#xff09;文章 内容 属性 &#xff08;2&#xff09;访问文件之前&#xff0c;都必须打开它&#xff08;打开文件&#xff0c;等价于把文件加载到内存中&#xff09; 如果不打开文件&#xff0c;文件就在磁盘中 &#xff08;3&am…

Spring Boot Web项目全解析:从前端请求到后端处理

第一章&#xff1a;对静态资源的整合 ConfigurationProperties(prefix"spring.resources", ignoreUnknownFieldsfalse)public class ResourceProperties implements ResourceLoaderAware {//可以设置和静态资源有关的参数&#xff0c;缓存时间等WebMvcAuotConfigura…

Java创建对象有几种方式?

大家好&#xff0c;我是锋哥。今天分享关于【Java创建对象有几种方式?】面试题。希望对大家有帮助&#xff1b; Java创建对象有几种方式? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Java 中&#xff0c;创建对象有几种常见的方式&#xff0c;具体如下&…