C语言零敲碎打之一:变长元素数组

· 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.

·这种变长元素数组平时使用较少,毕竟变长元素的操作比较容易出错,只有在这种数据类型转换的场景才会使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章