一、什么是指针?

指针与迭代器一样,指针提供对其所指对象的间接访问,指针保存的是另一个对象的地址;

string s("hello");
string *ps = &s; //ps holds the address of s

二、指针的定义和初始化

1、两种声明指针变量的风格


string *ps1;
string* ps2;

理解指针声明语句时,请从右向左阅读:

从右向左阅读pstring变量的定义,可以看到:

string *pstring;

语句把pstring定义为一个指向string类型对象的指针变量。

2、避免使用未初始化的指针

int *pi; //ok, but dangerous,pi is uninitialized

三、指针初始化和赋值操作的约束

对指针进行初始化和赋值只能使用以下四种类型的值:

1. 0值常量表达式;

2. 类型匹配的对象的地址;

3. 另一对象之后的下一地址;

4. 同类型的另一个有效指针。

四、void* 类型的指针

void* 类型的指针可以保存任何类型对象的地址。

    double obj = 3.14;
double *pd = &obj; void* pv = &obj;
pv = pd;

五、指针操作

1、生成左值的解引用操作

(1)解引用操作符返回指定对象的左值,利用这个功能可修改指针所指对象的值;

(2)修改指针本身的值,使sp指向另一个新的对象;

    string s2 = "some new value";
sp = &s2;

2、指针和引用的比较

指针的和引用的相同点:

两者都可以间接访问另一个值;

指针和引用的重要区别:

(1)引用一经初始化,就始终指向某个特定对象,所以引用必须在定义时初始化;

(2)赋值行为的差异:给引用赋值修改的是该引用所关联的对象的值,而并不是使引用与另一个对象关联。引用相当于起别名。

3、使用指针访问数组元素

4、指针和const限定符

【指向const对象的指针】

【const指针】

1)指向const对象的指针

定义方式:

const double *cptr;

这里cptr是一个指向double类型const对象的指针,const限定了cptr所指向的对象类型,而并非cptr本身。也就是说cptr本身并不是const,所以,cptr在定义时,并不一定需要初始化。

【Warning】:

1、C++语言强制要求指向const对象的指针也必须具有const特性;

2、不能通过cptr修改所指对象的值;

*cptr = 42; //Error

3、把一个const对象的地址赋给一个指向普通的、非const对象的指针也会导致编译时的错误;

const double pi = 3.141592653589793 ;
double *pd = π //Error
const double *cptr = π //OK, cptr is a pointer to const

4、不能使用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址;

5、允许把非const对象的地址赋值给指向const对象的指针

    double dval = 3.14;
cptr = &dval; //ok, but can not change dval through cptr

但是,我们不能够保证指向const的指针所指对象的值一定不可修改。

2)const指针

int errNumb = 0;
int *const curErr = &errNumb; //curErr is a constant pointer

从右向左把上述定义读作“curErr是指向int 型对象的const 指针”

3、指向const对象的const指针

4、指针和typedef

在typedef中使用指针往往会带来意外的结果。

    typedef string *pstring;
const pstring cstr;

请问cstr变量是什么类型?

很多人都会认为真正的类型是:

const string *cstr;也就是说,const pstring是一种指针,指向string类型的const对象,

但是:这是错误的!!!

错误的原因:

将typedef当做文本拓展了。声明const pstring时,const修饰的是pstring的类型,这是一个指针。因此,该声明语句应该是把cstr定义为指向string类型对象的const指针,这个定义等价于:

//cstr is a const pointer to string
string *const cstr;

建议:

理解复杂的const类型的声明

阅读const声明语句产生的部分问题,源于const限定符既可以放在类型前也可以放在类型后:

string const s1;
const string s2; //s1 and s2 both strings that are const

用typedef写const类型定义时,const限定符加在类型名前面容易引起对所定义的真正类型的误解:

string s;
typedef string *pstring;
const pstring cstr1 = &s;
pstring const cstr2 = &s;
string *const cstr3 = &s;

把const放在类型pstring之后,然后从右向左阅读该声明语句就会非常清楚的知道cstr2是const pstring类型,即指向string对象的const指针。

C++ Primer 学习笔记_Chapter4 数组和指针–指针的更多相关文章

  1. C++ Primer学习笔记(二)

    题外话:一工作起来就没有大段的时间学习了,如何充分利用碎片时间是个好问题. 接  C++ Primer学习笔记(一)   27.与 vector 类型相比,数组的显著缺陷在于:数组的长度是固定的,无法 ...

  2. PHP学习笔记之数组篇

    摘要:其实PHP中的数组和JavaScript中的数组很相似,就是一系列键值对的集合.... 转载请注明来源:PHP学习笔记之数组篇   一.如何定义数组:在PHP中创建数组主要有两种方式,下面就让我 ...

  3. C++ Primer学习笔记(三) C++中函数是一种类型!!!

    C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...

  4. JavaScript学习笔记之数组(二)

    JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...

  5. C语言学习笔记之数组与指针的关系

    首先,大家先需知道一个关于基类型的概念 基类型:组成一个新类型的基础类型 这句话是什么意思呢?举个例子: int a[3] = {1,2,3}; 上面是由三个int类型的数组成一个新的类型也就是数组, ...

  6. go 学习笔记之数组还是切片都没什么不一样

    上篇文章中详细介绍了 Go 的基础语言,指出了 Go 和其他主流的编程语言的差异性,比较侧重于语法细节,相信只要稍加记忆就能轻松从已有的编程语言切换到 Go 语言的编程习惯中,尽管这种切换可能并不是特 ...

  7. Scala入门学习笔记三--数组使用

    前言 本篇主要讲Scala的Array.BufferArray.List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer 提 ...

  8. JavaScript学习笔记:数组reduce()和reduceRight()方法

    很多时候需要累加数组项的得到一个值(比如说求和).如果你碰到一个类似的问题,你想到的方法是什么呢?会不会和我一样,想到的就是使用for或while循环,对数组进行迭代,依次将他们的值加起来.比如: v ...

  9. [Golang学习笔记] 07 数组和切片

    01-06回顾: Go语言开发环境配置, 常用源码文件写法, 程序实体(尤其是变量)及其相关各种概念和编程技巧: 类型推断,变量重声明,可重名变量,类型推断,类型转换,别名类型和潜在类型 数组: 数组 ...

随机推荐

  1. 【Python学习一】使用Python+selenium实现第一个自动化测试脚本

    1.Python的下载 python官方下载地址:https://www.python.org/downloads/ 这边安装的3.6.5为最新版本以适应未来的需求 进入页面就有两个版本的下载选择,2 ...

  2. Git提交代码到主分区

    git 提交代码,本地新建一个my分支,不从本地master分支直接上传,而是先从本地my分支上提交至本地master分支,然后本地master提交至远程master分支 上.前提是远程只有一个mas ...

  3. C#入门--索引器

    C#入门--索引器 索引器允许类或结构的实例按照与数组相同的方式进行索引.索引器类似于属性,不同之处在于它们的访问器采用参数. 索引器概述 索引器使得对象可按照与数组相似的方法进行索引. get 访问 ...

  4. Akka探索第一个例子by fsharp 1

    如何构建一套分布式程序一直是我想知道的问题. Akka就是一套用来开发分布式系统的开发库.当然开发分布式系统只是它的能力之一.除此之外高度抽象的并行运算能力,轻量级的消息系统,容错能力都是该库的特点. ...

  5. .Net程序员学习Linux最简单的方法(转载)

    有很多关于Linux的书籍.博客.大多数都会比较“粗暴“的将一大堆的命令塞给读者,从而使很多.NET程序员望而却步.未入其门就路过了. 所以我设想用一种更为平滑的学习方式, 就是在学习命令时,先用纯语 ...

  6. JavaSE之Java基础(1)

    1.为什么重写equals还要重写hashcode 首先equals与hashcode间的关系是这样的: 1.如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相 ...

  7. poj 1741 两点距离小于K(树DP)

    http://blog.csdn.net/woshi250hua/article/details/7723400 求两点间距离小于等于k的方案数 理一下思路: 求通过点A与另一点连接符合条件的个数 = ...

  8. SublimeText插件cssrem : px转换为rem

    步骤: 下载插件: https://github.com/flashlizi/cssrem 安装插件: 打开:Sublime Text 点击: Preferences 选择: Browse Packa ...

  9. Linux 查看CPU、Memory等资源占用情况

    linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下获取占用 ...

  10. Bucking the stigma (留学生请摘掉有色眼镜看社区大学)

    Many Chinese students second-guess the benefits of attending a US community college. 很多中国学生对去美国社区大学学 ...