C语言_指针进阶(下)

文章目录

  • 前言
  • 一、函数指针数组
  • 二、指向函数指针数组的指针
  • 三. 回调函数
  • 四. qsort 函数
  • 五. 数组名的理解 sizeof
    • 5.1 数组名的理解(二维数组)
      • 5.1.1 数组名的理解 strlen
      • 5.1.2 例题:
        • 例一.
        • 例二.
        • 例三.
        • 例四.


前言


一、函数指针数组

数组是一个存放相同类型数据的存储空间,
那把函数的地址存放到一个数组中,那这个数组就叫函数指针数组
提示:以下是代码样例,下面案例可供参考

int Add(int x, int y) //加
{return x + y;
}int Sub(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;
}
//计算器
void  menu()
{printf("************************\n");printf("*****1. Add 2. Sub *****\n");printf("*****3. Mul 4. Div *****\n");printf("*****  0. exit  ********\n");printf("************************\n");
}int main()
{int x = 0;int y = 0;int ret = 0;int input = 0;//定义一个函数指针数组int (*pfArr[5])(int, int) = { NULL,Add,Sub,Mul,Div };//                             0     1   2   3   4do{menu();printf("请选择:>\n");scanf("%d", &input);if (input >= 1 && input <= 4){printf("请输入两个操作数:");scanf("%d %d", &x, &y);ret = pfArr[input](x, y);printf("ret = %d\n", ret);}else if (input = 0){printf("退出计算器\n");}else{printf("选择错误,重新选择\n");}} while (input);return 0;
}

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

三. 回调函数

回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时有另外的一方调用的,用于对该事件或条件进行响应。

四. qsort 函数

qsort 是标准库函数,用于对数组中的元素进行快速排序。它通过比较两个元素的大小来确定它们的顺序。以下是 qsort 函数的定义:

void qsort(void *base, size_t count, size_t size, int (*compare)(const void *, const void *));

参数说明:

  • base:指向要排序的数组的第一个元素的指针。
  • count:要排序的元素数量。
  • size:每个元素的字节数。
  • compare:一个比较函数,用于比较两个元素的大小。该函数返回一个整数值,指示两个元素的顺序关系。如果返回负数,则表示第一个元素应该排在第二个元素的前面;如果返回正数,则表示第一个元素应该排在第二个元素的后面;如果返回 0,则表示两个元素相等。

使用 qsort 函数时,需要自定义一个比较函数,根据实际需要对元素进行比较。以下是一个简单的示例:

#include <stdio.h>
#include <stdlib.h>int compare(const void *a, const void *b) {return (*(int*)a - *(int*)b);
}int main() {int arr[] = {3, 1, 4, 2, 5};int n = sizeof(arr) / sizeof(int);qsort(arr, n, sizeof(int), compare);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

输出结果为:1 2 3 4 5,表示数组已经按从小到大的顺序排好了序。qsort 是标准库函数,用于对数组中的元素进行快速排序。它通过比较两个元素的大小来确定它们的顺序。以下是 qsort 函数的定义:

void qsort(void *base, size_t count, size_t size, int (*compare)(const void *, const void *));

参数说明:

  • base:指向要排序的数组的第一个元素的指针。
  • count:要排序的元素数量。
  • size:每个元素的字节数。
  • compare:一个比较函数,用于比较两个元素的大小。该函数返回一个整数值,指示两个元素的顺序关系。如果返回负数,则表示第一个元素应该排在第二个元素的前面;如果返回正数,则表示第一个元素应该排在第二个元素的后面;如果返回 0,则表示两个元素相等。

使用 qsort 函数时,需要自定义一个比较函数,根据实际需要对元素进行比较。以下是一个简单的示例:

#include <stdio.h>
#include <stdlib.h>int compare(const void *a, const void *b) {return (*(int*)a - *(int*)b);
}int main() {int arr[] = {3, 1, 4, 2, 5};int n = sizeof(arr) / sizeof(int);qsort(arr, n, sizeof(int), compare);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

输出结果为:1 2 3 4 5,表示数组已经按从小到大的顺序排好了序。qsort 是标准库函数,用于对数组中的元素进行快速排序。它通过比较两个元素的大小来确定它们的顺序。以下是 qsort 函数的定义:

void qsort(void *base, size_t count, size_t size, int (*compare)(const void *, const void *));

参数说明:

  • base:指向要排序的数组的第一个元素的指针。
  • count:要排序的元素数量。
  • size:每个元素的字节数。
  • compare:一个比较函数,用于比较两个元素的大小。该函数返回一个整数值,指示两个元素的顺序关系。如果返回负数,则表示第一个元素应该排在第二个元素的前面;如果返回正数,则表示第一个元素应该排在第二个元素的后面;如果返回 0,则表示两个元素相等。

使用 qsort 函数时,需要自定义一个比较函数,根据实际需要对元素进行比较。以下是一个简单的示例:

#include <stdio.h>
#include <stdlib.h>int compare(const void *a, const void *b) {return (*(int*)a - *(int*)b);
}int main() {int arr[] = {3, 1, 4, 2, 5};int n = sizeof(arr) / sizeof(int);qsort(arr, n, sizeof(int), compare);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

输出结果为:1 2 3 4 5,表示数组已经按从小到大的顺序排好了序。

五. 数组名的理解 sizeof

提示:以下是代码样例,下面案例可供参考

char arr[] = "abcdef";//[a b c d e f \0]printf("%d\n", sizeof(arr));//7//char [7]printf("%d\n", sizeof(arr + 0));//arr + 0是首元素的地址   4printf("%d\n", sizeof(*arr));//*arr其实就是首元素,1个字节   //*arr--> *(arr+0) -- arr[0]printf("%d\n", sizeof(arr[1]));//arr[1]是第二个元素,1个字节   printf("%d\n", sizeof(&arr));//&arr是数组的地址,是地址就是4/8个字节printf("%d\n", sizeof(&arr + 1));//&arr + 1是跳过一个数组的地址,4/8printf("%d\n", sizeof(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 4/8

 printf("%d\n", sizeof(p));//p是一个指针变量 大小就是4/8printf("%d\n", sizeof(p + 1));//p+1是'b'的地址,是地址大小就是4/8个字节printf("%d\n", sizeof(*p));//*p 就是'a',就是1个字节printf("%d\n", sizeof(p[0]));//p[0]--> *(p+0) --> *p  1个字节printf("%d\n", sizeof(&p));//4/8   &p -- char**printf("%d\n", sizeof(&p + 1));//4/8printf("%d\n", sizeof(&p[0] + 1));//4/8 , &p[0] + 1得到是'b'的地址 

5.1 数组名的理解(二维数组)

5.1.1 数组名的理解 strlen

特点


提示:以下是代码样例,下面案例可供参考

int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", strlen(arr));//因为字符数组arr中没有\0,所以在求字符串长度的时候,会一直往后找,产生的结构就是随机值printf("%d\n", strlen(arr + 0));//arr + 0是首元素的地址,和第一个一样,也是随机值printf("%d\n", strlen(*arr));//err(错误的写法), arr是数组首元素的地址,*arr就是数组首元素,就是'a'-97//strlen函数参数的部分需要传一个地址,当我们传递的是'a'时,'a'的ASCII码值是97,那就是将97作为地址传参//strlen就会从97这个地址开始统计字符串长度,这就非法访问内存了//printf("%d\n", strlen(arr[1]));//errprintf("%d\n", strlen(&arr));//&arr是数组的地址,数组的地址和数组首元素的地址,值是一样的,那么传递给strlen函数后,依然是从数组的第一个元素的位置开始往后统计printf("%d\n", strlen(&arr + 1));//随机值printf("%d\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址。结果也是随机值return 0;
}
char* p = "abcdef";//     012345printf("%d\n", strlen(p));//6printf("%d\n", strlen(p + 1));//5//printf("%d\n", strlen(*p));//err//printf("%d\n", strlen(p[0]));//errprintf("%d\n", strlen(&p));//随机值  编译器会随机给他分配地址printf("%d\n", strlen(&p + 1));//随机值  &p+1  与  &p  没有差异,没啥关系printf("%d\n", strlen(&p[0] + 1));//5
int a[3][4] = { 0 };printf("%d\n", sizeof(a));//3*4*4 = 48printf("%d\n", sizeof(a[0][0]));//4  零行零列的元素printf("%d\n", sizeof(a[0]));//a[0]是第一行这个一维数组的数组名//数组名算是单独放在sizeof内部了,计算的是整个数组的大小,大小是16个字节printf("%d\n", sizeof(a[0] + 1));//?//a[0]作为第一行的数组名,没有单独放在sizeo内部,没有&//a[0]表示数组首元素的地址,也就是a[0][0]的地址//所以a[0]+1是第一行第二个元素的地址,是地址就是4/8个字节printf("%d\n", sizeof(*(a[0] + 1)));//4//计算的是就是第一行第2个元素的大小printf("%d\n", sizeof(a + 1));//4 / 8//a是数组首元素的地址,是第一行的地址 int(*)[4]//a+1 就是第二行的地址printf("%d\n", sizeof(*(a + 1)));//16//*(a+1) --> a[1] -> sizeof(*(a+1))->sizeof(a[1]) 计算的是第二行的大小//a+1 --> 是第二行的地址,int(*)[4]//*(a+1) 访问的第二行的数组printf("%d\n", sizeof(&a[0] + 1));//4/8//&a[0]是第一行的地址 int(*)[4]//&a[0]+1 是第二行的地址 int(*)[4]printf("%d\n", sizeof(*(&a[0] + 1)));//16 计算的是第二行的大小printf("%d\n", sizeof(*a));//计算的是第一行的大小-16//a是数组首元素的地址,就是第一行的地址//*a 就是第一行//*a --> *(a+0) --> a[0]printf("%d\n", sizeof(a[3]));//16//a[3]--> int [4]

5.1.2 例题:

例一.

例二.

例三.

例四.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107189.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于STM32程序万年历液晶1602显示-proteus仿真-源程序

一、系统方案 本设计采用STM32单片机作为主控器&#xff0c;液晶1602显示&#xff0c;按键设置万年历。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 //通用定时器3中断初始化 //这里时钟选择为APB1的2倍&#xff0c;而APB1为36M //arr&…

强大的JTAG边界扫描(5):FPGA边界扫描应用

文章目录 1. 获取芯片的BSDL文件2. 硬件连接3. 边界扫描测试4. 总结 上一篇文章&#xff0c;介绍了基于STM32F103的JTAG边界扫描应用&#xff0c;演示了TopJTAG Probe软件的应用&#xff0c;以及边界扫描的基本功能。本文介绍基于Xilinx FPGA的边界扫描应用&#xff0c;两者几乎…

嵌入式学习之链表

对于链表&#xff0c;要重点掌握链表和数组区别和实现&#xff0c;链表静态添加和动态遍历&#xff0c;链表中pointpoint-next,链表节点个数的查找&#xff0c;以及链表从指定节点后方插入新节点的知识。

024 - STM32学习笔记 - 液晶屏控制(一) - LTDC与DMA2D初始

024- STM32学习笔记 - LTDC控制液晶屏 在学习如何控制液晶屏之前&#xff0c;先了解一下显示屏的分类&#xff0c;按照目前市场上存在的各种屏幕材质&#xff0c;主要分为CRT阴极射线管显示屏、LCD液晶显示屏、LED显示屏、OLED显示屏&#xff0c;在F429的开发板上&#xff0c;…

STLINK-V3 STDC14座转2.54mm排针转接板Kicad工程

简介 这是一个 STLINK-V3 STDC14座转2.54mm排针转接板Kicad工程 。STDC14座实际工作中不太方便&#xff0c;所以搞了这个转接板。另外转接版上提供了可选的电源输出功能。 An adapter board for STLINK-V3. It change the STDC14 to 2.54mm pin header.It also provides 5V an…

提示msvcr120.dll丢失怎样修复呢?全面分析msvcr120.dll解决方法

在计算机使用过程中&#xff0c;可能会遇到 msvcr120.dll 丢失的问题。msvcr120.dll 是 Microsoft Visual C Redistributable 的一部分&#xff0c;是一个动态链接库文件&#xff08;DLL&#xff09;&#xff0c;用于支持运行在 Windows 操作系统上使用了 Microsoft Visual C 2…

防止公司电脑文件数据外泄(任何途径)

公司可以采取以下措施&#xff0c;使用天锐绿盾加密管理方案&#xff0c;以防止内部终端电脑文件数据外泄&#xff1a; ▷对公司各类文档进行加密管理&#xff0c;采取高强度的加密措施&#xff0c;确保即使文档被窃取&#xff0c;也无法被打开查看。同时&#xff0c;该方案还提…

电路电子技术1--关联参考方向及功率的计算

1.判断 电流由元件的低点位端流向高电位端的参考方向称为关联参考方向。() 考点&#xff1a;电流、电压的参考方向 解释&#xff1a;在一些复杂的电路中&#xff0c;往往不能预先确定某段电路上的电流、电压的实际方向&#xff0c;所以引进了 “关联参考方向”。为了能够解决问…

无涯教程-JavaScript - RATE函数

描述 RATE函数返回年金每个周期的利率。 RATE通过迭代计算得出,可以有零个或多个解。如果RATE的连续输出在20次迭代后未收敛到0.0000001以内,则RATE返回#NUM!错误值。 语法 RATE (nper, pmt, pv, [fv], [type], [guess])有关参数nper,pmt,pv,fv和type的完整说明,请参见PV Fu…

海南大学金秋悦读《乡村振兴战略下传统村落文化旅游设计》2023新学年许少辉八一新书​

海南大学金秋悦读《乡村振兴战略下传统村落文化旅游设计》2023新学年许少辉八一新书​

2023/9/12 -- C++/QT

作业 实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xf…

2023最新计算机大数据毕业设计选题推荐100例

文章目录 0 前言1 如何选题1.1 选题技巧&#xff1a;如何避坑(重中之重)1.2 为什么这么说呢&#xff1f;1.3 难度把控1.4 题目名称1.5 最后 2 大数据 - 选题推荐2.1 大数据挖掘类2.2 大数据处理、云计算、区块链 毕设选题2.3 大数据安全类2.4 python大数据 游戏设计、动画设计类…