c指针是个啥

常见指针的类型

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 结合,说明该指针所指向的元素是整型数据。

int p(int); //从P 处起,先与()结合,说明P 是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数,然后再与外面的int 结合,说明函数的返回值是一个整型数据

Int (*p)(int); //从P 处开始,先与指针结合,说明P 是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P 是一个指向有一个整型参数且返回类型为整型的函数的指针

int *(*p(int))[3]; //从P 开始,先与()结合,说明P 是一个函数,然后进入()里面,与int 结合,说明函数有一个整型变量参数,然后再与外面的*结合,说明函数返回的是一个指针,然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组,然后再与*结合,说明数组里的元素是指针,然后再与int 结合,说明指针指向的内容是整型数据,所以P 是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数.

指针是啥

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。

指针所指向的类型(指针的类型)

当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

不管是什么类型的指针变量,所存的值都是地址(int类型的值)。那么声明不同类型的作用是什么?答案是规定指针在内存中每次移动的字节数。(结合下面的算数运算理解)

例如定义“int *pa = &a”,取值时,int类型占4个字节,指针就从首地址开始移动,读取4个字节。同理,short类型占2字节,指针就移动2字节。通过声明指针类型,告诉指针每次移动多少字节,来获取变量的值。

从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

在近乎所有使用到数组名的表达式中,数组名都表示数组第一个元素的地址,可将其看作是一个指针常量。而这个指针常量所指向的类型与数组元素的类型一致

 (1)int* ptr;                  //指针所指向的类型是int,ptr+1,指针一次移动4字节
 (2)char* ptr;                //指针所指向的的类型是char ,ptr+1,指针一次移动1字节
 (3)int** ptr;                //指针所指向的的类型是int* ,ptr+1,指针一次移动4字节(因为所有的指针都是int来存放的),*ptr+1 指针一次移动4字节(因为*ptr指向的是int类型的数据)
 (4)int *ptr[3];              //这是一个数组而不是指针。但数组名可以作为指针,所以讨论一下,
    ptr;                      //返回一个指向第一个元素(是个指针)的指针
    ptr+1;                    //返回一个指向第二个元素(是个指针)的指针
    ptr[1];                  //访问数组中的第2个元素。这个元素是个指针
    *(ptr+1);                //与 arr[1] 作用相同。
    *ptr+1 ;               //*的优先级高于+,表示第一个元素(是个指针)的值+1。相当于该指针移动4字节
 (5)int (*ptr)[3];           //指针所指向的的类型是int [3] ,ptr+1,指针一次移动3*4字节(因为数组元素是int),*ptr+1 表示ptr指向的数组的第一个元素的值+1
 //
 (6)int *(*ptr)[3];          //这是一个(指向(指向(一个数组)的)指针的)指针。即一个指向上面语句5代表的指针的指针
 //指针所指向的的类型是int*[3] ,ptr+1,指针一次移动4字节(因为它指向的是一个指针,每个指针都是int,4字节),*ptr+1 表示数组的第二个元素的的地址,*(*ptr+1 )表示数组的第二个元素的值,(*ptr)+1 代表一次移动3*4字节

----------二更分割线------------

int *(*ptr)[3]; 我似乎搞错了, 他是一个指向Array[3]数组的指针,数组类型是 int*。式中()去掉又是什么意思呢? 去掉是一个数组(有三个元素),元素是 int**;

指针所指向的的类型是int*[3] ,ptr+1,指针一次移动3*4字节(因为它指向的是一个数组,每个元素都是指针,每个指针都是int,4字节),ptr+1 表示数组的第一个元素的值加一(也就是一个指针+1,是指针的运算,代表该指针(第一个元素)指向的地址移动4个字节),(ptr+1) 代表一次移动3 *4字节,取ptr+1地址处的值, * (*ptr+1 )表示第一个指针(第一个元素)指向的地址移动4个字节里面的内容,

int (*(*ptr))[3]; ,这个是一个(指向(指向(一个数组)的)指针的)指针。即一个指向上面语句5代表的指针的指针。指针所指向的的类型是int(*)[3] ,ptr+1,指针一次移动4字节(因为它指向的是一个指针,每个指针都是int,4字节),ptr+1 表示数组的第二个元素的的地址,(*ptr+1 )表示数组的第二个元素的值,(ptr)+1 代表一次移动34字节

指针的值----或者叫指针所指向的内存区或地址

指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32 位程序里,所有类型的指针的值都是一个32 位整数,因为32 位程序里内存地址全都是32 位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX 为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。

指针本身会占据内存区

指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32 位平台里,指针本身占据了4 个字节的长度。指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。

指针的算术运算

一个指针ptrold 加(减)一个整数n 后,结果是一个新的指针ptrnew,ptrnew 的类型和ptrold 的类型相同,ptrnew 所指向的类型和ptrold所指向的类型也相同。ptrnew 的值将比ptrold 的值增加(减少)了n 乘sizeof(ptrold 所指向的类型)个字节。就是说,ptrnew 所指向的内存区将比ptrold 所指向的内存区向高(低)地址方向移动了n 乘sizeof(ptrold 所指向的类型)个字节。指针和指针进行加减:两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,而且毫无意义。两个指针可以进行减法操作,但必须类型相同,一般用在数组方面,不多说了。

发布了78 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43657442/article/details/103712054