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
既要告訴我們“執行成功還是失敗”,又要把“分配到的設備號”返回回來。一個返回值不夠用,所以就把設備號通過輸出參數返回。
四、總結
- 輸出參數的本質:通過指針讓函數“返回”額外的結果。
- 適用場景:當一個函數需要返回多個值時。
- 簡單例子:計算平方和兩倍,用指針參數返回。
- 實際應用:
alloc_chrdev_region
用輸出參數返回分配到的設備號。
總結:
返回值表示成功與否,輸出參數返回結果數據。
這就是為什么 alloc_chrdev_region
的 dev_t *dev
參數一定要傳指針的原因。
(完)