C++ 学习笔记(2)变量和基本类型(复合类型:引用、指针)、const、constexpr、typedef(using)、auto、decltype

C++ 学习笔记(2)变量和基本类型(复合类型:引用、指针)、const、constexpr、typedef(using)、auto、decltype

参考书籍:《C++ Primer 5th》


2.1 基本内置类型

2.1.1 算术类型

  • 类型char和类型signed char并不一样,类型char可能表现形式是带符号或无符号的,具体由编译器决定。所以最好不要直接用char作算术运算。

在这里插入图片描述

2.1.2 类型转换

  • 当赋给无符号类型一个超过表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。取模和取余的区别

2.1.3 字面值常量

  • short 类型没有字面值常量。负数的字面值,负号不在字面值内,只是对字面值取负值而已。
  • 字面值 ‘A’ 代表单独的字符,字符串 “A” 包含两个字符:‘A’和’\0’。

在这里插入图片描述

在这里插入图片描述


2.2 变量

2.2.1 变量定义

  • 列表初始化:下面四种方法都可以。同理可用于赋值。
int a = 0;
int a = {0};
int a{0};
int a(0);
  • 对于内置类型的变量,使用列表初始化且初始值存在丢失信息风险时,编译器会报错。
long double ld = 3.1415926;
int a{ ld }, b = { ld };	// 编译器报错:“错误 C2397 从“long double”转换到“int”需要收缩转换”
int c(ld), d = ld;			// 正确:但确实丢失了精度。
  • 定义于任何函数体制外的变量被初始化为0,如全局变量,类成员变量。静态变量除外。

2.2.3 标识符

  • C++为标准库保留了一些名字。 用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头。定义在函数体外的标识符不能以下划线开头。

2.3 复合类型

2.3.1 引用

  • 引用必须初始化:因为无法令引用重新绑定到另一个对象。
  • 引用类型的初始值必须为一个对象,常量引用可以绑定字面值。
  • 引用不是对象,没有实际地址,所以不能定义指向引用的指针。

2.3.2 指针

  • 指针的值(地址)应属于下面4种状态:

    • 指向一个对象。
    • 指向紧邻对象所占空间的下一个位置。
    • 空指针(nullptr或者0)。
    • 无效指针。
  • void* 指针:可以存放任意对象的地址。仅仅是存储空间,没办法访问内存空间所存的对象,因为不知道对象是什么类型(void)。

  • 指向指针的引用:指针是对象,所以存在对指针的引用

int i = 666;
int *p;			// p 是一个 int型指针
int *&r = p;		// r 是一个对指针 p 的引用

r = &i;			// r 引用了一个指针,因此给 r 赋值 &i 就是令 p 指向 i
*r = 233;		// 解引用 r 得到 i,也就是p指向的对象,将 i 的值改为233

2.4 const限定符

  • const对象一旦创建后其值就不能改变,所以const对象必须初始化。
  • 默认情况下,const对象仅在文件内有效(即使是全局变量)。想要在多个文件共享const对象,必须在变量定义前添加extern关键字。
  • const int a = 1;const int &a = 1;的区别:这里

2.4.1 const的引用

  • 称作对常量的引用。不能修改绑定的对象(对象可以不是常量)。
int a = 233;
const int &b = a;		// 正确:可以绑定普通int对象。

const int ci = 1024;
const int &r1 = ci;		// 正确:可以绑定常量。
r1 = 18;					// 错误:r1是对常量的引用。
int &r2 = ci;				// 错误:非常量引用不能指向常量引用。

const int d = 123;		// 正确:在编译时,所有用到d变量都会替换为对应值。(变成字面量,而非变量)
const int &d = 123;		// 正确:不过还是作为变量,会分配地址。

2.4.2 指针和const

  • 普通指针不能指向常量,需要用常量指针。
  • 指向常量的指针 和 const指针:(判断方法:从右往左看)
const double pi = 3.1415926;
const double *cptr = π		// 指向常量的指针。指针不是常量,指针可以更改,内容不能改。

int a = 0;
int *const b = &a;				// const指针。指针是常量,指针不能改,内容可以改。

const double *const pip = π	// 指向常量对象的常量指针。指针和内容都不能改。

2.4.3 顶层const 和 底层const

  • 顶层const:指针本身是常量。
  • 底层const:指针所指对象是常量。

2.4.4 constexpr 和 常量表达式

  • 常量表达式:不会改变且编译过程就能得到计算结果的表达式。(如字面量)
  • constexpr变量:告诉编译器这一定是个常量。要用常量表达式初始化:
constexpr int a = 20;
constexpr int b = a + 1;
constexpr int size = Size();			// 只有constexpr函数这样声明才正确。

constexpr int Size() { return 10; }		// constexpr函数。
  • constexpr指针的初始化必须是nullptr或者0,或者是存于某个固定地址的对象。即对于函数体内一般是存非固定地址的,所以不能指向这样的变量。
  • constexpr声明中如果定义了指针,限定符constexpr仅对指针有效,指针所指的对象无关:
const int *p = nullptr;		// p是指针,指向一个整形常量。
constexpr int *q = nullptr;	// p是常量指针,指向一个整形。

constexpr int i =123;
constexpr const int *p = &i;	// p是常量指针,指向一个整形常量。注意这个 i 不能在函数体内定义。

2.5 处理类型

2.5.1 类型别名(type alias)

  • 传统方法:
typedef double wages;	// wages是double的同义词。	
typedef wages base, *p;	// base是double的同义词。p是double*的同义词。
  • 别名声明:
using SI =Sales_item;		// SI是Sales_item的同义词。

2.5.2 auto 类型说明符

auto sz = 0 , pi = 3.14 	// 错误。sz和pi类型不一致。
  • auto一般会忽略掉顶层const,同时底层const则会保留下来
int i = 0;
const int ci = i, &cr = ci;
auto b = ci;		// b 是整数(ci 顶层const被忽略)
auto c = cr;		// c 是整数(cr 是 ci 别名,ci是顶层const)	
auto d = &i;		// d 是整形指针(指向i)
auto e = &ci;	// e 是指针,指向一个常量(对常量对象区地址是一种底层const)

const auto f = ci;		// f 是const int类型

auto &g = ci;		// g 是 ci 的引用

2.5.3 decltype 类型指示符

  • 用于选择并返回操作数的数据类型。
decltype(f()) sum = x;	// sum类型就是 f() 函数的返回值类型,f()不会被调用。
  • 1.decltype使用的表达式是变量时,返回该变量类型包括顶层const和引用在内)。
const int a = 0, &b = c;
decltype(a) x = 1;		// x 类型是 const int
decltype(b) y = 2;		// y 类型是 const int&
decltype(b) z;			// 错误:z类型是引用,必须初始化
  • 2.decltype使用的表达式不是变量时,返回表达式结果的类型
int i = 42, *p = &i, &r = i;
decltype(r + 2.3) b;		// 正确:b 是浮点类型。
decltype(*p) c;			// 错误:c 是 int&,必须初始化。这里*p是解引用,得到的是引用类型。而非int类型。
  • 如果给变量加上括号,编译器就会把它当成一个表达式。即上面1情况变到2情况。
decltype((i)) d;		// 错误:d 是 int& 类型,必须初始化。
decltype(i) e;		// 正确:e 是 int 类型。

  • auto 和 decltype的更多区别:这里
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值