C、C++指针

什么是指针?

  • 指针(pointer)是"指向(point to)"另外一种类型的复合类型。
  • 定义指针类型的方法:在变量类型后、变量名之前加 *,即可
  • 可以理解为 *属于类型的一部分!

获取对象的地址

  • 指针存放某个对象的地址,用取址操作符(&)获取地址
  • & 操作符还有其他作用,视上下文而定!
double dv;
double *pd0 = &dv;
double *pd1 = pd0;
int *pi = pd0; // 错误示例:指针pi的类型和pd的类型不匹配
pi = &dv;  // 错误示例:试图把double型对象的地址赋给int型指针

指针值

指针的值(即地址)有4种状态:

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

这里很多同学可能不是特别理解,指针指向对象,为啥指向相邻空间的位置?这个可以参考数组去理解,数组可以当作指针理解,数组名就是指针名并指向第一个数据,那 数组名+1...+n,就指向数组第n个数据!

  • 空指针,意味着指针没有指向任何对象
  • 无效指针

容易发现错误的情况就是拷贝或以其他方式访问无效指针,编译器不负责检查此类错误,访问无效指针的后果很严重!

通过指针如何访问对象

  • 指针指向了一个对象,则可以使用解引用符(*)来访问该对象
  • * 操作符还有其他作用,是视上下文而定!
  • 对指针解引用会得到所指的对象,如果给解引用的结果赋值,就是给指针所指的对象赋值
int iv = 8;
int *pi = &ivl;  //  pi 是指向变量 iv 的指针
cout << *pi ;  // *pi 得到指针pi指向的对象,输出 8

*pi = 80; // *pi 得到指针pi指向的对象,可由 *pi 为变量 iv 赋值
cout << *pi; // 输出 80
cout << iv; // 输出 80

什么是空指针

  • 空指针不指向任何对象,使用一个指针前可以先判空
  • 获取空指针最直接的方法就是使用字面值nullptr。
  • 直接把 int 变量赋值给指针是错误的操作
int *p1 = nullptr; // 创建空指针
int *p2 = 0; //错误:不能直接赋值!虽然不会提示语法错误,但是不能这么写!

赋值和指针

  • 问:赋值语句是改变了指针的值还是改变了指针所指对象的值?
    答:赋值语句永远改变的是等号左侧的对象的值
int iv1 = 1;
int iv2 = 2;
int *p = &iv1;
*p = iv2;  //改变的是 指针p 所指对象的值
p = &iv2; //指针p 被改变,指向 iv2 的地址

指针比较

可以用相等操作符(==)或者不相等操作符(!=)进行比较,比较结果是布尔类型的。如果两个指针存放的地址值相同,则其相等;反之,不相等

void* 指针

  • void是一种特殊的指针类型,可用于存放任意对象的地址。一个void 指针存放着一个地址,但是该地址中存放的是什么类型的对象并不透明。
  • void指针的功能有限:可以作为函数的输入或输出,或者赋给另外一个void指针;不能直接操作void*指针所指的对象。

指针的转换

  • 数组自动转换成指向数组首元素的指针
  • nullptr能转换成任意指针类型
  • 常量整数值0能转换成任意指针类型
  • 指向任意非常量的指针能转换成void*
  • 指向任意对象的指针能转换成 const void*

指向指针的指针

  • 一般来说,声明符中修饰符的个数没有限制,当有多个修饰符连写在一起时,按照其逻辑关系详加解释即可。
  • 指针是内存中的对象,有自己的地址,允许把指针的地址再存放到另一个指针中。
  • 通过*的个数可以区分指针的级别,即为 **表示指向指针的指针,***表示指向指针的指针的指针
  • 问:何时用到指向指针的指针?
    答:常用的一个场景:当一个函数接收一个指针A(地址A),函数内部只能修改这个指针A指向的对象,不能修改这个指针A指向地址B,如果我们想修改这个指针A指向地址B怎么办?就需要传递指针B(指针A的地址),这个时候我们就可以修改指针A的指向了,指针B就是指向指针的指针

指针和const

  • 常量指针,指向常量的指针(pointer to const)不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用常量指针。
const int dv = 2; // dv是常量,值不能改变
int *pd = &dv; // 错误:pd 是一个普通指针
const int *cpd = &dv; // 正确:cpd 可以指向一个常量

int dv2 = 3; 
cpd = &dv2 ; // 正确:但是不能通过cpd 改变 dv 的值 可以通过其他途径修改dval的值

  • const指针(指针常量)
    指针常量(const pointer)必须初始化,而且指针一旦初始化,指针的值(存放在指针中的地址)就不允许改变。
int i = 0;
int *const ptr = &i;

指针和数组

  • 指针和数组关系密切。
  • 使用取地址符&可以获取某个对象的指针,取地址符可以用于任何对象。
  • 数组的元素也是对象,对数组使用下标运算符得到该数组指定位置的元素。对数组的元素使用取地址符能得到指向该元素的指针。
  • 在用到数组名字的地方,很多时候编译器会自动地把数组替换为一个指向数组首元素的指针

数组名被解释为指向该数组的第一个元素的指针,但以下情况除外:
1.当作为sizeof运算符及typeid运算符的操作数时
2.当作为取地址符的操作数时 ("&数组名" 是指向数组整体的指针,而不是指向"指向第一个元素的指针"的指针。)
3.当使用decltype关键字时,返回的类型是数组而非指针。

  • 很多情况下使用数组类型的对象其实是使用一个指向该数组首元素的指针

指针允许递增递减

  • vector和string的迭代器支持的运算,数组的指针全部支持。
  • 允许使用递增、递减运算符将指向数组元素的指针向前移动到下一个、上一个位置,超过边界时不能解引用和递增(尾后指针)
  • 标准库函数begin和end
    尾后指针比较容易失误,非常危险,C++11引入了begin和end函数,这两个函数和容器中的两个同名成员函数功能类似,但是数组不是类类型,因此这两个函数不是成员函数。使用方法如下
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *beg = begin(ia); // 指向ia的首元素的指针
int *last = end(ia); // 指向ia尾元素的下一位置的指针
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容