[C++编程笔记] 01 变量和数据类型

[C++编程笔记] 01 变量和数据类型

联系作者:359152155@qq.com



C++数据类型总图

  • 内置类型
    • 基本内置类型
      • 算数类型:布尔型、字符型、整型、浮点型
      • 空类型(void)
    • 引用
    • 指针
    • 数组
  • 自定义类型
    • struct
    • class
    • enum

1. 算数类型

1.1

类型含义最小尺寸
bool未定义
char字符8位
wchar_t宽字符16位
char16_tUnicode字符16位
char32_tUnicode字符32位
short16 位
int32位
long32位
long long64位
float32位
double64位

带符号和无符号

  • short、int、long、long long都是带符号的,加上前缀unsigned就可以得到无符号类型。
  • char是否带符号由编译器决定。signed char专用来指定带符号char,unsigned char专用来指定无符号char。

关于符号的注意事项:

  • 算数运算时切勿混用带符号类型和无符号类型。如果表达式里既有带符号类型又有无符号类型,当带符号类型取值为负时会出现异常结果。例:

    如果有int a = -1; unsigned int b = 1;,则表达式a*b的值并非-1。结果具体是什么由当前机器上int所占位数而定。

  • 算数表达式中不要使用char或bool。因为char类型是否带符号由编译器决定。如果你确实需要一个不大的整数,明确指定他的类型是signed char或unsigned char。

1.2 算数类型字面量

整型字面量的类型

默认情况下,十进制字面量是带符号数,类型是能容纳其数值的int、long、long long中最小者。八进制和十六进制字面量的类型是能容纳其数值的int、unsigned int、long、unsigned long、long long、unsigned long long中的最小者。


整型字面量后缀

  • u或U:表示unsigned
  • l或L:表示至少是long
  • ll或LL:表示至少是long long
  • 无后缀:表示至少是int

浮点型字面量后缀

  • f或F:表示float
  • l或L:表示long double
  • 无后缀:表示double

字符型字面量前缀

  • u:表示Unicode 16字符,类型char16_t。例:u'a'
  • U:表示Unicode 32字符,类型char32_t。例:U'a'
  • L:表示宽字符,类型wchar_t。例:L'a'
  • 无前缀:类型char。

2. 指针和引用类型

2.1 引用类型

引用为对象起了一个别名。例:

int a = 1024;
int &refA = a; // 引用refA是对象a的别名

定义引用时,必须初始化,使引用与其初始值绑定到一起。
一旦初始化完成,引用将和它的初始值对象一直绑定在一起。


2.2 指针

int *p1, *p2;

int a = 45;
int *p = &a;

空指针: nullptr


void *指针

void *指针是一种特殊的指针类型,可以存放任意对象的地址。


多级指针

int **a;
int ***b;

指针的引用

int a = 45;
int *pa = &a;

int *&refPA = pa;  // refPA是对指针对象pa的引用。即:refPA是pa的别名。

2.3 const限定符

const限定符限制变量的值在初始化之后就不能改变。


2.3.1 定义const变量

const int a = 512;

小提示

默认状态下,const对象仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同的文件中分别定义了独立的变量。

如果需要在一个文件中定义const变量,而在其他多个文件中声明并使用它。可以在const变量的定义和声明都加上extern关键字:

// file1.cc 定义并初始化了一个const变量
extern const int bufSize = 45;

// file1.h 声明该const变量
extern const int bufSize;

2.3.2 const的引用

对常量的引用(reference to const)。例:

const int ci = 1024;
const int &refCI = ci;

const的引用也可以绑定到一个临时对象。所谓临时对象,就是当编译器需要一个空间来暂存表达式求实结果时,临时创建的一个未命名对象。例:

int a = 40;
const int &r1 = a*5; // 表达式a*5的结果作为一个临时量绑定到r1上。

double b = 1.25;
const int &r2 = b;  // 相当于:const int temp = b; const int &r2 = temp;

const的引用可以引用一个并非const的对象

const的引用仅对引用可参与的操作做出了限定,对于引用的对象本身是不是一个常量未作限定。

int i = 42;
int &r1 = i;
const int &r2 = i; // r2也绑定了i,但是不允许通过r2修改i。

2.3.3 const与指针

指向常量的指针

const int a = 45;
const int *cpa = &a;

指向常量的指针也没有规定其所指的对象必须是一个常量。所谓指向常量的指针仅仅导致不能通过该指针改变对象的值。例:

int a = 45;
const int *cpa = &a;

*cpa = 46;  // 错误
a = 46;     // 正确

const指针

指针本身是常量。例:

int a = 0;
int *const pa = &a;  // pa将一直指向a,不能变更地址,但可以通过pa修改对象的值。

const int b = 1;
const int *const pb = &b; // pb是一个指向常量对象的常量指针

2.3.4 顶层const和底层const

名词 顶层const 表示对象是个常量。
名词 底层const 表示指针所指的对象是一个常量。

举例:

int i = 0;
int *const p1 = &i;  // 这是一个顶层const,不能改变p1中的地址。
const int ci = 42;  // 这是一个顶层const,不能改变ci中的值。
const int *p2 = &ci; // 这是一个底层const,不能改变p2指向的对象的值,允许改变p2中的地址。
const int *const p3 = p2; // 右边的const是顶层const,它限定p3中的地址不可改变。靠左的const是顶层const,它限定不能修改p3指向的对象的值。
const int &r = ci;  // 用于声明引用的const都是底层const。

当执行对象的拷贝操作时,拷入和拷出的对象必须满足:具有相同的底层const,或底层非const转换为const。而顶层const并不是拷贝能否进行的条件。


3. 其他与类型有关的事情

3.1 定义类型别名

传统的方式(C风格的)

typedef double Width; // Width是double的同义词
typedef Width Abc, *p; // Abc是double的同义词,p是double *的同义词 

新标准引入的方式

using UI = UserInfo;    // UI是UserInfo的同义词

3.2 auto类型说明符

C++11引入了auto类型说明符,用它可以让编译器替我们去分析表达式所属的类型。

// 编译器根据a + b的结果的类型推断出item的类型
auto item = a + b;

关于auto有两点注意:

  • 若表达式的结果是引用类型,auto会去掉表达式结果类型中的引用。例:
    int i = 0;
    int &r = i;
    auto a = r; // a将会是int型,而不是int&型。
    
  • auto一般会去掉表达式结果类型中的顶层const,但底层const一定会保留下来。
    int i = 0;
    
    const int ci = i;
    const int &cr = ci;
    auto a = ci;    // a是int型(顶层const被丢弃)
    auto b = cr;    // b是int型(cr是ci的别名,而ci是const int型,顶层const将被丢弃)
    
    const int *cpi = &i;
    const int *const cpci = &i;
    auto c = &i;    // c是int*型
    auto d = cpi;    // d是const int*型(底层const被保留)
    auto e = cpci;   // e是const int*型(顶层const被丢弃, 底层const被保留)
    
    auto f = &ci;   // f是const int* (对常量对象取地址是一种底层const)
    

那么问题来了:

  • 如果希望推断出的auto类型含有引用,怎么搞? 方法是使用auto &:
    int i = 0;
    auto &g = i;  // g是int&
    
    const int ci = i;
    auto &h = ci;   // h是const int& (注意,此时的顶层const被保留了)
    
  • 如果希望推断出的auto类型是一个顶层const,怎么搞? 方法是使用const auto
    const int ci = i;
    const auto x = ci;  // x推断出来是const int类型
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空旅客er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值