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

《C++ Primer Plus》第十二章复习题和编程练习

目录

  • 一、复习题
  • 二、编程练习

一、复习题

1. 假设String类有如下私有成员:

// String 类声明
class String
{
private: char* str;int len;// ...
};

a. 下述默认构造函数有什么问题?

String::String() { }  // 默认构造函数

b. 下述构造函数有什么问题?

String::String(const char* s)  // 构造函数
{str = s;len = strlen;
}

c. 下述构造函数有什么问题?

String::String(const char* s)  // 构造函数
{strcpy(str, s);len = strlen(s);
}

答:注意:下面的代码需要包含相应的头文件和using声明。
a. 该默认函数并未进行任何操作,则成员变量str与len的值是未知的(和创建局部变量未初始化一个道理)。而String类涉及动态内存分配,所以需要给str适当初始化(一般初始化为空指针——nullptr)。
修改如下:

String::String()  // 默认构造函数
{str = nullptr;len = 0
}

b. 该构造函数中语句str = s; 只是单纯地让str和s指向同一个字符串,str只是存储了s指向的字符串的首地址,这是浅拷贝。而我们需要拷贝存储字符串的副本(深拷贝)。
修改如下:

String::String(const char* s)
{len = strlen(s);  // 存储字符串的长度,不包括空字符str = new char[len + 1];  // 申请空间,别忘了空字符'\0'strcpy(str, s);  // 拷贝字符串内容副本
}

c. 还未在堆上申请空间,str指向的地方是未知的,直接使用函数strcpy()进行内容拷贝会导致不确定的问题。
修改如下:

String::String(const char* s)
{len = strlen(s);  // 存储字符串的长度,不包括空字符str = new char[len + 1];  // 申请空间,别忘了空字符'\0'strcpy(str, s);  // 拷贝字符串内容副本
}

2. 如果你定义了一个类,其指针成员是使用new初始化的,请指出可能出现的三个问题及如何纠正这些问题?

答:
1)问题:没有定义对应的析构函数,和使用对应的delete运算符的形式。
纠正:使用new为成员指针分配空间需要对应的析构函数来释放空间,使用什么形式申请空间就需要使用什么形式释放空间,如:int * pi = new int; —— delete pi; ,int* pa = new int[5];——delete[5]pa;。而且所有构造函数只能使用上面相同的一种new形式,使之与析构函数中的delete形式对应。
2)问题:没有定义相关的复制构造函数。
纠正:如果没有定义赋值构造函数,编译器会提供默认的复制构造函数,其只能进行浅拷贝,只能复制需要拷贝的内容的地址。需要定义相关的复制构造函数进行深拷贝,为拷贝内容申请空间。
3)问题:没有重载对应的赋值运算符
纠正:和问题2一样,如果没有重载赋值运算符,编译器也会提供默认的,同样是浅拷贝。我们需要定义相关的赋值运算符,来进行深度拷贝。需要先释放前面存储的动态空间,然后根据拷贝大小申请新的空间。

3. 如果没有显示提供类方法,编译器将自动生成哪些类方法?请描述这些隐式生成的函数的行为。

答:
1)若没有提供构造函数,则编译器会提供一个默认构造函数,该函数什么都不做,但允许声明数组和未初始化的对象。
2)若没有提供析构函数,则编译器会提供一个默认析构函数,该函数什么都不做。
3)若没有提供拷贝构造函数,则编译器会提供一个默认的拷贝构造函数,该函数进行浅拷贝。
4)若没有提供赋值运算符重载,则编译器会提供默认的赋值运算符重载,该函数也进行浅拷贝。
5)若没有提供地址运算符重载,则编译器会提供默认的地址运算符重载,该函数返回调用对象的地址,也就是this指针的值。

4. 找出并改正下述类声明中的错误。

// nifty 类声明
class nifty
{// 数据char personality[];int talents;// 方法nifty();nifty(char* s);ostream& operator<<(ostream& os, nifty& n);
};nifty::nifty()
{personality = NULL;talents = 0;
}nifty::nifty(char* s)
{personality = new char[strlen(s)];personality = s;talents = 0;
}ostream& nifty::operator<<(ostream& os, nifty& n)
{os << n;
}

答:首先,类声明中一般成员变量为私有成员(private),而成员函数为公有成员(public)。不显式声明时,类(class)默认为private,而结构(struct)默认为public。所以需要将成员函数声明为public。在默认构造函数中,personality是数组名也是指向第一个元素的char指针,但是其指向不能改变,可以使用strcpy()函数将其初始化为空字符串,参数s最好声明为const。在第二个提供一个参数的构造函数中,也是同样的问题。最后一个重载运算符(<<)函数需要被声明为友元函数,且该函数定义完全就是狗屁,我们都还没定义,你就用上了成品。根据上述问题,我们通过把变量personality修改为char指针,然后添加析构函数进行重写代码。(当然拷贝构造函数和赋值运算符重载也是需要的,读者可以自行编写)

下面是正确的代码:

// nifty 类声明
class nifty
{
private:// 数据char* personality;int talents;
public:// 方法nifty();nifty(const char* s);~nifty();friend ostream& operator<<(ostream& os, const nifty& n);
};// 类方法定义
nifty::nifty()  // 默认构造函数
{personality = nullptr;talents = 0;
}nifty::nifty(const char* s)  // 构造函数
{int len = strlen(s);personality = new char[len+1];strcpy(personality, s);talents = 0;
}nifty::~nifty()  // 析构函数
{if (personality != nullptr)delete[]personality;
}ostream& operator<<(ostream& os, const nifty& n)  // 运算符(<<)重载
{os << "Personality: " << personality << endl;os << "Talents: " << talents << endl;return os;
}

5. 对于下面的类声明,回答下面的问题。

// Golfer 类声明
class Golfer
{
private:char* fullname;  // 指向包含高尔夫的名称的字符串int games;  // 保存玩的高尔夫游戏的个数int* scores;  // 指向高尔夫分数数组的第一个元素
public:Golfer();Golfer(const char* name, int g = 0);Golfer(const Golfer& g);~Golfer();
};

a. 下列各条语句将调用哪些类方法?
1 Golfer nancy;
2 Golfer lulu(“Little Lulu”);
3 Golfer roy(“Roy Hobbs”, 12);
4 Golfer *par = new Golfer;
5 Golfer next = lulu;
6 Golfer hazzard = “Weed Thwacker”;
7 *par = nancy;
8 nancy = “Nancy Putter”;
b. 很明显,类需要有另外几个方法才能更有用,但是类需要哪些方法才能防止数据被损坏呢?

答:
a.

  1. 调用默认构造函数。
  2. 调用一个参数的构造函数。
  3. 调用两个参数的构造函数。
  4. 调用默认构造函数。
  5. 调用编译器提供的默认的复制构造函数。
  6. 先调用一个参数的构造函数创建临时对象,然后调用编译器提供的默认复制构造函数。
  7. 调用编译器提供的默认的赋值运算符重载函数。
  8. 先调用一个参数的构造函数创建临时对象,然后调用编译器提供的默认的赋值运算符重载函数。

b. 由于编译器提供的默认的复制构造函数和赋值运算符重载函数都是浅拷贝,所以需要用户自己定义复制构造函数和赋值运算符重载函数来对对象实行深度拷贝,避免程序出现问题。

二、编程练习

1. 对于下面的类声明,为这个类提供实现,并编写一个使用所有成员函数的小程序。

// Cow 类声明
class Cow
{
private:char name[20];char* hobby;double weight;
public:Cow();  // 默认构造函数Cow(const char* nm, const char* ho, double wt);Cow(const Cow& c);  // 复制构造函数~Cow();  // 析构函数Cow& operator=(const Cow& c);  // 赋值运算符重载void ShowCow() const;  // 显示所有有关于奶牛的数据
};

答:三个文件。

Cow.h头文件

#pragma once// 头文件
#include <iostream>// Cow 类声明
class Cow
{
private:char name[20];char* hobby;double weight;
public:Cow();  // 默认构造函数Cow(const char* nm, const char* ho, double wt);Cow(const Cow& c);  // 复制构造函数~Cow();  // 析构函数Cow& operator=(const Cow& c);  // 赋值运算符重载void ShowCow() const;  // 显示所有有关于奶牛的数据
};

main.cpp测试文件

// 头文件
#include "Cow.h"// using 声明
using std::cout;
using std::endl;int main()
{// 默认构造函数Cow cow1;cow1.ShowCow();cout << endl;// 三个参数的构造函数Cow cow2("若雪", "干饭", 888.8);cow2.ShowCow();cout << endl;// 复制构造函数Cow cow3(cow2);cow3.ShowCow();cout << endl;// 赋值运算符cow3 = cow1;cow3.ShowCow();cout << endl;return 0;
}

Cow.cpp方法定义文件

// 头文件
#include "Cow.h"
#include <cstring>// using 声明
using std::cout;
using std::endl;Cow::Cow()  // 默认构造函数
{strcpy(name, "小雪");// 申请空间hobby = new char[strlen("吃草") + 1];strcpy(hobby, "吃草");weight = 888.0;
}Cow::Cow(const char* nm, const char* ho, double wt)
{strcpy(name, nm);// 申请空间hobby = new char[strlen(ho) + 1];strcpy(hobby, ho);weight = wt;
}Cow::Cow(const Cow& c)  // 复制构造函数
{strcpy(name, c.name);// 申请空间hobby = new char[strlen(c.hobby) + 1];strcpy(hobby, c.hobby);weight = c.weight;
}Cow::~Cow()  // 析构函数
{// 释放空间delete[]hobby;  // 与申请的格式对应
}Cow& Cow::operator=(const Cow& c)  // 赋值运算符重载
{if (this == &c)  // 检查是否给自己赋值{return *this;}else{strcpy(name, c.name);// 释放原来的空间delete[]hobby;// 申请新的空间hobby = new char[strlen(c.hobby) + 1];strcpy(hobby, c.hobby);weight = c.weight;return *this;}
}void Cow::ShowCow() const  // 显示所有有关于奶牛的数据
{cout << "Name: " << name << endl;cout << "Hobby: " << hobby << endl;cout << "Weight: " << weight << endl;
}

2. 通过完成下面的工作来改进String类的声明(即将String1.h升级为String2.h)。
a. 对+运算符进行重载,使之可以将两个字符串合并成一个。
b. 提供一个Stringlow()成员函数,将字符串中所有的字母字符转换为小写(注意cctype系列的字符函数)
c. 提供String()成员函数,将字符串中所有字母字符转换为大写。
d. 提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数。使用下面的程序来测试你的工作。

// 头文件
#include "String2.h"// using 声明
using std::cin;
using std::cout;
using std::endl;int main()
{String s1(" and I am a C++ student.");String s2 = "Please enter your name: ";String s3;cout << s2;cin >> s3;s2 = "My name is " + s3;cout << s2 << endl;s2 = s2 + s1;s2.Stringupper();cout << "The string\n" << s2 << "\ncontains " << s2.ch_times('A')<< " 'A' characters in it.\n";s1 = "red";String rgb[3] = { String(s1), String("green"), String("blue") };cout << "Enter the name of a primary color for mixing light: ";String ans;bool success = false;while (cin >> ans){ans.Stringlow();for (int i = 0; i < 3; ++i){if (ans == rgb[i]){cout << "That's right!\n";success = true;break;}}if (success)break;elsecout << "Try again!\n";}cout << "Bye\n";return 0;
}

输出应于下面相似。
Please enter your name: Fretta Farbo
My name is Fretta Farbo.
The string
My NAME IS FRETTA FARBO AND I AM A C++ STUDENT.
contains 6 ‘A’ characters in it.
Enter the name of a primary color for misxing light: yellow
Try again!
BLUE
That’s right!
Bye

答:两个文件。

String2.h头文件

#pragma once// 头文件
#include <iostream>// String 类声明
class String
{
private:char* str;  int len;  // 字符串长度static int num_strings;  // 目前有多少个String对象static const int CINLIM = 80;  // 输入的限制
public:String();  // 默认构造函数String(const char* s);String(const String& s);  // 复制构造函数~String();  // 析构函数int lenth() const { return len; }  // 返回字符串长度int ch_times(char key) const;  // 返回字符key在字符串中出现的次数void Stringlow();void Stringupper();String& operator=(const char* s);String& operator=(const String& s);char& operator[](int i);const char& operator[](int i) const;String operator+(const String& s) const;// 关系运算符重载friend bool operator<(const String& s1, const String& s2);friend bool operator>(const String& s1, const String& s2);friend bool operator==(const String& s1, const String& s2);friend String operator+(const char* s, const String& str);friend std::ostream& operator<<(std::ostream& os, const String& s);friend std::istream& operator>>(std::istream& is, String& s);// 静态成员函数static int HowMany();
};

String2.cpp方法定义文件

// 头文件
#include "String2.h"
#include <cctype>
#include <cstring>// using 声明
using std::endl;// 静态成员变量初始化
int String::num_strings = 0;String::String()  // 默认构造函数
{str = nullptr;len = 0;++num_strings;
}String::String(const char* s)
{len = strlen(s);// 申请空间str = new char[len + 1];strcpy(str, s);++num_strings;
}String::String(const String& s)  // 复制构造函数
{len = s.len;// 申请空间str = new char[len + 1];strcpy(str, s.str);++num_strings;}String::~String()  // 析构函数
{// 释放空间if (str != nullptr)delete[]str;
}int String::ch_times(char key) const  // 返回字符key在字符串中出现的次数
{int times = 0;for (int i = 0; i < len; ++i){if (str[i] == key)++times;}return times;
}void String::Stringlow()
{for (int i = 0; i < len; ++i){str[i] = tolower(str[i]);}
}void String::Stringupper()
{for (int i = 0; i < len; ++i){str[i] = toupper(str[i]);}
}String& String::operator=(const char* s)
{len = strlen(s);// 释放之前的空间delete[]str;// 申请新的空间str = new char[len + 1];strcpy(str, s);return *this;
}String& String::operator=(const String& s)
{len = s.len;// 释放之前的空间delete[]str;// 申请新的空间str = new char[len + 1];strcpy(str, s.str);return *this;
}char& String::operator[](int i)
{return str[i];
}const char& String::operator[](int i) const
{return str[i];
}String String::operator+(const String& s) const
{int total = len + s.len;// 申请空间char* result = new char[total + 1];strcpy(result, str);strcat(result, s.str);String tmp(result);// 释放空间delete[]result;return tmp;
}String operator+(const char* s, const String& str)
{int total = strlen(s) + str.len;// 申请空间char* result = new char[total + 1];strcpy(result, s);strcat(result, str.str);String tmp(result);// 释放空间delete[]result;return tmp;
}// 关系运算符重载
bool operator<(const String& s1, const String& s2)
{return (strcmp(s1.str, s2.str) < 0);
}bool operator>(const String& s1, const String& s2)
{return s2 < s1;
}bool operator==(const String& s1, const String& s2)
{return !strcmp(s1.str, s2.str);
}std::ostream& operator<<(std::ostream& os, const String& s)
{if (s.str != nullptr){os << s.str;}return os;
}std::istream& operator>>(std::istream& is, String& s)
{char tmp[String::CINLIM];is.getline(tmp, String::CINLIM);if (!is){is.clear();while (is.get() != '\n')continue;return is;}s = tmp;return is;
}// 静态成员函数
int String::HowMany()
{return num_strings;
}

运行结果
在这里插入图片描述

3. 重写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态分配的内存,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的程序。

答:使用动态内存分配,可以使用char*指针,也可以使用指向string类的指针。在构造函数中申请空间,在析构函数中释放空间,申请和释放的形式需要匹配。

Stock.h头文件

#pragma once// 头文件
#include <iostream>// Stock 类声明
class Stock
{
private:char* company;  // 股票公司名称int shares;  // 股票数量double share_val;  // 每份股票double total_val;  // 总值void set_tot() { total_val = share_val * shares; }  // 设置总值
public:Stock();  // 默认构造函数Stock(const char* co, int n, double pr);~Stock();  // 析构函数void buy(int num, double pr);  // 买进void sell(int num, double pr);  // 卖出void update(double pr);  // 更新价格// 运算符(<<)重载friend std::ostream& operator<<(std::ostream& os, const Stock& s);const Stock& topval(const Stock& s) const;  // 返回总值大的对象
};

main3.cpp测试文件

// 头文件
#include "Stock.h"// using 声明
using std::cin;
using std::cout;
using std::endl;// 符号常量声明
const int STKS = 4;int main()
{Stock stocks[STKS] = {Stock("NanoSmart", 12, 20.0),Stock("Boffo Objects", 200, 2.0),Stock("Monolithic Obelisks", 130, 3.25),Stock("Fleep Enterprises", 60, 6.5)};// 显示所有股票cout << "Stock holdings:\n";for (int i = 0; i < STKS; ++i)cout << stocks[i];// 找出总值最大的股票const Stock* top = &stocks[0];for (int i = 1; i < STKS; ++i)top = &top->topval(stocks[i]);cout << "\nMost valuable holding:\n";cout << *top << endl;return 0;
}

Stock.cpp方法定义文件

// 头文件
#include "Stock.h"
#include <cstring>// using 声明
using std::cout;
using std::endl;Stock::Stock()  // 默认构造函数
{company = nullptr;shares = 0;share_val = 0;set_tot();
}Stock::Stock(const char* co, int n, double pr)
{// 申请空间,拷贝公司名称int len = (int)strlen(co);company = new char[len + 1];strcpy(company, co);// 赋值其他成员shares = n;share_val = pr;set_tot();
}Stock::~Stock()  // 析构函数
{// 释放申请空间if (company != nullptr)delete[]company;
}void Stock::buy(int num, double pr)  // 买进
{if (num > 0){shares += num;share_val = pr;set_tot();}else{cout << "买进股票的数量不能为负";}
}void Stock::sell(int num, double pr)  // 卖出
{if (num < 0){cout << "卖出股票的数量不能为负";}else if (num > shares){cout << "卖出股票的数量不能超过自身拥有的股票数量";}else{shares -= num;share_val = pr;set_tot();}
}void Stock::update(double pr)  // 更新价格
{share_val = pr;
}// 运算符(<<)重载
std::ostream& operator<<(std::ostream& os, const Stock& s)
{os << "Company: " << s.company;os << " Shares: " << s.shares << endl;os << "  Share Price: $" << s.share_val;os << " Total Worth: $" << s.total_val << endl;return os;
}const Stock& Stock::topval(const Stock& s) const  // 返回总值大的对象
{if (total_val > s.total_val)return *this;elsereturn s;
}

4. 请看程序清单10.10定义的Stack类的变量。

#pragma once// 头文件
#include <iostream>// 类型声明
typedef unsigned long Item;// Stack 类声明
class Stack
{
private:enum { MAX = 10 };Item* pitems;int size;int top;
public:Stack(int n = MAX);Stack(const Stack& st);~Stack();bool isempty() const;bool isfull() const;bool push(const Item& item);bool pop(Item& item);Stack& operator=(const Stack& st);void get_info() const;
};

正如私有成员表明的,这个类使用动态分配的数组来保存栈中的项。请重新编写方法,以适应这种新的表示方法,并编写一个程序来演示所有的方法,包括复制构造函数和赋值运算符。

答:头文件上面有,这里就提供测试文件和方法定义文件。

main4.cpp测试文件

// 头文件
#include "Stack.h"// using 声明
using std::cout;
using std::endl;int main()
{// 默认构造函数Stack stack1;for (int i = 0; i < 5; ++i){stack1.push(i);}stack1.get_info();cout << endl;// 复制构造函数Stack stack2(stack1);stack2.get_info();cout << endl;Item tmp;stack2.pop(tmp);stack2.pop(tmp);stack2.get_info();cout << endl;// 赋值运算符stack1 = stack2;stack1.get_info();return 0;
}

Stack.cpp方法定义文件

// 头文件
#include "Stack.h"// using 声明
using std::cout;
using std::endl;Stack::Stack(int n)
{if (n > MAX){size = MAX;}else if (n > 0){size = n;}else{cout << "栈的大小不能为非正整数\n";size = top = 0;pitems = nullptr;return;}// 申请空间pitems = new Item[size];top = 0;
}Stack::Stack(const Stack& st)
{size = st.size;// 申请空间pitems = new Item[size];top = st.top;// 复制每个元素for (int i = 0; i < top; ++i)pitems[i] = st.pitems[i];
}Stack::~Stack()
{// 释放空间if (pitems != nullptr)delete pitems;
}bool Stack::isempty() const
{return top == 0;
}bool Stack::isfull() const
{return top == size;
}bool Stack::push(const Item& item)
{if (!isfull()){pitems[top++] = item;return true;}else{return false;}
}bool Stack::pop(Item& item)
{if (!isempty()){item = pitems[--top];return true;}else{return false;}
}Stack& Stack::operator=(const Stack& st)
{if (&st == this){return *this;}else{// 释放之前的空间delete[]pitems;// 申请新的空间size = st.size;pitems = new Item[size];// 赋值内容top = st.top;for (int i = 0; i < top; ++i){pitems[i] = st.pitems[i];}return *this;}
}void Stack::get_info() const
{if (pitems != nullptr){for (int i = 0; i < top; ++i){cout << pitems[i] << " ";}}
}

后面两题的答案作者没写,因为目前不是很懂,这些编程练习的答案都是我自己写的,然后运行验证的。作者今天就不加班了,偷个懒,明天早上把这两道题补上。

相关文章:

《C++ Primer Plus》第十二章复习题和编程练习

目录 一、复习题二、编程练习 一、复习题 1. 假设String类有如下私有成员&#xff1a; // String 类声明 class String { private: char* str;int len;// ... };a. 下述默认构造函数有什么问题&#xff1f; String::String() { } // 默认构造函数b. 下述构造函数有什么问题…...

2024 年科技裁员综合清单

推荐阅读&#xff1a; 独立国家的共同财富 美国千禧一代的收入低于父辈 创造大量就业机会却毁掉了财富 这四件事是创造国家财富的关键 全球财富报告证实联盟自始至终无能 美国人已陷入无休止债务循环中&#xff0c;这正在耗尽他们的财务生命 2024 年&#xff0c;科技行业…...

Linux系统编程学习笔记

1 前言 1.1 环境 平台&#xff1a;uabntu20.04 工具&#xff1a;vim,gcc,make 1.2 GCC Linux系统下的GCC&#xff08;GNU Compiler Collection&#xff09;是GNU推出的功能强大、性能优越的多平台编译器&#xff0c;是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执…...

vue3 excel 文件导出

//文件导出 在index.ts 中 export function downloadHandle(url: string,params?:object, filename?: string, method: string GET){ try { downloadLoadingInstance ElLoading.service({ text: "正在生成下载数据&#xff0c;请稍候", background: "rgba…...

优雅的代码规范

在软件开发中&#xff0c;优雅的代码规范可以帮助我们写出既美观又实用的代码。 以下是提升代码质量的建议性规范&#xff1a; 命名清晰&#xff1a; 使用描述性强的命名&#xff0c;让代码自我解释。 简洁性&#xff1a; 力求简洁&#xff0c;避免冗余&#xff0c;用最少的代…...

JVM、JRE 和 JDK 的区别,及如何解决学习中可能会遇到的问题

在学习Java编程的过程中&#xff0c;理解JVM、JRE和JDK之间的区别是非常重要的。它们是Java开发和运行环境的核心组件&#xff0c;各自扮演不同的角色。 一、JVM&#xff08;Java Virtual Machine&#xff09; 定义 JVM&#xff08;Java虚拟机&#xff09;是一个虚拟化的计算…...

【开源】加油站管理系统 JAVA+Vue.js+SpringBoot+MySQL

目录 一、项目介绍 论坛模块 加油站模块 汽油模块 二、项目截图 三、核心代码 一、项目介绍 Vue.jsSpringBoot前后端分离新手入门项目《加油站管理系统》&#xff0c;包括论坛模块、加油站模块、汽油模块、加油模块和部门角色菜单模块&#xff0c;项目编号T003。 【开源…...

详解 Scala 的泛型

一、协变与逆变 1. 说明 协变&#xff1a;Son 是 Father 的子类&#xff0c;则 MyList[Son] 也作为 MyList[Father] 的 “子类”逆变&#xff1a;Son 是 Father 的子类&#xff0c;则 MyList[Son] 作为 MyList[Father] 的 “父类”不变&#xff1a;Son 是 Father 的子类&…...

【本周面试问题总结】

01.如何判断链表中是否有环 ①穷举遍历&#xff1a;从头节点开始&#xff0c;依次遍历单链表中的每一个节点。每遍历到一个新节点&#xff0c;将新节点和此前节点进行比较&#xff0c;若已经存在则说明已被遍历过&#xff0c;链表有环。 ②快慢指针&#xff1a;创建两个指针&am…...

SaltStack

SaltStack 官方文档 1.简介 作用&#xff1a;批量处理状态管理&#xff08;配置管理&#xff09;事件驱动&#xff08;通过事件触发操作&#xff09;管理私有云/公有云 yum仓库&#xff1a;http://repo.saltstack.com 安装1.master和minionrpm --import https://repo.saltproj…...

【Rust日报】Rust 中的形式验证

文章 - 未来的愿景&#xff1a;Rust 中的形式验证 这篇文章回顾了形式化验证的基本概念&#xff0c;作者展示了如何使用 Hoare triples 来描述和推理程序的正确性&#xff0c;以及如何使用分离逻辑来解决验证的复杂性。文章还解释了为什么 Rust 适用于形式化验证&#xff0c;以…...

vue3项目中新增修改时使用nextTick时遇到的问题

前提 页面是个列表页&#xff0c;需要实现增删改查&#xff0c;新增和修改使用表单提交 关键代码如下 // html部分&#xff0c;新增、修改的表单 <el-dialogv-model"dialogVisible2":title"addTitle"width"600"class"update-shujuji-d…...

算法训练 | 二叉树Part7 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数

目录 530.二叉搜索树的最小绝对差 数组法 双指针法 ⭐ 迭代法 501.二叉搜索树中的众数 双指针法 迭代法 530.二叉搜索树的最小绝对差 题目链接&#xff1a;530. 二叉搜索树的最小绝对差 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 数组…...

C++面向对象程序设计 - 标准输出流

在C中&#xff0c;标准输出流通常指的是与标准输出设备&#xff08;通常是终端或控制台&#xff09;相关联的流对象。这个流对象在C标准库中被定义为std::cout、std::err、std::clog&#xff0c;它们是std::ostream类的一个实例。 一、cout&#xff0c;cerr和clog流 ostream类…...

警惕Mallox勒索病毒的最新变种hmallox,您需要知道的预防和恢复方法。

引言 &#xff1a; 在数字化时代&#xff0c;数据已成为企业和个人最宝贵的资产之一。然而&#xff0c;随着技术的不断发展&#xff0c;网络威胁也日益猖獗&#xff0c;其中.hmallox勒索病毒以其独特的加密手段和狡猾的传播方式&#xff0c;成为了网络安全领域的一颗“隐形炸弹…...

2024年华为OD机试真题-火星文计算-C++-OD统一考试(C卷D卷)

题目描述: 已知火星人使用的运算符为#、$,其与地球人的等价公式如下: x#y = 4*x+3*y+2 x$y = 2*x+y+3 1、其中x、y是无符号整数 2、地球人公式按C语言规则计算 3、火星人公式中,#的优先级高于$,相同的运算符,按从左到右的顺序计算 现有一段火星人的字符串报文,请…...

3.00001 postgres如何初始化系统参数?

文章目录 加载参数整体流程参数结构举例&#xff1a;ConfigureNamesBool 初始化参数 InitializeGUCOptionsbuild_guc_variablesInitializeOneGUCOptionInitializeGUCOptionsFromEnvironment 命令行添加SelectConfigFiles配置 加载参数整体流程 我们先看下guc参数是如何管理的。…...

C# 读取 CSV 文件的方法汇总

文章目录 1. 使用System.IO命名空间中的类2. 处理标题行和指定列3. 使用CsvHelper库4. 高级功能和异常处理5. 使用 LINQ6. 总结 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff09;文件是一种简单的文本文件格式&#xff0c;用于存储表格数据。在C#中&a…...

element+ 引入图标报错 Failed to resolve import “@element-plus/icons-vue“ from “

element 引入图标报错 Internal server error: Failed to resolve import “element-plus/icons-vue” from “src\components\TimeLine.vue”. Does the file exist? 原因&#xff1a;element-plus需要单独引入 icons 文档 pnpm install element-plus/icons-vue之后就可以…...

Github 2024-05-25 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-25统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3TypeScript项目3非开发语言项目1HTML项目1Rust项目1Go项目1Jupyter Notebook项目1Java项目1Angular文档:交付Web应用程序的自信之选…...

VPN的详细理解

VPN&#xff08;Virtual Private Network&#xff0c;虚拟私人网络&#xff09;是一种在公共网络上建立加密通道的技术&#xff0c;通过这种技术可以使远程用户访问公司内部网络资源时&#xff0c;实现安全的连接和数据传输。以下是对VPN的详细介绍&#xff1a; 选择代理浏览器…...

java后端轮播图的设计

对于表示轮播图位置这种有限且较小范围的数据&#xff0c;一般可以使用整数类型来表示。考虑到位置序号一般是非负整数且数量较少&#xff0c;可以选择使用小范围的整数类型&#xff0c;如下&#xff1a; 整数类型: 对于Java中&#xff0c;可以考虑使用 int 类型来表示位置序号…...

upload-labs 21关解析

目录 一、代码审计 二、实践 三、总结 一、代码审计 $is_upload false; $msg null; if(!empty($_FILES[upload_file])){//检查MIME$allow_type array(image/jpeg,image/png,image/gif);if(!in_array($_FILES[upload_file][type],$allow_type)){$msg "禁止上传该类型…...

常用汇编指令

&#xff08;arg&#xff09;argument&#xff1a;自变量&#xff0c;变元 &#xff08;reg&#xff09;register&#xff1a;寄存器 &#xff08;seg&#xff09;segment&#xff1a;段寄存器 &#xff08;mem&#xff09;memory&#xff1a;存储器&#xff08;内存单元&am…...

LabVIEW软件需求分析文档内容和编写指南

编写LabVIEW软件需求分析文档&#xff08;Software Requirements Specification, SRS&#xff09;是软件开发的关键步骤之一。以下是详细的内容结构、编写指南和注意事项&#xff1a; 内容结构 引言 项目背景&#xff1a;简要介绍项目背景和目的。 文档目的&#xff1a;说明需…...

spring cache(三)demo

目录 一、入门demo 1、pom 2、配置文件 3、config 4、controller 5、service 6、dao 7、dto与常量 8、测试&#xff1a; 8.1、无参 8.2、单参 &#xff08;1&#xff09;缓存与删除缓存 &#xff08;2&#xff09;删除缓存加入异常 二、自定义删除key 1、pom 2、…...

Android 应用开发语言选择对比

Android开发语言有多种&#xff0c;但是每种语言的各有不同的适用场景&#xff0c;对比介绍如下&#xff1a; 一.首选&#xff1a;原生应用Java&#xff0c;Kotlin 1.截至目前&#xff0c;大约有70%的Android开发者仍然使用Java语言进行开发&#xff0c;而30%的开发者则选择…...

Git 小白入门到进阶—(基本概念和常用命令)

一.了解 Git 基本概念和常用命令的作用 (理论) 基本概念 1、工作区 包含.git文件夹的目录&#xff0c;主要用存放开发的代码2、仓库 分为本地仓库和远程仓库&#xff0c;本地仓库是自己电脑上的git仓库(.git文件夹);远程仓库是在远程服务器上的git仓库git文件夹无需我们进行操…...

大数据框架总结(全)

☔️ 大数据框架总结&#xff08;全&#xff09; 关注“大数据领航员”&#xff0c;在公众号号中回复关键字【大数据面试资料】&#xff0c;即可可获取2024最新大数据面试资料的pdf文件 一. Hadoop HDFS读流程和写流程 HDFS写数据流程 &#xff08;1&#xff09;客户端通过…...

44、Flink 的 Interval Join 详解

Interval Join Interval join 组合元素的条件为&#xff1a;两个流&#xff08;暂时称为 A 和 B&#xff09;中 key 相同且 B 中元素的 timestamp 处于 A 中元素 timestamp 的一定范围内&#xff0c;即 b.timestamp ∈ [a.timestamp lowerBound; a.timestamp upperBound] 或…...