【C++初阶】类和对象(中)

news2024/12/23 22:13:04

目录

一.类的6个默认成员函数

1.知识引入 

​编辑 2.构造函数 

(1)概念 

(2)语法特性

(3)特征 

①问题引入1

②问题引入2  (缺少默认构造函数)

3.析构函数

(1)概念

(2)特性

4.拷贝构造函数 

(1)概念

(2)特征

①拷贝构造函数是构造函数的一个重载形式。

②拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。 

③若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象的内置类型成员按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。自定义类型成员调用它的拷贝构造。

5.赋值运算符重载  

 (1)运算符重载

① 语法及注意事项

(2)赋值运算符重载

二.总结 


一.类的6个默认成员函数

1.知识引入 

如果一个类中什么成员都没有,简称为空类

空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成6个默认成员函数。

默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数

  • 示例 

 2.构造函数 

(1)概念 

构造函数是一个特殊的成员函数,名字与类名相同,创建类 类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。 

  • 注意

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象

(2)语法特性

  1. 函数名与类名相同。
  2. 无返回值。(不是void,是就不需要写)
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载。
  •  示例 
class Date
{
public:
	Date()//构造函数
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	/*Date(int year=1,int month=1,int day=1)带参构造函数(函数重载)
	{
		_year = year;
		_month = month;
		_day = day;
	}*/
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
    //调用无参构造函数
	Date d1;
	d1.Print();

    //调用带参构造函数
	/*Date d2(2024,2,8);
	d2.Print();*/
	return 0;
}
  • 注意
 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
 warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)

//Date d3();

 通常情况只写一个构造函数,避免调用时存在歧义。

 (3)特征 

①问题引入1

关于编译器生成的默认成员函数,会有以下疑惑:不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但是d对象_year/_month/_day,依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么用?? 

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	
	Date d1;
	d1.Print();

	return 0;
}

  • 解答

 C++把类型分成内置类型(基本类型)自定义类型。内置类型就是语言提供的数据类型,如:int/char...,自定义类型就是我们使用class/struct/union等自己定义的类型。默认生成的构造函数,对于内置类型不做处理,自定义类型会去调用他的默认构造函数。 

class A
{
public:
	A()
	{
		cout <<"A()" << endl;
		_a = 0;
	}
private:
	int _a;
};
class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;//也可以在这里给缺省值
	int _month;
	int _day;

	A _aa;
};

int main()
{
	
	Date d1;
	d1.Print();

	return 0;
}
  •  结果显示

 ②问题引入2  (缺少默认构造函数)
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//也可以在声明时给缺省值
	int _year=1;
	int _month=1;
	int _day;

};

int main()
{
	
	Date d1;
	d1.Print();

	return 0;
}

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数全缺省构造函数我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。

问题存在:我们写了一个带参数的构造函数,编译器就不再给我们生成构造函数了。

  • 修改 
class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//也可以在声明时给缺省值
	int _year=1;
	int _month=1;
	int _day;

};

int main()
{
	Date d1;
	d1.Print();
	return 0;
}

3.析构函数

 (1)概念

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

(2)特性

1. 析构函数名是在类名前加上字符 ~。

2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。

4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

class Date
{
public:
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	~Date()
	{
		cout << this << endl;
		cout << "~Date()" << endl;
	}
private:
	//也可以在声明时给缺省值
	int _year=1;
	int _month=1;
	int _day;

};
void func()
{
	Date d2;
}
int main()
{
	func();

	Date d1;
	d1.Print();

	return 0;
}

 

4.拷贝构造函数 

(1)概念

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

(2)特征

①拷贝构造函数是构造函数的一个重载形式
//拷贝构造函数
class Date
{
public:
	Date(int year = 2024, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(const Date& d) // 错误写法:编译报错,会引发无穷递归
	 Date(const Date& d) // 正确写法
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2024,1,28);

	Date d2(d1);
	return 0;
}
②拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。 
  •  C++规定自定义类型的拷贝都会调用拷贝构造

而传引用传参则不再需要调用拷贝构造。 

  • 为什么会引发无穷递归 

③若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象的内置类型成员按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。自定义类型成员调用它的拷贝构造。
class Date
{
public:
	Date(int year = 2024, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	 void Print()
	 {
		 cout << _year << "-" << _month << "-" << _day << endl;
	 }
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024,1,28);
	Date d2(d1);

	d1.Print();
	d2.Print();

	return 0;
}
  • 深拷贝 
typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};
int main()
{
	Stack st1;
	Stack s2(st1);
	return 0;
}

程序最终崩溃,这是为什么呢?

  • 问题分析 

  • 代码修改(手写拷贝构造)
typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	//Stack st2(st1)
	Stack(const Stack& s)
	{
		DataType* tmp = (DataType*)malloc(sizeof(s._capacity * (sizeof(DataType))));
		if (tmp == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(tmp, s._array, sizeof(DataType) * s._size);

		_array = tmp;
		_size = s._size;
		_capacity = s._capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};
int main()
{
	Stack st1;
	Stack s2(st1);
	return 0;
}

5.赋值运算符重载  

 (1)运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 

① 语法及注意事项

函数原型:返回值类型 operator操作符(参数列表) 

  • 注意事项
  1. 不能通过连接其他符号来创建新的操作符:比如operator@
  2. 重载操作符必须有一个类类型参数
  3. 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  5. .*    ::    sizeof    ?:    .注意注意以上5个运算符不能重载。
  • 比较两个日期相等及小于(传统写法) 
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private:
	int _year;
	int _month;
	int _day;
};
//判断日期相等
bool DataEqual(const Date& x, const Date& y)
{
	return x._year == y._year
				&& x._month == y._month
				&& x._day == y._day;
}
//判断日期小于
bool DateLess(const Date& x, const Date& y)
{
	if (x._year < y._year)
	{
		return true;
	}
	else if (x._year == y._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if (x._month == y._month)
		{
			return x._day < y._day;
		}
	}
	return false;
}
int main()
{
	Date d1(2024, 1, 28);
	Date d2(2024, 2, 27);

    cout << DataEqual(d1, d2) << endl;
	cout << DateLess(d1, d2) << endl;
	return 0;
}

缺陷:由于函数名可能会存在取名字不规范的情况,将导致不知道这个函数的作用是什么。

因此采用运算符重载,来更容易让看代码的人知道这个代码的作用,增强代码可读性。 

  • 运算符重载写法 
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private:
	int _year;
	int _month;
	int _day;
};
//判断日期相等
bool operator==(const Date& x, const Date& y)
{
	return x._year == y._year
				&& x._month == y._month
				&& x._day == y._day;
}
//判断日期小于
bool operator<(const Date& x, const Date& y)
{
	if (x._year < y._year)
	{
		return true;
	}
	else if (x._year == y._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if (x._month == y._month)
		{
			return x._day < y._day;
		}
	}
	return false;
}
int main()
{
	Date d1(2024, 1, 28);
	Date d2(2024, 2, 27);

	cout << (d1==d2) << endl;//cout<<(operator==(d1,d2)<<endl;
	cout << (d1<d2) << endl;

	return 0;
}
  • 注意 

这里代码能执行是因为我们将类内的成员设置成了公有权限,否则在类外面是不能访问类里面的成员的。

  • 处理方式(将类外函数放入类内)
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//判断日期相等
	bool operator==( const Date& y)
	{
		return _year == y._year
			&& _month == y._month
			&& _day == y._day;
	}
	//判断日期小于
	bool operator<( const Date& y)
	{
		if (_year < y._year)
		{
			return true;
		}
		else if (_year == y._year)
		{
			if (_month < y._month)
			{
				return true;
			}
			else if (_month == y._month)
			{
				return _day < y._day;
			}
		}
		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 1, 28);
	Date d2(2024, 2, 27);

	cout <<d1.operator==(d2) << endl;
	cout << d1.operator<(d2) << endl;

	cout << (d1==d2) << endl;
	cout << (d1<d2) << endl;

	return 0;
}

(2)赋值运算符重载

赋值运算符重载格式 :

  1.  参数类型:const T&,传递引用可以提高传参效率
  2. 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  3. 检测是否自己给自己赋值
  4. 返回*this :要复合连续赋值的含义
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//d1=d2
	void operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 1, 28);
	Date d2(2024, 2, 27)

	Date d3(d1);//拷贝构造,同类型一个存在的对象进行初始化要创建的对象
	
	d1 = d2;//已经存在的对象,一个拷贝赋值给另一个
	d1.Print();
	d2.Print();


	return 0;
}
  • 返回值问题 
d1=d2=d3;

我们知道赋值操作是将右操作数赋值给左操作数,然后将左操作数作为返回值,因此该赋值函数需要有明确的返回值类型。因此要对上方代码进行部分修改:

    Date& operator=(const Date& d)//这里的“&”是引用
	{
		if (this != &d)//这里的“&”是取地址
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
  • 赋值运算符只能重载成类的成员函数不能重载成全局函数  
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	int _year;
	int _month;
	int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{
	if (&left != &right)
	{
		left._year = right._year;
		left._month = right._month;
		left._day = right._day;
	}
	return left;
}
// 编译失败:
// error C2801: “operator =”必须是非静态成员

原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值 运算符重载只能是类的成员函数。 

 

二.总结 

 

  

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

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

相关文章

css伪类函数 :is()、:where()、:has()、:not()

本文主要描述:is()、:where()、:has()、:not()&#xff0c;四个方法大部分内容相同&#xff0c;首先主要讲:is()方法&#xff0c;并根据:is()方法与:where()、:has()、:not()方法的不同来说明这三种方法的特性 :is() 使用方法 选择器特定性 安全性 伪类和伪元素的支持 :前…

Java 后端面试指南

面试指南 TMD&#xff0c;一个后端为什么要了解那么多的知识&#xff0c;真是服了。啥啥都得了解 MySQL MySQL索引可能在以下几种情况下失效&#xff1a; 不遵循最左匹配原则&#xff1a;在联合索引中&#xff0c;如果没有使用索引的最左前缀&#xff0c;即查询条件中没有包含…

【elasticsearch实战】知识库文件系统检索工具FSCrawler

需求背景 最近有一个需求需要建设一个知识库文档检索系统&#xff0c;这些知识库物料附件的文档居多&#xff0c;有较多文档格式如&#xff1a;PDF, Open Office, MS Office等&#xff0c;需要将这些格式的文件转化成文本格式&#xff0c;写入elasticsearch 的全文检索索引&am…

YOLO-World:实时开放词汇目标检测

paper&#xff1a;https://arxiv.org/pdf/2401.17270.pdf Github&#xff1a;GitHub - AILab-CVC/YOLO-World: Real-Time Open-Vocabulary Object Detection online demo&#xff1a;https://huggingface.co/spaces/stevengrove/YOLO-World 目录 0. 摘要 1. 引言 2. 相关工…

解决docker中运行的jar包连不上数据库

目录 数据库主机地址设置问题&#xff1a; 网络连接问题&#xff1a; 数据库端口映射&#xff1a; 数据库认证问题&#xff1a; 数据库服务是否正常运行&#xff1a; 日志查看&#xff1a; 如果在 Docker 中运行的 JAR 包无法连接到数据库&#xff0c;有几个可能的原因和…

优秀自媒体工作者常用的7款ai写作工具! #AI写作#AI写作

我们做自媒体运营&#xff0c;想要快速的创作内容&#xff0c;提供文章的创作速度是我们的目标&#xff0c;我们别的大佬可以很快地就创作出一篇内容&#xff0c;而自己墨迹半天确出不了一个字呢&#xff1f;其实这关乎到创作技巧&#xff0c;下面小编就跟大家分享如何利用自媒…

Linux的Ubuntu的APT使用

Linux的Ubuntu的APT使用 apt 介绍 apt 是 Advanced Packaging Tool 的简称&#xff0c;是一款安装包管理工具。在 Ubuntu 下&#xff0c;我们可以使用 apt 命令进行软件包的安装、删除、清理等&#xff0c;类似于 Windows 中的软件管理工具。 Ubuntu 软件操作的相关命令 su…

SD-WAN专线:助力企业海外社交媒体推广

随着全球化的发展&#xff0c;越来越多的企业将目光投向海外市场&#xff0c;而在海外市场推广中&#xff0c;社交媒体平台成为了一个重要的推广渠道。然而&#xff0c;很多企业在海外社交媒体推广过程中都会遇到网络问题&#xff0c;传统的VPN解决方案往往存在IP被封、网络不稳…

32单片机基础:GPIO输入

1.1按键控制LED 按键介绍&#xff1a; 两种方式&#xff0c;我们一般用下接的方式。 第一个图&#xff1a;注意点。当按键按下&#xff0c;PA0接地&#xff0c;被置为低电平&#xff0c; 但是一旦按键松手&#xff0c;PA0悬空&#xff0c;引脚电压不确定。所以无论怎么读引脚…

MySQL 核心模块揭秘 | 06 期 | 事务提交之前,binlog 写到哪里?

1. 准备工作 参数配置&#xff1a; binlog_format ROW binlog_rows_query_log_events OFF创建测试表&#xff1a; CREATE TABLE t_binlog (id int unsigned NOT NULL AUTO_INCREMENT,i1 int DEFAULT 0,str1 varchar(32) DEFAULT ,PRIMARY KEY (id) USING BTREE ) ENGINEIn…

使用 Nuxt 构建简单后端接口及数据库数据请求

写在前面 本文主要为大家介绍&#xff0c;如何使用 Nuxt 框架实现一个简单的后端接口&#xff0c;并且从数据库中请求数据返回给前端。 实现 创建 serverMiddleware 文件夹 首先我们新建一个名字为 serverMiddleware 文件夹用来存储接口相关信息 目录结构如下&#xff1a;…

探索 JavaScript ES8 中的函数式编程并通过实例加以实践

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 介绍 函数式编程是一种强大的范式&#xff0c…

【buuctf--outguess】

看题目就知道应该要用到 outguess 这个工具了&#xff0c;具体用处和下载方式请参照这篇博客Outguess下载和使用方法_outguess工具-CSDN博客 下载的 tar 压缩包解压&#xff0c;huhuhu.zip是伪加密的&#xff0c;直接用 binwalk -e 提取一下就可以&#xff0c;也可以修改压缩源…

python游戏代码大全可复制,python基础游戏代码

本篇文章给大家谈谈python游戏编程入门游戏代码&#xff0c;以及python游戏代码大全可复制&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 仅限技术学习参考 分享13个游戏源码&#xff0c;可以自己复现玩玩&#xff0c;研究下里面的编程逻辑&#xff0c;对学…

PMP考试难度怎么样?

PMP考试整体难度并不大&#xff0c;因为目前的考试题型都是选择题&#xff0c;所以通过率相对较高。然而&#xff0c;新考纲中增加了更多关于敏捷方法的题型&#xff0c;这些题目相对更加变化多样&#xff0c;也有不少考生觉得难以抉择&#xff0c;四个选项都似乎都是正确的。P…

电商数据采集+跨境电商|API电商数据采集接口洞悉数字新零售发展

随着全球经济一体化和电子商务的快速发展&#xff0c;网络购物的需求日益增加。不断涌现的电商企业使得行业的竞争情况愈演愈烈。在这种情况下&#xff0c;企业不仅要加大经营力度&#xff0c;还要在自己的基础设施和技术上持续投入&#xff0c;才能更好的适应市场和消费习惯。…

开源CMS Drupal本地快速部署并实现无公网ip环境远程访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

TP4366 1A 低成本 天源 同步移动电源方案 SOP-8

描述 TP4366是一款专为移动电源设计的同步升压的单芯片解决方案,内部集成了线性充电管理模块、同步放电管理模块、电量检测与LED指示模块、保护模块。TP4366内置充电与放电功率MOS,充电电流固定为0.8A,同步升压支持1A 输出电流。TP4366内部集成了温度补偿、过温保护、过充与过…

MySQL数据库基础(十二):子查询(三步走)

文章目录 子查询&#xff08;三步走&#xff09; 一、子查询&#xff08;嵌套查询&#xff09;的介绍 二、子查询的使用 三、总结 子查询&#xff08;三步走&#xff09; 一、子查询&#xff08;嵌套查询&#xff09;的介绍 在一个 select 语句中,嵌入了另外一个 select …

数据结构与算法:栈

朋友们大家好啊&#xff0c;在链表的讲解过后&#xff0c;我们本节内容来介绍一个特殊的线性表&#xff1a;栈&#xff0c;在讲解后也会以例题来加深对本节内容的理解 栈 栈的介绍栈进出栈的变化形式 栈的顺序存储结构的有关操作栈的结构定义与初始化压栈操作出栈操作获取栈顶元…