跟着我学Python进阶篇:03. 面向对象(下)

往期文章

跟着我学Python基础篇:01.初露端倪
跟着我学Python基础篇:02.数字与字符串编程
跟着我学Python基础篇:03.选择结构
跟着我学Python基础篇:04.循环
跟着我学Python基础篇:05.函数
跟着我学Python基础篇:06.列表
跟着我学Python基础篇:07.文本
跟着我学Python基础篇:08.集合和字典


跟着我学Python进阶篇:01.试用Python完成一些简单问题
跟着我学Python进阶篇:02.面向对象(上)


目录

  • 往期文章
  • 1. 面向对象的三大特征
  • 2. 封装
  • 3. 继承
    • 3.1 单继承
    • 3.2 isinstance()和issubclass()方法
    • 3.3 多继承
    • 3.4 重写
    • 3.5 super关键字
  • 4. 多态
  • 5. 运算符重载
    • 5.1 四则运算重载
    • 5.2 索引和分片重载
    • 5.3 定制对象和字符串形式
  • 6. __new__方法
  • 7. 单例模式
  • 8. 工厂模式

1. 面向对象的三大特征

面向对象开发思想具有三个典型特征:封装、继承和多态

  1. 封装
    使用封装能隐藏对象的视线细节,使代码更容易维护,同时因为不能直接调用修改内部私有信息,在一定程度上保证了系统的安全性。
  2. 继承
    继承主要描述类与类的关系,他可以在不必重写类的情况下,对原有类的功能进行扩展。继承不仅增强了代码的复用性,还提高了开发效率。为程序后期维护提供了便利。
  3. 多态
    多态与继承紧密相连,是面向对象变成的另一个突出的特点。对象的多态性是指在父类中定义的属性和方法被子类继承后,可以使用同一个属性或方法在父类及各个子类中具有不同的含义,这称为多态性。简单来说,就是一种行为产生多种结果。

2. 封装

封装是面向对象编程中的一种重要概念,它允许将数据和相关的操作封装在一个单元中,同时隐藏内部细节并提供对外的接口。通过封装,我们可以实现信息的隐藏和保护,同时提供更清晰、简洁的编程接口。

在封装中,一个类被用来封装数据和方法。数据通常被定义为类的属性(或成员变量),而方法则是操作这些数据的函数。通过使用访问修饰符(如公有、私有、受保护等),我们可以控制数据和方法的可访问性。

封装的主要目的有以下几点:

  1. 数据隐藏:封装允许将数据隐藏在类的内部,只暴露必要的接口供外部使用。这样可以防止不合理的访问和修改数据,增强了程序的安全性和稳定性。

  2. 接口简化:通过封装,我们可以将复杂的内部实现细节隐藏起来,只提供一个简洁的接口供其他代码使用。这样可以降低代码的耦合度,提高代码的可维护性和可重用性。

  3. 代码隔离:封装将数据和方法封装在类内部,使得每个类都具有独立的作用域。这样可以避免命名冲突和代码混乱,提高代码的可读性和可理解性。

  4. 代码组织:封装使得代码按照功能模块进行组织,更易于管理和扩展。类的内部实现可以自由修改,而不会影响到其他代码。

3. 继承

3.1 单继承

在面向对象的编程里,所有的事物都对应一个类,一个类可以继承自另一个类,并自动拥有另一个类的属性和方法,并且可以进一步完善,添加新的特性和方法。当一个类继承自其他类时,继承类叫做子类,被继承类叫做超类或者父类。
在Python中,继承使用如下语法格式:

class 子类名(父类名)

如果在类定义时没有标注,则默认类是继承自object的。
需要说明的是,子类不能继承父类的私有属性和方法,也不能在子类中直接访问。但子类对象可以通过调用父类方法的途径访问父类私有属性。

3.2 isinstance()和issubclass()方法

Python提供isinstance和issubclass两个和继承相关的函数。

1.isinstance()函数

isinstance(o,t)函数用于检查对象的类型,它有两个参数,第一个参数是判断类型的对象(o),第二个参数是类型(t),如果o是t类型的对象,则返回True,否则返回False。

  1. issubclass()函数

函数issubclass(cls,classinfo)用于检查类和继承关系,它也有两个参数,第一个参数是要判断的子类类型(cls),第二个参数是要判断父类类型(classinfo),如果cls是classinfo的子类,则函数返回True,否则返回False。

3.3 多继承

一个子类可以继承自多个不同的父类,这种情况叫做多继承。Python语言是支持多继承的,多继承的基本语法格式如下:

class 子类(父类1,父类2

我们创建房车类(RV),让他继承自房屋类(House)和车辆类(Car)两个父类。

class House():
    def live(self):
        print("--房子可以居住--")
class Car():
    def move(self):
        print("--汽车可以行驶--")
class RV(House,Car):
    pass

rv=RV()
rv.live()
rv.move()

在这里插入图片描述
从运行结果可知,子类的对象同时继承了两个父类方法。那么问题来了,如果子类的多个父类有一个同名的方法,那么子类的对象继承来的是哪个父类的方法呢?我们来做一个测试:

class House():
    def get_color(self):
        print("白色的房子")
class Car():
    def get_color(self):
        print("红色的汽车")
class RV(House,Car):
    pass

rv=RV()
rv.get_color()

在这里插入图片描述
实际上,在Python3中,如果子类继承的多个父类间是平行关系,子类先继承哪个类就会调用哪个类的方法。如果当前类的继承关系非常复杂,Python会使用mro算法找到合适的类。
mro算法专门用在多继承时判断调用的属性方法和路径,即来自哪个类,可以通过类名访问_mro()_属性方法查看该类搜索属性和方法时先后顺序。
如果多个父类有同名的方法或属性,在子类中要指定使用某个父类的方法或属性时,我们可以在子类中对该属性或者方法名赋值来覆盖继承。
下面例子来说明多继承情况下指定父类元素的使用:

class House():
    color="白色"
    def get_color(self):
        print(self.color)
class Car():
    color="红色"
    def get_color(self):
        print(self.color)
class RV(House,Car):
    color=Car.color
    get_color=Car.get_color

rv=RV()
print(rv.color)
rv.get_color()

在这里插入图片描述

3.4 重写

在有些情况下,子类希望对父类提供的属性和方法进行修改,提供自己的实现,这种行为就叫重写。

下面,我们使用子类InServiceStudent(在职生)重写父类Student(学生)的方法:

class Student(object):
    def main(self):
        print("学习")
class InServiceStudent(Student):
    def main(self):
        print("一边工作一边学习")

in_service_student=InServiceStudent()
in_service_student.main()

在这里插入图片描述

父类Student有一个main()方法,子类InServiceStudent重写了main()方法,从运行结果可以看出,在in_service_student对象调用方法时,调用的是子类的main()方法。

3.5 super关键字

在子类重写父类方法后,如果还需要访问父类的同名方法,可以使用super关键字,super关键字用在子类访问父类中。
使用super关键字的经典场合是在_init()_方法中,在Python中,如果子类重写了_init()_构造方法,子类并不会自动调用父类的构造方法,但是子类通常需要父类的构造方法,包括在构造方法里定义的父类的属性,或者初始化设置等,所以在子类重写的_init()_方法中,要调用父类的_init()_方法

class Father(object):
    def __init__(self):
        print("父类构造方法")


class Son(Father):
    def __init__(self):
        print("子类构造方法")

son=Son()

在这里插入图片描述
我们可以看出,子类重写构造方法后,并没有调用父类的构造方法。
如果子类需要在构造方法中增加自己的属性,或者扩充其他功能,而需要重写构造方法的话,一定要记住在最后调用父类的构造方法,比如上述代码中的Son类的构造方法可以更改为:

class Father(object):
    def __init__(self):
        print("父类构造方法")


class Son(Father):
    def __init__(self):
        super().__init__();
        print("子类构造方法")

son=Son()

在这里插入图片描述
从结果可知,子类调用了父类的构造方法。

4. 多态

多态是面向对象的语言的最核心的特征。如果一个语言不具有多态性,那么就不能称之为面向对象的语言。
在Python中,多态指在不考虑对象类型的情况下使用对象。Python不关注对象的类型,而关注对象具体的行为。
由于Python是动态类型的语言,所以多态随处可见,Python中使用对象,并不需要显示指定对象类型,只要对象具有预期的方法和表达式操作符,就可以使用。

看一个多态的案例:

class Animal(object):
    def move(self):
        pass
class Rabbit(Animal):
    def move(self):
        print("兔子蹦蹦跳跳")
class Snail(Animal):
    def move(self):
        print("蜗牛缓慢爬行")
def test(obj):
    obj.move()

rabbit=Rabbit()
test(rabbit)
snail=Snail()
test(snail)

在这里插入图片描述
从运行结果可以看出,根据传入参数对象不同,调用的是不同类型对象的move方法,实际上,test并没有规定参数的类型,所以传入其他类型的对象可以,只要该对象具有move方法,而不一定继承自animal类。

在强语言类型中,由于严格限制了变量类型,所以多态适用于把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,赋值之后,父类类型的对象就可以根据当前赋值给他的子类对象的特征以不同的方式运作,也就是,父类的行为像儿子,而非儿子的行为像父亲。

5. 运算符重载

在Python里,用户可以在自定义类里通过特殊方法来重载内建运算符,类可以重载所有表达式运算符,以及打印、函数调用、属性点号运算符等内置运算,重载使得类对象的行为更像内置类型,在类中提供特殊名称的类方法,可以实现对应运算符重载。
例如,加法+对应__add__方法,当调用+进行运算的时候,实际上调用了__add__方法。表中给出了部分运算符重载的方法:

在这里插入图片描述

5.1 四则运算重载

我们创建一个简单的计算器,Calculator类,它能执行四则运算,并且把运算结果记录下来,作为下一次运算符的起始数字,代码如下:

class Calculator():
    def __init__(self,number):
        self.number=number
    def __add__(self, other):
        self.number=self.number+other
        return self.number

    def __sub__(self, other):
        self.number=self.number-other
        return self.number

    def __mul__(self, other):
        self.number=self.number*other
        return self.number

    def __truediv__(self, other):
        self.number=self.number/other
        return self.number

calucator=Calculator(10)

print(calucator+10)

print(calucator-5)

print(calucator*2)

print(calucator/3)

在这里插入图片描述

5.2 索引和分片重载

以下是跟索引和分片相关的3个重载方法:
getitem:索引、分片取值
setitem:索引、分片赋值
delititem:索引和分片删除

  1. __getitem__方法
    在对实例对象进行索引、分片或者for迭代操作取值时,会自动调用该方法。
class ClassScore(object):
    def __init__(self,numbers):
        self.scores=numbers[:]
    def __getitem__(self, index):
        return self.scores[index]

mathscore=ClassScore([85,91,95,98])
print(mathscore[0])

print(mathscore[1:])

for score in mathscore:
    print(score)


在这里插入图片描述

  1. __setitem__方法

通过赋值语句给索引或者分片赋值时,调用该方法可以实现对序列对象的修改。

class ClassScore(object):
    def __init__(self,numbers):
        self.scores=numbers[:]
    def __setitem__(self, index, value):
        self.scores[index]=value

mathscore=ClassScore([85,91,95,98])
print(mathscore.scores)

mathscore[0]=100
print(mathscore.scores)

mathscore[1:3]=[99,98,97]
print(mathscore.scores)

在这里插入图片描述

5.3 定制对象和字符串形式

重载__str__和__reper__ 方法可以定义对象转换为字符串的形式,在执行print,str,reper及交互模式下直接显示对象时,会调用__str__和__reper__方法,但是只重载某个方法与把两个方法都重载的效果是不同的。

当只重载__str__()方法时:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"Person: {self.name}, Age: {self.age}"

person = Person("Alice", 25)
print(person)  # 输出:Person: Alice, Age: 25

str_representation = str(person)
print(str_representation)  # 输出:Person: Alice, Age: 25

repr_representation = repr(person)
print(repr_representation)  # 输出:'<__main__.Person object at 0x00000123456789>'

在这里插入图片描述

当只重载__repr__()方法时:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __repr__(self):
        return f"Point({self.x}, {self.y})"

point = Point(3, 4)
print(point)  # 输出:'<__main__.Point object at 0x00000123456789>'

str_representation = str(point)
print(str_representation)  # 输出:'<__main__.Point object at 0x00000123456789>'

repr_representation = repr(point)
print(repr_representation)  # 输出:'Point(3, 4)'

在这里插入图片描述

当同时重载__str__()和__repr__()方法时:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"Person: {self.name}, Age: {self.age}"
    
    def __repr__(self):
        return f"Person({self.name}, {self.age})"

person = Person("Alice", 25)
print(person)  # 输出:Person: Alice, Age: 25

str_representation = str(person)
print(str_representation)  # 输出:Person: Alice, Age: 25

repr_representation = repr(person)
print(repr_representation)  # 输出:'Person(Alice, 25)'

在这里插入图片描述

6. __new__方法

Python中object类还有一个内建方法__new__,用于创建类,在自定义类时一般不重写这个方法,但在特殊场合也会重写。
该方法是类的静态方法,即使重写时没有被加上静态方法修饰器。

我们来看一下object类中对该方法的定义:

@staticmethod 
def __new__(cls,*more):
    """Create and return a new object"""
    pass

关于定义的介绍如下:

cls 代表要实例化的类,此参数在实例化时由Python解释器自动提供。
该方法必须要有返回值,返回实例化出来的实例,这点在自己实现__new__方法时要特别注意,可以return 父类__new__方法返回的实例,或者直接返回object类的__new__方法返回的实例。

class Test(object):
    def __init__(self):
        print("执行init方法")
        print("self对象的id是%s"%id(self))

    def __new__(cls):
        print("执行new方法")
        demo_object=object.__new__(cls)
        print("demo_object对象的id是%s"%id(demo_object))
        return demo_object

test=Test()

在这里插入图片描述
从结果可以看出,在创建test对象时,首先运行了__new__方法,然后才是__init__方法,并且__new__方法返回对象id与传入__init__方法的对象id相同,证明他们是同一个对象。

__new__方法和__init__方法还是有区别的:

new创建对象,init在new的基础上完成其他一些初始化工作,包括设置对象私有属性等。
init方法不需要返回值。
init方法的参数是self,就是new方法返回的实例。

7. 单例模式

单例模式是一种设计模式,用于确保一个类只有一个实例对象,并提供一个全局访问点来获取该实例。在单例模式中,通过限制类的实例化过程,可以确保只有一个实例对象存在,并且可以在程序的任何地方使用该实例。

实现单例模式的方法有多种,以下是其中两种常见的方式:

  1. 使用模块级别的变量:在 Python 中,模块是天然的单例,因为模块在程序的整个生命周期中只会被加载一次。可以将需要单例化的类定义在一个模块中,然后其他模块可以通过导入该模块来使用该类的唯一实例。例如:
# singleton.py

class SingletonClass:
    def __init__(self):
        # 初始化操作
        pass

# 使用单例类
singleton_instance = SingletonClass()

在其他模块中使用这个单例类的实例:

# other_module.py

from singleton import singleton_instance

# 使用 singleton_instance 进行操作
  1. 使用装饰器:通过定义一个装饰器函数,可以将一个普通的类转换为单例类。装饰器函数在创建实例对象时,检查是否已经存在实例对象,如果存在则返回已有的实例,否则创建一个新的实例并返回。例如:
def singleton(cls):
    instances = {}

    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper

@singleton
class SingletonClass:
    def __init__(self):
        # 初始化操作
        pass

# 使用单例类
singleton_instance = SingletonClass()

这样,每次创建 SingletonClass 的实例时,都会通过装饰器函数来获取唯一的实例对象。

8. 工厂模式

工厂模式是一种创建型设计模式,用于封装对象的实例化过程。它通过定义一个共同的接口来创建不同类型的对象,而无需直接指定其具体类。

工厂模式的主要目的是将对象的创建与使用代码解耦,以提高代码的灵活性和可维护性。它对于创建复杂对象或者对象有多个变体的情况非常有用。

在工厂模式中,通常存在一个抽象工厂类或者接口,用于定义创建对象的方法。具体的对象创建由其子类或者实现类来完成。这样,客户端代码只需要通过调用工厂方法来获取所需的对象,而无需直接依赖具体的类。

下面是一个简单的示例,展示了如何使用工厂模式创建不同类型的汽车对象:

from abc import ABC, abstractmethod

class Car(ABC):
    @abstractmethod
    def drive(self):
        pass

class SedanCar(Car):
    def drive(self):
        print("Driving a sedan car.")

class SUVCar(Car):
    def drive(self):
        print("Driving an SUV car.")

class CarFactory(ABC):
    @abstractmethod
    def create_car(self):
        pass

class SedanCarFactory(CarFactory):
    def create_car(self):
        return SedanCar()

class SUVCarFactory(CarFactory):
    def create_car(self):
        return SUVCar()

# 使用工厂模式创建汽车对象
sedan_factory = SedanCarFactory()
sedan_car = sedan_factory.create_car()
sedan_car.drive()

suv_factory = SUVCarFactory()
suv_car = suv_factory.create_car()
suv_car.drive()

在上述示例中,Car是一个抽象基类,定义了所有汽车对象的共同方法。SedanCar和 SUVCar是具体的汽车类,分别实现了 drive()`方法。

CarFactory 是抽象工厂类,定义了创建汽车对象的抽象方法 create_car()。SedanCarFactory`和 SUVCarFactory是具体的工厂类,分别实现了 create_car() 方法,用于创建 SedanCar和SUVCar对象。

通过使用工厂模式,客户端代码只需要和抽象工厂类以及抽象产品类交互,而无需直接依赖具体的类。这样,当需要添加新的汽车类型时,只需要新增对应的具体产品类和具体工厂类,并在客户端代码中使用相应的工厂对象即可,不会影响到原有代码的稳定性。

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

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

相关文章

【ARM 嵌入式 编译系列 7.3 -- GCC 链接脚本中 DISCARD 与 .ARM.exidx】

请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 文章目录 背景.ARM.exidx方法一:使用链接器脚本方法二:使用链接器选项注意事项背景 在移植 RT-Thread 到 cortex-m33(RA4M2)上的时候,在编译的时候遇到下面问题: Building target: ra4m2.elf arm

Vue2基础-Vue对象进阶介绍2

文章目录 一、自定义指令1、用法2、注意点 二、生命周期1、概念2、示意图3、分析 一、自定义指令 本质上是封装了DOM元素的具体操作 1、用法 <div >放大十倍后的值是&#xff1a;<span v-big"n"></span></div> <input type"text&…

【Linux】—— 共享内存

本期我将要带大家学习的是有关进程间通信的另一种方式——共享内存。共享内存是一种用于进程间通信的高效机制&#xff0c;允许多个进程访问和操作同一块内存区域。 目录 &#xff08;一&#xff09;深刻理解共享内存 1.1 概念解释 1.2 共享内存原理 1.3 共享内存数据结构 …

Spring | Srping AOP (AOP简介、动态代理、基于“代理类”的AOP实现)

目录: 1.Spring AOP简介1.1 AOP简介1.2 AOP术语 2.动态代理2.1 JDK动态代理2.2 CGLIB代理 3.基于“代理类”的AOP实现3.1 Spring的通知类型3.2 ProxyFactoryBean ( 可通知.xml配置文件完成aop功能 ) 1.Spring AOP简介 1.1 AOP简介 Spring的AOP模块&#xff0c;是Spring框架体系…

【C++】list容器迭代器的模拟实现

list容器内部基本都是链表形式实现&#xff0c;这里的迭代器实现的逻辑需要注意C语言中指针的转换。 list容器如同数据结构中的队列&#xff0c;通常用链式结构进行存储。在这个容器中&#xff0c;我们可以模仿系统的逻辑&#xff0c;在头结点后设置一个“ 哨兵 ”&#xff0c;…

什么勒索攻击,应该如何防护?

当前&#xff0c;勒索攻击、僵尸网络攻击、DDos攻击、APT攻击、挖矿攻击、供应链攻击、网站攻击、电信诈骗等各种攻击手段层出不穷。 勒索攻击应该是今年网络安全行业讨论最多的话题&#xff0c;勒索钱财或者窃取商业数据是黑产最主要的目的。 勒索软件的攻击特征 与其它攻击行…

限价单和止损单是什么?澳福实例讲解

什么是限价单和止损单&#xff0c;投资者如何使用它?了解交易基础知识&#xff0c;快速进入市场盈利收场&#xff0c;今天fpmarkets澳福和各位投资者继续探讨交易基础知识。 止损单是在看涨趋势中以更高的价格买入的前提&#xff0c;通过图表得知&#xff0c;黄线显示欧元兑美…

刷题 ------ 排序

文章目录 1.K 次取返后最大化的数组和&#xff08;堆&#xff09;2.数组的相对排序&#xff08;桶&#xff09;3.最小绝对差4.根据数字二进制下1的数目排序&#xff08;qsort&#xff09;5.有多少小于当前数字的数字6.非递增顺序的最小子序列7.按照频率将数组升序排序&#xff…

生成当天递增唯一的流水号的几种方式

说明&#xff1a;当开发中&#xff0c;如交易、文件传输过程中的文件名&#xff0c;可能需要我们使用一串唯一的数字来锁定这一条“交互记录”&#xff0c;即流水号。 本文介绍几种生成6位递增唯一&#xff0c;且每日重置的流水号的方式。 方式一&#xff1a;使用Redis 我们…

Leetcode—22.括号生成【中等】

2023每日刷题&#xff08;七十九&#xff09; Leetcode—22.括号生成 算法思想 实现代码 class Solution { public:vector<string> generateParenthesis(int n) {vector<string> ans;int m n * 2;string path(m, 0);function<void(int, int)> dfs [&…

自己构建webpack+vue3+ts

先看看我的目录结构&#xff08;我全局使用TS&#xff09;&#xff1a; 一、安装配置webpack打包 安装esno npm install esnoesno 是基于 esbuild 的 TS/ESNext node 运行时,有了它&#xff0c;就可以直接通过esno *.ts的方式启动脚本&#xff0c;package.json中添加 type:…

力扣62. 不同路径

动态规划 思路&#xff1a; 定义 dp[r][c] 为到达坐标 (r, c) 的路径数&#xff1a; 它只能有同一行左边相邻方格向右到达或者同一列上方相邻方格向下到达&#xff1b;状态转移方程&#xff1a; dp[r][c] dp[r][c - 1] dp[r - 1][c]初始状态 dp[0][0] 1第一行的路径数是 1第…

二维码地址门牌管理系统:社区新风向

文章目录 前言一、集成先进技术的系统二、便捷居民体验三、支持社区管理四、未来展望与可扩展性 前言 随着科技的不断发展&#xff0c;智能化管理已经深入到我们的生活中。二维码门牌管理系统作为一款创新产品&#xff0c;在社区管理领域迅速引起广泛关注。这款系统不仅提升了…

CTFhub-bak文件

CTFhub-Web-信息泄露-备份文件下载-bak文件 题目信息 解题过程 看到提示说和index.php有关&#xff0c;在url后面加index.php.bak&#xff0c;跳转到http://challenge-7a4da2076cfabae6.sandbox.ctfhub.com:10800/index.php.bak网址&#xff0c;即&#xff1a; 跳转到下载页…

彻底搞定让人头痛的nginx location 路径匹配规则

nginx location 路径匹配规则 一、前言二、说在前面三、开始表演 一、前言 很多同学&#xff0c;在配置nginx的时候&#xff0c;都会遇到一个头痛的问题&#xff0c;就是location 的路径应该怎么写&#xff1f;到底要不要加斜杠&#xff0c;有点傻傻分不清楚。今天就来帮助大家…

蓝桥杯真题(Python)每日练Day3

题目 题目分析 为了找到满足条件的放置方法&#xff0c;可以带入总盘数为2和3的情景&#xff0c;用递归做法实现。 A中存在1 2两个盘&#xff0c;为了实现最少次数放入C且上小下大&#xff0c;先将1放入B&#xff0c;再将2放入C&#xff0c;最后将1放入C即可。同理当A中存在1 …

柔性数组和C语言内存划分

柔性数组和C语言内存划分 1. 柔性数组1.1 柔性数组的特点&#xff1a;1.2 柔性数组的使用1.3 柔性数组的优势 2. 总结C/C中程序内存区域划分 1. 柔性数组 也许你从来没有听说过柔性数组&#xff08;flexible array)这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff…

以太坊账户地址与比特B地址生成方法对比

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 以太坊和比特B地址在生成方…

C语言——内存函数介绍和模拟实现(memcpy、memmove、memset、memcmp)

之前我们讲过一些字符串函数&#xff08;http://t.csdnimg.cn/ZcvCo&#xff09;&#xff0c;今天我们来讲一讲几个内存函数&#xff0c;那么可能有人要问了&#xff0c;都有字符串函数了&#xff0c;怎么又来个内存函数&#xff0c;这不是一样的么&#xff1f; 我们要知道之前…

【C语言】指针进阶之sizeof和strlen函数的对比

目录 1.sizeofyu 2.strlen函数 3.sizeof与strlen的对比 1.sizeof >>sizeof计算变量所占内存内存空间 大小 的&#xff0c;单位是 字节 &#xff0c;如果操作数是类型的话&#xff0c;计算的是使⽤类型创建的变量所占内存空间的大小。 >>sizeof 只关注占⽤内存空…