1. 先来看几个例子,你能说出这几个表示方法的意义和不同点吗?
a. int *p[10]
b. int (*p)[10]
c. int (*p)(int)
d. int *p(int a) //这个是一个指针函数,函数返回的是一个地址,使用在在返回数组某一个元素的地址上;
e. int (*p[10])(int)
这几种表示方法经常出现在程序中,很容易使人混淆,需要注意的是:C语言经常用函数指针的方式实现面相对象的功能,在动态调用过程中,把实现不同功能的类似函数通过函数指针的形式赋值给真正调用的函数,来实现面相对象的过程。
2. 多维数组和指针
例如:整型二维数组a[3][4]:
设数组a的首地址为1000,C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0],a[1],a[2]。每一个一维数组又含有四个元素。例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。
数组及数组元素的地址表示如下:a是二维数组名,也是二维数组0行的首地址,等于1000。a[0]是第一个一维数组的数组名和首地址,因此也为1000,*(a+0)或*a是与a[0]等效的, 它表示一维数组a[0]的0号元素的首地址,也为1000,&a[0][0]是二维数组a的0行0列元素首地址,同样是1000。
因此,a,a[0],*(a+0),*a,&a[0][0]是相同的。同理,a+1是二维数组1行的首地址,等于1008。a[1]是第二个一维数组的数组名和首地址,因此也为1008。&a[1][0]是二维数组a的1行0列元素地址,也是1008。因此a+1,a[1],*(a+1),&a[1][0]是等同的。由此可得出:a+i,a[i],*(a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i],*(a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。由a [i]=*(a+i)得a[i]+j=*(a+i)+j,由于*(a+i)+j是二维数组a的i行j列元素的首地址。该元素的值等于*(*(a+i)+ j)。
试一下以下程序段
#define PF "%d,%d,%d,%d,%d,\n"
int main(void)
{
}
运行结果如下:(注意,是打印的10进制数)
其中数组地址信息如下:
说明:0x003a7038的十进制为3829816
3. 二级指针做参数
通过下面的例子来了解二级指针做函数参数时,主函数对此函数是怎么调用的。
#include "stdio.h"
typedef struct tst
{
}tst_t;
typedef struct student
{
}stu_t;
void fun(stu_t **p)
{
}
int _tmain(int argc, _TCHAR* argv[])
{
}