【C++初阶】C++简单入门(长期维护)

本篇博客是对C++的一些简单知识分享,有需要借鉴即可。

C++简单入门目录

  • 一、C++前言
    • 1.C++的概念:
    • 2.C++发展历程
    • 3.C++如何学?
  • 二、C++入门
    • 1.C++关键字(C++98标准)
    • 2.命名空间
    • 3.C++输入&输出
      • ①概念说明
      • ②使用说明
      • ③特征说明
      • ④细节拓展
      • ⑤cout与cin的意义
    • 4.缺省参数
      • ①概念说明
      • ②使用规则
      • ③应用举例
      • ④缺省参数的意义
    • 5.函数重载
      • ①概念
    • 6.引用
      • ①概念
      • ②特性
      • ③应用场景
        • 1.做参数
          • - 1.引用做输出型参数,更加方便
          • - 2.引用在对象比较大情况下,用引用代替值拷贝更加高效
        • 2.做返回值
          • - 1错误的引用做返回值用法
          • - 2.正确的引用返回---修改返回对象
          • - 3.正确的引用返回---减少拷贝提高效率
      • ④引用和指针的区别
      • ⑤引用的意义
    • 7.内联函数
      • 内联函数概念
      • 内联函数特性
      • 内联函数意义
      • 内联函数的认识
    • 8.auto关键字
      • auto概念
      • auto特性
      • auto意义
      • suto的认识
    • 9.for的范围用法
    • 10.NULL与nullptr
      • C++中NULL的问题

一、C++前言

1.C++的概念:

一种高级编程语言,由C发展而来,满足过程化程序设计、基于对象的程序设计、面向对象的程序设计。

2.C++发展历程

在这里插入图片描述
C++最新发展:LINK

3.C++如何学?

  • 写博客总结
  • 定期画思维导图总结
  • 常复习(博客笔记、知乎答案、看书)
  • 刷题

二、C++入门

1.C++关键字(C++98标准)

在这里插入图片描述

2.命名空间

C++命名空间概念:一种命名域、是C++专门用来解决C语言变量命名冲突问题而产生的。
命名空间的意义很大程度上解决C变量命名冲突问题。

知识拓展:C中的命名冲突
命名冲突主要有两大类:

  • 程序员 与 库
    在这里插入图片描述

  • 程序员 与 程序员

知识拓展1:域,C++上指的是作用域LINK
在C++中,大体有四种域:

  • 全局域:生命周期 访问
  • 局部域:生命周期 访问
  • 命名空间域:访问
  • 类域


知识拓展2:编译器对名称的搜索原则:

  • 在不指定域的情况下
  1. 当前域
  2. 全局域
  • 在指定域的情况下
  1. 直接去指定域搜索

命名空间的定义: namespace关键字+命名空间的名字+{…}

  1. 命名空间中可以定义变量/函数/类型
  2. 命名空间可以嵌套
  3. 同一命名空间会被合并
namespace bit
{
 // 命名空间中可以定义变量/函数/类型
 int rand = 10;
 int Add(int left, int right)
 {
 return left + right;
 }
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

命名空间的使用:

  • 法1:指定访问

需要用到访问操作符 ::

  1. 访问变量/函数 命名空间名称 + :: + 变量名/函数名
  2. 访问结构体 struct + 空间名 + :: + 结构体名
  • 法2:直接访问(展开访问)

需要用到指令:using namespace + 空间名 —>等价于把空间内的命名放到全局变量

  • 法3:展开特定项

eg:using std::cout;

在这里插入图片描述

总结:对比指定访问与展开访问,分析其利弊
答:

  • 指定访问 解决变量冲突问题 麻烦
  • 展开访问 直接把变量放到全局中 方便
  • 部分展开 把常用的变量放到全局中 方便
    其中,做项目一般使用第1与第3方式,第2种方法一般在练习中使用。

头文件展开与命名空间展开的区别:
头文件的展开本质是在预处理阶段拷贝头文件内容。
命名空间的展开本质是影响编译器的搜索规则。

3.C++输入&输出

①概念说明

cpp的输入输出分别是cout与cin,这两个函数均包含在iostream头文件中,在使用时需要展开命名空间进行使用。
在这里插入图片描述

②使用说明

#include<iostream>
using namespace std;

int main()
{
	// <<,1.左移
	int a = 10;
	a = a << 1;
	printf("a<<1:%d\n", a);
	// <<,2.流插入
	cout << "hello cpp" << endl;

	// >>,1.右移
	a = a >> 1;
	printf("a>>1:%d\n", a);
	// >>.2.流提取
	cin >> a;
	
	return 0;
}

③特征说明

下面是cout的特征说明示例:cin也是同理

④细节拓展

在这里插入图片描述

⑤cout与cin的意义

弥补了C语言自定义类型输入输出麻烦的问题

4.缺省参数

①概念说明

缺省参数是c++提供的一种在函数缺少传入值的情况下使用默认值的一种参数。

缺省参数分为两类

  • 全缺省参数
    在这里插入图片描述

  • 半缺省参数
    在这里插入图片描述

②使用规则

  • 有实参优先使用,没有实参使用默认参数
    在这里插入图片描述
  • 缺省参数函数传实参时候从左到右依次给值,缺省参数函数形参从右向左依次给默认值
  • 缺省参数不能在声明与定义中同时出现,要优先给函数声明使用缺省
    在这里插入图片描述
  • 缺省值必须是常量值或者全局变量

思考:为什么缺省参数要优先在函数声明中使用?而不是优先给函数定义使用?
答:
我们首先要明白编译器的编译原理,编译器首先要进行预处理,在这一步中展开头文件,之后编译器要进行编译,在这一步中编译器主要是检查语法,通常情况下,这种时候每个源文件都是独立的,每个调用函数的源文件中也自然大概率没有函数的定义,但是已经有了函数声明(因为经过了预处理),所以为了要让编译器不报错,肯定是先让函数声明有缺省参数。


那为什么不直接函数定义也有缺省参数,函数声明也有缺省参数呢?
因为语法是规定只能有一个的。
在这里插入图片描述

③应用举例

在c语言阶段,我们设计一个栈时候往往初始化不知道要给几个空间,这样我们可以给一个缺省参数来默认给值,然后不够了的话扩容。
在这里插入图片描述

④缺省参数的意义

对函数定义更加灵活化。

5.函数重载

①概念

函数名相同,函数参数不同,称为函数重载

函数参数不同在哪里?

  • 参数的类型不同
    在这里插入图片描述
  • 参数的个数不同
    在这里插入图片描述
  • 参数的顺序不同

思考:编译器是如何支持函数重载的?C语言就不行。
答:名称修饰
在这里插入图片描述

6.引用

①概念

引用:底层汇编层面是用指针实现的,但是在语法层面上是为变量起别名,与指针起到互补作用。
在这里插入图片描述

②特性

  1. 引用在定义时必须初始化
    在这里插入图片描述

  2. 引用不能更改指向
    在这里插入图片描述
    在这里插入图片描述

  3. 一个变量可以有多个引用
    在这里插入图片描述

思考:引用可以完全替代指针吗?
答:不能,引用往往是在用指针比较复杂的地方代替指针。
为什么引用不能完全替代指针?
虽然引用可以在大多数情况下替代指针的使用从而简化指针,但是某些情况下是不能用引用解决的。
比如下面这个例子:
现在有一个单链表,要求删除中间的一个结点。
在这里插入图片描述
这里的关键点就在于引用不能改变指向,现在你把中间结点删除了,但是前面结点的指向怎么办?

//例子,链表
typedef int SLTDataType;
typedef struct SListNode
{
	SLTDataType val;
	struct SListNode* next;
}SLNode, * PSLNode;


//指针的方法
void SLPush(SLNode** pphead, SLTDataType x)
{
	assert(pphead);

	SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
	newnode->next = NULL;
	newnode->val = x;
	
	if (*pphead == NULL)
	{
		*pphead = newnode;
		return;
	}
	else
	{
		SLNode* pcur = *pphead;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newnode;
	}
}

//引用的方法
void SLPush(SLNode*& pphead , SLTDataType x)
{
	assert(pphead);

	SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
	newnode->next = NULL;
	newnode->val = x;
	
	if (pphead == NULL)
	{
		pphead = newnode;
		return;
	}
	else
	{
		SLNode* pcur = pphead;
		while (pcur->next)
		{
			pcur = pcur->next;
		}
		pcur->next = newnode;
	}
}

void SLPrint(SLNode*& phead)
{
	while (phead)
	{
		cout << phead->val << "  ";
		phead = phead->next;
	}
}

void test_3()
{
	SLNode* phead = NULL;
	SLPush(&phead, 1);
	SLPush(phead, 2);
	SLPush(&phead, 3);
	SLPush(phead, 4);
	SLPrint(phead);
}

③应用场景

1.做参数
void C_Swap(int* a,int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

void CPP_Swap(int& a2, int& b2)//在这里可以起与实参一样的名字吗?可以。因为属于不同的域。
{
	int temp = a;
	a = b;
	b = temp;
}

void test_1()
{
	int a1 = 10;
	int b1 = 20;
	printf("a1 = %d , b1 = %d\n", a1, b1);
	C_Swap(&a1,&b1);
	printf("a1 = %d , b1 = %d\n", a1, b1);

	int a2 = 10;
	int b2 = 20;
	cout << "a2 = " << a2 << " b2 = " << b2 << endl;
	CPP_Swap(a2, b2);
	cout << "a2 = " << a2 << " b2 = " << b2 << endl;
}

思考:在这里可以起与实参一样的名字吗?
答:可以,因为属于不同的域。

在做函数参数这一用法上,用引用可以有两大好处

- 1.引用做输出型参数,更加方便

在这里插入图片描述
输出型参数:能够通过改变形参影响实参。

- 2.引用在对象比较大情况下,用引用代替值拷贝更加高效
void testfunc1(A a)
{
	;
}

void testfunc2(A& a)
{
	;
}

void test_4()
{	
	A a;
	//以值作为函数参数
	size_t begin1 = clock();
	for (int i = 0; i < 10000; i++)
	{
		testfunc1(a);
	}
	size_t end1 = clock();
	
	//以引用作为函数参数
	size_t begin2 = clock();
	for (int i = 0; i < 10000; i++)
	{
		testfunc2(a);
	}
	size_t end2 = clock();

	printf("%zd ", end1 - begin1);
	printf("%zd ", end2 - begin2);
}

在这里插入图片描述

传值、传引用效率比较
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

2.做返回值
- 1错误的引用做返回值用法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


如何规避函数的野引用?
答:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。
那该如何正确使用引用来返回函数值呢?
一般是返回静态变量,全局变量,堆上的空间…等等。

- 2.正确的引用返回—修改返回对象

对比C中的get函数与c++中的get函数
读下面代码。
get如果返回int,那么就是一种值拷贝,如果是int&,那么就是别名。不但可以读还可以写。


struct SLTNode {
	int* a;
	int size;
	int capacity;
};

void SLTInit(struct SLTNode& sl)
{
	sl.a = NULL;
	sl.capacity = sl.size = 0;
}

void SLTPush(struct SLTNode& sl,int x)
{
	//...扩容
	if (sl.size == sl.capacity)
	{
		int* psl = (int*)realloc(sl.a, 10*sizeof(int));
		sl.a = psl;
		sl.capacity+=10;
	}
	
	//检查
	sl.a[sl.size++] = x;
}

void SLTPrint(struct SLTNode& sl)
{
	int i = 0;
	for (int i = 0; i < sl.size; i++)
	{
		cout << sl.a[i];
	}
}

void SLTModify(struct SLTNode& sl,int pos,int x)
{
	sl.a[pos] = x;
}

void test_C()
{
	//例子:顺序表
	struct SLTNode sl;
	SLTInit(sl);
	SLTPush(sl, 1);
	SLTPush(sl, 2);
	SLTPush(sl, 3);
	SLTPush(sl, 4);
	SLTPrint(sl);
}

void test_CPP()
{
	struct SeqList
	{
		// 成员变量
		int* a;
		int size;
		int capacity;

		// 成员函数
		void Init()
		{
			a = (int*)malloc(sizeof(int) * 4);
			// ...
			size = 0;
			capacity = 4;
		}

		void PushBack(int x)
		{
			// ... 扩容
			a[size++] = x;
		}

		// 读写返回变量
		int& Get(int pos)//这个地方如果返回int,那么就是一种值拷贝,如果是int&,那么就是别名。不但可以读还可以写。
		{
			assert(pos >= 0);
			assert(pos < size);

			return a[pos];
		}

		int& operator[](int pos)
		{
			assert(pos >= 0);
			assert(pos < size);

			return a[pos];
		}
	};
	struct SeqList a;
	a.Init();
	a.PushBack(1);
	a.PushBack(2);
	a.PushBack(3);
	a.PushBack(4);
	for (int i = 0; i < 4; i++)
	{
		cout << a.Get(i) << "  ";
	}

}

void test_5()
{
	//test_C();
	test_CPP();
}
- 3.正确的引用返回—减少拷贝提高效率

与引用做参数是一样的,这里不做细细说明。

#include <time.h>
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A& TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
 // 以值作为函数的返回值类型
 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;
}

④引用和指针的区别

  • 从语法层面来看
    • 引用是别名,不需要额外开空间,指针需要额外开空间使用
    • 引用必须初始化,指针可以选择不初始化
    • 引用不能改变防线,指针可以任意改变方向
    • 引用相对安全,不容易写出问题;指针容易写出野指针
    • sizeof,++,解引用等方面的区别
  • 从底层层面来看
    • 从汇编层面上,没有引用,引用都会被转换为指针。
      在这里插入图片描述

⑤引用的意义

引用不是用来替代指针的,而是弥补指针在有些地方的不适用,比如二级指针、三级指针过于复杂,比如指针作参数,作返回值修改不够方便等等问题。

7.内联函数

内联函数概念

概念:
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

下面为内联函数和一般函数的比较:一般函数建立了栈帧,内联函数没有建立栈帧。

int add1(int a,int b)
{
	return a + b;
}

inline int add2(int a,int b)
{
	return a + b;
}

void test_5()
{
	//假设add函数需要大量重复调用
	int a = 10;
	int b = 20;
	//一般函数add1
	int c = add1(a, b);

	//内联函数add2对照
	c = add2(a, b);
}

在这里插入图片描述

注:如果想要看到上面对比图需要对编译器优化进行配置
在这里插入图片描述


内联函数特性

  • inline是在编译阶段直接函数调用替换为函数体,也就是一种以空间换时间的方法
    • 好处:少了调用开销
    • 缺点:会使目标文件变大
  • inline对于编译器只是一个建议,实现机制取决于编译器。
    • 如果是递归函数、较大的函数编译器会忽略inline
  • inline不建议声明与定义相分离,因为可能会导致链接错误
    • 这是因为inline没有产生函数地址在变量列表中。
// F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{
 cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{
 f(10);
 return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl 
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

内联函数意义

解决某一功能需要大量重复调用,造成栈频繁开辟销毁降低性能的问题。

在这里插入图片描述

一般来说,C语言解决这一问题是搞一个宏函数,虽然解决了问题,但是还有一些其他问题,比如语法复杂,不能调试,没有类型安全检查等等。C++为了解决这个问题,创建了新的语法,内联函数。

如果一个函数定义在了.h文件中该如何解决这个问题?
在这里插入图片描述
注:inline内敛,内联函数不会把其地址加载到符号表中,自然也不会引起链接错误。


内联函数的认识

那我们该如何看待或者使用内联函数的呢?
建议:

  在我看来内联函数就是为了解决体积小且大量重复的函数调用而诞生的,如果今后碰到一些大量重复调用且体积小的函数,可以考虑加上inline

  但是切忌不可每个函数都加上inline

  • 如果函数过大或者函数是递归函数的话 ---->编译器会忽略inline关键字
  • 如果体积过大会大大增加代码,从而造成“代码膨胀”的问题。

8.auto关键字

auto概念

是C++关键字之一,用来自动为变量匹配类型,而auto类型本质是一种新类型。

int TestAuto()
{
return 10;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}

注:auto是一种类型声明时的“占位符”,编译器在编译期间会将auto替换为实际类型。

auto特性

  • auto使用必须初始化
  • auto与指针和引用结合起来使用
    用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则须加&
  • 在同一行定义多个变量
    当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  • auto不能直接用来声明数组
  • auto过度使用会使可读性变差

auto意义

类型越来越复杂,难拼写,易出错 —> typedef —> auto
C语言中typedef的问题:
在这里插入图片描述


suto的认识

auto可以在面对较复杂的类型时候用一次,切忌不可连用,因为这会大大降低代码的可读性。

9.for的范围用法

在C++98中如果要遍历一个数组,可以按照以下方式进行:

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

注意

  • or循环迭代的范围必须是确定的
    对于数组而言,就是数组中第一个元素和最后一个元素的范围
  • 迭代的对象要实现++和==的操作

10.NULL与nullptr

C++中NULL的问题

NULL的字面值是0,默认是int类型的,这会有bug存在。
在这里插入图片描述

void f(int)
{
 cout<<"f(int)"<<endl;
}
void f(int*)
{
 cout<<"f(int*)"<<endl;
}
int main()
{
 f(0);
 f(NULL);
 f((int*)NULL);
 return 0;
}

注:nullptr不需要包头文件,因为他是关键字,且在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。


EOF

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

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

相关文章

freertos作业day1

1.总结keil5下载代码和编译代码需要注意的事项 1.&#xff09;仿真器设置&#xff1a; 点击魔术棒&#xff0c;选择debug选项&#xff0c;找到使用的仿真器&#xff0c;选择ST-LINK仿真器&#xff0c;点击setting&#xff0c;选择flash download ,勾选reset and run,选择pack…

竞技游戏新纪元:如何打造满足现代玩家需求的极致体验?

文章目录 一、现代玩家需求分析二、以玩家体验为核心的游戏设计三、个性化与定制化服务四、强化社交互动与社区建设五、持续更新与优化《游戏力&#xff1a;竞技游戏设计实战教程》亮点编辑推荐内容简介目录获取方式 随着科技的飞速发展和游戏产业的不断壮大&#xff0c;现代玩…

负荷预测 | Matlab基于TCN-GRU-Attention单变量时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单变量时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行环境matlab2023及以…

DNF手游攻略:萌新入坑大全!

玩DNF手游国服已经正式定档&#xff0c;离上线已经越来越近了&#xff0c;很多小伙伴对于装备打造以及附魔还不是特别了解。如果你还不知道装备要怎么附魔&#xff0c;不要担心&#xff0c;本篇攻略将为你全面解析全职业过渡和毕业附魔推荐。 ​ 一、物理职业附魔推荐 1. 武器…

渗透测试信息收集

一、渗透信息收集流程 渗透测试过程前期&#xff0c;需要大量的完善的网站业务信息收集工作&#xff0c;大致信息收集流程为 1、网站域名信息探测 2、网站子域信息探测 3、网站敏感信息收集 4、网站安全工具核实 5、网站旁站利用情况 6、网站业务资产梳理 二、网站域名信息探…

【行为型模式】策略模式

一、策略模式概述 策略模式(又叫政策Policy模式)&#xff0c;属于对象行为模式下的&#xff1a;Strategy类提供了可插入式(Pluggable)算法的实现方案。 策略模式的定义-意图&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并让它们互相替换。策略模式…

.NET MVC API Swagger 自动生成API文档入坑

开发环境 Win10 VS2022 .NET8.0 1.从NuGet添加Swagger 在解决方案资源管理器中右键单击项目>管理 NuGet 包 将包源设置为“nuget.org” 确保启用“包括预发行”选项 在搜索框中输入“Swashbuckle.AspNetCore” 从“浏览”选项卡中选择最新的“Swashbuckle.AspNetCore”包&a…

OCCT几何内核开发-TopoDS_Shape

如果要基于OCCT几何内核搞建模算法&#xff0c;特别是想开发自己的算法&#xff0c;需要深刻理解拓扑与几何的关系、相关的数据结构&#xff0c;TopoDS_Shape、TopoDS_TShape、BRep_TFace、Tolerances等。 一个简单Box的数据结构 两个面缝合&#xff08;Sewing&#xff09;后的…

优惠券布局的最终方案------css属性mask

先贴图&#xff1a; 以上这些都是通过mask去实现出来&#xff1a; <!DOCTYPE html><html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

【多模态检索】Coarse-to-Fine Visual Representation

快手文本视频多模态检索论文 论文&#xff1a;Towards Efficient and Effective Text-to-Video Retrieval with Coarse-to-Fine Visual Representation Learning 链接&#xff1a;https://arxiv.org/abs/2401.00701 摘要 近些年&#xff0c;基于CLIP的text-to-video检索方法…

FreeRTOS_day1

1.总结keil5下载代码和编译代码需要注意的事项 下载代码前要对仿真进行设置 勾选后代码会立刻执行 勾选后会导致代码不能执行 写代码的时候要写在对应的begin和end之间&#xff0c;否则会被覆盖 2.总结STM32Cubemx的使用方法和需要注意的事项 ①打开软件&#xff0c;新建工程…

初学python记录:力扣924. 尽量减少恶意软件的传播

题目&#xff1a; 给出了一个由 n 个节点组成的网络&#xff0c;用 n n 个邻接矩阵图 graph 表示。在节点网络中&#xff0c;当 graph[i][j] 1 时&#xff0c;表示节点 i 能够直接连接到另一个节点 j。 一些节点 initial 最初被恶意软件感染。只要两个节点直接连接&#x…

BK9535可替代BK9531 BEKEN博通 无线高品质语音发射传输芯片 提供开发资料

概 述 BK9531已经停产&#xff0c;厂家推出升级替代芯片BK9535 BK9535芯片是用于无线高品质语音发射传输的芯片&#xff0c;芯片覆盖频段范围为&#xff1a;V段&#xff08;160~270MHz&#xff09;、U段&#xff08;450~980MHz&#xff09;、1G频段&#xff08;980~1176MHz&a…

一款可自动跳广告的安卓App开源项目

开放权限有风险&#xff0c;使用App需谨慎&#xff01; gkd 基于 无障碍 高级选择器 订阅规则 的自定义屏幕点击 APP 功能 基于 高级选择器 订阅规则 快照审查, 它可以实现 点击跳过任意开屏广告/点击关闭应用内部任意弹窗广告, 如关闭百度贴吧帖子广告卡片/知乎回答底…

HarmonyOS开发案例:【智能煤气检测】

样例简介 智能煤气检测系统通过实时监测环境中烟雾浓度&#xff0c;当一氧化碳浓度超标时&#xff0c;及时向用户发出警报。在连接网络后&#xff0c;配合数字管家应用&#xff0c;用户可以远程配置智能煤气检测系统的报警阈值&#xff0c;远程接收智能煤气检测系统报警信息。…

华为再次布局新行业:合作伙伴已超前谋划,该领域将大有可为

华为布局新行业 华为向外界公布了一个重要信息&#xff1a;在过去的三年里&#xff0c;尽管受到美国的制裁&#xff0c;华为仍然成功地完成了超过13000个元器件的国产替代研发&#xff0c;以及4000多块电路板的迭代开发。 不仅在硬件领域取得了显著成就&#xff0c;在软件和生…

AutoMQ 登顶 Hacker News: 开源项目流量的第一桶金以及经验分享

01 事件回顾 2024 年 4 月 8 日中午&#xff0c;随着 AutoMQ 的一则简短的标题内容&#xff1a;Show HN: AutoMQ - A Cost-Effective Kafka Distro That Can Autoscale in Seconds[1] 成功登顶 Hacker News &#xff08;HN&#xff09; &#xff0c;我们迎来了大量优质、精准的…

为什么一开始不被看好的单片机,现在概括了所有数据产品行业?

这主要归因于技术和认知的局限。 在其发展初期&#xff0c;单片机的性能、存储容量以及开发工具都颇为有限&#xff0c;难以契合复杂应用的种种需求。彼时&#xff0c;许多人确实难以洞察到它的未来走向。 然而&#xff0c;时过境迁&#xff0c;人们逐步领悟到了单片机在各个…

密码学 | 椭圆曲线数字签名方法 ECDSA(下)

目录 10 ECDSA 算法 11 创建签名 12 验证签名 13 ECDSA 的安全性 14 随机 k 值的重要性 15 结语 ⚠️ 原文&#xff1a;Understanding How ECDSA Protects Your Data. ⚠️ 写在前面&#xff1a;本文属于搬运博客&#xff0c;自己留着学习。同时&#xff0c;经过几…

部署Zabbix代理服务器

目录 1.准备环境 2.设置 zabbix 的下载源 3.安装 zabbix 所需的数据库 3.1添加数据库用户&#xff0c;以及 zabbix 所需的数据库信息 3.2导入数据库信息 4.修改 zabbix-proxy 配置文件 5.启动 zabbix-proxy 6.在所有主机上配置 hosts 解析 7.在 Web 页面配置 agent 代…