C语言柔性数组详解
什么是柔性数组
柔性数组是指在结构体中的一个成员是一个数组,而数组的大小是在运行时动态分配的。在C99标准中,引入了柔性数组的概念,用来处理动态数组的需求。柔性数组成员必须放在结构体最后面,并且数组的大小不能指定。
定义柔性数组
柔性数组的定义需要一个明确的长度,这样做是为了分配内存。由于在定义时无法确定柔性数组的长度,因此柔性数组需要使用一个特殊的符号"[]"来表示。
struct student
{
int age;
char name[20];
int score[];
};
在上面的结构体中,score就是一个柔性数组,它表示一个学生的成绩。在内存中,score数组紧跟在name字符数组的末尾。
初始化柔性数组
由于结构体中的柔性数组是在运行时分配内存的,因此初始化柔性数组变得比较困难。我们需要手动分配内存,并使用指针来访问数组元素。
struct student *p;
p = malloc(sizeof(struct student) + n * sizeof(int));
上述代码中,我们使用了malloc函数来分配内存,并且分配的内存大小是结构体的大小加上数组部分的大小,即sizeof(struct student) + n * sizeof(int)。
使用柔性数组
使用柔性数组其实就是使用普通数组,唯一的区别在于无法使用sizeof运算符来获取数组的大小。在使用柔性数组时,我们需要手动记录数组的长度。下面是一个示例:
struct student *p;
int n = 10; // 定义学生数量
p = malloc(sizeof(struct student) + n * sizeof(int)); // 分配内存
for(int i = 0; i < n; i++) {
p->score[i] = i * 10; // 给柔性数组赋值
}
for(int i = 0; i < n; i++) {
printf("%d ", p->score[i]); // 打印柔性数组元素
}
在上述代码中,我们首先分配了一块内存,大小为sizeof(struct student) + n * sizeof(int),这样就可以存储n个学生的信息。然后我们使用for循环对柔性数组进行赋值和输出操作。
示例说明
示例1
下面是一个简单的例子,演示了如何使用柔性数组来实现不定长的二维数组。
#include <stdio.h>
#include <stdlib.h>
struct matrix
{
int row;
int col;
int data[]; // 柔性数组
};
void mat_print(struct matrix *mat)
{
int i, j;
for(i = 0; i < mat->row; i++)
{
for(j = 0; j < mat->col; j++)
{
printf("%d ", mat->data[i * mat->col + j]);
}
printf("\n");
}
}
int main()
{
int n, m, i, j;
scanf("%d %d", &n, &m);
struct matrix *mat = malloc(sizeof(struct matrix) + n * m * sizeof(int));
mat->row = n;
mat->col = m;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
mat->data[i * m + j] = i + j;
}
}
mat_print(mat);
free(mat);
return 0;
}
在这个示例中,我们定义了一个结构体matrix,其中包含row、col两个成员和一个柔性数组data。在main函数中,我们首先读入二维数组的行和列,然后使用malloc函数分配了一个大小为sizeof(struct matrix)+nmsizeof(int)的内存块。我们使用for循环对柔性数组进行初始化,并使用函数mat_print打印输出了整个二维数组。在程序结束时我们还需要使用free函数释放掉申请的内存。
示例2
下面是另一个简单的例子,演示了如何使用柔性数组来实现一个动态队列。
#include <stdio.h>
#include <stdlib.h>
struct queue
{
int head;
int tail;
int data[];
};
int main()
{
int n, i, x;
char op[10];
struct queue *q = malloc(sizeof(struct queue) + n * sizeof(int));
q->head = 0;
q->tail = 0;
while(scanf("%s", op) != EOF) // 循环读入操作
{
if(op[0] == 'p') // push操作
{
scanf("%d", &x);
q->data[q->tail++] = x;
}
else if(op[0] == 'p') // pop操作
{
if(q->head < q->tail) printf("%d\n", q->data[q->head++]);
}
}
free(q);
return 0;
}
在这个示例中,我们定义了一个结构体queue,其中包含head、tail以及柔性数组data三个成员。我们使用malloc函数分配了一个大小为sizeof(struct queue)+n*sizeof(int)的内存块。在循环中,我们读入操作,并分别处理push和pop操作。push操作将元素插入队列的尾部,pop操作从队列的头部取出一个元素并输出。在程序结束时我们还需要使用free函数释放掉申请的内存。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言柔性数组详解 - Python技术站