指针与数组中的难点剖析

指针与数组中的难点剖析

1. 指针数组

指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。


首先先定义一个指针数组,既然是数组,名字就叫arr

char* arr[]={"hello","world","fun","abcd"};

arr就是我定义的一个指针数组,它有四个元素,每个元素是一个char *类型的指针,这些指针存放着其对应字符串的首地址。
这里写图片描述
使用:
指针数组常用在主函数传参,在写主函数时,参数有两个,一个确定参数个数,一个这是指针数组用来接收每个参数(字符串)的地址。

int main(int argc, char *argv[]);

此时可以想象内存映像图,主函数的栈区有一个叫argv的数组,这个数组的元素是你输入的参数的地址,指向着只读数据区。

如果是向子函数传参,这和传递一个普通数组的思想一样,不能传递整个数组过去,如果数组很大,这样内存利用率很低,所以应该传递数组的首地址,用一个指针接收这个地址。因此,指针数组对应着二级指针。

void fun(char** p)//实参是指针的地址,那用二级指针很合理
{
}
int main()
{
char* arr[4];
fun(arr)   //实参为指针数组的首地址,是指针的地址
}

2. 数组指针
数组指针可以说成是”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。


我们来定义一个数组指针,既然是指针,我们就叫pa

char(* pa)[4];

pa是一个指针指向一个char [4]的数组,每个数组元素是一个char类型的变量,所以我们不妨可以写成:char[4] (*pa);这样就可以直观的看出pa的指向的类型,不过在编辑器中不要这么写,因为编译器根本不认识,这样写只是帮助我们理解。


指针数组和数组指针的区别:
指针数组和数组指针写法十分相似。指针数组char* arr[4]中只是因为[ ]的比较级高于,所以arr和[ ]结合为arr[ ],是数组,而char*则是他的元素类型;数组指针char(* pa)[4]中必须让pa先和*结合成*pa代表这是一个指针,而剩下的部分代表这个指针是指向一个数组的。

3. 函数指针
void (*pfun)( )
这就是一个函数指针,其作用就是存储函数的地址。pfun因为()的优先级高于*,所以给*pfun加括号,说明pfun是一个指针,指向的函数无参数,返回值为void。
看两段有趣的代码:

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

这里写图片描述
这里写图片描述

4. 函数指针数组
定义:
把函数的地址存到一个数组中,这个数组就叫函数指针数组。

int (*parr[10])( );

parr 先和 [ ] 结合,说明parr是数组,数组的元素是int () ( )*类型的函数指针。
函数指针数组的用途:转移表
举例:(计数器)
代码:

#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;
}

运行结果:
这里写图片描述
5. 指向函数指针数组的指针
指向函数指针数组的指针值一个指针,指针指向一个数组,数组的元素都是函数指针;
定义:

void (*(*pfunArr)[10])(const char*)==&pfunArr

函数指针的应用:回调函数
使用回调函数,模拟模拟qsort(采用冒泡方式)

#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[] = { 1, 2, 3, 4, 5, 6, 7, 8, 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;
}

运行结果:
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值