C++单目运算符和特殊运算符的重载(9)

news2024/7/4 15:49:59

运算符的重载

原理和机制

C++中运算符只支持基本数据类型运算,如果需要运算符支持类类型的运算,需要使用C++提供的新语法 ------- 运算符的重载

运算符的重载本质上是通过函数来实现的,将类类型数据的运算过程写成一个特殊的函数,当该类型的对象遇到这种运算时自动调用该函数来完成运算过程。

实现运算符重载的函数既可以是成员函数,也可以是全局函数。

双目运算符的重载

通过成员函数重载(以加法为例)

成员函数加法的重载: 本类类型 operator+(第二操作数){…} //xxx + yyy xxx是第一操作数 ,yyy 是第二操作数 //第一操作数就是调用该函数的对象

/08-双目运算符的重载/

#include <iostream>

using namespace std;

//分数
class Fraction {
public:
    Fraction(int x = 0, int y = 1) :x(x), y(y) {}
    //打印
    void print()
    {
        cout << this->x << "/" << this->y << endl;
    }
    Fraction operator+(const Fraction  &fb) {   //不传引用,会拷贝,效率问题 
        cout << "  NO-1 " << endl;
        // 1/2+ 1/3 = 5/6
      return  Fraction(this->x * fb.y + fb.x * this->y/*分子*/, this->y * fb.y/*分母*/);     
    }

private:
    int x;
    int y;
};
    int main()
    {
        Fraction fa(1, 2);
        Fraction fb(1, 3);

        Fraction fc = fa + fb;//fa.operator+(fb);   operator+(fa,fb);
        fc.print();


        return 0;
    }

通过全局函数重载(以加法为例)

全局函数加法的重载: 操作数的类型 operator+(第一操作数,第二操作数){…}

/*08-双目运算符的重载*/
#include <iostream>

using namespace std;

//分数
class Fraction {
public:
    Fraction(int x = 0, int y = 1) :x(x), y(y) {}
    //打印
    void print()
    {
        cout << this->x << "/" << this->y << endl;
    }
    Fraction operator+(const Fraction  &fb) {   //不传引用,会拷贝,效率问题 
        cout << "  NO-1 " << endl;
        // 1/2+ 1/3 = 5/6
      return  Fraction(this->x * fb.y + fb.x * this->y/*分子*/, this->y * fb.y/*分母*/);     
    }
    friend Fraction operator+(const Fraction& fa, const Fraction& fb);   //设置友元可以
private:
    int x;
    int y;
};
Fraction operator+(const Fraction& fa,const Fraction& fb) {   //不传引用,会拷贝,效率问题 
    cout << "  NO-2 " << endl;
    // 1/2+ 1/3 = 5/6
    return  Fraction(fa.x * fb.y + fb.x * fa.y/*分子*/, fa.y * fb.y/*分母*/);
}
    int main()
    {
        Fraction fa(1, 2);
        Fraction fb(1, 3);

        Fraction fc = fa + fb;//fa.operator+(fb);   operator+(fa,fb);
        fc.print();


        return 0;
    }

//如果类外重载无法访问类中的成员,可以使用以下方法 //1.直接将成员设置为公有(不推荐) //2.使用友元 //3.为私有成员提供访问接口

练习:

使用成员函数实现Fraction的减法,使用全局函数实现Fraction的乘除

//使用成员函数实现Fraction的减法,使用全局函数实现Fraction的乘除

/*08-双目运算符的重载*/
#include <iostream>

using namespace std;

//分数
class Fraction {
public:
    Fraction(int x = 0, int y = 1) :x(x), y(y) {}
    //打印
    void print()
    {
        cout << this->x << "/" << this->y << endl;
    }
    Fraction operator-(const Fraction  &fb) {   //不传引用,会拷贝,效率问题 
        cout << " " << endl;
        // 1/2+ 1/3 = 5/6
      return  Fraction(this->x * fb.y - fb.x * this->y/*分子*/, this->y * fb.y/*分母*/);     
    }
    friend Fraction operator*(const Fraction& fa, const Fraction& fb);   //设置友元可以
    friend Fraction operator/(const Fraction& fa, const Fraction& fb);
private:
    int x;
    int y;
};
Fraction operator*(const Fraction &fa,const Fraction &fb) {   //不传引用,会拷贝,效率问题 

    // 1/2 * 1/3 = 5/6
    return  Fraction((fa.x * fb.x)/*分子*/, (fa.y * fb.y)/*分母*/);
}
Fraction operator/(const Fraction& fa, const Fraction& fb) {   //不传引用,会拷贝,效率问题 
    //除以一个数等于乘以一个数的倒数
    // 1/2 * 1/3 = 5/6
    return  Fraction((fa.x * fb.y)/*分子*/, (fa.x * fb.y)/*分母*/);
}
 int main()
    {
        Fraction fa(1, 2);
        Fraction fb(1, 3);

        Fraction fc = fa - fb;//fa.operator-(fb);   operator-(fa,fb);
        Fraction fd = fa * fb;
        Fraction ff = fa / fb;
        fc.print();
        fd.print();
        ff.print();

        return 0;
    }

作业:

完成以下笔试题

(1)没有虚函数,不支持多态,不能用父类类型指向子类对象

(2)分配new [] ,释放应该用delete []

(3)没有虚函数,不支持多态,不能用父类类型指向子类对象

修改实参不影响形参,给NULL指针拷贝数据,段错误

(4)不能返回局部数组的地址,得到是野指针,使用结果不确定

构造一个类表示复数(Complex) -------- a+bi

重载+ - * 写出加减乘除

double real;
double imag;
C1 = 2+3i
C2 = 5-4i
C1+C2 = 7-i
C1-C2 = -3+7i
C1*C2 = 10 - 8i + 15i + 12 = 22+7i
 /*08-双目运算符的重载*/
#include <iostream>
using namespace std;

class Complex {
public:
    Complex(int real = 0, int imag = 0) :real(real), imag(imag) {}
    //打印
    void print()
    {
        cout << this->real << (this->imag>=0 ? " +":"") << this->imag << "i" << endl;
    }
    friend  Complex operator+(const Complex& n1, const Complex& n2);
    friend  Complex operator-(const Complex& n1, const Complex& n2);
    friend  Complex operator*(const Complex& n1, const Complex& n2);
    friend  Complex operator/(const Complex& n1, const Complex& n2);
    //-----------------------------------------
    // 如果必须要在类内定义的话,只能定义为单参数的运算符函数: friend  Num operator+(const Num& n1);
    // 如果定义为双参数的运算符函数,只能在类外定义
    //-------------------------------------

private:
    int real;
    int imag;
};
Complex operator+(const Complex& n1, const Complex& n2) {

    return  Complex(n1.real + n2.real, n1.imag + n2.imag);
}
Complex operator-(const Complex& n1, const Complex& n2) {

     return  Complex(n1.real - n2.real, n1.imag - n2.imag);
 }
Complex operator*(const Complex& n1, const Complex& n2) {

     return  Complex(n1.real * n2.real - n1.imag * n2.imag, n1.real * n2.imag+ n1.imag * n2.real);
 }

    int main()
    {
        Complex  c1(2, 3);
        Complex  c2(5, -4);
        Complex c3 = c1 + c2;
       /*等价于Complex*/
        //Complex c3 = c1.operator+(c2);//由于是类外定义使用,类内就可以是使用
        c3.print();
        Complex c4 = c1 - c2;
        c4.print();
        Complex c5 = c1 * c2;
        c5.print();
        return 0;
    }

编译器对类类型数据的双目运算符的处理(加法为例)

1.当编译器遇到fa+fb的代码,就会先去fa对应的类类型Fraction中寻找一个成员函数:
operator+(const Fraction &),如果有这个成员函数,就调用该函数计算  fa+fb ===> fa.operator+(fb); 
2.如果Fraction类中没有对应的成员函数,就去寻找一个全局函数:
operator+(const Fraction &,const Fraction &),如果有这个全局函数,就调用该函数计算  fa+fb ===> operator+(fa,fb);
3.全局函数也没有,编译器报错           

其他的双目运算符

== != > < >= <= (返回bool类型) = += -= (返回第一操作数的引用) //当类中有拷贝构造函数,=运算符才需要重载

类类型和基本类型之间的运算

Complex+浮点数 ----- 可以重载成成员函数/全局函数 浮点数+Complex ----- 只能重载成全局函数

重载也是可以加上参数的(写法有改变的)

Complex operator+(const double &num) {

        return  Complex(this->real + num, this->imag);
    }
#include <iostream>
using namespace std;

class Complex {
public:
     Complex(double real = 0, double imag = 0) :real(real), imag(imag) {}
    //打印
    void print()
    {
        cout << this->real << (this->imag>=0 ? " +":"") << this->imag << "i" << endl;
    }
   
    Complex operator+(const double &num) {

        return  Complex(this->real + num, this->imag);
    }

    //-----------------------------------------
    // 如果必须要在类内定义的话,只能定义为单参数的运算符函数: friend  Num operator+(const Num& n1);
    // 如果定义为双参数的运算符函数,只能在类外定义
    //-------------------------------------

private:
    double real;
    double imag;
};

    int main()
    {
        Complex cp(4, 2);

        Complex cp1 = cp + 2;
        cp1.print();
        //如果要常数在前面,改重载方法里的参数就可以了
       
        return 0;
    }

注意:

当使用非本类类型去初始化一个新对象时,先尝试使用初始化数据作为参数去调用构造函数构造成本类型对象,要支持该语法类中必须具有以初始化数据类型作为参数的单参构造函数。

如果不希望C++编译器使用该隐式转换,可以在类的构造函数声明前加 explicit 关键字

#include <iostream>
using namespace std;

class Complex {
public:
     explicit Complex(double real = 0, double imag = 0) :real(real), imag(imag) {}
    //打印
    void print()
    {
        cout << this->real << (this->imag>=0 ? " +":"") << this->imag << "i" << endl;
    }
   
    Complex operator+(const double &num) {

        return  Complex(this->real + num, this->imag);
    }

    //-----------------------------------------
    // 如果必须要在类内定义的话,只能定义为单参数的运算符函数: friend  Num operator+(const Num& n1);
    // 如果定义为双参数的运算符函数,只能在类外定义
    //-------------------------------------

private:
    double real;
    double imag;
};

    int main()
    {
        Complex cp(4, 2);

        Complex cp1 = cp + 2.1;
        cp1.print();
        //如果要常数在前面,改重载方法里的参数就可以了
       
        return 0;
    }

输入输出运算符的重载(cout<< cin>>)

cin>>a

1.先去cin对应的类istream中寻找一个成员函数:istream& operator>>(a的引用类型) 
2.如果没有,就去寻找一个全局函数:istream& operator<<(istream &is,a的引用类型); 
3.如果再没有,报错 //istream是C++预定义的类,不能修改,因此开发者只能通过全局函数重载 //并且将重载函数设置为a类型的友元          
/*08-双目运算符的重载*/
#include <iostream>
using namespace std;

class Complex {
public:
     Complex(double real = 0, double imag = 0) :real(real), imag(imag) {}
    //打印
    void print()
    {
        cout << this->real <<(this->imag>=0 ? "+":"")<< this->imag << "i" << endl;
    }
   
    Complex operator+(const double &num) {

        return  Complex(this->real + num, this->imag);
    }

    friend istream& operator>>(istream& is, Complex& c);

      
private:
    double real;
    double imag;
};
istream& operator>>(istream &is,Complex &c ) {

    return  is >> c.real >> c.imag;
}
    int main()
    {
        Complex  c1;

        cin >> c1;
        c1.print();

       
        return 0;
    }

cout<<

1.先去cout对应的类ostream中寻找一个成员函数:ostream& operator<<(a的常引用类型) 2.如果没有,就去寻找一个全局函数:ostream& operator<<(ostream &os,a的常引用类型); 3.如果再没有,报错 //ostream是C++预定义的类,不能修改,因此开发者只能通过全局函数重载 //并且将重载函数设置为a类型的友元

/*08-双目运算符的重载*/
#include <iostream>
using namespace std;

class Complex {
public:
     Complex(double real = 0, double imag = 0) :real(real), imag(imag) {}
    //打印
    //void print()
    //{
    //    cout << this->real <<(this->imag>=0 ? "+":"")<< this->imag << "i" << endl;
    //}

    friend istream& operator>>(istream& is, Complex& c);
    friend ostream& operator<<(ostream& is, const Complex& c);
      
private:
    double real;
    double imag;
};
istream& operator>>(istream &is,Complex &c ) {

    return  is >> c.real >> c.imag;
}

ostream& operator<<(ostream & os,const Complex &c ) {

    return  os << c.real << (c.imag >= 0 ? "+" : "") << c.imag << "i" << endl;
}
    int main()
    {

        Complex  c1;

        cin >> c1;
        //c1.print();


        cout << c1;
        //c1.print();

        return 0;
    }

练习:

为Fraction类实现 ==,>,+=,>>,<<的重载

3.单目运算符的重载

/*08-单目运算符的重载*/
#include <iostream>
using namespace std;

class Interger {
public:
    Interger(int d = 0) :data(d) {}
    //重载-号(负号)
    Interger operator-()  //!!!!
    {
        return Interger(-this->data);
    }
    int get_data() {
        return this->data;
    }

    friend ostream& operator<<(ostream& os, const Interger& i);
private:
    int data;
};

ostream& operator<<(ostream& os, const Interger& i)
{
    return os << i.data;
}
    int main()
    {

        Interger  i1(10);

        Interger  i2;

        i2 = -i1;
        cout << i2 << endl;

        return 0;
    }

++,–的重载

/*03-单目运算符的重载*/
#include <iostream>

using namespace std;

class Interger{
public:
    Interger(int d=0):data(d){}

    //重载-号(负号)
    Interger operator-()
    {
        return Interger(-this->data);
    }

    //重载前++
    Interger& operator++()
    {
        ++this->data;
        return *this;
    }

    //重载后--
    Interger operator--(int)
    {
        return Interger(this->data--);
    }

    friend ostream& operator<<(ostream &os,const Interger &i);
    friend Interger operator++(Interger &i,int);
    friend Interger& operator--(Interger &i);

private:
    int data;
};

ostream& operator<<(ostream &os,const Interger &i)
{
    return os<<i.data;
}
//--------------
//重载后++  
//后++要有哑元
//--------------
Interger operator++(Interger &i,int)
{
    return Interger(i.data++);
}

//重载前--
Interger& operator--(Interger &i)
{
    --i.data;
    return i;
}

int main()
{
    Interger i1(10);
    Interger i2(20);

    //i2 = -i1;
    //cout<<i2<<endl;

    //i2 = ++i1;
    //i2 = i1++;
    //i2 = --i1;
    i2 = i1--;
    cout<<-i1<<endl;
    cout<<i2<<endl;

    return 0;
}

编译器对单目运算符(#)的处理

对象 ----- 去成员函数中找一个operator#()的一个函数 如果没有,就去全局函数中找一个operator#(对象) 再没有就报错 对象# ----- 去成员函数中找一个operator#(int)的一个函数 如果没有,就去全局函数中找一个operator#(对象,int) 再没有就报错

练习:

实现Float类(浮点类),重载 前后++(成员函数) 前后–(全局函数),<<,-(负号),=,+=

class Float{ //… private: double data; }

运算符重载的限制

以下运算符不能重载

?: . :: sizeof && || & |

不能发明运算符

@ $

不能改变运算符的特性,符合对象的运算属性

不能重载基本类型的运算,重载时至少要有一个是类类型

只能重载成全局函数的运算符

第一个操作数是C++预定义类型 >> << 第一操作数是基本类型 整数+类类型

只能重载成成员函数的运算符

=(+= -= *=) ------ 赋值运算符 [] -------- 数组对象(把对象当数组使用) () -------- 强转,函数对象(把对象当函数使用) -> * ------ 指针对象(把对象当指针使用)


特殊运算符的重载

数组对象

当对象遇到[]运算符时,在成员函数中找一个 operator,如果没有就报错

/*01-重载拷贝构造*/
#include <iostream>
#include <cstring>

using namespace std;

class MyArray {
public:
    //构造函数
    MyArray(int* arr = NULL, size_t len = 10) :len(len)
    {
        //分配空间 ----- 默认抛异常
        this->pdata = new int[this->len];
        //初始化数组元素
        if (arr) {
            //传入了数组就使用数组的数据进行初始化
            memcpy(this->pdata, arr, this->len * sizeof(int));
        }
        else {
            //没有传数组就初始化为0
            memset(this->pdata, 0, this->len * sizeof(int));
        }
    }

    //析构函数
    ~MyArray()
    {
        delete[] this->pdata;
    }

    //拷贝构造函数
    MyArray(const MyArray& arr) :len(arr.len)/*初始化参数列表*/
    {
        //this->len = arr.len;
        this->pdata = new int[this->len];
        memcpy(this->pdata, arr.pdata, this->len * sizeof(int));
    }
   //----------------------------------------
    //重载=运算符
    MyArray& operator=(const MyArray& arr)
    {
        //防止自赋值  防止出现arr1=arr1的情况
        if (this == &arr)
            return *this;

        //释放旧空间
        delete[] this->pdata;
        //申请空间
        this->pdata = new int[arr.len];
        this->len = arr.len;
        //拷贝数据
        for (size_t i = 0; i < arr.len; i++) {
            this->pdata[i] = arr.pdata[i];
        }

        return *this;
    }
 //数组对象,重载[]
    int& operator[](int n)
    {
        return this->pdata[n];
    }

    //重载<<
    friend ostream& operator<<(ostream& os, const MyArray& arr);

private:
    int* pdata;
    /*const */size_t len;
};

ostream& operator<<(ostream& os, const MyArray& arr)
{
    for (size_t i = 0; i < arr.len - 1; i++)
        os << arr.pdata[i] << ",";

    return os << arr.pdata[arr.len - 1];
}

int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9 };
    MyArray arr2(arr, 9);
    cout << arr2 << endl;
    MyArray arr1 = arr2;
    cout << arr1 << endl;
    return 0;
}

强转和函数对象

强转

当编译器遇到 (类型)对象 语法时,就回去对象对应的类中寻找一个 operator 类型() 的成员函数,找不到就按默认强转/报错来处理。

函数对象

当编译器遇到 对象(实参) 语法时,就回去对象对应的类中寻找一个 operator()(参数) 的成员函数,找不到就报错。

/*01-重载拷贝构造*/
#include <iostream>
#include <cstring>

using namespace std;

class MyArray {
public:
    //构造函数
    MyArray(int* arr = NULL, size_t len = 10) :len(len)
    {
        //分配空间 ----- 默认抛异常
        this->pdata = new int[this->len];
        //初始化数组元素
        if (arr) {
            //传入了数组就使用数组的数据进行初始化
            memcpy(this->pdata, arr, this->len * sizeof(int));
        }
        else {
            //没有传数组就初始化为0
            memset(this->pdata, 0, this->len * sizeof(int));
        }
    }

    //析构函数
    ~MyArray()
    {
        delete[] this->pdata;
    }

    //拷贝构造函数
    MyArray(const MyArray& arr) :len(arr.len)/*初始化参数列表*/
    {
        //this->len = arr.len;
        this->pdata = new int[this->len];
        memcpy(this->pdata, arr.pdata, this->len * sizeof(int));
    }
    //----------------------------------------
     //重载=运算符
    MyArray& operator=(const MyArray& arr)
    {
        //防止自赋值  防止出现arr1=arr1的情况
        if (this == &arr)
            return *this;

        //释放旧空间
        delete[] this->pdata;
        //申请空间
        this->pdata = new int[arr.len];
        this->len = arr.len;
        //拷贝数据
        for (size_t i = 0; i < arr.len; i++) {
            this->pdata[i] = arr.pdata[i];
        }

        return *this;
    }
    //数组对象,重载[]
    int& operator[](int n)
    {
        return this->pdata[n];
    }

    //重载(强转) ------ (int)得到数组第一个元素
    operator int()
    {
        return this->pdata[0];
    }


    //强转(size_t),得到数组长度
    operator size_t()
    {
        return this->len;
    }


    //重载() ----- 函数对象 ---- 数组求和
    int operator()(const MyArray& arr)
    {
        int sum = 0;
        for (size_t i = 0; i < arr.len; i++) {
            sum += arr.pdata[i];
        }

        return sum;
    }
    //重载<<
    friend ostream& operator<<(ostream& os, const MyArray& arr);

private:
    int* pdata;
    /*const */size_t len;
};

ostream& operator<<(ostream& os, const MyArray& arr)
{
    for (size_t i = 0; i < arr.len - 1; i++)
        os << arr.pdata[i] << ",";

    return os << arr.pdata[arr.len - 1];
}

int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9 };
    MyArray arr2(arr, 9);
    cout << arr2 << endl;
    MyArray arr1 = arr2;
    cout << arr1[2] << endl;
    MyArray arr1 = arr2;

    //强转(size_t),得到数组长度
    cout << (size_t)arr1 << endl;

    //重载(强转) ------ (int)得到数组第一个元素
    cout << (int)arr1 << endl;

    //重载() ----- 函数对象 ---- 数组求和
    cout << arr1(arr2) << endl;
    return 0;
}

指针对象 ( 把对象当指针用)

当编译器遇到 对象-> 语法时,就会去对象对应的类中寻找一个 operator->() 的成员函数,找不到就报错。

当编译器遇到 对象 语法时,就会去对象对应的类中寻找一个 operator() 的成员函数,找不到就报错。

使用指针对象把对象当指针用,目的是管理其他对象的指针。

如果指针对象再结合模板的语法,就是可以实现管理各种类型指针的智能指针。

/*02-指针对象*/
#include <iostream>
#include <cstring>

using namespace std;

class A{
public:
    A(){cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}

    void show()
    {
        cout<<"show A"<<endl;
    }
};

//实现一个指针对象,管理A类型的指针
class myauto_ptr{
public:
    myauto_ptr(A *p=NULL):pdata(p)
    {
        cout<<"myauto_ptr()"<<endl;
    }

    ~myauto_ptr()
    {
        cout<<"~myauto_ptr()"<<endl;
        if(this->pdata)
            delete this->pdata;
    }

    //重载->运算符
    A *operator->()
    {
        return this->pdata;
    }

    //重载*运算符
    A& operator*()
    {
        return *this->pdata;
    }

private:
    A *pdata;//要管理的指针
};

int main()
{
    A *pa = new A;

    //使用指针对象管理pa ----- 无需再释放pa
    myauto_ptr ap(pa);

    //通过指针对象访问管理的指针指向的成员
    ap->show();
    //ap.operator->()->show();

    //解引用指针对象得到管理对象
    (*ap).show();
    //ap.operator*().show();

    return 0;
}

练习:

设计一个产品类(Product),记录包括单价(double price)和数量(int count)的成员

1.实现强转语法 (double) ----- 得到单价 (int) ----- 得到数量 2.实现函数对象,计算自己的总价 Product pd(19.8,12); pd() ===> 19.8 X 12 = 237.6

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

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

相关文章

YOLOv8 图像分割

一、背景 二、环境配置 官网&#xff1a;Previous PyTorch Versions | PyTorch cuda 11.7 pytorch 1.13.0 torchvision 0.14.0 pytorch-cuda 11.7 三、安装yolov8 官网&#xff1a;GitHub - ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONNX &…

Mendix 10 树形组件分析及应用

一、前言 产品研发目标是服务于业务&#xff0c;解决具体业务问题&#xff0c;带来业务价值。 因此&#xff0c;任何产品功能的推出&#xff0c;都应该秉承“从实践中来&#xff0c;到实践中去”的原则&#xff0c;在实战中发现问题&#xff0c;通过新功能设计和功能改进解决…

chatgpt科普

引言 chatgpt没有国内开放&#xff0c;为什么如此重要。抛开技术细节&#xff0c;少用专业名词&#xff0c;在整体功能上讲解 ChatGPT 的工作原理、制造过程、涌现的能力、未来的影响以及如何应对。让大家明白&#xff1a; ChatGPT是如何回答问题的。 它是怎么被制造的&…

Go语言实现单链表

博主最近在学习Go语言&#xff0c;所以打算更新一期Go语言版本的数据结构。这篇文章将的是Go语言如何实现单链表。 文章目录 前言一、个人见解&#xff0c;为什么学GO&#xff1f;二、Go语言实现单链表1.创建节点2.通过数组创建一个单链表3.遍历单链表4.单链表插入操作4.1 伪代…

HOOPS Visualize SDK 2023 Crack

桌面和移动工程应用程序的图形引擎 HOOPS Visualize 是 3D 图形 SDK&#xff0c;支持来自市场领导者 Hexagon、Trimble、Ansys、SOLIDWORKS、™ Autodesk 等的数百个工程应用程序。 用于 3D CAD 渲染的图形 SDK HOOPS Visualize 是一个以工程为中心的高性能图形库&#xff0c…

安卓蓝牙ATT协议介绍

介绍 ATT&#xff0c;Attribute Protocol&#xff0c;用于发现、读、写对端设备的协议(针对BLE设备) ATT允许蓝牙远程设备&#xff08;比如遥控器&#xff09;作为服务端提供拥有关联值的属性集&#xff0c;让作为客户端的设备&#xff08;比如手机、电视&#xff09;来发现、…

通用能力及AI核心能力表现优异!合合信息智能文档处理系统(IDP)高评级通过中国信通院评估

数字经济快速发展的背后&#xff0c;全球数据总量呈现出爆发式增长趋势。智能文档处理&#xff08;IDP&#xff09;技术能够高效地从多格式文档中捕捉、提取和处理数据&#xff0c;帮助机构和企业大幅提升文档处理效率&#xff0c;节约时间和人力成本。近期&#xff0c;合合信息…

C语言进阶--字符函数与内存函数

目录 一.字符函数 1.strlen函数 模拟实现strlen 2.strcpy函数 模拟实现strcpy 3.strcat函数 模拟实现strcat strcat能否用于自己追加自己&#xff1f; 4.strcmp函数 模拟实现strcmp 5.strncpy函数 6.strncat函数 7.strncmp函数 模拟实现strncmp 8.strstr函数 模…

哨兵2号数据下载与利用Python处理(波段融合、降采样、可视化、裁剪等)

简单介绍 网址:https://scihub.copernicus.eu/dhus/#/home 哨兵2号(Sentinel-2)是欧洲空间局(European Space Agency,简称ESA)推出的一组遥感卫星,旨在为地球观测和环境监测提供高质量的光学图像数据。 S2MSI2A是哨兵2号卫星的一种传感器。 S2MSI2A是哨兵2号卫星搭载…

huggingface - PEFT.参数效率微调

GitHub - huggingface/peft: &#x1f917; PEFT: State-of-the-art Parameter-Efficient Fine-Tuning. 最先进的参数高效微调 (PEFT) 方法 Parameter-Efficient Fine-Tuning (PEFT) 方法可以使预训练语言模型 (PLM) 高效适应各种下游应用程序&#xff0c;而无需微调模型的所有…

记录--Vue3 封装 ECharts 通用组件

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 按需导入的配置文件 配置文件这里就不再赘述&#xff0c;内容都是一样的&#xff0c;主打一个随用随取&#xff0c;按需导入。 import * as echarts from "echarts/core"; // 引入用到的图表…

ctfshow web入门 php特性 web93-97

1.web93 intval($num,0),0代表根据变量类型进行使用哪一种进制进行取整 可以使用8进制&#xff0c;正负数&#xff0c;小数点 payload: 010574 4476.0 4476.0 2.web94 过滤了0&#xff0c;不能使用8进制了&#xff0c;还可以使用小数点&#xff0c;正负数等 payload&#xff1…

【Java算法题】剑指offer_算法之02动态规划

对于动态规划问题&#xff0c;我将拆解为如下五步曲&#xff0c;这五步都搞清楚了&#xff0c;才能说把动态规划真的掌握了&#xff01; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 JZ42 连续子数组的…

CTFshow-pwn入门-栈溢出pwn35-pwn36

pwn35 首先还是先下载pwn文件拖进虚拟机加上可执行权限&#xff0c;使用checksec命令查看文件的信息。 chmod x pwn checksec pwn32位的我们直接拖进ida中反编译&#xff1a; // main int __cdecl main(int argc, const char **argv, const char **envp) {FILE *stream; // […

阿里云 OSS介绍

1、什么是阿里云 OSS&#xff1f; OSS 为 Object Storage Service&#xff0c;即对象存储服务。是阿里云提供的海量、安全、低成本、高可靠的云存储服务。 OSS 具有与平台无关的 RESTful API 接口&#xff0c;可以在任意应用、任意时间、任意地点 存储与访问 任何类型的数据。…

软考:软件工程:软件可行性分析,需求分析,ER实体图,数据流图,状态转换图,数据字典

软考&#xff1a;软件工程: 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &#xff08;1&#…

微信小程序——分页组件的创建与使用

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

使用Aspose.Words将word转PDF并且去水印。

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;Java、工具类、转换、word转pdf、Aspose.Words、后端☀️每日 一言&#xff1a;只要思想不滑坡&#xff0c;办法总比困难多。 前言 在我们日常开发中经常会有将word文档转为PDF的场景&#xff0…

深入理解循环队列----循环数组实现ArrayDeque

我们知道队列这种数据结构的物理实现方式主要还是两种&#xff0c;一种是链队列&#xff08;自定义节点类&#xff09;&#xff0c;另一种则是使用数组实现&#xff0c;两者各有优势。此处我们将要介绍的循环队列其实是队列的一种具体实现&#xff0c;由于一般的数组实现的队列…

IP地址分类

IP地址是TCP/IP协议中非常关键的要素之一&#xff0c;它用于标识网络中的设备和主机。根据使用版本的不同&#xff0c;IP地址分为IPv4和IPv6两种类型。 IPv4&#xff08;Internet Protocol version 4&#xff09;是IP地址的第四个版本&#xff0c;采用32位二进制数来表示IP地址…