C++入门先填坑

news2024/11/28 8:23:02

C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。熟悉C语言之后,对C++学习也有一定的帮助。

C++入门先填坑系列主要内容会围绕以下方面

  •  补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等。
  • 为后续类和对象学习打基础

1. C++关键字

C++总计63个关键字,C语言32个关键字(加粗)。

这里我们只是看一下C++有多少关键字,并不对关键字进行具体的讲解。因为实在是太多,列举起来也不是非常轻松,我会在C++学习的整个过程中一步一步来学习遇见的关键字,并对其进行实例解读,希望大家多多关注我以后的博客内容。

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast

2. 命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

 定义的变量名与库形成命名冲突

 C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决。为了接下来更好地学习命名空间 namespace 的知识,我们需要先来引出域作用限定符 :: 。

域作用限定符的初认识

我们在学习C语言的作用域时遗留下了一个疑问,若两个相同变量名同时出现在全局范围和局部范围中,那么在代码执行时有“局部优先”原则,会默认处于局部范围的变量优先被访问,那有没有一种方法可以使得这种默认情况得以改变,将处于全局范围的变量被访问呢,而域作用限定符 :: 则为这种猜想提供了可能性。

 

 对::域作用限定符有了初步认识后,我们来进一步对 namespace 命名空间进行学习。

2.1 命名空间 namespace 定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字(一般开发中是用项目名字做命名空间名),然后接一对{ }即可,{ }中即为命名空间的成员(可以是变量/函数/类型
)。

1、正常的命名空间定义

namespace flash
{
	// 命名空间中可以定义变量/函数/类型
	int a = 0;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
}

2、命名空间可以嵌套

namespace N1
{
    int a;
    int b;
    int Add(int left, int right)
    {
        return left + right;
    }
    namespace N2
    {
        int c;
        int d;
        int Sub(int left, int right)
        {
            return left - right;
        }
    }
}

 在访问时需要按照层级关系进行逐层使用域作用限定符进行剥离访问。

int main()
{
	printf("%d\n", N1::a);
	printf("%d\n", N1::N2::a);
	printf("%d\n", N1::Add(1, 2));
	return 0;
}

3、同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中

  • 例如一个工程中的test.h和上面test.cpp中两个namespace N1会被合并成一个。

2.2 深入理解 using namespace ... 

一个命名空间就定义了一个新的作用域,目的是防止内部定义的变量名,函数名等与外界产生冲突。相当于为自己建了一堵墙,命名空间中的所有内容都局限于该命名空间中。而 using namespace ... 相当于将这堵墙破坏,将自己内部的元素完全暴露,很容易与其余代码产生命名冲突问题,因此,不要轻易使用 using namespace ... 将命名空间展开。

不要轻易使用 using namespace ... 将命名空间展开

2.3 命名空间使用

那么命名空间中成员该如何使用,下面我将给出几种方案,命名空间如下:

namespace flash
{
	int a = 0;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int x;
	};
}

加命名空间名称及作用域限定符

int main()
{
    printf("%d\n", flash::a);
    return 0;
}

使用using将命名空间中某个成员引入

using flash::b;

int main()
{
    printf("%d\n", flash::a);
    printf("%d\n", b);
    return 0;
}

使用using namespace 命名空间名称 引入

using namespce flash;
int main()
{
    printf("%d\n", flash::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;
}


3. C++输入&输出

回归到各位的编程生涯第一个C++程序:

#include<iostream>
using namespace std;

int main()
{
	cout << "hello world!\n" << endl;
	return 0;
}

可能大多数同学都可能搞不清楚这里为什么 iostream 后不跟 .h ,为什么要使用using namespace std,那咱们先来扩展一下吧。

在C++早期时 iostream 后是有 .h 的,因为当时C++还没有提出命名空间这个概念,再后来大牛对C++缝缝补补之后,提出了命名空间概念,将 C++的库和STL全部放在一个叫 std 的命名空间中(我们称为C++标准库),由于担心 iostream.h 与 C语言中的某些头文件重名歧义,在借助命名空间的帮助下,大胆取消了 .h 后缀。 形象比喻一下:

namespace std
{
    //C++库;
    //STL;
}

因此在想使用C++标准库中的东西时,我们得加上 using namespace std; 但前文提到过,这种方法具有一定的危险性;推荐使用指定访问。

C++输入和输出

  • cout:可暂时理解为VS的黑框框。
  • <<:流插入运算符。相较于C中的printf,流运算操作符具有自动识别类型的特点。
  • cin:相当于scanf。
  • >>:流提取运算符,同样可以自动识别类型。

4. 缺省参数

主要是解决了C语言中 #define 定义的常数使用起来不是非常灵活,而C++缺省参数的出现极大的提高了程序员在解决问题时的灵活程度。

4.1 缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

4.2 缺省参数分类

1、全缺省参数

2、半缺省参数 

4.3 缺省参数不能在函数声明和定义中同时出现

我们在项目中使用缺省参数作为函数参数时,在声明中给出缺省值,定义中不给出缺省值。原因是如果声明与定义位置同时出现缺省值,且恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。

5. 函数重载

C++允许在同一作用域中声明几个功能类似的同名函数

5.1 函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数类型类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

1、参数类型不同

int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}

double Add(double left, double right)
{
    cout << "double Add(double left, double right)" << endl;
    return left + right;
}

2、参数个数不同

void f()                                    //无参数
{
    cout << "f()" << endl;
}

void f(int a)                               //一个参数
{
    cout << "f(int a)" << endl;
}

3、参数类型顺序不同

void f(int a, char b)
{
    cout << "f(int a,char b)" << endl;
}

void f(char a, int b)
{
    cout << "f(char a, int b)" << endl;
}

扩展问题:函数无参数与函数缺省参数在函数重载的无参调用时会出现歧义。

6. 引用

6.1 引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

用法:类型& 引用变量名(对象名) = 引用实体。 (引用类型必须和引用实体是同种类型的) 

6.2 引用特性

1. 引用在定义时必须初始化

int main()
{
    int a = 6;
    //int&b;      error
    int&b = a;
    return 0;
}

2. 一个变量可以有多个引用

int main()
{
    int a = 6;
    int& b = a;
    int& c = b;
    int& d = c;
    return 0;
}

3. 引用一旦引用一个实体,再不能引用其他实体

int main()
{   
	int a = 6;
	int c = 8;
	int& b = a;
	int& b = c;

	return 0;
}

6.3 使用场景

1. 引用做输出型参数

void Swap(int& left, int& right)
{
    int temp = left;
    left = right;
    right = temp;
}

2、使用引用做参数可以提高效率,尤其是对大对象/深拷贝类对象时

struct A { int a[10000]; };

void TestFunc1(A a) {}

void TestFunc2(A& a) {}

int main()
{
	A a;
	// 以值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分别计算两个函数运行结束后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
	return 0;
}

3、使用引用做返回值可以减少拷贝提高效率,尤其是对大对象/深拷贝类对象时(前提是返回的是变量空间不销毁)

int& Count()
{
    static int n = 0;
    n++;
    return n;
}

若不使用引用做返回值,函数返回结果时会生成一个临时变量,将n的值拷贝放在临时变量中。而使用引用做返回值时会直接将结果传入main函数中进行下一步操作。

#include <time.h>

struct A { int a[10000]; };

A a;

A TestFunc1() { return a; }

A& TestFunc2() { return a; }

int main()
{
	// 以值作为函数的返回值类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	// 以引用作为函数的返回值类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	// 计算两个函数运算完成之后的时间
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
	return 0;
}

4、引用做返回值可以修改返回值,返回值具有读和写的双重功能

使用C语言时对顺序表数据的查询修改的操作 

struct SeqList
{
	int a[100];
	size_t size;
};

//C实现对顺序表的修改和查询
void SLModify(struct SeqList* ps, int pos, int x)
{
	assert(pos < 100 && pos>0);
	ps->a[pos] = x;
}

int SLGet(struct SeqList* ps, int pos)
{
	assert(pos < 100 && pos>0);
	return ps->a[pos];
}

int main()
{
	struct SeqList s;
	SLModify(&s, 5, 8);
	printf("%d\n", SLGet(&s, 5));
	//对第6个位置+6
	int ret = SLGet(&s, 5);
	SLModify(&s, 5, ret+6);
	return 0;
}

使用C++引用带来的便利,使函数具有更多的功能,大大减少了代码量

struct SeqList
{
	int a[100];
	size_t size;
};

//具有读和写的双重作用
int& SLAt(SeqList& s, int pos)
{
	assert(pos < 100 && pos>0);
	return s.a[pos];
}

int main()
{
	SeqList s;
	SLAt(s, 5) = 8;
	cout << SLAt(s, 5) << endl;
	//对第6个位置+6
	SLAt(s, 5) += 6;
	return 0;
}

上例代码只做解释,下面是最正宗的C++写法

struct SeqList
{
	int a[100];
	size_t size;

	int& operator[](int pos)
	{
		assert(pos < 100 && pos>0);
		return a[pos];
	}
};


int main()
{
	SeqList s;
	s[5] = 8;
	//对第6个位置+6
	s[5] += 6;
	cout << s[5] << endl;
	return 0;
}

6.4 常引用

我们在对变量以及引用使用 const 修饰时,提出了“权限”的概念。

我们知道对变量取别名,也就是引用时,相当于既可以通过这个新取得别名对原始变量进行读取,也可以对其进行修改。那么const的加入让一些操作变得复杂:

权限被放大

权限缩小

权限平移

多学一点

6.5 引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。而指针则是另外开辟空间来存放这个指针。

 在底层汇编实现上实际是有空间的,因为引用是按照指针方式来实现的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求。
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
  4. 没有NULL引用,但有NULL指针。
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用。
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理。
  9. 引用比指针使用起来相对更安全。

7. 关键字auto(C++11)

7.1 类型别名

随着后期学习的程序越来越复杂,其中用到的类型也越来越复杂,经常体现在:

  1. 类型难于拼写
  2. 含义不明确导致容易出错

C语言的解决方法:通过typedef给类型取别名

#include <string>
#include <map>
typedef std::map<std::string, std::string> Map;
int main()
{
    //std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange", "橙子" }, 
    //{"pear","梨"} };
    Map m{ { "apple", "苹果" },{ "orange", "橙子" }, {"pear","梨"} };
    //std::map<std::string, std::string>::iterator it = m.begin();
    Map::iterator it = m.begin();
    while (it != m.end())
    {
        //....
    }
    return 0;
}

在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的类型。然而有时候要做到这点并非那么容易,因此C++11给auto赋予了新的含义。

7.2 auto初认识

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量。C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型
指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

8.3 深入认识auto

auto与指针和引用结合起来使用

int main()
{
    int x = 10;

    auto a = &x;      //用auto声明指针类型时,用auto和auto*没有任何区别
    auto* b = &x;     //用auto声明指针类型时,用auto和auto*没有任何区别

    auto& c = x;      //用auto声明引用类型时则必须加&
    return 0;
}

在同一行定义多个变量

int mian()
{
    auto a = 1, b = 2;
    //auto c = 3, d = 4.0;    error:c和d的初始化表达式类型不同
    return 0;
}

7.3 auto不能推导的几个场景

auto不能作为函数的参数

void TestAuto(auto a)  //error
{
    //... ...
}

auto不能直接用来声明数组

int main()
{
    int a[] = {1,2,3};
    // auto b[] = {4,5,6};        error
    return 0; 
}

auto在实际中最常见的优势用法就是C++11提供的新式for循环,还有lambda表达式等进行配合使用。

8、范围for循环的语法糖(C++11)

8.1 C语言范围for的语法

int main()
{
    int array[] = { 1, 2, 3, 4, 5 };
    for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
        array[i] *= 2;
    for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
        cout << *p << endl;
    return 0;
}

对于一个有范围的集合而言C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

int main()
{
    int array[] = { 1, 2, 3, 4, 5 };
    for(auto& e : array)
        e *= 2;
    for(auto e : array)
        cout << e << " ";
    return 0;
}

与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
 

8.2 范围for的使用条件

1、for循环迭代的范围必须是确定的,对于数组而言,就是数组中第一个元素和最后一个元素的范;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。

//error
void TestFor(int array[])   
{
    for(auto& e : array)       //error
    cout<< e <<endl;            
}

2、迭代的对象要实现++和==的操作。(只提一下,后期会在博客中详细介绍)

9. 指针空值nullptr(C++11)

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:

void TestPtr()
{
    int* p1 = NULL;
    int* p2 = 0;
    // ……
}

而在传统的C头文件(stddef.h)中,NULL实际是一个宏:

//代码如下
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

因此NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:

在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

因此我们今后在使用空指针时应该注意我们当前C++语法的一些规定:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

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

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

相关文章

servlet Filter与spring的OncePerRequestFilter

servlet 规范 javax.servlet Filter 任何的servlet容器都要实现的&#xff0c;例如tomcat、undertow、jetty等等。类似于jdbc规范&#xff0c;制定好了一个约束&#xff0c;各家数据库厂商根据规范开发对应的驱动来实现访问自己的数据库。 spring 对于Filter的自定义实现 所…

NLP(六十)Baichuan-13B-Chat模型使用体验

2023年7月11日&#xff0c;百川智能正式发布参数量130亿的通用大语言模型Baichuan-13B-Base、对话模型Baichuan-13B-Chat及其INT4/INT8两个量化版本。   本文将介绍大模型BaiChuan-13B-Chat的使用体验&#xff0c;其HuggingFace网址为&#xff1a;https://huggingface.co/bai…

【C语言day02】

转义字符 \\ 表示字符\&#xff0c;\123表示字符{&#xff0c;\t表示制表符&#xff0c;这些都是一个字符宏只是替换 替换后NUM的样子是(211)*21/2常量指针与指针常量 const和* 来区别&#xff0c;如果是const * 这样的顺序就是常量指针&#xff0c;所以说他的本质是指针&am…

uni-app:请求后端数据uni.request

完整代码&#xff1a; onLoad() {uni.request({url: getApp().globalData.position Produce/select_employee,data: {username: getApp().globalData.username,},method: POST,dataType: json,success: res > {this.employee_name res.data.info.employee_name;// consol…

uniapp 之 微信小程序、支付宝小程序 对于自定义导航栏的不同

目录 前言 微信小程序 代码 支付宝小程序 首页配置文件 二级菜单页面 配置 总结 不同 相同 前言 小程序都是 uni-app 写的 不是原生 微信小程序 代码 pages.json文件中配置 重点&#xff1a; "navigationStyle": "custom", // 导航栏样式…

安卓开发日记问题记录(隐藏标题栏中的应用名称)

当我们设置了显示标题栏&#xff0c;应用名也会显示出来&#xff0c;这对设置标题栏内容很不方便 可以在activity里的onCreate部分设置这句代码隐藏APP名字 getSupportActionBar().setDisplayShowTitleEnabled(false);或者改变它 getSupportActionBar().setTitle("new …

疲劳驾驶检测和识别1: 疲劳驾驶检测和识别数据集(含下载链接)

疲劳驾驶检测和识别1&#xff1a; 疲劳驾驶检测和识别数据集(含下载链接) 目录 疲劳驾驶检测和识别1&#xff1a; 疲劳驾驶检测和识别数据集(含下载链接) 1. 前言 2. 疲劳驾驶类别说明 3. 疲劳驾驶检测数据集&#xff1a; &#xff08;1&#xff09;Drowsy-Driving-Det1 …

hadoop安全保护机制(kerberos + ldap)

信息安全理论&#xff1a; CIA模型&#xff1a;机密性、完整性和可用性 CIA模型能够帮助建议一些信息安全原则&#xff0c;但该模型并不是一个需要严格遵守的规则 hadoop平台可能设计多个CIA模型组件&#xff0c;也kennel一个也不涉及 机密性&#xff1a; 信息只应该被期望的…

高压放大器的增益和偏压是什么意思

高压放大器是一种广泛应用的电子元器件&#xff0c;主要用于放大高压信号和驱动负载等方面。在实际应用中&#xff0c;了解高压放大器的增益和偏压是非常重要的&#xff0c;下面安泰电子将详细介绍它们的意义和作用。 高压放大器的增益 增益是指放大器输入信号与输出信号之间的…

iClient3D for CesiumWebGL入门之使用vscode以服务方式运行调试

作者&#xff1a;超图研究院技术支持中心-于丁 iClient3D for Cesium&WebGL入门之使用vscode以服务方式运行调试 相信大家第一次使用SuperMap iClient3D for Cesium或SuperMap iClient3D for WebGL的时候&#xff0c;都遇到过和我一样的事情&#xff1a; 在文件夹中直接打…

二极管钳位电路的原理与实际应用

写在前面 本文参考了什么是二极管钳位的作用及原理&#xff1f; - 知乎 针对一些文章讲述错误的地方进行了更正&#xff0c;在讲述不清楚的地方进行了详细的解释&#xff0c;还请各位两篇文章结合而看&#xff0c;效果更佳。 钳位电路说明 1.我们都知道二极管具有单向导电性&a…

【Ajax】笔记-Ajax重复发送请求

问题的产生 用户频繁地点击一个发送请求的按钮&#xff0c;服务器就会频繁地处理请求&#xff0c;而且处理的内容是一样的&#xff0c;这样会导致服务器的压力很大。 这种情况下服务器就没有必要处理每一个请求。 解决方案 发送请求的时候先查看有没有正在请求的相同请求&am…

docker - prometheus+grafana监控与集成到spring boot 服务

一、Prometheus 介绍 1.数据收集器&#xff0c;它以配置的时间间隔定期通过HTTP提取指标数据。 2.一个时间序列数据库&#xff0c;用于存储所有指标数据。 3.一个简单的用户界面&#xff0c;您可以在其中可视化&#xff0c;查询和监视所有指标。二、Grafana 介绍 Grafana 是一…

Android图形系统之ANativeWindow与Surface关系(十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Unity 之 错误的停止协程的方式

相信很多人都会这样开启一个协程 StartCoroutine(Cor_1()); 这样确实没啥毛病&#xff0c;那么怎么关掉这个协程呢&#xff0c;是不是在想也是一样的传cor_1()这个参数&#xff0c;然后start对应stop,试着输入stopCor....诶&#xff0c;代码提示有这个方法喔&#xff0c;然后…

【计算机网络】socket编程基础

文章目录 1. 源IP地址和目的IP地址2. 理解MAC地址和目的MAC地址3. 理解源端口号和目的端口号4. PORT与PID5. 认识TCP协议和UDP协议6. 网络字节序7. socket编程接口7.1 socket常见API7.2 sockaddr结构 1. 源IP地址和目的IP地址 因特网上的每台计算机都有一个唯一的IP地址&#…

windows命令之获取电脑已经连接过的wifi的密码

有时候想连接wifi不知道密码&#xff0c;恰巧电脑此时正连接着能用的wifi&#xff0c;想获取密码吗&#xff0c;使用下面这个指令&#xff1a;这个指令能获取历史连接的wifi的信息&#xff0c;密码也是之前连接的时候保存的密码&#xff0c;并不能获取某个wifi的正确密码 netsh…

Redis进阶(2)——Redis数据的持久化 CAP分布式理论(高可用性) Redis主从搭建 Redis的哨兵机制

目录 引出Redis数据的持久化RDB方式(redis database数据备份文件)RDB工作机制RDB优势和劣势RDB常用参数 AOF的方式&#xff08;命令追加&#xff09;AOF优缺点 Redis集群CAP理论 主从搭建(Master/Slave)主master的redis自定义docker静态网段创建文件上传redis.conf到conf文件夹…

物联网的介绍

目录 1.什么是物联网 2.物联网给人类带来的福利 3.学习物联网需要什么知识 4.物联网未来的发展趋势 5.物联网专业的就业前景 1.什么是物联网 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指连接、交互和共享数据的各种物理设备、传感器、软件和…

你的语言是第几名?

2023年已经过半&#xff0c;最新一期的编程语言排行榜你看了吗&#xff1f;刚刚&#xff0c;全球知名编程语言社区TIOBE公布了7月榜单&#xff0c;一起来看吧&#xff01; TIOBE 7 月 TOP 15 编程语言&#xff1a; 详细榜单可参考官网&#xff1a; https://www.tiobe.com/tio…