学习笔记——指针那些事儿

指针概况

关于指针这一块儿,学起来容易迷,当然也是C语言的重点。下面详细说说指针的类。

指针是特殊的变量,相当于地址,指针里面存储的数据数值实际上就是内存地址。需要考虑四个方面:指针的类型,指针所指的类型,指针的值(地址),指针本身的地址(内存空间)

需要注意的是,指针的类型和指针所指的类型不一样,不可以混为一谈。比如:
int * p;
int *p();
int *p[4];
int (*p)[4];

等等,指针类型可以简单记为去掉指针名称,而指针所指的类型可以简单记为去掉指针名称和名称前面的 *。
比如上面的例子:(指针的类型)
int *
int *()
int * [ ]
int ( * )[ ]
而(指针所指的类型):
int
int ()
int [ ]
int ()[ ]

联动一下,提到变量要牢记四件事:变量名称、变量类型、变量值以及变量的内存空间。

指针形式

  1. int p; 表明p是一个int型变量
  2. int *p;p先和 *结合,是一个指针,再和int结合,返回的是int数据。表明p是一个返回int数据的指针
  3. int p[ ];p先和[]结合,是一个数组,再和int结合,返回的是int型数据,表明p是一个返回整型数据的数组
  4. int *p[ ];p与[ ]先结合,是一个数组,再与 * 结合,数组中的数据类型都是指针类型,再和int结合,数组中每一个指针指向的数据都是int型,表明p是一个由返回整型数据的指针所组成的一个数组
  5. int ( * p)[ ];p先和 * 结合,说明p是指针,再和[]结合,说明指针指向的内容是一个数组,( )只是为了提高优先级,可以省略分析,再和int结合说明数组里面全部都是int型数据。表明p是一个指向由int型数据组成的数组的指针
  6. int **p;二级指针。好像没怎么考,函数调用用的多。
#include <stdio.h>
int main(){
	int array[5];
	int *p = &array;//一级保存array[0]的地址
	int **pp = &p;//而二级保存p的地址,层层嵌套
	详细的下面讲
}
  1. int p(int,int);p先与( )结合,说明p是一个函数,里面有两个整型参数,再和int结合,说明函数返回的是int型数据。表明p是一个返回int型数据的函数
  2. int *p(int);p先和( )结合,说明是函数,函数里面有int参数,再和 * 结合 ,函数的返回类型是指针类型,再和int结合,说明指针指向的都是int型,表明p是一个指针型函数,是返回指向int型数据的指针的函数
  3. int (*p)(int);p先和 * 结合,说明p是指针,再和(int)结合,表明指针指向的内容是带有int参数的函数,再和最外边的 int 结合,说明返回int数据。表明p是一个指向返回int数据的函数的指针
  4. int *(*p(int))[3];p先和(int)结合,说明是带 int 参数的函数,再和 *结合说明函数返回的是指针类型,再和[ ]结合,说明指针指向的是一个数组,再和 * 结合,说明数组的每一项都是指针组成的,再和int结合,说明返回int型数据。表明p是一个指向由返回整型指针所组成的数组的指针

指针运算

  1. 指针通常可以加减运算,但是和普通的数值操作不一样,指针是通过地址的高位或者低位加减来运算的。比如:
#include <stfio.h>
int main(){
char arr[20];
char *P = arr;
p++;

这里就是p通过不断地+1,在地址中不断的向高位移动一位,来操作数组中的数据。

  1. 接下来看看这个不能操作的例子:
#include <stdio.h>
int main(){
char arr[] = "abcdefghijklmn";
char *p = arr;
char **pp = &p;
pp++;
printf("%c\n",**pp);
return 0;
}

这里有个比较容易错的点,就是pp++之后,p的地址向高位移动8位,那么printf打印的也就是*(&p+8),那么这个地址是不得而知的,有可能是内存中某个数据地址,总之不是我们指定的arr的地址。(关于这个8就是不同类型的大小而已,指针的通常是用8个字节表示一个地址,自己可以用sizeof一下)。

  1. &和*的运算。&是取地址符号, * 是取内容符号
#include <stdio.h> 
int main(){
int a = 10;
int *p = &a;
printf("%p",&a);//p是打印地址,&a是取出a的地址
//printf("%p",p);一样的效果。

printf("%d",*p);//p是一个指针,里面存储a的地址,*p是取出p所指向地址的值。
//int*p这里的*是表明p是一个指针变量,标识符号.表明指针变量,用来保存别人的地址
//*(&a)是读取内存地址的数据

return 0;
}

指针表达式

指针的表达式就是正常的指向操作,比如下面的几种写法:
char arr[20];
char *p;
char **pp;

p = arr; pp = &p; p++;这些都是指针的表达式
char * arr[20];
char ** parr=arr; 如果把arr 看作指针的话,arr 也是指针表达式
char * str;
str= * parr; * parr 是指针表达式
str= * (parr+2); *(parr+2)是指针表达式

指针、数组、函数

指针数组:强调数组,数组中的每个元素都是指针类型int * p[4]
[ ]比 * 优先级高,所以 p 先和[4]结合,形成 p[4] 数组形式,表明p数组中有4个元素再和 * 结合,表明这是指针类型的,每个数组元素都可以指向一个整型变量。写法:类型名 * 数组名[数组长度]

数组指针,强调指针,int (*p)[4] 、float (*pointer)[4]。指向数组的指针,可以跟函数指针一起记

指针函数:int * p 是指针变量,int * p 是变量,为int指针类型。二者表达的意思是相同的。

float (*func)(int param1, int param);
这是一个函数指针的例子,指向一个返回值为float,参数为两个int的函数
因此我们推断上面那个是指向float[4]的指针

float *pointer[4]
指针数组,相当于而二维数组

数组指针 int (*p)[3]
指针数组 int *p[3]
函数指针 int (*getData)(int a,int b)
指针函数 int *p(int x,int y)返回指针类型的参数
函数指针数组 int (*p[3])(int ,int);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石子君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值