重生之我在异世界学编程之C语言:深入结构体篇(上)

news2025/1/11 8:04:49

大家好,这里是小编的博客频道
小编的博客:就爱学编程

很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!

本文目录

  • 引言
  • 正文
  • 《1》 结构体的两种声明
      • 一、结构体的定义
      • 二、全局结构体变量
      • 三、局部结构体变量
      • 四、匿名结构体与全局/局部变量
  • 《2》typedef对结构体类型进行重命名
      • 一、基本语法
      • 二、作用与优势
      • 三、示例说明
  • 《3》 结构体的初始化和访问
      • 1. **声明时初始化**
      • 2. **后续初始化**
      • 3.访问结构体成员
  • 《4》 结构体的内存对齐和修改默认对其数的方法
      • 一、结构体与内存对齐的基本概念
      • 二、结构体内存对齐的规则
      • 三、为什么存在内存对齐
      • 四、如何修改默认对齐数
        • 1.使用#pragma pack
        • 2.使用__attribute__((packed))
  • 《5》结构体传参
        • 一、通过值传递结构体
        • 二、通过指针传递结构体
        • 三、返回结构体
          • 3.1 返回结构体值
          • 3.2 返回结构体指针
  • 快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

引言

在C语言中,结构体(struct)是一种用户自定义的数据类型,它允许将多个不同类型的数据项组合成一个单一的类型。结构体是编程中组织相关数据的有效方式,尤其在处理复杂数据时显得尤为重要。以下是对C语言结构体基础知识的详细介绍,一起来看看吧!!

在这里插入图片描述


那接下来就让我们开始遨游在知识的海洋!

正文


在C语言中,当结构体被定义后,可以在全局作用域或局部作用域(如函数内部)中声明其变量。这些结构体变量的作用域和生命周期会根据它们是在全局还是局部声明的而有所不同。下面小编将详细解释全局变量、局部变量以及匿名声明与结构体之间的关系,特别是在主函数内的区别。

《1》 结构体的两种声明


一、结构体的定义

首先,我们需要定义一个结构体。例如:

struct MyStruct {
    int a;
    float b;
};

这里我们定义了一个名为MyStruct的结构体,它包含两个成员:一个整型a和一个浮点型b


二、全局结构体变量

如果在所有函数之外声明一个结构体变量,那么它就是全局的。全局结构体变量在整个程序的生命周期内都有效,并且可以被任何函数访问。例如:

// 全局作用域中声明结构体变量
struct MyStruct globalVar;

int main() {
    // 可以在main函数中访问globalVar
    globalVar.a = 10;
    globalVar.b = 3.14;
    // ... 其他代码
}

在这个例子中,globalVar是一个全局结构体变量,它在整个程序中都是可见的,包括在main函数内。


三、局部结构体变量

如果在某个函数内部声明一个结构体变量,那么它就是局部的。局部结构体变量只在声明它的函数内部有效,一旦函数执行完毕,该变量就会被销毁。例如:

int main() {
    // 局部作用域中声明结构体变量
    struct MyStruct localVar;
    localVar.a = 20;
    localVar.b = 6.28;
    // localVar只能在main函数内部使用
    // ... 其他代码
}

在这个例子中,localVar是一个局部结构体变量,它只能在main函数内部被访问和使用。


四、匿名结构体与全局/局部变量

在C语言中,还可以声明匿名结构体变量。匿名结构体是没有名称的结构体类型,通常用于只需要一个结构体实例的情况。匿名结构体变量的声明方式与全局或局部变量类似,只是没有给出结构体的名称。例如:

// 在全局作用域中声明匿名结构体变量
struct {
    int x;
    int y;
} globalAnonymousVar;

int main() {
    // 在局部作用域中声明另一个匿名结构体变量(注意:这是另一个不同的类型)
    struct {
        int m;
        int n;
    } localAnonymousVar;
    
    globalAnonymousVar.x = 1;
    globalAnonymousVar.y = 2;
    
    localAnonymousVar.m = 3;
    localAnonymousVar.n = 4;
    
    // 注意:globalAnonymousVar和localAnonymousVar是不同类型的变量
    // 因此不能相互赋值或比较
    // ... 其他代码
}

在这个例子中,globalAnonymousVarlocalAnonymousVar分别是全局和局部的匿名结构体变量。需要注意的是,由于它们是匿名的且定义不同,因此它们是两种完全不同的类型,不能相互赋值或比较。

  • 全局结构体变量在整个程序生命周期内有效,可以被任何函数访问。
  • 局部结构体变量只在声明它的函数内部有效,函数执行完毕后会被销毁。
  • 匿名结构体变量没有名称的结构体类型,通常用于单个实例的情况。全局和局部的匿名结构体变量是两种不同的类型。

希望以上内容能够帮助宝子们理解C语言中结构体与全局变量、局部变量以及匿名声明之间的关系。


typedef是C语言中的一个关键字,它主要用于为数据类型定义新的名称(别名),这包括基本数据类型、引用类型以及自定义的数据类型。在结构体(struct)的使用中,typedef的作用尤为显著,因为它可以简化结构体的声明和使用,提高代码的可读性和可维护性。以下是对typedef对结构体进行重命名的详细介绍.

《2》typedef对结构体类型进行重命名


一、基本语法

typedef的基本语法如下:

typedef 原有类型 新类型名;

当用于结构体时,可以这样写:

typedef struct {
    成员列表;
} 新类型名;

或者先定义结构体,再用typedef为其命名:

struct 旧类型名 {
    成员列表;
};
typedef struct 旧类型名 新类型名;

二、作用与优势

  1. 简化声明:使用typedef可以为复杂的结构体类型定义一个简短且易于理解的新名字,从而简化变量的声明。例如,对于包含多个成员的结构体,直接使用其原始类型声明变量可能会显得冗长,而使用typedef定义的新类型名则可以使声明更加简洁明了。
  1. 提高可读性:通过为结构体类型定义具有描述性的新名字,可以提高代码的可读性。这些新名字通常能够更直观地反映结构体的用途或内容,从而使代码更容易被理解和维护。
  1. 便于修改:如果需要在程序中更改结构体的定义,只需修改结构体本身的定义即可,而不必修改所有使用该结构体的变量声明。这是因为这些变量声明使用的是由typedef定义的新类型名,而不是结构体的原始类型名。因此,使用typedef可以降低因修改结构体定义而导致的代码修改量。

三、示例说明

以下是一个使用typedef对结构体进行重命名的示例:

#include <stdio.h>

// 使用typedef定义一个新的结构体类型Point3D
typedef struct {
    int x;
    int y;
    int z;
} Point3D;

int main() {
    // 使用新类型名Point3D声明变量p
    Point3D p = {1, 2, 3};
    
    // 打印变量p的成员值
    printf("x: %d, y: %d, z: %d
", p.x, p.y, p.z);
    
    return 0;
}

在这个示例中,我们首先使用typedef定义了一个新的结构体类型Point3D,该结构体包含三个整型成员xyz。然后,我们在main函数中使用新类型名Point3D声明了一个变量p,并初始化了它的成员值。最后,我们打印了变量p的成员值以验证其正确性。

注意:

  1. 在使用typedef对结构体进行重命名时,应确保新类型名的唯一性和描述性,以避免与其他类型名冲突并提高代码的可读性。
  1. 如果结构体中包含指向自身的指针成员(即自引用),则需要特别注意typedef的使用方式。在这种情况下,可以先定义结构体的匿名类型,然后使用typedef为该类型命名;或者在定义结构体的同时直接使用typedef为其命名,并在结构体内部使用struct关键字加上新类型名来声明指向自身的指针成员。

综上所述:

  • typedef是C语言中一个非常有用的关键字,它可以极大地简化结构体的声明和使用,提高代码的可读性和可维护性。

当然!在C语言中,结构体(struct)是一种用户自定义的数据类型,允许将不同类型的数据组合成一个单一的类型。链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。通过结构体,我们可以方便地实现链表。

下面是一篇关于如何使用C语言的结构体来实现链表的详细介绍。

《3》 结构体的初始化和访问


1. 声明时初始化

我们可以在声明结构体变量的同时对其进行初始化。这通常使用花括号{}来指定每个成员的初值。

struct Student student1 = {"Alice", 20, 95.5};

在这个例子中,我们创建了一个名为student1Student结构体变量,并在声明时将其成员初始化为"Alice"2095.5


2. 后续初始化

如果我们在声明时没有初始化结构体变量,那么可以在后续的代码中逐个设置其成员的值。

struct Student student2;
strcpy(student2.name, "Bob");  // 使用strcpy函数复制字符串到字符数组
student2.age = 22;
student2.grade = 88.0;

注意:

  • 对于字符数组类型的成员,我们不能直接赋值(如student2.name = "Bob";),因为这样会尝试将一个字符串常量的地址赋给字符数组,而不是将字符串内容复制到数组中。因此,我们使用strcpy函数来复制字符串。

3.访问结构体成员

一旦我们有了结构体变量,就可以通过点运算符.来访问其成员。以下是一些示例:

printf("Name: %s
", student1.name);
printf("Age: %d
", student1.age);
printf("Grade: %.2f
", student1.grade);

在这个例子中,我们使用点运算符.来访问student1的各个成员,并将它们打印到控制台上。


《4》 结构体的内存对齐和修改默认对其数的方法

以下是一篇关于结构体的内存对齐和修改默认对齐方法的详细介绍.


一、结构体与内存对齐的基本概念

在编程中,结构体(Structure)是一种可以存储不同类型数据项的复合数据类型。它是一种用户自定义的数据类型,用于封装一组相关联的不同类型的数据项。结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

内存对齐是指数据在内存中按照一定的规则进行排列,以提高内存访问的效率。对于结构体来说,内存对齐意味着其成员变量在内存中的地址需要满足特定的对齐要求。这种对齐通常是由编译器自动处理的,但程序员也可以通过特定指令进行修改。


二、结构体内存对齐的规则

  1. 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处。
  1. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。这个对齐数通常是编译器默认的一个对齐数与该成员大小的较小值。不同的编译器和平台可能有不同的默认对齐数。
  1. 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,取其中最大的一个)的整数倍。这是为了确保结构体在内存中的布局是紧凑且高效的。
  1. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。

三、为什么存在内存对齐

内存对齐的存在主要有以下几个原因:

  1. 提高内存访问效率:在许多计算机架构中,内存的访问速度是有限的。如果数据在内存中的位置是随机的,那么CPU需要花费额外的时间来寻找数据,这被称为内存访问延迟。然而,如果数据按照特定的对齐规则进行存储,CPU的内存控制器就可以更有效地预取数据,从而减少内存访问延迟。
  1. 提高硬件效率:许多现代CPU都有专门为对齐数据而设计的内部机制。例如,一些CPU具有专门的对齐引擎,可以更快地处理对齐的数据。如果数据没有对齐,CPU可能需要进行多次访问内存才能获取到完整的数据,这会降低CPU的效率。
  1. 减少数据依赖:在某些情况下,如果数据没有对齐,可能会导致一些特定的CPU指令无法使用,从而增加了数据的依赖性。这可能会使得程序的并行度降低,从而影响程序的性能。
  1. 提高程序的稳定性:在某些情况下,不对齐的内存访问可能会导致硬件异常或者程序崩溃。因此,编程时进行内存对齐不仅可以提高程序的性能,还可以提高程序的稳定性和可维护性。

四、如何修改默认对齐数

在C语言中,可以使用#pragma pack__attribute__((packed))来改变结构体的对齐方式以减少填充字节。以下是两种方法的示例:

1.使用#pragma pack
#include <stdio.h>
#include <stddef.h>

// 将对齐设置为1字节
#pragma pack(push, 1)
typedef struct {
    char c1;       // 1 byte
    int i;         // 4 bytes, but aligned to 1 byte boundary here
    char c2;       // 1 byte
} S1;
#pragma pack(pop)  // 恢复默认对齐设置

int main() {
    printf("%zu
", sizeof(S1));  // 输出结果为6,因为没有额外的填充字节
    return 0;
}

在这个例子中,使用了#pragma pack(push, 1)将当前的对齐设置保存在栈中,并设置新的对齐方式为1字节。这样,结构体S1的成员就会紧密排列在一起,没有额外的填充字节。使用完之后,通过#pragma pack(pop)恢复之前的对齐设置。

2.使用__attribute__((packed))

这种方法适用于GCC和一些兼容的编译器。它告诉编译器不要为结构体的成员进行任何额外的对齐填充。

#include <stdio.h>
#include <stddef.h>

typedef struct __attribute__((packed)) {
    char c1;       // 1 byte
    int i;         // 4 bytes, but packed tightly with no padding
    char c2;       // 1 byte
} S2;

int main() {
    printf("%zu
", sizeof(S2));  // 输出结果为6,同样没有额外的填充字节
    return 0;
}

需要注意的是:

  • 虽然这两种方法可以减少结构体的总大小,但它们可能会降低数据访问的效率。因为未对齐的数据访问可能需要更多的内存操作,这在某些平台上可能会有较大的性能影响。

结构体的内存对齐是提高内存访问效率和程序稳定性的重要手段。了解并掌握结构体内存对齐的规则和修改默认对齐数的方法对于优化程序性能和资源利用具有重要意义。在实际编程中,应根据具体需求和平台特性选择合适的对齐方式和策略。


《5》结构体传参

一、通过值传递结构体

最简单的方式是通过值传递结构体到函数中。这意味着函数会接收到结构体的一个副本,对副本的任何修改都不会影响原始结构体。

#include <stdio.h>
#include <string.h>

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

void printPerson(struct Person p) {
    printf("Name: %s
", p.name);
    printf("Age: %d
", p.age);
    printf("Height: %.2f
", p.height);
}

int main() {
    struct Person person1 = {"Alice", 30, 5.7};
    printPerson(person1); // 通过值传递
    return 0;
}

缺点

  • 如果结构体很大,通过值传递会导致大量的内存复制操作,从而降低程序效率。

二、通过指针传递结构体

更常见且高效的方法是通过指针传递结构体。这样,函数接收的是指向结构体的指针,可以直接访问和修改原始数据。

#include <stdio.h>
#include <string.h>

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

void printPerson(struct Person *p) {
    printf("Name: %s
", p->name);
    printf("Age: %d
", p->age);
    printf("Height: %.2f
", p->height);
}

void modifyPerson(struct Person *p) {
    strcpy(p->name, "Bob");
    p->age = 25;
    p->height = 6.0;
}

int main() {
    struct Person person1 = {"Alice", 30, 5.7};
    printPerson(&person1); // 通过指针传递
    modifyPerson(&person1); // 修改结构体内容
    printPerson(&person1); // 再次打印以查看修改结果
    return 0;
}

优点

  • 避免了大结构体的复制开销。
  • 可以直接修改原始结构体中的数据。

在某些情况下,你可能希望从函数中返回一个结构体。这同样可以通过值和指针两种方式来实现。

三、返回结构体
3.1 返回结构体值
#include <stdio.h>

struct Point {
    int x;
    int y;
};

struct Point createPoint(int x, int y) {
    struct Point p;
    p.x = x;
    p.y = y;
    return p;
}

int main() {
    struct Point p1 = createPoint(10, 20);
    printf("Point created: (%d, %d)
", p1.x, p1.y);
    return 0;
}

对于小型结构体,这种方式是可行的,但对于大型结构体,返回值可能会导致性能问题,因为涉及到结构体的复制。

3.2 返回结构体指针
#include <stdio.h>
#include <stdlib.h>

struct Point {
    int x;
    int y;
};

struct Point* createPoint(int x, int y) {
    struct Point *p = (struct Point*)malloc(sizeof(struct Point));
    if (p != NULL) {
        p->x = x;
        p->y = y;
    }
    return p;
}

int main() {
    struct Point *p1 = createPoint(10, 20);
    if (p1 != NULL) {
        printf("Point created: (%d, %d)
", p1->x, p1->y);
        free(p1); // 不要忘记释放动态分配的内存
    }
    return 0;
}

这种方法适用于大型结构体或需要在函数外部持续使用结构体的情况,但需要注意内存管理,确保在使用完毕后释放动态分配的内存。

  • 通过值传递:简单直观,但不适合大型结构体,因为会有较大的内存开销。
  • 通过指针传递:高效且灵活,可以直接修改原始数据,是推荐的方法。
  • 返回结构体:小型结构体可以通过值返回,大型结构体建议通过指针返回并注意内存管理。

理解并掌握这些结构体传参方式,将有助于宝子们编写更高效、灵活的C语言程序。


快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

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

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

相关文章

Diffusion中guidance_scale 的理解

guidance_scale 是一个控制生成图像引导程度的参数。它的含义和使用与论文 Imagen: Photorealistic Text-to-Image Diffusion Models with Composable Conditions 中的公式 (2) 的引导权重 类似。 1. Classifier-Free Guidance 的背景 Classifier-Free Guidance 是一种在扩散…

【kettle】mysql数据抽取至kafka/消费kafka数据存入mysql

目录 一、mysql数据抽取至kafka1、表输入2、json output3、kafka producer4、启动转换&#xff0c;查看是否可以消费 二、消费kafka数据存入mysql1、Kafka consumer2、Get records from stream3、字段选择4、JSON input5、表输出 一、mysql数据抽取至kafka 1、表输入 点击新建…

新书速览|循序渐进Node.js企业级开发实践

《循序渐进Node.js企业级开发实践》 1 本书内容 《循序渐进Node.js企业级开发实践》结合作者多年一线开发实践&#xff0c;系统地介绍了Node.js技术栈及其在企业级开发中的应用。全书共分5部分&#xff0c;第1部分基础知识&#xff08;第1&#xff5e;3章&#xff09;&#xf…

基于大模型的图像重命名工具ai-renamer

文章目录 基础使用语言问题命名风格 基础使用 ai-renamer是一款自动为图片重命名的工具&#xff0c;由于需要调用基于本地大模型&#xff0c;在使用之前需要用Ollama或者LM Studio配置好至少一个大模型&#xff0c;比如Llava, Gemma, Llamad等。如果想要为视频重命名&#xff…

element Cascader级联选择器 点文字即可选中,去掉radio按钮

需求 将示例的点击radio和点击文字功能结合在一起。可以选择任意一级的内容&#xff0c;直接点击文字即可选中&#xff0c;同时如果有下一级就展示&#xff0c;去掉radio标签。 实现方法 通过css将radio标签做成文字框一样大小并且透明覆盖在整个文字上方&#xff0c;点击文…

【已解决】黑马点评项目中启动Spring Boot服务失败,com.sun.tools.javac.tree.JCTree qualid

黑马点评项目中启动Spring Boot服务失败 报错提示 java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field com.sun.tools.javac.tree.JCTree qualid这是因为 lombok 版本不兼容造成的 找到 pom.xml 文件&#xff0…

C#,人工智能,深度学习,目标检测,OpenCV级联分类器数据集的制作与《层级分类器一键生成器》源代码

一、目标识别技术概述 1、摘要 目标检测是计算机视觉中最基本和最具挑战性的问题之一&#xff0c;它试图从自然图像中的大量预定义类别中定位目标实例。深度学习技术已成为直接从数据中学习特征表示的强大策略&#xff0c;并在通用目标检测领域取得了显著突破。鉴于这一快速发…

绿虫光伏设计系统:清洁能源的未来

煤炭、石油、天然气是我们现在依赖的重要能源&#xff0c;但这些能源难以再生&#xff0c;而且开采过程中会产生污染。太阳能发电作为清洁能源的一种重要形式&#xff0c;受到了越来越多的关注。绿虫光伏发电系统&#xff0c;不仅考虑到其发电效率&#xff0c;还可以考虑其经济…

2025澄迈漓岛音乐节品牌招商大会成功举行

——共谋音乐盛事&#xff0c;携手推动文化经济发展 12月6日&#xff0c;“2025澄迈漓岛音乐节品牌招商大会”&#xff08;以下简称“招商大会”&#xff09;在澄迈举行。本次大会由澄迈福山发展有限公司、福山咖啡文化风情镇旅游区联合主办&#xff0c;海南绿发投资有限公司承…

基于Java和Vue开发的漫画阅读软件漫画阅读小程序漫画APP

前景分析 受众广泛&#xff1a;漫画的受众群体广泛&#xff0c;不仅限于青少年&#xff0c;还涵盖了成年人等多个年龄层和社会阶层。漫画文化在全球范围内的影响力不断扩大&#xff0c;未来漫画软件创业可以考虑全球市场的拓展。 市场需求大&#xff1a;数字化阅读趋势下&…

Lua中实现HTTP请求的User-Agent自定义

User-Agent&#xff08;用户代理&#xff09;是HTTP请求头的一部分&#xff0c;用于描述发出请求的客户端的信息&#xff0c;包括浏览器类型、版本和操作系统等。自定义User-Agent对于开发者来说是一个重要的功能&#xff0c;它可以帮助服务器识别请求来源&#xff0c;也可以模…

dell电脑开不了机怎么回事?戴尔电脑无法开机解决方法

dell戴尔电脑开不了机&#xff0c;这是很多使用dell电脑用户常遇到的问题。这种故障情况是由多种原因引起&#xff0c;包括硬件故障、软件问题或电源问题等等。dell电脑开不了机怎么办呢&#xff1f;下面便为大家介绍一下相关解决修复方法&#xff0c;帮助用户解决戴尔电脑无法…

148. 排序链表(java) 标记一下

我的思路是插入排序&#xff0c;然而时间超出限制&#xff01;&#xff01;&#xff01; 时间复杂度是 O(nlogn) 的排序算法包括归并排序、堆排序和快速排序&#xff08;快速排序的最差时间复杂度是 O(n 2)&#xff09;&#xff0c;最适合链表的排序算法是归并排序。 题目描述…

C语言实验 二维数组

时间:2024.12.6 一、实验 7-1 矩阵运算 代码 #include<stdio.h> int main(){int a[20][20]={0};int n,i,j;int sum=0;scanf("%d",&n);for(i=0;i<n;i++){for(j=0;j<n;j++){scanf("%d",&a[i][j]);if((i!=n-1)&&(j!=n-1)&am…

物通博联,smart200配置

设备&#xff1a;物通博联smart200plc交换机 网线直连&#xff0c;并网&#xff0c;本地链接&#xff0c;电脑直连 配置电脑ip&#xff0c;以太网修改ip网段为2段&#xff0c;ping通192.168.2.1 浏览器访问192.18.2.1&#xff0c;输入账号密码进入后台配置页面 &#xff0c;…

租赁小程序的优势与应用场景解析

内容概要 租赁小程序&#xff0c;听起来是不是很酷&#xff1f;其实&#xff0c;它就是一个让你可以方便地租借各种高成本但用得不频繁的商品的平台。想象一下&#xff0c;当你需要租一件派对用的华丽小礼服&#xff0c;或是想体验一下超酷的运动器材&#xff0c;租赁小程序就…

最简单的线性回归神经网络

数据&#xff1a; # 线性回归 import torch import numpy as np import matplotlib.pyplot as plt# 随机种子&#xff0c;确保每次运行结果一致 torch.manual_seed(42)# 生成训练数据 X torch.randn(100, 3) # 100 个样本&#xff0c;每个样本 3 个特征 true_w torch.tenso…

第九篇:k8s 通过helm发布应用

什么是helm&#xff1f; Helm 是 Kubernetes 的包管理器。Helm 是查找、分享和使用软件构建 Kubernetes 的最优方式。 在红帽系的Linux中我们使用yum来管理RPM包&#xff0c;类似的&#xff0c;在K8s中我们可以使用helm来管理资源对象&#xff08;Deployment、Service、Ingress…

FastAPI解决跨域报错net::ERR_FAILED 200 (OK)

目录 一、跨域问题的本质 二、FastAPI中的CORS处理 1. 安装FastAPI和CORS中间件 2. 配置CORS中间件 3. 运行FastAPI应用 三、解决跨域报错的步骤 四、案例&#xff1a;解决Vue.js与FastAPI的跨域问题 1. Vue.js前端应用 2. FastAPI后端API 3. 配置CORS中间件 4. 运行…

ThinkPHP+Layui开发的ERP管理系统

ERP采购生产销售系统&#xff0c;一款基于ThinkPHPLayui开发的ERP管理系统&#xff0c;帮助中小企业实现ERP管理规范化&#xff0c;此系统能为你解决五大方面的经营问题&#xff1a;1.采购管理 2.销售管理 3.仓库管理 4.资金管理 5.生产管理&#xff0c;适用于&#xff1a;服装…