高级指针

在学习C语言过程中,指针的使用是必不可少的,下面我们来简单的对一些高级指针做一些介绍以及应用。
一、指针数组
指针数组是一个数组,是用来存放指针的数组,来看下面一段代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<string.h>
int main()
{
    int i = 0;
    char *arr[] = { "one", "two", "three", "four", "five" };
    for (i = 0; i < 5; i++)
    {
        printf("%s\n", arr[i]);
    }
    printf("%s\n", arr[1] + 1);
    system("pause");
    return 0;
}

运行结果如下:
这里写图片描述
我们定义了一个指针数组arr[],数组的每个元素都是一个指针,指向一个字符串,所以这个for循环执行完之后输入的是五个字符串。再看下面的输出语句,arr[1]+1意为数组第二个元素的起始地址加1,则指针指向的就是字符“w”,所以输出的字符串就是wo。
二、数组指针
数组指针是一个指针,可以指向一个数组。
那我们看一个简单的数组指针的定义:
int (*p)[10];
解 释 : p 先 和 * 结 合 , 说 明 p 是 一个 指 针 变 量 , 然 后 指 着 指 向 的 是 一个 大 小 为 1 0 个 整 型 的 数 组 。 所 以 p 是 一个 指 针 , 指 向 一个 数 组 , 叫 数 组 指 针。
这 里 要 注 意 : [ ] 的 优 先 级 要 高 于 * 号 的 , 所 以 必 须 加 上() 来 保 证 p 先 和 * 结 合。
下面来看一段代码

    int arr[5] = { 1, 2, 3, 4, 5 };
    int(*p)[5] = &arr;
    printf("%p\n", &arr[3]);
    printf("%p\n", p);
    printf("%p\n", p[1]);
    printf("%p\n", p + 1);
    printf("%d\n", (*p)[3]);

这里写图片描述

我们定义了一个数组指针,指向arr[]这个数组。我们来看第一个输出语句,打印的是第四个元素的地址006FFA40,再来看第二行输出语句,输出的是数组的地址,和之前输出的地址相差十进制的十二位,也就是3个int型,即为第一个元素的地址。再看下面两行输出语句,输出结果都为006FFA48和p的地址相差十进制20位,也就是一个数组的大小。所以p+1和p[1]都是指向下一个数组的。最后一行就是用数组指针的形式输入数组第四个元素。
三、函数指针
函数指针是一个指针用来存放函数的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
int max1(int x, int y)
{
    int z;
    if (x > y)
        z = x;
    else
        z = y;
    return z;
}
int main()
{
    int max1(int, int);
    int(*p)(int, int);
    int a = 1;
    int b = 2;
    int c;
    p = max1;
    c = (*p)(a, b);
    printf("a=%d\nb=%d\nmax=%d\n", a, b, c);
    system("pause");
    return 0;
}

运行结果如下
这里写图片描述
程序int(p)(int)(int);用来定义p是一个指向函数的指针变量,最前面的int表示这个函数值(即函数返回值)是整型的。最后面的括号中有两个int,表示这个函数有两个int型参数。注意*p两侧的括号不可省略,表示p先与结合,是指针变量,然后再与后面的()结合,()表示函数,即该指针变量不是指向一般的变量,而是指向函数。如果写成int*p(int,int)由于()优先级高于,它相当于int(p(int,int)),就成了声明一个p函数了(这个函数的返回值是指向整型变量的指针)。
赋值语句p=max的作用是将函数max的入口地址赋给指针变量p。和数组名代表数组首元素地址类似,函数名代表函数的入口地址。这样,p就是指向函数max的指针变量,此时p和max都指向函数的开头。调用*p就是调用max函数。请注意p是指向函数的指针变量,它只能指向函数的入口处而不可能指向函数中间某一条指令处,因此对指向函数的指针变量不能进行算术运算。
四、函数指针数组
数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组, 比如:
int *arr[10];
/ / 数 组 的 每 个 元 素 是 i n t *
那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组 如何定义呢?
int (*parr1[10]])();
int *parr210;
int (*)() parr3[10];
答案是:parr1 parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢? 是 int (*)() 类型的函数指针。
函数指针数组的用途:转移表
例子:(计算器)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
int add(int a, int b)
{
    return a + b;
}
int sub(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a*b;
}
int div(int a, int b)
{
    return a / b;
}
int main()
{
    int x, y;
    int input = 1;
    int ret = 0;
    while (input)
    {
        printf("*************************\n");
        printf("  1:add           2:sub  \n");
        printf("  3:mul           4:div  \n");
        printf("*************************\n");
        printf("请选择:");
        scanf("%d", &input);
        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;
        default:
            printf("选择错误\n");
            break;
        }
        printf("ret = %d\n", ret);
    }
    return 0;
}

使用函数指针数组的实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
int add(int a, int b)
{
    return a + b;
} int sub(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a*b;
}
int div(int a, int b)
{
    return a / b;
}
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:div  \n" );
        printf( "*************************\n" );
        printf( "请选择:" );
        scanf( "%d", &input);
        if ((input < 4 && input > 1))
        {
            printf( "输入操作数:" );
            scanf( "%d %d", &x, &y);
            ret = (*p[input])(x, y);
        }
        else
            printf( "输入有误\n" );
        printf( "ret = %d\n", ret); 
}
    return 0;
}

五、指向函数指针数组的指针
指向函数指针数组的指针是一个 指针 指针指向一个 数组 ,数组的元素都是 函数指针 ;

void test(const char* str)
{
    printf("%s\n", str);
}
int main()
{
    //函 数 指 针 p f u n
        void(*pfun)(const char*) = test;
    //函 数 指 针 的 数 组 p f u n A r r
        void(*pfunArr[5])(const char* str);
    pfunArr[0] = test;
    //指 向 函 数 指 针 数 组 p f u n A r r 的 指 针 p p f u n A r r
        void(*(*ppfunArr)[10])(const char*) = &pfunArr;
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值