嵌入式学习-QT-Day08

embedded/2024/12/26 18:27:57/

嵌入式学习-QT-Day08

八、数据库

1、准备工作

2、连接数据库

3、创建表

4、增删改

5、查询

5.1 全查

5.2 模糊查询

八、数据库

1、准备工作

Qt本身并没有数据库的功能,但是Qt支持调用其他主流的数据库产品,并且这些数据库产品指定了统一的Qt接口,实际上使一种数据库的中间件。

Qt支持以下数据库类型。

嵌入式常用的数据库是SQLite3,本体只有几兆大小,非常适合集成到嵌入式产品当中。在Qt5版本及其以上也集成了SQLite数据库,因此可以直接通过驱动名称连接SQLite。

数据库编程中需要用到以下几个相关类:

  • QSqlDatabase

数据库相关类,用于一个数据库的连接。

  • QSqlQuery

数据库的操作类,可以操作SQL语句。

  • QSqlError

数据库操作信息类,用户手机数据库底层传递到Qt中的错误信息的。

数据库的相关产品无法直接使用,需要在.pro项目配置文件中添加sql模块。

添加完成后保存。

2、连接数据库

主要通过QsqlDatabase类进行连接,相关函数实现:

// 获得一个数据库连接对象
// 参数为数据库类型,详见本章第一节表格(注意大小写)
// 返回值:为连接对象
QSqlDatabase QSqlDatabase::​addDatabase(const QString & type)[static]
// 设置数据库名称
// 参数:要设置的数据库名称。对于SQLite,此函数表示数据库文件名。此文件会在项目目录中生成。
void QSqlDatabase::​setDatabaseName(const QString & name)
// 打开数据库连接
// 返回值为打开的结果,如果打开成功返回true、打开失败false。可以通过lastError函数获取错误信息。
bool QSqlDatabase::​open()
// 返回上一次的错误信息封装类
QSqlError QSqlDatabase::​lastError() const
// 从QSqlError对象中提取错误信息文本
QString QSqlError::​text() const
// 返回数据库连接的打开状态
bool QSqlDatabase::​isOpen() const
// 关闭数据库连接
void QSqlDatabase::​close()

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
    Q_OBJECTpublic:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;    // 数据库连接对象
    void connetD2B();   // 连接到数据库private slots:
    void btnClickedSlots(int);
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnClickedSlots(int)));    connetD2B();
}Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }
    delete ui;
}// 连接数据库
void Dialog::connetD2B()
{
    // 获取数据库的连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_management.db");
    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug () << "打开成功";
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errInfo = db.lastError();
        QString text = errInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
    }
    else if(id == 2)
    {
        qDebug () << "删除";
    }
    else if(id == 3)
    {
        qDebug () << "修改";
    }
    else if(id == 4)
    {
        qDebug () << "查找";
    }
    else
    {    }
}

3、创建表

建表语句:

CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price  REAL,author TEXT);
// 执行SQL语句
// 参数为执行的SQL语句内容
// 返回值为执行的结果
bool QSqlQuery::​exec(const QString & query)
// 与本章第二节的同名函数用法完全一样
QSqlError QSqlQuery::​lastError() const

一个操作SQLite的可视化软件

下载链接:百度网盘 请输入提取码

提取码:hqyj

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QSqlQuery>private:
    void createTable(); // 创建表#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"// 连接数据库
void Dialog::connetD2B()
{
    // 获取数据库的连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_management.db");
    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug () << "打开成功";
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errInfo = db.lastError();
        QString text = errInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}// 创建表
void Dialog::createTable()
{
    // sql语句
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT);";    // 创建数据库操作类
    QSqlQuery sq;    if(sq.exec(sql))    // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else    // 建表失败,注意:建表成功或者失败都很正常,如果要建立的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败:" << text;
    }
}

4、增删改

增删改操作都需要录入用户输入,然后把用户输入的数据组装成SQL语句,最后执行。

组装SQL语句有两种方式:

  • 字符串拼接

这种方式原理简单,但是容易出错,且安全性较低。

  • 预处理+占位符

推荐使用这种方式,这种方式需要先编写有占位符的预处理SQL语句,交给Qt,Qt内部就知道要执行的SQL语句格式,然后在进行参数与占位符的替换,最终执行。

占位符有两种表示风格:

  • Oracle风格

使用:字段的格式

UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id;
  • ODBC风格

使用?的格式

INSERT INTO book VALUES(?,?,?,?);
// 预处理SQL语句,此时SQL语句并没有执行,只是送入到Qt内部。
// 参数为要处理的SQL语句
// 返回为预处理的结果
bool QSqlQuery::​prepare(const QString & query)
// 绑定ODBC风格的占位符参数,绑定时一定要注意参数的顺序。
// 参数为要绑定的数据
void QSqlQuery::​addBindValue(const QVariant & val)

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QSqlQuery>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
    Q_OBJECT
private:
    void insertData();  // 添加数据
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"// 插入数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }
    QString author = ui->lineEdit_2->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名称");
        return;
    }    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?)";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);    // 执行绑定后的SQL语句
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据插入成功");
    }
    else // 失败
    {
       // 获取错误信息封装类
        QSqlError info = sq.lastError();
        QString text = info.text();
        QMessageBox::warning(this,"通知","数据插入失败");
        qDebug() << text;
    }
}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
        insertData();
    }
    else if(id == 2)
    {
        qDebug () << "删除";
    }
    else if(id == 3)
    {
        qDebug () << "修改";
    }
    else if(id == 4)
    {
        qDebug () << "查找";
    }
    else
    {    }
}

删除

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QSqlQuery>class Dialog : public QDialog
{
private:
    void deleteData();  // 删除数据
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"// 删除数据
void Dialog::deleteData()
{
    int id = ui->spinBox->value();    // 查询表中id是否存在
    // TODO    // 预处理的SQL语句
    QString sql = "DELETE FROM book WHERE id=?";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定参数
    sq.addBindValue(id);    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据删除成功");
    }
    else
    {
        // 获取错误信息封装类
        QSqlError info = sq.lastError();
        QString text = info.text();
        QMessageBox::critical(this,"通知",text);
    }
}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
        insertData();
    }
    else if(id == 2)
    {
        qDebug () << "删除";
        deleteData();
    }
    else if(id == 3)
    {
        qDebug () << "修改";
    }
    else if(id == 4)
    {
        qDebug () << "查找";
    }
    else
    {
    }
}

// 绑定Oracle风格的占位符参数,绑定的顺序可以乱序
// 参数1:占位符
// 参数2:要绑定的数据
void	bindValue(const QString & placeholder, const QVariant & val)

dialog.h

#ifndef DIALOG_H
#define DIALOG_Hclass Dialog : public QDialog
{private:
    void updateData();  // 更改数据
};#endif // DIALOG_H

dilaog.cpp

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}// 更改数据
void Dialog::updateData()
{
    // 获取用户输入
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名!");
        return;
    }
    QString author = ui->lineEdit_2->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名!");
        return;
    }    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();    // 预处理sql语句(Oracle风格)
    QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定数据
    sq.bindValue(":price",price);
    sq.bindValue(":id",id);
    sq.bindValue(":author",author);
    sq.bindValue(":name",name);    // 执行绑定后的sql语句
    if(sq.exec())
    {
        qDebug() << "更新成功";
        QMessageBox::information(this,"提示","数据更改成功");
    }
    else
    {
        QString text =  sq.lastError().text();
        QMessageBox::critical(this,"提示",text);
    }}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
        insertData();
    }
    else if(id == 2)
    {
        qDebug () << "删除";
        deleteData();
    }
    else if(id == 3)
    {
        qDebug () << "修改";
        updateData();
    }
    else if(id == 4)
    {
        qDebug () << "查找";
    }
    else
    {    }
}

5、查询

5.1 全查

相关函数

// 判断查询结果有无数据,如果有则移动游标并取出,没有返回false
bool QSqlQuery::​next()
// 按照字段序号取出对应的值,需要从0开始
// 返回值为QVariant类型,可以根据需要直接转为所需类型
QVariant QSqlQuery::​value(int index) const
// 按照字段名称取出对应的值
// 返回值为QVariant类型,可以根据需要直接转为所需类型
QVariant QSqlQuery::​value(const QString & name) const

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QSqlQuery>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
private:
    void seleteAll();   // 查找全部数据
    bool isDataExists(int id);  // 判断数据是否存在
};#endif // DIALOG_H

dilaog.cpp

#include "dialog.h"
#include "ui_dialog.h"// 全查
void Dialog::seleteAll()
{
    ui->textBrowser->clear();
    QString sql = "SELECT * FROM book";
    QSqlQuery sq;    if(sq.exec(sql))
    {
        while(sq.next())    // 循环取出
        {
           QString id = sq.value(0).toString();
           QString name = sq.value(1).toString();
           QString price = sq.value(2).toString();
           QString author = sq.value(3).toString();           QString text = id.append("-")+name.append("-")+price.append("-")+author;
           ui->textBrowser->append(text);
        }
    }
}// 判断数据是否存在,采用字符串拼接的方式
bool Dialog::isDataExists(int id)
{
    QString idText = QString::number(id);
    QString sql = "SELECT *FROM book WHERE id=";
    sql.append(idText); // 拼接只为证明可以使用,但是不建议    QSqlQuery sq;
    if(sq.exec(sql))
    {
       return sq.next();
    }
    else
    {
        return false;
    }
}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
        insertData();
    }
    else if(id == 2)
    {
        qDebug () << "删除";
        deleteData();
    }
    else if(id == 3)
    {
        qDebug () << "修改";
        updateData();
    }
    else if(id == 4)
    {
        qDebug () << "查找";
        seleteAll();
    }
    else
    {    }
}

5.2 模糊查询

可以使用LIKE关键字配合两个通配符实现模糊查询。

  • %

任意多个(0,1,......n)字符

  • _

任意一个字符

[查询] 查询“文”字辈的人员信息。

SELECT * FROM book WHERE name LIKE "_文%";

[例子]查询姓名中包含"文"的人员信息

SELECT * FROM book WHERE name LIKE "%文%";

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QButtonGroup>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QSqlQuery>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{
    Q_OBJECTpublic:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;    // 数据库连接对象
    void connetD2B();   // 连接到数据库
    void createTable(); // 创建表
    void insertData();  // 添加数据
    void deleteData();  // 删除数据
    void updateData();  // 更改数据
    void seleteAll();   // 查找全部数据
    bool isDataExists(int id);  // 判断数据是否存在
    void selectLike();  // 模糊查询private slots:
    void btnClickedSlots(int);
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnClickedSlots(int)));    connetD2B();
}Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }
    delete ui;
}// 连接数据库
void Dialog::connetD2B()
{
    // 获取数据库的连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_management.db");
    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug () << "打开成功";
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errInfo = db.lastError();
        QString text = errInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}// 创建表
void Dialog::createTable()
{
    // sql语句
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT);";    // 创建数据库操作类
    QSqlQuery sq;    if(sq.exec(sql))    // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else    // 建表失败,注意:建表成功或者失败都很正常,如果要建立的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败:" << text;
    }
}// 插入数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }
    QString author = ui->lineEdit_2->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名称");
        return;
    }    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?)";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);    // 执行绑定后的SQL语句
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据插入成功");
    }
    else // 失败
    {
       // 获取错误信息封装类
        QSqlError info = sq.lastError();
        QString text = info.text();
        QMessageBox::warning(this,"通知","数据插入失败");
        qDebug() << text;
    }
}// 删除数据
void Dialog::deleteData()
{
    int id = ui->spinBox->value();    // 查询表中id是否存在
    if(!isDataExists(id))
    {
        QMessageBox::information(this,"提示","没有找到要删除的数据");
        return;
    }    // 预处理的SQL语句
    QString sql = "DELETE FROM book WHERE id=?";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定参数
    sq.addBindValue(id);    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据删除成功");
    }
    else
    {
        // 获取错误信息封装类
        QSqlError info = sq.lastError();
        QString text = info.text();
        QMessageBox::critical(this,"通知",text);
    }
}// 更改数据
void Dialog::updateData()
{
    // 获取用户输入
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名!");
        return;
    }
    QString author = ui->lineEdit_2->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名!");
        return;
    }    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();    // 查询表中id是否存在
    if(!isDataExists(id))
    {
        QMessageBox::information(this,"提示","没有找到要修改的数据");
        return;
    }    // 预处理sql语句(Oracle风格)
    QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);    // 绑定数据
    sq.bindValue(":price",price);
    sq.bindValue(":id",id);
    sq.bindValue(":author",author);
    sq.bindValue(":name",name);    // 执行绑定后的sql语句
    if(sq.exec())
    {
        qDebug() << "更新成功";
        QMessageBox::information(this,"提示","数据更改成功");
    }
    else
    {
        QString text =  sq.lastError().text();
        QMessageBox::critical(this,"提示",text);
    }}// 全查
void Dialog::seleteAll()
{
    ui->textBrowser->clear();
    QString sql = "SELECT * FROM book";
    QSqlQuery sq;    if(sq.exec(sql))
    {
        while(sq.next())    // 循环取出
        {
           QString id = sq.value(0).toString();
           QString name = sq.value(1).toString();
           QString price = sq.value(2).toString();
           QString author = sq.value(3).toString();           QString text = id.append("-")+name.append("-")+price.append("-")+author;
           ui->textBrowser->append(text);
        }
    }
}// 判断数据是否存在,采用字符串拼接的方式
bool Dialog::isDataExists(int id)
{
    QString idText = QString::number(id);
    QString sql = "SELECT *FROM book WHERE id=";
    sql.append(idText); // 拼接只为证明可以使用,但是不建议    QSqlQuery sq;
    if(sq.exec(sql))
    {
       return sq.next();
    }
    else
    {
        return false;
    }
}// 模糊查询
void Dialog::selectLike()
{
    // 获取用户输入数据
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }    QString sql = "SELECT * FROM book WHERE name LIKE ?";    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);
    sq.addBindValue(name.prepend("%").append("%"));
    if(sq.exec())
    {
        // 是否查询到状态
        bool retState = true;
        // 清空上一次显式
        ui->textBrowser->clear();        while(sq.next())
        {
            QString id = sq.value(0).toString();
            QString name = sq.value(1).toString();
            QString price = sq.value(2).toString();
            QString author = sq.value(3).toString();            // 显式
            QString text = id.append("-")+name.append("-")+price.append("-")+author;
            ui->textBrowser->append(text);
            retState = false;
        }
        if(retState)
        {
            QMessageBox::information(this,"提示","没有查询到相关数据");
        }
    }
    else
    {
        QString text = sq.lastError().text();
        text.append("查询失败");
        QMessageBox::critical(this,"错误",text);
    }
}void Dialog::btnClickedSlots(int id)
{
    if(id == 1)
    {
        qDebug () << "增加";
        insertData();
    }
    else if(id == 2)
    {
        qDebug () << "删除";
        deleteData();
    }
    else if(id == 3)
    {
        qDebug () << "修改";
        updateData();
    }
    else if(id == 4)
    {
        qDebug () << "查找";
        selectLike();
    }
    else
    {    }
}

http://www.ppmy.cn/embedded/148962.html

相关文章

最新版本 - 二进制安装k8s1.29.2 集群

一、环境初始化 角色IPmaster01192.168.174.143master02192.168.174.144master03192.168.174.145node01192.168.174.146node02192.168.174.147 角色组件masternginx、APIServer、Schedule、Controllermanager、kubelet、kube-proxy、ETCDnodenginx、kubelet、kube-proxy 作者…

kkfileview代理配置,Vue对接kkfileview实现图片word、excel、pdf预览

kkfileview部署 官网&#xff1a;https://kkfileview.keking.cn/zh-cn/docs/production.html 这个是官网部署网址&#xff0c;这里推荐大家使用docker镜像部署&#xff0c;因为我是直接找运维部署的&#xff0c;所以这里我就不多说明了&#xff0c;主要说下nginx代理配置&am…

WPF的右键菜单项目引入DLL和DllImport特性引入DLL文件的异同点

在WPF&#xff08;Windows Presentation Foundation&#xff09;应用程序中&#xff0c;引用DLL&#xff08;Dynamic Link Library&#xff09;可以通过不同的方式实现&#xff0c;其中包括使用右键菜单添加引用和使用代码中的 DllImport 特性引入。 第一种&#xff1a;右键项…

【落羽的落羽 C语言篇】动态内存管理·上

文章目录 一、动态内存管理是什么二、动态内存管理相关函数1. malloc2. free3. calloc4. realloc 三、柔性数组1. 概念2. 使用 一、动态内存管理是什么 我们之前已经知道&#xff0c;定义变量就是申请一块空间&#xff0c;int a;就是申请四个字节的空间&#xff0c;char arr[2…

【Rust自学】7.1. Package、Crate和定义Module

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 7.1.1. Rust的代码组织 代码组织主要包括&#xff1a; 那些细节可以对外暴露&#xff0c;而哪些细节是私有的在作用域内哪些名称有效… …

ML-Agents:训练配置文件(一)

注&#xff1a;本文章为官方文档翻译&#xff0c;如有侵权行为请联系作者删除 Training Configuration File - Unity ML-Agents Toolkit–原文链接 ML-Agents&#xff1a;训练配置文件&#xff08;一&#xff09; ML-Agents&#xff1a;训练配置文件&#xff08;二&#xff09;…

对 MYSQL 架构的了解

MySQL 是一种广泛使用的关系型数据库管理系统&#xff0c;其架构主要包括以下几个关键部分&#xff1a; 一、连接层 客户端连接管理&#xff1a;MySQL 服务器可以同时处理多个客户端的连接请求。当客户端应用程序&#xff08;如使用 Java、Python 等语言编写的程序&#xff09;…

Llama 3 模型系列解析(一)

目录 1. 引言 1.1 Llama 3 的简介 1.2 性能评估 1.3 开源计划 1.4 多模态扩展 ps 1. 缩放法则 2. 超额训练&#xff08;Over-training&#xff09; 3. 计算训练预算 4. 如何逐步估算和确定最优模型&#xff1f; 2. 概述 2.1 Llama 3 语言模型开发两个主要阶段 2.2…