解码JSON

news/2025/11/26 21:43:46/文章来源:https://www.cnblogs.com/YouEmbedded/p/19261130

JSON 核心概念

JSON(JavaScript Object Notation)是 “JavaScript 对象表示法” 的简称,是一种轻量级数据交换文本格式,不依赖任何编程语言。它具有简洁清晰的层次结构,易于人类阅读编写,同时便于机器解析和生成,现已成为 Web 开发、跨平台应用间数据传输的主流格式。

JSON 数据格式

JSON 的核心数据结构只有两种,可相互嵌套组成复杂数据:

对象(无序键值对集合)

  • 用花括号{}包围,键值对以:分隔,多个键值对用,分隔。
  • 键必须是字符串(用双引号""包裹),值可是任意合法 JSON 类型。
  • 示例(修正原文档键名重复错误):
{"name": "lmx",       // 值类型:字符串"age": 29,           // 值类型:整型"score": [           // 值类型:数组(元素为对象){"math": 85.5,    // 值类型:浮点型"english": 92    // 值类型:整型}]
}

数组(有序值集合)

  • 用方括号[]包围,多个值用,分隔。
  • 数组中的值可是任意合法 JSON 类型,包括对象和数组。
  • 示例:
["apple", "banana", 100, true, null, {"city": "Beijing"}]

合法值类型

  • 字符串(双引号包裹,不可用单引号)
  • 数值(整型、浮点型,无引号)
  • 布尔值(truefalse,小写)
  • 空值(null,小写)
  • 对象({}包裹的键值对集合)
  • 数组([]包裹的值集合)

cJSON 库介绍

cJSON 是基于 C 语言的轻量级 JSON 解析 / 构造库,开源且跨平台(兼容 C89 标准),适用于嵌入式开发等场景。

获取与使用

  • 下载地址:https://github.com/DaveGamble/cJSON
  • 核心文件:仅需cJSON.c(实现文件)和cJSON.h(头文件),直接复制到项目中即可使用。
  • 编译方式:将cJSON.c与项目源码一起编译(如gcc main.c cJSON.c -o main)。

核心结构体(cJSON)

用于存储 JSON 数据的树形结构节点,每个节点对应一个 JSON 值:

/*** cJSON核心结构体,存储单个JSON节点数据* @brief 构成JSON树形结构的基本单元,每个节点对应一个JSON值(字符串、数字、对象等)* @param next 链表下一个节点指针(用于遍历数组/对象的子节点)* @param prev 链表上一个节点指针(用于双向遍历)* @param child 子节点指针(对象/数组类型节点的子元素链表头)* @param type 节点类型(如cJSON_String、cJSON_Number、cJSON_Object等)* @param valuestring 字符串类型值(仅type为cJSON_String或cJSON_Raw时有效)* @param valueint 整型值(type为cJSON_Number时有效,建议用cJSON_SetNumberValue设置)* @param valuedouble 浮点型值(type为cJSON_Number时有效)* @param string 节点名称(仅当节点是对象的子节点时有效,即键名)*/
typedef struct cJSON {struct cJSON *next;struct cJSON *prev;struct cJSON *child;int type;char *valuestring;int valueint;double valuedouble;char *string;
} cJSON;

JSON 解析流程(cJSON 实现)

解析流程:获取 JSON 字符串 → 解析为 cJSON 树形结构 → 提取数据 → 释放资源

关键函数

解析 JSON 字符串

/*** 解析JSON格式字符串为cJSON树形结构* @brief 将零终止的JSON字符串转换为cJSON结构体指针,后续可通过该指针遍历提取数据* @param string 输入的JSON格式字符串(必须零终止,格式合法)* @return cJSON* 成功返回指向cJSON树形结构根节点的指针,失败返回NULL* @note 解析成功后需调用cJSON_Delete释放内存,避免内存泄漏*       若JSON字符串格式错误(如括号不匹配、键未用双引号),返回NULL*/
cJSON *cJSON_Parse(const char *string);

调试输出 JSON

/*** 将cJSON树形结构转换为格式化的JSON字符串* @brief 用于调试验证解析结果,生成易读的JSON字符串* @param json 指向cJSON树形结构根节点的指针* @return char* 成功返回动态分配的JSON字符串,失败返回NULL* @note 返回的字符串需手动用free释放,否则会造成内存泄漏*       生成的字符串包含换行和缩进,便于人类阅读*/
char *cJSON_Print(const cJSON *json);

获取对象中的键值对

/*** 从JSON对象中获取指定键名的子节点(不区分大小写)* @brief 用于提取对象类型节点中某个键对应的值节点* @param object 指向JSON对象节点的指针(type必须为cJSON_Object)* @param string 要查找的键名(字符串)* @return cJSON* 成功返回对应值节点的指针,失败返回NULL* @note 若对象中无该键,或传入的节点不是对象类型,返回NULL*       区分大小写版本可用cJSON_GetObjectItemCaseSensitive*/
cJSON *cJSON_GetObjectItem(const cJSON *const object, const char *const string);

获取数组信息

/*** 获取JSON数组的元素个数* @brief 用于确定数组节点中包含的子元素数量* @param array 指向JSON数组节点的指针(type必须为cJSON_Array)* @return int 成功返回数组元素个数,失败返回0* @note 若传入的节点不是数组类型,返回0*/
int cJSON_GetArraySize(const cJSON *array);/*** 获取数组中指定索引的元素节点* @brief 按索引遍历数组,提取对应位置的子节点* @param array 指向JSON数组节点的指针(type必须为cJSON_Array)* @param index 元素索引(从0开始)* @return cJSON* 成功返回对应索引的元素节点指针,失败返回NULL* @note 索引超出数组范围(>=元素个数)时返回NULL*/
cJSON *cJSON_GetArrayItem(const cJSON *array, int index);

释放资源

/*** 释放cJSON树形结构占用的内存* @brief 递归释放整个cJSON链表的内存,包括所有子节点* @param item 指向cJSON树形结构根节点的指针* @return void 无返回值* @note 必须在解析完成后调用,否则会造成严重内存泄漏*       仅需传入根节点指针,会自动递归释放所有子节点*/
void cJSON_Delete(cJSON *item);

完整解析示例(解析天气 API 响应)

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"int main() {// 假设这是从API获取的JSON字符串const char *json_str = "{""\"results\": [""{""\"path\": \"Beijing, Beijing, China\",""\"timezone\": \"Asia/Shanghai\",""\"timezone_offset\": \"+08:00\",""\"txt\": \"sunny\",""\"code\": \"0\",""\"temperature\": \"32\",""\"last_update\": \"2024-06-11T11:27:51+08:00\"""},""{""\"path\": \"Shanghai, Shanghai, China\",""\"timezone\": \"Asia/Shanghai\",""\"timezone_offset\": \"+08:00\",""\"txt\": \"cloudy\",""\"code\": \"1\",""\"temperature\": \"28\",""\"last_update\": \"2024-06-11T11:27:51+08:00\"""}""]""}";// 解析JSONcJSON *root = cJSON_Parse(json_str);if (root == NULL) {printf("JSON解析失败:%s\n", cJSON_GetErrorPtr());return -1;}// 获取results数组cJSON *results_array = cJSON_GetObjectItem(root, "results");if (results_array == NULL || !cJSON_IsArray(results_array)) {printf("未找到results数组\n");cJSON_Delete(root);return -1;}// 使用 cJSON_ArrayForEach 宏遍历数组// 宏的参数:当前元素节点指针, 数组节点指针cJSON *weather_obj;cJSON_ArrayForEach(weather_obj, results_array) {// 提取基础类型值cJSON *city = cJSON_GetObjectItem(weather_obj, "path");cJSON *weather = cJSON_GetObjectItem(weather_obj, "txt");cJSON *temp = cJSON_GetObjectItem(weather_obj, "temperature");cJSON *update_time = cJSON_GetObjectItem(weather_obj, "last_update");// 输出提取的信息if (city && cJSON_IsString(city) && weather && cJSON_IsString(weather) &&temp && cJSON_IsString(temp) && update_time && cJSON_IsString(update_time)) {printf("\n城市:%s\n", city->valuestring);printf("天气:%s\n", weather->valuestring);printf("温度:%s℃\n", temp->valuestring);printf("最后更新时间:%s\n", update_time->valuestring);}}// 释放资源cJSON_Delete(root);return 0;
}

JSON 构造流程(cJSON 实现)

构造流程:创建根对象 → 添加子节点 / 键值对 → 生成 JSON 字符串 → 释放资源

关键构造函数

/*** 创建JSON对象节点(对应{})* @brief 生成一个空的JSON对象节点,作为树形结构的根或子对象* @return cJSON* 成功返回对象节点指针,失败返回NULL* @note 需配合cJSON_AddItemToObject等函数添加键值对*/
cJSON *cJSON_CreateObject(void);/*** 创建JSON数组节点(对应[])* @brief 生成一个空的JSON数组节点* @return cJSON* 成功返回数组节点指针,失败返回NULL* @note 需配合cJSON_AddItemToArray等函数添加元素*/
cJSON *cJSON_CreateArray(void);/*** 创建字符串类型节点* @brief 生成存储指定字符串的JSON节点* @param string 要存储的字符串(零终止)* @return cJSON* 成功返回字符串节点指针,失败返回NULL*/
cJSON *cJSON_CreateString(const char *string);/*** 创建数值类型节点* @brief 生成存储指定浮点型数值的JSON节点(支持整型和浮点型)* @param num 要存储的数值(整型可直接传入,自动转换为double)* @return cJSON* 成功返回数值节点指针,失败返回NULL*/
cJSON *cJSON_CreateNumber(double num);/*** 向JSON对象添加键值对* @brief 将子节点作为指定键的值,添加到对象节点中* @param object 目标对象节点指针* @param string 键名(字符串)* @param item 要添加的子节点指针(任意JSON类型节点)* @return void 无返回值* @note 子节点的内存由cJSON管理,无需手动释放*/
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);/*** 向JSON数组添加元素* @brief 将子节点添加到数组节点的末尾* @param array 目标数组节点指针* @param item 要添加的子节点指针(任意JSON类型节点)* @return void 无返回值*/
void cJSON_AddItemToArray(cJSON *array, cJSON *item);

完整构造示例

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {// 创建顶层对象(根节点)cJSON *root = cJSON_CreateObject();if (root == NULL) {printf("创建根对象失败\n");return -1;}// 向根对象添加基础类型键值对cJSON_AddItemToObject(root, "name", cJSON_CreateString("zhangsan"));cJSON_AddItemToObject(root, "age", cJSON_CreateNumber(25));cJSON_AddItemToObject(root, "is_student", cJSON_CreateBool(0)); // false// 创建数组并添加元素cJSON *hobbies = cJSON_CreateArray();cJSON_AddItemToArray(hobbies, cJSON_CreateString("reading"));cJSON_AddItemToArray(hobbies, cJSON_CreateString("coding"));cJSON_AddItemToArray(hobbies, cJSON_CreateString("hiking"));// 将数组添加到根对象cJSON_AddItemToObject(root, "hobbies", hobbies);// 创建嵌套对象并添加cJSON *address = cJSON_CreateObject();cJSON_AddItemToObject(address, "province", cJSON_CreateString("Guangdong"));cJSON_AddItemToObject(address, "city", cJSON_CreateString("Shenzhen"));cJSON_AddItemToObject(address, "detail", cJSON_CreateString("Nanshan District"));// 将嵌套对象添加到根对象cJSON_AddItemToObject(root, "address", address);// 生成JSON字符串(格式化输出)char *json_str = cJSON_Print(root);if (json_str == NULL) {printf("生成JSON字符串失败\n");cJSON_Delete(root);return -1;}printf("构造的JSON:\n%s\n", json_str);// 释放资源free(json_str);cJSON_Delete(root);return 0;
}

输出:

构造的JSON:
{"name": "zhangsan","age":  25,"is_student":   false,"hobbies":      ["reading", "coding", "hiking"],"address":      {"province":     "Guangdong","city": "Shenzhen","detail":       "Nanshan District"}
}

实战练习:调用聚合天气 API 解析 JSON

核心步骤

  • 申请聚合天气 API 接口,获取 API 密钥。
  • 用 C 语言通过 HTTP 协议发送请求(如使用 libcurl 库),获取 JSON 格式的响应数据。
  • 用 cJSON 库解析响应数据,提取城市、天气、温度、风力等信息。
  • 将提取的信息输出到终端。

方式一:HTTP 请求实现(基于 libcurl)

需安装 libcurl 库(sudo apt-get install libcurl4-openssl-dev),编译时链接(gcc main.c cJSON.c -o main -lcurl):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "cJSON.h" /*** @brief 用于存储动态增长的响应数据的结构体*/
typedef struct {char *data;size_t size;
} ResponseBuffer;/*** @brief libcurl 的回调函数,用于接收 HTTP 响应数据* * @param ptr 指向接收到的数据的指针* @param size 每个数据块的大小(单位:字节)* @param nmemb 数据块的数量* @param userdata 用户自定义数据,这里是 ResponseBuffer 结构体指针* @return size_t 实际处理的数据大小(通常是 size * nmemb)*/
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {size_t realsize = size * nmemb;ResponseBuffer *buffer = (ResponseBuffer *)userdata;// 重新分配内存,为新数据腾出空间char *temp = (char *)realloc(buffer->data, buffer->size + realsize + 1);if (temp == NULL) {// 内存分配失败,这是一个严重错误fprintf(stderr, "Failed to allocate memory in write_callback\n");return 0; }buffer->data = temp;// 将新数据复制到缓冲区末尾memcpy(&(buffer->data[buffer->size]), ptr, realsize);buffer->size += realsize;// 确保字符串以 null 字符结尾buffer->data[buffer->size] = '\0';return realsize;
}/*** @brief 发送 HTTP GET 请求并返回响应体的 JSON 字符串* * @param url 请求的 URL* @return char* 成功则返回动态分配的 JSON 字符串,失败则返回 NULL*/
char *get_weather_json(const char *url) {CURL *curl;CURLcode res;ResponseBuffer buffer = {0}; // 初始化缓冲区// 全局初始化 libcurl (建议在程序开始时调用一次)curl_global_init(CURL_GLOBAL_DEFAULT);// 初始化一个 curl 会话curl = curl_easy_init();if (!curl) {fprintf(stderr, "curl_easy_init() failed\n");curl_global_cleanup();return NULL;}// 设置 curl 选项curl_easy_setopt(curl, CURLOPT_URL, url);// 设置回调函数和用户数据curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buffer);// 执行请求res = curl_easy_perform(curl);if (res != CURLE_OK) {fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));free(buffer.data); // 释放已分配的内存buffer.data = NULL;}// 清理 curl 会话curl_easy_cleanup(curl);// 全局清理 libcurl (建议在程序结束时调用一次)curl_global_cleanup();// 返回响应数据(调用者需要负责 free)return buffer.data;
}int main() {// !!! 重要:请替换为你的聚合数据 API 密钥 !!!const char *api_key = "你的API密钥";const char *city = "Beijing";char api_url[256];// 构建完整的 API 请求 URLsnprintf(api_url, sizeof(api_url), "http://v.juhe.cn/tianqi/query?city=%s&key=%s", city, api_key);printf("正在请求天气数据...\nURL: %s\n", api_url);// 调用函数获取 JSON 字符串char *json_str = get_weather_json(api_url);if (json_str == NULL) {fprintf(stderr, "获取天气数据失败\n");return 1;}printf("\n成功获取到 JSON 数据:\n%s\n", json_str);// --- 使用 cJSON 解析 JSON 数据 ---cJSON *root = cJSON_Parse(json_str);if (root == NULL) {const char *error_ptr = cJSON_GetErrorPtr();if (error_ptr != NULL) {fprintf(stderr, "JSON 解析失败: %s\n", error_ptr);}free(json_str); // 释放 JSON 字符串return 1;}// 检查返回状态cJSON *error_code = cJSON_GetObjectItem(root, "error_code");if (error_code && error_code->valueint != 0) {cJSON *reason = cJSON_GetObjectItem(root, "reason");fprintf(stderr, "API 请求失败: %s (错误码: %d)\n", reason ? reason->valuestring : "未知错误", error_code->valueint);cJSON_Delete(root);free(json_str);return 1;}// 获取 results 数组cJSON *results_array = cJSON_GetObjectItem(root, "result");if (results_array == NULL || !cJSON_IsArray(results_array)) {printf("未找到 'result' 数组\n");cJSON_Delete(root);free(json_str);return 1;}// 使用 cJSON_ArrayForEach 宏遍历数组cJSON *weather_obj;cJSON_ArrayForEach(weather_obj, results_array) {cJSON *city_name = cJSON_GetObjectItem(weather_obj, "city");cJSON *weather = cJSON_GetObjectItem(weather_obj, "weather");cJSON *temperature = cJSON_GetObjectItem(weather_obj, "temperature");cJSON *humidity = cJSON_GetObjectItem(weather_obj, "humidity");cJSON *wind = cJSON_GetObjectItem(weather_obj, "wind");cJSON *update_time = cJSON_GetObjectItem(weather_obj, "update_time");// 打印提取的信息printf("\n--------------------\n");printf("城市: %s\n", city_name ? city_name->valuestring : "N/A");printf("天气: %s\n", weather ? weather->valuestring : "N/A");printf("温度: %s\n", temperature ? temperature->valuestring : "N/A");printf("湿度: %s\n", humidity ? humidity->valuestring : "N/A");printf("风向: %s\n", wind ? wind->valuestring : "N/A");printf("更新时间: %s\n", update_time ? update_time->valuestring : "N/A");}// --- 释放所有资源 ---cJSON_Delete(root); // 释放 cJSON 对象树free(json_str);     // 释放从 get_weather_json 返回的字符串return 0;
}

方式二:popen 调用 curl 命令,并通过 fread 读取其输出

#include <stdio.h>
#include <stdlib.h>
#include <string.h>/*** @brief 使用 popen 和 curl 命令获取 HTTP 响应* * @param url 请求的 URL 地址* @return char* 成功则返回动态分配的响应字符串,失败则返回 NULL*/
char *get_weather_json_with_popen(const char *url) {if (url == NULL) {return NULL;}// 构建 curl 命令// -s: 静默模式,不显示进度条等额外信息// "%s": 要请求的 URLchar command[1024];int ret = snprintf(command, sizeof(command), "curl -s \"%s\"", url);if (ret < 0 || ret >= sizeof(command)) {fprintf(stderr, "命令字符串太长,可能会被截断。\n");return NULL;}// 使用 popen 执行命令,并以只读方式打开管道FILE *fp = popen(command, "r");if (fp == NULL) {perror("popen 失败");return NULL;}// 读取管道内容// 使用动态缓冲区来存储读取的数据char *response = NULL;size_t buffer_size = 1024; // 初始缓冲区大小size_t total_bytes_read = 0;// 初始分配内存response = (char *)malloc(buffer_size);if (response == NULL) {perror("malloc 失败");pclose(fp);return NULL;}response[0] = '\0'; // 确保初始为空字符串char chunk[256];size_t bytes_read;printf("正在通过 curl 命令获取数据...\n");// 循环读取,直到文件结束while ((bytes_read = fread(chunk, 1, sizeof(chunk) - 1, fp)) > 0) {// 确保 chunk 是一个以 null 结尾的字符串,方便 strcatchunk[bytes_read] = '\0';// 检查缓冲区是否足够容纳新读取的数据if (total_bytes_read + bytes_read >= buffer_size - 1) { // 预留一个字节给 null 结束符buffer_size *= 2; // 翻倍扩容char *temp = (char *)realloc(response, buffer_size);if (temp == NULL) {perror("realloc 失败");free(response);pclose(fp);return NULL;}response = temp;}// 将新读取的数据追加到响应字符串末尾strcat(response, chunk);total_bytes_read += bytes_read;}// 检查 fread 是否因为错误而退出if (ferror(fp)) {perror("fread 失败");free(response);response = NULL;}// 关闭管道// pclose 会等待子进程 (curl) 结束并回收其资源if (pclose(fp) == -1) {perror("pclose 失败");// 即使 pclose 失败,我们也已经读取了数据,所以可以选择返回它// 这里为了简化,我们在发生任何错误时都返回 NULLfree(response);response = NULL;}return response;
}int main() {// !!! 重要:请替换为你的聚合数据 API 密钥 !!!const char *api_key = "你的API密钥";const char *city = "Beijing";char api_url[256];// 构建完整的 API 请求 URLsnprintf(api_url, sizeof(api_url), "http://v.juhe.cn/tianqi/query?city=%s&key=%s", city, api_key);// 调用函数获取 JSON 字符串char *json_str = get_weather_json_with_popen(api_url);if (json_str == NULL) {fprintf(stderr, "获取天气数据失败\n");return 1;}printf("成功获取到 JSON 数据:\n%s\n", json_str);// 在这里可以继续使用 cJSON 解析 json_str ...// ...// 释放动态分配的内存free(json_str);return 0;
}

拓展:Base64 编码 + 百度 AI 物体识别 API 实战

Base64 编码核心规则

Base64 是一种基于 64 个可打印字符的编码方式,用于将二进制数据转换为文本格式(便于 HTTP 传输):

  • 编码表:A-Z(0-25)、a-z(26-51)、0-9(52-61)、+(62)、/(63)。
  • 编码原理:3 个字节(24 位)拆分为 4 个 6 位组,每个 6 位组对应编码表中的一个字符。
  • 不足 3 字节处理:缺 1 字节补 2 个=,缺 2 字节补 1 个=

图片转 Base64 编码(C 语言实现)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Base64编码表
const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";// 将图片文件转换为Base64字符串
char *image_to_base64(const char *img_path) {// 读取图片二进制数据FILE *fp = fopen(img_path, "rb");if (!fp) return NULL;fseek(fp, 0, SEEK_END);long img_size = ftell(fp);fseek(fp, 0, SEEK_SET);unsigned char *img_data = malloc(img_size);fread(img_data, 1, img_size, fp);fclose(fp);// 计算Base64字符串长度long base64_len = (img_size + 2) / 3 * 4;char *base64_str = malloc(base64_len + 1);memset(base64_str, 0, base64_len + 1);// 编码核心逻辑for (long i = 0, j = 0; i < img_size; i += 3, j += 4) {// 取3个字节unsigned char byte1 = i < img_size ? img_data[i] : 0;unsigned char byte2 = i+1 < img_size ? img_data[i+1] : 0;unsigned char byte3 = i+2 < img_size ? img_data[i+2] : 0;// 拆分为4个6位组unsigned int triple = (byte1 << 16) | (byte2 << 8) | byte3;base64_str[j] = base64_table[(triple >> 18) & 0x3F];base64_str[j+1] = base64_table[(triple >> 12) & 0x3F];base64_str[j+2] = i+1 < img_size ? base64_table[(triple >> 6) & 0x3F] : '=';base64_str[j+3] = i+2 < img_size ? base64_table[triple & 0x3F] : '=';}free(img_data);return base64_str;
}

调用百度 AI 物体识别 API

  • 百度 AI 开放平台申请 “物体识别” API,获取 API Key 和 Secret Key,生成访问令牌(Access Token)。
  • 将图片 Base64 编码字符串构造为 JSON 请求体:
{"image": "图片的Base64编码(去掉前缀data:image/jpg;base64,)","image_type": "BASE64"
}
  • 用 HTTP POST 请求发送 JSON 数据,接收响应后用 cJSON 解析识别结果(如物体名称、置信度等)。

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

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

相关文章

项目启动

Vue3 大屏可视化平台项目启动 快速启动 开发模式 npm run dev启动后访问 http://localhost:3000 使用脚本快速启动(Windows): # 使用批处理文件 start.bat# 或使用 PowerShell start.ps1生产构建 npm run build构建…

11/26

今天满课,好累

2025-11-26

CF 构造(1300) Problem - 1867C - Codeforces(交互) #include <bits/stdc++.h> using namespace std; #define LL long long const LL mod = 998244353; const int N=2e5+10; int a[N];void solve() {int n;…

关于生育问题的初步看法

生育问题,即现代社会面对的,结婚率、生育率逐渐或断崖式下降的现象。 个人看法,生育问题已经涉及到现代社会的根基,即资本。 无论是工业时代的工业化、还是现代社会金融爆发,本质都是资本的不断升级,而资本升级能…

游戏立项games-stats,查询游戏tag的销量,以卡牌游戏举例

有这样一个网站叫,https://games-stats.com/ 这个网站可以查询steam上面的不同的游戏tag,他们的中位数销量是如何的 进去这个网站,然后按照如图的点击方式 首先 Games Count 数量是小于1000的,就不用看了,一般是一…

深入解析:Vue2.x + Webpack + ES6仿懂球帝足球项目实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年11月砝码,无磁不锈钢砝码,定制砝码厂家推荐:行业权威盘点与品质红榜发布

引言在全球工业生产与科研实验中,砝码作为重要的计量器具,其精度和质量直接影响着测量结果的准确性。为了能为广大用户筛选出优质的砝码厂家,国际知名的计量协会开展了一场全面且严格的测评活动。本次测评综合考量了…

2025年11月不锈钢砝码,无磁不锈钢砝码,挂钩砝码厂家推荐,高精度与可靠性兼具的优质品牌

引言在全球工业生产、科研实验以及质量检测等众多领域,砝码作为重要的计量器具,其精度和质量至关重要。为了能给广大用户筛选出优质的砝码厂家,国际知名的计量协会开展了一场严谨且全面的测评活动。该协会采用了多维…

上下文无关文法序列

import torch import torch.nn as nn import torch.optim as optim import numpy as np def generate_data(num_samples): data = [] for _ in range(num_samples): n = 30 # 固定n为30 seq = [0]n + [1]n data.appen…

生产事故救火指南:Kafka 消息积压了怎么办?如何保证数据一条不丢?

生产事故救火指南:Kafka 消息积压了怎么办?如何保证数据一条不丢?生产事故救火指南:Kafka 消息积压了怎么办?如何保证数据一条不丢?摘要:在大数据与微服务架构中,消息队列(MQ)是血管,数据是血液。但血管会堵…

ARCGIS Pro 绘图技巧——水文站的尖尖垂直于河流的水流方向

一、目标:把水文站的图标设置为随河流流向变化二、实现方法思路 1、把河流截断成尽量短的河段 2、计算各小河段的“线段平均方向” 3、对水文站、各小河段进行空间邻近分析,进行就近匹配 4、根据匹配结果进行属性表链…

优美的字符串

Problem Description 小X对字符串十分感兴趣。 对于一个只有0和1的字符串S,小X称其为优美的,当且仅当这个字符串最终可以通过不断的做下面的操 作变成"1":选择一个奇数 \(i(3 \le i \le |S|)\)。 将字符串…

【普中Hi3861开发攻略--基于鸿蒙OS】-- 第 31 章 WIFI 实验-华为 IoTDA 设备接入 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年11月不锈钢砝码,铸铁砝码,定制砝码厂家推荐,实力品牌深度解析采购无忧之选!

引言在全球工业生产与科研实验领域,砝码作为关键的计量器具,其精度与质量直接影响着各类测量结果的准确性。为了给全球用户提供客观、公正的砝码厂家参考,国际权威计量协会开展了一项全面的测评活动。该协会联合了多…

OpenHarmony与ArkUI-X的跨平台开发环境搭建细节版

OpenHarmony与ArkUI-X的跨平台开发环境搭建细节版 安装所有一切东西, 尽可能安装在英文路径位置下, 尽可能使用默认路径位置, 尽可能使用英文账户名,这样默认安装时,路径就符合上述要求,可以避免奇奇怪怪的问题 正…

五分钟教你学会MarkDown语法 - echo

MarkDown语法 推荐文本编辑器:Typora 文件后缀 xxx.md 标题 使用一个#号加空格就是一级标题 一级标题 使用两个#号加空格是二级标题 二级标题 以此类推三个#号就是三级标题甚至更多 字体样式使用 * 号可以实现字体的加…

Linux命令行与Shell脚本编程大全笔记

Linux命令行与Shell脚本编程大全笔记Linux Linux可划分为四部分: 1. Linux内核 2. GNU工具 3. 图形化桌面环境 4. 应用软件 Linux系统的核心是内核。内核控制着计算机系统上的所有硬件和软件,在必要时分配硬件, 并根…

OpenHarmony与ArkUI-X的跨平台开发环境搭建速通版

OpenHarmony与ArkUI-X的跨平台开发环境搭建速通版 ‍ 该文档于时间20251125编写, 是Windows端, 特定版本的OpenHarmony使用ArkUI-X框架跨平台开发 默认会了一些基础常识,直接操作不解释,有需要看详细版 默认会了一…

卷积神经网络的引入4 —— 局部扰动与空间结构破坏下的鲁棒性验证

在前三篇文章中,我们依次验证了:CNN 对平移等空间扰动具有天然优势 在低维灰度图(Fashion-MNIST)上,CNN 与 MLP 差距有限 在中等复杂度数据集(CIFAR-10)上,差距迅速拉大到这里,一个重要问题浮现:CNN 的优势到…

qoj 2610 题解

题意 给你 \(n\) 个二维平面上的点,初始你有一个位于 \((0, 0)\) 的退化矩形。每次你可以选择一个点,并将矩形扩张(长、宽不能减小)使得矩形包含这个点,代价为新矩形相对于原矩形多出来的那部分。你需要判断有没有…