· C語言零敲碎打系列是爲了夯實各種C語言的高級用法,來源是多種多樣,比如開源代碼,知名書籍等等;提升我們對C語言的語言特性的理解。
· 今天第一次分享,先分享Linux內核中的USB驅動中的一段代碼:變長元素數組,記得在C專家編程中看到過對指針數組的描述,講到通過指針的指針可以實現不同長度元素長度的內容放在一起的操作。今天在內核代碼中看到了這種用法,才知道這個可以這麼使用。
知識點1:
· 使用枚舉enum來表示某整數,類似宏定義的用法。例如如下,USB的各級別速度:
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH, /* usb 2.0 */
USB_SPEED_WIRELESS, /* wireless (usb 2.5) */
USB_SPEED_SUPER, /* usb 3.0 */
};
· 這裏要注意,一般會將0設計爲一個異常值,有時也會設計一個最大值作爲上限的判斷。
· 這裏其實利用了枚舉類型,其實是用整型來實現的這一規則。
知識點2:
甜點後面就是正餐了,變長元素數組在如下函數中:
const char *usb_speed_string(enum usb_device_speed speed)
{
static const char *const names[] = {
[USB_SPEED_UNKNOWN] = "UNKNOWN",
[USB_SPEED_LOW] = "low-speed",
[USB_SPEED_FULL] = "full-speed",
[USB_SPEED_HIGH] = "high-speed",
[USB_SPEED_WIRELESS] = "wireless",
[USB_SPEED_SUPER] = "super-speed",
};
if (speed < 0 || speed >= ARRAY_SIZE(names))
speed = USB_SPEED_UNKNOWN;
return names[speed];
}
· 首先函數內部使用static,其實是將static數組封裝成函數的用法調用,這是重構的常用方法。
· 這裏的 static const char *const names[] 是一個靜態的指針數組,數組大小是6,數組既是const,數組的元素 也是const,這樣用來表示一些固定數據類型轉換,這裏的函數usb_speed_string的目的就是將speed轉換爲對應的字符串,用來輸出打印。而數組的元素則是字符串的頭,雖然長度不一定相同,但是""的字符串都有’\0’結尾,使用起來很安全。
· 而這種數組的初始化方式我們使用的很少,是一種對各個元素逐個初始化的方式,雖然很複雜,但是顯示非常清晰;
· 最後對數組長度做異常判斷,異常返回0.
·這種變長元素數組平時使用較少,畢竟變長元素的操作比較容易出錯,只有在這種數據類型轉換的場景纔會使用。