指针与数组、函数的组合

指针数组

指针数组是一个存放指针的数组

int *arr1[10];
char *arr2[10] = {"hello", "world", "123",}; //把字符串首字符的地址存入数组中
char **arr3[5]; //存放一级指针

数组指针

数组指针的定义

int (*p)[10]; 
//int表示p指向数组的元素类型,(*p)表示这是一个指针,[10]表示p指向数组的元素个数
//p先和*结合,说明p是一个指针,指针指向一个大小为10的整型的数组
//[]的优先级高于*,所以需要添加()来保证p先和*结合
//int(*)[10]即为p的类型

数组指针的使用

数组地址的存储
int arr1[10];
int(*p)[10] = &arr1; //p指向arr数组
//&arr1表示取数组的地址

int *arr2[10]; //指针数组
int* (*p1)[10] = &arr2; //数组指针,存放数组的地址
int **p2 = arr2; //二级指针,存放首元素的地址
二维数组的传参
例如
int main()
{
    int arr[3][5] = { 0, 1, 2 };
    test(arr);
    //arr表示数组首元素的地址,即二维数组的第一行(一维数组)
    return 0;
}
在这里,我们test()函数的参数进行设计
void test(int arr[3][5]) //使用二维数组的方式接受参数
{
    printf("%d\n", arr[0][1]);
}

void test(int (*arr)[5]) //使用数组指针的方式接受
{
    printf("%d\n", *(*(arr)+1));
    //arr 指向第一行
    //arr+i 指向第i行
    //*(arr+i) 第i行的数组名,即第i行首元素的地址
    //*(arr + i) + j 第i行、第j列的元素的地址
    //*(*(arr+i)+j) 第i行、第j列的元素
}

存放数组指针的数组

int(*p[10])[5]; //存放数组指针的数组
//p先与[]结合,说明p是一个数组,数组有10个元素
//然后我们去掉p[10],即int(* )[5],即数组p的类型
//int(*p[10])[5]表示一个存放数组指针的数组,这个数组有10个元素,每个元素都是一个数组指针,指向有5个元素,类型为int的数组

指针和数组的定义与声明

我们创建两个源文件tesc.c和main.c,分别写入不同的代码

例1
//test.c
char arr[] = "abcdef";
main.c
extern char *arr;
int main()
{
    printf("%s\n", arr); //输出错误
    return 0;
}
在这里,我们在test.c中定义arr有7个字节;在main.c中声明时只声明了4个字节;由于声明和定义使用的是同一块空间,所以,在main.c的角度,arr只声明了4个字节,即arr占用的是“abcd”4个字节,但在输出时,arr是当作一个地址来输出的,即把“abcd”当作地址输出,所以内存访问出错
改正
printf("%s\n", (char *)&arr);
//取出arr的地址,强制类型转化为char *
例2
test.c
char *p = "abcdef";
main.c
extern char p[];
int main()
{
    printf("%s\n", p); //随机值
    return 0;
}
在test.c中,p为4个字节,即a的地址;在main.c中,p[ ]最多有4个元素;p表示数组名,表示在test.c中首元素的地址,输出时,把a的地址当成4个字符输出。
改正
printf("%s\n",(char *) * (int *) p);
//(int *)p  向后取4个字节
//*(int *)p 得到a的地址
//(char *) * (int *) p  转化成char *(地址)

printf("%s\n", *(char **)p);
//*(char **)p  取出一个char *(4个字节)

函数指针

函数指针

函数指针的定义
void (*pfun)() = &test; //函数指针
//void表示所指向函数的返回类型,(*pfun)表示这是一个指针,()包含函数的参数
//pfun先和*结合,说明pfun是一个指针,指针指向一个函数,指向的函数无参数,返回类型为void
//void (*)()即为pfun的类型
//test与&test均为test函数的地址

(*pfun)(); //调用
//()函数调用操作符
//*无实际意义

函数指针数组

函数指针数组的定义
int (*pfun[10])(); //函数指针数组
//pfun先与[]结合,说明pfun是一个数组,数组有10个元素
//然后我们去掉pfun[10],即int (*)()即数组pfun的类型
//int (*pfun[10])()表示一个存放函数指针的数组,这个数组有10个元素,每个元素都是一个函数指针,指向一个无参数,返回类型为int的函数
函数指针数组的应用-转移表
例如:计算器
#include <stdio.h>

int Add(int x, int y)
{
    return x + y;
}
int Sub(int x, int y)
{
    return x - y;
}
int Mul(int x, int y)
{
    return x * y;
}
int Div(int x, int y)
{
    return x / y;
}

int main()
{
    int x, y;
    int input = 1;
    int ret = 0;
    int(*p[5])(int x, int y) = { 0, Add, Sub, Mul, Div }; //转移表
    while (input)
    {
        printf("************************\n");
        printf("****  1.add  2.sub  ****\n");
        printf("****  3.mul  4.dov  ****\n");
        printf("****     0.exit     ****\n");
        printf("************************\n");
        printf("请选择:");
        scanf("%d", &input);
        if (input <= 4 && input >= 1)
        {
            printf("输入操作数:");
            scanf("%d %d", &x, &y);
            ret = (*p[input])(x, y); //调用
            printf("ret = %d\n", ret);
        }
        else
        {
            break;
        }
        //switch (input)
        //{
        //case 1:
        //  printf("请输入操作数:");
        //  scanf("%d %d", &x, &y);
        //  ret = Add(x, y);
        //  break;
        //case 2:
        //  printf("请输入操作数:");
        //  scanf("%d %d", &x, &y);
        //  ret = Sub(x, y);
        //  break;
        //case 3:
        //  printf("请输入操作数:");
        //  scanf("%d %d", &x, &y);
        //  ret = Mul(x, y);
        //  break;
        //case 4:
        //  printf("请输入操作数:");
        //  scanf("%d %d", &x, &y);
        //  ret = Div(x, y);
        //  break;
        //case 0:
        //  break;
        //}
        //if (input)
        //  printf("ret = %d\n", ret);
    }
    return 0;
}

指向函数指针数组的指针

指向函数指针数组的指针的定义
void (*pfunarr[5])(int x) = { test }; //函数指针数组
(*pfunarr[0])(1); //调用函数

void (*(*ppfunarr)[5])(int x) = &pfunarr;
//ppfunarr先与*结合,说明ppfunarr是一个指针
//然后我们去掉*ppfunarr,即void (*()[5])(int x)即指针ppfunarr的类型
//void (*pfunarr[5])(int x)表示一个指向函数指针数组的指针,指针指向的数组函数指针有5个元素,每个元素都是一个函数指针,指向一个有一个参数,返回类型为void的函数

总结

int *arr[5]; //指针数组

int (*p)[5]; //数组指针

int (*parr[10])[5]; //存放数组指针的数组

void (*pfun)(); //函数指针

int (*pfun[10])(); //函数指针数组

void (*(*ppfunarr)[5])(int x); //指向函数指针数组的指针

猜你喜欢

转载自blog.csdn.net/lw13572259173/article/details/80245406
今日推荐