C 语言设计模式(创建型)

文章目录

  • 工厂模式
    • 场景
    • 使用结构体示例
    • 使用函数指针示例
    • 线程安全示例
  • 单例模式
    • 场景
    • 示例
    • 线程安全示例
  • 建造者模式
    • 场景
    • 示例
  • 原型模式
    • 场景
    • 示例

工厂模式

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式,同时隐藏了创建对象的细节。工厂模式的主要目的是将对象的实例化过程封装起来,使得客户端代码不需要知道具体对象的实例化细节,只需要知道如何使用工厂来创建对象即可。

  1. 工厂(Factory):工厂是一个接口或者抽象类,它定义了一个创建对象的方法。具体的工厂类负责实现这个方法,并根据客户端的请求来创建具体的对象。

  2. 具体工厂(Concrete Factory):具体工厂是工厂接口的实现类,它实现了创建对象的方法,并根据客户端的请求来创建具体的对象实例。

  3. 产品(Product):产品是工厂创建的对象,它可以是一个接口、抽象类或者具体类。工厂模式通过工厂创建产品对象,并将其返回给客户端使用。

场景

  1. 动态对象创建: 当程序需要根据某些条件或配置动态创建不同类型的对象时,工厂模式非常有用。工厂函数可以根据传入的参数或条件决定创建哪种类型的对象。

  2. 隐藏对象创建细节: 工厂模式可以将对象的创建过程封装在一个工厂函数中,从而隐藏对象的具体创建细节。这样可以降低代码的耦合度,提高代码的可维护性和可扩展性。

  3. 统一接口: 工厂模式可以为不同类型的对象提供一个统一的接口,使得客户端代码无需关心具体对象的创建过程,只需要通过工厂函数来获取对象实例。

  4. 扩展性: 当需要添加新的产品类时,可以通过扩展工厂函数来实现,而无需修改现有的客户端代码。这样可以提高代码的可扩展性,使得系统更加灵活。

  5. 多态性: 尽管C语言没有面向对象的多态性概念,但是通过工厂模式,你可以模拟多态性的行为。通过一个统一的接口函数来创建不同类型的对象,并通过函数指针来实现不同类型对象的特定行为。

使用结构体示例

#include <stdio.h>
#include <stdlib.h>// 定义产品类型枚举
typedef enum {PRODUCT_TYPE_A,PRODUCT_TYPE_B
} ProductType;// 定义产品结构体
typedef struct {ProductType type; // 产品类型int id;           // 产品编号char* name;       // 产品名称
} Product;// 创建产品A的工厂函数
Product* createProductA() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_A;product->id = 1;product->name = "Product A";}return product;
}// 创建产品B的工厂函数
Product* createProductB() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_B;product->id = 2;product->name = "Product B";}return product;
}// 工厂函数根据产品类型创建产品实例
Product* createProduct(ProductType type) {switch (type) {case PRODUCT_TYPE_A:return createProductA();case PRODUCT_TYPE_B:return createProductB();default:return NULL;}
}int main() {// 用户输入选择要创建的产品类型printf("请输入要创建的产品类型(0代表产品A,1代表产品B):");int choice;scanf("%d", &choice);// 创建产品Product* product = createProduct((ProductType)choice);// 根据产品类型显示产品信息if (product != NULL) {printf("产品类型:%s\n", (product->type == PRODUCT_TYPE_A) ? "产品A" : "产品B");printf("产品编号:%d\n", product->id);printf("产品名称:%s\n", product->name);free(product); // 释放产品内存} else {printf("无效的产品类型。\n");}return 0;
}
  • 输出结果
请输入要创建的产品类型(0代表产品A,1代表产品B):0
产品类型:产品A
产品编号:1
产品名称:Product A请输入要创建的产品类型(0代表产品A,1代表产品B):1
产品类型:产品B
产品编号:2
产品名称:Product B

使用函数指针示例

#include <stdio.h>
#include <stdlib.h>// 定义产品类型枚举
typedef enum {PRODUCT_TYPE_A,PRODUCT_TYPE_B
} ProductType;// 定义产品结构体
typedef struct {ProductType type; // 产品类型int id;           // 产品编号char* name;       // 产品名称
} Product;// 定义工厂函数指针类型
typedef Product* (*CreateProductFunc)();// 创建产品A的函数
Product* createProductA() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_A;product->id = 1;product->name = "Product A";}return product;
}// 创建产品B的函数
Product* createProductB() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_B;product->id = 2;product->name = "Product B";}return product;
}// 根据产品类型选择对应的工厂函数
CreateProductFunc chooseFactory(ProductType type) {switch (type) {case PRODUCT_TYPE_A:return createProductA;case PRODUCT_TYPE_B:return createProductB;default:return NULL;}
}int main() {// 用户输入选择要创建的产品类型printf("请输入要创建的产品类型(0代表产品A,1代表产品B):");int choice;scanf("%d", &choice);// 根据用户选择获取相应的工厂函数CreateProductFunc factory = chooseFactory((ProductType)choice);// 创建产品Product* product = factory();// 根据产品类型显示产品信息if (product != NULL) {printf("产品类型:%s\n", (product->type == PRODUCT_TYPE_A) ? "产品A" : "产品B");printf("产品编号:%d\n", product->id);printf("产品名称:%s\n", product->name);free(product); // 释放产品内存} else {printf("无效的产品类型。\n");}return 0;
}
  • 输出结果
输入要创建的产品类型(0代表产品A,1代表产品B):0
产品类型:产品A
产品编号:1
产品名称:Product A请输入要创建的产品类型(0代表产品A,1代表产品B):1
产品类型:产品B
产品编号:2
产品名称:Product B

线程安全示例

使用C语言结构体实现工厂模式,并通过函数指针来动态选择创建产品的具体函数。同时,通过在多线程环境中使用不同的工厂对象来创建产品对象,确保了线程安全。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>// 定义产品类型枚举
typedef enum {PRODUCT_TYPE_A,PRODUCT_TYPE_B
} ProductType;// 定义产品结构体
typedef struct {ProductType type; // 产品类型int id;           // 产品编号char* name;       // 产品名称
} Product;// 定义工厂函数指针类型
typedef Product* (*CreateProductFunc)();// 创建产品A的函数
Product* createProductA() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_A;product->id = 1;product->name = "Product A";}return product;
}// 创建产品B的函数
Product* createProductB() {Product* product = (Product*)malloc(sizeof(Product));if (product != NULL) {product->type = PRODUCT_TYPE_B;product->id = 2;product->name = "Product B";}return product;
}// 定义工厂结构体
typedef struct {CreateProductFunc createProduct; // 创建产品的函数指针
} Factory;// 创建工厂对象的函数
Factory* createFactory(CreateProductFunc createProduct) {Factory* factory = (Factory*)malloc(sizeof(Factory));if (factory != NULL) {factory->createProduct = createProduct;}return factory;
}// 获取产品的函数
Product* getProduct(Factory* factory) {if (factory != NULL && factory->createProduct != NULL) {return factory->createProduct();} else {return NULL;}
}// 打印产品信息的函数
void printProductInfo(Product* product) {if (product != NULL) {printf("产品类型:%s, 编号:%d, 名称:%s\n", product->type == PRODUCT_TYPE_A ? "A" : "B", product->id, product->name);} else {printf("获取产品失败!\n");}
}int main() {// 创建产品A工厂Factory* factoryA = createFactory(createProductA);// 创建产品B工厂Factory* factoryB = createFactory(createProductB);// 创建线程pthread_t thread1, thread2;// 在两个线程中同时获取产品pthread_create(&thread1, NULL, (void*(*)(void*))getProduct, factoryA);pthread_create(&thread2, NULL, (void*(*)(void*))getProduct, factoryB);// 等待线程结束pthread_join(thread1, NULL);pthread_join(thread2, NULL);// 输出产品信息printf("线程1获取的产品信息:\n");printProductInfo(getProduct(factoryA));printf("线程2获取的产品信息:\n");printProductInfo(getProduct(factoryB));// 释放内存free(factoryA);free(factoryB);return 0;
}
  • 输出结果
线程1获取的产品信息:
产品类型:A, 编号:1, 名称:Product A
线程2获取的产品信息:
产品类型:B, 编号:2, 名称:Product B

单例模式

单例模式是一种创建型设计模式,用于确保类只有一个实例,并提供全局访问点。在C语言中,由于缺乏类和对象的概念,单例模式的实现会略有不同,通常可以通过静态变量或全局变量来实现。

场景

  1. 全局资源管理: 当程序中需要共享一个全局资源,例如日志文件、配置文件、数据库连接等,可以使用单例模式确保只有一个实例存在,避免资源的重复创建和管理。

  2. 线程池、连接池: 在多线程环境中,使用单例模式可以创建一个线程池或连接池,确保所有线程共享同一个池,提高资源利用率和性能。

  3. 对象缓存: 在需要频繁创建和销毁对象的场景下,可以使用单例模式来缓存对象,避免重复的创建和销毁过程,提高性能。

  4. 系统配置管理: 当程序需要读取和管理系统的配置信息时,可以使用单例模式将配置信息保存在单例对象中,提供全局访问点,方便其他模块使用。

  5. 日志管理: 单例模式可以用于创建日志管理器,确保只有一个日志对象存在,并提供统一的接口来记录日志,方便程序的调试和排查问题。

  6. 游戏开发: 在游戏开发中,通常会有一些全局的管理器对象,例如场景管理器、资源管理器、音效管理器等,可以使用单例模式确保这些管理器只有一个实例存在。

示例

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>// 定义单例结构体
typedef struct {// 单例对象的属性int data;
} Singleton;// 获取单例实例的函数
Singleton* getSingletonInstance() {// 定义静态局部变量来存储单例对象的实例static Singleton instance = {0};// 返回单例对象的指针return &instance;
}int main() {// 获取单例实例Singleton* singleton1 = getSingletonInstance();Singleton* singleton2 = getSingletonInstance();// 修改单例实例的数据singleton1->data = 10;// 输出单例实例的数据printf("单例实例1的数据:%d\n", singleton2->data); // 预期输出结果为 10return 0;
}
  • 输出结果
单例实例1的数据:10

线程安全示例

使用互斥锁来确保单例对象的创建过程是线程安全的。定义了一个名为singletonMutex的互斥锁,并在getSingletonInstance函数中使用pthread_mutex_lock和pthread_mutex_unlock函数来加锁和解锁。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>// 定义单例结构体
typedef struct {// 单例对象的属性int data;
} Singleton;// 定义单例对象指针
static Singleton *singletonInstance = NULL;// 定义互斥锁
static pthread_mutex_t singletonMutex = PTHREAD_MUTEX_INITIALIZER;// 获取单例实例的函数(线程安全版本)
Singleton* getSingletonInstance() {// 加锁pthread_mutex_lock(&singletonMutex);// 如果单例对象尚未创建,则创建它if (singletonInstance == NULL) {singletonInstance = (Singleton*)malloc(sizeof(Singleton));if (singletonInstance != NULL) {singletonInstance->data = 0;}}// 解锁pthread_mutex_unlock(&singletonMutex);// 返回单例对象指针return singletonInstance;
}int main() {// 创建线程pthread_t thread1, thread2;// 在两个线程中同时获取单例实例pthread_create(&thread1, NULL, (void*(*)(void*))getSingletonInstance, NULL);pthread_create(&thread2, NULL, (void*(*)(void*))getSingletonInstance, NULL);// 等待线程结束pthread_join(thread1, NULL);pthread_join(thread2, NULL);// 输出单例实例的地址printf("单例实例1的地址:%p\n", getSingletonInstance());printf("单例实例2的地址:%p\n", getSingletonInstance());return 0;
}
  • 输出结果
单例实例1的地址:0x7ff329111840
单例实例2的地址:0x7ff329111840

建造者模式

建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

  1. 产品(Product): 表示被构建的复杂对象。通常,产品类是一个包含多个部件的复杂对象,它们的组合形成了一个完整的产品。

  2. 建造者(Builder): 定义了构建产品的接口。通常,建造者接口包含多个方法,每个方法用于构建产品的一个部件。不同的具体建造者可以实现相同的接口,但是具体实现方式可能不同。

  3. 具体建造者(Concrete Builder): 实现了建造者接口,负责构建具体的产品部件。每个具体建造者负责构建特定类型的产品,并提供了构建该产品所需的具体实现逻辑。

  4. 指挥者(Director): 负责使用建造者对象构建产品。指挥者通常包含一个构建方法,该方法接收一个建造者对象作为参数,并根据需要调用建造者对象的方法来构建产品。

场景

  1. 复杂对象的构建: 当一个对象的构建过程较为复杂,需要多个步骤或者多个组件来完成,可以使用建造者模式。通过将构建过程拆分成多个步骤,并由建造者对象负责组装这些步骤,可以使得构建过程更加灵活和可控。

  2. 对象的构建与表示分离: 建造者模式可以将一个复杂对象的构建过程与其表示分离,使得构建过程独立于表示,并且可以灵活地组装不同的部件来构建不同的对象。

  3. 创建复杂的产品变种: 当需要创建多个相似但又有所不同的产品变种时,可以使用建造者模式。通过定义不同的建造者来创建不同的产品变种,可以有效地复用相同的构建过程。

  4. 避免构造函数参数过多: 当一个类的构造函数需要接收大量参数时,可以使用建造者模式。通过将参数封装在建造者对象中,并逐步设置这些参数,可以避免构造函数参数过多导致代码难以理解和维护的问题。

  5. 动态配置对象的属性: 建造者模式允许在构建过程中动态配置对象的属性,从而可以根据需求灵活地调整对象的属性。

示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义产品结构体
typedef struct {char type[20];  // 产品类型int size;       // 产品尺寸char color[20]; // 产品颜色
} Product;// 定义建造者结构体
typedef struct {// 建造者对象的属性char type[20];  // 产品类型int size;       // 产品尺寸char color[20]; // 产品颜色
} Builder;// 定义建造者初始化函数
void initBuilder(Builder *builder, const char *type, int size, const char *color) {strncpy(builder->type, type, sizeof(builder->type) - 1);builder->type[sizeof(builder->type) - 1] = '\0'; // 确保字符串以'\0'结尾builder->size = size;strncpy(builder->color, color, sizeof(builder->color) - 1);builder->color[sizeof(builder->color) - 1] = '\0'; // 确保字符串以'\0'结尾
}// 定义建造者创建产品的函数
void buildProduct(Builder *builder, Product *product) {// 将建造者对象的属性复制到产品对象strncpy(product->type, builder->type, sizeof(product->type) - 1);product->type[sizeof(product->type) - 1] = '\0'; // 确保字符串以'\0'结尾product->size = builder->size;strncpy(product->color, builder->color, sizeof(product->color) - 1);product->color[sizeof(product->color) - 1] = '\0'; // 确保字符串以'\0'结尾
}int main() {// 创建建造者对象Builder builder;initBuilder(&builder, "Chair", 20, "Red");// 创建产品对象Product product;buildProduct(&builder, &product);// 输出产品信息printf("产品类型:%s\n", product.type);printf("产品尺寸:%d\n", product.size);printf("产品颜色:%s\n", product.color);return 0;
}
  • 输出结果
产品类型:Chair
产品尺寸:20
产品颜色:Red

原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,它用于创建对象的新实例,同时通过复制原型对象的方法来避免显式的构造函数调用。原型模式基于原型对象创建新对象,而不是通过实例化类。

  1. 原型(Prototype):原型是一个接口或者抽象类,它定义了一个克隆方法,用于复制原型对象并返回新的对象实例。具体的原型类负责实现这个克隆方法,以复制自身并返回新的对象实例。

  2. 具体原型(Concrete Prototype):具体原型是原型接口的实现类,它实现了克隆方法,并在其中对自身进行复制并返回新的对象实例。

  3. 客户端(Client):客户端使用原型对象来创建新的对象实例,而不需要显式调用构造函数。客户端通过调用原型对象的克隆方法来复制原型对象并获取新的对象实例。

场景

  1. 动态创建对象: 当需要根据运行时的条件或用户输入动态创建对象时,原型模式非常有用。通过克隆一个已有的对象,可以避免重复的创建过程,提高效率。

  2. 对象初始化复杂: 如果对象的初始化过程比较复杂,包含大量的计算或资源分配,可以使用原型模式来避免重复的初始化过程。通过复制已有的对象,可以节省初始化的时间和资源消耗。

  3. 减少子类数量: 在一些情况下,可能存在大量类似的对象,但它们的差异只是一些属性或配置的不同。使用原型模式可以减少类的数量,将共同的部分抽取到原型对象中,然后通过克隆来创建不同的对象。

  4. 资源共享: 如果多个对象需要共享某些资源,但又需要保持独立性,可以使用原型模式。通过共享原型对象,可以避免资源的重复分配,提高资源利用率。

  5. 保护对象: 在一些情况下,需要保护对象的创建过程,防止外部直接访问构造函数或初始化函数。使用原型模式可以隐藏对象的创建细节,只提供一个克隆接口来创建对象。

示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义原型结构体
typedef struct {// 原型对象的属性int id;char name[20];
} Prototype;// 创建原型对象的函数
Prototype* createPrototype(int id, const char *name) {// 动态分配内存并初始化原型对象Prototype *prototype = (Prototype*)malloc(sizeof(Prototype));if (prototype != NULL) {prototype->id = id;strncpy(prototype->name, name, sizeof(prototype->name) - 1);prototype->name[sizeof(prototype->name) - 1] = '\0'; // 确保字符串以'\0'结尾}return prototype;
}// 复制原型对象的函数
Prototype* clonePrototype(Prototype *prototype) {// 动态分配内存并复制原型对象Prototype *clone = (Prototype*)malloc(sizeof(Prototype));if (clone != NULL) {*clone = *prototype; // 执行浅拷贝}return clone;
}int main() {// 创建原型对象Prototype *original = createPrototype(1, "Original");// 克隆原型对象Prototype *clone = clonePrototype(original);// 修改克隆对象的数据clone->id = 2;strncpy(clone->name, "Clone", sizeof(clone->name) - 1);clone->name[sizeof(clone->name) - 1] = '\0'; // 确保字符串以'\0'结尾// 输出原型对象和克隆对象的数据printf("原型对象:ID=%d, Name=%s\n", original->id, original->name);printf("克隆对象:ID=%d, Name=%s\n", clone->id, clone->name);// 释放内存free(original);free(clone);return 0;
}
  • 输出结果
原型对象:ID=1, Name=Original
克隆对象:ID=2, Name=Clone

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

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

相关文章

汇编原理(三)编程

源程序&#xff1a; 汇编指令&#xff1a;有对应的机器码与其对应 伪指令&#xff1a;无对应的机器码&#xff0c;是由编译器来执行的指令&#xff0c;编译器根据伪指令来进行相关的编译工作。 ex1:XXX segment、XXX ends这两个是一对成对使用的伪指令&#xff0c;且必须会被用…

thingsboard 仪表盘部件如何解析设备RCP应答

对设备添加仪表部件Switch control后&#xff0c;开关部件默认会发送getValue v1/devices/me/rpc/request/0 {"method":"getValue","params":null} 此时设备收到请求后回复一个“value”值&#xff0c;“value”可以是任何字符串 v1/devices/…

spark机器学习之协同过滤

协同过滤算法 协同过滤是一类基于用户行为数据的推荐算法,它的核心思想是利用用户的历史行为数据(比如评分、购买、点击等)来发现用户之间的相似性或者物品之间的相似性,从而给用户推荐他们可能感兴趣的物品。协同过滤算法通常分为两种类型:基于用户的协同过滤和基于物品…

打工人好用的大模型问答,还需要一款可靠的文档解析工具

如果说三四年前&#xff0c;我们对AI的展望还停留在科幻片的话&#xff0c;现在&#xff0c;通向AI智能的路径已经初现端倪。各行各业的朋友们不约而同地嗅到了大模型带来的生产方式变革气息。 LLM宣布了AI时代的正式到来。 2022年11月30日&#xff0c;ChatGPT发布&#xff0…

“智能体时代:探索无限可能——零代码构建智能教练智能体“

随着智能体技术的飞速发展&#xff0c;各个领域正经历着空前的变革和新的发展机遇。作为人工智能的一个关键组成部分&#xff0c;智能体以其自我驱动、智能响应和适应能力&#xff0c;逐渐深入到我们日常生活的各个层面&#xff0c;成为促进社会发展和科技进步的新引擎。 顺应这…

Linux 文件权限管理详解

查看文件权限 使用ls -l命令&#xff1a; 打开终端&#xff0c;进入文件所在的目录&#xff0c;然后输入以下命令查看文件或目录的详细信息&#xff0c;包括权限、所有者、所属组、大小、修改日期等&#xff1a; ls -l 文件或目录名 示例&#xff1a; ls -l myfile.txt ls -l m…

力扣刷题--2951. 找出峰值【简单】

题目描述 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的下标&#xff0c;顺序不限 。 注意&#xff1a; 峰值 是指一个严格大于其相邻元素的元素。 数组的第一个和最后一个元素 不 是峰值。 示例…

30V MOS管 60VMOS管 100VMOS管 150VMOS管推荐

MOS管&#xff0c;即金属氧化物半导体场效应管&#xff0c;其工作原理是&#xff1a;在P型半导体与N型半导体之间形成PN结&#xff0c;当加在MOS管栅极上的电压改变时&#xff0c;PN结之间的沟道内载流子的数量会随之改变&#xff0c;沟道电阻也会发生改变&#xff0c;进而改变…

【JavaEE精炼宝库】多线程(3)线程安全 | synchronized

目录 一、线程安全 1.1 经典线程不安全案例&#xff1a; 1.2 线程安全的概念&#xff1a; 1.3 线程不安全的原因&#xff1a; 1.3.1 案例刨析: 1.3.2 线程不安全的名词解释&#xff1a; 1.3.3 Java 内存模型 (JMM)&#xff1a; 1.3.4 解决线程不安全问题&#xff1a; 二…

内存池的实现

概述&#xff1a;本文介绍用户层内存池的实现 Q:为什么需要内存池&#xff1f; A&#xff1a;在项目中&#xff0c;用户层通过malloc系统调用申请内存的次数可能很多&#xff0c;每一次malloc系统调用&#xff0c;都会引起用户态——内核态的切换&#xff0c;这样的开销对性能…

工业AI的崛起,中国自主创新的新机遇

我们都知道&#xff0c;互联网已经深刻地改变了我们的生活方式&#xff0c;催生了无数的新型商业模式和创新产业&#xff0c;推动了社会的经济变革。中国在互联网领域的发展取得了举世瞩目的成就&#xff0c;建成了全球规模最大、技术领先的5G网络&#xff0c;互联网应用的普及…

各种网络协议在设计目的、工作方式、应用场景等方面存在显著的区别

各种网络协议在设计目的、工作方式、应用场景等方面存在显著的区别。以下是一些常见网络协议的区别 概述&#xff1a; TCP与UDP&#xff1a; 设计目的&#xff1a;TCP&#xff08;传输控制协议&#xff09;提供面向连接的、可靠的、基于字节流的传输服务。UDP&#xff08;用户…

linux文件编程api: creat

1.基本信息 功能 创建新文件 头文件 #include<fcntl.h> 函数形式 int creat(const char *pathname, mode_t mode); 返回值 如果成功&#xff0c;则返回文件描述符号 如果失败&#xff0c;则返回-1 参数 pathname: 创建的文件名 mode: 新建文件时&#xff0c;文件权限…

Java Web(入门)

Java Web 1. 入门基础 1.1 Java Web简介 Java Web开发是指使用Java技术来创建动态网站或Web应用程序。Java Web开发主要使用Servlet、JSP&#xff08;JavaServer Pages&#xff09;、JavaBeans等技术来实现动态页面和处理业务逻辑。 1.2 环境搭建 为了开发Java Web应用程序…

TypeScript-字面量类型

字面量类型 使用 JS字面量 作为类型对变量进行类型注解&#xff0c;这种类型就是字面量类型&#xff0c;字面量类型比普通的类型更加精确 // 普通number类型&#xff0c;可以赋值任何数值 let count: number count 1 count 2 // 字面量类型100 只能赋值为100 let count: 1…

Django革新者:突破传统,构建下一代Web应用

书接上文 —— 家园建筑师&#xff1a;用Django打造你的Web帝国&#xff0c;从前面的学习中&#xff0c;咱们我们经历了一个完整的Django Web开发之旅&#xff0c;涵盖了从基础概念到高级特性的各个方面&#xff1a; 引言&#xff1a;介绍了企业级Web框架的需求&#xff0c;并概…

牛客NC67 汉诺塔问题【中等 递归 Java/Go/PHP/C++】 lintcode 169 · 汉诺塔

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/7d6cab7d435048c4b05251bf44e9f185 https://www.lintcode.com/problem/169/ 思路 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上&#xff0c;有三根杆(编号A、B、C…

使用Python操作Jenkins

大家好&#xff0c;Python作为一种简洁、灵活且功能丰富的编程语言&#xff0c;可以与各种API轻松集成&#xff0c;Jenkins的API也不例外。借助于Python中的python-jenkins模块&#xff0c;我们可以轻松地编写脚本来连接到Jenkins服务器&#xff0c;并执行各种操作&#xff0c;…

拌合楼系统开发(二十)解决海康DS-TVL224系列屏幕显示二维码思路

前言&#xff1a; 需求是想在通过程序动态控制显示屏显示二维码&#xff0c;最开始有些担心led这种点阵屏会不会对二维码显示出来后无法识别&#xff0c;实际测时候发现是没问题的。对于显示文字和语音播报&#xff0c;csdn上已经有大神有完整的代码。 海康威视道闸进出口LED屏…

100个 Unity小游戏系列三 -Unity 抽奖游戏专题二 水果机游戏

一、演示效果 二、知识点 2.1 布局 private void CreateItems(){for (int i 0; i < rewardDatas.Length; i){var reward_data rewardDatas[i];GameObject fruitOjb;if (i < itemRoot.childCount){fruitOjb itemRoot.GetChild(i).gameObject;}else{fruitOjb Instant…