《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;
		else
			cout << "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;
	else
		return 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] << " ";
		}
	}
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

民国漫画杂志《时代漫画》第29期.PDF

时代漫画29.PDF: https://url03.ctfile.com/f/1779803-1248635405-bf3c87?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

分享之远程调试

1:在线上启动脚本添加如下的内容&#xff1a; #! /bin/sh# 设置启动的jar SERVICE_NAME"xxx.jar"PRJ_BIN_DIR$(dirname $(readlink -f "$0")) SERVICE_HOME$(dirname $PRJ_BIN_DIR)LOGS_DIR$SERVICE_HOME/logs # 控制台日志 STDOUT_FILE$SERVICE_HOME/log…

New Phytologist:杨树特有miRNA在调控杨树抗旱中的分子机制

2024年3月6日&#xff0c;林木遗传育种全国重点实验室、北京林业大学生物科学与技术学院尹伟伦与夏新莉教授课题组在New Phytologist&#xff08;中科院一区&#xff0c;影响因子9.4&#xff09;期刊发表了题为“The miR6445-NAC029 module regulates drought tolerance by reg…

Python3 笔记:Python的所有关键字

查看Python的关键字首先需要用import导入keyword模块 import keyword # 查看Python的所有关键字&#xff0c;先用import导入keyword模块 print(keyword.kwlist) 运行结果&#xff1a; [False, None, True, and, as, assert, async, await, break, class, continue, def, …

96.网络游戏逆向分析与漏洞攻防-ui界面的设计-角色管理功能的界面设计

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

QT使用gsoap获取手机归属地

1-环境变量 用的win32 E:\hes_scc\tools\gsoap_2.8.134\gsoap-2.8\gsoap\bin\win32 2-生成代码接口 自己建一个目录&#xff0c;在此打开cmd窗口&#xff0c;生成的文件都会在这个文件夹中。 这里用的手机归宿地。 wsdl2h -o GetPhoneInfo.h -s -n Phone -t ....\typemap.…

DES加密算法笔记

【DES加密算法&#xff5c;密码学&#xff5c;信息安全】https://www.bilibili.com/video/BV1KQ4y127AT?vd_source7ad69e0c2be65c96d9584e19b0202113 根据此视频学习 DES是对称密码中的分组加密算法 (分组加密对应流加密算法) 流加密算法就是一个字节一个字节加密 分组加…

SSL协议:网络安全通信的守护者

在网络通信迅猛发展的今天&#xff0c;数据安全和隐私保护变得尤为重要。安全套接层协议&#xff08;Secure Sockets Layer, SSL&#xff09;作为早期网络加密及身份验证的基石&#xff0c;为在线数据传输提供了安全保障。下面我们就来了解一下SSL协议。 SSL协议概述 SSL协议最…

NSSCTF | [SWPUCTF 2021 新生赛]no_wakeup

打开题目后&#xff0c;点击三个&#xff1f;&#xff0c;发现是一个php序列化脚本 <?phpheader("Content-type:text/html;charsetutf-8"); error_reporting(0); show_source("class.php");class HaHaHa{public $admin;public $passwd;public function…

System32文件夹千万不能删除,看完这篇你就知道为什么了

序言 C:\Windows\System32目录是Windows操作系统的关键部分,重要的系统文件存储在该目录中。网上的一些恶作剧者可能会告诉你删除它,但你不应该尝试去操作,如果你尝试的话,我们会告诉你会发生什么。 什么是System32文件夹 位于C:\Windows\System32的System32文件夹是所有…

OpenHarmony应用开启Service以及完成自启动和常驻

一.背景 由于有需求实现一个后台常驻服务,这里就是来实现在鸿蒙里面如何实现后台服务并且实现自启动和常驻 二.添加服务 如下来添加服务 然后此时直接运行这个hap是报错的,如下: 此处参考: 应用中添加ServiceExtensionAbility然后安装HAP时提示“code:9568344 error: inst…

计算机二级Access操作题总结——基本操作

基础操作题 设置主键 例&#xff1a;将“线路”表中的“线路ID”字段设置为主键 ①右键单击“线路”表&#xff1b; ②单击【设计视图】&#xff1b; ③鼠标指到表的第一行→“线路ID”处&#xff0c;右键单击&#xff1b; ④单击【主键】 设置有效性规则 例&#xff1a;设…

算法之背包问题

可分的背包问题是可以用贪心法来解决&#xff0c;而0-1背包问题通常使用动态规划方法来解决。 可分背包问题&#xff1a; 在可分背包问题中&#xff0c;物品可以被分割&#xff0c;您可以取走物品的一部分以适应背包的容量。这里的关键是物品的价值密度&#xff0c;即单…

【电路笔记】-二阶滤波器

二阶滤波器 二阶(或双极)滤波器由两个连接在一起的 RC 滤波器部分组成,可提供 -40dB/十倍频程滚降率。 1、概述 二阶滤波器也称为 VCVS 滤波器,因为运算放大器用作压控电压源放大器,是有源滤波器设计的另一种重要类型,因为与我们之前研究过的有源一阶 RC 滤波器一起,…

常见排序算法之选择排序

目录 一、选择排序 1.1 什么是选择排序&#xff1f; 1.2 思路 1.2.1 思路一 1.2.2 优化思路 1.3 C语言源码 1.3.1 思路一 1.3.2 优化思路 二、堆排序 2.1 调整算法 2.1.2 向上调整算法 2.1.3 向下调整算法 2.2 建堆排序 一、选择排序 1.1 什么是选择排序&#xf…

985上交应届生转正12天,被某东辞退了!

&#x1f447;我的小册 45章教程:(小白零基础用Python量化股票分析小册) ,原价299&#xff0c;限时特价2杯咖啡&#xff0c;满100人涨10元。 01.事情起源 最近粉丝群都在转发一个截图&#xff0c;某应届毕业生在某东实习一年&#xff0c;才转正才12天&#xff0c;就因为自己调侃…

打包软件注意

1.建个文件夹D:333 /Dalsa_Cameras /cam1 cam2 2. 3.缺的包 4.自动启动.exe exe快捷方式放一起

增强创作者能力:The Sandbox 首届 “创作者挑战” 回顾

首届 "创作者挑战" 为创作者在平台上赚取收入提供了难得机会。 我们发起 “创作者挑战” 的目的是支持创作者&#xff0c;赋予他们构建元宇宙的能力。我们提出三大行动号召&#xff1a;发布、参与和赚钱。新推出的「参与奖池」&#xff08;Engagement Pool&#xff0…

深度学习500问——Chapter09:图像分割(3)

文章目录 9.8 PSPNet 9.9 DeepLab系列 9.9.1 DeepLabv1 9.9.2 DeepLabv2 9.9.3 DeeoLabv3 9.9.4 DeepLabv3 9.8 PSPNet 场景解析对于无限制的开放词汇和不同场景来说是具有挑战性的。本文使用文中的 pyramid pooling module 实现基于不同区域的上下文集成&#xff0c;提出了PS…

长三角智能科技高端盛会—南京人工智能展览会(南京智博会)

南京&#xff0c;作为一座历史悠久的文化名城&#xff0c;早已不仅仅以其深厚的文化底蕴和独特的自然风貌著称于世。而今&#xff0c;这座古老而又年轻的城市&#xff0c;正以其卓越的科技实力和创新精神&#xff0c;成为中国乃至全球科研领域的一颗璀璨明珠。南京不仅是中国三…