【C++起飞之路】类和对象 —— 类

news2024/11/17 7:52:18

类 ~ ~ ~

  • 一、面向过程和面向对象初步认识
    • a. 面向过程编程
    • b. 面向对象编程
    • 例如:无人机送货系统
      • 1、面向过程编程方式
      • 2、面向对象编程方式
  • 二、类的引入
    • 1、定义类的关键字
    • 2、栈的手动实现
      • a. C语言实现栈
      • b. C++实现栈
  • 三、类的定义
    • 类的两种定义方式:
  • 四、类的访问限定符
    • 1. public访问限定符
    • 2. private访问限定符
    • 3. protected访问限定符
  • 五、类的作用域
    • 类成员的访问
    • 命名空间的作用域与组织
    • 类的作用域与命名空间的关系
  • 六、类的实例化
    • 实例化
    • 类比 制造汽车
  • 七、类的对象大小的计算
    • 内存对齐
    • 填充
    • 计算类的对象大小的基本原则
  • 八、类成员函数的this指针
    • 1. this指针的作用
    • 2. this指针的用法
    • 3. this指针的特性
    • 4. this指针的实际应用
      • a. 成员函数调用成员函数:
      • b. 实现链式调用
    • 5. 注意事项

面向对象是一种更高级的编程方式

一、面向过程和面向对象初步认识

当谈论编程范式时," 面向过程 " 和 “面向对象” 是两个重要的概念。

它们描述了编程的 不同方法和思维方式,以解决问题和构建应用程序。下面让我们详细了解一下这两种编程范式。

a. 面向过程编程

面向过程编程是一种以流程和步骤为中心的编程方式。它强调的是将问题分解成一系列的 步骤或过程,然后按照 严格的顺序 执行这些步骤来解决问题。在面向过程编程中,数据和函数(或过程)是分开的,函数操作数据并返回结果。

🗽主要特点:

  1. 程序的执行流程: 面向过程编程关注程序的执行流程,按照顺序执行不同的步骤来完成任务。

  2. 数据和函数分离: 数据和操作数据的函数是分开的,函数仅仅作为对数据的操作。

  3. 可读性较差: 随着程序复杂度增加,面向过程编程可能会导致代码的可读性下降,因为各个步骤之间的关系不够清晰。

🗼适用场景: 面向过程编程 适用于简单的、线性的问题,如数据处理、算法等。

b. 面向对象编程

面向对象编程是 一种更具组织性和结构性的编程方式,强调将数据和对数据的操作封装为对象。在面向对象编程中,数据和函数(或方法)是紧密关联的,对象是数据和方法的一个实例。

🗽主要特点:

  1. 对象与类: 面向对象编程基于对象和类的概念。类是对象的蓝图,定义了对象的属性(成员变量)和方法(成员函数)。

  2. 封装: 封装是将数据和操作数据的函数封装在一起,隐藏了内部的细节。这提高了代码的安全性和可维护性。

  3. 继承: 继承允许一个类继承另一个类的属性和方法。这促进了代码的重用和扩展。

  4. 多态: 多态性允许不同的类共享相同的接口,但可以根据具体实现的不同表现出不同的行为。

  5. 可读性较高: 面向对象编程使代码的结构和关系更加清晰,提高了代码的可读性和可维护性。

🗼适用场景: 面向对象编程 适用于大型、复杂的应用程序,能够更好地组织和管理代码。

例如:无人机送货系统

1、面向过程编程方式

在面向过程编程中, 关注程序的执行流程,将问题分解为一系列的步骤或过程,并按照顺序执行这些步骤来完成任务

· 程序流程: 将送货任务分解为一系列步骤:启动无人机、导航、取货、交付、返回等。

函数: 编写一系列函数来执行每个步骤,如StartDrone()NavigateToLocation()PickupItem()deliverItem()等。

全局变量: 使用全局变量来存储无人机的状态、目标位置等信息,这些变量在各个函数中共享。

可读性: 随着任务的复杂性增加,代码可能会变得难以维护和理解,因为不同步骤之间的关系可能不够清晰。

2、面向对象编程方式

在面向对象编程中,关注对象和类的概念,将问题中的实体和操作封装为对象和方法

· 类和对象: 定义类如"Drone"、"DeliveryPoint"等,分别表示无人机和送货点,每个类具有属性和方法。

· 封装: 封装每个类的属性和操作,隐藏内部实现细节。例如,"Drone"类可能有start()、navigate()、pickup()、deliver()等方法。

· 继承: 如果系统需要支持多种类型的无人机,可以通过继承创建子类,实现共性和特性。

· 多态: 不同类型的无人机可以共享相同的接口,但根据实际类型执行不同的行为,提高灵活性。

· 可读性: 由于将功能和数据封装在对象内部,代码更加模块化,每个对象负责自己的操作,提高了可读性和可维护性

二、类的引入

1、定义类的关键字

C++定义类的关键字: structclass
C++ 兼容 C 中结构体的用法,同时 struct 在 C++ 中升级成了类

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,我们就会发现struct中也可以定义函数

2、栈的手动实现

a. C语言实现栈

#include <stdio.h>
#include <stdbool.h>

#define MAX_SIZE 100
//C语言结构体中只能定义变量
typedef struct 
{
    int data[MAX_SIZE];
    int top;
} Stack;

void initialize(Stack* stack) 
{
    stack->top = -1;
}

bool isEmpty(Stack* stack) 
{
    return stack->top == -1;
}

bool isFull(Stack* stack) 
{
    return stack->top == MAX_SIZE - 1;
}

void push(Stack* stack, int value) 
{
    if (isFull(stack)) 
    {
        printf("Stack is full. Cannot push.\n");
        return;
    }
    stack->data[++stack->top] = value;
}

int pop(Stack* stack)
{
    if (isEmpty(stack))
    {
        printf("Stack is empty. Cannot pop.\n");
        return -1;
        return stack->data[stack->top--];
    }
}

int peek(Stack* stack)
{
    if (isEmpty(stack))
    {
        printf("Stack is empty. Cannot peek.\n");
        return -1;
    }
    return stack->data[stack->top];
}

b. C++实现栈

#include <iostream>
template <typename T>

class MyStack 
{
private:
    T* data;
    int top;
    int capacity;

public:
    MyStack(int size) 
    {
        capacity = size;
        data = new T[capacity];
        top = -1;
    }

    ~MyStack() 
    {
        delete[] data;
    }

    void push(T value) 
    {
        if (top < capacity - 1) 
        {
            data[++top] = value;
        }
        else 
        {
            std::cout << "Stack is full. Cannot push." << std::endl;
        }
    }

    T pop() 
    {
        if (top >= 0) 
        {
            return data[top--];
        }
        else 
        {
            std::cout << "Stack is empty. Cannot pop." << std::endl;
            return T(); // 默认构造一个类型对象返回
        }
    }

    T peek() 
    {
        if (top >= 0) 
        {
            return data[top];
        }
        else 
        {
            std::cout << "Stack is empty. Cannot peek." << std::endl;
            return T(); // 默认构造一个类型对象返回
        }
    }

    bool isEmpty() 
    {
        return top == -1;
    }

    bool isFull() 
    {
        return top == capacity - 1;
    }
};

原来C中结构体的定义,在C++中更喜欢用class来代替struct

三、类的定义

class className 
{
// 类体:由成员函数和成员变量组成

};// 一定要注意后面的分号

class为定义类的关键字,ClassName为类的名字,{ }中为类的主体

注意类定义结束时后面分号不能省略。

类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者成员函数

类的两种定义方式:

  1. 声明和定义全部放在类体中。

需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理

#include <iostream>
class Person 
{
public:
    void introduce() 
    {
        std::cout << "My name is " << name << " and I am " << age << " years old." << std::endl;
    }
private:
    std::string name;
    int age;
};
  1. 类声明放在.h文件中,成员函数定义放在.cpp文件中。
    注意:成员函数名前需要加类名::

在这里插入图片描述

一般情况下,更期望采用第二种方式。

四、类的访问限定符

在这里插入图片描述

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. 如果后面没有访问限定符,作用域就到 } 即类结束。
  5. class的默认访问权限为private,struct为public(因为struct要兼容C)

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

1. public访问限定符

public是最常见的访问限定符,它允许类的成员在类的外部被访问。这意味着无论在哪里,我们都可以直接访问类的公有成员。公有成员通常用于表示类的接口,即外部代码与类交互的方法。

class Person {
public:
    std::string name;

    void introduce() {
        std::cout << "My name is " << name << std::endl;
    }
};

2. private访问限定符

private访问限定符将类的成员隐藏在类的内部,外部代码无法直接访问私有成员。这种封装性**保护了类的实现细节,确保了数据的安全性和一致性。**私有成员通常用于存储类的内部状态。

class BankAccount {
private:
    double balance;

public:
    void deposit(double amount) {
        balance += amount;
    }

    double getBalance() {
        return balance;
    }
};

3. protected访问限定符

protected访问限定符介于public和private之间。类的派生类可以访问基类的受保护成员,但其他外部代码无法访问。这在实现继承和多态时很有用,允许派生类使用基类的实现细节~

class Shape {
protected:
    int sides;

public:
    Shape(int s) : sides(s) {}

    int getNumSides() {
        return sides;
    }
};

五、类的作用域

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

类成员的访问

类的成员可以通过成员访问操作符(.->)进行访问。

在类的作用域内,可以直接访问任意成员,而在类的外部,只能访问公有成员。

私有和受保护成员需要通过公有成员函数来间接访问。

class MyClass {
public:
    int publicMember;

private:
    int privateMember;

protected:
    int protectedMember;
};

MyClass obj;
obj.publicMember = 10;  // 可以直接访问公有成员

// 无法直接访问私有成员和受保护成员
obj.privateMember;      // 编译错误
obj.protectedMember;    // 编译错误

命名空间的作用域与组织

命名空间是一种用来防止命名冲突和组织代码的机制。它允许将相关的变量、函数、类等放置在一个命名空间内,以防止全局命名冲突。命名空间还可以嵌套定义,形成层次结构。

namespace Math {
    int add(int a, int b) {
        return a + b;
    }
}

int main() 
{
    int result = Math::add(5, 3);  // 通过命名空间访问函数
    return 0;
}

类的作用域与命名空间的关系

类的作用域与命名空间的作用域存在一定的联系。

类的定义可以位于全局命名空间中,也可以位于其他命名空间内。

通过使用类的全名(包括命名空间前缀)可以在不同命名空间中访问类。

namespace MyNamespace {
    class MyClass {
    public:
        void foo() {}
    };
}

int main() 
{
    MyNamespace::MyClass obj;  // 在命名空间中访问类
    obj.foo();
    return 0;
}

六、类的实例化

用类类型创建对象的过程,称为类的实例化

实例化

换句话说,类的实例化是通过创建对象来实现的。在C++中,对象是类的实例,它具有类定义的属性和方法。通过使用构造函数,我们可以在对象创建时初始化成员变量,确保对象的正确初始化。

class Person {
public:
    std::string name;

    Person(const std::string& n) : name(n) {
        std::cout << "Person " << name << " created." << std::endl;
    }
};

int main() 
{
    Person person1("Alice");  // 实例化对象
    Person person2("Bob");
    return 0;
}

类比 制造汽车

类的实例化可以类比为现实生活中的"模具制造物品"的过程。

让我们以制造汽车为例来解释这个比方:

在汽车制造过程中,设计师首先会设计一个汽车的模型,类比于编写一个类的定义。模型定义了汽车的特征、属性和功能,就像类定义了成员变量和成员函数。

然后,制造工厂会使用这个模型来制造实际的汽车。这个过程类似于在C++中创建一个对象。每个实际的汽车都是根据同一个模型制造的,但每辆汽车都是独立的个体,拥有自己的状态和特性。

汽车模型中的规格和属性,例如引擎类型、座位数量、颜色等,对应于类的成员变量。而汽车模型中定义的功能,例如启动引擎、加速、刹车等,对应于类的成员函数

在汽车制造过程中,模型提供了标准和规范,确保每辆汽车都遵循相同的设计。类的实例化也提供了一种标准方式来创建对象,确保每个对象都有相同的结构和功能

总的来说,类的实例化就像在现实中使用模具制造物品,模具定义了物品的外观和特征,而每个制造出来的物品都是基于同一个模具创建的,类似于对象都是基于同一个类实例化出来的。

七、类的对象大小的计算

一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐
注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

在C++中,类的对象大小是由其成员变量和继承关系所决定的。计算类的对象大小涉及到内存对齐和填充等概念。

内存对齐

计算机在存储数据时通常会按照一定的规则进行对齐,以提高访问效率。 常见的对齐规则是以数据的字节大小为单位,要求数据在内存中的地址是其字节大小的整数倍。

  1. 第一个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的对齐数为8
  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

填充

为了满足对齐要求,编译器可能会在成员之间插入额外的字节,这些字节被称为填充。

计算类的对象大小的基本原则

以下是计算类的对象大小的基本原则:

成员变量的大小: 类的对象大小取决于其成员变量的大小之和,加上可能的填充。成员变量的字节大小是根据数据类型决定的,如int通常是4字节。

内存对齐: 默认情况下,编译器会以平台相关的字节对齐方式来对齐成员变量。例如,如果平台要求变量以4字节对齐,则如果一个int变量占4字节,那么它的起始地址必须是4的倍数。

继承和多态: 如果类涉及继承和多态,那么类的对象大小还会受到虚函数表(vtable)的影响。每个具有虚函数的类都会有一个vtable,这个vtable中存储了指向虚函数的指针,从而支持多态性。vtable的大小和指针的大小有关。

举个例子,考虑以下类的情况:

class Base {
public:
    int a;
};

class Derived : public Base {
public:
    int b;
};

假设int类型占4字节,平台要求以4字节对齐。那么Derived类的对象大小可能是8字节(int a占4字节,int b占4字节),加上可能的填充。

需要注意的是,不同的编译器和平台可能会对对象大小的计算产生不同的结果,因此在写代码时应该避免过于依赖对象的大小,而是专注于代码的可读性和可维护性。

你可以使用sizeof运算符在编译时获取对象的大小:

size_t size = sizeof(Derived);

八、类成员函数的this指针

this指针用于指向当前对象的指针

1. this指针的作用

在C++中,每个非静态成员函数(方法)都有一个隐含的this指针,指向调用该方法的对象。this指针允许在成员函数内部访问对象的成员变量和其他成员函数,即使成员函数的参数与成员变量同名。

2. this指针的用法

this指针的使用方式非常简单。在成员函数中,可以使用this指针来引用当前对象的成员。例如,使用this指针来区分成员变量和参数名相同的情况

class MyClass {
public:
    int x;

    void setValue(int x) {
        this->x = x;  // 使用this指针引用成员变量
    }
};

3. this指针的特性

  1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
  2. 只能在“成员函数”的内部使用
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
  4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

4. this指针的实际应用

a. 成员函数调用成员函数:

在类的成员函数内部,可以通过this指针调用其他成员函数,从而实现代码的复用和逻辑封装。

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }

    int addTwice(int a, int b) {
        return this->add(a, b) * 2;  // 通过this调用add函数
    }
};

b. 实现链式调用

使用this指针可以在一个成员函数内返回*this,从而实现链式调用。

class Chain {
public:
    Chain& setValue(int value) {
        this->value = value;
        return *this;  // 返回*this,实现链式调用
    }

    int getValue() {
        return value;
    }

private:
    int value;
};

5. 注意事项

  1. this指针只能在成员函数内部使用,且只有在非静态成员函数中才有效
  2. 静态成员函数没有this指针,因为它们与具体的对象无关。
  3. 在多线程编程中,使用this指针时需要注意线程安全性。

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

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

相关文章

Linux6.40 Kubernetes 配置资源管理

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes 配置资源管理一、Secret1.Secret 四种类型1&#xff09;kubernetes.io/service-account-token2&#xff09;Opaque3&#xff09;kubernetes.io/dockerconfigjson4&#xff09;kubernetes.io/tls 2.Pod 需要先引用才能使用某…

售后服务管理系统哪家好?云部署的售后服务软件有什么优势?

如今&#xff0c;越来越多的企业开始利用数字化系统来监控他们建造、操作或维护的高科技设备的技术属性。然而&#xff0c;仍然有很多公司依赖于孤立的低技术解决方案&#xff0c;比如使用Excel电子表格和手动流程来管理工作。当然&#xff0c;对于一家公司来说&#xff0c;寻找…

【AI大模型】训练Al大模型 (上篇)

大模型超越AI 前言 洁洁的个人主页 我就问你有没有发挥&#xff01; 知行合一&#xff0c;志存高远。 目前所指的大模型&#xff0c;是“大规模深度学习模型”的简称&#xff0c;指具有大量参数和复杂结构的机器学习模型&#xff0c;可以处理大规模的数据和复杂的问题&#x…

QT的工程文件认识

目录 1、QT介绍 2、QT的特点 3、QT模块 3.1基本模块 3.2扩展模块 4、QT工程创建 1.选择应用的窗体格式 2.设置工程的名称与路径 3.设置类名 4.选择编译器 5、QT 工程解析 xxx.pro 工程配置 xxx.h 头文件 main.cpp 主函数 xxx.cpp 文件 6、纯手工创建一个QT 工程…

spring框架之AOP模块,附带通知类型-----详细介绍

一&#xff0c;AOP简介 是Spring框架中的一个重要模块&#xff0c;它提供了一种通过面向切面编程的方式来实现横切关注点的模块化的方法。AOP可以将应用程序的核心业务逻辑与横切关注点&#xff08;如日志记录、事务管理、安全性等&#xff09;分离开来&#xff0c;从而提高代码…

6G 特点及表现

6G R&D Vision: Requirements and Candidate Technologies 5G已经提出来了大移动带宽&#xff0c;低时延和大规模机器互联&#xff0c;在这个基础上&#xff0c;6G加上了高可靠性&#xff0c;高定位精度和高智能化。 6G的主要候选技术&#xff0c;包括(子) THz 通信&#x…

学校如何公布录取情况表?这个不用技术的方法,小白老师都能轻松制作

作为一名教师&#xff0c;我深切了解学生和家长们对录取情况的关注和重视。为了满足他们的需求&#xff0c;我们学校一直致力于改进公布录取情况的方式和效果。在本篇文章中&#xff0c;我将向您介绍我们学校独特的录取查询系统&#xff0c;并分享我们选择这种方式的原因。 我…

ES基础及面试题

1. 什么是ES ES是一种开源的分布式搜索引擎&#xff0c;可以实现快速存储、搜索、分析大量数据。支持结构化查询和全文检索等多种方式 2. ES的实际用途 1. 全文搜索和信息检索 2. 日志分析&#xff0c;例如埋点分析 3. 监控和指标分析&#xff0c;网络流量&#xff0c;服务器…

C++11并发与多线程笔记(4) 创建多个线程、数据共享问题分析、案例代码

C11并发与多线程笔记&#xff08;4&#xff09; 创建多个线程、数据共享问题分析、案例代码 1、创建和等待多个线程2、数据共享问题分析2.1 只读的数据2.2 有读有写2.3 其他特例 3、共享数据的保护案例代码 1、创建和等待多个线程 #include<iostream> #include<threa…

Scada和lloT有什么区别?

人们经常混淆SCADA&#xff08;监督控制和数据采集&#xff09;和IIoT&#xff08;工业物联网&#xff09;。虽然SCADA系统已经存在多年&#xff0c;但IIoT是一种相对较新的技术&#xff0c;由于其能够收集和分析来自各种设备的大量数据而越来越受欢迎。SCADA和IIoT都用于提高工…

tomcat源码修改与编译

1、获取源码 从github下载其源码&#xff1a;https://github.com/apache/tomcat 2、选择版本 切换到对应版本&#xff08;直接用相对应的Git tag即可&#xff09;&#xff1a; git checkout 9.0.793、修改源代码&#xff0c;并且生成补丁 这里我们以修改去掉新版本的ws的检…

Docker网络与Cgroup硬件资源占用控制

目录 1.dockers的网络模式 1.1 获取容器的进程号 1.2 docker网络模式的特性 1.3 host主机模式 1.4 container模式 1.5 none模式 1.6 bridge 桥接模式 1.6 容器的自定义网络 &#xff08;1&#xff09;未创建自定义网络时&#xff0c;创建指定IP容器的测试 &#xff0…

VBA技术资料MF44:VBA_把数据从剪贴板粘贴到Excel

【分享成果&#xff0c;随喜正能量】人皆知以食愈饥&#xff0c;莫知以学愈愚,生命中所有的不期而遇都是你努力的惊喜.人越纯粹&#xff0c;就越能感受到美。大江、大河、大海、大山、大自然&#xff0c;这些风景从来都不会受“属于谁”的污染&#xff0c;人人都感受到它们的美…

来自句子转换器:转换器和池化组件

一、说明 转换器和池化组件&#xff0c;它们来自 Bert 在 SentenceTransformer 对象中预先训练的模型。 在我之前的文章中&#xff0c;我用拥抱面转换器介绍了预训练模型来计算句子之间的余弦相似性分数。在这篇文章中&#xff0c;我们将深入研究变压器模型的参数。句子转换器对…

Unity 编辑器资源导入处理函数 OnPreprocessTexture:深入解析与实用案例

Unity 编辑器资源导入处理函数 OnPreprocessTexture 用法 点击封面跳转下载页面 简介 在Unity中&#xff0c;我们可以使用编辑器资源导入处理函数&#xff08;OnPreprocessTexture&#xff09;来自定义处理纹理资源的导入过程。这个函数是继承自AssetPostprocessor类的&#x…

.NET Core6.0使用NPOI导入导出Excel

一、使用NPOI导出Excel //引入NPOI包 HTML <input type"button" class"layui-btn layui-btn-blue2 layui-btn-sm" id"ExportExcel" onclick"ExportExcel()" value"导出" />JS //导出Excelfunction ExportExcel() {…

微信小程序OCR插件,实现身份证、行驶证、银行卡、营业执照和驾驶证等识别

随着科技的不断发展&#xff0c;图片识别技术已经成为了当下移动互联网中的热点话题。而基于微信小程序和 OCR 插件的图文识别方案&#xff0c;更是成为了越来越多小程序开发者关注和研究的问题。本文中&#xff0c;我将为大家介绍微信小程序 OCR 插件&#xff0c;帮助大家实现…

并发编程系列-分而治之思想Forkjoin

我们介绍过一些有关并发编程的工具和概念&#xff0c;包括线程池、Future、CompletableFuture和CompletionService。如果仔细观察&#xff0c;你会发现这些工具实际上是帮助我们从任务的角度来解决并发问题的&#xff0c;而不是让我们陷入线程之间如何协作的繁琐细节&#xff0…

Linux学习之基本指令一

在学习Linux下的基本指令之前首先大家要知道Linux下一切皆目录&#xff0c;我们的操作基本上也都是对目录的操作&#xff0c;这里我们可以联想我们是如何在windows上是如何操作的&#xff0c;只是形式上不同&#xff0c;类比学习更容易理解。 目录 01.ls指令 02. pwd命令 0…

Android Ble蓝牙App(六)请求MTU与显示设备信息

前言 在上一篇文章中已经了解了数据操作的方式&#xff0c;而数据交互的字节长度取决于我们手机与蓝牙设备的最大支持长度。 目录 Ble蓝牙App&#xff08;一&#xff09;扫描Ble蓝牙App&#xff08;二&#xff09;连接与发现服务Ble蓝牙App&#xff08;三&#xff09;特性和属…