玳瑁的嵌入式日记D12-0805(C语言)
指针


1.认识指针
(1).指针概念
指针 就是 地址
地址 就是 内存单元的编号
代表的意义:
地址 只是 告诉了说 在哪里
(2).指针类型
地址 本身 是一种特殊的数据 --- 是具有指向含义的 整数
c语言为了能够表示这种特殊的数据
专门设计一种数据类型 --- 指针类型
2.定义指针(变量)
语法:
基类型 * 指针变量名;
(1) (2) (3)
(1)基类型
基类型说明了 通过指针 找到的空间
a.多大
b.怎么用
就是 指针找到的空间上 所存储的 数据类型
(2) *
只是一个修饰符
用来说明现在定义的变量,不是普通变量,而是指针变量
(3)指针变量名
是个标识符 ,符合标识符命名规则
定义多个指针变量:
int *p1,*p2,*p3; //*用来修饰变量名
*p1
*p2
*p3
eg:
int a = 10; //定义一个int型变量 初始化为10
int * p = &a; //定义了一个指针类型的变量p
//用a的地址初始化
//说,p指向了a
eg:
地址 是 内存单元的编号 -- 就是编号本身
记录地址的指示牌 --- 相当于是指针变量
通过指针变量(指示牌) ---获得地址信息
|----告诉说在哪里
理解:
1.指针 就是 地址
地址 内存单元编号
2.通过地址 只能 完成 找到 对应的空间 这个事情
3.通过指针实现数据引用
int a = 10;
int *p = &a;
此时通过p 找到空间
如果要用,还必须 指针的间接访问 操作
指针运算符 *
*地址数据
作用:
表示 使用 地址 所在的 空间
*p //相当于是在用a的空间
此时a的空间两种使用方式
1.通过a直接使用 --- 直接访问
2.通过p来使用 --- 通过p拿到地址值 ,再对地址做*运算 ,才能使用到a的空间
间接访问
*p 运算过程:
step1:从p中拿出地址值,到内存中定位
step2:从定位处开始偏移sizeof(基类型)大小的一块空间
step3:将这块空间当做一个基类型变量/数据来看
*p <=> a
4.为什么需要指针的间接访问
a.可以使函数带出多个结果
//指针间接访问
b.提高效率
函数传参
避免了大数据的拷贝
5.用途
被调函数中,实现对主调函数中 数据的使用和修改
指针类型
int *p; //p是个什么类型?
//int* ---指针类型 ---表示的是这么一类指针 --- 基类型为int型的这一类指针
6.想要实现 被调 修改 主调
a.要修改谁 就把谁的地址传过去
b.被调函数中,还必须有对应的 *p 这样运算
函数传参的方式:
值传递 --- 实参的值 给到 形参变量
地址传递 --- 可以实现被调修改主调
练习:
实现一个函数,得到 两个整数 和 和 差

练习:
实现一个函数,找出两个整数中的最大值 和 最小值

练习:
实现一个函数,完成两个整型数的交换

指针的运算
&
*
int a = 10;
int *p = &a;
指针的多种表示
printf("%p\n",&*p); //&(*p)
printf("%p\n",*&p); //*(&p) //
printf("%d\n",*&a);
printf("%d\n",&*a); //error a是整型数据 不是 地址数据
指针 算术运算
+ - * / % ++ --
p+1 //指针加 1 表示 指向了下一个 基类型
p+n //sizeof(基类型)*n
p-1
p-n
p++
p--
++p
--p
p+q //p q 都是指针 ---两个指针不能相加
p-q //可以相减
//要求,必须是同类型指针
// 表示 相差了几个 基类型
* / %
//指针不能做 * / %
int a = 10;
short *p = (short *)&a; // &a --- 地址值类型 int *
// int *p = &a;
p的类型 short *
int a = 0x12345678;
short *p = (short *)&a; // &a --- 地址值类型 int *
// int *p = &a;
+-------+ <--- 0x1000小端
| 0x78 |
+-------+ <--- 0x1001
| 0x56 |
+-------+ <--- 0x1002
| 0x34 |
+-------+ <--- 0x1003
| 0x12 |
+-------+ <--- 0x1004
| |
+-------+
| |
+-------+
| 0x1000| p
+-------+
| |
+-------+
考点:
请写程序判断你电脑大小端?

a = 1;
在十六进制中为0000 0001;
若为小端,则printf("%d\n",*p)输出为 1
反之为 0
关系运算 (看的就是指针的数值 地址编号大的 就大)
> >= < <= == !=
p1 == &m
指针 + 整型一维
int a[10] = {1,2,3,4,5,6,};
//数组的特点:
连续 有序 单一
操作数组 --- 只需要获得首元素的地址即可
p+1 //指针运算
p+2
*(p+3)
a[0] //首元素
&a[0] //首元素地址 ----啥类型
// a[0] 是什么类型 --- int类型
// &a[0] 地址就是 int *
int *p = &a[0]; //指针变量 指向了数组首元素
//指向了数组
a 数组名 --- 数组名
代表类型 --- 数组类型
代表的值 --- 首元素的地址
int *p = a; //说 p 指向了 数组a
a[i] //数组下标的方式 --- 其实本质就是 指针的运算

i[a] // *(i+p)
特殊的指针:
NULL ---空指针 --- 地址编号为 0 的地址
野指针 --- 野指针 需要避免出现
指向不明确
练习:
准备一个数组,实现函数找出最大值
*(p+i)

练习:
逆 序

练习:
排序
选择排序 //



练习:
查找
返回? -- 找到元素的指针
NULL

快速排序
效果
//1.函数
//2.指针
//3.递归
b e
0 1 2 3 4 5 6 7 8 //下标
[3 1 4 7 8 2 4 0 5 ] //数值
step1: 找一个基准值
//数组的第一个元素
step2: 从右往左 开始找 第一个比 基准值 小 的值
step3: 从左往右 开始找 第一个比 基准值 大 的值
step4: 交换找到值,重复step2 到 step4
直到begin 和 end相遇
step5: 相遇后,将相遇位置上的值 与 基准值 交换
e
b
0 1 2 3 4 5 6 7 8 //下标
[2 1 0 3 8 7 4 4 5 ] //数值
-
step6: 对小的一部分 继续快速排序
对大的一部分 继续快速排序
void quickSort(int *begin,int *end)
{
int *p = begin;
int *q = end;
if (begin >= end)
{
return ;
}
//step1: 找一个基准值
int *k = begin;
while (begin < end)
{
//step2: 从右往左 开始找 第一个比 基准值 小 的值
// *k 基准值
while (begin < end && *end >= *k)
{
--end;
}
//step3: 从左往右 开始找 第一个比 基准值 大 的值
// *k 基准值
while (begin < end && *begin <= *k)
{
++begin;
}
//step4: 交换找到值,重复step2 到 step4
直到begin 和 end相遇
swap(begin,end);
}
//step5: 相遇后,将相遇位置上的值 与 基准值 交换
swap(begin,k);
//step6: 对小的一部分 继续快速排序
//对大的一部分 继续快速排序
quickSort(p,end-1); //小的一部分
quickSort(begin+1,q); //大的一部分
}


openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)