(7)二级指针
指向一级指针的指针.
类似的,可有更高级的指针.
(8)指向数组的指针
声明语法: 类型名 (*变量名)[表达式1]...[表达式n];
(9)指向函数的指针
声明语法: 值类型 (*指针名)(形参表);
运算与用途:
1.赋值
2.调用语法 (*函数指针)(实参表);
3.可作函数参数
4.可作函数值
5.可作数组元素
(10)复合说明项
在c语言中,处理声明语句时,遇到[]处理成数组;遇到*处理成指针;遇到()处理成函数;
但是,
1.不能有元素为函数的数组,但是可以有元素为函数指针的数组;
2.不能有函数值是函数的函数,但是函数值可以是指向函数的指针;
3.不能有函数值是数组的函数,但是函数值可以是指向数组的指针.
示例程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void show(int array[]);
void swap_1(int **a, int **b);
void swap_2(int **a, int **b);
double g(double a, double b, double (*fp)(double));
//注意,c语言中的抽象说明符 ??
double g(double, double, double (*)(double));
double y(double x);
//自己实现scanf
void scanf_m(char *c, void *p);
void main()
{
int i;
/*
* 二级指针
*/
int array[10], *p[10];
int **q;
for(i = 0; i < 10; i++)
p[i] = &array[i];
//为q赋初值
q = p;
//下面的语句只能给array[0]赋值
for(i = 0; i < 10; i++)
**q = i;
//应改为
for(i = 0; i < 10; i++)
{
**q = i;
q++;
}
//下面的程序会出错
/*
for(i = 0; i < 10; i++)
{
*q = ++ *q;
printf("%d ", **q);
}*/
//show(array);
//使用二级指针,交换两个指针的指向
int u = 1, v = 2, *pointer = &u, *qointer = &v;
swap_1(&pointer, &qointer);
//printf("%d, %d/n", u, v);
//printf("%d, %d", *pointer, *qointer);
//swap_2(&pointer, &qointer);
//printf("%d, %d/n", u, v);
//printf("%d, %d", *pointer, *qointer);
/*
* 指向数组的指针:一个指针,所指对象是数组,例如:
*/
int (*pa)[10], a[5][10];
pa = a;
printf("pa = %d/n", pa);
//pa + 1跨过了40个字节
printf("pa + 1 = %d/n", pa + 1);
int (*qb)[5][10], b[1][5][10];
qb = b;
/*
* 在c语言中, 不论p是什么样的指针, p[i] = *(p + i)总成立.
*/
for(i = 0; i < 5; i++){
for(int j = 0; j < 10; j ++){
a[i][j] = i;
}
}
int (*pb)[10] = pa + 5;
//打印数组元素
for(; pa < pb; pa++)
{
printf("%d ", **pa);
printf("%d ", *(*pa + 9));
}
printf("/n");
/*
* 指向函数的指针:一个指针,值为函数入口地址
*/
printf("%f/n", g(0, 10, y));
printf("%f/n", g(0, 3.1415926, sin));
/*
* 复合说明项
*/
//例1.windows消息映射,使用了元素为函数指针的数组,而不是一个大的switch语句.
//例2.返回值是指向一个函数的指针,用的不多.
//例3.返回值是指向数组的指针
//指针的强制类型转换
int intTemp = 0;
double flTemp = 0;
char chTemp[100];
char ch = 'd';
scanf_m(&ch, &intTemp);
ch = 'f';
scanf_m(&ch, &flTemp);
ch = 's';
scanf_m(&ch, chTemp);
printf("%d, %f, %s/n", intTemp, flTemp, chTemp);
}
/*
* 输出数组
*/
void show(int array[])
{
int i = 0;
for(i = 0; i < 10; i++)
{
printf("%d ", array[i]);
}
}
/*
* 下面的2个程序交换两个指针指向的内容
*/
void swap_1(int **a, int **b)
{
int *x = NULL;
x = *a;
*a = *b;
*b = x;
}
void swap_2(int **a, int **b)
{
int **x = NULL;
//下面的程序会报错,x的值不定,说不定指到哪.
*x = *a;
*a = *b;
*b = *x;
}
/*
* 积分计算
*/
double g(double a, double b, double (*fp)(double))
{
int i = 0;
double s = 0;
double d = (b - a)/10000;
for(; i < 10000; i++){
s += (*fp)(a + i * d + d / 2) * d;
}
return s;
}
double y(double x)
{
return x;
}
//复合说明项
//error1: array element type cannot be function
//int a[10](int *, int);
//error2:
/*
int f1(int);
int f2(int);
int f(int x)
{
if(x > 0)
return f1;
else
return f2;
}*/
//例2.返回值是指向一个函数的指针:
//f是一个函数,形参是x,返回值是一个函数指针:其形参是float型,返回double.
double (* f(int x))(float);
//error3:function returns array
//int f()[10];
//例3.返回值是指向数组的指针
int (* fun(int))[10];
//自己实现的scanf()函数
void scanf_m(char *c, void *p)
{
char a[100], *s = a, *r;
while(*s = getchar(), *s != '/n')
s++;
*s = '/0';
if(*c == 'd')
{
*(int *)p = atoi(a);
return;
}
if(*c == 'f')
{
*(double *)p = atof(a);
return;
}
else
{
s = a;
r = (char *)p;
while(*r ++ = *s ++);
}
}