C语言学习笔记(十)—— 指针进阶

一、小补充

const char* ptr1 = "abcdsf";  // 此语句不是把“abcdsf”存入ptr1中,而是把字符串常量“abcdsf”的首地址放进了ptr1中

const char* ptr2 = "abcdsf";   // 此时ptr1 == ptr2,常量数组不能修改,不会另外开辟一个一样的。因此,ptr1和ptr2指向同一块空间

int * p1 [10];  // 此条语句中p1是个数组,该数组里面存放的是int*指针变量

int (*p2) [10];  // 词条语句中p2是个指针,指向的类型为int [10],p的类型是int (*)[10]

数组名是数组首元素的地址,二维数组的每一行可以理解为一个二维数组的元素,该元素是一个一维数组。因此,二维数组其实是一维数组的数组,首元素地址就是第一行的地址

int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int (*ptr) [10] = &arr;  // 此时ptr是整个数组的指针,+1跳过整个数组范围

// *ptr == arr,但解引用以后ptr只是首元素的地址,而不是整个数组的元素

二、函数指针

函数指针,就是指向函数的指针。

void func()

{}

printf("%p\n", &func);  // 取出了函数的地址

printf("%p\n", func);  // 函数名就是函数的地址

返回类型 (*ptr)(函数参数类型) = &func;  // ptr为函数指针变量;

int ret = (*ptr)(3, 5);  // 此为函数指针的用法

int ret = ptr(3, 5);  // 不解引用也可以

(*(void(*)())0)();  // 该语句调用0地址处的函数,该函数类型是void ()

void(* signal (int, void (*)(int)))(int);  // 该语句表示一个signal函数,函数的参数是int和void (*)(int),返回值为void (*)(int)

// 这样的语句太复杂,可读性也很低,因此我们常常使用typedef来优化

typedef unsigned int u_int;  // 对整型重定义

typedef int* ptr_t;  // 对整型指针重定义

typedef int (*)[10] ptr_arr;  // error,此种重定义数组指针的方法是错的

typedef int (*ptr_arr)[10];   //对数组指针重定义为ptr_arr

typedef int (*)(int, int) pf_t;  // error,此种重定义函数指针的方法是错的

typedef int (*pf_t)(int, int);  //对函数指针重定义为pf_t

//开始简化最开始两行代码

typedef void(aaa*)();

typedef void(bbb*)(int);

(*(aaa)0)();

bbb signal(int, bbb);

三、函数指针数组

数组的每个元素都是函数指针;

int (* arr[3]) (int, int) 

好处是可以通过数组下标,在不同的情况调用不同的函数,且不用增加判断分支语句,代码量和需要修改的代码少。——  这种使用方式被称为“转移表”

四、指向函数指针数组的指针

int (*p) (int, int);  // 函数指针

int (*p[3]) (int, int);  // 函数指针数组

int (*(*p)[3]) (int, int);  // 指向函数指针数组的指针

五、回调函数

函数指针有一个非常大的用途就是实现回调函数;回调函数,就是将A的函数指针作为参数传给函数B,由函数B在某些特定的情况下通过该指针调用函数A,这样就实现了回调;

// 标准库里面的 —— “qsort”

// 1、采用快速排序

// 2、适合于任何类型

// void qsort(void* base, size_t num, size_t size, int (*cmp)(const void*, const void*))

// base指向被排序数组的首地址,单个元素是size长,总共有num个数据,排序规则为cmp

// 这里面cmp就是回调函数,实现不同任意类型排序

 

//扩展

//void*—— 无具体类型的指针,什么类型的指针都可以存放在void*中

// 这种类型的指针是不能进行解引用操作的,也不能进行指针运算;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值