1.“*”与“&”的作用
*除了表示取出指定地址的数以外,还有一层含义就是将行地址转换为具体到某个元素的列地址。&除了表示取地址以外,还有可以表示将元素地址转换为行地址。
例子1:
(1)int a[3][4];//a是一个数组名,a数组包含3行分别是a[0]、a[1]、a[2],它门不是一个简单的整形元素而是由4个整形元素所组成的一维元素。所以数组名a表示一个第0行的一个行地址,从a的角度来看它只是包含了3个数组元素的数组;
(2)a[0],a[1],a[2]既然是一维数组(它们不是行地址了,是一个具体元素地址),C语言又规定了数组名代表数组首元素地址,则它们又分别代表了&a[0][0]、&a[1][0]以及&a[2][0]
(3)int (*p)[4]=a;//表示一个行地址;
(4)a+1,&a[1]:行首地址,但是这是一个行地址的概念,“&”将a[1]由原来的“指向第一行第一个元素”转换为“指向第一行的行地址”;
(5)a[0]、*(a+0)、*a:表示第0行第0个元素的地址,“*”将行地址转换为指向具体元素的地址;
(6) 求a[i][j]的方法:*(a[i]+j)、*(*(a+i)+j) (红色的星号起转换的作用)、a[i][j];
例子2:
void main()
{
int a[3][4]={0};
search(a,3);//调用的时候,传进去元素首行地址和一个行数
search1(*a,12);//调用的时候传进去首行第0个元素的地址,但是后面必须传整个二维数组的大小。
}
void search(int(*p)(4),int n);//二维数组作为函数参数
void search(int *p,int n)
{
int end=p+n-1;//在函数中可以定义这样一个指针表示数组的结束
}
例子3:
int a[4]={1,2,3,4};//此时a指向第0个元素表示具体元素的指针;
int (*p)[4]=&a;//"&"将a转换为了行指针且每行有4个元素;
int num=*(*(p+1)-1);“*”又起了一个转换的作用,此时num=4,具体参考《程序员面试宝典第七章》;
2.有关指针定义几个容易混淆的地方
int *a[10];//指针数组,a首先与“[]”结合表示数组;
int (*a)[10];//指向数组的指针,该数组含有10个元素;
int *f();//声明了一个函数,f首先与“()”结合表示函数
int (*f)();//声明了一个指向函数的指针。
int*(*f())();//声明了一个函数f,该函数返回一个函数指针,即int*(*)(),该函数指针指向的函数返回一个int类型的指针
int (*(*f)())();//声明了一个函数指针f,该指针指向的函数返回值为int(*)(),即一个返回值为int类型的函数指针
int **(*abc[6])();//声明了一个指针数组,该指针数组的指针类型为函数指针int **()();
3.void类型的指针
可以用来指向一个抽象的类型的数据,在将他的值赋给另一指针变量时要进行强制类型转换使之适合于被赋值的变量的类型。
char *p1;
void *p2;
p2=(void *)p1;
常用的操作就是定义回调函数。
4.转移表
double add(double,double);
double sub(double,double);
double mul(double,double);
double div(double,double);
double (*oper_func[])(double,double)={add,sub,mul,div};
#define ADD 0
#define SUB 1
#define MUL2
#define DIV 3
result=oper_func[ADD ](op1,op2);//调用的时候这样调用