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

2.类和对象(上)

1. 类的定义

1.1 类定义格式

class为定义类的关键字,Stack为类的名字,{ }中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; (类和结构体非常像,跟结构体不一样的就是在类里面可以定义函数)类中的函数称为类的方法或者成员函数。
为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前面或者后面加_ 或者 m开头,注意C++中这个并不是强制的,只是一些惯例,具体看公司的要求。
C++中也可以使用struct来定义类,C++兼容C中struct的用法,同时struct升级成了类,明显的变化是struct中可以定义函数,一般情况下我们还是推荐用class定义类。(struct 也可以定义类)

这是我们在C语言中定义的

在C++中就不一样了,在C++中struct就可以定义函数,但是我们遵循1.1第二条的原则,要加一个特殊标识符,就要设计成这个样子了。

定义在类里面的成员函数默认为inline。

在C++之后,就可以用类名当类型定义对象。(类名就是类型,用类型来定义对象)
类可以对比我们的结构体学习,跟结构体不同的地方是:类里面可以定义函数,这是最大的不同,用法上不用加class。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;
class Stack
{
public:
    // 成员函数
    void Init(int n = 4)
    {
        array = (int*)malloc(sizeof(int) * n);
        if (nullptr == array)
        {
            perror("malloc申请空间失败");
            return;
        }
        capacity = n;
        top = 0;
    }
    void Push(int x)
    {
        // ...扩容
        array[top++] = x;
    }int Top()
    {
        assert(top > 0);
        return array[top - 1];
    }
    void Destroy()
    {
        free(array);
        array = nullptr;
        top = capacity = 0;
    }
private:
    // 成员变量
    int* array;
    size_t capacity;
    size_t top;
}; // 分号不能省略

struct Person
{
public:
    void Init(const char* name, int age, int tel)
    {
        //在这要初始化这个名字就不能直接给了,我们要借助C语言的库函数,strcpy
        strcpy(_name, name);//加个特殊标识好区分
        _age = age;
        _tel = tel;
    }
    //我们也可以写一个打印函数
    void Print()
    {
        cout << "姓名:" << _name << endl;
        cout << "年龄:" << _age << endl;
        cout << "电话号码:" << _tel << endl;
    }
private:
    char _name[10]; //在这为什么不用const char*,而要用一个数组呢?
    int _age;      //用一个数组的原因是:后面我们要修改一个信息,我们就可以修改,如果用一个const char*,
    int _tel;     //外面是一个常量字符串,想修改我们的名字,是修改不了的。其实用const char*也可以,不影响。
};
int main()
{
    /*Stack st;
    st.Init();
    st.Push(1);
    st.Push(2);
    cout << st.Top() << endl;
    st.Destroy();*/
    Person p1;
    p1.Init("张三", 18, 110);
    p1.Print();
    return 0;
}

//我们用class定义类的时候与struct定义类的时候,一模一样(在这个角度来说)

//C++对这块定义的时候进行了升级

反正不论struct还是class,一般来说,成员变量都是私有的,不期望在外面去访问,要访问都通过成员函数去访问。

C++还有一个特点是兼容C当中struct的所有用法,

1.2 访问限定符

C++⼀种实现封装的方式,用类将对象的属性与方法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
• 公有就是 public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,在我们这个阶段我们认为protected和private是一样的,以后继承章节才能体现出他们的区别。
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到即类结束。
class定义成员没有被访问限定符修饰时默认为private,struct默认为public。
般成员变量都会被限制为private/protected,需要给别人使用的成员函数会放为public。一般情况下,一个类成员变量都是私有的,成员函数大部分都是公有的。
一般来说,我的类设计的时候,我不期望你随便访问修改我的数据。你要访问我的数据,本质是通过调用我的函数去访问,比如说要初始化,调用Init函数,要插入数据,调用Push,也不用关心Top到底是指向栈顶元素还是栈顶元素的下一个,要插入数据就插入,要获取栈顶元素就获取,要初始化就初始化,要销毁就销毁,不用管里面的细节,这是一种封装的体现,这呢对比C语言是有好处的,有什么好处呢?这里我们把类学了更多了以后,这个章节的最后一个部分( 4. C++和C语言实现Stack对比)我们再来对比。

1.3 类域

类定义了以个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

我们说,同一个域不能有同名变量,不同的域可以有同名变量,所以类这块也形成一个域,叫做类域。
类域影响的是编译的查找规则,下面程序中Init如果不指定类域Stack,那么编译器就把Init当成全
局函数,那么编译时,找不到array等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知
道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。

2. 实例化

2.1 实例化概念

类的类型在物理内存中创建对象的过程,称为类实例化出对象。
类是对象进行一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。
个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。打个比方:类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,设计图规划了有多少个房间,房间大小功能等,但是并没有实体的建筑存在,也不能住人,用设计图修建出房子,房子才能住人。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。(类里面不能存数据)
接下来我们定义一个日期类:
class Data
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    //下面三个变量都是声明
    int _year;
    int _month;
    int _day;
};
int year;//这里是定义
int main()
{
    //我们用class定义出的是一个类型Data
    //用类型定义出一个对象d1,这个对象包含_year,_month,_day
    //是随着对象定义而定义的,这里的对象定义我们把它叫做类实例化出对象
    //类和对象的关系是一对多的关系,也就是说,一个类可以实例化出多个对象
    Data d1;
    return 0;
}
(声明和定义不能用初始化来区分)声明和定义的特征在这个地方要用什么来看呢?比较好的一个方式就是有没有开空间。

2.2 对象大小

分析⼀下类对象中哪些成员呢?类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?首先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在一个单独的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针。再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各自独立的成员变量_year/_month/_day存储各自的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。如果用Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。这里需要再额外哆嗦一下,其实函数指针是不需要存储的,函数指针是一个地址,调用函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运行时找,只有动态多态是在运行时找,就需要存储函数地址,这个我们以后会讲解。

对象大小怎么算呢?

上面我们分析了对象中只存储成员变量,C++规定类实例化的对象也要符合内存对齐的规则。

首先也是要考虑内存对齐的问题,其实类的对象实例化里面只存了成员变量,没有存成员函数。成员函数可以认为存储在一个公共的区域。严格来说成员函数如果你调用,是在编译时就确定好地址了,只是函数呢编译好指令会存到一个公共的代码段。它不需要那个指针单独往对象里面存,因为都是一样的。编译的时候就已经确定好这个地址了。

 内存对齐规则

第一个成员在与结构体偏移量为0的地址处。
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的⼀个对齐数 与 该成员大小的较小值。
VS中默认的对齐数为8
结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
上面的程序运行后,我们看到没有成员变量的B和C类对象的大小是1,为什么没有成员变量还要给1个字节呢?因为如果⼀个字节都不给,怎么表示对象存在过呢!所以这里给1字节,纯粹是为了占位标识对象存在。

首先类B和类C是一样的,都没有成员变量,那结果不应该是0吗?为什么会是1呢?

如果是0的话,说明B和C定义的时候不需要开空间,不需要开空间怎么表示B和C存在过呢?假设不开空间,那么类B和类C的地址是什么?0个字节不需要开辟空间,那它的地址是什么?

所以对于没有成员变量的类呢, 它的对象我们要给它开空间,开多大的空间呢?开一个字节,那开一个字节是干嘛的?是为了占位,不存储有效数据。只是为了标识对象存在。我们后面会讲到仿函数的类,这个类基本上就没有成员变量。没有成员变量的类还是很常用的。

class A
{
public:
    void Print()
    {
        cout << _ch << endl;
    }
private:
    char _ch;
    int _i;
};
class B
{
public:
    void Print()
    {
        //...
    }
};
class C
{};
int main()
{
    A a;
    B b;
    C c;
    cout << sizeof(a) << endl; cout << sizeof(b) << endl;
    cout << sizeof(c) << endl;
    return 0;
}

3. this指针

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用Init和
Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这里就要看到C++给了
一个隐含的this指针解决这里的问题。
编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。比如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day),所有的成员函数都有一个隐含的参数,这个参数叫this。
#include<iostream>
using namespace std;
class Date
{
public:
    //这里的Init隐含一个形参 void Init(Date* const this, int year, int month, int day)
    void Init(int year, int month, int day)
    {
        // 编译报错:error C2106: “=”: 左操作数必须为左值
        // this = nullptr;
        // this->_year = year;
        _year = year;
        this->_month = month;
        this->_day = day;
    }
    //所有的成员函数都有一个隐含的参数,这个参数叫this
    //void Print(Date* const this, int year, int month, int day) 
    void Print() 
    {
        //cout << this->_year << "/" << this->_month << "/" << this->_day << endl;
        cout << _year << "/" << _month << "/" << _day << endl;
    }
private:
    // 这里只是声明,没有开空间
    int _year;
    int _month;
    int _day;
};
int main()
{
    // Date类实例化出对象d1和d2
    Date d1;
    Date d2;
    //在这调用Init也不是这样调用的,是这样调用的
    //d1.Init(&d1, 2024, 3, 31);
    //d2.Init(&d2, 2024, 7, 5);
    //所以Init和Print的时候就能够区分谁是谁了
    //调用的确确实实是一个函数,但是用d1调用的时候,this是d1的地址,
    //用d2调用的时候,this是d2的地址。
    //d1.Print(&d1);
    //d2.Print(&d2);
    d1.Init(2024, 3, 31);
    d1.Print();
    d2.Init(2024, 7, 5);
    d2.Print();
    return 0;
}
类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this-
>_year = year;(也就意味着在这打印的时候,其实编译器是做成下面的样子的)
C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),具体编译器的处理是什么样的要看上图。但是可以在函数体内显示使用this指针。

实参、形参、函数体类你不加,编译器都会显示的加,但是实参和形参的位置我们不能显示加,函数体类我们可以显示着加 。

4. C++和C语言实现Stack对比

面向对象三大特性:封装、继承、多态,下面的对比我们可以初步了解⼀下封装。
通过下面两份代码对比,我们发现C++实现Stack形态上还是发生了挺多的变化,底层和逻辑上没啥变化。
C++中数据和函数都放到了类里面,通过访问限定符进行了限制,不能再随意通过对象直接修改数据,这是C++封装的⼀种体现,这个是最重要的变化。这里的封装的本质是⼀种更严格规范的管
理,避免出现乱访问修改的问题。当然封装不仅仅是这样的,我们后面还需要不断的去学习。
C++中有⼀些相对方便的语法,比如Init给的缺省参数会方便很多,成员函数每次不需要传对象地
址,因为this指针隐含的传递了,方便了很多,使用类型不再需要typedef用类名就很方便
在我们这个C++入门阶段实现的Stack看起来变了很多,但是实质上变化不大。等着我们后面看STL中的用适配器实现的Stack,大家再感受C++的魅力。

相关文章:

2.类和对象(上)

1. 类的定义 1.1 类定义格式 • class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{ }中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; &#xff08;类和结构体非常像&#…...

【实际案例】服务器宕机情况分析及处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问麒麟软件产品专区&#xff1a;https://product.kylinos.cn 服务器环境以及配置 物理机/虚拟机/云/容器 物理机 外网/私有网络/无网络 私有网络 处理器&#xff1a; Kunpeng 920 内存&#xff1a; 4 TiB BIOS版…...

Linux系统之ncdu命令的基本使用

Linux系统之ncdu命令的基本使用 一、ncdu命令命令介绍1.1 ncdu简介1.2 ncdu特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查系统镜像源3.4 更新软件列表 四、安装ncdu工具4.1 安装ncdu软件4.2 n…...

STM32L051K8U6-HAL-LED闪烁设计

HAL三步法&#xff1a; 1、配置下载线 2、配置晶振 3、配置时钟 注意&#xff1a;中断优先级&#xff08;这里防止HAL_Delay卡死&#xff0c;详细请看 http://t.csdnimg.cn/NQhQV&#xff09; 4、 配置灯引脚属性为输出模式。并设置标签为LED 生成代码&#xff1a;编写while里…...

记一次远程API调用失败

记一次远程API调用失败 最近开发忙&#xff0c;项目紧&#xff0c;系统出现一些忽隐忽现的问题&#xff0c;本地也不能复现&#xff0c;当时也无法理解&#xff0c;就先搁置了&#xff0c;现在回想起来&#xff0c;这里还是明智的。 这个bug很神奇 今天&#xff0c;原本好好的…...

【力扣】746.使用最小花费爬楼梯

题目描述 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 示例…...

06:【stm32】中断一:NVIC的配置

中断 1、中断的简介1.1、什么是中断1.2、为什么需要中断 2、中断的优先级2.1、中断优先级的表示方法 3、NVIC3.1、什么的NVIC3.2、NVIC的内部结构3.3、中断向量表3.4、程序实现①开启中断源②配置NVIC③中断响应函数 1、中断的简介 1.1、什么是中断 正在进行的事务被突发事件打…...

Flutter简介

Flutter是一个由Google开发的开源移动UI框架&#xff0c;它允许开发者使用Dart语言来构建高性能、高保真的iOS和Android应用。Flutter的设计理念是"编写一次&#xff0c;到处运行"&#xff08;write once, run everywhere&#xff09;&#xff0c;这意味着开发者可以…...

WT2605C蓝牙语音芯片赋能对讲机新体验:无屏操控、音频解码与蓝牙音箱三合一

一、产品概况 对讲机市场是一个技术成熟且具有广泛应用前景的市场。对讲机作为无线通信设备的一种&#xff0c;在许多不同的领域和业务中发挥着重要作用。从技术发展角度来看&#xff0c;对讲机经历了从模拟到数字的转型&#xff0c;以及从简单通信工具向多功能设备的演进。当…...

ctfshow-web入门-sql注入(web191-web195)

目录 1、web191 2、web192 3、web193 4、web194 5、web195 1、web191 过滤了 ascii 使用 ord 代替&#xff1a; import requests import string url "http://a585c278-320a-40e7-841f-109b1e394caa.challenge.ctf.show/api/index.php" out for j in range(1…...

【ARM】v8架构programmer guide(3)_ARMv8的寄存器

目录 4.ARMv8 registers 4.1 AArch64 特殊寄存器 4.1.1 Zero register 4.1.2 Stack pointer &#xff08;SP) 4.1.3 Program Counter &#xff08;PC) 4.1.4 Exception Link Register(ELR) 4.1.5 Saved Process Status Register &#xff08;SPSR&#xff09; 4.2 Proc…...

SpringIOC整合dbUtil做的增删改查以及转账业务的实现

目录 一、xml方式实现 1.介绍lombok插件 2.功能 3.步骤 3.1 idea安装插件(只做一次) 3.2 添加坐标 3.3 编写注解 4.核心类 4.1 QueryRunner 4.2 query() 查询 4.3 update() 增删改 5.配置文件applicationContext.xml 6.junit测试 6.1使用步骤 6.1.1 坐标 6.1.2…...

【Nacos无压力源码领读】(二) 集成 LoadBanlancer 与 OpenFeign

上一篇文章中, 详细介绍了 Nacos 注册中心的原理, 相信看完后, 大家应该完全掌握了 Nacos 客户端是如何自动进行服务注册的, 以及 Nacos 客户端是如何订阅服务实例信息的, 以及 Nacos 服务器是如何处理客户端的注册和订阅请求的; 本文承上启下, 在订阅服务实例的基础上, 介绍如…...

CP AUTOSAR标准之DefaultErrorTracer(AUTOSAR_SWS_DefaultErrorTracer)(更新中……)

1 简介和功能概述 本规范描述了默认错误跟踪器的API。基础软件中检测到的所有开发和运行时错误都会报告给此模块。API参数允许跟踪错误来源和类型: 检测到错误的模块检测到错误的函数错误类型此模块API背后的功能不在本规范的范围内。软件开发人员和软件集成商应根据其特定应用…...

SpringMVC (发送请求——>参数传递—— >响应数据)

设置请求访问路径 RequestMapper&#xff1a;将请求访问路径和我们业务层的方法联系起来 ResponseBody&#xff1a;将我们业务层方法的返回值转化为json&#xff0c;xml或其他格式的数据返回给页面 两种请求 get请求 post请求 测试案例 RequestMapping("/getNameAndAge&…...

认识Modbus RTU与Modbus TCP

&#xff08;选自成都纵横智控-Modbus RTU与Modbus TCP协议区别详解 &#xff09; Modbus RTU 和 Modbus TCP 是两种常用的工业通信协议&#xff0c;用于连接电子设备&#xff0c;但它们在多方面有所不同。以下是它们的详细比较&#xff1a; Modbus RTU 协议类型&#xff1a; …...

如何在 Kubernetes 中使用 ClickHouse 和 JuiceFS

ClickHouse 结合 JuiceFS 一直是一个热门的组合&#xff0c;社区中有多篇实践案例。今天的文章来自美国公司 Altinity&#xff0c;一家提供 ClickHouse 商业服务的企业&#xff0c;作者是 Vitaliy Zakaznikov&#xff0c;他尝试了这个组合并公开了过程中使用的代码。原文有两篇…...

云计算任务调度优化matlab仿真,对比蚁群优化和蛙跳优化

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 ACO蚁群优化 4.2 蛙跳优化 5.完整程序 1.程序功能描述 云计算任务调度优化,优化目标位任务消耗时间&#xff0c;调度后的经济效益以及设备功耗&#xff0c;对比蚁群优化算法和蛙跳优化…...

基于双PI+EKF扩展卡尔曼滤波的PMSM速度控制simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PMSM数学模型 4.2 双PI控制器设计 4.3 扩展卡尔曼滤波器(EKF) 4.4 控制系统实现 5.完整工程文件 1.课题概述 基于双PIEKF扩展卡尔曼滤波的PMSM速度控制simulink建模与仿真。对比基于双PI的扩展卡…...

医疗器械注册资源宝库数屿医械官方平台!

医学影像设备市场作为医疗器械领域的佼佼者&#xff0c;技术门槛高且规模庞大&#xff0c;2021年全球规模达458亿美元&#xff0c;预计2022年逼近500亿美元&#xff0c;增长动力源自技术革新与临床需求攀升。中国市场亦不甘落后&#xff0c;受政策驱动与市场需求双重提振&#…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...