指针总结

1 引言

最近在上数据结构课时,老师让复习一下指针的应用。然后就百度了很多指针的知识,特地汇总了一下。当然本文不是我原创,而上借鉴了很多人的一些总结。在此表示衷心感谢。

2 什么是指针?

指针就是一种变量类型。它的大小依机器而定,在32位机上一般是4个字节。指针变量中存储的值是一个内存地址。

2.1 常见指针

分析指针,可以从变量名处起,根据运算符优先级结合,一步一步分析.
int p; //这是一个普通的整型变量。
int *p; //首先从P处开始,先与*结合,所以说明P是一个指针,然后再与int结合,说明指针所指向的内容的类型为int 型.所以 P是一个返回整型数据的指针。
int p[3]; //首先从P处开始,先与[]结合,说明P 是一个数组,然后与int结合,说明数组里的元素是整型的,所以 P是一个由整型数据组成的数组。
int *p[3]; //首先从P处开始,先与[]结合,因为其优先级比高,所以P是一个数组,然后再与结合,说明数组里的元素是指针类型,然后再与 int结合,说明指针所指向的内容的类型是整型的,所以P是一个由返回整型数据的指针所组成的数组。
int (*p)[3]; //首先从P处开始,先与*结合,说明P是一个指针然后再与[]结合(与”()”这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P是一个指向由整型数据组成的数组的指针。
int **p; //首先从 P开始,先与结合,说明P是一个指针,然后再与结合,说明指针所指向的元素是指针,然后再与 int结合,说明该指针所指向的元素是整型数据. 所以P是一个返回指向整型数据的指针的指针。
int p(int); //从P处起,先与()结合,说明P是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数然后再与外面的int 结合,说明函数的返回值是一个整型数据.所以P是一个有整型参数且返回类型为整型的函数。
int (*p)(int); //从P处开始,先与指针结合,说明P是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P是一个指向有一个整型参数且返回类型为整型的函数的指针。
int *(*p(int))[3]; //从 P开始,先与()结合,说明P是一个函数,然后进入()里面,与int结合,说明函数有一个整型变量参数,然后再与外面的结合,说明函数返回的是一个指针,,然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组,然后再与结合,说明数组里的元素是指针,然后再与int 结合,说明指针指向的内容是整型数据.所以P是一个参数为一个整数且返回一个指向由整型指针变量组成的数组的指针变量的函数。

2.2 细说指针

一个指针包括以下4个方面:指针类型、指针指向数据类型、指针指向的内存区、指针在内存中占空间大小。
例如:int *ptr;
char *ptr;
int **ptr;
int (*ptr)[3];
int *(*ptr)[3];

指针类型: 去掉变量名,所剩就是指针类型,指针类型为 int *,char*,int **, int (*)[3],int *(*)[3];
指针所指数据类型: 去掉变量名及名字左边的 *, int,char,int *,int() [3],int*()[3] 即为指针指向数据的类型;
指针指向的内存区:指针指向数据类型为多大,那么指针指向的内存区大小就为多少。
指针在内存中所占空间大小:在 32位的系统上, 指针在内存中始终是一个占了4个字节的数据类型。指针本身占据的内存这个概念在判断一个指针表达式是否是左值是很有用。(C/C++中的表达式分为两种:1) 左值:可以出现在赋值语句的左边或右边。左值表达式指向一个存在于内存中的对象,我们可以对这个对象进行读写操作。2) 右值:只能出现在赋值的右边。右值表达式返回对象进行运算后的值。简单的说,左值相当于地址值,右值相当于数据值。变量是左值,常量和表达式是右值。
)

2.3 指针的操作

一个指针p加减一个整数N后,结果是一个新指针pnew,两者的类型相同,只是新指针的值比旧指针的值加减了N*sizeof(p所指向的类型)个字节。
两个指针不能相加,无意义,非法操作。但是两个指针可以进行相减,主要应用于数组操作。
&是取地址运算符,*是间接运算符。&a的运算结果是一个指针,指针的类型是a的类型加个*,指针所指向的类型是a的类型。指针所指向的地址就是a的地址。*p的运算结果比较多。

2.4 指针表达式

一个表达式的结果是指针,那么这个表达式就是指针表达式。一样具有指针的四要素。

2.5 指针与数组

数组是内存中一段连续的地址空间,数组名表示这段空间的首地址。可以认为数组名是一个常量的地址值,因此它是不可以做左值的,但可以做右值。
在算术操作上,数组名与指针有着相似之处,可以做与整数的加减操作,下标操作,解引用操作,但不能做自增自减操作与赋值操作。
数组名不是指针,因为它不是变量,而是一个常量,其值等于数组首项的地址。在C/C++中我们可以改变一个变量中存储的值,但不能改变这个变量所在的内存地址。因为数组名是地址常量,所以我们可以把数组名赋值给同类型的指针,就相当于把一个整数常量赋值给int型变量一样。
在将数组名当作参数传递给函数时,函数需要用一个指针型变量来接收这个参数,此时即使将这个变量写成指针形式,它代表的也不再是数组,而是一个指针变量了。
将数组名当作sizeof的参数时,返回的是整个数组占用的内存空间字节数,而将指针当作sizeof(*数组名)的参数时,返回的是指针本身占用的内存空间数,一般为4。

2.6 指针类型转换

当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式,这就要求两边的类型一致,所指向的类型也一致,如果不一致的话,需要进行强制类型转换。语法格式是:(TYPE *)p;
这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE *,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。要注意的是,原来的指针p的一切属性都没有被修改。
另外,一个函数如果使用了指针作为形参, 那么在函数调用语句的实参和形参的结合过程中,也必须保证类型一致 ,否则需要强制转换。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值