如何理解指针与数组之间的关系

1.指针是什么?
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为”指针”。意思是通过它能找到以它为地址的内存单元。

#include<stdio.h>
int main()
{
int a=10;    //在内存开辟一块空间
int *p=&a;   //这里我们对变量a,取出它的地址
             //将a的地址存放在p变量中,p就是一个指针变量
    *p=20;   //通过指针我们可以改变a的值     
return 0;
}

这里写图片描述
2.数组是什么?
所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 这些无序排列的同类数据元素的集合称为数组。数组是用于储存多个相同类型数据的集合
数组的两种初始化

char arr[]={'a','b','c','d','e'}  //末尾无'\0'
cahr arr[]="abcde"                //末尾有‘\0'

3.指针数组和数组指针

**指针数组**:指针数组是数组,是一个存放指针的数组。
int *p[10]  //p和[10]先结合(组成数组),再和*结合(形成数组指针)
**数组指针**:数组指针是指针,这个指针是指向数组的。
int (*p)[10]    //由于()的参与*和p先结合,p是一个指针变量,然后指向一个10个整数的数组
                //[]优先级高于*

4.函数指针

void test()
{
printf("hello\n")
}

//下面pfun1和pfun2谁能存放test函数的地址?

void (*pfun1)();
void *pfun2();

我们先来分析一下,能够存储地址,这就要求是一个指针,通过上面(数组指针和指针数组)的判断,我们发现*pfun1是指针。指针指向一个无参数的函数,返回类型是void

下面我们再来分析两个有意思的代码

(*(void(*)()0)()

我们从内往外一步一步来分析:

1、(void(*)()0 将0强制转换为数组指针
假设 a=(void(*)()0
2 、 *a 将a解引用
3、整体是个函数

void (*signal(int,void(*)(int)))(int);

1、signal是一次函数声明
2、signal函数的参数:第一个是int(整形),第二个是函数指针,该函数指针指向的函数参数为int,返回类型是void

5、函数指针数组
函数指针数组:数组是存放相同类型数据的存储空间,当我们把函数的地址存到一个数组中,这个数组就叫做函数指针数组。
通过指针数组 :int *arr[10]
得到函数指针数组:int (*arr[10])()

函数指针的用途举例:计算器的实现

#include <stdio.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 ret = 0;
    int input = 1;
    int(*arr[])(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 = (*arr[input])(x, y);
        }
        else
            printf("操作有误");
        printf("ret=%d\n", ret);
    }
    return 0;
}

结果如下:
这里写图片描述
6、指向函数指针数组的指针
指针指向一个数组,数组的元素都是函数指针
通过函数指针数组:int (*arr[10])()
得到函数指针数组:int (*(*arr)[10])()

指向函数指针数组的指针的用途举例:回调函数

回调函数:如果你把函数的指针(地址)作为参数传递给另外一个函数,当这个指针被用来条用其他所指向的函数时,我们就说这是回调函数

#include<stdio.h>
int int_cmp(const void* p1, const void* p2)
{
    return (*(int*)p1 > *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
    int i = 0;
    for (i = 0; i < size; i++)
    {
        char tmp = *((char*)p1 + i);
        *((char*)p1 + i) = *((char*)p2 + i);
        *((char*)p2 + i) = tmp;
    }
}
void bubble_sort(void* base, int count, int size, int(*cmp)(void*, void*))
{
    int i = 0;
    int j = 0;
    for (i = 0; i < count - 1;i++)
    {
        for (j = 0; j < count - 1 - i; j++)
        {
            if ((cmp((char*)base + j*size, (char*)base + (j+1)*size))>0)
            {
                _swap((char*)base + j*size, (char*)base + (j + 1)*size, size);
            }
        }
    }
}
int main()
{
    int arr[] = { 9,4,5,71,3,5,6,1,0};
    int i = 0;
    bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
    for (i = 0;i< sizeof(arr) / sizeof(arr[0]);i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
    return 0;
}

这里写图片描述


猜你喜欢

转载自blog.csdn.net/qq_42321594/article/details/81320738
今日推荐