C嘎嘎入门篇:类和对象(1)

news2024/11/18 22:27:39

前言:

  小编在之前讲述了C++的部分入门基础,读者朋友一定要掌握好那些,因为C++的学习和C有点不同,C++的知识都是比较连贯的,所以我们学好了前面才可以学习后面的内容,本篇文章小编将会讲述C++真正的入门篇:类和对象,学完这一部分后我们才可以说我们真的C++入门了,下面废话不多说,开启今天第一部分的讲解:


目录

1.类的定义

 1.1.类定义的格式

  1.1.1class关键字

 1.1.2.类定义的两种方式

 1.声明和定义放在一起

 2.声明和定义分离

 1.2.访问限定符

 1.2.1.引例

 1.2.2.访问限定符的概念

 1.2.3.访问限定符的分类

 1.2.4.访问限定符的使用

 1.3.类域

 1.3.1.类域的概念

 1.3.2.类域的使用

2.实例化

 2.1.实例化的概念

2.2.对象的大小

 2.2.1.内存对齐的规则

 2.2.2.实例化后对象的大小

3.this指针

4.两道小小的选择题

 1.第一道选择题

 2.第二道选择题


正文:

1.类的定义

 1.1.类定义的格式

  类是C++增加的内容,以小编的话来说,其实类就是我们在C学到的结构体的升级版,可能看到这里很多读者朋友会懵,不要急,等会小编就会慢慢的讲到,首先我们先说一下定义类类型的关键字。

  1.1.1class关键字

  class是C++用于定义类 类型 的关键字,这个记住就好,下面小编就先拿出一段代码来带大家去看一下如何用C++来书写类,也方便小编对于class的使用做出解释:

可以把class想成更加高级的struct,只不过它比结构体多了可以增加函数,并且类的名字就是类的类型
//class wang
//{
//public:
   //成员函数
//	void add(int a, int b)
//	{
//		cout << a + b << endl;
//	}
//	void Init(int a = 1,int b = 1)   //后面学习的构造函数
//	{
//		_a = a;
//		_b = b;
//	}
//private:
  // 成员变量
//	int _a;
//	int _b;
//};
//

  首先不难看出,类和结构体的用法都是相似的,它们都是在对应的关键字后面加上名字,然后用{},最后别忘加个“;”就好,这个就是结构体的用法,小编在上面也说过,类就是结构体的升级版,之后比结构体更高级的是,类里面是可以放置函数的,我们把类里面的函数叫做成员函数(类的方法),与结构体一样,类里面也应该有成员,此时我们叫做成员变量(类的属性),这便是类的一些基本组成部分,当然,为了区分某些成员变量,就比如小编上面的成员函数Init的形参是a,b,我们在写成员变量的时候,可以在变量前面加上 _ 或者m开头,当然,C++对于成员变量的命名没有什么要求,这只是为了区分形参和成员变量而来的,可以看作一种惯例,写不写都可以的,全看自己。对于成员函数,小编在这里说一下,类里面的成员函数都默认为inline,也就是内联函数,对于内联函数小编在上一篇文章讲过,感兴趣的读者朋友可以看一下小编上一篇关于内联函数的介绍。

  可能有很多读者朋友对于上面的public和private很好奇这几个单词出现在这里是为了什么,不要着急,小编稍后会讲到的。

 1.1.2.类定义的两种方式

  对于类,我们可以通过两种方式进行定义(主要是通过成员函数进行区分),下面我们先来讲述一下第一种:

 1.声明和定义放在一起
class wang
{
	int add(int a, int b)
	{
		return a + b;
	}
	int _a;
	int _b;
};

  此种情况其实就是小编在上面展示的代码,不难看出,此时我们在书写成员函数的时候,直接把它的定义给写出来了,此时我们函数的声明和定义是在一起的,这是我们书写类的第一种方式,不过不知道读者朋友是否还记着小编在之前数据结构的文章中,小编对于顺序表什么的书写都是函数的声明和定义分别在不同文件中,声明放在头文件,定义放在源文件中实现,所以我们在写类的时候,第二种方式就是声明和定义是分离的:

 2.声明和定义分离

 ceshi.h

class wang
{
	int add(int a, int b);  //此时就是函数的声明
	int _a;
	int _b;
};

 ceshi.cpp

int wang::add(int a, int b)  //对于前面的操作符小编也在文章后面说
{
	return a + b;
}

  此时上面就是类的定义和声明是分离的,此时我们只需要把我们想要写的类放在头文件中,然后把实现方法写在源文件就好了,这对于我们书写一些数据结构或者一些比较大的项目的时候是很实用的,各位读者朋友一定要掌握好这种写法。小编虽然目前还是个小白,但是我猜测后面我们实现一些数据结构的时候,对于类的使用应该就是这样的,不过现在肯定有很多小伙伴疑惑,小编在ceshi源文件写的 “wang :: ”是什么意思,为什么会用到域作用限定符了?难道类也是一种域?这是肯定的,小编在之前讲述域的时候,就说过C++是有四种域的,此时就是我们在之前没有讲过的:类域!对于类域的讲解,小编也是后面会讲,不要着急,慢慢来,下面小编先要讲述一下我之前没讲的,对于访问限定符的讲解!

 1.2.访问限定符

 1.2.1.引例

  在讲述访问限定符之前,小编先通过一段代码来带大家去感受一下访问限定符到底是干啥的,此时我们就拿上面的代码举例:

class wang
{
	int add(int a, int b)
	{
		return a + b;
	}
	int _a;
	int _b;
};

int main()
{
	wang s1;  //我们可以认定此时wang是定义了一个s1的对象,这个叫做实例化,后面我会说
	s1.add(1, 2);  //这里为什么会报错?
	return 0;
}

    此时我们在进行编译的时候,发现编译器给我们报错,说我们无法访问private成员,这个其实就是其中一个访问限定符,它限制了我们去访问这个函数,所以此时我们便知道了访问限定符的作用,它是用来限定我们去使用类里面的数据的,下面我们正式来讲一下访问限定符的概念!

 1.2.2.访问限定符的概念

  C++是一种实现封装的方式,用类将对象(呜呜呜我也是有对象的人了),让对象更加的完善,通过访问的权限来选择性的将其接口提供给外部的成员使用,此时访问限定符就是可以决定我们对于类中元素的使用权限,这便是访问限定符的概念,从前面小编写过的代码我们可以看出访问限定符似乎有多种,下面小编就给各位读者朋友讲述一下访问限定符的分类:

 1.2.3.访问限定符的分类

  正如上图所示,在我目前我学习的C++的知识中,上面就是现阶段我们要学习的访问限定符,现在让小编带领各位去了解每个限定符的用法:

  首先是 public 限定符,它的中文名是公开的,所以它再类的作用就是公有,以为着类外的元素可以访问被它修饰过的类里面的元素,之后是private和protected,经过翻译后的意思是私有和保护,在目前我们的学习中,我们可知道被这两个符号修饰过的类中的元素是不可以被外界元素访问的,这里可能很多读者朋友会有疑问了,那这两个作用不都是一样的吗?为啥还要区分开,确实,以我们目前的知识储备,他们都是一样的,但是其实我们在往后学,在继承章节我们才可以知道它们的不同,所以他俩还是不一样的,不然为什么祖师爷会分出这俩。这里小编爷爷奥提一嘴下面我们来讲一下如何使用访问限定符(其实小编在上面的代码已经展现了):

 1.2.4.访问限定符的使用

  这个也是蛮简单的,我们只要写访问限定符,再加上一个“ :”就好了,如下面代码所示:

class wang
{
public:
	void Init(char * arr,int age,char* arr1)
	{
		strcpy(arr, _arr);
		_age = age;
		strcpy(_arr1,arr1);
	}
private:
	char* _arr;
	int _age;
	char* _arr1;
};

    上面就是对于访问限定符的使用,对于访问限定符,我们也要知道它的作用域,它的作用域是从访问限定符开始,到下个访问限定符之前,如上面的代码,public的作用域就是在它:之后到private之前,而private的作用域是从它的:开始到},如果在类中只有一个访问限定符,那么它的作用域就是到 } 之前,也就是包含整个类域的。小编在之前也提到过类域,但是小编还没有讲,那么下面,我们开始进入类域的学习。

 1.3.类域

 1.3.1.类域的概念

  类定义了一个新的作用域,类的所有成员都在类的作用域中。毕竟类就像我们再刚开始讲过的命名空间一样,我们都是把名字进行隔离了,我们在类外面同样也是可以用类里面的成员名来去使用这些名字的,目前为止,小编已经把四种域讲完了,不知道各位读者朋友是否还记得:分别是全局域,局部域,命名空间域,类域,下面小编将会讲述类域的一些使用注意事项

 1.3.2.类域的使用

  对于域的使用,小编在之前也说过,我们需要用到域作用限定符,也就是“:”,那么我们什么时候才会用到类域呢?我们一般在进行声明和定义分离到不同文件时候,我们才可以去使用类作用限定符,就拿小编上面讲的ceshi.cpp来说,通过这个我们就可以看见小编此时用到了域作用限定符,因为如果小编不加这个的话,编译器会默认到全局域中去查找这个函数,在全局域是不存在这个函数的,因为小编把函数声明放到类域里面的,除非我们使用了域作用限定符,否则编译器是不会去识别类里面的函数的,此时就展现了我们如何对类域进行使用,此时我们已经讲述完了类的一些基础知识,下面我们就要用类去创建对象了(对象来喽!),系好安全带,准备出发喽!

2.实例化

  很多读者朋友一看到这个就感觉很懵,实例化是个啥玩意,小编当时也是觉得有些懵的,直到我学了以后,才知道,实例化通俗点来讲,就是用类去定义一个变量,就像我们定义整型变量,结构体类型的变量一样,但是也是有一些不同的,因为很多读者朋友在学完了类域的知识以后,认为我们在想要使用类里面元素的时候,可以直接用域作用限定符去使用,其实这是不可以的,因为我们类里面的成员变量只是声明,编译器并没有给他开辟空间,只有开辟了空间的我们才可以叫做定义,下面我们来好好说一下实例化的相关概念:

 2.1.实例化的概念

  用类类型在物理内存中创建对象的过程,称为类实例化对象,类是对象进行一种抽象概述,是一个模型一样的东西,限定了类有哪些成员变量,小编在上面说过,成员变量只是声明,并没有分配空间,用类实例化出对象以后,才会分配空间。

  当然,一个类可以有多个对象,实例化出的对象是占物理空间的,其实此时,我们可以把类比做成一个图纸,而对象就是依靠图纸建造的房子,通过这个图纸可以建立好多个房子,就如下图所示:

  上图就是类的一个类比图·,类就是建房子的图纸,而对象就是通过图纸建造的房子,所以只有建造房子的时候才会开辟空间,而类(图纸)并没有分配空间,这个是类比较重要的知识,各位读者朋友一定要好好的去理解 

2.2.实例化的使用

  其实对于类的实例化,和定义结构体变量是一样的,我们直接确定一个对象名直接建立就好,至于我们对于类里面成员的运用,和结构体一样 ,如果我们创立的不是指针,那么就用“.”操作符,如果是建立了类指针,那么就用“->”操作符,所以这里也能体现类就是结构体的升级版,不过和结构体不同的是,我们在这里进行定义的时候,类的名字就是类的类型,想当初我们学习结构体的时候,关键字+结构体名才代表着结构体的类型,不过在C++中,结构体名也是结构体的类型了,我们不在需要使用typedef关键字来进行改名了,这就是C++对于C的优化,所以从这里我们也看出来了C++的香了,不多废话,下面小编展示一下用完整的用类写完一个类(日期类):

using namespace std;
//日期类
class Date
{
public:
	void Init(int year, int mouth, int day)
	{
		_year = year;
		_mouth = mouth;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _mouth << "/" << _day << endl;
	}
private:
	int _year;
	int _mouth;
	int _day;
};
int main()
{
	Date s1;
	s1.Init(2024, 8, 8);
	s1.Print();
	Date s2;
	s2.Init(2024,8,7);
	s2.Print();
	return 0;
}

  上面的代码就是小编用了完整的类写了个简易的程序,可以看出此时我们实例化后的使用,也可以看出类比C时的结构体的优点,因为类实现了方法和元素封装在一起的功能,这样会让我们去更方便的完成一些事情,上面的代码还体现了一个类可以实例化多个对象,这也印证了小编上面所说的,下面让我们看看上面代码的运行图:

  可以看出成功运行出了程序,这便是实例化的使用,我们在之前无论学习什么类型,整形,指针类型,结构体类型……我们都知道了这些类型定义完后变量的大小,自然的,我们学习完了类的实例化以后,我们还需要知道实例化后对象的大小,这个也是很重要的,下面我们来进行对象大小的学习。

2.2.对象的大小

 2.2.1.内存对齐的规则

  我们想要去计算对象的大小,首先我们就要复习一下我们在C语言阶段学习的关于结构体内存对齐的知识,上面就是小编找之前学习内存对齐的时候记下的规则(当时我懒没有写博客),为了让读者朋友去更好的了解内存对齐的知识,小编通过一个例子来给各位读者朋友去更好的了解内存知识:

struct wang
{
	char a;
	int b;
	int c;
};

  对于这个题的大小小编通过图片和文字的方式进行讲解:

  首先我们可以知道a是字符型,所以内存占据一个字节,而b和c都是整型,所以在内存中占据四个字节,所以我们可以知道对齐数是4个字节(4比8小,小编的编译器是VS,自然也是用的VS的规则),所以如图所示:

  通过上图我们可以知道,此时我们的对齐数是9,但是此时的对齐数是4,不符合对齐数的倍数,所以大小应该是4的倍数也就是12个字节大小,下面来看一下此代码的运算图:

  可以看出小编说的并没有错,那么知道了对齐知识以后,下面我们开始进入对象大小的探究喽!

 2.2.2.实例化后对象的大小

  对于实例化后对象的大小,得看类里面的元素,小编在上文说过,类是结构体的升级版,所以我们计算大小的时候,也是跟结构体一样,我们需要用到结构体内存对齐的知识,小编在之前偷懒没写过结构体的文章,前面小编说了如何进行结构体内存对齐的运算,当下我们的问题是,对于类里面的函数我们是否需要计算大小?那么,我们可以大胆的去猜测一下,类里面的函数是不需要去计算大小的,当然我说的肯定是不准的,下面小编来计算一下上面小编写过程序的代码:

using namespace std;
//日期类
class Date
{
public:
	void Init(int year, int mouth, int day)
	{
		_year = year;
		_mouth = mouth;
		_day = day;
	}
private:
	int _year;
	int _mouth;
	int _day;
};
int main()
{
	Date s1;
	s1.Init(2024, 8, 8);
	cout << sizeof(s1) << endl;
	Date s2;
	s2.Init(2024,8,7);
	cout << sizeof(s2) << endl;
	return 0;
}

   通过我们前面讲过的内存对齐的知识,我们可以发现此时类里面的数据仅仅就是计算了成员变量的大小,并没有计算函数的大小,其实我们可以这么想,我们在进行类实例化对象以后,对象已经开辟了空间,所以此时的成员变量肯定就是已经开辟好了空间,那么成员函数呢?首先我们要知道,函数在被编译完以后是一段指令,在对象中是没有办法储存的,这些指令会单独放在一个区域,如果说对象中非要储存的话,只可以是成员函数的指针。这种说法可能会比较难理解,小编换一种说法,我们知道,当我们实例化对象以后,每个对象里面的成员变量肯定是各不相同的(如果相同的话那么类按道理说只可以实例化出一个对象了),但是我们类里面的方法(成员函数)肯定是一样的,它们都是实现的同一个功能,所以没必要再多去开坡空间,几个对象共用一个函数就好了,如果不一样的话,我们每创建一个对象,就要多为成员函数开辟一份空间,如果我们创建100个变量,意味着函数指针要重复100次,这样的话会显的很浪费,所以函数是不需要去开辟空间的,自然也就计算大小对象大小的时候只计算成员变量就好,小编现在准备拿出一个代码题来考验一下各位读者朋友,下面请看:

using namespace std;
class wang
{
public:
	int add(int a, int b)
	{
		return a + b;
	}
};
int main()
{
	wang s1;
	cout << sizeof(s1) << endl;
	return 0;
}

  可能对于这个代码,很多读者朋友会脱口而出,答案是0!如果按照小编之前的讲解,而且可以很清楚的看见小编写的这个类里面只有成员函数,这个答案是没错的,不过,如果这个题那么简单的话,小编也不会去让各位读者朋友去做这个题了,下面小编也不卖关子了,先给大家看一下运行图:

  看到上面的结果,可能很多读者朋友会举着奇怪,难道成员函数是是开辟空间的?这里小编直接给大家解惑:成员函数确实是不开辟空间的,这里的一个字节,其实不是代表着成员函数的大小,它只是编译器开辟1个字节,来代表着:这个对象存在着,而不是啥也没有,仅仅是个标记的作用,各位读者朋友知道就好,可别下次遇到这种题了,你回答个:成员函数也开辟空间!那就闹笑话了。

  根据小编之前的讲解,各位读者朋友知道了我们实例化出多个对象以后,它们的成员函数是共用的,但他们的成员变量都是互不相等,各自开辟空间的,那么小编问各位一个问题:那成员函数是如何区分每一个对象的呢?可能学过C++的读者朋友已经知道小编想要考察什么了,但我相信看这篇博客的大多都是没学过C++的,小编也不藏着掖着了,这些都和一个隐藏指针有关,它就是小编接下来要说的:this指针!

3.this指针

using namespace std;
//日期类
class Date
{
public:
	void Init(int year, int mouth, int day)
	{
		_year = year;
		_mouth = mouth;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _mouth << "/" << _day << endl;
	}
private:
	int _year;
	int _mouth;
	int _day;
};
int main()
{
	Date s1;
	s1.Init(2024, 8, 8);
	s1.Print();
	Date s2;
	s2.Init(2024,8,7);
	s2.Print();
	return 0;
}

  为了小编的讲解,小编这就拿日期类进行举例,上面Date类中有Init和Print两个成员函数,函数体中是没有不同对象的区分的,为了解决函数解决不同对象的问题,C++特地引进了this指针来帮助函数去辨别不同对象的,就拿上面对于s1的Print函数为例,其实这个函数在编译器看来,是这么写的:

s1.Print(&s1);//这个是调用函数的时候,实参的内容

void Print(Date* const s1); //这个是形参的内容

  上面其实就是成员函数的真实摸样,每一个成员函数都有一个隐藏的this指针, 编译器在编译后,成员函数都会在形参第一个位置,来去放置this指针,从而区分处理不同对象的情况,并且类的函数来访问成员变量时,实际上都是通过this指针进行访问的,可能此时很多读者朋友会想,我可不可以在写函数的时候就加上this指针呢?这是不可以的!C++规定不能在形参和实参的位置显示的写this指针(在编译的时候编译器会处理),不过吧,我们可以在函数内部写this指针,虽说可以写,但小编不推荐大家写出来,因为这样的话写的单词就多了(滑稽),不开玩笑啦,这个全凭自己的代码书写习惯,想写就写,不想写就不写,现在,我们已经学完了this指针和对象大小的知识,下面小编给两道选择题来考考大家知识掌握程度,一定要细心哦~

4.两道小小的选择题

 1.第一道选择题

#include <iostream>
using namespace std;
class A {
public:
    void Print() { cout << "A::Print()" << endl; }

private:
    int _a;
};
int main() {
    A* p = nullptr;
    p->Print();
    return 0;
}

我相信,很多读者朋友看到这个题,一看p是一个空指针,一看我们对p使用了解引用操作符,直接给出结果:无脑选A,小编当初也是认为这题选A,秒了!如果这个题真这么简单的话,那我就不会给出这个题了,以小编的老师来说,选A的,就该坐在电机椅上,让自己被电击清醒一下~这个题无论如何都是不选A的,这个就考察到了小编刚才讲的this指针以及成员函数,首先,Print函数里面会有个隐藏的this指针,这是读者朋友们清楚的;其次,小编说过,成员函数是类实例化对象以后所有对象共有的,所以成员函数是不开辟空间的,他在编译阶段就已经形成了一个函数指针,所以实际上这里我们看着是对函数进行了解引用操作,实际上这里我们仅仅就是调用了这个函数,并没有进行解引用,所以这个题应该是C.正常运行!各位读者朋友一定不要迷糊

 2.第二道选择题

#include <iostream>
using namespace std;
class A {
public:
    void Print() { cout << "A::Print()" << endl;
cout << _a << endl;
 }

private:
    int _a;
};
int main() {
    A* p = nullptr;
    p->Print();
    return 0;
}

  这个题和上个题神似,但是这个题目多了一行代码,就在Print函数内部,可能有些读者朋友又想选C,如果真想选C,用小编的话来讲,待遇和上面选A的一块处置,这里我们就用this指针来进行解答,我们知道,成员函数有个隐藏的this指针,它的作用就是来区分不同对象的,让我们进入函数内部,看看第二行代码,这真的仅仅是_a吗?那肯定是错误的,其实这里是this -> _a,此时我们成功的对空指针进行解引用操作了,这肯定编译就过不去,编译器没那么傻,所以这个题选A.编译报错!以上便就是小编根据学过的知识出的题目,各位读者朋友一定要好好的去理解这两个题目,这俩虽然看着简单,但是有很多坑,小编当时就跳进去了,所以各位读者朋友一定要好好的领悟小编前面讲过的知识~

5.C++中的结构体

  本来小编写到上面就不打算写了,突然想到小编似乎只说过类是C结构体的升级版,但是没有说过C++中的结构体是怎样的,小编这就简单的说说,C++的结构体实际上和类的功能大部分是相通的,C++兼容了C中struct的语法,也把结构体升级成了类,结构体也是可以有成员函数,成员变量,结构体的名字就是结构体类型,我们再也不用像当初学习顺序表示用typedef对结构体改名了,这里可能有很多读者朋友会想,这结构体不就是类吗?其实他俩也是有一点差别的,我们如果在类中不用任何访问限定符,其实类默认是private(私有)的,而struct默认为public(公开)的,这是这俩不同的地方,它们可能也会有很多不同的地方,但是小编目前学的不算深,如果以后知道了小编·1会把这篇文章在进行更正修复的,虽说他俩是差不多的,但是小编还是推荐大家以后用class去定义类,毕竟这是C++了,我们一些语法也要跟着大众走了~

总结:

  这篇文章的编写其实非常漫长,小编用了三天的时间才正式把这篇文章学完,不是这篇文章太难,只是小编这两天有点太放纵,太过于沉迷小说,动漫,各位读者朋友可不要学习小编,大家还是要去好好学习的,如果文章有错误,可以在评论区指出,我会及时的去更改,那么我们下篇文章见啦!

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

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

相关文章

爬虫逆向学习(九):记录一个集cookie、请求参数、请求体、响应文本加密的站点反爬

此分享只用于学习用途&#xff0c;不作商业用途&#xff0c;若有冒犯&#xff0c;请联系处理 反爬前置信息 站点&#xff1a;aHR0cHM6Ly96d2Z3LmNxLmdvdi5jbi9pY2l0eS9pY2l0eS9lbmdpbmVlcmluZy9uYXZpZ2F0aW9u 接口&#xff1a;/icity/api-v2/cq.app.icity.engineering.Engine…

vue3组件通信(组合式API)

vue3组件通信&#xff08;组合式API&#xff09; vue3组件通信&#xff0c;采用组合式API。选项式API&#xff0c;参看官网 Vue3组件通信和Vue2的区别&#xff1a; 移出事件总线&#xff0c;使用mitt代替。 vuex换成了pinia。把.sync优化到了v-model里面了。把$listeners所…

fo-dicom开源库,深入理解项目的模块化设计

前言 DICOM&#xff08;Digital Imaging and Communications in Medicine&#xff09;是医学图像和相关信息的国际标准&#xff0c;广泛应用于医学影像领域。FO-DICOM是一个开源的DICOM库&#xff0c;提供了丰富的功能和模块&#xff0c;用于处理DICOM数据、实现DICOM网络通信…

16.面试算法-树的层次遍历与相关面试题

1. 树的层次遍历与相关面试题 1.1 层次遍历简介 广度优先在面试里出现的频率非常高&#xff0c;但是相对简单&#xff0c;题目也比较少&#xff0c;常见的题目也就七八道。 广度优先又叫层次遍历&#xff0c;基本过程如下&#xff1a; 层次遍历就是从根节点开始&#xff0c…

【STM32】 TCP/IP通信协议(1)

一、前言 TCP/IP是干啥的&#xff1f;它跟SPI、IIC、CAN有什么区别&#xff1f;它如何实现stm32的通讯&#xff1f;如何去配置&#xff1f;为了搞懂这些问题&#xff0c;查询资料可解决如下疑问&#xff1a; 1.为什么要用以太网通信? 以太网(Ethernet) 是指遵守 IEEE 802.3 …

【mbti课堂】计算机系统的六个层次与指令系统

课件&#xff1a;可以从 6 个层次分析和看待计算机系统的基本组成。 指令系统层处在硬件系统和软 件系统之间&#xff0c; 是硬、 软件之间的接口部分&#xff0c; 对两部分都有重要影响。 硬件系统用于实现每条指令的功能&#xff0c; 解决指令之间的衔接关系&#xff1b; 软件…

Golang | Leetcode Golang题解之第437题路径总和III

题目&#xff1a; 题解&#xff1a; func pathSum(root *TreeNode, targetSum int) (ans int) {preSum : map[int64]int{0: 1}var dfs func(*TreeNode, int64)dfs func(node *TreeNode, curr int64) {if node nil {return}curr int64(node.Val)ans preSum[curr-int64(targ…

复杂网络分析_NetworkX

一&#xff1a;NetworkX简介 NetworkX库是一个用于创建、操作复杂网络的结构、动态和功能的Python库。在经济网络中&#xff0c;它可以帮助分析各种经济实体&#xff08;如公司、个人、国家&#xff09;之间的相互关系和互动模式。以下是一些NetworkX在经济网络分析中的实际应…

ArrayList源码实现(一)

ArrayList源码实现&#xff08;一&#xff09; 1. ArrayList的大小是如何自动增加的&#xff1f; 初始化 在构造函数中&#xff0c;可以设定列表的初始值大小&#xff0c;如果没有的话默认使用&#xff0c;提供的静态数据 public ArrayList(int initialCapacity) {if (initi…

Milvus - 架构设计详解

Milvus 是一个专为在大规模密集向量数据集上进行相似性搜索而设计的开源向量数据库系统。其架构建立在流行的向量搜索库之上&#xff0c;如 Faiss、HNSW、DiskANN 和 SCANN&#xff0c;能够处理数百万、数十亿甚至数万亿的向量数据。为了全面了解 Milvus 架构&#xff0c;我们首…

计网作业3

1.交换机是依据 MAC地址 来转发数据包的 2.数据链路层 负责将数据封装成帧&#xff0c;在相邻节点间进行传输 数据链路层负责以下任务&#xff1a; 封装数据 物理地址寻址&#xff1a;使用MAC地址进行寻址&#xff0c;确保数据能够在局域网中正确传输到目标节点 介质访问控…

正确理解C++的友元friend

C的友元&#xff08;friend&#xff09;是个很重要的概念&#xff0c;该如何正确理解呢&#xff1f;本文将以友元函数为例讲解一下&#xff0c;仔细看。 友元的特性&#xff1a; 1、使用friend修饰的成员函数可以访问其他成员的私有成员(private)和保护成员(protected)。 2、…

快速上手基于Vue的动画引擎vueuse/motion

在现代前端开发中&#xff0c;动画可以极大地提升用户体验和界面美感。VueUse Motion 是一个强大的动画库&#xff0c;旨在为 Vue 应用提供简单易用的动画功能。那我们就来看看它在Vue项目中是如何应用的&#xff0c;快速手上为主&#xff0c;官网地址&#x1f447; vueuse/mo…

DevExpress WinForms中文教程:Data Grid - 如何添加或删除行?

本教程介绍DevExpress WinForm的Data Grid控件UI元素和API&#xff0c;它们使您和最终用户能够添加或删除数据行。您将首选学习如何启用内置的数据导航器&#xff0c;然后学习如何使用Microsoft Outlook启发的New Item行添加新记录。最后教程将向您展示基本的API&#xff0c;它…

全景可视化特点+可视化功能实现

全景可视化介绍 全景可视化是一种利用现代计算机技术、图像处理技术和虚拟现实技术&#xff0c;将现实世界中的场景以360度全景的方式呈现在用户面前的技术。它不仅能够提供水平方向360度的全景视野&#xff0c;还能通过垂直方向的视角变化&#xff0c;实现上下视角的调节&…

MVC core 、MVC framework addTagHelper、htmlhelper 、Environment

mvc core 标签助手 TagHelper 只有core 支持 htmlhelper mvc、mvc core 都支持 Environment <environment include"Development">*开发环境,使用不压缩的文件&#xff0c;排除压缩的文件*<link rel"stylesheet" asp-href-include"css/*"…

Linux相关概念和重要知识点(8)(操作系统、进程的概念)

1.操作系统&#xff08;OS&#xff09; &#xff08;1&#xff09;基本结构的认识 任何计算机系统都包含一个基本的程序集合&#xff0c;用于实现计算机最基本最底层的操作&#xff0c;这个软件称为操作系统。操作系统大部分使用C语言编写&#xff0c;少量使用汇编语言。 从…

[极客大挑战 2019]RCE ME1

<?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($code); } else{highlight_file(__FILE__); }// ?>…

【React】组件通信

1. 组件通信 组件间的数据传递 1.1 父传子 步骤&#xff1a; 父组件传递数据——在子组件标签上绑定属性子组件接收数据——子组件通过props参数接收数据 function Son(props) {return <div>{props.value}</div> }function App() {const value 父组件传给子…

实验二十:ds1302时钟实验

数码管硬件如以前实验所示‘ 完整代码如下 ds1302驱动 C文件 #include "ds1302.h" #include "intrins.h"u8 gWRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//秒,分,时,日,月,周,年 u8 gREAD_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,…