C++ Prime Plus 学习笔记041

书籍:C++ Primer Plus (第六版)(中文版)

工具:Dev-C++ 5.11

电脑信息:Intel® Xeon® CPU E5-2603 v3 @ 1.60GHz

系统类型:64位操作系统,基于X64的处理器 windows10 专业版

第18章 探讨C++新标准

18.1 复习前面介绍过的C++11功能

实例18.1

rvref.cpp

cpp 复制代码
#include <iostream>
inline double f(double tf) { return 5.0 * (tf - 32) / 9.0; };
 
int main()
{
   // std::cout << "Hello World!\n";
	using namespace std;
	double tc = 21.5;
	double && rd1 = 7.07;
	double&& rd2 = 1.8 * tc + 32;
	double&& rd3 = f(rd2);
 
	cout << "tc value and address :" << tc <<", "<< & tc << endl;
	cout << "rd1 value and address :" << rd1 << ", " << &rd1 << endl;
	cout << "rd2 value and address :" << rd2 << ", " << &rd2 << endl;
	cout << "rd3 value and address :" << rd3 << ", " << &rd3 << endl;
	cin.get();
	return 0;
}

编译运行结果:

cpp 复制代码
tc value and address :21.5, 0x6ffdd8
rd1 value and address :7.07, 0x6ffde0
rd2 value and address :70.7, 0x6ffde8
rd3 value and address :21.5, 0x6ffdf0

18.2 移动语义和右值引用

实例18.2

useless.cpp

cpp 复制代码
// useless.cpp -- an otherwise useless class with move semantics
#include<iostream>
using namespace std;

// interface
class Useless {
private:
    int n;      // number of elements
    char * pc;      // pointer to data
    static int ct;  // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f); // regular copy constructor
    Useless(Useless && f);      // move constructor
    ~Useless();
    Useless operator+(const Useless & f) const;
    // need operator=() in copy and move versions
    void ShowData() const;
};

// implematation
int Useless::ct = 0;

Useless::Useless() {
    ++ct;
    n = 0;
    pc = nullptr;
    cout << "default constructor called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(int k) : n(k) {
    ++ct;
    cout << "int constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    ShowObject();
}

Useless::Useless(int k, char ch) : n(k) {
    ++ct;
    cout << "int, char constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    for(int i = 0; i < n; i++){
        pc[i] = ch;
    }
    ShowObject();
}

Useless::Useless(const Useless & f): n(f.n) {
    ++ct;
    cout << "copy constructor called; number of objects: " << ct << endl;
    pc = new char[n];
    for (int i = 0; i < n; i++){
        pc[i] = f.pc[i];
    }
    ShowObject();
}

Useless::Useless(Useless && f) : n(f.n) {
    ++ct;
    cout << "move constructor called; number of objects: " << ct << endl;
    pc = f.pc;      // steal address
    f.pc = nullptr;     // give old object nothing in return
    f.n = 0;
    ShowObject();
}

Useless::~Useless() {
    cout << "destructor called; objects left: " << --ct << endl;
    cout << "deleted object:\n";
    ShowObject();
    delete [] pc;
}

Useless Useless::operator+(const Useless &f) const {
    cout << "Entering operator+()\n";
    Useless temp = Useless(n+f.n);
    for (int i = 0; i < n; i++) {
        temp.pc[i] = pc[i];
    }
    for (int i = n; i < temp.n; i++){
        temp.pc[i] = f.pc[i-n];
    }
    cout << "temp object:\n";
    cout << "Leaving operator+()\n";
    return temp;
}

void Useless::ShowObject() const {
    cout << "Number of element: " << n;
    cout << " Data address: " << (void *) pc << endl;
}

void Useless::ShowData() const {
    if (n == 0 ) {
        cout << "(object empty)";
    }
    else {
        for (int i = 0; i< n; i++){
            cout << pc[i];
        }
    }
    cout << endl;
}

// application
int main() {
    {
        Useless one(10, 'x');
        Useless two = one;      // calss copy constructor
        Useless three(20, 'o');
        Useless four (one + three); // calls operator+(), move contructor
        cout << "object one: ";
        one.ShowData();
        cout << "object two: ";
        two.ShowData();
        cout << "object three: ";
        three.ShowData();
        cout << "object four: ";
        four.ShowData();
    }
}

编译运行结果:

cpp 复制代码
int, char constructor called; number of objects: 1
Number of element: 10 Data address: 0xab1900
copy constructor called; number of objects: 2
Number of element: 10 Data address: 0xab1510
int, char constructor called; number of objects: 3
Number of element: 20 Data address: 0xab1530
Entering operator+()
int constructor called; number of objects: 4
Number of element: 30 Data address: 0xab5940
temp object:
Leaving operator+()
object one: xxxxxxxxxx
object two: xxxxxxxxxx
object three: oooooooooooooooooooo
object four: xxxxxxxxxxoooooooooooooooooooo
destructor called; objects left: 3
deleted object:
Number of element: 30 Data address: 0xab5940
destructor called; objects left: 2
deleted object:
Number of element: 20 Data address: 0xab1530
destructor called; objects left: 1
deleted object:
Number of element: 10 Data address: 0xab1510
destructor called; objects left: 0
deleted object:
Number of element: 10 Data address: 0xab1900

--------------------------------
Process exited after 0.3316 seconds with return value 0
请按任意键继续. . .

实例18.3

stdmove.cpp

cpp 复制代码
// stdmove.cpp -- using std::move()
#include<iostream>
#include<utility>

// interface
class Useless {
private:
    int n;  // number of elements
    char * pc;  // pointer to data
    static int ct;  // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f);     // regular copy constructor
    Useless(Useless && f);          // move constructor
    ~Useless();
    Useless operator+(const Useless & f) const;
    Useless & operator=(const Useless & f);     // copy assignment
    Useless & operator=(Useless && f);          // move assignment
    void ShowData() const;
};


// implementation
int Useless::ct = 0;

Useless::Useless() {
    ++ct;
    n = 0;
    pc = nullptr;
}

Useless::Useless(int k) : n(k) {
    ++ct;
    pc = new char[n]; 
}

Useless::Useless(int k, char ch) : n(k) {
    ++ct;
    pc = new char[n];
    for (int i = 0; i < n; i++ ){
        pc[i] = ch;
    }
}

Useless::Useless(const Useless & f): n(f.n) {
    ++ct;
    pc = new char[n];
    for(int i = 0; i < n; i++ ){
        pc[i] = f.pc[i];
    }
}

Useless::Useless(Useless && f) : n(f.n) {
    ++ct;
    pc = f.pc;      // steal address
    f.pc = nullptr; // give old object nothing in return
    f.n = 0;
}

Useless::~Useless() {
    delete [] pc;
}

Useless & Useless::operator=(const Useless & f) {   // copy assignment
    std::cout << "copy assignment operator called:\n";
    if (this == &f){
        return *this;
    }
    delete[] pc;
    n = f.n;
    pc = new char[f.n];
    for (int i = 0; i < n; i++){
        pc[i] = f.pc[i];
    }
    return *this;
}

Useless & Useless::operator=(Useless && f) {  // move assignment
    std::cout << "move assignment operator called:\n";
    if (this == &f) {
        return *this;
    }
    delete [] pc;
    n = f.n;
    pc = f.pc;
    f.n = 0;
    f.pc = nullptr;
    return *this;
}

Useless Useless::operator+(const Useless &f) const {
    Useless temp = Useless(n + f.n);
    for (int i = 0; i< n; i++){
        temp.pc[i] = pc[i];
    }
    for (int i = n; i < temp.n; i++){
        temp.pc[i] = f.pc[i-n];
    }
    return temp;
}

void Useless::ShowObject() const {
    std::cout << "Number of elements: " << n;
    std::cout << " Data address: " << (void *) pc << std::endl;
}

void Useless::ShowData() const {
    if (n == 0){
        std::cout << "(object empty)";
    }
    else{
        for (int i = 0; i < n; i++){
            std::cout << pc[i];
        }
    }
    std::cout << std::endl;
}

// application
int main(){
    using std::cout;{
        Useless one(10, 'x');
        Useless two = one + one;   // calls move contructor
        cout << "object one: ";
        one.ShowData();
        cout << "object two: ";
        two.ShowData();
        Useless three, four;
        cout << "three = one\n";
        three = one;
        cout << "now object three = ";
        three.ShowData();
        cout << "and object one = ";
        one.ShowData();
        cout << "four = one + two\n";
        four = one + two;       // automatic move assignment
        cout << "now object four = ";
        four.ShowData();
        cout << "four = move(one)\n";
        four = std::move(one);      // forced move assignment
        cout << "now object four = ";
        four.ShowData();
        cout << "and object one = ";
        one.ShowData();
    }

    return 0;
}

编译运行结果:

cpp 复制代码
object one: xxxxxxxxxx
object two: xxxxxxxxxxxxxxxxxxxx
three = one
copy assignment operator called:
now object three = xxxxxxxxxx
and object one = xxxxxxxxxx
four = one + two
move assignment operator called:
now object four = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
four = move(one)
move assignment operator called:
now object four = xxxxxxxxxx
and object one = (object empty)

--------------------------------
Process exited after 0.3382 seconds with return value 0
请按任意键继续. . .

18.3 新的类功能

18.4 Lamnda函数

实例18.4

lambda0.cpp

cpp 复制代码
// lambda0.cpp -- using lambda expressions
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size1 = 39L;
const long Size2 = 100*Size1;
const long Size3 = 100*Size2;
 
bool f3(int x) {return x % 3 == 0;}
bool f13(int x) {return x % 13 == 0;}
 
int main()
{
    using std::cout;
    std::vector<int> numbers(Size1);
 
    std::srand(std::time(0));
    std::generate(numbers.begin(), numbers.end(), std::rand);
 
// using function pointers
    cout << "Sample size = " << Size1 << '\n';
 
    int count3 = std::count_if(numbers.begin(), numbers.end(), f3);
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    int count13 = std::count_if(numbers.begin(), numbers.end(), f13);
    cout << "Count of numbers divisible by 13: " << count13 << "\n\n";
 
// increase number of numbers
    numbers.resize(Size2);
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size2 << '\n';
// using a functor
    class f_mod
    {
    private:
        int dv;
    public:
        f_mod(int d = 1) : dv(d) {}
        bool operator()(int x) {return x % dv == 0;}
    };
 
    count3 = std::count_if(numbers.begin(), numbers.end(), f_mod(3));
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    count13 = std::count_if(numbers.begin(), numbers.end(), f_mod(13));
    cout << "Count of numbers divisible by 13: " << count13 << "\n\n";
 
// increase number of numbers again
    numbers.resize(Size3);
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size3 << '\n';
// using lambdas
    count3 = std::count_if(numbers.begin(), numbers.end(),
             [](int x){return x % 3 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    count13 = std::count_if(numbers.begin(), numbers.end(),
              [](int x){return x % 13 == 0;});
    cout << "Count of numbers divisible by 13: " << count13 << '\n';
 
    // std::cin.get();
    return 0;
}

编译运行结果:

cpp 复制代码
Sample size = 39
Count of numbers divisible by 3: 15
Count of numbers divisible by 13: 2

Sample size = 3900
Count of numbers divisible by 3: 1340
Count of numbers divisible by 13: 304

Sample size = 390000
Count of numbers divisible by 3: 129983
Count of numbers divisible by 13: 30221

--------------------------------
Process exited after 0.3764 seconds with return value 0
请按任意键继续. . .

实例18.5

lambda1.cpp

cpp 复制代码
// lambda1.cpp -- use captured variables
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size = 390000L;
 
int main()
{
    using std::cout;
    std::vector<int> numbers(Size);
 
    std::srand(std::time(0));
    std::generate(numbers.begin(), numbers.end(), std::rand);
    cout << "Sample size = " << Size << '\n';
// using lambdas
    int count3 = std::count_if(numbers.begin(), numbers.end(), 
		      [](int x){return x % 3 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    int count13 = 0;
    std::for_each(numbers.begin(), numbers.end(),
         [&count13](int x){count13 += x % 13 == 0;});
    cout << "Count of numbers divisible by 13: " << count13 << '\n';
// using a single lambda
    count3 = count13 = 0;
    std::for_each(numbers.begin(), numbers.end(),
         [&](int x){count3 += x % 3 == 0; count13 += x % 13 == 0;});
    cout << "Count of numbers divisible by 3: " << count3 << '\n';
    cout << "Count of numbers divisible by 13: " << count13 << '\n';
 
    // std::cin.get();
    return 0;
}

编译运行结果:

cpp 复制代码
Sample size = 390000
Count of numbers divisible by 3: 129681
Count of numbers divisible by 13: 30080
Count of numbers divisible by 3: 129681
Count of numbers divisible by 13: 30080

--------------------------------
Process exited after 0.9402 seconds with return value 0
请按任意键继续. . .

18.5 包装器

实例18.6

somedefs.h

cpp 复制代码
// somedefs.h
#include <iostream>
 
template <typename T, typename F>
  T use_f(T v, F f)
  {
      static int count = 0;
      count++;
      std::cout << "use_f count = " << count
		        << ", &count = " << &count << std::endl;
      return f(v);
  }
 
  class Fp
  {
  private:
      double z_;
  public:
      Fp(double z = 1.0) : z_(z) {}
      double operator()(double p) { return z_*p; }
  };
 
  class Fq
  {
  private:
      double z_;
  public:
      Fq(double z = 1.0) : z_(z) {}
      double operator()(double q) { return z_+ q; }
  };

callable.cpp

cpp 复制代码
// callable.cpp -- callable types and templates
#include <iostream>
#include"somedefs.h"
using namespace std;
 
double dub(double x) { return 2.0 * x; }
double square(double x) { return x * x; }
 
int main()
{
	double y = 1.21;
	cout << "Function pointer dub:\n";
	cout << "  " << use_f(y, dub) << endl;
	cout << "Function pointer sqrt:\n";
	cout << "  " << use_f(y, square) << endl;
	cout << "Function object Fp:\n";
	cout << "  " << use_f(y, Fp(5.0)) << endl;
	cout << "Function object Fq:\n";
	cout << "  " << use_f(y, Fq(5.0)) << endl;
	cout << "Lambda expression 1:\n";
	cout << "  " << use_f(y, [](double u) {return u * u; }) << endl;
	cout << "Lambda expresson 2:\n";
	cout << "  " << use_f(y, [](double u) {return u + u / 2.0; }) << endl;
 
	return 0;
}

编译运行结果:

cpp 复制代码
Function pointer dub:
use_f count = 1, &count = 0x487060
  2.42
Function pointer sqrt:
use_f count = 2, &count = 0x487060
  1.4641
Function object Fp:
use_f count = 1, &count = 0x487040
  6.05
Function object Fq:
use_f count = 1, &count = 0x487050
  6.21
Lambda expression 1:
use_f count = 1, &count = 0x4a7034
  1.4641
Lambda expresson 2:
use_f count = 1, &count = 0x4a7038
  1.815

--------------------------------
Process exited after 0.3259 seconds with return value 0
请按任意键继续. . .

实例18.8

wrapped.cpp

cpp 复制代码
// wrapped0.cpp  -- using a function wrapper
#include "somedefs.h"
#include <iostream>
#include <math.h>
#include <functional>
 
double dub(double x) { return 2.0 * x; }
double sqaure(double x) { return x * x; }
int main()
{
	using std::cout;
	using std::endl;
	using std::function;

	double y = 1.21;
	function<double(double)> ef1 = dub;
	function<double(double)> ef2 = sqaure;
	function<double(double)> ef3 = Fq(10.0);
	function<double(double)> ef4 = Fp(10.0);
	function<double(double)> ef5 = [](double u) {return u * u; };
	function<double(double)> ef6 = [](double u) {return u + u / 2.0; };
	cout<<"Function pointer dub:\n";
	cout << use_f(y, ef1) << endl;
	cout<<"Function pointer square:\n";
	cout << use_f(y, ef2) << endl;
	cout<<"Function object Fp:\n";
	cout << use_f(y, ef3) << endl;
	cout<<"Function object FQ:\n";
	cout << use_f(y, ef4) << endl;
	cout<<"Function expression 1:\n";
	cout << use_f(y, ef5) << endl;
	cout<<"Function expression 2:\n";
	cout << use_f(y, ef6) << endl;
 
	return 0;
}

编译运行结果:

cpp 复制代码
Function pointer dub:
use_f count = 1, &count = 0x489040
2.42
Function pointer square:
use_f count = 2, &count = 0x489040
1.4641
Function object Fp:
use_f count = 3, &count = 0x489040
11.21
Function object FQ:
use_f count = 4, &count = 0x489040
12.1
Function expression 1:
use_f count = 5, &count = 0x489040
1.4641
Function expression 2:
use_f count = 6, &count = 0x489040
1.815

--------------------------------
Process exited after 0.2212 seconds with return value 0
请按任意键继续. . .

18.6 可变参数模板

实例18.9

variadic1.cpp

cpp 复制代码
//variadic1.cpp -- using recursion to unpack a parameter pack
#include <iostream>
#include <string>
// definition for 0 parameters -- terminating call
void show_list3() {}
 
// definition for 1 or more parameters
template<typename T, typename... Args>
void show_list3(T value, Args... args)
{
	std::cout << value << ", ";
	show_list3(args...);
}
 
int main()
{
	int n = 14;
	double x = 2.71828;
	std::string mr = "Mr. String objects!";
	show_list3(n, x);
	show_list3(x*x, '!', 7, mr);
	return 0;
}

编译运行结果:

cpp 复制代码
14, 2.71828, 7.38905, !, 7, Mr. String objects!,
--------------------------------
Process exited after 0.323 seconds with return value 0
请按任意键继续. . .

实例18.10

variadic2.cpp

cpp 复制代码
// variadic2.cpp
#include <iostream>
#include <string>
 
// definition for 0 parameters
void show_list() {}
 
// definition for 1 parameter
template<typename T>
void show_list(const T& value)
{
    std::cout << value << '\n';
}
 
// definition for 2 or more parameters
template<typename T, typename... Args>
void show_list(const T& value, const Args&... args)
{
    std::cout << value << ", ";
    show_list(args...); 
}
 
int main()
{
    int n = 14;
    double x = 2.71828;
    std::string mr = "Mr. String objects!";
    show_list(n, x);
    show_list(x*x, '!', 7, mr);
    return 0;
}

编译运行结果:

cpp 复制代码
14, 2.71828
7.38905, !, 7, Mr. String objects!

--------------------------------
Process exited after 0.3245 seconds with return value 0
请按任意键继续. . .

18.7 C++11新增的其他功能

18.8 语言变化

实例18.11

lexcast.cpp

cpp 复制代码
// lexcast.cpp -- simple cast from float to string
#include <iostream>
#include <string>
#include "boost/lexical_cast.hpp"
int main()
{
	using namespace std;
	cout << "Enter your weight: ";
	float weight;
	cin >> weight;
	string gain = "A 10% increase raises ";
	string wt = boost::lexical_cast<string>(weight);
	gain = gain + wt + " to ";  // string operator+()
	weight = 1.1 * weight;
	gain = gain + boost::lexical_cast<string>(weight) + ".";
	cout << gain << endl;
	return 0;
}

编译运行结果:

没有安装boost库,编译失败!

18.9 接下来的任务

附录E 其它运算符

E.1 按位运算符

E.2 成员解除引用运算符

实例E.1 memb_pt.cpp

cpp 复制代码
// memb_pt.cpp -- simple cast from float to string
#include <iostream>
using namespace std;

class Example
{
	private:
		int feet;
		int inches;
	public:
		Example();
		Example(int ft);
		~Example();
		void show_in() const;
		void show_ft() const;
		void use_ptr() const;
};
Example::Example()
{
	feet=0;
	inches=0;
}

Example::Example(int ft)
{
	feet=ft;
	inches=12*feet;
}

Example::~Example()
{
}

void Example::show_in() const
{
	cout<<inches<<" inches\n";
}

void Example::show_ft() const
{
	cout<<feet<<" feet\n";
}

void Example::use_ptr() const
{
	Example yard(3);
	int Example::*pt;
	
	pt=&Example::inches;	
	cout<<" Set pt to &Example::inches:\n";
	cout<<" this->pt:"<<this->*pt<<endl;
	cout<<" yard.*pt:"<<yard.*pt<<endl;
	
	pt=&Example::feet;	
	cout<<" Set pt to &Example::feet:\n";
	cout<<" this->pt:"<<this->*pt<<endl;
	cout<<" yard.*pt:"<<yard.*pt<<endl;	
	
	void(Example::*pf)() const;
	pf=&Example::show_in;	
	cout<<" Set pf to &Example::show_in:\n";
	cout<<" Using (this->*pf)(): ";
	(this->*pf)();
	cout<<" Using (yard.*pt)(): ";
	(yard.*pf)();
}

int main()
{
	Example car(15);
	Example van(20);
	Example garage;
	
	cout << "car use_ptr() output:\n";
	car.use_ptr();
	cout<<"\nvan.use_ptr() output:\n";
	van.use_ptr();
	
	return 0;
}

编译运行结果:

cpp 复制代码
car use_ptr() output:
 Set pt to &Example::inches:
 this->pt:180
 yard.*pt:36
 Set pt to &Example::feet:
 this->pt:15
 yard.*pt:3
 Set pf to &Example::show_in:
 Using (this->*pf)(): 180 inches
 Using (yard.*pt)(): 36 inches

van.use_ptr() output:
 Set pt to &Example::inches:
 this->pt:240
 yard.*pt:36
 Set pt to &Example::feet:
 this->pt:20
 yard.*pt:3
 Set pf to &Example::show_in:
 Using (this->*pf)(): 240 inches
 Using (yard.*pt)(): 36 inches

--------------------------------
Process exited after 0.319 seconds with return value 0
请按任意键继续. . .

附录E.3 alignof (C++11)

实例E.2 align.cpp

cpp 复制代码
// memb_pt.cpp -- simple cast from float to string
#include <iostream>
using namespace std;

class things1
{
	char ch;
	int a;
	double x;
};
class things2
{
	int a;
	double x;
	char ch;
};

int main()
{
	things1 th1;
	things2 th2;
	
	cout << "char alignment: "<<alignof(char)<<endl;
	cout << "int alignment: "<<alignof(int)<<endl;
	cout << "double alignment: "<<alignof(double)<<endl;
	cout << "thing1 alignment: "<<alignof(things1)<<endl;
	cout << "thing2 alignment: "<<alignof(things2)<<endl;
	cout << "thing1 size: "<<sizeof(things1)<<endl;
	cout << "thing2 size: "<<sizeof(things2)<<endl;
	
	return 0;
}

编译运行结果:

cpp 复制代码
char alignment: 1
int alignment: 4
double alignment: 8
thing1 alignment: 8
thing2 alignment: 8
thing1 size: 16
thing2 size: 24

--------------------------------
Process exited after 0.3231 seconds with return value 0
请按任意键继续. . .
相关推荐
_风华ts2 小时前
虚函数与访问权限
c++
1001101_QIA2 小时前
C++中不能复制只能移动的类型
开发语言·c++
万岳科技系统开发2 小时前
私域直播小程序源码的整体架构设计与实现思路
学习·小程序
闻缺陷则喜何志丹2 小时前
【组合数学】P9418 [POI 2021/2022 R1] Impreza krasnali|普及+
c++·数学·组合数学
richxu202510012 小时前
嵌入式学习之路>单片机核心原理篇>(11) 存储器(Flash & SRam)
单片机·嵌入式硬件·学习
sszdlbw2 小时前
后端springboot框架入门学习--第二篇
java·spring boot·学习
晨曦夜月2 小时前
头文件与目标文件的关系
linux·开发语言·c++
刃神太酷啦2 小时前
C++ list 容器全解析:从构造到模拟实现的深度探索----《Hello C++ Wrold!》(16)--(C/C++)
java·c语言·c++·qt·算法·leetcode·list
9527(●—●)3 小时前
windows系统python开发pip命令使用(菜鸟学习)
开发语言·windows·python·学习·pip