C语言指针总结

int [3];

int a=(*pfun)("abcdefg",7);

指针的算术运算

指针可以加上或者减去一个整数。

例1:

char a[20];int *ptr=a;ptr++;

指针 ptr 加1相当于 ptr 的值加上 sizeof。所以 ptr
指向的地址由原来的变量 a 的地址加上4个字节。由于 char
长度是一个字节,所以 ptr 指向的是 a
数组中从第四号元素开始的四个字节。

例2:

int array[20]={0};int *ptr=array;for(int i=0;i<20;i++){ ++; ptr++;}

这个例子中, ptr 指向的类型和数组元素的类型相同,循环中先是将 ptr
指向的元素加一然后将指针移向下一个元素,最后的效果就是依次将每个元素加一。

例3:

char a="helloworld";char *p=a;char **ptr=&p;ptr++;printf("%c",**ptr);

ptr的类型是一个 char **,指向的类型是 char * ,指针的值是 p
的地址,执行 ptr++ 的时候,指针的值会加上一个 sizeof 也就是4,而 *
是一个无意义的值。

总结:

一个指针 old 加一个整数 n 后,结果是一个新的指针 new
,指针的类型没有变化,指针指向的对象的类型也没有变化,newold
的值增加了 n 乘 sizeof个字节。

注意:

两个指针不能进行加法,这是非法操作,因为得到的是一个指向无意义的指针。两个指针可以进行减法,但是类型必须相同,常常用于数组。

ptr->a; //或者可以这们(*ptr).a,建议使用前者

一个普通的整型类型

C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身。

先看 p() 结合,说明 p
是一个函数而且有一个整型变量作为参数,最后与 int 结合。所以 p
是一个返回值为整型且有一个整型变量参数的函数。

int (*p)[3];
//首先从P处开始,先与*结合,说明P是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int
结合,说明数组里的元素是整型的.所以P是一个指向由整型数据组成的数组的指针

int ;

 

全面了解指针要从四个方面来看:

指针和指针进行加减:两个指针不能进行加法运算,这是非法操作;两个指针可以进行减法操作,但必须类型相同,一般用在数组方面。

指针本身所占据的内存区

指针本身占用的内存等于sizeof

ptr->c;

指针类型转换

小转大不安全。

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

先看 p* 结合,说明 p 是一个指针,然后再与 int
结合,说明指针指向的内容是整型类型。所以 p 是一个指向整型类型的指针。

 

先看 p() 结合,说明 p
是一个有一个整型变量作为参数的函数,然后再和 *
结合,说明函数的返回类型是一个指针,然后再和 []
结合,说明指针指向一个数组,然后再和 *
结合,说明数组的元素是指针,最后再和 int
结合,说明指针指向的类型是整型。所以 p
是一个有一个整型类型参数且返回类型是一个指向由整型类型指针组成的数组的指针的函数。

指针所指向的内存区:从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。(一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址)

int *p[3];

还是那句老话,重要的是实践,多写代码,才是学好C语言的关键。

总结:变量的类型由第一个相结合的符号决定

本文将从八个常见的方面来透视C语言中的指针,当然,还有其他没有具体提到的方面,像指针表达式、指针安全等问题,以后有机会我再慢慢补充。

  • 指针的类型
  • 指针指向的类型
  • 指针的值或者指针指向的内存区域
  • 指针本身占用的内存区

指针的类型:把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型

int *p;

第二 ,它是一个常量指针,该指针的类型是TYPE*,该指针指向的类型是
TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似
array++的表达式是错误的。

指针所指向的类型

把指针声明语句中的指针名字和名字左边的指针符号去掉,剩下的就是指针所指向的类型。

新京葡娱乐场网址,例子:

int *ptr; // intint **ptr; // int *int [3]; // int ()[3]

指针的算术运算中,指针所指向的类型有很大的作用。

指针的类型和指针所指向的类型完全是两个不同的概念。

pfun=fun;

int p;

指针所指向的类型:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型(在指针的算术运算中,指针所指向的类型有很大的作用)

先看 p[] 结合,说明 p 是一个数组,然后与 *
结合,说明数组中的元素的类型是指针,最后再与 int
结合,说明指针指向的内容的类型的整型。所以 p
是一个由指向整型数据的指针组成的数组。

这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE
*,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。要注意的是,原来的指针p的一切属性都没有被修改。

先看 p* 结合,说明 p 是一个指针,然后再与 []
结合,说明指针指向的内容是一个数组,最后和 int
结合,说明数组的元素是整型类型。所以 p
是一个指向由整型数据组成的数组的指针。

int p; //这是一个普通的整型变量

int *[3];

指针和整数进行加减:一个指针 ptrold加(减)一个整数
n后,结果是一个新的指针ptrnew,ptrnew 的类型和 ptrold 的类型相同,ptrnew
所指向的类型和 ptrold所指向的类型也相同,ptrnew的值将比 ptrold
的值增加(减少)了n乘sizeof(ptrold所指向的类型)个字节。

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


32位程序里所有类型的指针的值都是一个32位的整型,因为32位程序里的地址都是32位长。

指针所指向的内存区就是从指针的值所代表的内存地址开始,长度为 sizeof
的一片内存区。简单的说,就是指针其实是指向了一片内存空间,指针的值时该内存空间的首地址。

注意,指针所指向的内存区和指针所指向的类型是完全不同的概念,如果指针没有初始化,而指针所指向的类型已经确定,那么它所指向的内存区是不存在的或者是没有意义的。

第一,它代表整个数组,它的类型是 TYPE[n];

先看 p* 结合,说明 p 是一个指针,然后又和 *
结合,说明指针指向的元素还是一个指针,最后再与 int
结合,说明指向的类型的是整型。所以 p
是一个指向返回整型类型的指针的指针。平时最多也就会用到二级指针,更多级的指针极少使用。

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

先看 p* 结合,说明 p 是一个指针,然后和 ()
结合,说明指针指向一个有一个整型变量作为参数的函数,最后与 int
结合,说明函数的返回类型是整型。所以 p
是一个指向有一个整型变量作为参数且返回类型是整型的函数的指针。

6. 指针和结构类型的关系

指针是一个特殊的变量,里面存储的数值其实是内存中的一个地址。

&是取地址运算符,*是间接运算符。

int p[3];

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

指针的类型

把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。

例子:

int *ptr; // int *int **ptr; // int **int [3]; // int [3]

4. 运算符&和*

int **p;

1.指针类型分析

int p; 

同时定义结构体的结构对象并初始化,struct MyStructss={20,30,40};

先看 p[] 结合,说明 p 是一个数组,然后再与 int
结合,说明数组中元素的类型是整型。所以 p
是一个由整型类型元素组成的数组。

例中,定义了一个指向函数fun的指针pfun,把pfun作为函数的形参。把指针表达式作为实参,从而实现了对函数fun的调用。

 

当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式,这就要求两边的类型一致,所指向的类型也一致,如果不一致的话,需要进行强制类型转换。语法格式是:(TYPE
*)p;

3.指针的算术运算

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。