文档章节

【C++注意事项】4 指针 Pointers

NoMasp
 NoMasp
发布于 2015/09/08 21:48
字数 1644
阅读 0
收藏 0

和上一节的引用类似,指针(pointer)是“指向(point to)”另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的间接访问。然后指针和引用相比有许多不同。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。

指针的值(即地址)应属下列4种状态之一:

1)指向一个对象

2)指向紧邻对象所占空间的下一个位置

3)空指针,意味着指针没有指定任何对象

4)无效指针,也就是上述情况之外的其他值

试图拷贝或以其他方式访问无效指针的值都将引发错误。编译器并不负责检查此类错误,这一点和试图使用未经初始化的变量是一样的。访问无效指针的后果无法预计,因此程序员必须清楚任意给定的指针是否有效。因此解引用符也只适用于那些确实指向了某个对象的有效指针。

所谓的解引用符就是使用操作符*来访问指针指向的对象。

int ival= 42;
int *p= &ival;  // p存放着变量ival的地址,或者说p是指向变量ival的指针
cout<<*p;  // 由符号*得到指针p所指的对象,输出42
*p= 0;  // 由符号*得到指针p所指的对象,即可经由p为变量ival赋值
cout<<*p;  // 输出0

取地址符(&)和解引用符(*)的多重含义:

int i= 42;   
int &r= i;  // &紧随类型名出现,因此是声明的一部分,r是一个引用
int *p;  // *紧随类型名出现,因此是声明的一部分,p是一个指针
p= &i;  // &出现在表达式中,是一个取地址符
*p= i;  // *出现在表达式中,是一个解引用符
int &r2= *p;  // &是声明的一部分,*是一个解引用符

空指针(null pointer)不指向任何对象,在试图使用一个指针之前代码可以检查它是否为空。下面有3种生成空指针的方式:

// 需要首先#include cstdlib
inht *p1=NULL;

过去的程序会用到一个名为NULL的预处理变量(preprocessor variable)来给指针赋值,这个变量在头文件cstdlib中定义,它的值就是0。

int *p2= 0;

直接将p2初始化为字面常量0

int *p3= nullptr;

这是C++11新标准所引入的一种方法。

需要注意的是不能将int变量直接赋值给指针,即便int变量的值恰好等于0也不行。

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

但是不能直接操作void*指针,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。


English…


With two exceptions, which we will see at later, the types of the pointer and the object to which it points must match:

double dval;
double *pd= &dval;  // ok: initializer is the address of a double
double *pd2= pd;  // ok: initializer is a pointer to double
int *pi= pd;  // error: types of pi and pd differ
pi= &dval;  // error: assigning the address of a double to a pointer to int

The types must match because the type of the pointer is used to infer the type of the object to which the pointer points. If a pointer addressed an object of another type, operations performed on the underlying object would fail.

As with reference, we can define pointers that point to either const or not const types. Like a reference to const, a pointer to const may not be used to change the object to which the pointer points. We may store the address of a const object only in a pointer to const:

const double pi= 3.14;  // pi is const; its value may not be changed
double *ptr= &pi;  // error: ptr is a plain pointer
const double *cptr=&pi;  // ok: cptr may point to a double that is const
*cptr= 42;  // error: cannot assign to *cptr

The first exception is that we can use a pointer to const to point to a nonconst object:

double dval= 3.14;  // dval is a double; its value can be changed
cptr= &dval;  // ok: but can't change dval through cptr

Defining a pointer as a pointer to const affects only what we can do with the pointer. It is important to remenber that there is no guarantee that an object pointed to by a pointer to const won’t change.

It may be helpful to think of pointers and reference to const as pointers or references “that think they point to refer to const.”

const pointers

Unlike references, pointers are objects. Hence, as with any other object type, we can have a pointer that is itself const. Like any other const object, a const pointer must be initialized, and once initialized, its value(i.e., the address that it holds) may not be changed. We indicate that the pointer is const by putting the const after the *. This placement indicates that it is the pointer, not the pointed-to type, that is const:

int errNumb= 0;
int *const curErr= &errNumb;  // curErr will always point to errNumb
const double pi= 3.14159;
const double *const pip= &pi;  // pip is a const pointer to a cosnt object

The symbol closest to curErr is const, which means that curErr itself will be a const object. The type of that object is formed from the rest of the declarator. the next symbol in the declarator is *, which means that curErr is a const pointer. Finally, the base type of the declaration completes type of curErr, which is a const pointer to an object of type int. Similarly, pip is a const pointer to an object of type const double.

The fact that a pointer is itself const says nothing about whether we can use the pointer to change the underlying object. Whether we can change that object depends entirely on the type to which the pointer points. For example, pip is a const pointer to const. Neither the value of the object addressed by pip nor the address stored in pip can be changed. On the other hand, curErr addresses a plain, nonconst int. We can use curErr to change the value of errNumb:

*pip= 2.72;  // error: pip is a pointers to const
// if the object to which curErr points(i.e., errNumb) is nonzero
if(*curErr)
{
    errorHandler();
    *curErr= 0;  // ok: reset the value of the object to which curErr is bound
}

Note: “C++ Notes” series of blog mainly reference books of C++ Prime is the fifth edition of the Chinese version and English version. My English is very poor, and I don’t want there are some syntax error in blog. So the blogs have lots of words and sentences from the book. I wrote this series in order to consolidate the knowledge of C++, but also in order to improve my poor English. I also hope to help readers. Thank you.、



感谢您的访问,希望对您有所帮助。 欢迎大家关注、收藏以及评论。

我的更多博客文章:NoMasp博客导读


为使本文得到斧正和提问,转载请注明出处:
http://blog.csdn.net/nomasp


版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp

本文转载自:http://blog.csdn.net/nomasp/article/details/45890361

NoMasp
粉丝 7
博文 334
码字总数 0
作品 0
镇江
程序员
私信 提问
加载中

评论(0)

C++ 智能指针

智能指针(Smart Pointer),是一个来用存储指向动态分配(堆)对象指针的类。简单的说,它本身是一个类,这个类是用来存储对象指针。 一、智能指针的介绍 智能指针,就是具备指针功能同时提...

长平狐
2013/01/06
863
0
重读经典-《Effective C++》Item1:视C++为一个语言联邦

本博客(http://blog.csdn.net/livelylittlefish )贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正! C++已经是个多重范型编程语言(multiparadigm programming la...

晨曦之光
2012/03/09
83
0
C++的35个技巧阅读笔记(一)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/orangelittlegirl/article/details/98376501 文章目录 1.仔细区别指针...

su扬帆启航
2019/08/03
0
0
C++11 中委派 (Delegates) 的实现

介绍 在 C++ 中通过一个全局函数来绑定到对象的成员函数是很有用的,这个特性也存在于其他语言中,例如 C#的委派。在 C++ 中相当于成员函数指针,但是并没有提供相应的特性。在这篇文章中,我...

红薯
2012/05/15
6.8K
18
C++11 中委派 (Delegates) 的实现

介绍 在 C++ 中通过一个全局函数来绑定到对象的成员函数是很有用的,这个特性也存在于其他语言中,例如 C#的委派。在 C++ 中相当于成员函数指针,但是 并没有提供相应的特性。在这篇文章中,...

彭博
2012/11/27
748
2

没有更多内容

加载失败,请刷新页面

加载更多

0228 我的潘多拉

我的潘多拉 从一个故事说起。<br />从前,有个Java程序员非常喜欢写程序,喜欢研究源码,读英文文档。但是它在一家小公司里工作,公司的技术栈很陈旧。<br /> <br />单个系统代码中含有很多的...

李福春carter
今天
18
0
OSChina 周六乱弹 —— 屁会不会传染病毒

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《ハレハレヤ(朗朗晴天)》- 猫瑾 手机党少年们想听歌,请使劲儿戳(这里) @空格...

小小编辑
今天
63
1
两个值得注意的问题

对成员变量的操作只能放在方法中,方法可以对成员变量和方法体中自己定义的局部 变量进行操作.在定义类的成员变量时可以同时赋予初值,如 class A { int a=12; float b=12.56f; } 但是不可以这...

咔啡
今天
27
0
第三章 分布式服务框架的选择

1.大项目工程且多人维护的弊端 (1)项目团队协同成本高,业务响应越来越慢 (2)应用复杂度已超出人的认知负载(向杂乱的电线一样) (3)错误难于隔离(一个模块出错,整个系统挂掉) (4...

zxx901221
今天
68
0
eclipse 上传jar到远程仓库

使用maven的项目中,有时需要把本地的项目打成jar包上传到mevan仓库。 操作如下: 前提:pom文件中配置好远程库的地址,否则会报错 一、将maven 中的settings文件配置好用户名和密码,如下:...

文文1
昨天
63
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部