当前位置: 首页 > news >正文

嵌入式设备的 Json 库基本使用

大家好,今天给介绍一款基于 C 语言的轻量级的 Json 库 – cJson。可用于资源受限的嵌入式设备中。

 

cJSON 是一个超轻巧,携带方便,单文件,简单的可以作为 ANSI-C 标准的 JSON 解析器。

cJSON 是一个开源项目,github 下载地址:

https://github.com/DaveGamble/cJSON

cJSON,目前来说,主要的文件有两个,一个 cJSON.c 一个 cJSON.h。使用的时候,将头文件 include 进去即可。

如果是在 Linux 操作系统中使用,编译 到时候需要添加数学库 libm.so,如下所示:

gcc  *.c  cJSON.c  -lm

1. cJSON 结构体

在 cJSON.h 中定义了一个非常重要的结构体 cJSON,想要熟悉使用 cJSON 库函数可从 cJSON 结构体入手,cJSON 结构体如下所示:

typedef struct cJSON {  struct cJSON *next,*prev;   struct cJSON *child;   int type;   char *valuestring;        // value值是字符串类型int valueint;  double valuedouble;   char *string;             // 对象中的key
} cJSON; 

关于这个结构体做如下几点的说明:

  1. cJOSN 结构体是一个双向链表,并且可通过 child 指针访问下一层。

  2. 结构体成员 type 变量用于描述数据元素的类型(如果是键值对表示 value 值的类型),数据元素可以是字符串可以是整形,也可以是浮点型。

  • 如果是整形值的话可通过 valueint 将值取出

  • 如果是浮点型的话可通过 valuedouble 将值取出

  • 如果是字符串类型的话可通过 valuestring 将值取出

  1. 结构体成员 string 表示键值对中键值的名称。

cJSON 作为 Json 格式的解析库,其主要功能就是构建和解析 Json 格式了,比如要发送数据:用途就是发送端将要发送的数据以 json 形式封装,然后发送,接收端收到此数据后,还是按 json 形式解析,就得到想要的数据了。

2. cJson API

Json 格式的数据无外乎有两种 Json对象和 Json数组,创建的 Json 数据串可能是二者中 的一种,也可能是二者的组合,不管哪一种通过调用相关的 API 函数都可以轻松的做到这一点。

2.1 数据的封装

在 cJSON.h 头文件中可以看到一些函数声明,通过调用这些创建函数就可以将 Json 支持的数据类型封装为 cJSON 结构体类型:

// 空值类型
extern cJSON *cJSON_CreateNull(void);
// 布尔类型
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
// 数值类型
extern cJSON *cJSON_CreateNumber(double num);
// 字符串类型
extern cJSON *cJSON_CreateString(const char *string);
// json数组(创建空数组)
extern cJSON *cJSON_CreateArray(void);
// json对象(创建空对象)
extern cJSON *cJSON_CreateObject(void);

另外,cJson 库中还给我我们提供了一些更为简便的操作函数,在创建数组的同时还可以进行初始化

// 创建一个Json数组, 元素为整形
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
// 创建一个Json数组, 元素为浮点
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
// 创建一个Json数组, 元素为字符串类型
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);

2.2 Json 对象操作

当得到一个 Json 对象之后,就可以往对象中添加键值对了,可以使用 cJSON_AddItemToObject()

extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

在 cJSON 库中节点的从属关系是通过树来维护的,每一层节点都是通过链表来维护的,这样就能分析出该函数参数的含义:

  • object:要添加的键值对从属于那个节点

  • string:添加的键值对的键值

  • item:添加的键值对的 value 值(需要先将其封装为 cJSON 类型的结构体)

为了让我的操作更加方便,cJson 库还给我们提供了一些宏函数,方便我们快速的往 Json 对象中添加键值对

#define cJSON_AddNullToObject(object,name)      cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name)      cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b)    cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n)  cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)  cJSON_AddItemToObject(object, name, cJSON_CreateString(s))

我们还可以根据 Json 对象中的键值取出相应的 value 值,API 函数原型如下:

extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);

2.3 Json 数组操作

添加数据到 Json 数组中(原始数据需要先转换为 cJSON 结构体类型)

extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);

得到 Json 数组中元素的个数:

extern int cJSON_GetArraySize(cJSON *array);

得到 Json 数组中指定位置的原素,如果返回 NULL 表示取值失败了。

extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);

2.4 序列化

序列化就是将 Json 格式的数据转换为字符串的过程,cJson 库中给我们提供了 3 个转换函数,具体如下:

第一个参数 item 表示 Json 数据块的根节点。

extern char  *cJSON_Print(cJSON *item);
extern char  *cJSON_PrintUnformatted(cJSON *item);
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
  • 调用 cJSON_Print() 函数我们可以得到一个带格式的 Json 字符串(有换行,看起来更直观)

  • 调用 cJSON_PrintUnformatted() 函数会得到一个没有格式的 Json 字符串(没有换行,所有的数据都在同一行)。

  • 调用 cJSON_PrintBuffered() 函数使用缓冲策略将 Json 实体转换为字符串,参数 prebuffer 是指定缓冲区的大小,参数 fmt==0 表示未格式化,fmt==1 表示格式化。

我们在编码过程中可以根据自己的实际需求调用相关的操作函数得到对应格式的 Json 字符串。

2.5 Json 字符串的解析

如果我们得到了一个 Json 格式的字符串,想要读出里边的数据,就需要对这个字符串进行解析,处理方式就是将字符串转换为 cJSON 结构体,然后再基于这个结构体读里边的原始数据,转换函数的函数原型如下:

extern cJSON *cJSON_Parse(const char *value);

2.6 内存释放

当我们将数据封装为 cJSON 结构类型的节点之后都会得到一块堆内存,当我们释放某个节点的时候可以调用 cJson 库提供的删除函数 cJSON_Delete(),函数原型如下:

extern void   cJSON_Delete(cJSON *c);

该函数的参数为要释放的节点的地址,在此强调一点:在进行内存地址释放的时候,当前节点以及其子节点都会被删除。

3. Json 数据的封装

3.1 Json 对象操作举例

创建一个对象,并向这个对象里添加字符串和整型键值:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"cJSON.h"int main()
{cJSON * root;cJSON *arry;root=cJSON_CreateObject();                     // 创建根数据对象cJSON_AddStringToObject(root,"name","luffy");  // 添加键值对cJSON_AddStringToObject(root,"sex","man");     // 添加键值对cJSON_AddNumberToObject(root,"age",19);        // 添加键值对char *out = cJSON_Print(root);   // 将json形式转换成字符串printf("%s\n",out);// 释放内存  cJSON_Delete(root);  free(out);        
}

运行结果

{"name": "luffy","sex": "man","age": 19
}

若干说明:

  • cJSON_CreateObject 函数可创建一个根对象,返回的是一个 cJSON 指针,在这个指针用完了以后,需要手动调用 cJSON_Delete(root) 进行内存回收。

  • 函数 cJSON_Print() 内部封装了 malloc 函数,所以需要使用 free() 函数释放被 out 占用的内存空间。

3.2 Json 数组操作举例

创建一个数组,并向数组添加一个字符串和一个数字

int main(int argc, char **argv)
{cJSON *root;root = cJSON_CreateArray();cJSON_AddItemToArray(root, cJSON_CreateString("Hello world"));cJSON_AddItemToArray(root, cJSON_CreateNumber(10)); // char *s = cJSON_Print(root);char *s = cJSON_PrintUnformatted(root);if(s){printf(" %s \n",s);free(s);}cJSON_Delete(root);return 0;
}

运行结果:

["Hello world",10]

3.3 Json 对象、数组嵌套使用

对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字

{"person":[{"name":"luffy","age":19}]
}

示例代码:

int main(int argc, char **argv)
{cJSON *root, *body, *list;// josn 对象 rootroot = cJSON_CreateObject();// root 添加键值对 person:json数组AcJSON_AddItemToObject(root,"person", body = cJSON_CreateArray());// json数组A 添加Json对象BcJSON_AddItemToArray(body, list = cJSON_CreateObject());// 在json对象B中添加键值对: "name":"luffy"cJSON_AddStringToObject(list,"name","luffy");// 在json对象B中添加键值对: "age":19cJSON_AddNumberToObject(list,"age",19);// char *s = cJSON_Print(root);char *s = cJSON_PrintUnformatted(root);if(s){printf(" %s \n",s);free(s);}if(root){cJSON_Delete(root); }return 0;
}

运行结果:

{"person":[{"name":"luffy","age":19}]}

4. 解析 Json 字符串

4.1 解析 Json 对象

Json 字符串的解析流程和数据的封装流程相反,假设我们有这样一个 Json 字符串(字符串中的双引号需要通过转义字符将其转译为普通字符):

{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}

示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"int main()
{cJSON *json, *name, *sex, *age;char* out="{\"name\":\"luffy\",\"sex\":\"man\",\"age\":19}";json = cJSON_Parse(out); //解析成json形式name = cJSON_GetObjectItem(json, "name");  //获取键值内容sex = cJSON_GetObjectItem(json, "sex");age = cJSON_GetObjectItem(json, "age");printf("name:%s,sex:%s,age:%d\n", name->valuestring, sex->valuestring, age->valueint);cJSON_Delete(json);  //释放内存 
}

输出的结果:

name:luffy,sex:man,age:19

如果是在严格的场所,应该先判定每个 item 的 type,然后再考虑去取值

4.2 解析嵌套的 Json 对象

加大一点难度,下面我们解析一个嵌套的 Json 对象,数据如下:

{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}
int main()
{char *s = "{\"list\":{\"name\":\"luffy\",\"age\":19},\"other\":{\"name\":\"ace\"}}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *js_list = cJSON_GetObjectItem(root, "list");if(!js_list) {printf("no list!\n");return -1;}printf("list type is %d\n",js_list->type);cJSON *name = cJSON_GetObjectItem(js_list, "name");if(!name) {printf("No name !\n");return -1;}printf("name type is %d\n",name->type);printf("name is %s\n",name->valuestring);cJSON *age = cJSON_GetObjectItem(js_list, "age");if(!age) {printf("no age!\n");return -1;}printf("age type is %d\n", age->type);printf("age is %d\n",age->valueint);cJSON *js_other = cJSON_GetObjectItem(root, "other");if(!js_other) {printf("no list!\n");return -1;}printf("list type is %d\n",js_other->type);cJSON *js_name = cJSON_GetObjectItem(js_other, "name");if(!js_name) {printf("No name !\n");return -1;}printf("name type is %d\n",js_name->type);printf("name is %s\n",js_name->valuestring);if(root){cJSON_Delete(root);}return 0;
}

打印结果:

list type is 6
name type is 4
name is luffy
age type is 3
age is 19
list type is 6
name type is 4
name is ace

4.3 解析 Json 数组

如果我们遇到的 Json 字符串是一个 Json 数组格式,处理方式和 Json 对象差不多,比如我们要解析如下字符串:

{\"names\":[\"luffy\",\"robin\"]}
int main(int argc, char **argv)
{char *s = "{\"names\":[\"luffy\",\"robin\"]}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *js_list = cJSON_GetObjectItem(root, "names");if(!js_list){printf("no list!\n");return -1;}int array_size = cJSON_GetArraySize(js_list);printf("array size is %d\n",array_size);for(int i=0; i< array_size; i++) {cJSON *item = cJSON_GetArrayItem(js_list, i);printf("item type is %d\n",item->type);printf("%s\n",item->valuestring);}if(root){cJSON_Delete(root);}return 0;
}

4.4 解析嵌套的 Json 对象和数组

对于 Json 字符串最复杂的个数莫过于 Json 对象和 Json 数组嵌套的形式,下面通过一个例子演示一下应该如何解析,字符串格式如下:

{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}

在解析的时候,我们只需要按照从属关系,一层层解析即可:

  • 根节点是一个 Json 对象,基于根节点中的 key 值取出对应的 value 值,得到一个 Json 数组

  • 读出 Json 数组的大小,遍历里边的各个元素,每个元素都是一个 Json 对象

  • 将 Json 对象中的键值对根据 key 值取出对应的 value 值

  • 从取出的 Value 值中读出实际类型对应的数值 示例代码如下:

#include "cJSON.h"
#include <stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{char *s = "{\"list\":[{\"name\":\"luffy\",\"age\":19},{\"name\":\"sabo\",\"age\":21}]}";cJSON *root = cJSON_Parse(s);if(!root) {printf("get root faild !\n");return -1;}cJSON *list = cJSON_GetObjectItem(root, "list");if(!list){printf("no list!\n");return -1;}int array_size = cJSON_GetArraySize(list);printf("array size is %d\n",array_size);for(int i=0; i< array_size; i++) {cJSON* item = cJSON_GetArrayItem(list, i);cJSON* name = cJSON_GetObjectItem(item, "name");printf("name is %s\n",name->valuestring);cJSON* age = cJSON_GetObjectItem(item, "age");printf("age is %d\n",age->valueint);}if(root){cJSON_Delete(root);}return 0;
}

相关文章:

嵌入式设备的 Json 库基本使用

大家好&#xff0c;今天给介绍一款基于 C 语言的轻量级的 Json 库 – cJson。可用于资源受限的嵌入式设备中。 cJSON 是一个超轻巧&#xff0c;携带方便&#xff0c;单文件&#xff0c;简单的可以作为 ANSI-C 标准的 JSON 解析器。 cJSON 是一个开源项目&#xff0c;github 下…...

GEEMAP 中如何拉伸图像

图像拉伸是最基础的图像增强显示处理方法&#xff0c;主要用来改善图像显示的对比度&#xff0c;地物提取流程中往往首先要对图像进行拉伸处理。图像拉伸主要有三种方式&#xff1a;线性拉伸、直方图均衡化拉伸和直方图归一化拉伸。 GEE 中使用 .sldStyle() 的方法来进行图像的…...

软件测试学术顶会——ISSTA 2023 论文(网络安全方向)清单、摘要与总结

总结 本次会议涵盖的安全研究主题广泛,包括源代码分析、二进制代码分析、恶意软件检测、漏洞检测、模糊测试、程序验证等。一些热门的研究方向包括:基于机器学习的漏洞检测、大型语言模型在软件安全中的应用、区块链智能合约安全分析。这些方向都在最近几年持续发展。一些较冷门…...

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…...

centos安装mysql8

检查是否有mariadb rpm -qa|grep mariadb rpm -e --nodeps mariadb-server安装mysql-8.0.31-el7-x86_64.tar.gz包 安装mysql-8.0.31-el7-x86_64.tar.gz包 cd datatar -xvf mysql-8.0.31-el7-x86_64.tar.gzmv mysql-8.0.31-el7-x86_64 mysql 依赖安装 报错解决&#xff0c;安…...

【Apollo】阿波罗自动驾驶技术:引领汽车行业革新

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…...

一文看懂!数据管道和数据流在数据分析中的作用

当我们谈论数据分析时&#xff0c;我们通常会想到一系列的步骤&#xff0c;包括数据收集、数据清洗、数据分析和数据可视化等。然而&#xff0c;在这些步骤中&#xff0c;有两个非常重要的概念&#xff1a;数据管道和数据流。这两个概念在数据分析过程中起着至关重要的作用。本…...

Linux系统下检验Tensorflow 2.xx版本和1.xx版本是否安装成功

目录 版本问题Tensorflow 1.xx的测试代码&#xff1a;Tensorflow 2.xx的测试代码&#xff1a;Tensorflow 2.6版本实际的测验结果 总结 版本问题 查询资料发现&#xff0c;多数检验Tensorflow是否安装成功的方法&#xff0c;多数方法都是1.xx版本的&#xff0c;直接使用1.xx版本…...

暑期高铁站大量遗失物品,FindMy帮助寻找

近日&#xff0c;一女子在上海坐高铁时&#xff0c;将户口本、房产证遗落安检处的新闻引起网友的关注。然后业内人士表示&#xff1a;常事&#xff0c;车站什么都能捡到。 据中国铁路透露&#xff0c;暑运期间&#xff0c;上海虹桥站客流增加&#xff0c;日均发送旅客20多万人…...

通过安全日志读取WFP防火墙放行日志

前言 之前的文档中&#xff0c;描写了如何对WFP防火墙进行操作以及如何在防火墙日志中读取被防火墙拦截网络通讯的日志。这边文档&#xff0c;着重描述如何读取操作系统中所有被放行的网络通信行为。 读取系统中放行的网络通信行为日志&#xff0c;在win10之后的操作系统上&am…...

JDK、JRE、Java SE、Java EE和Java ME有什么区别?

Java现在已不仅仅是一种语言&#xff0c;从广义上说&#xff0c;它代表了一个技术体系。该体系根据应用方向的不同主要分为Java SE、Java EE和Java ME的3个部分。 1.SE(JavaSE)&#xff0c;standard edition&#xff0c;标准版&#xff0c;是我们通常用的一个版本&#xff0c;从…...

Neo4j之unwind基础

UNWIND 语句在 Cypher 查询中用于将列表&#xff08;数组&#xff09;中的元素逐个“展开”&#xff0c;从而将每个元素视为单独的行进行处理。它通常与 MATCH、CREATE、MERGE 等语句结合使用&#xff0c;用于对列表中的每个元素执行相应的操作。以下是一些常用的示例和解释&am…...

回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现SSA-SVM麻雀搜索算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基…...

深入探索代理技术:Socks5、IP代理与网络安全

在当今高度互联的世界中&#xff0c;代理技术在网络安全和爬虫等领域发挥着重要作用。本文将着重介绍Socks5代理、IP代理以及它们在网络安全与爬虫开发中的应用&#xff0c;旨在帮助读者深入理解这些技术&#xff0c;从而更好地应用于实际情境。 1. Socks5代理的特点与用途 S…...

Matlab 频谱图中如何设置频率刻度

Matlab 频谱图中如何设置频率刻度&#xff08;横坐标&#xff09; 1、概述 时域信号经FFT 变换后得到了频谱&#xff0c;在作图时还必须设置正确的频率刻度&#xff0c;这样才能从图中得到正确的结果。下面来介绍如何设置正确的频率刻度。 2、案例分析 有一个余弦信号&#…...

在线转换器有哪些优势?在线Word转PDF操作分享

我们如果想要将两者不同格式文件进行格式转换&#xff0c;就需要下载安装转换器。如果出门带的设备没有安装转换软件客户端&#xff0c;就无法使用&#xff0c;会比较麻烦。现在有了在线转换工具&#xff0c;只需要打开相应的网页就可使用&#xff0c;那么在线Word转PDF的操作是…...

2023国赛数学建模A题思路模型代码汇总 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…...

vue3如何批量设置动态ref

示例如下&#xff1a; <template v-for"item in selectList"><el-select v-model"item.value" :ref"el > setRef(el, item)"><el-optionv-for"v in item.options":key"v.value":label"v.label"…...

Android Studio run app 设置 release 模式

背景 为验证我们的 SDK 集成在客户应用上的质量&#xff0c;需要我们的测试环境尽量的与客户应用保持一致。客户普遍都会打 release 包并混淆&#xff0c;然后进行上线应用&#xff0c;因此我们在测试过程中也需要使用 release 包进行验证。对于 Android Studio 运行项目&…...

【SA8295P 源码分析】41 - SA8295所有镜像位置、拷贝脚本、生成QFIL包

【SA8295P 源码分析】41 - SA8295所有镜像位置、拷贝脚本、生成QFIL包 一、SA8295 各镜像位置二、SA8295 QNX 侧镜像拷贝脚本三、SA8295 Android 侧镜像拷贝脚本四、使用QFIL 下载整包五、Fastboot 下载命令整理系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...