当前位置: 首页 > news >正文

嵌入式学习笔记十三——C语言指针变量、一维数组的指针、快速排序

指针变量

指针初始化

指针变量初始化:如果没有初始化,指针是随机值,既野指针。初始化可以让指针变量有明确的指向。

	int a = 10;int *p = &a;//指针初始化int *p = NULL; //NULL 0号地址   --- 空指针 

指针赋值

	int * p;p = NULL;int a;int *p;p = &a;int *p,q; //p是指针类型 int * //q是int型int *p,*q; //此时表示定义了两个 int*类型的变量 p 和q //注意:  //定义时候的 * 修饰变量名的 表示定义的是一个指针类型的变量 

为什么需要地址?

    为了实现被调修改主调函数,值传递无法改变主函数中的数据,如果要对数据进行修改,就要用到指针进行地址传递。

指针作为函数的参数

形参:指针类型变量,用来接收实参,实参是要操作的内存空间的地址。

实参:需要修改的变量的地址,被调函数1中一定要有*运算

体会指针,被调修改主调,练习:1.找出两个数中最大值 和 最小值写成函数 2.写swap()函数,实现交换两数的值。     

#include <stdio.h>
void add(int n,int m,int *sum)
{*sum = n + m;
}
void findMaxMin(int n,int m,int *max,int *min)
{if(n>m){*max = n;*min = m;}else {*max = m;*min = n;}
}
void Swap(int *a,int *b)
{int t = *a;*a = *b;*b = t;
}
int main(void)
{int x=5,y=10;int sum;int max;int min;
//	add(x,y,&sum);
//	printf("%d\n",sum);
//	findMaxMin(x,y,&max,&min);
//  printf("max = %d\nmin = %d\n",max,min);Swap(&x,&y);printf("x = %d\ny = %d\n",x,y);return 0;
}

形参中的指针类型变量,只需定义需要修改的变量就可以,其他的值如果也用地址来操作就有些多于了,效率也会降低。需要修改的数据,在传入实参时要用取地址&来传入地址。

指针和一维整型数组

int  a[5]; 数组名a表示数组首元素的地址,数组名是个常量不能自增自减。

a =>&a[0]   a[0]的数据类型是int,&a[0]的数据类型是int*(指针类型)

int *p = a; p指向数组a

指针运算:&取地址,*指针运算(访问运算对象指向的地址)

p+1,p+n,p-1,p-n,p++,p--:表示(+向后,-向前)跳过了一个或n个基类型。

对数组指针进行自加减:

//打印数组
void printArray(int *a,int len)
{int i = 0;for (i = 0;i < len ;++i){printf ("a[%d] = %d\n",i,*a++);//	printf ("a[%d] = %d\n",i,a[i]);//	printf ("a[%d] = %d\n",i,i[a]);//	printf ("a[%d] = %d\n",i,*(a+i));}
}

1. a <=>  &a[0]//a[0]的数据类型 -- int型 ,&a[0]  地址的类型 -- int* 

int *p = a; //表示 p指向数组a

此时*p等价于a[0],*p 访问指针p指向的地址中的内容。*p  <=> a[0]

2.*(p+i) <=> a[i] <=> *(a+i)//a是一个地址,代表首元素首地址,所以a = & a[0]  <=> p
 a[i]  <=> *(a+i)
 i[a]  <=> *(i+a) //a[i]==i[a];

所以上述代码中所有printf打印的内容都相同。

3.如果p,q,都是地址,则:

p - q     //表示差了多少元素(基类型)

两指针相减,必须是同一类型的指针  
          
p + q     是不允许的,会报错,没有意义。 

用指针可以实现用迭代的方式实现逆序,排序和查找。

练习:

1. 准备一个数组,找数组中的最大值 ,用指针完成。

2.数组逆序。

3.对数组排序。
 下面的代码只要修改主函数就能实现相关功能。

void findMax(int *a,int len)//找最大值
{int i = 0;int max = *a;for (i = 0;i < len;++i){if (*(a+i)>max)max = *(a+i);}return max;
}void printArray2(int *begin,int *end)//打印
{while (begin <= end)printf("%d ",*begin++);putchar('\n');
}void revArray(int *begin,int *end)//数组逆序
{int t;while(begin < end)//不用等于{t = *begin;*begin=*end;*end = t;++begin;--end;}
}
void selectSort(int *begin,int *end)//选择排序
{int *p;int *q;for (p = begin;p < end;++p){for (q = p+1;q <= end;++q)if (*q < *p)Swap(q,p);}
}void bubbleSort(int *begin,int *end)//冒泡排序
{int *p;int *q;for (p = end;p >begin;--p){for (q = begin;q < p;++q){if (*q > *(q+1))Swap(q,q+1);}}}
void insertSort(int *begin,int *end)//插入排序
{int *p;int *q;for (p = begin+1;p <= end;++p){int t = *p;q = p;while (q > begin && t < *(q-1)){*q = *(q -1);--q;}*q = t;}
}int * binaryFind(int *begin,int *end,int n)//二分查找
{int *ret = NULL;int *mid;while (begin <= end){mid = begin + (end - begin)/2;if(*mid < n)end = mid - 1;else if (*mid > n)begin = mid +1;else{ret = mid;break;}}return ret;}int main(void)
{int a[] = {1,5,7,8,4,1,3};int len = sizeof(a)/sizeof(a[0]);
//    printArray2(a,a+len-1);int max = 0;findMax(a,5,&max);printf("max = %d\n",max);insertSort(a,a+len-1);
//	revArray(a,a+len-1);int n;scanf("%d",&n);printArray2(a,a+len-1);return 0;
}

快速排序

思想:使用分治法的策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。快速排序的基本思想可以概括为以下几个步骤:

1.选择基准值:从数组中选择一个元素作为基准值(pivot),通常选择第一个元素、最后一个元素或中间元素。

2.分区操作:重新排列数组,使得所有比基准值小的元素都在基准值的左边,所有比基准值大的元素都在基准值的右边。这个称为分区(partitioning)的过程。

3.递归排序:递归地将上述步骤应用到基准值左边和右边的子数组上。

4.结束条件:当子数组的大小减少到1或0时,递归结束。

理解过程:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 25考研计算机组成原理复习·3.3主存储器与CPU的连接·3.4外部存储器
  • Web前端开发环境搭建
  • 后台数据库与Excel互联操作
  • 基于大数据的气象数据分析与可视化系统设计与实现【爬虫海量数据,LSTM预测】
  • SSRS rdlc报表 九 在.net core中使用RDLC报表
  • Linux 下查看 CPU 使用率
  • 达梦数据库 逻辑备份还原
  • SQL注入第一关-Less1
  • 备战秋招60天算法挑战,Day12
  • 企业数据治理之主数据治理--组织主数据
  • 学习记录第二十天
  • 从零搭建xxl-job(四):xxljob进行一些性能优化
  • 每天写两道(数组篇)在排序数组中查找元素的第一个和最后一个位置、x的平方根
  • Linux系统编程 day09 线程同步
  • 学生公寓电费信息管理小程序的设计
  • 时间复杂度分析经典问题——最大子序列和
  • Angular数据绑定机制
  • Effective Java 笔记(一)
  • FastReport在线报表设计器工作原理
  • Java Agent 学习笔记
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • js中forEach回调同异步问题
  • NSTimer学习笔记
  • PHP变量
  • vuex 笔记整理
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 汉诺塔算法
  • 前端性能优化--懒加载和预加载
  • 通过几道题目学习二叉搜索树
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 线上 python http server profile 实践
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #单片机(TB6600驱动42步进电机)
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (55)MOS管专题--->(10)MOS管的封装
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)ABI是什么
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)树状数组
  • (自用)gtest单元测试
  • .NET 4.0中的泛型协变和反变
  • .NET Core Web APi类库如何内嵌运行?
  • .net 获取url的方法
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NetCore部署微服务(二)
  • .NET分布式缓存Memcached从入门到实战
  • @SentinelResource详解
  • [20180129]bash显示path环境变量.txt