安庆做网站的公司做网站上传图片

张小明 2026/1/6 11:16:52
安庆做网站的公司,做网站上传图片,上传设计作品集的网站,社交网站页面设计1.静态数组管理多个结构体变量对于c语言当一个结构体要创建多个变量时#xff0c;若我们分开管理就会比较难以管理#xff0c;但是我们可以通过结构体数组#xff08;对象数组#xff09;的形式对其进行管理。我们看下面这段程序#xff1a;#include stdio.h #inc…1.静态数组管理多个结构体变量对于c语言当一个结构体要创建多个变量时若我们分开管理就会比较难以管理但是我们可以通过结构体数组对象数组的形式对其进行管理。我们看下面这段程序#include stdio.h #include stdint.h typedef struct { uint8_t port; //引脚接口 0GPIOA 1GPIOB uint8_t pin; //引脚标号 0-15 uint8_t mode; //输入输出模式 0输入 1输出 uint8_t state;//引脚状态 0低电平 1高电平 }GPIO_Pin_t; GPIO_Pin_t gpio_conf[8] { //{port ,pin ,mode ,state}GPIO参数配置列表 {0 ,0 ,0 ,0}, {0 ,1 ,0 ,0}, {0 ,2 ,1 ,0}, {0 ,3 ,1 ,0}, {1 ,0 ,0 ,0}, {1 ,1 ,0 ,0}, {1 ,2 ,1 ,0}, {1 ,3 ,1 ,0} }; void GPIO_Write_Pin(uint8_t index, uint8_t state) { if (index 0 | index 8) return; gpio_conf[index].state state; } void GPIO_init(void) { for (int i 0; i 8; i) { if (1 gpio_conf[i].mode) { GPIO_Write_Pin(i,1); } } } int main(void) { GPIO_init(); //批量处理 return 0; }可见当我们需要管理多个gpio时我们就可以通过一个数组的方式将其管理在一个数组内并且通过对数组的遍历我们还可以批量处理数据方便了我们的管理。2.手写一个类似hal库的串口设备库在我们常使用的hal库中也有着c语言面向对象的思想的体现下面我们来实现一个串口类。我们先来看.h文件#ifndef USART_H #define USART_H #include stm32f4xx.h #include stdint.h //前向声明 typedef struct USART_Device USART_Device; //串口类定义 struct USART_Device{ USART_TypeDef* hw; //硬件基地址 uint32_t baurate; //波特率 uint8_t tx_buffer[256]; //发送buffer uint8_t rx_buffer[256]; //接收buffer void (*init) (USART_Device* self); //串口初始化 void (*send) (USART_Device* self, const char* data, uint32_t len); //发送数据 int (*recv) (USART_Device* self, char* buffer, uint32_t max_len); //接收数据 void (*deint)(USART_Device* self); //销毁创建的对象 }; #endif // USART_H在这个文件中我们定义出了串口类类中包含了属性和方法。下面我们来看.c文件中一些方法的具体实现#include usart.h #include string.h static void usart_init(USART_Device* self) { //时钟配置 if (self-hw USART1) { RCC-APB2ENR | RCC_APB2ENR_USART1EN; } //波特率配置 uint32_t usartdiv 42000000 / (16 * self-baurate); self-hw-BRR usartdiv; //串口使能 self-hw-CR1 USART_CR1_UE | //使能串口 USART_CR1_TE | //使能发送 USART_CR1_RE; //使能接收 //清空缓存区 menset(self-tx_buffer, 0, 256); menset(self-rx_buffer, 0, 256); } static void usart_send(USART_Device* self, const char* data, uint32_t len) { for (int i 0; i len; i) { //发送寄存器为空 while (!(self-hw-SR UART_SR_TXE)); //写入 self-hw-DR data[i]; //发送完成 while (!(self-hw-SR UART_SR_TC)); } } USART_Device* usart_create(USART_TypeDef* hw, uint32_t baurate) { //分配内存 USART_Device* dev (USART_Device*)malloc(sizeof(USART_Device)); if (dev NULL) return NULL; //初始化成员 dev-hw hw; dev-baurate baurate; menset(dev-tx_buffer, 0, 256); menset(dev-rx_buffer, 0, 256); //绑定方法 dev-init usart_init; dev-send usart_send; dev-recv usart_recv; dev-deint usart_deint(); return dev; }可见上面的程序与标准的hal库一样都实现了对象化的处理这也是c语言中面向对象思想的体现。我们来看看main函数的实现#include usart.h int main(void) { USART_Device* uart1 usart_create(USART1, 115200); USART_Device* uart2 usart_create(USART2, 9600); uart1-init(uart1); uart2-init(uart2); uart1-send(uart1, hello usart1, 12); uart2-send(uart2, hello usart2, 12); return 0; }可见在mian函数中我们创建了两个串口对象并分别使用同一个接口实现了对不同对象的初始化和发送数据可见对象化的思想使我们的程序更加清晰明了啦。3.解决对象内存分配使用malloc不高效的问题我们知道当我们每创建一个对象时使用malloc需要向系统申请一块空间每次使用完毕后还需要使用free来进行销毁这就会导致程序不够高效。对此我们可以通过使用对象池来解决这个问题,首先我们要定义出一个对象池程序如下typedef struct { int is_free; //0有对象使用1没有对象使用 char obj[256]; //对象使用空间 }Object; typedef struct { Object* pool; //对象池地址 int pool_size; //池容量 int pool_count;//池使用量 };对象池定义好后我们需要对其进行操作程序如下Objectpool* pool_init(int size) { //创建管理池 Objectpool* p (Objectpool*)malloc(sizeof(Objectpool)); if (p NULL) { return NULL; } //创建池 p-pool (Object*)malloc(size * sizeof(Object)); if (p-pool NULL) { free(p); return NULL; } //管理池参数初始化 p-pool_size size; p-pool_count 0; //池参数初始化 for (int i 0; i size; i) { p-pool[i].is_free 1; } } Object* object_alloc(Objectpool* p) //向对象池中获取存储对象的空间 { if (p NULL) { return NULL; } for (int i 0; i p-pool_size; i) { if (p-pool[i].is_free 1) { p-pool[i].is_free 0; //标志位置为0表示已被使用 p-pool_count; //表示内存时使用量加1 return p-pool[i]; } } return NULL; } void object_free(Objectpool* p, Object* obj) //将对象池中的对象空间还回对象池 { if (p NULL | obj NULL) { return; } if (obj p-pool obj p-pool p-pool_size)//通过和p指向的内存池地址相比较确保该对象空间是从该对象池中申请的 { obj-is_free 1; p-pool_count--; //表示内存使用量减1 } } void pool_destory(Objectpool* p) { if (p NULL) { return; } free(p-pool); free(p); }我们分别实现了对象池的初始化向对象池中获取一个对象空间将从对象池中获取的对象空间还回对应对象池和销毁对象池的基本操作。下面我们在main函数中使用一下该对象池。int main(void) { //创建对象池 Objectpool* p pool_init(7); if (p NULL) { printf(对象池分配失败\n); return -1; } //创建对象并从对象池中获取存储空间 Object* obj1 object_alloc(p); Object* obj2 object_alloc(p); Object* obj3 object_alloc(p); if (obj1 obj2 obj3) { printf(成功分配三个对象对象池已用%d/7\n, p-pool_count); } //释放对象将从对象池中获取的空间还回对象池 object_free(p, obj3); printf(成功释放一个对象对象池已用%d/7\n, p-pool_count); //再创建对象从对象池获取存储空间 Object* obj4 object_alloc(p); if (obj4 ! NULL) { printf(成功再次分配一个对象对象已用%d/7\n, p-pool_count); } //对象池使用完毕销毁对象池 pool_destory(p); return 0; }我们在主函数中分别进行上述操作验证对象池的操作程序是否正确。运行后结构如下可见对象的操作没有问题。4.单例模式的使用当我们对同一个硬件进行初始化时若不使用单列模式的话每一个实例的对象都相当于是用的不同的硬件。当一个硬件以及被其中一个对象初始化并且开始运行时其他的对象并不会知道该硬件的状态然后就可能导致该硬件执行到一般就又被初始化了或者之间的混乱使用导致出现问题。对此我们就可以使用单例模式来解决。我们看下面的程序#include stdio.h #include stdlib.h typedef struct { int port; int pageCount; }Pinter; Pinter* get_pinter(void) { static Pinter pinter; static int init_flag 0; if (!init_flag) { pinter.port 0x378; pinter.pageCount 5; init_flag 1; } return pinter; } int main(void) { Pinter* p1 get_pinter(); Pinter* p2 get_pinter(); if (p1 p2) printf(p1p2\n); else printf(p1!p2\n); return 0; }我们通过static关键字的使用就实现了单例模式因为static修饰后变量只会被初始化一次不会出现多次初始化的问题其中pinter也只有一个函数返回的都是同一个pinter即可以实现了其中信息的共享也不会因为多个对象一起操作同一个硬件出现问题。5.浅拷贝与深拷贝问题浅拷贝和深拷贝对于基本类型都是直接复制值但是对于引用类型或者指针浅拷贝只是将指针的值复制过去了并没有将指针指向的内容复制深拷贝则是重新开辟一个内存然后将指针指向的内容进行复制。我们来看看下面这段程序#include stdio.h #include stdlib.h #include string.h typedef struct { char* name; int age; }Person; Person shallow_copy(Person* src) { Person p; p.name src-name; p.age src-age; return p; } Person deep_copy(Person* src) { Person p; p.age src-age; //创建一块新的内存 p.name (char*)malloc(sizeof(src-name)); //复制内容 strcpy(p.name, src-name); return p; } int main(void) { Person p1; p1.age 18; p1.name (char*)malloc(10); strcpy(p1.name, 张三); Person p2 shallow_copy(p1); Person p3 deep_copy(p1); strcpy(p1.name,李四); printf(p1.name:%s\n, p1.name); printf(p2.name:%s\n, p2.name); printf(p3.name:%s\n, p3.name); strcpy(p2.name, 王五); printf(p1.name:%s\n, p1.name); printf(p2.name:%s\n, p2.name); printf(p3.name:%s\n, p3.name); free(p1.name); free(p3.name); return 0; }可见我们分别对p2和p3实现了浅拷贝和深拷贝运行后结果如下可见p2和p1的name指向的是同一块内存所以不管是通过p1来修改该内存下的内容还是p2来修改其中的内容两者都会被修改。故浅拷贝容易造成内容不安全指针悬空重复释放等问题所以我们一般当有指针或引用赋值操作时都使用深拷贝但是在基本变量复制或者不会对数据内容进行修改等情况下也可以使用浅拷贝因为虽然深拷贝是实现了数据的安全性和解决了指针悬空等问题但是也消耗了更多的空间和时间。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

上海轨道交通建设查询网站河南网站建设软件

MATLAB优化建模终极指南:YALMIP工具箱完整使用手册 【免费下载链接】YALMIP MATLAB toolbox for optimization modeling 项目地址: https://gitcode.com/gh_mirrors/ya/YALMIP YALMIP是MATLAB生态系统中功能最强大的优化建模工具箱,彻底改变了复杂…

张小明 2026/1/4 22:58:07 网站建设

哪个网站做美食好一点wordpress主题的网站

还在为Beyond Compare的评估期到期而烦恼?每次打开软件都要面对那个"缺少评估信息"的提示框?别担心,今天我将为你揭秘一套完整的本地授权生成方案,让你轻松获得永久使用权限!🤩 【免费下载链接】…

张小明 2026/1/4 22:57:28 网站建设

网站主题分析网站建设能解决哪些问题

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个测试数据生成器原型,功能:1)选择数据库类型(MySQL/PostgreSQL等) 2)输入表结构(字段名类型) 3)设置生成行数(1-10000) 4)为每个字段选择生成规则(随…

张小明 2026/1/4 22:56:51 网站建设

济南正规的网站制作网站开发前端技术

还在为繁琐的Steam游戏文件管理而烦恼吗?Onekey作为一款专业的开源Steam清单下载工具,将复杂的数据获取过程简化为几个简单点击。无论你是游戏收藏家、开发者还是普通玩家,这款工具都能让你的游戏管理效率翻倍提升。 【免费下载链接】Onekey …

张小明 2026/1/6 0:36:24 网站建设

国内优秀设计网站站长工具国产2022

Meshroom完全攻略:零基础快速掌握AI驱动的3D重建技术 【免费下载链接】Meshroom 3D Reconstruction Software 项目地址: https://gitcode.com/gh_mirrors/me/Meshroom 想要用普通照片创建专业级3D模型?Meshroom这款基于人工智能的开源软件将彻底改…

张小明 2026/1/4 22:55:46 网站建设

网站调用谷歌地图引擎网站推广法怎么做

企业微信定位修改终极指南:完整教程与实用技巧 【免费下载链接】weworkhook 企业微信打卡助手,在Android设备上安装Xposed后hook企业微信获取GPS的参数达到修改定位的目的。注意运行环境仅支持Android设备且已经ROOTXposed框架 (未 ROOT 设备…

张小明 2026/1/4 22:55:14 网站建设