深浅拷贝、函数

这篇具有很好参考价值的文章主要介绍了深浅拷贝、函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

普通函数

1、函数的定义与特性
定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
1、代码重用
2、保持一致性
3、可扩展性

2、函数的创建

格式:
def 函数名(参数列表):
	函数体

函数的命名规则:
1、函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的	标点符号;
2、函数名是区分大小写的。
3、函数名不能是保留字

形参与实参:
形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应)

实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参   

区别:形参是虚拟的,不占用内存空间,.形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参

3、函数的参数

# 必须参数:需要以正确的顺序传入函数。调用时的数量必须和声明时一样
def f1(name, age):
	print('name:{},age:{}'.format(name, age))

f1('张三', 20)


# 关键字参数:关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值
def f2(name, age):
	print('name:{},age:{}'.format(name, age))

f2(age=20, name='李四')


# 默认值参数:默认值参数的值如果没有传入,则使用默认值,否则使用传入的值

def f2(name, age, sex='male'):
	print('name:{},age:{},sex:{}'.format(name, age, sex))

f2('张三', 20)
f2('李四', 21, 'male')
f2('李四', 21, sex='female')

# 可变参数 *args
'''
*args:将接收到的变量存到元组里,就是装包操作
	拆包和装包:
		函数的装包
			def 函数(*args) -->此时会出现装包操作
				pass
			函数(1,2,3,4)

		拆包:
			调用的时候:
			函数(*列表) | 函数(*元组) | 函数(*集合)
'''


def run(a, *args):
	print(a)  # 1
	# args是一个元素,内容为(2,3)
	print(args)  # (2,3)
	# *args是将元组中的元素依次取出来,相当于拆包
	print(*args)  # 2,3
	# 将未拆包的数据传递给run1
	run1(args)  # ((2,3),)
	# 将拆包的数据传递给run1
	run1(*args)  # (2,3)


def run1(*args):
	print(args)


run(1, 2, 3)


# 可变参数**kwargs
# *args:将接受到的变量存到字典里,就是装包操作


def userinfo(**kwargs):  # 传来的key=value类型的实参会映射到kwargs的键值对里
	# kwargs是一个字典
	print(kwargs)  # {'username':'admin','password':'123'}
	# **kwargs不能像之前的*args那样打印出来看

	# 此处可以理解成对**kwargs进行了拆包,username='admin' password='123'
	run1(**kwargs)


def run1(username, password):
	print(username, password)  # admin 123


userinfo(username='admin', password='123')
# userinfo(**{'username': 'admin', 'password': '123'})



# 形参和实参的参数位置说明
形参:
	1、默认值参数必须放在非默认值参数和**kwargs参数的前面
	2、可变参数*args必须放在可变参数**kwargs的前面
实参:
	1、关键字参数必须放在非关键字参数的前面

4、函数的返回值

1、函数在执行的过程中如果遇到return就结束,并返回结果
2、函数没有return语句时,默认返回None
3、return多个对象,解释器会把这多个对象组装成一个元组作为一个一个整体结果输出

5、可变与不可变数据类型

# 可变数据类型:修改内容后地址值不发生变化,包含:列表、字典、集合
# 不可变数据类型:修改后地址值发生变化,包含:数字、布尔、字符串、元组

# 数字,修改变量值后,地址值发生变化
a = 100
print(id(a))  # 1846611504
a = 200
print(id(a))  # 1846611504

# 字符串,修改变量值后,地址值发生变化
a = 'abc'
print(id(a))  # 2540610897488
a = 'xyz'
print(id(a))  # 2540615908296

# 布尔,修改变量值后,地址值发生变化
a = True
print(id(a))  # 1846354096
a = False
print(id(a))  # 1846354128

# 元组,修改变量值后,地址值发生变化
a = (1, 2, 3)
print(id(a))  # 2034282589280
a = (4, 5, 6)
print(id(a))  # 2034282615720

# 列表,修改变量值后,地址值不发生变化
a = [1, 2, 3]
print(id(a))  # 2181241446088
a.append(4)
print(id(a))  # 2181241446088

# 集合,修改变量值后,地址值不发生变化
a = {1, 2, 3}
print(id(a))  # 2136282285224
a.add(4)
print(id(a))  # 2136282285224

# 字典,修改变量值后,地址值不发生变化
a = {'username': 'admin', 'password': '123'}
print(id(a))  # 2386169288968
a['username'] = 'root'
print(id(a))  # 2386169288968

6、作用域

# 1、作用域的介绍:python中的作用域分4种情况

L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa,全局变量,就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

x = int(2.9)  # int built-in
g_count = 0  # global
def outer():
	o_count = 1  # enclosing
	def inner():
		i_count = 2  # local
		print(o_count)
	# print(i_count) 找不到
	inner()
outer()
# print(o_count) #找不到
当然,local和enclosing是相对的,enclosing变量相对上层来说也是local

# 2、作用域的产生

在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:

if 2>1:
	x = 1
print(x)  # 1
这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用。

def test():
	x = 2
print(x) # NameError: name 'x2' is not defined
def、class、lambda是可以引入新作用域的。


# 3、变量的修改

场景一:函数内部可以查看全局变量的值
a = 10
def f():
	print(a)  # 10
f()

场景二:函数内部不可直接修改全局变量的值,想要修改使用global关键字
a = 10
def f():
	# a+=10   # local variable 'a' referenced before assignment 直接修改全局变量的值会报错
	global a
	a += 10
	print(a)  # 20
f()

场景三:全局变量和局部变量相同时,采用就近原则
a = 10
def f2():
	a = 5
	print(a)  # 5,就近原则
f2()

场景四:当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量时要使用nolocal关键字

def outer():
a = 10
def inner():
    nonlocal a
    a += 10
    print(a)
inner()
outer()

总结:
1、变量的查找顺序:LEGB,局部作用局--》外层的局部作用域-》当前模块的全局变量--》python内置作用域
2、只有模块、类、函数才引入新的作用域
3、对于一个变量、内部作用域先声明就会覆盖外部的全局变量,不声明直接使用就会使用外部的全局变量
4、内部作用域想要修改外部作用域的变量值时,全局变量要使用global关键字,嵌套作用域要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就能完美的实现闭包了。

递归函数

定义:如果在函数内部调用自己,这个函数就是递归函数

递归函数的有点:定义简单,逻辑清晰,理论上所有的递归函数都可以用循环实现,但是循环的逻辑不如递归清晰

递归的特性:
	1、必须有一个明确的结束条件
	2、每次进入更深一层递归时,问题规模相对上次递归都应该有所减少
	3、递归效率不高,递归次数过多会导致栈溢出(在计算机中,函数调用是通过栈这种数据结果实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减少一层栈帧。由于栈的大小不是无限的,所以递归的次数过多会导致栈溢出)

案例1:实现递归函数
def f(n):
if n == 1:
    return 1
return n * f(n-1)

print(f(5))


案例2:斐波那契数列
def f(n):
if n == 1:
    return 0
if n == 2:
    return 1
return f(n - 1) + f(n - 2)
print(f(8))

匿名函数

用lambda函数能创建匿名函数,这种函数得名于省略了用def定于函数的标准步骤
lambda的函数只有一种语法,如下
	lambda 参数列表:运算表达式

add = lambda x,y:x+y
print(add(1,2))	# 3

匿名函数可以执行任意表达式,可以是print函数,但是一般认为表达式应该有一个计算结果供返回使用。

# 匿名函数作为实参传递
def func(a, f):
	return f(a)
print(func(5, lambda x: x + 5))

高级函数

高阶函数
max:返回最大值
min:返回最小值
sorted():排序,返回一个新的列表
filter():过滤,返回一个filter对象
map():加工,返回一个map对象
reduce():压缩,返回一个数

from functools import reduce

students = [
	{'name': 'zhangsan', 'age': 18, 'score': 92},
	{'name': 'lisi', 'age': 20, 'score': 90},
	{'name': 'wangwu', 'age': 19, 'score': 95},
	{'name': 'jerry', 'age': 21, 'score': 98},
	{'name': 'chris', 'age': 17, 'score': 100},
]

# max(*args,key=None) -》 value  找最大的成绩的记录
print(max(students, key=lambda x: x['score']))

# min(*args,key=None) -》 value  找最小的成绩的记录
print(min(students, key=lambda x: x['score']))

# sorted(iterable,key) -> list 根据成绩排序
list1 = sorted(students, key=lambda x: x['score'], reverse=True)
print(list1)

# filter(func,iterable) -> filter object ,过滤出成绩大于94的记录
print(list(filter(lambda x: x['score'] > 94, students)))

# map(func,iterable) -> map object,对每个元素进行加工
print(list(map(lambda x: x['name'].title(), students)))

# reduce(func,iterable) -> value 累计
print(reduce(lambda x, y: x + y, range(11)))

# zip(list1,list2) -> list 将多个可迭代对象的索引相同的位置的值放到一个元组里,最后统一放到一个列表中
print(list(zip([1, 2, 3], [4, 5, 6, 7])))  # [(1, 4), (2, 5), (3, 6)]

装饰器

1、闭包

闭包必须满足的条件:
	1、必须要有函数的嵌套
	2、内部函数使用了外部函数的变量
	3、外部函数返回值为外部函数名

说明:闭包本身没有意义,在装饰器中使用

代码:
def outer():
x = 10
def inner():
    print(x)
return inner
outer()()

2、装饰器

# 装饰器的功能
	原则:遵循开放封闭原则,在不改变原函数功能的情况下,扩展了函数的功能
	适用场景:
		a:引入日志
		b:统计函数执行时间
		c:执行函数前预备处理
		d:权限校验
		e:缓存


场景一:不带参数的装饰器
def login_outer(func):
	print('-------进入购物商城----------')
	def login_inner():
		func()
		print('购买牙膏')
		print('购买牙刷')
		print('------离开购物商城-----------')
	return login_inner

@login_outer  <==> shopping_car = login_outer(shopping_car)
def shopping_car():
	print('开始购物')

shopping_car()

执行步骤:
1、先将函数login_outer()和函数shopping_car()加载到内存中
2、执行函数shopping_car()时,会先执行@login_outer,此时会调用loing_outer()函数,
3、执行 print('-------进入购物商城----------')语句
4、将login_inner()函数加载到内存中
5、执行return login_inner,将login_inner()函数的地址返回给shopping_car()函数,所以调用函数shopping_car() 相当于调用了函数 login_inner()


# 场景二:带参数的装饰器函数
def outer(func):
	def inner(*args,**kwargs):
		func(*args,**kwargs)
	return inner

@outer
def add(*args,**kwargs):
	print(sum(args))

add(1,2,3,4)

# 场景三:带参数和返回值的装饰器函数
def outer(func):
	def inner(*args,**kwargs):
		return func(*args,**kwargs)
	return inner

@outer
def add(*args,**kwargs):
	return sum(args)

print(add(1,2,3,4))


# 场景四:装饰器带有参数
# 带参数的装饰器
def login(fo):
	def outer(func):
		def inner():
			if fo in ('jingdong','taobao'):
				func()
			else:
				print('登录失败')
		return inner
	return outer

@login('jingdong')
def jingdong():
	print('欢迎进入京东商城')

@login('taobao')
def taobao():
	print('欢迎进入淘宝商城')

jingdong()
taobao()

3、装饰器之登录练习

is_login = False


def login(auth_type=None):
	def login_outer(func):
		def login_inner():
			global is_login
			while not is_login:
				user_name = input('请输入用户名:')
				pass_word = input('请输入密码:')
				with open(''.join([auth_type, '.txt']), 'r', encoding='utf-8') as f:
					for user in f:
						# 将字符串转化为字典
						user = eval(user)
						if user['username'] == user_name and user['password'] == pass_word:
							is_login = True
							print('登录成功!')
							break
					else:
						print('用户名或密码错误,请重新选择!')
			if is_login:
				func()

		return login_inner

	return login_outer


@login(auth_type='jingdong')
def home():
	print('欢迎来到home页面')


@login(auth_type='weixin')
def finance():
	print('欢迎来到finance页面')


@login(auth_type='jingdong')
def book():
	print('欢迎来到book页面')


if __name__ == '__main__':
	menu = {
		'1': home,
		'2': finance,
		'3': book
	}
	while True:
		print('欢迎来到京东商城'.center(30, '-'))
		print('1.home\n2.finance\n3.book\n4.退出\n')
		choice = input('请选择>>')
		if choice in menu:
			menu[choice]()
		elif choice == '4':
			break
		else:
			print('选择有误,请重新选择!')

列表生成式

1、列表推导式的概念
所谓列表推导式,就是指轻量级循环创建列表

2、基本的使用方式

a = [x for x in range(9)]
print(a)  # [0,1,2,3,4,5,6,7,8]

3、在循环的过程中使用if

a = [x for x in range(9) if x % 2 == 0]
print(a)  # [0, 2, 4, 6, 8]

4、在循环过程中使用if-else

words = ['123', 'hello', 'word', 'how']
# 将以h开头的单词首字母大写,否则全部大写
a = [word.title() if word.startswith('h') else word.upper() for word in words if word.isalpha()]
print(a)

4、双重for循环

a = [(x,y) for x in range(9) for y in range(9)]
print(a)

5、练习题:请写出一段 Python 代码实现分组一个 list 里面的元素,比如 [1,2,3,...100]变成 [[1,2,3],[4,5,6]....]

list1 = [i for i in range(1,101)]
list2 = [list1[i:i+3] for i in range(0,101,3)]
print(list2)

生成器

生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。代码3远没有代码1简洁,生成器(yield)既可以保持代码1的简洁性,又可以保持代码3的效果。它不需要再像上面的类一样写 __iter__() 和 __next__() 方法了,只需要一个 yiled 关键字。 生成器有如下特征是它一定也是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成器。用生成器来实现斐波那契数列的例子是:

def fib(max):
n, before, after = 0, 1, 1
while n < max:
    yield before
    before, after = after, before + after
    n += 1
b = fib(8)
print(b)    # <generator object fib at 0x000001B30ADFDF68>

for num in b:
	print(num)

 fib 就是一个普通的python函数,它特殊的地方在于函数体中没有 return关键字,函数的返回值是一个生成器对象。当执行 f=fib(5) 返回的是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码。

 yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个generator,在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

也可以手动调用 fab(5) 的 next() 方法(因为 fab(5) 是一个 generator 对象,该对象具有 next() 方法),这样我们就可以更清楚地看到 fab 的执行流程:

print(next(b))  # 1
print(next(b))  # 1
print(next(b))  # 2
print(next(b))  # StopIteration


需要明确的就是生成器也是iterator迭代器,因为它遵循了迭代器协议.
第二中创建方式如下:
g = (i for i in ragne(4))

2、生成器函数中带有return语句

在一个生成器中,如果没有return,则默认执行到函数完毕;如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代.
def f():

yield 5
print("ooo")
return
yield 6
print("ppp")

f=f()
# print(f.__next__())
# print(f.__next__())
for i in f:
	print(i)

'''
return即迭代结束
for不报错的原因是内部处理了迭代结束的这种情况
'''

3、读取文件

def read_file():
	with open('jingdong.txt','r',encoding='utf-8') as f:
		while True:
			data = f.read(1)
			if data:
				yield data
			else:
				return
f = read_file()
for s in f:
	print(s)

如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取。

注:生成器对象就是一种特殊的迭代器对象,满足迭代器协议,可以调用next;对生成器对象for 循环时,调用iter方法返回了生成器对象,然后再不断next迭代,而iter和next都是在yield内部实现的

3、练习1:使用文件读取,找出文件中最长的行的

print(max((len(x) for x in open('jingdong.txt','r',encoding='utf-8'))))

4、send()函数

def f():
print("ok1")
s1 = yield 7
print('ok2')
s2 = yield 8
print('ok3')


b = f()
print(b.send(None))  # ok1,7,相当于next(b)
print(next(b))  # ok2,8
print(next(b))  # 报错    StopIteration

5、协程应用:文章来源地址https://www.toymoban.com/news/detail-435530.html

  所谓协同程序也就是是可以挂起,恢复,有多个进入点。其实说白了,也就是说多个函数可以同时进行,可以相互之间发送消息等。
def consumer(name):
print('{}准备开始吃包子了'.format(name))
while True:
    num = yield
    print('{}吃了第{}个包子'.format(name, num))


def product(name):
	c1 = consumer('A')
	c2 = consumer('B')
	next(c1)
	next(c2)
	print('{}准备开始做包子了'.format(name))
	for i in range(1, 11, 2):
		print('已经做好了2个包子')
		c1.send(i)
		c2.send(i + 1)

product('zs')

可迭代对象iterable

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。list、dict、set、tupple、str都是可迭代对象

from collections import Iterable,Iterator
x = [1,2,3]
x1 = iter(x)
print(isinstance(x,Iterable))   # True
print(isinstance(x,Iterator))   # False
print(isinstance(x1,Iterable))  # True
print(isinstance(x1,Iterator))  # True

迭代器iterator

1、任何实现了 __next__() (python2中实现 next() )方法的对象都是迭代器
2、可迭代对象中只能使用iter()方法,迭代器中可以使用next()、iter()方法

for i in [12,3,4]:
print(i)

说明:for循环实现逻辑
1、先调用iter()方式生成一个迭代器
2、每次调用next()方法获取下一个值
3、自带捕获异常功能

到了这里,关于深浅拷贝、函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript深浅拷贝

    1. js浅拷贝只是创建了一个新的对象,复制了原有对象的基本类型的值。 手写实现  2. 深拷贝的原理和实现 将一个对象从内存中完整地拷贝出来一份给目标对象,并从堆内存中开辟一个全新的空间存放新的对象,且新对象的修改并不会改变原对象,二者实现真正的分离

    2024年01月18日
    浏览(32)
  • 浅析深浅拷贝

           我们在对对象进行复制时就用到深浅拷贝。 一、普通复制 控制台打印结果:               之所以我们要用到拷贝,是因为直接赋值的复制可能不能满足我们的需求。向上面代码所展示的,我们复制代码时,复制到的是 地址 ,所以对 复制体修改实际修改的是原对

    2024年02月12日
    浏览(22)
  • 认识Object类和深浅拷贝

    本文介绍了Object类以及Object类部分方法,toString方法,equals和hashCode方法(重写前和重写后的对比),getClass方法,clone方法,以及拷贝新对象时会出现的深浅拷贝, 内容较长,耗时一天,建议收藏后观看~ Object类是Java默认提供的一个类。而这个类是Java里所有类的顶级父类,即在继承体系下

    2023年04月20日
    浏览(22)
  • C# List 复制之深浅拷贝

    声明类 执行上述方法, 修改list1 中的属性值, 发现list2 的属性值会跟着变化, list3 的属性值不发生变化; 由于进行的是浅拷贝,所以直接将list1的内容复制给了list2,虽然list1和list2所在的地址不一样,但是两个list存储的对象仍然是相同的(因为把list1复制到list2时,浅拷贝复制的

    2024年02月07日
    浏览(29)
  • 深浅拷贝,类型检测及继承面试题

    基本类型:基本类型的值存在栈内存中 引用类型: 引用类型的地址存储在栈内存中,他的值存储在堆内存中,通过指针(地址)连接 基本类型:基本类型拷贝的是值 引用类型:引用类型拷贝的是变量的地址,会造成数据共享问题 基本类型: 基本类型传递的是值 引用类型:

    2024年02月02日
    浏览(28)
  • JavaScript深浅拷贝的几种方式

    深浅拷贝主要是针对于引用类型而言的 1. JSON.parse(JSON.strigify(Str)) JSON.stringify() 该方法用于将一个字转换为JSON字符串,该字符串符合JSON格式,并且可以被JSON.parse()方法还原。 对于原始类型的字符串,转换结果会带双引号 如果要转换的对象的属性是undefined,函数或xml对象,该

    2024年01月19日
    浏览(34)
  • 【C++】string类的深浅拷贝问题

    我们知道,定义一个类的时候,如果我们没有写构造,拷贝构造,赋值运算符重载,析构方法的话,编译器会自动生成。当该类成员中涉及到资源的管理时,实现的就是浅拷贝。所以,以上这几种方式是必须要程序猿手动实现的。 举例来看: 图中所示:实现了构造和析构,

    2023年04月26日
    浏览(31)
  • 【C++】vector类的模拟实现(增删查改,拷贝构造,赋值运算,深浅拷贝)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 我们模拟vector是用迭代器(start,end,endofstorage)来控制增删查改操作的 1普通构造 2迭代器构造 3初始化字符构造 4拷贝构造: 1当前大小(size()) 2总体容量(capacity()) 1begin()

    2024年02月15日
    浏览(48)
  • 前端面试题(第三弹)——js对象的基本方法和深浅拷贝

    第一种 第二种 1.configurable:属性是否可以通过delete删除,默认值为true。 2.enumberable:属性是否可以通过for in 进行循环返回,默认值为true。 3.writable:属性是否可被修改,默认值为true。 4.value:属性实际的值,默认为undefined。 访问器属性有四个属性类型,也是使用Object.defin

    2024年02月13日
    浏览(30)
  • 【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 在阅读本篇文章前,一定要先看前集: vector深度剖析(上) 本章重点: 本章会重点讲解vector迭代器失效问题 以及vector中的深浅拷贝问题 并且简

    2024年02月11日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包