C++ -Pointer指针总结(一)

C++ -Pointer指针总结(一)


近来实习无聊,参照官方教程复习一下c++的内容,指针作为c++一个很重要的特性,涉及内容有点点绕,我尽量用自己能明白的话表达,有错误还望指正。

本文参考地址:cplusplus.com官方教程

Introduction

在c++中,变量声明之后会被存在内存中,可以通过变量名(the identifier)进行访问,这种情况下程序不需要考虑变量的物理地址。

对于一个C++程序来说,计算机的内存就像一连串的内存单元,每个单元的大小为一个字节,每个单元都有一个唯一的地址。这些单字节的内存单元的排序方式是允许大于1个字节的数据表示占据具有连续地址的内存单元。

对于每一个内存单元都有唯一的地址,并且连续的内存单元地址也是连续的。e.g. 地址为1776的内存单元在1775之后。

变量声明之后,在程序运行时,操作系统会给变量分配地址并存到相应的位置。在程序中,指针的使用是为了得到变量的地址。

Address of operator &

变量的地址可以通过这种方式获得

address = &a; //将变量a的地址赋值给address

假设myvar的地址为1776:

myvar = 25; 
foo = &myvar;
a = myvar;

img

注:foo和bar的物理地址是运行时随机分配的。

这里的foo变量就是指针

Dereference operator *

储存物理地址的变量为指针。*这个操作符可以被读作"value pointed to by".

接上面例子

baz = *foo; //read as "baz equal to value pointed to by foo"

baz为25。foo 的值为 1776,*foo为1776所指向的值。

img

总结:

myvar == 25
&myvar == 1776
foo == 1776
*foo == 25

指针的声明

在声明指针时,数据类型必须是这个指针指向变量的数据类型,即与指针本身值无关。例:

int* number;
char* character;
double* decimals;

这里可以将 int*看作一个数据类型,即整数的指针。一个栗子

#include <iostream>
using namespace std;

int main ()
{
  int firstvalue = 5, secondvalue = 15;
  int * p1,* p2;

  p1 = &firstvalue;  // p1 = address of firstvalue
  p2 = &secondvalue; // p2 = address of secondvalue
  *p1 = 10;          // value pointed to by p1 = 10
  *p2 = *p1;         // value pointed to by p2 = value pointed to by p1
  p1 = p2;           // p1 = p2 (value of pointer is copied)
  *p1 = 20;          // value pointed to by p1 = 20
  
  cout << "firstvalue is " << firstvalue << '\n';
  cout << "secondvalue is " << secondvalue << '\n';
  return 0;
}

注意两个指针同时声明 !int * p1, * p2;

指针和数组

数组的概念与指针有关,数组被隐形的转换为该数据类型的指针,工作原理是指向第一个元素的指针。与指针不同的是,数组不可以被赋值(即不能变成其他的地址),而指针可以。

栗子!

#include <iostream>
using namespace std;

int main ()
{
  int numbers[5];
  int * p;
  p = numbers;  	*p = 10;
  p++;  			*p = 20;
  p = &numbers[2];  *p = 30;
  p = numbers + 3;  *p = 40;
  p = numbers;  	*(p+4) = 50;
  for (int n=0; n<5; n++)
    cout << numbers[n] << ", ";
  return 0;
}

p从数组第一元素依次后移,5种不同的给数组元素的赋值方法

在关于数组的一章中,括号brackets([])被解释为指定数组元素的索引。那么,事实上,这些括号是一个被称为偏移(offset)操作符的引申(dereferencing)操作符。它们和*一样,对后面的变量进行去引号,但是它们也会把括号之间的数字加到被引号的地址上。例如:

a[5] = 0;
*(a+5) = 0;

这里的两种表达是一样的,不管a是数组还是指针都是相同的。如果a是数组,那么a这个名字就是指向第一个元素的指针。

数组的初始化 intialization

声明方式

int myvar;
int *myptr = &myvar; //可以在初始化就赋值地址
//==============================================
int myvar;
int * myptr;
myptr = &myvar;
//这两个例子是一样的。

在上面这个例子中 注意区分==myptr = &myvar*myptr = &myvar== (运行第二个,会报错,不能将int* 转化为int。即*myptr是int,&myvar是地址。

指针计算

不同数据类型指针的计算

char *mychar;
short *myshort;
long *mylong;

++mychar;
++myshort;
++mylong;

img

++,–和*之间的优先级关系

++和–运算符可以用作prefix /suffix。作为前缀,增量发生在表达式执行前,而作为后缀,增量发生在表达式执行后。这里涉及到一个优先级的关系 ++优先级>*

*p++就等同于*(p++)而它所做的是增加p的值(所以它现在指向下一个元素),但由于++被用作后缀,所以整个表达式的值被评价为原来的指针所指向的值(被增量前它所指向的地址)。

四种不同的组合

*p++   // same as *(p++): increment pointer, and dereference unincremented address
*++p   // same as *(++p): increment pointer, and dereference incremented address
++*p   // same as ++(*p): dereference pointer, and increment the value it points to
(*p)++ // dereference pointer, and post-increment the value it points to

另一个例子

*p++ = *q++;

因为++的优先级比* 高,所以p和q都是递增的,但因为这两个递增运算符(++)都是作为后缀,所以在p和q都递增之前,分配给 *p的值是 *q。然后两者都被递增。所以等同于

*p = *q;
++p;
++q;

所以!具体应用时,为了防止混淆加括号加括号加括号!

总结

本文总结了指针的定义和比较基础的用法,指针的更多内容还请翻阅我的博客文章,感谢阅读。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值