深刻理解c++11基本类型

以前通过菜鸟教程自学了c++,自以为掌握c++所有基础知识和基本语法。今天偶尔翻下传说中的经典c++入门书籍《primer c++第五版 》。看到第二章才发现菜鸟还真是菜鸟,自己的基础是多么的脆弱不堪。
不说别的了,现在让我总结一下我之前没能彻底理解的c++基本类型,内置基本类型,类型转换,变量等基本概念这里不会详细讨论。

一、引用

引用的本质是为对象另外起一个名字。通过将声明符写成&d的形式来定义引用类型。
如下

int a = 102;
int &b = a;//b是a的引用

b = 2;//实际上b指向的对象被赋值,也就是 a = 2;
int c = b;//实际上是 c = a;
int &d = b;//实际上是 int &d = a;

定义引用时,程序会将引用和它的初始值绑定,而不是通过拷贝赋值。程序初始化后,无法令引用绑定别的对象,只能和之前的对象绑定。
所以引用必须初始化

int &b;//所以这种未给引用初始化的是错误的

引用本身不是对象,所以不能定义引用的引用

引用本身是给对象改名,所以对纯粹的数是不能使用引用的
如下是错误的

int &a = 10;//错误的,引用类型的初始值必须是对象

使用引用时要注意引用和被引用对象类型是否一致
如下

double a = 2.3;
int &b = a;//这是错误的,引用类型和被引用对象类型应一致

接下来是c系语言最强大也最令人难受的指针了

二、指针

指针和引用类似,但不同于引用,它是个对象,允许被赋值和拷贝,也不需要被初始化赋值

int *a;//指向整数类型的指针

指针存放的是对象的地址,所以以下写法很常见

int *a = &b;//a存放b的地址;或者说a是指向b的指针

和引用相似,指针和其指向的对象类型需一致

double *a;
double b;
int *c = &a;//错误
c = b;//错误
void* d = &a;//void*指针可以存放任意类型的指针

如何访问指针指向的对象,那就是用解引用符(*)

int a = 1024;
int *b = &a;
cout << *b;//输出的将是1024
*b = 0;//实际是为指针指向的对象赋值
cout << a;//输出为0
int *c;
c = b;//c,b都指向a

指针有一种不指向任何对象,那就是空指针。
如下

int *a = nullptr;

复合类型

int a = 1;
int *b = &a;
int **c = &b;//指向指针的指针

int *d;
int *&e = d;//指针的引用
e = &a;//引用了指针,实际上d指向a
*e = 0;//实际是 a = 0;

三、常量

const int a = 2;//用const限定的为常量
a = 5;//由于a是被const的常量,所以a无法

因为其值不能改变,const对象必须初始化

const int a;//这是错误的,没有初始化a

const对象仅在文件内有效,如果希望多个文件共享常量,需要声明,
如下

a.cpp文件初始化一个常量a,能被其他文件共享

extern const int a =44;

a.h文件,多个文件引入它,就能在多个文件共享常量a

extern const int a;//与a.cpp中定义的a是同一个

const的引用

引用可以绑定到常量上,但不能通过修改引用来改变常量

const int a = 1;
const int &b = a;//常量的引用也需要const来修饰
b = 4;//这是错误的,不能修改常量的引用
int &c = b;//这是错误的,常量的引用需要const修定

注意常量引用和普通引用的区别
如下

const int &a = 66;//这是正确的,这也是个常量引用
int &b = 10;//而这是错误的,原因之前已经阐述过

double c =83.3;
const int &d = c;//这是正确的,接下来会发生强制类型转换
int &e = c;//而这是错误的,原因之前已经阐述过

指针和常量

const int a = 1;
int *b = &a;//这是错误的
const int *c = &a;//常量的指针也需要const来修定
*c = 99;//这是错的

//const限定指针,只是不允许通过指针改变指针所指向的对象
int d = 4;
c = &d;//这是正确的,但不能通过c改变a的值

运行把指针定义为常量,常量指针必须被初始化

int a = 4;
int *const b = &a;//这样就不能改变指针的指向了
const int *const c = &a;//指针的指向和指针所指向对象的值都不能通过指针改变

顶层const

之前我们可以发现指针有2种,一种不能改变指针指向,但指针本身并不是常量,这就是顶层const;另一种不能改变指针指向常量的值,但指向可以改变,这种被称为底层const

int a = 233;
int *const b =&a;//不能改变b的值,这是个顶层const
const int c =44;//不能改变c的值,这是个顶层const
const int *d =&c;//运行改变d的值,这是个底层const
const int *const e =&d;//靠右的是顶层const,靠左的是底层const
const int &f =a;//常量引用都是底层const

d =e;//正确,指向类型相同,e顶层const部分不受影响,d,e都是底层const
d=&a;//int* 能转换成const int*

constexpr常量表达式

常量表达式是指值不会改变且在编译过程中得到计算结果的表达式
一个对象是不是常量表达式由它的数据类型和初值决定

const int a = 9;//a是常量表达式
const int b = a+1;//b是常量表达式

c++11标准规定允许将变量声明为constexpr类型以便编译器来验证变量值是否是一个常量表达式

constexpr int a = 9;//9是常量表达式
constexpr int b = a+1;//a+1是常量表达式

指针和constexpr

constexpr如果声明一个指针,constexpr只对指针有效,与指针指向常量无关

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

constexpr int i =99;//i的类型是整型常量
int j = 33;
constexpr const int *p1 =&i;//p1是常量指针,指向整型常量
constexpr int *q1 =&j;//q1是常量指针,指向整数j

四、类型别名

类型别名typedef能帮助程序员理解类型的真实目的。(可能我很菜吧,嫌弃,感觉程序更复杂了)

typedef double wages;//wages是double的同义词
typedef wages  base,*p;//base是double的同义词,p是double*的同义词
wages o;//等同double o;

注意

typedef char *patring;
const patring cstr =0;//cstr是指向char的常量指针
const char *cstr=0;//指向const char的指针,2者不一样

五、auto

auto类型说明符能让编译器替我们分析表达式所属的类型
使用auto时需要注意auto在一个语句能声明多个变量,但只能有一个基本数据类型

auto i =0,*p =&i;//i是整数,p是整型指针
auto a=0,b=9.3;//这是错误的,a,b类型需一致

auto会忽略顶层const,底层const会被保留下来

auto i =0,*p =&i;
const int c =i,&d =c;
auto e =c;//e是个整数,顶层const被忽略
auto f =d;//f是个整数,d是c的别名,c是个顶层const
auto g =&i;//g是个整型指针
auto h =&c;//h是个指向整型常量的指针

//如果希望推断出的const是个顶层const,需要明确指出
const auto m =c;

六、decltype

作用是选择返回操作数的数据类型

decltype(f()) sum = x;//sum的类型是f的返回类型
const int a =0,&b =a;
decltype(a) c=0;//const int c =0;
decltypee(b) d =c;//const int &d =c;
decltype(b) e;//错误,引用需要初始化

使用decltype时,如果在变量多加上一层括号,会有所不同

int a =33;
decltype((a)) b//int &b;需要初始化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值