VS2019B站课程笔记


二进制

在二进制数字前加0b,或0B,如0b11111111就是255

八进制前加0,十六进制前加0x

变量名不能以数字开头,可以使_开头的

定义变量的方法:int_hp_{900};, 数据类型_变量名_{初始值} 或者 int hp {900};

常量定义方式:

方法一:const 类型 名字 {初始值}; 或者 类型 const 名字 {初始值}; 如:const int hp {900};

方法二:#define 名字 值

方法三:直接使用值

image.png

在嵌入式设备中变量大小要注意尽量节省,能用小字节类型就不用大的

bool类型占用一个字节内存,取值true或者false

true = 0;false =1(所有非零的数)

输入:std::cin>>要存放输入内容的变量名;

数字后缀:L/l代表该值为long,LL/ll代表为long long型,U/u代表为无符号型。

一次运算最多只能用一次递增或者递减,例如int s_end = ++a*5 +16*a++; 这样的表达式结果是不确定的。

类型转换

#include 

int main()
{
    int a{ 500 };
    unsigned b{ 1000 };
    std::cout << a-b;
}

输出结果:4294966796

类型转换的时候经过运算以后会自动转成表达式里面最高的那一个,short和char都会自动转换成int

从上到下级别依次递减:

IYS2o8.md.png

因为查找麻烦,c++在c语言的基础上增加了一个static_cast静态转换:

static_cast <目标类型>(要转换的内容) int a = static_castb;

用sizeof(类型)可以查看类型占用的内存

3个二进制数可以表示一个8进制数,4个二进制数可以表示一个16进制数。所以可以一一对应000-111就是1-7,0000-1111就是1-F

4.1 字符

image.png

#include 
#include 

int main()
{
    setlocale(LC_ALL, "chs");

    char charA{ 'A' };//字母初始化
    char charB{ 65 };//数字初始化

    wchar_t wcharA{ L'我' };//L表示宽字节字符

    char16_t char16{ u'A' }; //u代表utf-16的标准
    char32_t char32{ U'A' }; //U代表utf-16的标准


    std::cout << (char)65 << std::endl;
    std::cout <<(int)'A' << std::endl;

    charA++;
    std::cout << wcharA << std::endl;//std::cout只支持了ASCII编码的规范
    std::wcout << wcharA;//std::wout支持了宽字节UTF-8的编码规范
    //std::cout和std::wcout不支持char16_t 和32的输出,只能输出为数字
    //char{10}是换行符,除了\转义符号写出那些不能直接打出来的,也可以用它们对应的ASCII表达出他们

}

输出结果:

A
65
25105

4.2 推断类型

auto 变量名 {初始值};

查看一个变量的类型:typeid(变量).name();

#include 

int main()
{

    auto a{ 200 };
    auto b{ 1200LL };
    auto c{ 1200L };

    std::cout << "变量a的类型为 " << typeid(a).name()<< char(10);
    std::cout << "变量b的类型为 " << typeid(b).name()<< (char)10;
    std::cout << "变量c的类型为 " << typeid(c).name() << char(10);
}

输出结果:

变量a的类型为 int
变量b的类型为 __int64
变量c的类型为 long

格式化输出流及转义

常见的IO流输出指令:

image.png

常见转义:\t制表符

\b退格 \a警告声

4.4运算优先级

image.png

运算优先级从上往下递增

4.5 位运算

移位在不同的CPU架构下与乘除速度不一一定谁快谁慢。

int是负数时移位补1,是正数时移位补0.unsigned没有符号,所有都是补0

求反运算符:~ 把0变1,1变0

与运算: & a和b都是1才是1 。

或运算:| 只要有1就是1

异或运算: ^ 两个不一样就是1,一样是0

// class4.5.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include  //输出二进制

int main()
{
    int a{ (int)0b111111111111111111111111111111111 };
    a <<= 8;//a=a<<8;
    std::cout << std::bitset<32>(a)<>= 7;
    std::cout << std::bitset<32>(b) << char(10);

    a >>= 7;
    std::cout << std::bitset<32>(a) << char(10);

    /*
    int是负数时移位补1,是正数时移位补0.unsigned没有符号,所有都是补0
    */

    int test1{ 0xFFFF };
    test1 = ~test1;
    std::cout << std::bitset<32>(test1) << char(10);

    int test2{ 0x2833 };
    test2 = test2 & 0xFF00;//把后两位的数字去掉

    std::cout << std::bitset<32>(test2)<

输出结果:

11111111111111111111111100000000
00000001111111111111111111111110
11111111111111111111111111111110
11111111111111110000000000000000
00000000000000000010100000000000
ff33

4.6字符的故事

要清楚的是:现在的是用什么编码的,需要转换成什么编码的,就可以解决字符问题。ASCII,ANSI,GB2312,GBK,UNICODE...

5.1 枚举变量

#include 
#define Normal 0
#define High 1
#define Rare 2
#define Epic 3
#define Legend 4
#define Myth 5


int main()
{
    short weaponLv;

    weaponLv = Normal;

    short weaponALv = Legend;
    short weaponBLv = Myth;

    std::cout << "这件装备的品质为" << weaponBLv;
}

为了输出不同武器类型,可以用宏定义,也可以分别单独定义类型。但是为了方便,这里提供枚举的方法。

形式:enum class 类型名称:基本类型

选项1

选项2

};

声明一个枚举变量的方法:

类型名称 变量名称;

// class5.1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#define Normal 0
#define High 1
#define Rare 2
#define Epic 3
#define Legend 4
#define Myth 5


int main()
{
    short weaponLv;

    weaponLv = Normal;

    short weaponALv = Legend;
    short weaponBLv = Myth;

    std::cout << "这件装备的品质为" << weaponBLv <

输出结果:

这件装备的品质为5
两件装备的品质差90

1. 枚举类型可以提高代码的可读性和安全性

2.枚举类型默认是int类型

3. 枚举类型成员只能是整数类型

4. 枚举类型和其他类型转换需要强制转换

5. 默认情况每一项递增1

5.2 自定义变量名称

#include 
#define 整数 int
#define eLong long


int main()
{
    整数 a{ 100 };
    std::cout << typeid(a).name()<

int
int

5.3 命名空间

#include 


namespace lGame
{
    int HP{ 1000 };
    int MP{ 1200 };
    int lv{ 1 };

    namespace Weapon { 
        int damage{ 3000 };
        namespace WeaponInfo {
            int lv{ 0 };
        }
    };
}
int main()
{
    /*using std::cout;
    using std::cin;
    using std::hex;*/
    using namespace std;//有了这一行代码,上面的都不用写了


    cout << "不需要std!";
    int a;
    cin >> hex >> a;
    cout << a<<"\n";

    int c = lGame::Weapon::damage;
    cout << c;

}

输出:

不需要std!
123
291
3000

命名空间规则:

  1. 不能放在函数体内
  2. 可以在一个命名空间内嵌入另一个命名空间
  3. 子级命名空间调用父级命名空间依然需要限定符(命名冲突时需要)

5.4 变量的生命周期

  1. 代码块中的变量的生命从声明开始,直到这个代码块结束。
  2. 声明在代码开始之前的变量叫全局变量,全局变量的生命从程序运行开始,到程序结束。
  3. 在变量名冲突的时候,采用就近原则。
  4. 要访问名称冲突的全局变量,可以使用限定符::来访问。
#include 

int a{ 100 };
int main()
{
    int a{ 160};
    {
        int a{ 350 };

        {
            char a = 'A';
            std::cout << ::a << std::endl;//直接拿全局变量
            std::cout << a << std::endl;
        }
        std::cout << a << std::endl;
    }
}


输出结果:

100
A
350

5.6 自定义数据类型

结构体:

struct 名称

? 类型 名称;

结构的本质是按照我们自己的方式定义一块连续的内存结构

声明一个结构变量的本质是向计算机申请一块内存,这块内存的大小至少是我们定义的结构成员需要占用的内存之和

使用结构则是按照我们定义好的方式从这块内存中读取和写入数据

#include 

int main()
{
    struct CAR
    {
        char logo{ 'A' };
        unsigned short wheel{ 19 };
        unsigned price{ 900000 };
    };

    CAR carA{'C',25,500000};
    CAR carB{'B',22,600000};
    CAR carC{'B',21,600000};

    carA.price += 50000;//假设涨价了,可以直接修改它的值

    std::cout << "车辆价格"<< carA.price<<"车辆轮子"<

输出:

车辆价格550000车辆轮子25车辆logoC

if(a^b)等价if(((atrue)&&(bfalse))||(afalse)&&(btrue))

在if里面的int是被转换成bool判断的,所以不是用两个值的二进制异或得到的结果,这里要注意区分!