c++新经典—c++基本语言

2023-05-16

13.1 语言特性、工程构成与可移植性

13.1.1 语言特性:过程式、对象式程序设计

1)面向过程式的程序设计

C语言的编程风格是面向过程式的程序设计。所谓过程式的设计语言就是当编写代码解决一个问题时,代码的编写方法是从上到下,逐步求精,一些公用的功能写成函数,需要用到结构体时就定义结构体。

2)基于对象的程序设计和面向对象的程序设计

C++本身支持C语言风格的过程式程序设计,同时也支持基于对象的程序设计和面向对象的程序设计。

基于对象和面向对象的不同?

1、基于对象和语言有关,而面向对象和程序有关。
2、基于对象仅仅支持了抽象数据类型的功能,只是建立了一个层次体系。而面向对象是根据对象的实际类型不同,可以自动完成不同的行为,而仅仅通过一致的调用形式。
3、面向对象主要有三个特性,封装、继承和多态,而基于对象是面向对象的初级阶段,只有封装。
 基于对象和面向对象程序设计的主要区别是:在基于对象的程序设计中额外运用了继承性和多态性技术。从而实现易维护,易扩展,模块化

c中结构体,c++类,类比结构更强大的地方在于:在类中,不仅可以定义成员变量,还可以定义成员函数(也叫方法)以实现一些功能

13.1.2 C++程序和项目文件构成

(1)一个项目(工程)中可以包含多个.cpp文件和多个.h头文件,
一般.cpp叫源文件,.h叫头文件(函数的声明,一些类、结构的定义,一些#define等)

(2)C++的头文件拓展名一般以.h居多。此外,还有.hpp,.hpp一般来讲就是把定义和实现都包含在一个文件里,有一些公共开源库就是这样做,主要是能有效地减少编译次数

(3)很多C++提供的头文件已经不带扩展名.h。以往在C语言中经常用到的头文件,如比较熟悉的stdio.h等,在C++98标准之后,都变成了以c开头并去掉拓展名的文件,如stdio.h就变成了cstdio文件。

13.1.3 编译型语言与可移植性

c++属于编译型语言,编译型语言在执行前需要一个专门的编译过程,把程序编译成二进制文件(可执行文件),执行时直接执行就可以
解释型语言,在执行时先解释再执行。
可移植性,在不同的操作系统上,代码生成的可执行文件执行后能够实现相同的功能,那么这份源代码就被称为可移植的。

13.2 命名空间简介与基本输入/输出精解

命名空间是为了防止名字冲突而引入的一种机制。防止在大型项目中多个.cpp存在函数名、类名和变量名同名的问题。
可以把命名空间看成一个作用域,这个命名空间里定义的函数与另外一个命名空间里定义的函数,即便同名,也互不影响。

(1)命名空间的定义:
namespace 命名空间名字
{
    void radius()
    {
       // ......
    }
} //这里无须分号结尾

(2)外界对命名空间中实体的访问方法:

两个冒号——>“作用域运算符”:

命名空间名::实体名

在同一个cpp中调用某个命名空间某个函数:
//MyProject.cpp源文件代码如下
namespace NMZhangSan			//定义命名空间
{
	void radius()
	{
		printf("NMZhangSan::radius函数被执行.\n");
	}
}
int main()						//主函数
{
	NMZhangSan::radius();		//调用NMZhangSan命名空间下的radius函数
}

不是在一个cpp中调用某个命名空间某个函数:

需要对那个命名空间建立一个.h的头文件指明函数有哪些

namespace NMLiSi
{
	void radius();			//函数声明
}

然后将头文件包含进来再调用

#include "MyProject2.h"

否则无法通过编译

13.2.2 基本输入/输出

C++中输入/输出用的标准库是iostream库(输人/输出流)。流就是一个字符序列。那怎样在程序中使用这个标准库呢?只需要包含一个头文件就可以了
#include < iostream >

1、输入输出都有个缓冲区,不能每次都仅输出一个字符,由于要调用内核
2、<<有左结合和右结合,不同编译器不一样
3、std::endl函数模板名,相当于函数指针,用于换行和刷新输出缓冲区(flush)
4、c中scanf需要地址符号&,cin不需要地址符号&,因为引用
5、>>输入运算符,类成员函数重载多个版本,处理不同数据类型

13.3 auto、头文件防卫、引用与变量

13.3.1 局部变量和初始化

c++需要时随时定义变量,c只在函数头部定义变量。
新标准可以使用{} ,表示一个数

 int abc {3};
 int abc = {3}; 两种方式都可以
 int abc[]={11,12,13}; 

这样写可以统一起来

13.3.2 auto关键字

变量的自动类型推断,声明变量时根据变量初始值的类型自动选择匹配类型,发生在编译期

13.3.3 头文件防卫式声明

同一个头文件被包含(include)多次

head.h 定义 int glo=5;
head2.h 定义 int glo2=3;然后#include "head.h"
myProgect.cpp 
   #include"head.h"
   #include"head2.h"
那么head.h就被包含了两次,glo就被定义了两次就会出现重定义错误。

C/C++中有两种宏实现方式避免这种情况:#ifndef方式和#pragma once方式

#ifndef方式

定义的名字不能一样

#ifndef __HEAD__
#define __HEAD__
	//......
#endif

#pragma once方式

#pragmaonce
	//......

ifndef会使得编译时间相对较长,可能出现后面的名字即宏名撞车,pragma once不支持跨平台
所以ifndef由语言支持所以移植性好,pragma once可以避免名字冲突

13.3.4 引用

引用是未变量起别名,与原变量名占用同一块内存,并不额外占用内存,必须定义时初始化,类型必须一样,不能绑到常量上。

int value = 10;
int &refval = value;//引用必须绑定到变量或对象上,不能绑到常量上

void changeValue(int &v) {
	v = 22;
}

13.3.5 常量

常量就是不变的量。可以有几个关键字修饰 const关键字、constexpr关键字

1)const关键字

const添加上,该值就不可以改变

const int var = 17; //承诺值不变,实际可改变
int &var2 = (int &)var; //const int需类型转换
var2 = 5; //var2修改值后会重新开辟内存空间?

cout <<var <<endl;  //17
cout <<var2 <<endl; //5,引用不是别名这么简单

通过引用可以修改值,但是输出还是那个constint func() {return 3;}
int v1 = 12;
const int v2 = v1 + func(12); //运行时求值也行

2)constexpr关键字

constexpr表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。编译时求值,能够提升运行时的效率,有利于系统优化等。

声明为constexpr的变量一定是一个const变量,而且必须用常量表达式初始化

constexpr int mf = 20;  //20是常量表达式
constexpr int limit = mf + 1; // mf本身是常量,因此mf + 1是常量表达式
		  int limit2 = mf + 1; // 可以
		  int mf2=20;
constexpr int limit = mf2 + 1; // 不可以,mf2是变量


constexpr int sz = size(mf2); //mf2	是变量,不可以
constexpr int sz = size(mf); //mf是常量,只有当size是一个constexpr函数时才是一条正确的声明语句,比如下面
	
	constexpr int size(int abc) { //constexpr函数中代码要尽可能简单,变量定义时要初始化
	int a3 = 5;
	//int var; //这样不进行初始化就会出错,所有的都要在定义时初始化
	//printf("good\n");//这样错误,constexpr函数中需要调用constexpr函数
	return abc * a3;
}

只要是constexpr修饰的,所有的都必须是常量,不能有变量混入,使用函数时 size(int a),传入的也是常量。

const关键字和constexpr区别

constexpr 和const在使用引用修改值时发现并没有改成功

在constexpr声明中如果定义了一个指针,限定符conxtexpr仅对指针有效,与指针所指的对象无关。

const int*p = nullptr;        //p是一个指向整形常量的指针
constexpr int* q = nullptr;   //q是一个指向整数的常量指针

13.4 范围for、动态内存分配与nullptr

13.4.1 范围for语句

范围for语句,遍历序列,支持begin和end成员函数返回迭代器的容器就可以支持范围for语句。
使用引用可以避免复制提高效率。

int v[]{12, 13, 14, 16, 48};

for(auto x : v) //依次复制v数组中元素值给x
	cout <<x <<endl;
for(auto x : {12, 13, 14, 16, 48}) //依次复制元素序列中值给x
	cout <<x <<endl;
for(auto &x : v) //引用避免复制
	cout <<x <<endl;

13.4.2 动态内存分配

1)内存存储空间

分为程序代码区、静态存储区、动态存储区。

  • 程序代码区:存放代码的区域
  • 静态存储区:程序运行期间分配固定的存储空间,存放运行时需要的数据
  • 动态存储区:程序运行期间根据需要进行动态的分配存储空间,存放运行时需要的数据

动态存储区存放函数形参,局部变量,函数调用时调用现场的一些数据和返回地址。这些数据在函数调用时开始分配空间,调用完毕后就会被回收,这种分配和释放被认为是动态的。

希望函数中局部变量的值在函数调用后不会被释放,在下一次调用时还有上一次的值,这种局部变量称为局部静态变量,用static关键字

2)内存细分区域

函数局部变量编译器自动分配释放。栈空间有限,系统规定,分配快。
程序员malloc/new申请,及时free/delete释放(节省系统资源,防止耗尽导致程序崩溃,忘记释放程序结束后操作系统回收)。堆空间由程序员自由分配,大小理论上不超过实际物理内存,分配慢。
全局/静态存储区,放置全局变量和静态变量,程序结束时释放。
常量存储区,存放常量,字符串常量等,不允许修改。
程序代码区,存放代码

3)malloc和free(c语言)

void * malloc(int NumBytes);

返回值是void *,void *类型可以强制转换成任何其他类型得指针,如果分配成功则分配指向该分配空间的指针,失败则返回空指针NULL

void free(void *Ptr);

例子

int * p= NULL;
p= (int *)malloc(10 * siezof(int));//返回void *指针后转换成int *类型的指针
free(p);

3)new和delete(使用这个,不要用malloc)

运算符,不是函数。比malloc和free做了额外的初始化和清理工作。

指针变量名 = new 类型标识符; //未初始化
指针变量名 = new 类型标识符(); //默认值初始化
指针变量名 = new 类型标识符(初始值); //指定值初始化
指针变量名 = new 类型标识符[内存单元个数]; //数组,delete[]释放

int *p = new int[100];
if(p != NULL) {
	int *q = p;
	*q++ = 1;
	*q++ = 5;
	delete[] p;//delete[]回收整个数组,[]内写了数字无意义,会被忽略
	//delete p只会回收第一个数组元素空间
	p = NULL;
}

new时用了[],delete就要用[],[]里面不用写数组元素个数,写了也会忽略。

13.4.3 nullptr

nullptr代表空指针,与指针相关尽量使用nullptr,不使用NULL。
nullptr能够避免在整数和指针间发生混淆。

cout <<type(NULL).name() <<endl; //输出int
cout <<type(nullptr).name() <<endl; //输出std::nullptr_t

因此两者类型不一样
如果将两者当函数实参传递到函数中会因为类型不同而调用不同的重载函数

(1)对于指针的初始化,能用nullptr的全部用nullptr。
(2以往用到的与指针有关的NULL的场合,能用nullptr取代的全部用nullptr取代。
即关于指针的null全用nullptr

13.5 结构、权限修饰符与类

13.5.1 结构 struct

成员函数 stu.number = 1001;
指针 std->number=1001;

struct student {
public:
	int number;
	char name[10];
	void func() {
		number++;
	}
}

13.5.2 public和private权限修饰符

public,共有/公共。修饰的成员(成员变量、成员函数),能被外界访问,类似外部接口。
private,私有,修饰的成员(成员变量、成员函数),只能被内部定义的成员函数使用。

struct(继承也)默认public,class(继承也)默认private。

13.5.3 类简介 class

用户自定义是数据类型(关联了操作),定义的类变量称为对象,一块能存储数据并具有某种类型的内存空间

c++中的结构和类的区别

1、结构的默认访问类型是public,而类的默认访问类型为private。
2、结构的继承默认是public,而类的默认继承是private。
如果明确写出public、protected、private那么这两个没有什么区别,区别主要是在缺省访问级别时有所不同

13.5.4 类的组织

类定义放在h头文件,类实现放在cpp源文件,使用时导入h头文件。头文件的文件名可以和类名相同。.cpp也可以相同

13.6 函数新特性、inline内联函数与const详解

13.6.1 函数前置和后置返回类型

前置返回类型,函数形参不使用时可以无形参名,函数调用是必须传递实参值。
在这里插入图片描述
后置返回类型,函数声明或定义中将返回类型写在参数列表之后,用于复杂返回类型和特殊场合。
auto表示函数返回类型放到参数列表之后,返回类型是通过—>开始的

auto func(int, int) -> int; //声明
auto func(int a, int) b -> int { //定义
	return 1;
}

这样做主要是为了模板方便

template<class T1,class T2>
auto getValue(T1 v1,T2 v2)->decltype (v1 + v2)
{
    return v1 + v2;
}

返回的类型由传入的参数确定

13.6.2 inline内联函数

inline int func(int a) { //函数增加inline,内联函数
	return a*a+3;
}

函数体很小,调用又很频繁的函数要频繁地进行压栈、出栈动作以处理函数调用和返回的问题,要频繁地开辟内存,耗费系统性能。

使用内联函数后的影响(背)

  • 影响编译器,编译阶段,系统尝试调用函数替换为函数本体(不再进行函数调用),提升性能。
  • 内联只是程序员对编译器的建议,做与不做的决定权在编译器。
  • inline内联函数的定义就放在头文件中。

使用内联函数的注意点
1、把inline函数的定义放到头文件中,在每个调用该inline函数的文件中包含该头文件。这种方法保证对每个inline函数只有一个定义,且程序员无需复制代码,并且不可能在程序的生命期中引起无意的不匹配的事情。

使用内联函数的优缺点是什么(背)

用函数本体取代函数调用,显然可以增加效率。但同时带来的问题是函数代码膨胀,所以内联函数函数体要尽可能短小,这样引人inline才有意义。调用一个函数时需要压栈开辟内存等动作,假如这些动作需要花费1s的时间,如果在这个函数中代码的执行需要花费1000s的时间,那这个函数写成内联函数之后,也就节省了1s的时间,但是源文件代码却膨胀的很大。如果在多个地方调用这个函数,那就相当于多个地方出现代码的重复膨胀,代码在程序运行时也是要占用内存的,因为内存中有代码段专门保存程序代码。

constexpr就是一种内联函数,内联函数比较像宏展开

inline和#define(宏展开)的区别(背)

1、define是 预处理时处理的宏; 只进行简单的字符替换,无类型检测,而inline是编译时的内联函数,有类型检查,且编译器有权拒绝内联。
2、inline有传参,这点和普通函数一致,define只是简单的文本替换

13.6 函数特殊写法

1、void表示无返回类型或无输入参数

void func1(void) 
{ }

2、函数返回指针和返回引用

int *myfunc1() {
	int tmp = 9; //tmp应该成为全局变量
	return &tmp;//局部变量有隐患
}


int &myfunc2() {
	int tmp = 9;//tmp应该成为全局变量
	cout <<&tmp <<endl;
	return tmp; //局部变量有隐患
}

int &k = myfunc2();  
cout <<&k<<endl; //调用打印结果一样


int k = myfunc2();
cout <<&k<<endl;

下面这个不成立,const关键字在比较同名函数时会被忽略掉

//函数重载不成立
void fs(const int i){}
void fs(int i){}

13.6.4 const char *、char const *与char * const的区别

1、常量指针 ——防止使用指针来修改指向的值

int age=30;

const int * p=&age;

2、指针常量——防止改变指针指向的位置

int * const p=&age;

其他注意的地方


const char * const p或char const * const p
指向变量和指向内容都固定

char const *p 等价 const char *p 还是就近

就近,看是给指针还是指针后面的元素,
给了指针就不能通过指针修改对应的值,可以通过其他方法修改。
给了后面的元素则后面的元素不能修改也就是不能更换指的地址,但可以改变地址上的内容

引用类型的const

在这里插入图片描述

int i = 100;
const int &a = i; //不能通过引用变量修改值
i = 200; //正确
a = 200; //错误

const int &b = 156;//正确,字面值初始化常量引用
int &b = 156;//错误
b = 200; //错误,b看作常量,不能修改值

上面&a可以认为是一个词,就是a是i的别名,那么加上const,b就不能动,但是是对b加的,对i没有影响,就像下面一样不想在局部函数里修改值,但是原值可以修改。

13.6.5 函数形参中的const引用

引用但不想改变值在前面加上const

void fs(const student &stu) { //可接受const引用,普通引用,字面值常量
	//stu.num = 1010;//const引用不能修改
}

普通的student不能接受const的student,但是const student&可以接受普通的student,也可以就收const类型的,这样既可以接受普通引用也可以接受常量就更加灵活

13.7 string类型

STL教程5-STL基本概念及String和vector使用

s.c_str(); 返回字符串里的内容,返回的是一个指向正规C字符串的常量指针,所以以"\0"结尾

13.7 vector类型

注意:
1、vector不能用来装引用,引用只是一个别名,不是一个对象,所以下面会报错误

vector< int& >abc;//语法错误

2、for语句中,不要改变vector的容量,增加、删除元素都不可以。这样会发生混乱

vector<int> vecvalue{ 1, 2, 3, 4, 5 };
for(auto vecitem : vecvalue) {
	vecvalue.push_back(888);//错误
	cout <<vecitem <<endl;
}

由于不同容器的实现不一样,插入元素可能会导致内存发生变化,那么迭代器就会失效

13.9 迭代器

1、const_iterator迭代器,如果容器对象是一个常量,就必须使用这个迭代器,这个迭代器只能读。
2、不管是否是常量容器,cbegin和cend,这两个返回的都是常量迭代器const_iterator,如下面所示,不能* iter修改其元素。
在这里插入图片描述

13.10 类型转换

13.10.1 隐式类型转换隐式转换

系统自动进行,无需人为介入的类型转换

int m = 3+45.6

13.10.2 显式类型转换(强制类型转换)

c语言风格的强制类型转换——将类型用()括起来

int k = 5 % (int)3.2;
k = 5 % int(3.2);//函数风格

STL教程3-类型转换static_cast、dynamic_cast、const_cast、reinterpret_cast方法

1、static_cast

1、相关类型转换,比如int转换为double
2、有继承关系的子类转换为父类
3、void*和其他指针的互转
4、不能用于其他类型的指针转换

2、dynamic_cast

用于父类转换为子类

3、const_cast

去除指针或者引用(只能去这俩,不能其他的)的const属性
去掉以后不要重新赋值,赋值的话是未定义行为,不要这么做以免产生无法预料的后果。
这个可以去掉表达式的常量属性

4、reinterpret_cast

可以处理无关类型的转换,随便转都行。
常用于
1、将整型转换成指针,一种类型指针转换成另一种
2、也可以一个指针到一个整型

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

c++新经典—c++基本语言 的相关文章

  • 使用VsCode配置MySQL实现连接、查询、等功能

    场景 xff1a 使用VsCode配置MySQL实现连接 查询 等功能 xff08 mrx xff09 步骤 xff1a 打开vscode左边的拓展栏 1 搜索MySQL MySQL Syntax两个插件 xff0c 并安装 xff1b 2
  • centos7安装mysql5.7步骤(图解版)

    目录 一 下载mysql5 7安装包 二 mysql5 7安装包上传到linux服务器 三 检查系统是否安装过mysql 四 卸载CentOS7系统自带mariadb 五 检查有无安装过mysql 用户组 没有的话创建 六 安装mysql5
  • IDEA报错之Failed to start bean ‘documentationPluginsBootstrapper‘问题及解决方案

    笔者今日创建一个Spring Boot 项目准备做产品 基于IDEA搭建是非常容易的 但是万万没想到 居然一切顺理成章的创建之后 运行报错 非常痛惜 错误截图如下 核心错误 Failed to start bean documentatio
  • Linux界面和字体大小调整

    1 调整桌面显示屏幕大小 点击页面上方的系统 gt 首选项 gt 显示 点击显示后出现显示器分辨率调节 xff0c 将分辨率选择最大基本可以覆盖虚拟机整个屏幕 2 调整屏幕字体大小 点击页面上方的系统 gt 首选项 gt 外观 选择字体栏
  • SQL语句:分组查询

    在对数据表中数据进行统计时 xff0c 可能需要按照一定的类别分别进行统计 比如查询每个部门的员工数 使用GROUP BY按某个字段 xff0c 或者多个字段中的值 xff0c 进行分组 xff0c 字段中值相同的为一组 语法格式 查询列表
  • Ubuntu18.04安装后基础配置(换源+WIFI适配+ROS+VScode)

    简单记录一下 xff0c 新安装好的Ubuntu系统 xff0c 需要什么初始化步骤呢 xff1f 1 建议首先换源 xff0c 换清华源 xff08 需要插网线 xff09 首先连接网线 xff0c 系统需要有网络环境 打开 软件和更新
  • PyInstaller库—Python第三方库—程序打包

    PyInstaller的作用是将Python源文件 xff08 py xff09 打包 xff0c 变成直接可运行的可执行文件 首先需要下载安装PyInstaller库 xff0c 在cmd 中输入pip install PyInstall
  • vcpkg问题-环境配置

    参考博客 xff1a Visual Studio开源库集成器Vcpkg全教程 利用Vcpkg轻松集成开源第三方库 https blog csdn net cjmqas article details 79282847 先说一些装好以后注意的
  • PVE系统安装

    PVE是专为家庭设计打造的 xff0c 永久免费的开源平台 xff0c 在低配置的小主机上都能轻松运行的一款轻量级平台 PVE是专业的虚拟机平台 xff0c 提供一个家庭设备集中管理平台 xff0c 你可以利用它安装任何你想要的系统 1 制
  • 初识c语言系列-1-第一个c语言程序

    目录 1 61 61 该系列的介绍 61 61 2 61 61 未来的打算 61 61 3 61 61 简单介绍c语言 61 61 4 61 61 第一个c语言程序 61 61 1 该系列的介绍 首先呢 xff0c 开始这个系列之前呢 xf
  • NestJS 项目实战 需求分析(文末附视频)

    前言 一般常规的项目立项之初会有一份 MRD xff08 Market Requirements Document xff0c 市场需求文档 xff09 用来判断产品的必需性以及价值等 对于基础项目开发来说 xff0c 使用 MRD 可能有
  • python-数据分析2csv

    首先 xff0c 我们需要导入数据并计算一些统计指标 请按照以下步骤操作 xff1a 使用pandas库的read csv 函数导入CSV文件 使用head 函数查看前五行 使用info 函数查看数据类型和缺失值 使用describe 函数
  • (Python)使用清华源进行python的pip安装(任何环境,不用换源,用时只需加上一行代码

    xff08 Python xff09 使用清华源进行python的pip安装及pip批量安装的方法 一 介绍二 pip安装三 扩展批量安装库 一 介绍 当我们在下载pip时是否因为速度太慢而失去耐心 xff0c 甚至由于太慢还会报错导致安装
  • 手把手教你写第一个C语言程序

    目录 xff1a 一 C语言项目的创建 xff1a 二 写第一个C语言程序 在屏幕上输出Hello World xff1a C语言是所有编程语言的基础 xff0c 历经50多年的发展依然被众多编程者使用 xff0c 那么怎么写C语言程序呢
  • java实现输入一行字符,分别统计其中的英文字母,空格,数字,和其他字符的个数

    主要原理 xff1a 定义四个变量用来积累个数利用Scanner录入字符串使用 toCharArray转换字符串for循环遍历字符if判断每个字符类型打印各个类型字符个数 import java util Scanner public cl
  • 31套VTK3D图像体绘制/VTK光线投射法/VTK三维重建程序源码

    31套VTK3D图像体绘制 VTK光线投射法 VTK三维重建程序源码 1 基于VTK的3D图像体绘制 xff08 实现了以VTK为基础的3D图像重建 xff09 2 基于VTK的人头骨3D图像 xff08 用表面重建的方法 vs2005 x
  • 在Unity中使用FFmpeg将视频绿色背景处理为透明背景

    1 安装FFmpeg 官方下载地址 xff1a Download FFmpeg 这里演示windows版的下载 建议下载shared压缩包 找到bin目录 xff0c 复制路径 设置环境变量 xff1a 状态栏左下角 xff0c 右键开始菜
  • keil 工程创建具体步骤(汇编语言)

    1 使用汇编语言时 xff0c 需要创建 s文件 具体步骤如下 xff1a 工程 new vision project 命名 英文 43 数字 xff0c 英文开头 保存 选择单片机型号 否 添加文件 保存命名 s 选择project中so
  • 洛谷 [模板]并查集

    题目链接 xff1a https www luogu org problemnew show 3367 span class hljs preprocessor include lt iostream gt span span class
  • LED流水灯实验(汇编语言)

    流水灯的本质就是使八个LED灯依次点亮 xff0c 本文所采用的LED灯为低电平有效 xff0c 故对八个LED灯依次赋低电平 对此 xff0c 我们通过使用指令 xff08 RL xff1a 累加器循环左移 xff09 实现循环点亮 代码

随机推荐