Linux设备驱动框架深度解析:从核心原理到字符设备实战
2026/8/7 10:26:42
char str[] = {"hello"};中,str是数组名,它代表首元素地址,即&str[0],类型为char *。str = ...非法)。str + 1指向第二个元素str[1],地址偏移量为sizeof(char)字节(通常为1字节)。str + n指向第n+1个元素,等价于&str[n]。*(str + n)等价于str[n]。地址: 0x2000 0x2001 0x2002 0x2003 0x2004 0x2005 内容: 'h' 'e' 'l' 'l' 'o' '\0' 指针: str str+1 str+2 str+3 str+4 str+5注意:字符串以
\0结尾,是C语言字符串处理的终止标志。
char str[]与char *str等价,均接收数组首地址。int mystrlen(char str[])与int mystrlen(char *str)功能完全相同。int (*p)[5];—— 声明一个指针p,它指向一个包含5个int元素的数组。5 * sizeof(int)。int a[5] = {1,2,3,4,5};a或&a[0]:类型为int *,指向首元素。&a:类型为int (*)[5],指向整个数组。a + 1:偏移sizeof(int)字节 → 指向a[1]。&a + 1:偏移sizeof(a)字节 → 指向数组末尾之后的位置(即跳过整个数组)。地址: 0x2000 0x2004 0x2008 0x200C 0x2010 0x2014 内容: 1 2 3 4 5 (越界) 指针: a a+1 a+2 a+3 a+4 &a+1 ↑ &a (指向整个数组)sizeof(a)返回整个数组大小(如5 * 4 = 20字节)。&a不能当作int *使用,其类型是int (*)[5],用于指向数组整体。int a[2][3] = {1,2,3,4,5,6};在内存中是连续存储的,按行优先排列。a代表首行地址,即&a[0],类型为int (*)[3](指向含3个int的一维数组)。a[0]是第一行的数组名,类型为int *,指向a[0][0]。a[1]是第二行的数组名,类型为int *,指向a[1][0]。a + 1→ 指向第二行,即&a[1],偏移量为3 * sizeof(int)。*(a + m) + n→ 等价于&a[m][n]。*(*(a + m) + n)→ 等价于a[m][n]。地址: 0x2000 0x2004 0x2008 0x200C 0x2010 0x2014 内容: 1 2 3 4 5 6 行指针: a[0] ← a[0][0]~a[0][2] a[1] ← a[1][0]~a[1][2] 整体指针: a → &a[0], a+1 → &a[1]二维数组作函数参数时,必须指定列数,行数可省略。
正确写法:
void print_2D_array(int a[][3], int hang); // 列数必须指定 void print_2D_array(int (*pa)[3], int hang); // 数组指针形式调用:print_2D_array(a, 2);
字符型二维数组同理:
char str[3][100] = {"hello", "world", "thanks"}; void print_str_array(char str[][100], int hang); void print_str_array(char (*pstr)[100], int hang);| 概念 | 类型 | 含义 | 示例 |
|---|---|---|---|
| 一维数组名 | T * | 首元素地址 | str→&str[0] |
| 数组指针 | T (*)[N] | 指向整个数组 | &a→int (*)[5] |
| 二维数组名 | T (*)[N] | 首行地址 | a→&a[0] |
| 二维数组行名 | T * | 某行首元素地址 | a[0]→&a[0][0] |
| 函数参数传递 | T arr[][N]或T (*p)[N] | 必须指定列数 | void f(int a[][3]) |