锻炼吃饭的家伙计算机杂谈互联网科技

【计算机本科补全计划】《C++ Primer》指针和const限

2017-10-06  本文已影响614人  张照博
感觉最近增粉降速了。只能放我“新垣结衣”出来吸睛了。

正文之前

今天下午看了一下午的计算机组成与设计,结果好死不死的看到了设计部分--处理器的设计。天哪,我现在还只是一个准备给人装一台电脑做实验田的家伙,连用都不咋会,你还叫我设计!!!虽然我学过数电模电和电路原理,也学过单片机组成和应用,但是不代表我对这些逻辑元件感兴趣啊!!!所以很果断的,我到了晚饭时节就果断的抛弃了第四章跳到第五章--存储层次和并发设计,这才有了点重新活下去的勇气。然后晚间继续看神书--《C++ Primer 第五版》,这里面的只是真的是看得我如痴如醉,配合不少在计算机组成里面看到的原理知识,每天收获最大的就这会时候了!下面是今天的读书笔记,感觉很多都是各大公司招收IT人才的笔试题的选择题类!!

正文

1、 承接上一节的引用讲起
2、 指针的定义的时候,书上有一种说法,如下:
int vdal;
int *pd=&vdal;   // 正确:初始值是int型变量的地址
int *pd1=vdal;    // 正确: 初始值是指向int对象的指针

对于第三行那个说法我是始终存疑的,因为在我的电脑上跑的时候是没法运行的,直接就报错了,所以大家定义指针的时候,还是直接按照第二行那个定义的方法吧,也许是第三行那种玩法太高端,反正现在我的编译器是跑不出来的~ ~

报错咯

另外声明指针的时候指针类型和指向的对象的类型要一致,不然很容易出错,比如下面的代码:

double dval;
int *pd=&dval;   // Error:int类型的指针不能指向一个double双精度浮点数的对象!!

不过有时候也是有特例的,后面容我慢慢介绍。

3、 指针的值

四种状态:

试图拷贝或者以其他方式访问无效指针的值都会引发错误。访问的后果无法预计。

4、利用指针访问对象

如果是指向一个变量,那么直接用*p就可以访问,如果指向一个结构体,那么形式有两种:

Struct *Item;
*Item.name="ZZB";
item->name="ZZB";

上面第二行第三行的含义是一样的。第一行是定义一个结构体,结构体内部有一个变量时name,所以如果要访问name的话。两种方式完全相同。
解引用(*)操作仅仅适用于指向了对象的有效指针。
下面几个很有意思,很容易混淆的定义或者是声明方法。我们一起来探讨一下:

int i=42;  //这就是个定义
int &r=i;   // 这就是个引用
int *p;     // 定义一个指针,你看,不一定要初始化对吧
p=&i;      // 给p这个指针对象复赋值 内容是i的地址
*p=i;       // 这个跟上面是一个意思。就是说i赋给解引用后的p指针,等同于把i的地址给p;
int &r2=*p;    // 这一句才是最骚气的,解读的顺序是:p指针解引用后被r2引用

上面透漏出来了一个计算机领域的常识:读一段代码,从右读到左边,按照优先级自己排列。

5、 空指针

空指针不指向任何对象,以下是生成空指针的几个办法:

int *p1=nullptr;
int *p2=0;
#incluede <cstdlib>  int *p3=NULL;

以上三种空指针的定义方法完全等效,最直接的是第一种。在我们编程的过程中,如果实在不知道指针指向何处,那么上面三种任选其一,欢迎选购!

6、 void * 指针

void* 是一种特殊的指针,可以存放任何类型的地址,也就是说你复制的时候随便放一种都可以,相当于搬运车,来者不拒。但是我们也没法通过这个指针查询到任何它所指向的对象的内容,因为你不确定指向的对象是什么类型,那么也就没法准备相对应的类型的寄存器来存放取出来的对象值。

int p=23;
double q=1.2;
void *a=&p;
a=&q;

上面的所有代码都不会报错,因为void指针就是这么溜,可以接受任何形式的对象传递指针给它,但是也就是因为这么6,所以不管你的对象再简单,void也没法调用,从void指针的角度来说,地址就只是指向了一个内存空间,至于里面是啥,我不管,我只是记着这个地址。


所以如果要强制转换一个对象的类型的话,可以尝试用void * 指向。然后调用的时候强制转换指针类型、不知道行不行,待会测试下下面的代码就好了:

int a=12;
void *p=&a;
cout<<(double)*p<<endl;
报错了。。心疼
7、 那些年定义指针踩的坑:
int* p;
int *p;

其实呢,根本没啥不用,只是让你看着很警惕而已。实际上没有任何的不同,只是第一种写法容易让人误会。

int *p1,*p2;
int* q1,q2;

然而,现实往往残酷,第一行是定义了两个指针,但是很不幸的第二行是一个指针,一个整形数 ,至于谁是谁,我咋知道,自己猜?!!

8、 指向指针的引用

请客官查看下面代码:

int i = 42 ;  
int *p ;   
int *&r=p;  
r=&i;   
*r=0;  
9、 const限定符
int  i = 42;
const int j=i;
int k=j;   //Right!!
j=100  //Error!!

很明显的,第三行是代表我可以取出const常量的值,但是第四行就好死不死的妄想去修改常量,这是大大的不对的!

10、 默认状态下,const仅仅在文件内有效

如果想要跑到别的文件里面去:

11、 对const的引用
int i=42;
const int &r1=i; 

允许把一个常量引用绑定在一个非常量上,但是因为引用本身不是一个对象,所以我们没法通过r1引用限制i是非常量这个事实!

const int &r2=42;

可以的,是一个常量引用!此处42是常量,对常量必须要定义引用也是“常量引用”

const int &r3=r1*2 ;

没问题,r1本身也是常量,定义常量引用绑定一个常量这是理所当然的!

int &r4=r1*2;   

Error: 不行!!r4这个引用不是常量引用,意味着外界可以改变通过改变r4来改变它绑定的对象,但是你想绑定常量?做梦!报错!!!

12、 指针和const

指针是对象,引用不是,所以允许定义指针本身是一个常量而不是常量引用。所以
!!常指针必须初始化,必须给出一个地址赋给常指针对象。不变的是指针本身的值,而不是指针所指向的那个值

int numb=0;
int *const err=&numb;
const double pi=3.14;
const double *const pip=&pi

那么我们的如下操作都是合法的:

*err=100;
cout<<numb<<endl;  //output:100而不是0;
cout<<*pip<<endl;  //output:3.14
cout<<pi<<endl;  //output:3.14 

所以啊,总结下里,const就是一个傲娇属性爆棚的家伙!自己是完全不能改变的,一旦有这个趋势,立马拉整个程序下水,报错!!如果自己指向别人,不管对方是不是常量,但是如果别人引用自己,那么就要求对方一定要是常量!!如果是用指针指向常量,那么就要求无法用指针修改,只能引用,至于你指针自己变不变,无所谓,反正你不能通过指针修改我!虽然这东西傲娇的不行!不过,我怎么这么喜欢这玩意呢???

正文之后

要睡了,今晚有点浪,明天继续看书,不过晚上想看看《羞羞的铁拳》 不知道是不是跟别人说的那样笑点十足,再改改睡觉!

上一篇 下一篇

猜你喜欢

热点阅读