指针的进阶-3

int main()
{
    //指针数组
    int* arr[5];
    char* ch[10];
    //arr首元素是int*类型的,arr数组名代表首元素地址,故arr是int**类型的,int**类型用来存放int*类型的地址
    int** p0 = arr;

    //数组指针
    int arr1[10] = { 0 };
    int(*p)[10] = &arr1;

    char* arr2[6];
    char* (*p)[6] = &arr2;
    return 0;
}

//函数指针-->指向函数的指针

int test(const char* str)
{
    printf("test()\n");
    return 0;
}
int main()
{
    char a = 'w';
    // 函数名或&函数名都可以得到函数的地址
    printf("%p\n", test);
    printf("%p\n", &test);

    //int (*p)(const char*) = &test 也可以
    int (*p)(const char*) = test; 

    //(*p)(a)也可以
    p(a);
    return 0;
}

我认为很重要的一部分

//函数定义的时候函数名加上括号也可以
void (test)()
{
    printf("heheh\n");
}
int main()
{
    /*
        注:注意*的优先级
            先运算( void(*)() )0
            再运算*( void(*)() )0
        这是一次函数调用
        void(*)() --> 是函数指针
        (void(*)())0 --> 0是int类型,将0强制转换成函数指针类型
        *( void(*)() )0 --> 解应用找到函数
        ( *( void(*)() )0 )(); --> 调用函数

    */
    ( *( void(*)() )0 )();

    /*
        注:函数定义是,函数名加上括号也可以
        个人理解:
        1.signal(int,  void(*)(int)) 表明signal是一个函数,函数定义在内存中有地址,放在代码区
        2.*signal(int,  void(*)(int))取出函数signal的地址
        3.void( 函数signal的地址 )(int); 声明一个函数,函数名是 函数signal的地址,返回类型是void,参数是int
            
        --------
    */
    void( *signal(int,  void(*)(int)) )(int);//不要忽略函数有返回值,类型用来定义变量,并没有具体的值
    /*
        正确理解:
            1.signal(int,  void(*)(int)) 是一个函数声 signal(int,  void(*)(int))的结果就是它的返回值
            2.void( *signal(int,  void(*)(int)) )(int);去掉signal(int,  void(*)(int)),只剩void( * )(int);
                说明函数signal的返回类型是void( * )(int)类型
            3.所以说void( *signal(int,  void(*)(int)) )(int);是一个函数指针类型

    */

    //test();
    
    return 0;
}

typedef unsigned int unint;
// 写成这样不对 typedef void(*)(int) pef
typedef void(*pef)(int);
int main()
{
    //这是一个函数的声明
    void(*signal(int, void(*)(int)))(int);
    pef signal(int, pef);

    /*
        正确理解:
            1.signal(int,  void(*)(int)) 是一个函数声 signal(int,  void(*)(int))的结果就是它的返回值
            2.void( *signal(int,  void(*)(int)) )(int);去掉signal(int,  void(*)(int)),只剩void( * )(int);
                说明函数signal的返回类型是void( * )(int)类型
            3.所以说void( *signal(int,  void(*)(int)) )(int);是一个函数指针类型
    */
    return 0;
}

//函数指针的用途


//写一个计算器,实现+-*/功能

//void meau()
//{
//    printf("**************************************\n");
//    printf("****         1.Add 2.Del         *****\n");
//    printf("****         3.Mul 4.Div         *****\n");
//    printf("****         0.exit              *****\n");
//    printf("**************************************\n");
//}
//int Add(int x, int y)
//{
//    return x + y;
//}
//int Del(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 input = 0;
    int x = 0;
    int y = 0;
    int ret = 0;
    do
    {
        meau();
        printf("请选择您需要的模式:\n");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("请输入两个操作数:\n");
            scanf("%d %d", &x, &y);
            ret = Add(x, y);
            printf("%d\n", ret);
            break;
        case 2:
            printf("请输入两个操作数:\n");
            scanf("%d %d", &x, &y);
            ret = Del(x, y);
            printf("%d\n", ret);
            break;
        case 3:
            printf("请输入两个操作数:\n");
            scanf("%d %d", &x, &y);
            ret = Mul(x, y);
            printf("%d\n", ret);
            break;
        case 4:
            printf("请输入两个操作数:\n");
            scanf("%d %d", &x, &y);
            ret = Div(x, y);
            printf("%d\n", ret);
            break;
        case 0:
            printf("退出\n");
            break;
        default:
            printf("对不起,您输入的数字不合法,请重新选择:\n");
            break;
        }
    } while (input);

    return 0;
}
//
使用函数指针
//
//void  Ret( int (*p)(int, int))
//{
//    int x = 0;
//    int y = 0;
//    printf("请输入两个操作数:\n");
//    scanf("%d %d", &x, &y);
//    printf("%d\n", p(x, y));
//}
//int main()
//{
//    int input = 0;
//    do
//    {
//        meau();
//        printf("请输入您要选择的模式:\n");
//        scanf("%d", &input);
//        switch (input)
//        {
//        case 1:
//            //这种方法叫做回调函数
//            Ret(Add);
//            break;
//        case 2:
//            Ret(Del);
//            break;
//        case 3:
//            Ret(Mul);
//            break;
//        case 4:
//            Ret(Div);
//            break;
//        case 0:
//            printf("退出\n");
//            break;
//        default:
//            printf("对不起,您输入的模式不正确,请重新输入:\n");
//            break;
//        }
//    } while (input);
//
//    return 0;
//}

//函数指针数组

//以下四个函数类型一样,故其地址也是一样的,同为 int(*)(int,int)
//一般分析的时候,类型的格式都是固定的,从类型名字入手

int Add(int x, int y)
{
    return x + y;
}
int Del(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;
}
typedef int(*pef)(int ,int );
int main()
{
    //指针数组
    int* arr[10];

    int x = 4;
    int y = 5;
    //函数指针数组
    printf("===============================================================\n");
    int (*p[4])(int,int) = {Add,Del,Mul,Div};
    printf("%d %d %d %d\n", p[0](x, y), p[1](x, y), p[2](x, y), p[3](x, y));
    printf("%d %d %d %d\n", (*p[0])(x, y), (*p[1])(x, y), (*p[2])(x, y), (*p[3])(x, y));

    printf("===============================================================\n");
    //等价于
    pef p1[4] = { Add,Del,Mul,Div };
    printf("%d %d %d %d\n", p1[0](x, y), p1[1](x, y), p1[2](x, y), p1[3](x, y));
    printf("%d %d %d %d\n", (*p1[0])(x, y), (*p1[1])(x, y), (*p1[2])(x, y), (*p1[3])(x, y));
    /*
        p1[4]是一个数组,有4个元素,每个元素int (*)(int ,int )类型
    */
    return 0;
}

//函数指针数组的用处


//void meau()
//{
//    printf("**************************************\n");
//    printf("****         1.Add 2.Del         *****\n");
//    printf("****         3.Mul 4.Div         *****\n");
//    printf("****         5.&   6.|           *****\n");
//    printf("****         7.^   8.&&          *****\n");
//    printf("****         9.||  10.exit       *****\n");
//    printf("**************************************\n");
//}
//int Add(int x, int y)
//{
//    return x + y;
//}
//int Del(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 bit_mul(int x, int y)
//{
//    return x & y;
//}
//int bit_and(int x, int y)
//{
//    return x | y;
//}
//int dif_and(int x, int y)
//{
//    return x ^ y;
//}
//int mul_mul(int x, int y)
//{
//    return x && y;
//}
//int and_and(int x, int y)
//{
//    return x || y;
//}
//
//typedef int(*pef)(int, int);
//int main()
//{
//    pef arr[9] = { Add,Del ,Mul ,Div ,bit_mul ,bit_and,dif_and ,mul_mul,and_and };
//    //转移表(跳转的功能)
//    int (*p[9])(int, int) = {Add,Del ,Mul ,Div ,bit_mul ,bit_and,dif_and ,mul_mul,and_and };
//    int input = 0;
//    int x = 0;
//    int y = 0;
//    int ret = 0;
//    do
//    {
//        meau();
//        printf("请输入您要选择的模式:\n");
//        scanf("%d", &input);
//        if (input >= 1 && input <= 9)
//        {
//            printf("请输入操作数:\n");
//            scanf("%d %d", &x, &y);
//            ret = p[input - 1](x, y);
//            printf("%d\n", ret);
//        }
//        else if (input == 0)
//        {
//            printf("退出\n");
//            break;
//        }
//        else
//        {
//            printf("对不起,您输入的模式不正确,请重新输入\n");
//            continue;
//        }
//    } while (input);
//
//
//    return 0;
//}

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

typedef int(*pef[10])(int, int);
int main()
{
    int arr[10] = { 0 };
    //数组指针 -- > 指向数组的指针
    int(*p1)[10] = &arr;
    //函数指针数组
    int(*p[10])(int, int);
    //pef p[10];
    pef* p = &p;
    int(*(*p2)[10])(int, int) = &p;
    /*
        个人理解:类型是固定的,一般从名字部分下手
        int(*(*p)[10])(int,int);
        其中*p代表p是指针,是地址,指向一个数组,有10个元素,每个元素是int(*)(int,int)
        -------
    */
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值