王老师 指针 第二讲

来源:互联网 发布:阿里云 王坚 哭 编辑:程序博客网 时间:2024/04/28 20:27

(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 ++);
 }
}