C语言结构体,枚举,联合

系列文章目录

第一章 C语言基础知识

第二章 C语言控制语句

第三章 C语言函数详解

第四章 C语言数组详解

第五章 C语言操作符详解

第六章 C语言指针详解

第七章 C语言结构体详解

第八章 详解数据在内存中的存储

第九章 C语言指针进阶


文章目录

1. 结构体

1.1 声明结构体

2.2 自引用结构

1. 单链表

2. 双链表

3. 二叉树

2.3 结构体变量的定义和初始化

2.4 结构体内存对齐

2.5 修改默认对齐数

2.6 结构体传参

1. 通过值传递结构体

2. 通过指针传递结构体

2. 位段

2.1 定义位段

2.2 位段的内存分配

3. 枚举

3.1 枚举类型的定义

3.2 使用枚举

4. 联合

4.1 联合类型的定义

4.2 使用联合

4.3 联合大小的计算


1. 结构体

1.1 声明结构体

struct Tag {
    type member1;
    type member2;
    ...
    type memberN;
};
  • struct:关键字,用于定义结构体。
  • Tag:结构体的标签(可选),可以用来声明该类型的变量。
  • member1, member2, ..., memberN:结构体成员,可以是任意数据类型,包括整型、浮点型、字符型、数组、甚至其他结构体。

代码示例:定义一个表示人的结构体:

struct Person {
    char name[50];
    int age;
    float height;
};

2.2 自引用结构

自引用结构是指在结构体定义中包含至少一个指向同类型结构体的指针。这个指针可以用来指向具有相同结构的其他实例,从而形成一个链式或树形结构。

示例:定义自引用结构体

链表结构,其中每个节点包含一个整数数据和指向列表中下一个节点的指针。

struct Node {
    int data;       // 存储的数据
    struct Node *next;  // 指向下一个节点的指针
};
1. 单链表

在单链表中,每个节点包含数据和一个指向下一个节点的指针。这种结构可以用来实现队列、栈或其他动态数据集合。

void printList(struct Node *node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
}
2. 双链表

在双链表中,每个节点除了有指向下一个节点的指针外,还有一个指向前一个节点的指针,允许在两个方向上遍历列表。

struct DNode {
    int data;
    struct DNode *prev;
    struct DNode *next;
};
3. 二叉树

在二叉树的实现中,每个节点包含数据和两个指向子节点的指针(左子节点和右子节点)。这种结构用于实现高效的搜索、插入和删除操作。

struct TreeNode {
    int value;
    struct TreeNode *left;
    struct TreeNode *right;
};

2.3 结构体变量的定义和初始化

定义结构体类型

struct Person {
    char name[100];
    int age;
    float height;
};

定义结构体变量

struct Person person1;
//定义了一个名为 person1 的变量,其类型为 struct Person

初始化结构体变量

struct Person person1 = {"TENET", 20, 2};

初始化结构体数组

结构体数组可以在定义时初始化

struct Person team[2] = {
    {"TENET", 20, 2},
    {"VENOM", 21, 2.1}
};

动态初始化

结构体的初始化也可以在程序执行中进行,尤其是当结构体的值需要在运行时确定时.

struct Person person3;
strcpy(person3.name, "TENET");  // 使用 strcpy 来复制字符串
person3.age = 20;
person3.height = 2.1;

完整代码示例:

#include <stdio.h>

// 定义一个名为 Point 的结构体,包含两个整数成员:x 和 y
struct Point
{
    int x; // x坐标
    int y; // y坐标
} p1; // 在定义类型的同时,声明了一个 Point 类型的变量 p1

// 单独声明一个 Point 类型的变量 p2
struct Point p2;

// 初始化:定义变量的同时赋初值
struct Point p3 = {1, 2}; // 使用列表初始化的方式初始化 p3,将 x 设置为 1,y 设置为 2

// 定义一个名为 Stu 的结构体,包含一个字符数组和一个整数
struct Stu // 类型声明
{
    char name[15]; // 存储名字的字符数组
    int age;       // 存储年龄的整型
} s = {"zhangsan", 20}; // 定义并初始化 Stu 类型的变量 s

// 定义一个名为 Node 的结构体,该结构体嵌套了 Point 结构体并包含一个指向自己类型的指针
struct Node
{
    int data; // 存储一个整数数据
    struct Point p; // 嵌套一个 Point 结构体
    struct Node* next; // 指向下一个 Node 结构体的指针
} n1 = {10, {4,5}, NULL}, // 初始化 n1,设置 data 为 10, p 的 x 和 y 分别为 4 和 5,next 为 NULL
  n2 = {20, {5, 6}, NULL}; // 同样初始化 n2,数据设置类似但不同于 n1

int main() {
    // 打印 n1 和 n2 的内容以验证初始化是否成功
    printf("n1 data: %d, point: (%d, %d)\n", n1.data, n1.p.x, n1.p.y);
    printf("n2 data: %d, point: (%d, %d)\n", n2.data, n2.p.x, n2.p.y);

    return 0;
}

2.4 结构体内存对齐

为什么需要内存对齐

内存对齐的主要目的是为了优化数据访问速度。大多数硬件平台对特定类型的数据访问有最佳的自然边界。例如,某些处理器访问一个整型数(通常是4字节)更有效率,如果它位于一个4字节的边界上。如果数据没有对齐,处理器可能需要多次访问内存来读取或写入单个数据项,这会降低程序的性能。

结构体对齐的规则

每个结构体成员相对于结构体起始的偏移量应该是该成员大小的整数倍。例如,如果一个成员是4字节整数,则其偏移量应该是4的倍数。

结构体的总大小也应该是其最宽基本类型成员大小的整数倍。如果不是,编译器会在结构体的末尾添加填充字节(padding),使其总大小符合这一规则。总的来说,就是让占用空间小的成员尽量集中在一起。

结构体示例:

struct Example {
    char a;    // 1 字节
    int b;     // 4 字节
    char c;    // 1 字节
};

内存布局是:

  • char a 直接放在起始位置。
  • 为了确保 int b 对齐到4字节边界,编译器在 char a 后面添加3字节的填充。
  • int b 放在第4字节位置。
  • char c 放在 int b 后面,紧接着是额外的填充字节,以确保整个结构体的大小是4的倍数(如果需要的话)。

练习:

struct S1
{
    char c1; // 占用 1 字节
    int i;   // 占用 4 字节,但因为对齐需求,c1 后面会有 3 字节的填充
    char c2; // 占用 1 字节
};
printf("%d\n", sizeof(struct S1)); // 输出结构体大小
  • 内存对齐:int 类型通常需要按 4 字节对齐。因此,char c1 后会有 3 字节的填充,以使 int i 在 4 字节边界上对齐。
  • 总大小:1字节 (c1) + 3字节 (填充) + 4字节 (i) + 1字节 (c2) = 9字节。但整个结构体也可能要对齐到 4 字节边界,因此实际大小可能为 12 字节(取决于具体的编译器和平台设置)。
struct S2
{
    char c1; // 占用 1 字节
    char c2; // 紧接着 c1,占用 1 字节
    int i;   // 需要对齐到 4 字节边界,因此 c2 后有 2 字节填充
};
printf("%d\n", sizeof(struct S2)); // 输出结构体大小
  • 内存对齐:为了让 int i 对齐到 4 字节边界,char c2 后需要填充 2 个字节。
  • 总大小:1字节 (c1) + 1字节 (c2) + 2字节 (填充) + 4字节 (i) = 8字节。
struct S3
{
    double d; // 占用 8 字节
    char c;   // 占用 1 字节,后面需要 7 字节填充以对齐 `int`
    int i;    // 占用 4 字节,需要对齐到 4 字节边界
};
printf("%d\n", sizeof(struct S3)); // 输出结构体大小
  • 内存对齐:double 类型通常需要按 8 字节对齐。为了让 int i 对齐到 4 字节边界,char c 后需要 7 字节的填充。
  • 总大小:8字节 (d) + 1字节 (c) + 7字节 (填充) + 4字节 (i) = 20字节。
struct S4
{
    char c1;   // 占用 1 字节
    struct S3 s3; // 嵌套结构体 S3,前面有 7 字节填充
    double d;  // 占用 8 字节,按 8 字节对齐
};
printf("%d\n", sizeof(struct S4)); // 输出结构体大小
  • 内存对齐:struct S3 已经分析为需要 20 字节,且需要按 8 字节对齐。char c1 后需要填充 7 字节,以确保 struct S3 s3 正确对齐。
  • 总大小:1字节 (c1) + 7字节 (填充) + 20字节 (s3, 嵌套结构体的大小) + 8字节 (d) = 36字节。

2.5 修改默认对齐数

#pragma 这个预处理指令,可以改变默认对齐数。

#include <stdio.h>

#pragma pack(8) // 设置默认对齐数为 8
struct S1
{
    char c1; // 1 字节
    int i;   // 4 字节,但由于对齐设置为 8,c1 后将填充 7 字节,使 i 对齐到 8 字节边界
    char c2; // 1 字节,由于对齐设置,c2 后可能填充至 8 字节边界
};
#pragma pack() // 取消设置的默认对齐数,还原为默认

#pragma pack(1) // 设置默认对齐数为 1
struct S2
{
    char c1; // 1 字节
    int i;   // 4 字节,紧接 c1,无需添加填充
    char c2; // 1 字节,紧接 i
};
#pragma pack() // 取消设置的默认对齐数,还原为默认

int main()
{
    // 输出结构体的大小
    printf("%d\n", sizeof(struct S1)); // 根据对齐规则和成员定义,预期的大小
    printf("%d\n", sizeof(struct S2)); // 根据对齐规则和成员定义,预期的大小
    return 0;
}

对于 struct S1,其对齐设置为 8 字节:

  • char c1 占用 1 字节,后面紧跟 7 字节填充,使得 int i 对齐到下一个 8 字节边界。
  • int i 占用 4 字节。
  • char c2 占用 1 字节,可能跟随 7 字节的填充,以确保整个结构体的大小为最大成员对齐(8 字节的倍数)。
  • sizeof(struct S1) 通常为 16 字节(1 字节 c1 + 7 字节填充 + 4 字节 i + 1 字节 c2 + 3 字节填充以达到8的倍数)。

对于 struct S2,其对齐设置为 1 字节:

  • char c1 占用 1 字节。
  • int i 紧接 c1,占用 4 字节,不需要填充因为对齐要求已经是 1 字节。
  • char c2 紧接 i,占用 1 字节。
  • 因此,sizeof(struct S2) 为 6 字节(1 字节 c1 + 4 字节 i + 1 字节 c2)。

2.6 结构体传参

1. 通过值传递结构体

当结构体通过值传递给函数时,实际上是传递结构体的一个副本。这意味着函数内部对结构体成员的任何修改都不会影响原始结构体。

代码示例

#include <stdio.h>

struct Point {
    int x, y;
};

// 函数接收结构体副本
void movePoint(struct Point p) {
    p.x += 1;
    p.y += 1;
    printf("Inside function: x = %d, y = %d\n", p.x, p.y);
}

int main() {
    struct Point pt = {10, 20};
    movePoint(pt);  // 传递副本
    printf("Outside function: x = %d, y = %d\n", pt.x, pt.y);  // 原始数据未改变
    return 0;
}

2. 通过指针传递结构体

当结构体通过指针传递给函数时,传递的是结构体的地址,允许函数直接访问并修改原始结构体的数据。

代码示例:

#include <stdio.h>

struct Point {
    int x, y;
};

// 函数接收结构体指针
void movePoint(struct Point *p) {
    p->x += 1;
    p->y += 1;
    printf("Inside function: x = %d, y = %d\n", p->x, p->y);
}

int main() {
    struct Point pt = {10, 20};
    movePoint(&pt);  // 传递指针
    printf("Outside function: x = %d, y = %d\n", pt.x, pt.y);  // 数据已被修改
    return 0;
}

2. 位段

位段(Bit-fields)是一种数据结构,用于访问结构体中的对象的指定数目的位。

位段的声明和结构是类似的,但有两个不同:
1.位段的成员必须是 int、unsigned int 或signed int 。
2.位段的成员名后边有一个冒号和一个数字。

2.1 定义位段

位段在结构体中定义,每个位段成员后面需要指定它所占用的位数。位段的声明通常涉及一个整数类型(如 int、unsigned int 或 signed int),后面紧跟冒号和位数。

struct TEST {
    unsigned int a : 1;  // 占用 1 位
    unsigned int d : 5;  // 填充 5 位
};
// TEST是一个位段类型

2.2 位段的内存分配

位段是连续存储的,并尽可能紧凑地放在一起,但它们的布局和总占用空间大小依赖于特定的编译器实现和对齐规则。

代码示例:

struct S
{
    char a:3;  // 定义一个位段 a,占用 3 位
    char b:4;  // 定义一个位段 b,占用 4 位
    char c:5;  // 定义一个位段 c,占用 5 位
    char d:4;  // 定义一个位段 d,占用 4 位
};
struct S s = {0};  // 使用列表初始化将所有位段初始化为 0
s.a = 10;  // 给位段 a 赋值为 10
s.b = 12;  // 给位段 b 赋值为 12
s.c = 3;   // 给位段 c 赋值为 3
s.d = 4;   // 给位段 d 赋值为 4
  • 位段定义:a, b, c, 和 d 分别占用 3, 4, 5, 和 4 位。尽管它们被定义为 char 类型,这仅仅意味着这些位段是从一个 char 类型的存储单元中分配的,实际上它们占用的是指定的位数。
  • 初始化:初始化时,所有位段被设为 0。这是通过 {0} 完成的,确保结构体开始时所有位都是清零的。
  • 赋值:之后,为每个位段赋予了一个新值。注意赋值时要考虑位段的溢出。例如,a:3 表示 a 可以存储的最大值是 23−1=723−1=7(因为是无符号值)。因此,赋值 10 实际存储的是 10 % 8 = 2。

3. 枚举

3.1 枚举类型的定义

枚举就是把可能的取值一一列举,枚举通过关键字 enum 定义。枚举的定义会创建一个新的数据类型名称,可以列举出所有可能的枚举值。每个枚举值都是一个整数(通常是 int 类型),默认从 0 开始,每个后续的值递增 1。你也可以显式指定枚举值的数值。
enum enum_name {
    constant1,
    constant2,
    constant3,
    ...
};

示例:定义一个枚举

enum Day {
    Sunday,    // 默认为 0
    Monday,    // 默认为 1
    Tuesday,   // 默认为 2
    Wednesday, // 默认为 3
    Thursday,  // 默认为 4
    Friday,    // 默认为 5
    Saturday   // 默认为 6
};

也可以指定特定的数值:

enum Day {
    Sunday = 1,
    Monday,
    Tuesday = 5,
    Wednesday,
    Thursday = 10,
    Friday,
    Saturday
};

在这个例子中,Monday 将自动被赋值为 2(因为它紧跟在值为 1 的 Sunday 后面),Wednesday 为 6(紧跟在值为 5 的 Tuesday 后面),Friday 为 11(紧跟在值为 10 的 Thursday 后面)。

3.2 使用枚举

枚举类型可以用来声明变量。这些变量可以存储任何在枚举中定义的值:

enum Day today;
today = Monday;

if (today == Monday) {
    printf("Start of work week.\n");
}

枚举与整数的关系

枚举在 C 语言中本质上是整数。你可以在不进行显式类型转换的情况下,将枚举值赋给整数变量:

int day = today;        
enum Day tomorrow = 3;  // 隐含星期四,如果从星期日开始 = 0

4. 联合

4.1 联合类型的定义

联合(共用体)是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。联合可以包含多个不同类型的成员,但任何时候只能存储其中一个成员的值。

联合通过关键字 union 定义,与结构体定义相似。联合体的定义创建了一个可以存储多个不同类型数据,但每次只能使用其中一个的数据类型。

union UnionName {
    type1 member1;
    type2 member2;
    type3 member3;
    ...
};

代码示例:

定义一个联合,这个联合可以用来存储整数、浮点数和字符指针。不管哪种类型的数据被存储,它们都使用同一块内存区域。

union Data {
    int i;
    float f;
    char *str;
};

4.2 使用联合

联合的使用类似于结构体,但需要记住的关键是联合存储的是同一块内存区域。因此,更改一个成员的值将影响到其他成员。

#include <stdio.h>

// 定义一个联合 Data,可以存储一个整数、一个浮点数或一个字符指针
union Data {
    int i;    // 可存储整数
    float f;  // 可存储浮点数
    char *str; // 可存储字符指针
};

int main() {
    union Data data;  // 声明一个 Data 类型的联合变量

    data.i = 10;  // 将整数 10 存储在联合的内存中
    printf("data.i : %d\n", data.i);  // 打印整数字段,输出 "data.i : 10"

    data.f = 220.5;  // 将浮点数 220.5 存储在同一块内存中,这会覆盖之前存储的整数
    printf("data.f : %.1f\n", data.f);  // 打印浮点数字段,输出 "data.f : 220.5"
    printf("data.i (corrupted) : %d\n", data.i);  // 再次打印整数字段,但由于内存已被浮点数覆盖,输出的值是未定义的(corrupted)

    data.str = "Hello World";  // 将字符串 "Hello World" 的指针存储在同一块内存中,这会覆盖之前存储的浮点数
    printf("data.str : %s\n", data.str);  // 打印字符串字段,输出 "data.str : Hello World"
    printf("data.f (corrupted) : %.1f\n", data.f);  // 再次打印浮点数字段,但由于内存已被字符串指针覆盖,输出的值也是未定义的(corrupted)

    return 0;
}

联合 Data 允许其成员 i、f 和 str 共享同一内存区域。该内存区域的大小等于其最大成员的大小,这里是 float 或 char*(具体取决于平台,通常这两种类型在现代架构上大小相同,都是 4 或 8 字节)。

当联合的一个成员被赋值时,它会覆盖联合内存中的当前内容。如果随后访问同一联合的另一个成员,得到的将是一个不确定的值,这是因为存储的位模式对于其他类型可能没有意义。这在程序中体现为给 data.f 赋值后访问 data.i,以及给 data.str 赋值后访问 data.f。

4.3 联合大小的计算

联合体的大小取决于其最大成员的大小,因为所有成员共用同一块内存空间。

union Un1 {
    char c[5]; // char 类型数组,占用 5 字节
    int i;     // int 类型,大小通常为 4 字节
};
union Un2 {
    short c[7]; // short 类型数组,每个 short 占用 2 字节,总共占用 14 字节
    int i;      // int 类型,大小通常为 4 字节
};
  • Un1 的大小将是其最大成员的大小,即 char 数组 c 的大小(5 字节)。不过,由于 int 类型可能需要按照特定的边界对齐(比如 4 字节对齐),联合体的实际大小可能需要向上取整到更大的对齐边界。具体的大小取决于编译器和平台,但如果 int 需要 4 字节对齐,Un1 的大小应该是 8 字节。
  • Un2 的大小将是其最大成员的大小,即 short 数组 c 的大小(14 字节)。和 Un1 一样,如果 int 需要 4 字节对齐,那么 Un2 的大小可能需要增加额外的填充,以满足对齐要求。然而,因为 14 已经是 2 的倍数(short 类型的自然对齐边界),Un2 不需要额外的填充就可以保证 int 成员对齐,所以 Un2 的大小应该是 14 字节。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

URL解析

目录 URIURLURL语法相对URLURL中的转义 现在与未来PURL 在 URL出现之前&#xff0c;人们如果想访问网络中的资源&#xff0c;就需要使用不同的 应用程序&#xff0c;如共享文件需要使用 FTP程序&#xff0c;想要发送邮件必须使用 邮件程序&#xff0c;想要看新闻那只能使用…

华为认证云计算前景如何

互联网/移动互联网经历了高速发展的二十年&#xff0c;我们有幸一起见证了华为、阿里、腾讯、百度、字节跳动、京东、滴滴、拼多多等互联网公司的崛起&#xff0c;让普通技术人实现逆袭拿到高薪&#xff0c;也让小镇做题家们有了阶层跨越的机会。 但机会都是留给有准备的人&…

2024年内外贸一体化融合发展(长沙)交易会

2024年内外贸一体化融合发展&#xff08;长沙&#xff09;交易会 一、总体思路 充分发挥湖南作为全国内外贸一体化试点地区作用&#xff0c;坚持“政府主导、市场驱动、企业为主”的原则&#xff0c;以“助力双循环&#xff0c;拓展新市场&#xff0c;促进新消费”为主题&…

AI预测体彩排列3第2套算法实战化测试第1弹2024年4月22日第1次测试

从今天开始&#xff0c;开始新一轮的测试&#xff0c;本轮测试&#xff0c;以6码为基础&#xff0c;同步测试杀号情况&#xff0c;争取杀至4-5码。经过计算&#xff0c;假如5码命中&#xff0c;即每期125注&#xff0c;投入250元&#xff0c;十期共计2500元&#xff0c;则命中率…

OpenFeign远程调用

一、OpenFeign替代RestTemplate 1、需要引入的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>4.1.1</version> </dependency> 在引入依…

YMP实现Oracle迁移到YashanDB

迁移需求 ip地址 数据库信息 操作系统信息 源库 192.168.3.132 实例名topdh 用户密码TOPICIS/oracle 端口1521 Centos7.9 x86_64 目标库 192.168.3.175 实例名yasdb 用户密码topicist/opicis 端口1688 Centos7.9 x86_64 迁移前准备 YMP工具获取 根据实际需求向厂…

ArrayList与顺序表(1)

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x…

GEE24:合肥市1986-2024年年均NDVI变化分析

代码如下&#xff1a; var roi ee.FeatureCollection("users/yipeizhao736/HefeiProvince"); Map.centerObject(roi); Map.addLayer(roi,{color:grey},roi); // Applies scaling factors. function applyScaleFactors(image) {var opticalBands image.select(SR_B…

如何使用渐变块创建自定义聊天机器人

如何使用渐变块创建自定义聊天机器人 文章目录 如何使用渐变块创建自定义聊天机器人一、介绍二、参考示例1、一个简单的聊天机器人演示2、将流式传输添加到您的聊天机器人3、喜欢/不喜欢聊天消息4、添加 Markdown、图像、音频或视频 一、介绍 **重要提示&#xff1a;**如果您刚…

FloodFill算法简介(用BFS、DFS算法解决)

FloodFill算法中文名&#xff1a;洪水灌溉 FloodFill通常是这样一类问题&#xff0c;如下图&#xff1a; 负数表示凹陷的土地&#xff0c;正数表示凸起的土地&#xff0c;发洪水/下雨会淹没凹陷的地方 通常会问这几种问题&#xff1a; 1.被淹没的区域有几块 2.被淹没的最大…

java的单元测试和反射

单元测试 就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试 Junit单元测试框架&#xff1a; 可以用来对方法进行测试 有点&#xff1a; 可以灵活的编写测试代码&#xff0c;可以针对某个方法进行测试&#xff0c;也支持一键完成对全部方法的自动发测试&a…

Linux中grep详解

一、grep基本介绍 全拼:Global search REgular expression and Print out the line. 从grep的全称中可以了解到&#xff0c;grep是一个可以利用”正则表达式”进行”全局搜索”的工具&#xff0c;grep会在文本文件中按照指定的正则进行全局搜索&#xff0c;并将搜索出的行打印出…

基于工程车辆/物流车辆/消防车辆远程通信的车队管理解决方案

交通运输对全球经济至关重要&#xff0c;特别是长途卡车在现今的供应链中发挥着重要作用。目前&#xff0c;货运物流面临许多挑战&#xff0c;包括不断上升的燃料价格和排放污染等问题。由于重型卡车的尺寸和载重量大&#xff0c;这意味着它们产生更多的二氧化碳排放足迹。在国…

java 溯本求源之基础(十八)之Monitoring--jmc

1.JMC概述 JMC全称Java Mission Control&#xff0c;集成了多个功能强大的组件&#xff0c;其中最核心的两部分是管理控制台和Java Flight Recorder。管理控制台允许开发者实时监控应用的运行状态&#xff0c;捕捉各种性能指标&#xff1b;而Java Flight Recorder则提供了一种高…

SQLite的DBSTAT 虚拟表(三十六)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite运行时可加载扩展(三十五&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 1. 概述 DBSTAT 虚拟表是一个只读的同名虚拟表&#xff0c;返回 有关用于存储内容的磁盘空间量的信息 的 SQLite 数据库。 示例用例…

陈奂仁联手 The Sandbox 推出“Hamsterz Doodles”人物化身系列

全新人物化身系列结合艺术与实用性 开创元宇宙新篇章 著名亚洲唱作歌手兼香港电影金像奖得主陈奂仁携手 The Sandbox&#xff0c;兴奋地宣布推出新的元宇宙人物化身系列 —— Hamsterz Doodles 仓鼠涂鸦。 陈奂仁在 The Sandbox 推出 Hamsterz Doodles 系列&#xff0c;将艺术与…

3i平台体验性能加持,13600KF+B760M+撼与科技A770 TITAN装机体验

在2022年&#xff0c;intel重启显卡线&#xff0c;带来了多款性价比十分不错的显卡。而近段时间&#xff0c;又有传言说intel第二代产品e即将面世&#xff0c;甚至已经有数款Battlemage GPU曝光&#xff0c;让不少intel忠实粉丝直呼期待&#xff0c;或许在今年年底&#xff0c;…

【新知实验室 - TRTC 实践】音视频互动 Demo、即时通信 IM 服务搭建

一、TRTC 初识 TRTC 是什么 TRTC&#xff08;Tencent RTC&#xff09;腾讯实时音视频&#xff0c;源自于 QQ 音视频团队&#xff0c;是基于 QQ 音视频多年来的音视频技术积累&#xff0c;位于腾讯云的 RTC 云服务。TRTC 支持腾讯会议、企业微信直播、微信视频号、腾讯云课堂、…

AI大模型探索之路-实战篇2:基于CVP架构-企业级知识库实战落地

目录 前言 一、概述 二、本地知识库需求分析 1. 知识库场景分析 2. 知识库应用特点 3. 知识库核心功能 三、本地知识库架构设计 1. RAG架构分析 2. 大模型方案选型 3. 应用技术架构选型 4. 向量数据库选型 5. 模型选型 三、本地知识库RAG评估 四、本地知识库代码落地 1. 文件…
最新文章