C语言中,很多个和我自己感觉都是指针是最难的一点,也是C语言的精华所在。
指针所指的类型很多种,按指针类型来分类则有:
int p; //这是一个普通的整型变量
int *p; //首先从p处开始,先与*结合,所以说明p是一个指针,然后再与int结合,说明指针所指向的内容的类型为int 型.所以p是一个返回整型数据的指针。
int p[3]; //首先从p处开始,先与[]结合,说明p是一个数组,然后与int结合,说明数组里的元素是整型的,所以p是一个由整型数据组成的数组 。
int
*p[3];
//首先从p处开始,先与[]结合,因为其优先级比*高,所以p是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与
int结合,说明指针所指向的内容的类型是整型的,所以是一个由返回整型数据的指针所组成的数组
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是一个指向有一个整型参数且返回类型为整型的函数的指针
变量的指针就是变量的地址。存放变量地址的变量是指针变量。指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。下面是指针的一些关系
1.
运算符&和*
&是取地址运算符,*是间接运算符。
&a的运算结果是一个指针,指针的类型是a的类型加个*,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。
*p的运算结果就五花八门了,总之*p 的结果是 p 所指向的东西,这个东西有这些特点:它的类型是 p指向的类型,它所占用的地址是p所指向的地址。
2. 数组和指针的关系
数组的数组名其实可以看作一个指针。
声明了一个数组 TYPE array[n],则数组名称array就有了两重含义:
第一,它代表整个数组,它的类型是 TYPE[n];
第二 ,它是一个常量指针,该指针的类型是TYPE*,该指针指向的类型是 TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似
array++的表达式是错误的。
3. 指针和结构类型的关系
假设我们定义了一个结构体,struct MyStruct{inta;int b;int c;};
同时定义结构体的结构对象并初始化,struct MyStructss={20,30,40};
那么我们如何通过指针ptr 来访问 ss的三个成员变量呢?
答案就是,我们先定义一个指向结构对象 ss的指针,struct MyStruct *ptr=&ss; 然后,使用指向运算符->便可实现对结构对象ss成员的访问。
ptr->a; //或者可以这们(*ptr).a,建议使用前者
ptr->b;
ptr->c;
4. 指针和函数的关系
可以把一个指针声明成为一个指向函数的指针,从而通过函数指针调用函数。让我们举一个例子来说明以下吧。
int fun(char *,int);
int (*pfun)(char *,int);
pfun=fun;
int a=(*pfun)("abcdefg",7);
例中,定义了一个指向函数fun的指针pfun,把pfun作为函数的形参。把指针表达式作为实参,从而实现了对函数fun的调用。
读大学时,老师就说学好了指针,就说明你基本上搞懂了C语言。