嵌入式课程day14-C语言指针进阶

目录

10.3指针进阶

10.3.1数组指针

10.3.2指针数组

10.3.3函数指针

10.3.4指针函数

10.3.5函数指针的实际应用案例qsort函数:


10.3指针进阶

10.3.1数组指针

是指针 --- 指向对象的类型是 数组 int [3]

数组指针一般用于指向二维数组里面的一行, --- 行指针,存储行地址

数组指针定义:

数据类型 (* 指针名)[元素个数];

int a[2][4] = {{1,3,4,5},{6,7,8,9}
};// 定义一个数组指针指向 第0行。  int [4]
int (*p)[4];   // 4 或者 8 指针名:p
指针类型:int (*)[4]
指针指向对象类型: int[4]p = a;// 分析:
// p + i  ---- i行的行地址		
// *(p+i) ---- i行0列的  列地址		
// *(p+i)+j ---- i行j列的地址 	// 空间列地址:*(p+i)+j     &a[i][j]
// 空间列名称:*(*(p+i)+j)   a[i][j]int i, j;for (i = 0; i < 2; i++)
{for (j = 0; j < 4; j++){printf ("%d ", *(*(p + i) + j));}printf ("\n");
}注意区分: 二维数组的地址偏移  行地址偏移  列地址的偏移  -- 类型不一样使用就不一样
//#include<stdio.h>
//
//int main(void)
//{
//	int a[2][4] = {
//		{1,3,4,5},
//		{6,7,8,9}
//	};
//	
//	// 定义数组指针指向a[0]
//	int (*p)[4] = a;
//	
//	printf("%p %p\n",&a,&a+1);
//	printf("%p %p\n",p,p+1);              // 行地址
//	printf("%p %p\n",*(p+0),*(p+1));     //  每一行的首列的地址	
//	printf("%p %p\n",*(p+0)+1,*(p+1)+1); // 列地址的偏移	 
//		
//	return 0;
//}

数组指针应用场景:

需要将二维数组传递到函数内部使用。

void test (int (*p)[4], int row, int col)
{int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf ("%d ", *(*(p + i) + j));}printf ("\n");}
}int main ()
{int a[2][4] = {{1,3,4,5},{6,7,8,9}};int r = sizeof (a) / sizeof (a[0]);int c = sizeof (a[0]) / sizeof (a[0][0]);test (a, r, c);   // 实参 是 &a[0] -- 行地址  ---- 形参和实参在类型上要一致,接收行地址用行指针。return 0;
}

总结:    

数组指针 是一个 指针指向 二维数组的一行, 一般用于将一个二维数组传入到函数内部的时候用,形参设计成数组指针。

10.3.2指针数组

是数组 里面存储同种类型的指针。

指针数组定义:

指针类型 数组名[元素个数];

例子:
int a = 10;
int b = 20;// &a  &b  ----  int *// 定义一个数组用来存储 &a &b 
int* arr[2];arr[0] = &a;
arr[1] = &b;int i;
for (i = 0; i < 2; i++)
{printf ("%d ", *(arr[i]));
}

总结:
数组指针:
行指针  -- 指向二维数组的一行 存储行地址

int (*p)[4];  // 4/8

和 二位数组的数组名用法类似
数据地址:* (p + i) + j
数据空间: * (*(p + i) + j)

场景:将二维数组传入到函数内部,形参设计成数组指针。

指针数组:
数组,里面存储同种类型的指针。

int* arr[2];  // 8 / 16

先按照数组[下标] 获取指针元素,在将指针元素按照指针使用。

10.3.3函数指针

是指针,指向对象类型是函数类型

(准备函数、定义函数指针、函数指针指向函数、函数指针定义函数)

函数指针的定义:

函数类型 *指针名;

#include<stdio.h>//test 是个函数,它的参数是函数指针,即p
void test (int (*p)(int, int),int a,int b)
{int res = p(a,b);printf ("%d \n", res);
}int add (int a,int b)
{return a + b;
}
int dis (int a, int b)
{return a - b;
}
int mul (int a, int b)
{return a * b;
}int main ()
{test (mul,6,9);return 0;
}

10.3.4指针函数

是函数,函数的返回值是指针类型,函数返回一个地址。

定义指针函数

指针类型 函数名(形参列表)
{函数体return 地址;
}
指针类型 变量名 = 调用函数(形参列表);

注意:指针函数返回的地址 不能是局部变量的地址

可以返回传入到函数内部的空间外部空间的地址 或者 动态内存申请的地址

错误案例
int *test()
{int n;return &n;
}
返回的地址在调用函数结束之后就被销毁了,还返回有啥用?

10.3.5函数指针的实际应用案例qsort函数:

qsort函数分析

qsort函数C语言编译器函数库自带的排序函数。

qsort 的函数原型是

void qsort(void*base,size_t num,size_t width,int(*compare)(const void*,const void*));      

qsort函数包含在C 标准库 - <stdlib.h>中。

函数原型分析:

void qsort(void*base,size_t num,size_t width,int(*compare)(const void*,const void*));

函数名:qsort

返回值类型:void

形参列表:

void *base , 接收任意类型地址  --- 数组首元素的地址

size_t nitems,  接受整型数据   --- 数组中元素的个数

size_t size, 接受整型数据      --- 数组中每个元素所占字节数

int(*compare)(const void*,const void*)    函数指针 --- 接受函数地址  --- 比较两个元素的函数

函数指针指针名:compare

函数指针指向对象类型: int (const void*,const void *)

返回值 >0 就交换位置

返回值 <0 就                

#include<stdio.h>
#include<stdlib.h>// 返回值 >0 就交换位置 // 从小到大		 
int cmp (const void* a, const void* b)
{return	*((int*)a) - *((int*)b);
}int main (void)
{int a[] = { 3,5,19,5,4,2,79,5,4,6,7,8 };int len = sizeof (a) / sizeof (a[0]);qsort (a, len, sizeof (a[0]), cmp);int i;for (i = 0; i < len; i++){printf ("%d ", a[i]);}return 0;
}

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

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

相关文章

蓝桥杯模拟

【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果为一个整数&#xff0c;在提交答案时只…

Ruby编程语言全景解析:从基础到进阶

Ruby是一种动态的、面向对象的编程语言&#xff0c;以其优雅的语法和强大的功能而闻名于世。自从1995年由日本程序员松本行弘&#xff08;Yukihiro Matsumoto&#xff09;发布以来&#xff0c;Ruby便迅速成为了开发者中颇受欢迎的编程语言之一。无论是构建简单的脚本还是复杂的…

数据结构的时间复杂度和空间复杂度

目录 时间复杂度 空间复杂度 时间复杂度 基本操作的执行次数&#xff0c;为时间复杂度。 我们使用大O的渐进表示法来表示时间复杂度。 怎么使用&#xff1f; 先看例子&#xff1a; 在这个例子中&#xff0c; 基本操作为变量 count 的 加加 操作&#xff0c;并且&#xff0c;执行…

Ubuntu20.04 解决一段时间后键盘卡死 输入延迟很大的问题 ubuntu

Ubuntu20.04 解决一段时间后键盘卡死 输入延迟很大的问题 为了确保您能顺利通过双击快捷方式来重启 IBus&#xff0c;下面详细描述了从脚本创建到快捷方式设置的每一步&#xff0c;包括具体的命令行操作和必要的说明&#xff0c;以确保您能够按步骤成功执行。 步骤 1: 创建并…

解决Oracle DECODE函数字符串截断问题的深度剖析20241113

解决Oracle DECODE函数字符串截断问题的深度剖析 在使用Oracle数据库进行开发时&#xff0c;开发者可能会遇到一些令人困惑的问题。其中&#xff0c;在使用DECODE函数时&#xff0c;返回的字符串被截断就是一个典型的案例。本文将以学生管理系统为背景&#xff0c;深入探讨这个…

【Chapter 3】Machine Learning Classification Case_Prediction of diabetes-XGBoost

文章目录 1、XGBoost Algorithm2、Comparison of algorithm implementation between Python code and Sentosa_DSML community edition(1) Data reading and statistical analysis(2)Data preprocessing(3)Model Training and Evaluation(4)Model visualization 3、summarize 1…

Rust Struct 属性初始化

结构体是用户定义的数据类型&#xff0c;其中包含定义特定实例的字段。结构有助于实现更容易理解的抽象概念。本文介绍几种初始化结构体对象的方法&#xff0c;包括常规方法、Default特征、第三方包实现以及构建器模式。 Struct声明与初始化 struct Employee {id: i32,name: …

AI大模型微调:Qwen2大模型微调入门实战(完整代码)

简介&#xff1a; 该教程介绍了如何使用Qwen2&#xff0c;一个由阿里云通义实验室研发的开源大语言模型&#xff0c;进行指令微调以实现文本分类。微调是通过在&#xff08;指令&#xff0c;输出&#xff09;数据集上训练来改善LLMs理解人类指令的能力。教程中&#xff0c;使用…

树莓派(Raspberry Pi)Pico 2 C_C++开发环境配置(Docker+SDK)

树莓派&#xff08;Raspberry Pi&#xff09;Pico 2 C_C开发环境配置&#xff08;DockerSDK&#xff09; 开发环境容器系统环境配置配置 Raspberry Pi Pico 2 C/C 开发环境编译构建 Blink 示例程序下载 pico-sdk 和 pico-examples构建 Blink 链接 文章介绍了在容器中配置Raspbe…

剑指offer第二版(PDF+源码)

通过百度网盘分享的文件&#xff1a;剑指offer第二版(PDF源码).zip 链接&#xff1a;https://pan.baidu.com/s/11chsELiBIgjLR1mW7M8j1g?pwd1pq7 提取码&#xff1a;1pq7 《剑指Offer》第二版&#xff1a;开启求职编程之路的宝藏资源 在编程学习与求职准备的征程中&#xf…

Mac打开time machine(时间机器)备份特殊文件

Mac 打开time machine&#xff08;时间机器&#xff09;备份特殊文件 设置“时间机器”的作用具体操作办法 前言&#xff1a;今天在使用Nas同步文件时发现有部分重要文件没有同步&#xff0c;为了省事手动拖拽复制文件&#xff0c;导致其中一份非常重要的文件丢失&#xff0c;尝…

基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统

项目名称&#xff1a;基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具&#xff1a;PyCharm、Visual Studio Code (VSCode)运行环境&#xff1a;Python 3.10、MySQL 8.0、Node.js 18技术框架&#xff1a;Django 5、Vue 3.4、Ant-Design-Vue 4.12 …

vue2,vue3响应式的理解

vue2的话主要使用的是defineProperty对已有属性添加get,set,从而完成对数据的响应式控制&#xff0c;但每次需要for循环对属性进行遍历 function DefineReactive(target, key, value) {//存在多层嵌套的objectObserver(value);Object.defineReactive(target, key, {get() {retu…

SpringBoot 创建对象常见的几种方式

SpringBoot 创建对象常见的几种方式 在 Spring Boot 中&#xff0c;将 Bean 对象添加到 IOC 容器中&#xff0c;通用的有下面几种方式&#xff1a; 使用 Component、Service、Repository 或 Controller 注解使用 Configuration 和 Bean 注解使用 Import 注解导入其他配置类通…

游戏服务器和普通服务器的区别

服务器&#xff0c;顾名思义&#xff0c;是提供服务的设备&#xff0c;在计算机领域&#xff0c;服务器是指具有网络功能的高性能计算机&#xff0c;用于存储、处理和传输数据&#xff0c;而游戏服务器则是专门为游戏提供服务的服务器&#xff0c;它需要具备更高的性能、更稳定…

C++初阶:类和对象(上)

1. 类的定义 1.1 类的定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{ } 中为类的主体&#xff0c;注意类定义结束后的分号不能省略。类体中的内容为类的成员&#xff1a;类中的变量称为类的属性或成员变量&#xff1b;类中的函数称为类的方法或成员…

ctfshow DSBCTF web部分wp

ctfshow 单身杯 web部分wp web 签到好玩的PHP 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__);class ctfshow {private $d ;private $s ;private $b ;private $ctf ;public function __destruct() {$this->d (string)$this->d;$this…

Git别名设置

在 Git 中设置命令别名可以让你更高效地使用常见的 Git 命令。通过为常用命令创建简短的别名&#xff0c;可以减少输入的字符数并加速工作流程。 参考链接 设置 Git 命令别名的方法&#xff1a; 使用 Git 配置命令&#xff1a; Git 允许通过 git config 命令来设置命令别名。这…

【分布式】万字图文解析——深入七大分布式事务解决方案

分布式事务 分布式事务是指跨多个独立服务或系统的事务管理&#xff0c;以确保这些服务中的数据变更要么全部成功&#xff0c;要么全部回滚&#xff0c;从而保证数据的一致性。在微服务架构和分布式系统中&#xff0c;由于业务逻辑往往会跨多个服务&#xff0c;传统的单体事务…

HarmonyOS开发 API 13发布首个Beta版本,部分已知的问题建议处理方案

HarmonyOS 5.0.1 Beta3&#xff0c;是HarmonyOS开发套件基于API 13正式发布的首个Beta版本。该版本在OS能力上主要增强了C API的相关能力&#xff0c;多个特性补充了C API供开发者使用。该版本对部分已知问题做了解决和优化&#xff0c;部分问题给出了解决方案和适配计划&#…