341 字
1 分钟
【C】void与特殊数组类型
2026-05-19

void 的用法#

用法示例含义
无返回值void foo(void);函数不返回值
无参数int bar(void);不接受参数(C 中推荐写 void
通用指针void *p = malloc(n);可指向任意对象类型地址

malloc 返回 void*,在 C 中可直接赋给具体指针;使用后 free 并置 NULL

柔性数组成员(FAM)#

定义在结构体最后一个成员,用于「头部固定 + 尾部变长数据」。

struct packet {
int len;
char data[]; // C99 标准写法(柔性数组成员)
// char data[0]; // GNU 扩展,可移植性较差
};
  • data[] 不计入 sizeof(struct packet),仅表示紧跟其后的可变区域起点
  • 须在上一次性分配:sizeof(结构体) + 额外字节
struct packet *p = malloc(sizeof(struct packet) + 100);
if (p) {
p->len = 100;
/* 使用 p->data[0] .. p->data[len-1] */
free(p);
}

不要对栈上局部结构体依赖柔性成员后的越界访问。

变长数组(VLA)#

void foo(int n) {
int vla[n]; // C99:n 为运行时值
for (int i = 0; i < n; i++)
vla[i] = i;
}
  • 长度在定义时由变量决定,定义后不可改变
  • 通常在上分配,过大易栈溢出
  • C11 起 VLA 为可选;MSVC 不支持;嵌入式与跨平台项目慎用

与「柔性数组成员 + malloc」区别:VLA 是自动存储期;FAM 多用于堆上动态包。

二维数组#

本质:一维数组的数组,行优先(row-major)连续存储。

int mat[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// mat[i][j] 等价于 *(*(mat + i) + j)
  • mat 在表达式中常退化为 int (*)[3](列数须为常量)
  • sizeof(mat) 为整个二维数组字节数
  • 作函数参数时须已知列数:
void print(int rows, int a[][3]) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < 3; j++)
printf("%d ", a[i][j]);
}

也可按一维连续内存传递:int *p,自行用 i * cols + j 计算下标。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【C】void与特殊数组类型
https://lysj.work/posts/studynotes/c/cvoid与特殊数组类型/
作者
Sekiro
发布于
2026-05-19
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录