C 语言面向对象
面向对象的基本特性:封装,继承,多态
1.0 面向过程概念
当我们在编写程序时,通常采用以下步骤:
2.0 程序案例
#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>struct student
{int id;char name[20];int gender;int mark;
};int MakeStudentId(int year, int classNum, int serialNum)
{// 创建一个char类型的数组char buffer[20];// 将三个变量转换为指定格式的字符串,存储在buffer数组中sprintf(buffer, "%d%d%d", year, classNum, serialNum);// 将字符串转换为整数int id = atoi(buffer);// 返回项目的id值return id;
}const char* NumGenderToStrGender(int numGender)
{if (numGender == 0){return "女";}else if (numGender == 1){return "男";}return "NULL";
}int StrGenderToNumGender(const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}return numGender;
}int main()
{// 创建结构体变量struct student stu;stu.id = MakeStudentId(2024, 123, 26);strcpy(stu.name, "小明");stu.gender = StrGenderToNumGender("男");stu.mark = 98;printf("学号:%d\n", stu.id);printf("姓名: %s\n", stu.name);const char* gender = NumGenderToStrGender(stu.gender);printf("性别:%s\n", gender);printf("分数:%s\n", stu.mark);return 0;} 3.0 面向对象
成员id的表示方式:

1. 将函数的第一个参数设置为 struct student * ,让函数直接操作 student 结构体。
4.0 封装特性
typedef struct
{int id;char name[20];int gender;int mark;
}StudentInfo_t;
注:将需要的信息封装为一个结构体内部包含学生的姓名,学号,性别,分数。
通过函数设置学生的id编号,函数可以通过结构体指针,直接操作结构体中的数据
void SetStudentId(StudentInfo_t* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->id = id;
} 获取学生的性别函数,在面向对象的编程方法中获取数据的函数被我们设置为GetXXX,设置数据的函数被我们设置为SetXXX。
const char* GetGender(StudentInfo_t* s)
{if (s->gender == 0){return "女";}else if (s->gender == 1){return "男";}return "未知";
} 设置数据的方法
void SetGender(StudentInfo_t* s, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}s->gender = numGender;
} 通过主函数进行调用
int main()
{StudentInfo_t stu;SetStudentId(&stu, 2022, 123, 26);strcpy(stu.name, "小明");SetGender(&stu, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.id);printf("姓名:%s\n", stu.name);const char* gender = GetGender(&stu);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);
} 完整函数代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>typedef struct
{int id;char name[20];int gender;int mark;
}StudentInfo_t;void SetStudentId(StudentInfo_t* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->id = id;
}const char* GetGender(StudentInfo_t* s)
{if (s->gender == 0){return "女";}else if (s->gender == 1){return "男";}return "未知";
}void SetGender(StudentInfo_t* s, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}s->gender = numGender;
}int main()
{StudentInfo_t stu;SetStudentId(&stu, 2022, 123, 26);strcpy(stu.name, "小明");SetGender(&stu, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.id);printf("姓名:%s\n", stu.name);const char* gender = GetGender(&stu);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);
} 对象.方法(对象指针,参数1,参数2, 参数3...) stu.setGender(&stu, "男"); const char* gender = stu.getGender(&stu); 5.0 面向对象
在结构体中声明函数指针
struct student {void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);int id; // 学号char name[20]; // 姓名int gender; // 性别int mark; // 分数
}; 这个时候可以将结构体作为一个对象看待,使用对象(结构体变量). 方法(函数)的方式进行参数的赋值和调用。
生成学生的id
void setStudentId(struct student* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->id = id;
} 获取学生的性别
const char* getGender(struct student* s)
{if (s->gender == 0){return "女";}else if (s->gender == 1){return "男";}return "未知";
} 设置学生的性别
void setGender(struct student* s, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}s->gender = numGender;
} 初始化函数指针【对象初始化之后才能被调用】
void initStudent(struct student* s)
{s->setStudentId = setStudentId;s->getGender = getGender;s->setGender = setGender;
} 主函数相关代码
int main()
{struct student stu;// 初始化studentinitStudent(&stu);stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.name, "小明");stu.setGender(&stu, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.id);printf("姓名:%s\n", stu.name);const char* gender = stu.getGender(&stu);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);
} 完整代码
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct student {void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);int id; // 学号char name[20]; // 姓名int gender; // 性别int mark; // 分数
};void setStudentId(struct student* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->id = id;
}const char* getGender(struct student* s)
{if (s->gender == 0){return "女";}else if (s->gender == 1){return "男";}return "未知";
}void setGender(struct student* s, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}s->gender = numGender;
}void initStudent(struct student* s)
{s->setStudentId = setStudentId;s->getGender = getGender;s->setGender = setGender;
}int main()
{struct student stu;// 初始化studentinitStudent(&stu);stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.name, "小明");stu.setGender(&stu, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.id);printf("姓名:%s\n", stu.name);const char* gender = stu.getGender(&stu);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);
} 6.0 继承基本概念
- 工号
- 姓名
- 性别
- 任课科目
struct teacher
{int id; // 工号char name[20]; // 姓名int gender; // 性别char subject[20]; // 任课科目
}; struct teacher {int id; // 工号char name[20]; // 姓名int gender; // 性别char subject[20]; // 任课科目
};
struct student {int id; // 学号char name[20]; // 姓名int gender; // 性别int mark; // 分数
}; - 编号
- 姓名
- 性别
- 学生有考试分数
- 老师有任课科目
struct person{int id; // 编号char name[20]; // 姓名int gender; // 性别
}; struct teacher {struct person super;char subject[20]; // 任课科目
};
struct student {struct person super;int mark; // 分数
}; // 原有代码
struct teacher {int id; // 工号char name[20]; // 姓名int gender; // 性别char subject[20]; // 任课科目
};
struct student {int id; // 学号char name[20]; // 姓名int gender; // 性别int mark; // 分数
};
// 现有代码
struct person{int id; // 编号char name[20]; // 姓名int gender; // 性别
};
struct teacher {struct person super;char subject[20]; // 任课科目
};
struct student {struct person super;int mark; // 分数
}; - 1. 减少重复代码
- 2. 代码层次更清晰

刚刚我们只讨论了数据,现在我们结合上方法一起讨论
struct person{int id; // 编号char name[20]; // 姓名int gender; // 性别
};
struct teacher {struct person super;char subject[20]; // 任课科目
};
struct student {struct person super;int mark; // 分数void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);
}; - 设置性别
- 获取性别
- 设置学号
创建一个Person方法,内部包含
struct person
{int id;char name[20];int gender;const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);
};struct teacher
{// 创建结构体成员变量struct person super;char subject[20];
};struct student {void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);struct person super;int mark; // 分数
}; const char* getGender(struct person* p)
{if (p->gender == 0){return "女";}else if (p->gender == 1){return "男";}return "未知";
}void setGender(struct person* p, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}p->gender = numGender;
} void setStudentId(struct student* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->super.id = id;
} void initPerson(struct person* p)
{p->getGender = getGender;p->setGender = setGender;
}void initStudent(struct student* s)
{initPerson(&(s->super));s->setStudentId = setStudentId;
}void initTeacher(struct teacher* t)
{initPerson(&(t->super));
} main函数调用
int main()
{struct student stu;// 初始化studentinitStudent(&stu);stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.super.name, "小明");stu.super.setGender(&stu.super, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.super.id);printf("姓名:%s\n", stu.super.name);const char* gender = stu.super.getGender(&stu.super);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);putchar('\n');struct teacher t;// 初始化teacherinitTeacher(&t);t.super.id = 12345;strcpy(t.super.name, "林老师");t.super.setGender(&t.super, "男");strcpy(t.subject, "C语言");// 打印这些数值printf("学号:%d\n", t.super.id);printf("姓名:%s\n", t.super.name);gender = t.super.getGender(&t.super);printf("性别:%s\n", gender);printf("科目:%s\n", t.subject);
} 完整代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct person
{int id;char name[20];int gender;const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);
};struct teacher
{// 创建结构体成员变量struct person super;char subject[20];
};struct student {void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);struct person super;int mark; // 分数
};void setStudentId(struct student* s, int year, int classNum, int serialNum)
{char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->super.id = id;
}const char* getGender(struct person* p)
{if (p->gender == 0){return "女";}else if (p->gender == 1){return "男";}return "未知";
}void setGender(struct person* p, const char* strGender)
{int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}p->gender = numGender;
}void initPerson(struct person* p)
{p->getGender = getGender;p->setGender = setGender;
}void initStudent(struct student* s)
{initPerson(&(s->super));s->setStudentId = setStudentId;
}void initTeacher(struct teacher* t)
{initPerson(&(t->super));
}int main()
{struct student stu;// 初始化studentinitStudent(&stu);stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.super.name, "小明");stu.super.setGender(&stu.super, "男");stu.mark = 98;// 打印这些数值printf("学号:%d\n", stu.super.id);printf("姓名:%s\n", stu.super.name);const char* gender = stu.super.getGender(&stu.super);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);putchar('\n');struct teacher t;// 初始化teacherinitTeacher(&t);t.super.id = 12345;strcpy(t.super.name, "林老师");t.super.setGender(&t.super, "男");strcpy(t.subject, "C语言");// 打印这些数值printf("学号:%d\n", t.super.id);printf("姓名:%s\n", t.super.name);gender = t.super.getGender(&t.super);printf("性别:%s\n", gender);printf("科目:%s\n", t.subject);
} 程序运行结果

7.0 多态
struct Rect {
void (*draw)(struct Rect *);int left;int top;int right;int bottom;
};
struct Circle {
void (*draw)(struct Circle *);int x;int y;int r;
};
struct Triangle {
void (*draw)(struct Triangle *);POINT p1;POINT p2;POINT p3;
}; struct Shape {
void (*draw)(struct Shape *);
}; 这是共性的结构体,可以称之为结构体对象

struct Rect {struct Shape super;int left;int top;int right;int bottom;
};
struct Circle {struct Shape super;int x;int y;int r;
};
struct Triangle {struct Shape super;POINT p1;POINT p2;POINT p3;
}; 
如果父对象和子对象的内存排布不重合会出现错误
// 正确
struct Rect {struct Shape super;int left;int top;int right;int bottom;
}; // 错误
struct Rect {int left;int top;int right;int bottom;struct Shape super;
}; void initRect(struct Rect* r)
{r->super.draw = drawRect;
}
void initCircle(struct Circle* c)
{c->super.draw = drawCircle;
}
void initTriangle(struct Triangle* t)
{t->super.draw = drawTriangle;
} - void (*)(struct Rect*)
- void (*)(struct Circle*)
- void (*)(struct Triangle*)
void initRect(struct Rect* r)
{r->super.draw = (void (*)(struct Shape*))drawRect;
}
void initCircle(struct Circle* c)
{c->super.draw = (void (*)(struct Shape*))drawCircle;
}
void initTriangle(struct Triangle* t)
{t->super.draw = (void (*)(struct Shape*))drawTriangle;
} struct Rect r = { {}, - 200, 200, 200, 0 };
struct Circle c = { {},0, 0, 100 };
struct Triangle t = { {}, {0, 200}, {-200, 0}, {200, 0} }; initRect(&r);
initCircle(&c);
initTriangle(&t); 让三个对象分别调用各自的初始化函数,给各自对象 super 成员中的 draw 设置为各自对应的绘图函数。
r.super.draw 设置为 drawRect
c.super.draw 设置为 drawCircle
t.super.draw 设置为 drawRTriangle
struct Shape *arrShape[3] = {
(struct Shape *)&r, (struct Shape*)&c, (struct Shape*)&t}; for (int i = 0; i < 3; i++)
{arrShape[i]->draw(arrShape[i]);
} 到了关键的一步,使用循环,依次调用 draw 函数。由于3次循环中的 draw 函数分别为各个图形各自的 绘图函数。所以,虽然统一调用的是 draw ,但是,却可以执行它们各自的绘图函数。至此,不同实现 的方法,在此得到统一。
完整代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>
#include <stdio.h>
#include <easyx.h>
#include <stdlib.h>struct Shape
{void (*draw)(struct Shape*);
};struct Rect
{struct Shape super;int left;int top;int right;int bottom;
};struct Circle
{struct Shape super;int x;int y;int r;
};struct Triangle
{struct Shape super;POINT p1;POINT p2;POINT p3;
};void drawRect(struct Rect* r)
{rectangle(r->left, r->top, r->right, r->bottom);
}void drawCircle(struct Circle* c)
{circle(c->x, c->y, c->r);
}void drawTriangle(struct Triangle* t)
{line(t->p1.x, t->p1.y, t->p2.x, t->p2.y);line(t->p2.x, t->p2.y, t->p3.x, t->p3.y);line(t->p3.x, t->p3.y, t->p1.x, t->p1.y);
}void InitRect(struct Rect* r)
{r->super.draw = (void(*)(struct Shape*)) drawRect;
}void InitCircle(struct Circle* c)
{c->super.draw = (void(*)(struct Shape*))drawCircle;
}void InitTriangle(struct Triangle* t)
{t->super.draw = (void(*)(struct Shape*))drawTriangle;
}int main()
{initgraph(800, 600);setaspectratio(1, -1);setorigin(400, 300);setbkcolor(WHITE);setlinecolor(BLACK);cleardevice();struct Rect r = { {}, - 200, 200, 200, 0 };struct Circle c = { {},0, 0, 100 };struct Triangle t = { {}, {0, 200}, {-200, 0}, {200, 0} };InitRect(&r);InitCircle(&c);InitTriangle(&t);struct Shape* arrShape[3] ={(struct Shape*)&r,(struct Shape*)&c,(struct Shape*)&t};for (int i = 0; i < 3; i++) {arrShape[i]->draw(arrShape[i]);}getchar();closegraph();return 0;
} 让我们回顾一下在之前实现多态的步骤:
注:参考你好编程C语言教程编写,仅供学习参考
相关文章:
C 语言面向对象
面向对象的基本特性:封装,继承,多态 1.0 面向过程概念 当我们在编写程序时,通常采用以下步骤: 1. 将问题的解法分解成若干步骤 2. 使用函数分别实现这些步骤 3. 依次调用这些函数 这种编程风格的被称作 面向过程…...
无人机探测:光电侦测核心技术算法详解!
核心技术 双光谱探测跟踪: 可见光成像技术:利用无人机表面反射的自然光或主动光源照射下的反射光,通过高灵敏度相机捕捉图像。该技术适用于日间晴朗天气下的无人机探测,具有直观、易于识别目标的特点。 红外成像技术࿱…...
ffmpeg视频滤镜:替换部分帧-freezeframes
滤镜描述 freezeframes 官网地址 > FFmpeg Filters Documentation 这个滤镜接收两个输入,然后会将第一个视频中的部分帧替换为第二个视频的某一帧。 滤镜使用 参数 freezeframes AVOptions:first <int64> ..FV....... set first fra…...
PHP 超级全局变量
超级全局变量是指在php任意脚本下都可以使用 PHP 超级全局变量列表: $GLOBALS:是PHP的一个超级全局变量组,在一个PHP脚本的全部作用域中都可以访问。 $_SERVER:$_SERVER 是一个PHP内置的超级全局变量,它是一个包含了诸如头信息(header)、路…...
Pytorch使用手册-Tensors(专题二)
这段代码是对 PyTorch 中张量(Tensors)的详细介绍和操作演示。以下是逐步讲解: 1. 什么是张量 (Tensor) 张量是一种专门的数据结构,与 NumPy 的多维数组(ndarray)类似: 它可以在 GPU 或其他硬件加速器上运行。张量可以与 NumPy 共享内存,避免不必要的数据拷贝。它是为…...
centos安装小火车
平时没事闲着 装个小火车玩-------->>>>> yum install sl.x86_64 启动命令 sl 就会出现以下场景...
241125学习日志——[CSDIY] [InternStudio] 大模型训练营 [17]
CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!!&…...
sklearn中常用数据集简介
scikit-learn库中提供了包括分类、回归、聚类、降维等多种机器学习任务所需的常用数据集,方便进行实验和研究,它们主要被封装在sklearn.datasets中,本文对其中一些常用的数据集进行简单的介绍。 1.Iris(鸢尾花)数据集…...
机器学习在教育方面的应用文献综述
引言 随着大数据时代的到来,机器学习作为人工智能的一个重要分支,在教育领域展现出广泛的应用前景。本文综述了机器学习技术在教育领域的应用,包括个性化学习、智能评估、知识图谱构建等多个方面。 个性化学习 个性化学习是机器学习…...
滑动窗口最大值(java)
题目描述 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1: 输入:nums [1,3,-1,-3,5,3,6,7]…...
sklearn学习
介绍:scaler:换算的意思 1. 归一化MinMaxScaler() 归一化的意思是将一堆数,如果比较离散,为了让数据更适合模型训练,将离散的数据压缩到0到1之间,以方便模型更高效优质的学习,而对数据的预处理…...
Ubuntu下手动设置Nvidia显卡风扇转速
在Ubuntu下,您可以使用 NVIDIA显卡驱动程序提供的工具手动调整风扇转速。以下是详细步骤: 1. 确保已安装NVIDIA显卡驱动 确保系统已经安装了正确的NVIDIA驱动: nvidia-smi如果没有输出驱动信息,请先安装驱动: sudo…...
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatisÿ…...
ES 和Kibana-v2 带用户登录验证
1. 前言 ElasticSearch、可视化操作工具Kibana。如果你是Linux centos系统的话,下面的指令可以一路CV完成服务的部署。 2. 服务搭建 2.1. 部署ElasticSearch 拉取docker镜像 docker pull elasticsearch:7.17.21 创建挂载卷目录 mkdir /**/es-data -p mkdir /**/…...
CodeIgniter如何手动将模型连接到数据库
在CodeIgniter中,模型通常是自动与数据库连接的,因为模型类(CI_Model)已经内置了对数据库操作的支持。但是,如果你需要手动指定数据库连接或者进行一些特殊的数据库配置,你可以通过几种方式来实现。 1. 使…...
商用密码应用安全性评估,密评整体方案,密评管理测评要求和指南,运维文档,软件项目安全设计相关文档合集(Word原件)
一、 密码应用安全性评估方案 (一) 密码应用测评工作思路 1.1.1. 测评准备活动的主要任务 1.1.2. 测评准备活动的输出文档 1.2. 方案编制活动 1.2.1. 方案编制活动的主要任务 1.2.2. 方案编制活动的输出文档 1.3. 现场预评估活动 1.3.1. 现场测评…...
AI赋能电商:构建高效、智能化的新零售生态
随着人工智能(AI)技术的不断进步,其在电商领域的应用日益广泛,从购物推荐到供应链管理,再到商品定价,AI正在全面改变传统电商的运营模式,并推动行业向智能化和精细化方向发展。本文将探讨如何利…...
【GAMES101笔记速查——Lecture 19 Cameras,Lenses and Light Fields】
本章节内容:相机、棱镜、光场 计算机图形学的两种成像方法: 1.合成方法:光栅化、光线追踪(展示出现实没有的东西) 2.捕捉方法:相机(捕捉现实已有的东西) 目录 1 相机 1.1 针孔相…...
虚拟机上搭建达梦DSC简略步骤
vmware 17 centos 7.6 达梦 dm8_20240920_x86_rh7_64.iso cd /d C:\Program Files (x86)\VMware\VMware Workstation\.\vmware-vdiskmanager.exe -c -s 100MB -a lsilogic -t 2 "F:\vm\dmdsc\sharedisk\share-dcr.vmdk" .\vmware-vdiskmanager.exe -c -s 100MB -a l…...
Python和R荧光分光光度法
🌵Python片段 Python在处理荧光分光光度法数据方面非常强大,得益于其丰富的数据处理和可视化库,可以轻松实现从数据读取到分析的完整流程。荧光分光光度法用于测量物质在激发光照射下发出的荧光强度,常用于定量分析和特性研究。 …...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...
手动给中文分词和 直接用神经网络RNN做有什么区别
手动分词和基于神经网络(如 RNN)的自动分词在原理、实现方式和效果上有显著差异,以下是核心对比: 1. 实现原理对比 对比维度手动分词(规则 / 词典驱动)神经网络 RNN 分词(数据驱动)…...
JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...
