第4章 C++的类

  • 类的保留字:class、struct 或 union 可用来声明和定义类。
  • 类的声明由保留字class、struct或union加上类的名称构成。
  • 类的定义包括类的声明部分和类的由{}括起来的主体两部分构成。
  • 类的实现通常指类的函数成员的实现,即定义类的函数成员。
class 类名;//前向声明
class 类名 {
private:私有成员声明或定义;
protected:保护成员声明或定义;
public:公有成员声明或定义;
};

定义类时应注意的问题

  • 使用private、protected和public保留字标识主体中每一区间的访问权限,同一保留字可以多次出现;
  • 同一区间内可以有数据成员、函数成员和类型成员,习惯上按类型成员、数据成员和函数成员分开;
  • 成员在类定义体中出现的顺序可以任意,函数成员的实现既可以放在类的外面,也可以内嵌在类定义体中;但是数据成员的定义顺序与初始化顺序有关。
  • 若函数成员在类定义体外实现,则在函数返回类型和函数名之间,应使用类名和作用域运算符“::”来指明该函数成员所属的类。
  • 在类定义体中允许对所数据成员定义默认值,若在构造函数的“:”和函数体的“{ ”之间对其进行了初始化,则默认值无效,否则用默认值初始化;
  • 类定义体的最后一个花括号后要跟有分号作为定义体结束标志。
  • 构造函数和析构函数都不能定义返回类型。
  • 如果类没有自定义的构造函数和析构函数,且有非公开实例数据成员等情形,则C++为类生成默认的无参构造函数和析构函数。
  • 构造函数的参数表可以出现参数,因此可以重载。
  • 构造函数和析构函数:是类封装的两个特殊函数成员,都有固定类型的隐含参数this 。
  • 构造函数:函数名和类名相同的函数成员。
  • 析构函数:函数名和类名相同且带波浪线的参数表无参函数成员。
  • 定义变量或其生命期开始时自动调用构造函数,生命期结束时自动调用析构函数。
  • 同一个对象仅自动构造一次。构造函数是唯一不能被显式(人工)调用的函数成员。
  • 构造函数用来为对象申请各种资源,并初始化对象的数据成员。构造函数有隐含参数this, 可以在参数表定义若干参数,用于初始化数据成员。
  • 析构函数是用来毁灭对象的,析构过程是构造过程的逆过程。析构函数释放对象申请的所有资源。
  • 析构函数既能被显式调用,也能被隐式(自动)调用。由于只有一个固定类型的this,故不可能重载,只能有一个析构函数。
  • 若实例数据成员有指针,应当防止反复析构(用指针是否为空做标志)。
  • 联合也是类,可定义构造、析构以及其它函数成员。

 e.g.

#include <alloc.h>
struct STRING {typedef  char* CHARPTR;        //定义类型成员CHARPTR  s;                //定义数据成员int  strlen();                //声明函数成员,求谁的长(有this)STRING(const char*);        //声明构造函数,有this~STRING();                //声明析构函数,有this
};
int STRING::strlen() {         //用运算符::在类体外定义int  k;for (k = 0; s[k] != 0; k++);return k;
}
STRING::STRING(char* t) {//用::在类体外定义构造函数,无返回类型int  k;for (k = 0; t[k] != 0; k++);s = (char*)malloc(k + 1);         //s等价于this->sfor (k = 0; (s[k] = t[k]) != 0; k++);
}
STRING::~STRING() {//用::在类体外定义析构函数,无返回类型free(s);
}
struct  STRING  x("simple");        //struct可以省略
void main() {STRING  y("complex"), * z = &y;int  m = y.strlen();                  //当前对象包含的字符串的长度            m = z->strlen();
}   //返回时自动调用y的析构函数

程序不同结束形式对对象的影响

  1. exit 退出:局部自动对象不能自动执行析构函数,故此类对象资源不能被释放。静态和全局对象在exit退出main时自动执行收工函数析构。
  2. abort 退出:所有对象自动调用的析构函数都不能执行。局部和全局对象的资源都不能被释放,即abort退出main后不执行收工函数。
  3. return 返回:隐式调用的析构函数得以执行。局部和全局对象的资源被释放。int main() { …; if (error) return 1; …; } ,提倡使用 return。如果用 abort和 exit,则要显式调用析构函数。另外,使用异常处理时,自动调用的析构函数都会执行。
#include <process.h>
#include “string.cpp”          //不提倡这样include:因为string.cpp内有函数定义
STRING x("global");        //自动调用构造函数初始化x
void main(void) {short error = 0;STRING y("local");        //自动调用构造函数初始化yswitch (error) {case  0: return;          //正常返回时自动析构 x、ycase  1: y.~STRING();        //为防内存泄漏,exit退出前必须显式析构 yexit(1);default: x.~STRING();        //为防内存泄漏,abort退出前须显式析构 x、yy.~STRING();abort();}
}

 

接受与删除编译自动生成的函数

        default = 接受, delete = 删除。

        若类A没有定义任何构造函数,则编译器会自动提供无参的构造函数 A()(实际上是空操作,相当于一条return语句);如果A定义了任何构造函数,编译器就不会自动提供无参构造函数。

        不管A是否定义了构造函数,A类只要没有定义带引用参数 A & 的构造函数 A(const A & a) ,编译器会自动提供该构造函数 A(const A & a)(利用浅拷贝实现该构造函数)。

        可以利用 default、delete 强制说明接受、删除编译器提供的构造函数,如 A() = default、 A(const A & a) = delete。

//使用delete禁止构造函数以及default接受构造函数。
struct A {int x = 0;A(int m) : x(m) {}A(const A& a) = default;   //接受编译生成的拷贝构造函数A(const A &)
};
void main(void) {A x(2);                   //正确:调用程序员自定义的单参构造函数A(int)A y(x);                   //正确:调用编译生成的拷贝构造函数A(const A &)A u;                      //错误:调用构造函数A( ),编译器不提供缺省的A()(因为有别的构造函数)A v();                    //正确:声明一个函数v( ),其返回类型为A
}   //A v()  <=>  extern  A v()

成员访问权限

  • private:私有成员,本类函数成员可以访问;派生类函数成员、其他类函数成员和普通函数都不能访问。
  • protected:保护成员,本类和派生类的函数成员可以访问,其他类函数成员和普通函数都不能访问。
  • public公有成员,任何函数均可访问。

        类的友元不受这些限制,可以访问类的所有成员。另外,通过强制类型转换可突破访问权限的限制。

        构造函数和析构函数可以定义为任何访问权限。不能访问构造函数则无法用其初始化对象。

#include <iostream>
class A {int  x;      //私有,只能被本类的成员访问typedef char* POINTER1;
public:         //公有,能被任何函数使用int y;
protected:    //保护:只能被本类及继承类的成员访问int z;
public:         //公有,能被任何函数使用typedef char* POINTER2;A(int x, int y, int z) : x(x), y(y), z(z) {}int sum() {return x + y + z;}
};
void main(void) {A a(1, 2, 3);
//    std::cout << a.x;         //错:不能访问私有成员std::cout << a.y<<std::endl;         //对
//    std::cout << a.z;         //错:不能访问保护成员std::cout << a.sum();  //对char s[] = "abcd";
//   A::POINTER1 p1 = s;    //错:类型A::POINTER1是私有的A::POINTER2 p2 = s;  //对
//    p2 = "abcd";   //错:"abcd"是const char *,p2是char *p2 = (char*)"abcd";  //对,等价 p2 = (A::POINTER2)"abcd"
}

 关于常量字符串

常量字符串(如“abc”、“123AB”等)本质上是 const 指针(char *const p), 它指向一个不可修改的字符串(即 const char *const p)。

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{const char* const p1 = "abc";              //等价:const char *const p1("abc")std::cout << "abc"[1] << p1[0]<<endl;//p1 = "123";                              //错const char* p2 = "abc";                    //等价:const char *p2("abc")std::cout << "abc"[1] << p2[0]<<endl;p2 = "123";                             //对
//    char* p3 = "abc";                     //错,等价 char *p3(“abc”),用1个const char指针去构造char指针char* p3 = (char*)"abc";                //等价:char *p3((char *)"abc")std::cout << "abc"[1] << p3[0]<<endl;p3[0] = '1';                           //编译对,运行错(指针可改,值不可改)int  k = 1;                            //等价:int k(1)char s[] = "abc";                      //对,等价 char s[]("abc")//   char* p =  "abc";                    //错,等价 char *p(“abc”),
}                                          //注意:构造数组和构造指针是不一样的!

函数成员的内联

        在类体内定义的任何函数成员都会自动内联。

        在类内或类外使用inline保留字说明函数成员。

        内联失败:有分支类语句定义在使用后取函数地址定义(纯)虚函数。

        内联函数成员的作用域局限于当前代码文件。

        匿名类函数成员只能在类体内定义(内联)。

        函数局部类的函数成员只能在类体内定义(内联),某些编译器不支持局部类。

位段成员:按位分配内存的数据成员

  • class、struct 和 union 都能定义位段成员;
  • 位段类型必须是字节数少于整数类型的类型,
  • 如:char,short,int,long long , enum(实现为int:简单类型)
  • 相邻位段成员分配内存时,可能出现若干位段成员共处一个字节,或一个位段成员跨越多个字节。
  • 因按字节编址,故位段无地址。
  • 位段用法:
  • 用于生产过程控制的各种开关、指示灯等;
  • 布尔运算、图象处理等;

new 和 delete

        C不必实现函数 malloc、free;

        C++必须实现运算符 new、delete。

内存分配

        malloc为函数,参数为值表达式

        new为运算符,操作数为类型表达式先底层调用malloc,然后调用构造函数;

        用 “new 类型表达式{}” 可使分配的内存清零,若“{}”中有数值可用于初始化。

内存释放

        free为函数,参数为指针类型值表达式,直接释放内存;

        delete为运算符,操作数为指针类型值表达式,先调用析构函数,然后底层调用 free。

  • 如为简单类型(没有构造、析构函数)分配和释放内存,则new和malloc、 delete和free没有区别,可混合使用:比如new分配的内存用free释放。
  • 无法用malloc代替new初始化, new调用的构造函数可维护多态。
  • 注意delete的新参类型应为const void* ,因为它可接受任意指针实参。
  • new <类型表达式> 后接()或 {}用于初始化或构造。{}可用于数组元素
  • 类型表达式:int* p = new int; //等价int *p = new int(0);
  • 数组形式仅第一维下标可为任意表达式,其它维为常量表达式int(*q)[6][8] = new int[x + 20][6][8];
  • 为对象数组分配内存时,必须调用参数表无参构造函数
  • delete <指针>
  • 指针指向非数组的单个实体:delete p; 可能调析构函数。
  • delete[]<数组指针>
  • 指针指向任意维的数组时:delete[] q;
  • 如为对象数组,对所有对象(元素)调用析构函数。
  • 若数组元素为简单类型,则可用delete <指针>代替。

 

#include <malloc.h>
#include <process.h>
class  ARRAY {                        //class体的缺省访问权限为privateint* a, r, c;
public:                             //访问权限改为publicARRAY(int x, int y);~ARRAY();
};
ARRAY::ARRAY(int x, int y) {a = new int[(r = x) * (c = y)];        //可用malloc:int为简单类型
}
ARRAY::~ARRAY() {          //a指向的简单类型int数组无析构函数if (a) { delete[] a; a = 0; }  //可用free(a), 也可用delete a
}
ARRAY  x(3, 5);                    //开工函数构造,收工函数析构x
void main(void) {int error = 0;ARRAY  y(3, 5), * p;         //退出main时析构yp = new ARRAY(5, 7);                  //不能用malloc,ARRAY有构造函数delete  p;                            //不能用free,否则未调用析构函数
}                                              //退出main时,y被自动析构
//程序结束时,收工函数析构全局对象x

 

this指针

        this指针是一个特殊的指针,它是普通函数成员隐含的第一个参数,其类型是指向要调用该函数成员的对象的const指针。

        当对象调用函数成员时,对象的地址作为函数的第一个实参首先压栈,通过这种方式将对象地址传递给隐含参数this。

        构造函数和析构函数的this参数类型固定。例如A::~A()的this参数类型为

        A* const this; //析构函数的this指向可写对象,但this本身是只读的

        注意:可用* this来引用或访问调用该函数成员的普通、const或volatile对象;类的静态函数成员没有隐含的this指针;this指针不允许移动。

#include <iostream>
using namespace std;
class  TREE {int   value;TREE* left, * right;
public:TREE(int);         //this类型: TREE * const this~TREE();           //this类型: TREE * const this,析构函数不能重载const TREE* find(int) const; //this类型: const TREE * const this
};
TREE::TREE(int value) {         //隐含参数this指向要构造的对象this->value = value;                //等价于TREE::value=valueleft = right = 0;                 //C++提倡空指针NULL用0表示
}
TREE::~TREE() {   //this指向要析构的对象if (left) { delete left; left = 0; }if (right) { delete right; right = 0; }
}
const TREE* TREE::find(int v) const {  //this指向 调用对象if (v == value) return this;  //this指向找到的节点if (v < value)                //小于时查左子树,即下次递归进入时新this=leftreturn  left != 0 ? left->find(v) : 0;return  right != 0 ? right->find(v) : 0; //否则查右子树
}
TREE root(5);   //收工函数将析构对象root
void main(void) {if (root.find(5)) cout << "Found\n";
}

构造和析构

        类可能会定义只读和引用类型的非静态数据成员,在使用它们之前必须初始化;若无默认值,该类必须定义构造函数初始化这类成员。

        类A还可能定义类B类型的非静态对象成员,若对象成员必须用带参数的构造函数构造,则A必须定义有初始化的构造函数(自定义的类A的构造函数,传递实参初试化类B的非静态对象成员:缺省的无参的A()只调用无参的B())。

        构造函数的初始化位置在参数表的“ : ”后,所有数据成员都必须在此初始化,未列出的成员用其默认值值初始化,未列出且无默认值的非只读、非引用、非对象成员的值根据对象存储位置可取随机值(栈段)或0及nullptr值(数据段)。

        定义顺序初始化或构造数据成员(大部分编译支持)。

        如未定义或生成构造函数,则可以用”{}”的形式初始化。联合仅需初始化第一个成员。

        对象数组的每个元素都必须初始化,默认采用无参构造函数初始化。

        单个参数的构造函数能自动转换单个实参值成为对象。

        若类未自定义构造函数,且类包含私有实例数据成员时,编译会自动生成构造函数。

        一旦自定义构造函数,将不能接受编译生成的构造函数,除非用default等接受。

        用常量对象做实参,总是优先调用参数为&& 类型的构造函数;

        用变量对象实参,总是优先调用参数为& 类型的构造函数。

class A {int  a = 0;                 //数据成员可以在定义时初始化
public:A(int x) { a = x; }        //重载构造函数;自动内联A() { a = 0; }             //重载构造函数;自动内联
};
class B {const  int  b = 1;          //数据成员可以在定义时初始化int  c, & d, e, f;          //b, d, g, h只能在构造函数体前初始化A    g, h;         //数据成员按定义顺序b, c, d, e, f, g, h初始化
public:  //类B构造函数体前未出现h,故h用A()初始化B(int y) : d(c), c(y), g(y), b(y), e(y) {  //自动内联c += y;f = y;}  //f被赋值为y
};
void main(void) {int x(5);                                  //int x = 5 等价于 int x(5)A a(x), y = 5;                             //A y = 5 等价于 A y(5)A* p = new A[3]{ 1, A(2) };                //初始化的元素为 A(1),  A(2), A(0)B b(7), z = (7, 8);                        //B z=(7, 8) 等价于 B z(8), 等号右边必须单值delete[] p;                        //防止内存泄漏:new 产生的所有对象必须用 delete 释放
}                                                 //故(7, 8)为C的扩号表达式,(7, 8) = 8

        创建对象时,不调用构造函数的情况(满足下面的条件):

  1. 类中没有定义任何构造函数、没有虚函数;
  2. 该类不是派生类(别的类可以是该类的派生类);
  3. 定义对象时用 { ... } 给对象赋值,{ ... }中的元素个数必须小于等于类中实例成员变量(非static变量)的个数。这相当于在构造函数的参数初始化列表中给实例成员变量初始化;
  4. 用非空的 { ... } 给对象赋值时, 类中对应的实例成员变量可以被访问。
struct  A  {		              class  A  {const  int  a;     或者  	       public:int  b;			                   const int a;
};				                       int  b;}
int main(void) {A  a1 = { };	        //对,不调用构造函数A  a2 = { 1 };	        //对,不调用构造函数A  a3 = { 1, 2 };       //对,不调用构造函数A  a4 = { 1, 2, 3 };    //错,需要调用带3个int参数的构造函数A  a5;	                //错,需要无参的构造函数(因为 const int a )
}

 如果A定义为如下情况


struct A {const  int  a;int  b;A(…) { }
}; //用 { … } 赋值也需要调用构造函数, 这时 {…}表示构造函数的参数表.
//或者
class A {const  int  a;int  b;
}; //成员变量不可访问, 不能用 { … } 赋值.

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

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

相关文章

C#,字符串匹配(模式搜索)Sunday算法的源代码

Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法。 核心思想&#xff1a;在匹配过程中&#xff0c;模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较&#xff0c;它在发现不匹配时&#xff0c;算法能跳过尽可能多的字符以进行下一步的匹配&…

港科夜闻|香港科大团队研发多功能,可重构和抗破坏单线感测器阵列

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大团队研发多功能、可重构和抗破坏单线感测器阵列。研究人员开发出一种受人类听觉系统启发的感测器阵列设计技术。透过模仿人耳根据音位分布来区分声音的能力&#xff0c;这种新型感测器阵列方法可能优化感测器阵列…

Yolov8_使用自定义数据集训练模型1

前面几篇文章介绍了如何搭建Yolov8环境、使用默认的模型训练和推理图片及视频的效果、并使用GPU版本的torch加速推理、导出.engine格式的模型进一步利用GPU加速&#xff0c;本篇介绍如何自定义数据集&#xff0c;这样就可以训练出识别特定物体的模型。 《Yolov8_使用自定义数据…

innoDB存储引擎

1.逻辑存储结构 行数据->行->页->区->段->表空间 表空间(ibd文件)&#xff0c;一个mysql实例可以对应多个表空间&#xff0c;来存储记录&#xff0c;索引等数据。 段&#xff1a;分为数据段和索引段&#xff0c;回滚段&#xff0c;数据段就是B树的叶子节点&am…

HR3D+HRAuido+HRUI+HR3D_Plugins(游戏引擎源码)

国内知名游戏公司开发的游戏引擎&#xff0c;简洁高效&#xff0c;代码值得参考。包含了这几部分&#xff1a;HR3DHRAuidoHRUIHR3D_Plugins HR3DHRAuidoHRUIHR3D_Plugins&#xff08;游戏引擎源码&#xff09; 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1…

使用xbindkeys设置鼠标侧键

1.安装如下包 sudo apt install xbindkeys xautomation 2.生成配置文件 xbindkeys --defaults > $HOME/.xbindkeysrc 3.确定侧键键号 在终端执行下面的代码&#xff1a; xev | grep button 此时会出现如下窗口&#xff0c;将鼠标指针移动到这个窗口上&#xff1a; 单…

【机器学习】调配师:咖啡的完美预测

有一天&#xff0c;小明带着一脸期待找到了你这位数据分析大师。他掏出手机&#xff0c;屏幕上展示着一份详尽的Excel表格。“看&#xff0c;这是我咖啡店过去一年的数据。”他滑动着屏幕&#xff0c;“每个月的销售量、广告投入&#xff0c;还有当月的气温&#xff0c;我都记录…

【MYSQL】事务隔离级别

脏读、幻读、不可重复读 脏读 一个事务正在对一条记录做修改&#xff0c;在这个事务完成并提交前&#xff0c;另一个事务也来读取同一条记录&#xff0c;读取了这些未提交的“脏”数据&#xff0c;并据此做进一步的处理&#xff0c;就会产生未提交的数据依赖关系。这种现象被形…

【控制篇 / 分流】(7.4) ❀ 01. 对指定IP网段访问进行分流 ❀ FortiGate 防火墙

【简介】公司有两条宽带&#xff0c;一条ADSL拨号用来上网&#xff0c;一条移动SDWAN&#xff0c;已经连通总部内网服务器&#xff0c;领导要求&#xff0c;只有访问公司服务器IP时走移动SDWAN&#xff0c;其它访问都走ADSL拨号&#xff0c;如果你是管理员&#xff0c;你知道有…

自定义 React Hooks:编写高效、整洁和可重用代码的秘密武器

欢迎来到神奇的 React 世界 大家好!在 React 的世界中,有一个强大的秘密武器,它往往隐藏在显而易见的地方,由于缺乏理解或熟悉而没有得到充分利用。 这个强大的工具,被称为自定义 React hooks,可以彻底改变我们编写 React 应用程序代码的方式。通过提取组件中的有状态逻辑,自…

查找局域网树莓派raspberry的mac地址和ip

依赖python库&#xff1a; pip install socket pip install scapy运行代码&#xff1a; import socket from scapy.layers.l2 import ARP, Ether, srpdef get_hostname(ip_address):try:return socket.gethostbyaddr(ip_address)[0]except socket.herror:# 未能解析主机名ret…

Electron Apple SignIn 登录

本人写博客&#xff0c;向来主张&#xff1a;代码要完整&#xff0c;代码可运行&#xff0c;文中不留下任何疑惑。 最讨厌写博客&#xff0c;代码只留下片段&#xff0c;文中关键的东西没写清楚。之前看了那么多文章&#xff0c;就是不告诉我clientId从哪来的。 官方资料地址&…

WordPress后台底部版权信息“感谢使用 WordPress 进行创作”和版本号怎么修改或删除?

不知道各位WordPress站长在后台操作时&#xff0c;是否有注意到每一个页面底部左侧都有一个“感谢使用 WordPress 进行创作。”&#xff0c;其中WordPress还是带有nofollow标签的链接&#xff1b;而页面底部右侧都有一个WordPress版本号&#xff0c;如下图中的“6.4.2 版本”。…

chisel入门初步1——基4的booth编码的单周期有符号乘法器实现

基4的booth编码乘法器原理说明 基2的booth编码 本质来说就是一个裂项重组&#xff0c;乘法器最重要的设计是改变部分积的数量&#xff0c;另外在考虑有符号数的情况下&#xff0c;最高位符号位有特别的意义。 &#xff08;注&#xff1a;部分积是指需要最后一起加和的所有部分…

使用的uview 微信高版本 头像昵称填写能力

<template><view><button class"cu-btn block bg-blue margin-tb-sm lg" tap"wxGetUserInfo">一键登录</button><view><!-- 提示窗示例 --><u-popup :show"show" background-color"#fff">&…

关于C#中的async/await的理解

1. 使用async标记的方法被认为是一个异步方法&#xff0c;如果不使用await关键字&#xff0c;调用跟普通方法没有区别 static async Task Main(string[] args){Console.WriteLine("主线程id&#xff1a;" Thread.CurrentThread.ManagedThreadId);TestAwait();Consol…

翻译: Streamlit从入门到精通六 实战缓存Cache请求数据

Streamlit从入门到精通 系列&#xff1a; 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三翻译: Streamlit从入门到精通 部署一个机器学习应用程序 四翻译…

从matlab的fig图像文件中提取数据

这里用的是openfig&#xff08;&#xff09;函数打开的fig文件 →→→【matlab 中 fig 数据提取】 很简洁 →→→【MATLAB提取 .fig 文件中的数据】 这个给出了包含多个曲线的情况 →→→【提取matlab fig文件里的数据和legend】 chatgpt给出的方法 打开fig文件并保存数据 我的…

StarRocks 生成列:百倍提速半结构化数据分析

半结构化分析主要是指对 MAP&#xff0c;STRUCT&#xff0c;JSON&#xff0c;ARRAY 等复杂数据类型的查询分析。这些数据类型表达能力强&#xff0c;因此被广泛应用到 OLAP 分析的各种场景中&#xff0c;但由于其实现的复杂性&#xff0c;对这些复杂类型分析将会比一般简单类型…

【单片机】改写DS2431芯片的地址码,地址ROM,DS2431芯片解密

对DS2431里面的128字节可以进行任意读写&#xff0c;方式可以看这里&#xff1a;https://blog.csdn.net/x1131230123/article/details/132248958 但DS2431芯片的地址码是光刻不可修改的&#xff0c;所以只有使用模拟芯片。 原理&#xff1a; https://www.dianyuan.com/article…