指针相关概念

通俗的说,指针就是地址;指针变量是变量,是一个用来存放地址的变量。
1.指针数组
指针数组是一个可以存放指针的数组。
例:

int *arr1[10]; char *arr2[4];

2.数组指针
数组指针是指向数组的一个指针。
例:

int (*p)[10];  //p代表数组指针
int *p[10];   //p代表指针数组

注意:
(1)[ ]的优先级要高于号的,所以加上()保证p先和结合;
(2)以后我们判断一个变量的类型时,只需要看它的优先级即可,若变量先和数组结合,那么该变量就是一个数组;若变量先和*结合,那说明此变量是一个指针。

数组指针的使用:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int arr[10] = { 0 };
    printf("%p\n", arr);  //008FFE58  arr:表示数组首元素地址;
    printf("%p\n", arr+1); //008FFE5C arr+1:表示第二个元素的地址;
    printf("%p\n", &arr+1); //008FFE80 &arr:表示数组的地址;&arr+1:表示该数组下一个数组的地址;
    system("pause");
    return 0;
}

数组在传参时需要:
(1)所有的数组都会降为一维数组;
(2)数组传参会退化为指针;
(3)该指针指向其内部元素类型。

二维数组传参:

void test(int arr[3][5])  //正确
{}
void test(int arr[][])  //错误
{}
void test(int arr[][5])  //正确
{}
//总结:二维数组传参时,函数形参只能省略第一个[]的数字。以后多维数组也一样,只能省略第一个参数。
void test(int *arr)  //类型不匹配
{}
void test(int *arr[5]) //类型不匹配,这是指针数组
{}
void test(int (*arr)[5])  //正确,是数组指针
{}
int main()
{
   int arr[3][5] = {0};
   test(arr);
}

3.函数指针

函数指针是一个变量,用来存放函数(即代码)的地址。

#include <stdio.h>
#include <stdlib.h>

void test()
{
    printf("hehe\n");
}
int main()
{
    printf("%p\n", test);  //000E12AD
    printf("%p\n", &test);  //000E12AD
    system("pause");
    return 0;
}

输出的两个地址一样,因为test和&test的结果都是数组首元素的地址,但意义完全不同;test代表首元素地址,&test代表整个数组的地址。
下面我们看这段代码:

void test()
{
   printf("hehe\n");
}
void (*pfun1)();  //函数指针;
void *pfun2();   //函数的声明;

指针就是地址,故pfun1可以存放函数的地址。因为pfun1先和*结合,说明pfun1是个指针,指针指向一个函数,即为函数指针。

阅读两段有趣的代码:

扫描二维码关注公众号,回复: 1213668 查看本文章
(*(void (*) ())0) (); //如何理解?
//(void (*) ())0) 先将0强转成函数指针,然后解引用,即调用0地址处的内容。
void (*signal(int,void(*)(int)))(int);  //函数的声明;

4.函数指针数组
把函数的地址存到一个数组中,那这个数组就叫函数指针数组。
判断下面哪个是函数指针数组:

int (*parr1[10])();
int *parr2[10]();
int (*)()parr3[10];

结果是:parr1.
parr1先和[ ]结合,说明parr1是数组,存放的内容是int(*)()类型的函数指针。

函数指针数组的应用实例:转移表


#include <stdio.h>
#include <stdlib.h>

int my_add(int x, int y)
{
    return x + y;
}
int my_sub(int x, int y)
{
    return x - y;
}
int my_mul(int x, int y)
{
    return x * y;
}
int my_div(int x, int y)
{
    return x / y;
}

int main()
{
    int input = 0;
    int x = 0;
    int y = 0;
    int(*p[5])(int x, int y) = { my_add,my_sub,my_mul,my_div};
    int ret = 0;
    while (1)
    {
        printf("********************\n");
        printf("* 0.add      1.sub *\n");
        printf("* 2.mul      3.div *\n");
        printf("*            4.exit*\n");
        printf("********************\n");
        printf("请选择:>");
        scanf("%d", &input);
        if (input >= 0 && input <= 3)
        {
            printf("请输入x,y的值 :");
            scanf("%d %d", &x, &y);
            ret = (*p[input])(x, y);
        }
        else if (input == 4)
        {
            printf("确认退出!\n");
            break;
        }
        else
        {
            printf("输入错误,请重新选择:>");
        }
        printf("%d\n", ret);
    }
    system("pause");
    return 0;
}

5.函数指针数组的指针
把指针指向一个数组,数组的元素都是函数指针的指针称为函数指针数组的指针。
例:

void test(const char* str)
{
    printf("%s\n", str);
}
int main()
{
    //pfun是函数指针
    void(*pfun)(const char *) = test;
    //pfunArr是函数指针数组
    void(*pfunArr[5])(const char * str);
    pfunArr[0] = test;
    //ppfunArr是指向函数指针数组pfunArr的指针
    void(*(*ppfunArr)[10])(const char *) = &pfunArr;
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41289858/article/details/79666213