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

C语言 - 输出参数详解:从简单示例到 alloc_chrdev_region

C语言中的输出参数详解:以 alloc_chrdev_region 为例

在学习 C 语言函数调用时,我们常常接触到“输入参数”,比如把一个数字传给函数,让函数帮我们算出结果。但有时候可能会发现,有些函数除了返回值之外,还会让我们传一个指针参数进去,用来返回额外的结果。这类指针参数就叫 输出参数

本文将从零理解输出参数的概念,先从一个简单的例子入手,再结合 Linux 驱动开发中的 alloc_chrdev_region 函数做深入解析。

一、什么是输出参数?

在 C 语言中,函数有一个返回值,但有时候我们希望函数能够返回多个结果。这时候,就可以通过 指针 把结果写回给调用者,这个指针参数就是输出参数。

  • 输入参数:函数从调用者那里获取的值。
  • 输出参数:函数通过指针写回调用者的值。

简而言之:输入参数进函数,输出参数出函数。

二、一个简单的例子

假设我们要写一个函数:给定一个整数,计算它的平方和两倍,并返回给调用者。

错误思路:只能返回一个值

int calc(int x) {return x * x;  // 只能返回平方,没法返回两倍
}

这样只能返回一个结果,不够用。

正确思路:用输出参数

#include <stdio.h>void calc(int x, int *square, int *twice) {*square = x * x;   // 通过指针写回平方*twice  = x * 2;   // 通过指针写回两倍
}int main() {int s, t;calc(5, &s, &t);printf("平方 = %d, 两倍 = %d\n", s, t);return 0;
}

运行结果:

平方 = 25, 两倍 = 10

在这里:

  • int *square, int *twice输出参数
  • 函数通过 *square*twice 把结果写回。

这样,函数就相当于“返回了多个结果”。

三、Linux 驱动开发中的例子:alloc_chrdev_region

在 Linux 字符设备驱动开发中,我们经常会调用 alloc_chrdev_region 来向内核申请一个设备号。

函数原型

int alloc_chrdev_region(dev_t *dev, unsigned baseminor,unsigned count, const char *name);

参数说明:

  • dev:输出参数,指向 dev_t 变量,用来存放分配到的设备号。
  • baseminor:起始次设备号。
  • count:需要的设备数量。
  • name:设备名称,会显示在 /proc/devices

返回值:

  • 0 表示成功。
  • 小于 0 表示失败。

使用示例

#include <linux/fs.h>static dev_t dev_num;  // 保存分配到的设备号int result = alloc_chrdev_region(&dev_num, 0, 1, "hello_drv");
if (result < 0) {printk("分配设备号失败!\n");
} else {printk("成功分配到设备号:主设备号=%d, 次设备号=%d\n", MAJOR(dev_num), MINOR(dev_num));
}

这里:

  • &dev_num 作为输出参数传给函数。
  • 内核在函数内部写入分配好的设备号到 *dev,也就是 dev_num
  • 我们调用 MAJOR(dev_num)MINOR(dev_num) 就能拿到主次设备号。

为什么要用输出参数?

因为 alloc_chrdev_region 既要告诉我们“执行成功还是失败”,又要把“分配到的设备号”返回回来。一个返回值不够用,所以就把设备号通过输出参数返回。

四、总结

  1. 输出参数的本质:通过指针让函数“返回”额外的结果。
  2. 适用场景:当一个函数需要返回多个值时。
  3. 简单例子:计算平方和两倍,用指针参数返回。
  4. 实际应用alloc_chrdev_region 用输出参数返回分配到的设备号。

总结:

返回值表示成功与否,输出参数返回结果数据。

这就是为什么 alloc_chrdev_regiondev_t *dev 参数一定要传指针的原因。


(完)

http://www.dtcms.com/a/358716.html

相关文章:

  • AV1编码资源可用性模式
  • DC-HRNet
  • SQL学习记录
  • 键查跑分、比配置的手机性能排行
  • ThingsBoard使用Vue3实现
  • nacos 2.5.1 心跳源码解析
  • MCP进阶指南:如何挑选最适合你的AI助手“装备“
  • 计算机毕业设计 java 在线学习系统 基于 Java 的在线教育平台 Java 开发的学习管理系统
  • Fourier 级数展开(案例:级数展开 AND 求和)
  • 仓颉编程语言青少年基础教程:程序基本结构和语言特点
  • Day31 进程间通信(IPC)多线程目录扫描
  • mysql(自写)
  • 谈物质的运动与运动的物质
  • 基于立创・庐山派 K230CanMV 开发板的视觉引导舵机追踪系统技术分析
  • kafka(自写)
  • 【MYSQL】GET_LOCK使用方法简单解析
  • C++_静态多态、运行多态和模板多态
  • 下一代 AI 交互革命:自然语言对话之外,“意念控制” 离商用还有多远?
  • AWD相关知识
  • Scikit-learn Python机器学习 - 数据集介绍
  • 矿物类型分类实战:从数据预处理到多模型对比
  • 幻觉与模仿:深入剖析当前大语言模型为何未能跨越“理解”与“推理”的鸿沟
  • TuringComplete游戏攻略(2.1算数运算)
  • 基础的汇编指令
  • 如何快速了解项目管理基础
  • 【机器学习入门】4.1 聚类简介——从“物以类聚”看懂无监督分组的核心逻辑
  • destoon8.0使用post插入keyword热搜到表
  • 深入理解shared_ptr与循环引用问题
  • 超越传统SEO:用生成引擎优化(GEO)驱动下一轮增长
  • 【蓝桥杯 2024 省 Python B】缴纳过路费