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

指针妙用:快速找出数组极值

求数组中最大数和最小数--利用指针

这段代码主要功能是动态定义一个整型数组,让用户输入指定数量的整数,然后找出并输出这些数中的最大值和最小值。

#include <stdio.h>
void f1(int *arr, int len)
{
if (len <= 0 || arr == NULL)
{
printf("数组长度不合法或指针为空!\n");
return;
}
printf("请输入%d个整数:\n", len);
for (int *p = arr; p < arr + len; p++) scanf("%d", p);
}
void f2(int *arr,int len,int *max,int *min)
{
if (len <= 0 || arr == NULL)
{
printf("数组长度不合法或指针为空!\n");
return ;
}
*max = *arr;
*min = *arr;
for(int *p = arr + 1;p < (arr + len);p++)
{
if(*p > *max) *max = *p;
if(*p < *min) *min = *p;
}
}
int main()
{
int n;
printf("请输入长度(数字):\n");
scanf("%d",&n);
int nums[n];
int max1,min1;
f1(nums,n);
f2(nums,n,&max1,&min1);

printf("数组:\n");
for(int i = 0;i<n;i++)
printf("%d ",nums[i]);
printf("\n最大值:%d\n最小值:%d\n",max1,min1);

return 0;
}

这段代码是学习 C 语言指针的绝佳案例。它几乎涵盖了指针在数组操作中最核心的几个概念:指针与数组的关系、指针算术、指针作为函数参数以及解引用。
下一篇文章我将结合这段代码,系统地讲解相关的指针知识。

输入函数 f1

  • 参数int *arr是数组首地址,int len是数组长度。
  • 安全检查:首先判断长度是否小于等于 0,或者指针是否为空(NULL)。这是一个很好的编程习惯,防止非法内存访问。
  • 指针遍历
    • int *p = arr:定义一个指针p,初始指向数组开头。
    • p < arr + len:循环条件。arr + len指向数组最后一个元素之后的位置(即越界的前一个位置)。只要p没到这个位置,循环就继续。
    • p++:指针向后移动一个int的位置(通常是 4 字节)。
    • scanf("%d", p):直接将输入的整数存入p指向的内存地址。注意:这里不需要取地址符&,因为p本身就是一个地址。

计算最值函数 f2

  • 参数:除了数组和长度,还传入了int *maxint *min
    • 关键点:这里传入的是地址。函数内部通过解引用操作符*(如*max = *p)直接修改main函数中对应变量的值。这是 C 语言中实现“函数返回多个值”的标准方法。
  • 初始化*max = *arr表示将数组第一个元素的值赋给max指向的变量。同理初始化min
  • 遍历优化for(int *p = arr + 1; ...)
    • 因为第一个元素已经用来初始化了,所以循环直接从第二个元素arr + 1开始,避免了不必要的自我比较。
  • 逻辑:逐个比较,动态更新最大值和最小值。

主函数main

变长数组 (VLA)int nums[n];

  • 这里数组的大小n是由用户在运行时输入的。
  • 特性:这是 C99 标准引入的特性。数组在栈(Stack)上分配。
  • 函数调用
    • f1(nums, n)nums作为数组名,自动退化为指向首元素的指针传入。
    • f2(nums, n, &max1, &min1):注意这里使用了&取地址符,将max1min1的地址传给f2,以便f2能修改它们的值。
  • 输出循环:这里使用了传统的下标法nums[i]进行遍历输出,与前面函数中的指针法形成对比,展示了两种访问数组的方式。
http://www.jsqmd.com/news/504013/

相关文章:

  • FireRedASR Pro实时字幕生成系统:低延迟架构设计与实现
  • 幻境·流金生产环境实践:日均万图生成下的显存监控与i2L采样稳定性调优
  • 量子芯片固件升级失败率下降83%的关键:C语言中volatile+memory barrier+cache-coherent DMA的4层内存语义建模(Intel Q200/Q300平台实证)
  • ComfyUI-Manager节点冲突检测:快速识别与解决冲突的完整指南
  • 贝加莱伺服系统常见故障码速查手册(附解决方案)
  • AI编程助手:3个维度解锁本地代码执行新范式
  • 光谱相机如何在恶劣环境下“透视”油污?
  • OpenClaw成本控制方案:GLM-4.7-Flash本地化部署降低Token消耗
  • Windows下用Anaconda一键搞定roLabelImg旋转框标注工具(附打包exe教程)
  • GLM-OCR惊艳效果展示:竖排中文古籍OCR,支持从右至左阅读顺序还原
  • 一文掌握 Go fmt:最常用的字符串与字节串操作总结
  • PHP Filter:深度解析与实际应用
  • Debian 磁盘常用操作汇总(补充中)
  • FaceRecon-3D实战落地:从科研原型到工业级API服务的演进路径
  • 飞书网页API实战:如何在uniapp H5中优雅处理iOS和安卓的PDF预览差异
  • SRE AI Agent 开发复盘及小白向教程 (三) Go语言内核编写和持久存储配置
  • 新装IDEA必做的几件事:以关掉@Autowired警告和SQL黄底为例,聊聊如何调教你的IDE
  • 5步搞定!在星图AI平台快速训练PETRV2-BEV道路识别模型
  • 【讯飞星火大模型AI】SpringBoot整合星火API实战:打造智能数据分析助手
  • 论文降重工具怎么选?实测五款主流神器,硕博必看!
  • XML文档处理太复杂?试试这款浏览器端免费工具
  • 找不到方法:“System.Collections.ObjectModel.Collection`1
  • C语言二刷强化(VS实用调试技巧和函数递归)
  • 5分钟体验GEMMA-3像素站:复古界面下的AI图像理解实战
  • STM32实现ModbusRTU与CAN总线高效分包重组
  • 2026年火锅粉采购指南:五大专业厂家综合评测与推荐 - 2026年企业推荐榜
  • 如何快速下载国家中小学智慧教育平台电子课本:教师学生的完整指南
  • 若依微服务中服务调用的5个常见坑点及解决方案(基于ruoyi-api-system示例)
  • 手把手教你连接迈瑞BeneVision监护仪:从设备联网到移动端查看数据
  • 魔法原子-小米“铁蛋”之父,春晚封神后突然消失:吴长征的180天惊险一跃