指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针

指针数组
   什么是指针数组?指针数组是指针还是数组?
  正如“好孩子”而言,强调的是孩子而不是好,所以指针数组是一个数组。
  那我们先了解一下什么是数组?
数组就是相同类型元素的集合
正如:整形数组存放整形元素;
字符型数组存放字符型元素;
  所以,指针数组存放指针;
即:
指针数组是数组,里面存放的元素类型是指针类型

//你认为哪一个是指针数组?
int *arr1[10];
char *arr2[4];
char **arr3[5];

它们都是指针数组;
1. arr1首先和[]结合形成数组,存放整形指针;
2. arr2首先和[]结合形成数组,存放字符型指针;
3. arr3[5]首先和[]结合形成数组,存放二级指针的数组;


数组指针
正如:整形指针能存放整形数据的地址;
字符型指针能存放字符型数据的地址;
所以:数组指针用于存放数组的地址;

//p分别是什么?
int *p[10];
int(*p)[10];
  1. 第一个p先和[]结合形成一个数组,存放整形指针,是指针数组。
  2. 第二个p先和*形成是一个指针,指向一个数组,数组里面有10个整形元素,是数组指针。
int *arr[10];
int (*p)[10]=arr;   // 1:………………ok?
int (*p)[10]=&arr;  // 2:………………ok?
int *(*p)[10]=&arr; // 3:………………ok?
  • int *arr[10] 是指针数组,存放的是10个整形指针。
  • int (*p)[10] 是数组指针,指向一个数组,该数组有10个整形元素。
  • int *( *p)[10] 是指针,指向一个数组,该数组有10个整形指针。

    1. 不可以
         由于arr表示的是数组首元素的地址,arr首元素的类型为in*, 地址应为int **,正确语句为:int **p=arr;
      所以int ( * p)[10]=arr不成立!
    2. 不可以
        虽然&arr表示的是数组的地址,数组指针也恰好指向的是数组的地址,但是arr数组每个元素的类型为int *,而int ( *p)[10] 指向的数组每个元素的类型是int; 所以 int (*p)[10]=&arr不成立;
    3. 可以
         &arr表示的是数组的地址,数组指针也恰好指向的是数组的地址,arr数组每个元素的类型为int ,int ( p)[10]指向的数组每个元素的类型也是int ,所以int *( *p)[10]=&arr成立;
      一个重要的知识点:
      int* p 去掉p, int* 指针p指向的元素的类型。
      所以 int(* p)[10],去掉p,int( *)[10]为p的类型,即为数组指针的类型。
int (*p[10]) [5];

  p先和[]结合表示数组,数组有10个元素,每个元素的类型为:int(*)[5];即每个元素的类型为数组指针;
  int (*p[10])[5]表示,p数组里面有10个元素,每个元素的类型都是数组指针,数组指针即指向数组的地址,被指向的这个数组里面有5个整形元素。
即为存放数组指针的数组。


函数指针
  数组指针用于存放数组的地址;
  所以函数指针用于存放函数的的地址。
对于数组指针:int (* p)[5] p先和*结合形成一个指针,指向一个数组,数组里面有5个整形元素;
类比对应函数指针:int (* p) () p先和*结合形成一个指针,指向一个函数,函数用()表示,函数返回类型为int;

#include<stdio.h>
#include<stdlib.h>
int Add(int x, int y)
{
    return x + y;
}
int main()
{
    int(*p)(int, int) = Add;//函数名就是函数的地址
    printf("%d\n", p(2, 3));
    system("pause");
    return 0;
}

函数指针数组
  指针数组是用来存放指针的数组
  所以函数指针数组是用来存放函数指针的数组。

int (*p[3])();

由于p先和[]结合形成数组,该数组中有3个元素,元素的类型为:int (*) ();即函数指针。所以p就是函数指针数组。
举例:

#include<stdio.h>
#include<stdlib.h>
int Add(int x, int y)
{
    return x + y;
}
int Sub(int x, int y)
{
    return x - y;
}
int main()
{
    int(*p[3])(int, int) = { 0, Add, Sub };
    printf("%d\n", p[1](2, 3));
    printf("%d\n", p[2](5, 4));
    system("pause");
    return 0;
}

运行如下:
这里写图片描述


指向函数指针数组的指针
函数指针 用于存放函数的的地址。
函数指针数组 是用来存放函数指针的数组。
函数指针数组的指针 用于存放函数指针数组的地址;

int(*pfun[3])(int, int);
int(*(*p)[3])(int, int) = &pfun;

  由于pfun先和[]结合形成数组,该数组中有3个元素,元素的类型为:int (*) ();即函数指针。所以p就是函数指针数组。
  p先和* 结合形成指针,该指针指向一个数组,这个数组有3个元素,3个元素的类型为int ( *)()即为函数指针。
所以int(*( *p)[3])(int, int)为指向函数指针数组的指针。


总结:

int *arr1[10];//指针数组
int(*arr2)[10];//数组指针
int(*arr3[10])[2];//指向数组指针的数组
int(*p)(int, int);//函数指针
int(*p[3])(int, int);//函数指针数组
int(*(*p)[3])(int, int);//指向函数指针数组的指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值