17 C++11常用语法

2023-05-16

文章目录

  • 一、C++11简介
  • 二、列表初始化
    • 2.1. 容器如何支持花括号初始化
  • 三、变量类型的推导
    • 3.1. 编译时类型推导:auto
    • 3.2. decltype类型推导
    • 3.3. 运行时类型推导 typeid
  • 四、final、override
  • 五、新增容器
  • 六、范围for循环
  • 七、默认成员函数控制
    • default
    • delete
  • 八、右值引用
    • 8.1. 右值引用的移动语义
    • 8.2. 移动语义需要注意的问题
    • 8.3. 右值引用引用左值
      • move的用法和注意事项
    • 8.4. 总结
    • 8.5. 完美转发


一、C++11简介

在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于TC1主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率。

阶段内容
C with classes类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等
C++1.0添加虚函数概念,函数和运算符重载,引用、常量等
C++2.0更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静态成员以及const成员函数
C++3.0进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理
C++98C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)
C++03C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性
C++05C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名C++0x,即:计划在本世纪第一个10年的某个时间发布
C++11增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等
C++14对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等
C++17在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等
C++20制定ing

二、列表初始化

在C++98中,标准允许使用花括号{}对数组元素进行统一的列表初始值设定。比如:

int array1[] = {1,2,3,4,5};
int array2[5] = {0};

对于一些自定义的类型,却无法使用这样的初始化。比如:

vector<int> v{1,2,3,4,5};

就无法通过编译,导致每次定义vector时,都需要先把vector定义出来,然后使用循环对其赋初始值,非常不方便。C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

  • 内置类型的列表初始化
int main()
 { 
 // 内置类型变量
 int x1 = {10};
 int x2{10};
 int x3 = 1+2;
 int x4 = {1+2};
 int x5{1+2};
 // 数组
 int arr1[5] {1,2,3,4,5};
 int arr2[]{1,2,3,4,5};
 
 // 动态数组,在C++98中不支持
 int* arr3 = new int[5]{1,2,3,4,5};
 
 // 标准容器
 vector<int> v{1,2,3,4,5};
 //等号可以不用写
 map<int, int>= m{{1,1}, {2,2,},{3,3},{4,4}};
 return 0;
 }
  • 自定义类型的列表初始化
class Point
{
public:
 Point(int x = 0, int y = 0): _x(x), _y(y)
 {}
private:
 int _x;
 int _y;
};
int main()
{
 Pointer p{ 1, 2 };
 return 0; 
}

2.1. 容器如何支持花括号初始化

以vector为例(list等其他容器也是类似),其中有个构造函数是使用initializer_list构造的。initializer_list是系统自定义的类模板,该类模板中主要有三个方法:begin()、end()迭代器以及获取区间中元素个数的方法size(),它只能使用花括号进行赋值。

std::initializer_list<int> list;
size_t n = list.size(); // n == 0
list = { 1, 2, 3, 4, 5 };
n = list.size(); // n == 5
list = { 3, 1, 2, 4 };
n = list.size(); // n == 4

在这里插入图片描述

容器支持花括号列表初始化,本质上是增加了一个initializer_list的构造函数,initializer_list支持接收一个花括号的列表。

#include <initializer_list>
template<class T>
class Vector {
public:
 // ... 
 Vector(initializer_list<T> l): _capacity(l.size()), _size(0)
 {
 _array = new T[_capacity];
 for(auto e : l)
 _array[_size++] = e;
 }
 
 Vector<T>& operator=(initializer_list<T> l) {
 delete[] _array;
 size_t i = 0;
 for (auto e : l)
 _array[i++] = e;
 return *this;
 } 
 // ...
private:
 T* _array;
 size_t _capacity;
 size_t _size;
};

三、变量类型的推导

3.1. 编译时类型推导:auto

作用:简化类型写法
缺点:可读性变差
auto是编译时,根据初始化表达式类型进行推导的.因此,auto对运行时的类型推导是无能为力的.

使用auto可以在不知道需要实际类型怎么给,或者类型写起来特别复杂的情况下进行变量定义:
在这里插入图片描述

3.2. decltype类型推导

auto使用的前提是:必须要对auto声明的类型进行初始化,否则编译器无法推导出auto的实际类型。但有时候可能需要根据表达式运行完成之后结果的类型进行推导,因为编译期间,代码不会运行,此时auto也就无能为力。
因此decltype是根据表达式的实际类型推演出定义变量时所用的类型。

int main()
{
 int a = 10;
 int b = 20;
 
 // 用decltype推演a+b的实际类型,作为定义c的类型
 decltype(a+b) c;
 cout<<typeid(c).name()<<endl;
 return 0; 
}

void* GetMemory(size_t size) {
 return malloc(size);
}
int main()
{
 // 如果没有带参数,推导函数的类型
 cout << typeid(decltype(GetMemory)).name() << endl;
 
 // 如果带参数列表,推导的是函数返回值的类型,注意:此处只是推演,不会执行函数
 cout << typeid(decltype(GetMemory(0))).name() <<endl;
 
 return 0;
}

auto和decltype不支持作为函数的参数:

  1. 语法原因,是编译时推导的
  2. 函数编译成指令,需要先建立起栈桢,那么就需要计算变量的大小,那么就需要提前知道变量的类型

3.3. 运行时类型推导 typeid

C++ 98支持的RTTI(运行时类型识别)
typeid只能查看类型不能用其结果定义类型,因为一个函数栈桢的建立需要计算其变量的大小,如果是运行时推导,那么就无法计算大小
运行时类型识别的缺陷是降低程序运行的效率

  1. 推演表达式类型作为变量的定义类型
  2. 推演函数返回值的类型

四、final、override

final:修饰虚函数,表示该虚函数不能再被继承
在这里插入图片描述

override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
在这里插入图片描述


五、新增容器

新增加容器—静态定长数组array、单链表forward_list以及unordered系列。
在这里插入图片描述
在这里插入图片描述


六、范围for循环

注意当容器存的对象比较大,或者这个对象要做深拷贝时,比如string,最好给&和const来减少拷贝提高效率,容器支持范围for的原理:范围for会被编译器替换成迭代器,也就意味着支持迭代器就支持范围for。


七、默认成员函数控制

C++中的空类,会默认生成一些成员函数,但是这些函数如果程序员自己编写了,就不会默认生成。然而有时候又需要默认生成,这就容易造成混乱,因此C++11,提供两个关键字,让程序员自己决定是否需要编译器生成。

default

在默认函数定义或者声明时加上=default,可以显示的指示编译器生成该函数的默认版本,用=default修饰的函数称为显示缺省函数

delete

在C++98之中,将函数设置成private并且不给定义,其它人就无法调用。
在C++11之中,只需要在函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,常用于防止拷贝。
在这里插入图片描述


八、右值引用

C++98中提出了引用的概念,引用即别名,引用变量与其引用实体公共同一块内存空间,而引用的底层是通过指针来实现的,因此使用引用,可以提高程序的可读性。
为了提高程序运行效率,C++11中引入了右值引用,右值引用也是别名,但其只能对右值引用。

左值:使用空间
右值:使用内容

一般认为:

  1. 可以修改的,普通类型的变量,因为有名字,可以取地址,都认为是左值。
  2. const修饰的常量,不可修改,只读类型的,理论应该按照右值对待,但因为其可以取地址(如果只是const类型常量的定义,编译器不给其开辟空间,如果对该常量取地址时,编译器才为其开辟空间),C++11认为其是左值。
  3. 如果表达式的运行结果是一个临时变量或者对象,认为是右值。
  4. 如果表达式运行结果或单个变量是一个引用则认为是左值。
#include<iostream>
using namespace std;
int main()
{
	//左值引用
	int a = 0;
	int& b = a;
	
	//右值引用
	int x = 1, y = 2;
	int&& c = 10;
	int&& d = x + y;
}

总结:

  1. 不能简单地通过能否放在=左侧右侧或者取地址来判断左值或者右值,要根据表达式结果或变量的性质判断。
  2. 能得到引用的表达式一定能够作为引用,否则就用常引用。
  3. 左值引用不能直接引用右值,但是const左值引用可以,右值引用不能引用左值,但是move函数可以将左值转化为右值。
    在这里插入图片描述

C++11对右值进行了严格的区分(除了右值就是左值):
纯右值(基本类型的常量,或临时对象): 比如 a+b, 100,强制类型转换产生的临时对象。
将亡值(自定义类型的临时对象): 比如函数按值返回一个对象。

这些纯右值和将亡值都会在栈帧中分配空间来存放临时变量,而右值引用就是他们的名字,这样就让临时变量和普通变量一样,有自己的名字和内存空间,此时就可以通过这个右值引用使用它的空间。

8.1. 右值引用的移动语义

由于左值引用和右值引用的类型不同,所以它们的函数构成重载。
在这里插入图片描述

C++11提出了移动语义概念,即:将一个对象中资源移动到另一个对象中的方式,可以有效的缓解拷贝构造对象时资源浪费的情况。

class String
{
public:

	String(const char* str = "")
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
		cout << "String(const char *str="")" << endl;
	}

	//正常构造
	String(const String& str)
		:_str(new char[strlen(str._str) + 1])
	{
		//深拷贝,代价比较大
		strcpy(_str, str._str);
		cout << "正常构造,深拷贝,代价比较大" << endl;
	}

	//移动构造
	String(String&& str)//是右值
		:_str(str._str)
	{
		
		str._str = nullptr;//直接进行资源转移,空间的交换,代价小,效率高
		cout << "移动构造,空间的交换,代价小,效率高" << endl;
	}

	//移动赋值
	String& operator=(String&& str)
	{
		cout << " 移动赋值,代价小,效率高" << endl;
		if (_str != str._str)
		{
			_str = str._str;
			str._str = nullptr;
		}
		return *this;
	}

	//正常赋值
	String& operator=(const String& str)
	{
		if (_str != str._str)
		{
			cout << "正常赋值,深拷贝,效率低" << endl;

			_str = new char[strlen(str._str) + 1];

			strcpy(_str, str._str);
		}

		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[]_str;
			cout << "~String()" << endl;
		}
	}

private:
	char* _str;
};

String Getstring(const char* str)
{
	String ret(str);
	//该函数返回一个临时对象,是右值
	return ret;
}

void test()
{
	String s1("左值");
	cout << endl;
	String s2(s1);
	cout << endl;
	String s3(Getstring("右值-将亡值"));
	cout << endl;
	String s4(move(s1));
	cout << endl;
	String s5("左值");
	s5 = Getstring("右值-将亡值");
	cout << endl;


}

int main()
{
	test();

	return 0;
}

在这里插入图片描述

移动构造和移动赋值是把将亡值(右值)的空间直接给要赋值的对象,因为将亡值出了作用域就析构了,所以与其让其白白析构,还不如将其空间利用起来,给要赋值的对象,这样就避免了深拷贝带来的效率降低。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在C++11的容器中,也增加了右值移动拷贝的插入:
在这里插入图片描述

8.2. 移动语义需要注意的问题

注意:

  1. 移动构造函数的参数千万不能设置成const类型的右值引用,因为const的资源无法转移,会导致移动语义失效。
  2. 在C++11中,编译器会为类默认生成一个移动构造,该移动构造为浅拷贝,因此当类中涉及到资源管理时,用户必须显式定义自己的移动构造。

8.3. 右值引用引用左值

按照语法,右值引用只能引用右值,但右值引用一定不能引用左值吗?因为:有些场景下,可能真的需要用右值去引用左值实现移动语义。当需要用右值引用引用一个左值时,可以通过move函数将左值转化为右值。该函数名字具有迷惑性,它并不搬移任何东西,唯一的功能就是将一个左值强制转化为右值引用,然后实现移动语义。
在这里插入图片描述

move的用法和注意事项

int main()
{
 String s1("hello world");
 String s2(move(s1));
 String s3(s2);
 return 0; 
 }
  1. 被转化的左值,其生命周期并没有随着左值的转化而改变,即std::move转化的左值变量不会被销毁。
  2. STL中也有另一个move函数,就是将一个范围中的元素搬移到另一个位置。
  3. move将s1转化为右值后,在实现s2的拷贝时就会使用移动构造,此时s1的资源就被转移到s2中,s1就成为了无效的字符
class Person
{
public:

	Person(const String &name)
	:_name(name)//调用String的拷贝构造函数
	{}

	Person(const Person& pl)
		:_name(pl._name)
	{
		cout << "Person(const Person& pl)" << endl;
	}

private:
	String _name;
};

在这里插入图片描述

对上述代码进行优化,增加右值引用:

class Person
{
public:

	Person(const String &name)
	:_name(name)//调用String的拷贝构造函数
	{}

	Person(const Person& pl)
		:_name(pl._name)
	{
		cout << "Person(const Person& pl)" << endl;
	}

	Person(const Person&& pl)
		:_name(pl._name)//pl中的string是左值,所以还是调用的深拷贝	
	{
		cout << "Person(const Person&& pl)" << endl;
	}

private:
	String _name;
};

在这里插入图片描述

继续优化,使用move函数:

class Person
{
public:

	Person(const String &name)
	:_name(name)//调用String的拷贝构造函数
	{}

	Person(const Person& pl)
		:_name(pl._name)
	{
		cout << "Person(const Person& pl)" << endl;
	}

	Person(Person&& pl)
		:_name(move(pl._name))//pl既然是一个将亡值,那么它的资源也是一个将亡值
	{
		cout << "Person(Person&& pl)" << endl;
	}


private:
	String _name;
};

在这里插入图片描述

8.4. 总结

在这里插入图片描述

C++98中引用作用:因为引用是一个别名,需要用指针操作的地方,可以使用指针来代替,可以提高代码的可读性以及安全性。
C++11中右值引用主要有以下作用:

  1. 实现移动语义(移动构造与移动赋值)
  2. 给中间临时变量取别名
int main()
{
 string s1("hello");
 string s2(" world");
 string s3 = s1 + s2; // s3是用s1和s2拼接完成之后的结果拷贝构造的新对象
 stirng&& s4 = s1 + s2; // s4就是s1和s2拼接完成之后结果的别名
 return 0; }
  1. 实现完美转发

8.5. 完美转发

完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。

void Func(int x) {
 // ......
}
template<typename T>
void PerfectForward(T t) {
 Fun(t);
}

PerfectForward为转发的模板函数,Func为实际目标函数,但是上述转发还不算完美,完美转发是目标函数总希望将参数按照传递给转发函数的实际类型转给目标函数,而不产生额外的开销,就好像转发者不存在一样。
所谓完美:函数模板在向其他函数传递自身形参时,如果相应实参是左值,它就应该被转发为左值;如果相应实参是右值,它就应该被转发为右值。这样做是为了保留在其他函数针对转发而来的参数的左右值属性进行不同处理(比如参数为左值时实施拷贝语义;参数为右值时实施移动语义)。

C++11通过forward函数来实现完美转发, 比如:

void Fun(int& x) { cout << "lvalue ref" << endl; }
void Fun(int&& x) { cout << "rvalue ref" << endl; }
void Fun(const int& x) { cout << "const lvalue ref" << endl; }
void Fun(const int&& x) { cout << "const rvalue ref" << endl; }
template<typename T>
void PerfectForward(T&& t) { Fun(std::forward<T>(t)); }
int main()
{
	PerfectForward(10); // rvalue ref

	int a;
	PerfectForward(a); // lvalue ref
	PerfectForward(std::move(a)); // rvalue ref
	const int b = 8;
	PerfectForward(b); // const lvalue ref
	PerfectForward(std::move(b)); // const rvalue ref
	return 0;
}

如果不使用forward函数,则会把右值变成左值。

在这里插入图片描述

在这里插入图片描述

资料参考:
C++11常用语法-壹
第三节 列表初始化—std::initializer_list

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

17 C++11常用语法 的相关文章

  • 解决vxe-table的表头动态渲染第一次不显示

    问题描述 xff1a vxe table表头当使用了 lt vxe colgroup gt 二级 多级表头 xff0c 设一级表头写死 xff0c 二级表头动态加载 xff0c 那么每次赋值二级表头时 xff0c 值赋上去了 xff0c 页
  • vite入门/徒手搭建vite/配置vite/使用vite脚手架/vite步骤

    以下内容全部以图片形式展示 xff08 自己动手尝试一下印象岂不是更深 xff1f xff09 当然啦 xff0c 也有完整的 xff0c 自己拉代码 https github com ispaomoya build vite git 文章
  • 解决vue跨域302,301,404,问题

    xff08 仅用于开发环境 xff0c 上线项目使用nginx配置 xff09 这里简单说一下配置的基本条件 目录 一 vue config js中配置devServer 二 使用axios发送请求 三 接口无误 以上三个都没问题了 要么就
  • 解决el-tooltip__popper设置宽度无效问题

    当采用了show overflow tooltip属性时 xff0c 如果内容过长 xff0c 摸上去的宽度单行占满整个屏幕 lt el table column show overflow tooltip gt 网上大家都说加上下面代码
  • 这些年工作以来自己读过的书

    gt 上学时不喜欢读书 看见书就烦 xff0c 就想把书拿来垫东西 gt 工作时强迫自己读书 有时会强迫饭后看半小时 xff0c 有时又会强迫看50页 xff0c 有时又会看着看着直接睡着了 xff0c 越看越疲劳 gt 慢慢接受每月读书的
  • addEventListener() 事件监听

    无意间有人问到了 xff0c 这个方法 xff0c 我就学了一下 xff0c 顺便敲了一个小demo addEventListener 用于向指定元素添加事件 可以向一个元素添加多次事件或者多次不同事件 xff0c 后面的事件是不会覆盖前面
  • JavaScript框架汇总

    本文转载于https www cnblogs com China Dream p 15770038 html 移动应用类框架 Vue js 官网地址 http cn vuejs org 官方简介 Vue js 是一套用于构建用户界面的渐进式
  • 计算机保研面试题-数据结构

    快速排序算法 xff0c 归并排序算法的复杂度 xff08 简单介绍各种排序 xff09 算法的特点 xff08 1 xff09 插入排序 xff1a a 直接插入排序 xff1a 比如将X插入有序序列L当中 xff0c 首先找到X在序列L
  • 计算机保研面试题——操作系统

    目录 1 操作系统的特点 xff1f 功能 xff1f 2 中断和系统调用的区别 3 进程 线程的概念以及区别 xff1f 进程间的通信方式 xff1f 4 进程有哪几种状态 xff0c 状态之间的转换 进程调度策略 xff1f 5 读写者
  • 计算机保研面试题——计算机网络

    目录 计算机网络体系结构 OSI xff0c TCP IP xff0c 五层协议的体系结构 xff0c 以及各层协议 IP地址的分类 32位地址 各种协议 xff1f TCP三次握手和四次挥手的全过程 六 TCP和UDP的区别 xff1f
  • 论文学习:Austere Flash Caching with Deduplication and Compression

    论文题目 xff1a Austere Flash Caching with Deduplication and Compression 来源 xff1a USENIX ATC 2020 链接 xff1a Austere Flash Cach
  • ubuntu 查看占用文件空间大小

    1 查看分区情况 fdisk l 2 查看系统的磁盘空间占用情况 df h df TH 3 查看某个目录的使用空间大小 du sh 需要先进入该目录 或者后面加上路径 du sh 路径 4 查看该目录下 每个文件夹占用的空间大小 查看某目录
  • 操作系统地址生成

    逻辑地址生成 从符号逻辑地址 gt 内存中具体的逻辑地址 不需要操作系统的帮助 xff0c 而是通过编译器 load等等完成 对于程序代码 cfile开始 xff0c 最开始的逻辑地址是对应的函数位置 变量名称 xff0c 通过编译成为 s
  • 主流数据库以及适用场景思维导图

  • 超声波测距模块(HC-SR04模块)特点及使用介绍

    超声波测距模块 xff08 HC SR04模块 xff09 特点及使用介绍 前言一 超声波测距模块 xff08 HC SR04模块 xff09 外观二 原理图三 相关参数讲解1 参数2 测量范围3 计算公式4 优点5 产品特性 xff08
  • ESP8266AT指令测试无返回值的问题

    ESP8266AT指令测试无返回值 xff1a 如图 xff0c 在使用esp8266测试at指令的时候无返回值 xff0c 然而我在检查硬件的时候没有任何错误 xff0c usb转ttl模块也是没有问题的 解决方法 xff1a 这时候只要
  • 重要:智能指针的使用(C++ 11 以上)

    智能指针的声明与初始化 xff1a 第一种 xff1a std shared ptr 指针 初始化方式1 xff08 推荐 xff09 std shared ptr lt int gt sp3 sp3 61 std make shared
  • 自顶向下和自底向上的实现方法

    1将一个大问题分解为小的易处理的子问题 xff0c 每个子问题可以使用一个方法来实现 xff0c 这种方法使得问题更加易于编写重用调试 xff0c 修改和维护 2当一个大问题分解为许多子问题 xff0c 各个子问题可以分配给不同的编程人员
  • c# --- 接口

    接口从某种程度上来说也是一个类 xff0c 但是接口中只包含方法的声明而没有方法的实现z 创建接口的关键字 xff1a interface 接口 xff0c 人机交互界面 创建接口的语法 xff1a 接口的访问权限 interface 接口
  • MAML++:HOW TO TRAIN YOUR MAML论文精读

    论文地址 https arxiv org abs 1810 09502 Abstract MAML是目前通过元学习进行少样本学习的最佳方法之一 MAML简单 xff0c 优雅和非常强大 xff0c 然而 xff0c 它有各种各样的问题 xf

随机推荐

  • webpack中的loader

    什么是loader loader是webpack中一个非常核心的概念 webpack用来做什么呢 xff1f 在我们之前的实例中 xff0c 我们主要是用webpack来处理我们写的js代码 xff0c 并且webpack会自动处理js之间
  • strtok()函数

    strtok 将字符串拆分成tokens xff0c tokens是被分隔符中的任何字符分隔的连续字符序列 char strtok char str const char sep sep参数是个字符串 xff0c 定义了用作分隔符的字符集合
  • MySQL夺命连环15问,你能坚持到第几问?

    文章目录 前言一 关系型和非关系型的区别 xff0c 以及使用场景二 Mysql索引优缺点三 给字段加索引最好怎么加 xff1f 四 什么情况下会导致索引失效 xff1f 五 为什么使用模糊匹配会使索引失效六 回表查询和索引覆盖是什么七 联
  • educoder数字逻辑实训:比较器设计(Logisim)

    第1关 xff1a 1位比较器设计 任务描述 本关任务 xff1a 在Logisim中完成1位比较器电路的绘制并完成测试 第2关 xff1a 2位比较器设计 任务描述 本关任务 xff1a 在Logisim中完成2位比较器电路的绘制并完成测
  • 1、树莓派的VNC文件传输

    目录 第一步 xff1a 在树莓派端打开VNC服务器 第二步 xff1a 输入指令运行vncserver 第三步 xff1a 在电脑端安装VNC查看器 第一步 xff1a 在树莓派端打开VNC服务器 第二步 xff1a 输入指令运行vncs
  • Hadoop 3.x(HDFS)----【HDFS 的读写流程】

    Hadoop 3 x xff08 HDFS xff09 HDFS 的读写流程 1 HDFS写数据流程1 剖析文件写入2 网络拓扑 结点距离计算3 机架感知 xff08 副本存储节点选择 xff09 1 机架感知说明2 Hadoop3 1 3
  • 【C++】程序运行时间计算的方式

    1 利用C 43 43 标准库 std chrono xff0c 如下计算一个主体程序的运行时间 xff0c 算出来的时间差值单位为毫秒 lt float std milli gt 表示用毫秒表示 auto t start 61 std c
  • FPGA之蜂鸣器播放音乐《花海》

    文章目录 前言一 蜂鸣器1 蜂鸣器简介 xff1a 2 有源蜂鸣器 xff1a 3 无源蜂鸣器 xff1a 二 简谱常识1 音符时值 xff1a 2 简谱名 xff1a 3 简谱名频率 xff1a 三 程序设计1 调用ROM IP核储存每个
  • Verilog语法基础HDL Bits训练 01

    文章目录 前言一 Basics simple wire1 RTL代码2 仿真波形图 二 Basics four wires1 RTL代码2 仿真波形图 三 Basics Not gate1 RTL代码2 仿真波形图 四 Basics And
  • c++文件写入数据

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • 基于HC-08蓝牙模块的蓝牙通讯

    RXD接TXD xff0c TXD接RXD 通过手机的蓝牙助手可以完成亮灭LED1和LED2的操作 当发送A时 xff0c LED1亮 发送B时 xff0c LED1灭 当发送C时 xff0c LED2亮 xff0c 当发送D时 xff0c
  • 计算机网络笔记

    文章目录 计算机网络课程笔记第一章 概述1 计算机网络的定义2 网络分类3 网络分层及协议3 1 网络分层的原因3 2 协议 xff1a 对等通信双方的通信规则3 3 网络服务类型 xff1a 面向连接和面向非连接3 4 服务原语 xff1
  • 关于OSPF区域划分

    区域划分的好处 背景 随着网络规模不断扩大 xff0c 结构也日趋复杂 xff0c 路由器完成路由计算所消耗的内存 CPU资源也越来越多网络发生故障的可能性也随之增加 xff0c 如果区域内某处发生故障 xff0c 整个区域内的路由器都要重
  • 多目标多角度的快速模板匹配算法(基于NCC,效果无限接近Halcon中........)

    多目标多角度的快速模板匹配算法 xff08 基于NCC xff0c 效果无限接近Halcon中 工程应用一 多目标多角度的快速模板匹配算法 xff08 基于NCC xff0c 效果无限接近Halcon中 Imageshop 博客园 主要是我
  • 蓝桥杯嵌入式第十三届模拟题做题笔记

    这届的蓝桥杯电子类延期了 xff0c 最近就很无聊 xff0c 想做点东西但是又什么啥也不会 xff0c five一个 在小破站寻求各路大佬的帮助 不求大家的赞了 xff0c 只希望大家能够分享知识 xff0c 帮助一下迷茫的人 首先第一眼
  • Code::Blocks

    Code Blocks出现A debugging check in this application has failed xff1f 虽然不懂 xff0c 但好像有一个灰常easy的解决方法 xff1a Settings gt Edito
  • Logidim中异或的符号表示

    logisim中的表达式以 代表异或
  • 本人开发环境基本配置一览 ~/.bashrc

    系统 xff1a ubuntu18 04 xff0c bashrc环境文件 1 配置CUDA路径 xff1b cudnn用deb包安装的 xff0c 会直接被装到系统相应路径 xff0c 不需要手动添加路径引用 2 ROS CUDA exp
  • QT笔记(一)

    学习目标 xff1a 总结学习的QT 学习内容 xff1a 1 QT的一些固定格式 2 控件和事件 3 信号和槽 记录内容 xff1a 1 QT的固定格式 1 引用头文件 自己创建的头文件用 34 34 括起 xff0c eg 96 inc
  • 17 C++11常用语法

    文章目录 一 C 43 43 11简介二 列表初始化2 1 容器如何支持花括号初始化 三 变量类型的推导3 1 编译时类型推导 xff1a auto3 2 decltype类型推导3 3 运行时类型推导 typeid 四 final ove