9_1、C++:指针介绍


内存地址访问:一个字节由8个二进制位组成。每个字节都会按照一定的规则编号,这个编号就是该字节存储单元的地址。计算机就是利用这种编号也就是字节存储单元的地址来定位内存进行数据读写的。访问内存数据有两种形式:

  1. 通过变量名;
  2. 通过地址。
    char型占1个字节,float型占4个字节。而内存空间的分配是在什么时候呢?全局变量、static静态变量等静态生存期变量在程序开始运行之前就被分配了内存空间,动态生存期的变量是在变量声明时分配内存空间的,然后变量名也代表了分配的空间。
    C++中的指针类型就是用来存放上面讲的内存单元地址的变量类型。

指针变量的声明

指针跟int等一样也是一种数据类型,指针类型的变量就是指针变量,指针变量存放的是内存单元的地址。指针同样是先声明再使用,声明的形式是:

数据类型 *标识符;
  • ‘ * ’它表示声明的是一个指针变量。“*”前面的“数据类型”表示的是指针所指向的变量或对象的类型,可以是任意类型,也就是说在声明的该指针所指向的内存单元中可以存放此数据类型的数据。而指针本身在32位系统上是unsigned long类型的,在64位系统上是unsigned _int64类型的,

地址运算符*和&

  1. “ * ”在地址运算中叫做指针运算符,表示指针指向的变量的值,是一元操作符,例如,如果p是一个int型的指针,则*p表示p指向的int型数据的值。
  2. “&”在地址运算中叫做取地址运算符,也是一个一元操作符,用来获取一个对象的地址,例如,有一个变量i,&i就表示变量i的存储单元地址。

NOTE:“”和“&”出现在声明语句中和在执行语句中意义是不一样的。*
3. “ * ”出现在声明语句中被声明的变量名之前时,表示声明的是指针,例如,int *p;。“ * ”出现在声明语句的初值表达式中或者执行语句中时,表示指针指向的对象的内容,例如,int i=*p; cout<<*p;。“
4. “&”出现在声明语句中被声明的变量名之前时,表示声明的是引用,例如,int &rf;。“&”出现在声明语句的初值表达式中或者执行语句中时,表示取对象的地址.

指针的赋值

当我们声明了一个指针之后,这个指针变量中没有存储任何确定的地址值,而是一个随机整数。也就是它指向的地址是不确定的,有可能它指向了系统的重要数据,这时候我们如果修改了它指向地址的值可能会引起想象不到的系统问题。所以指针声明以后要先赋值才可以引用。
指针变量赋值也有两种方式:

  1. 在声明指针时对其进行初始化,也就是赋一个初值,初始化形式为:数据类型 *指针名=初始地址值;。
  2. 在声明指针后,单独给它赋值,赋值的语法形式为:指针名=地址;。

可以将一个已经赋值的指针赋值给另一个指针,让多个指针指向相同的变量。

int a[5];         // 声明一个整型数组
int *p1=a;     // 声明指针p1,并用数组首地址a来初始化p1
int *p2;         // 声明指针p2
p2=a;           // 将数组首地址a赋值给指针p2
  • 数组名就是数组的首地址,所以它可以用来给指针赋值。

空指针应用:
赋给指针变量的值必须是地址常量(比如数组名)或地址变量,但一定不能是非0整数。给指针赋值为0时表示该指针是一个空指针,它不指向任何地址,比如,int *p=0;。为什么会把指针声明为空指针呢?大家想想,我们在声明一个指针时没有给它赋值,这时它是一个随机的值,在给它赋确定的地址值之前如果我们使用了它,就可能会访问到重要的内存地址并破坏此地址的数据,造成严重后果,所以我们在软件开发中一般先将指针设为空指针。

需要注意的问题:

  1. 我们可以声明指向常量的指针,这时候指针本身的值可以改变,也就是指针可以指向其他对象,但是我们不能通过指针改变它指向的值。
const char *name="Tom"; //指向常量的指针
char s[]="Lili";
name=s;                               //正确,name本身的值可以改变
*name=’a’;                           //编译时指出错误,不能通过name修改指向的对象
  1. 可以声明指针常量,这时候指针本身的值不能改变。
int a=1;
int b=2;
int *const p=&a;    // 声明指针常量p
p=&b;               // 错误,不能改变指针常量p的值
  1. 进行指针赋值时可以将某个指针的值赋给相同类型的另一个指针。但是有一种特殊类型的指针,可以用任意类型对象的地址为之赋值,这就是void类型指针。我们在使用void类型的指针访问数据时需要进行强制类型转换。
 void *p;
int *p1;
int a;
void main()
{
    p=&a;         // void类型的指针p指向整型变量a
   p1=(int*)p;   // 用强制类型转换的方式将void指针p的指针赋给int型指针p1
}

指针运算

指针也是一种数据类型,也可以参与一些运算。指针能够进行的运算有赋值运算、算术运算和关系运算。

  1. 指针可以和整数进行加减运算,但是跟一般的加减运算不同,指针的加减运算跟指针的类型密切相关,例如,char型指针p和整数3,p+3表示p所指地址后面第3个字符的地址,p-3就表示p所指地址前面第3个字符的地址。给大家一个更直接的例子,有整型数组int a[5],p指向数组首地址a,则a+3表示首地址后第3个整数的地址,即a[3]。
    “指针++”和“指针–”表示指针所指地址的下一个或前一个数据的地址。

指针的算术运算一般都是在操作数组的时候进行,因为只有声明数组才可以得到连续的内存空间。如果我们对一个单独的变量地址进行加或减的算术运算,然后改变新地址的值,则可能会破坏该地址的数据,所以在对指针进行算术运算时要明确运算的结果是程序中分配可用的地址。

  1. 指针的关系运算说的是相同类型的指针之间的关系运算。不同类型的指针之间的关系运算没有任何意义,指针和非0整数的关系运算也没有任何意义,但是指针可以和0进行关系运算.
  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值