网站建设笔记,做网站还赚钱么,东莞学习网站建设,怎么给网站做快照C语言定长数组 变长数组 柔性数组 文章目录 C语言定长数组 变长数组 柔性数组1. 定长数组2. 变长数组3. 柔性数组3.1 结构体的大小3.2 柔性数组的使用 1. 定长数组
在C99标准之前#xff0c;C语言在创建数组的时候#xff0c;数组的大小只能使用常量#xff0c;常量表达式来…C语言定长数组 变长数组 柔性数组 文章目录 C语言定长数组 变长数组 柔性数组1. 定长数组2. 变长数组3. 柔性数组3.1 结构体的大小3.2 柔性数组的使用 1. 定长数组
在C99标准之前C语言在创建数组的时候数组的大小只能使用常量常量表达式来或者在初始化数组时省略数组的大小这就是所谓的定长数组
#include stdio.h
int main()
{int arr1[10];int arr2[10 5];int arr3[] {1,2,3,4,5,6,7,8,9,10};return 0;
}2. 变长数组
有定长数组这样的语法限制让我们创建数组不够灵活有时数组大小给大了浪费空间有时数组大小给小了不够用所以在C99标准之后有个一个变⻓数组variable-length array简称 VLA的概念允许我们在创建数组的时候使用变量
int n a b;
int arr[n];在上述示例中arr 就是变长数组因为它的长度取决于变量n的值编译器没法事先确定只有运行时才能知道变量n是多少
变长数组特点: 变长数组⻓度只有运⾏时才能确定所以变⻓数组不能初始化变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的在程序运⾏的时候根据变量的⼤⼩来指定数组的元素个数⽽不是说数组的⼤⼩是可变的。数组的⼤⼩⼀旦确定就不能再变化了。 在VS2022中是不支持变长数组的没法测试在gcc编译器上可以测试
#include stdio.h
int main()
{int n 0;scanf(%d, n);//根据输⼊数值确定数组的⼤⼩int arr[n];int i 0;for (i 0; i n; i){scanf(%d, arr[i]);}for (i 0; i n; i){printf(%d , arr[i]);}return 0;
}3. 柔性数组
那么有没有一种数组在确定确定数组的大小还可以根据需要扩大数组 在C99 中结构体中的最后⼀个元素允许是未知⼤⼩的数组这就叫做『柔性数组』成员。 例如
struct S
{int i;char c;int arr[];
};在上述示例中arr就是变长数组
变长数组的特点 在结构体中最后一个成员未知大小的数组 这样的数组就是柔性数组 3.1 结构体的大小
struct S
{int i;char c;int arr[];
};#include stdio.h
int main()
{printf(%zd\n, sizeof(struct S));return 0;
}代码运行结果:8 根据结构体对齐规则int 4个字节char 1个字节总共5个字节不为最大对齐数4的倍数对齐至8字节 在存在柔性数组的结构体中计算结构体的大小时不会计算柔性数组的大小 3.2 柔性数组的使用
柔性数组是通过 malloc realloc的方式来实现数组大小的扩大的
代码一
#include stdio.h
#include string.h
#include stdlib.hstruct S
{int i;char c;int arr[];
};
int main()
{struct S* p (struct S*)malloc(sizeof(struct S) 10 * sizeof(int)); //通过结构体指针来访问结构体开辟一个结构体大小 想要开辟数组大小的空间if (p NULL) //判断开辟是否成功{perror(malloc fail);return 1;}//使用柔性数组int i 0; for (i 0; i 10; i) {p-arr[i] i;}struct S* tmp (struct S*)realloc(p, sizeof(struct S) 15 * sizeof(int)); //调整数组大小if (tmp ! NULL) //判断是否调整成功{p tmp;}else{perror(realoc fail);return 1;}//使用for (i 10; i 15; i){p-arr[i] i;}//打印for (i 0; i 15; i){printf(%d , p-arr[i]);}//释放free(p);p NULL;return 0;
}看不懂的可以去看看动态内存管理malloc calloc realloc free这篇博客
代码二
#include stdio.h
#include string.h
#include stdlib.hstruct S
{int i;char c;int *arr;
};
int main()
{struct S* p (struct S*)malloc(sizeof(struct S)); //开辟一块空间给结构体if (p NULL) //判断开辟是否成功{perror(malloc fail);return 1;}p-arr (int*)malloc(10 * sizeof(int)); //开辟数组if (p-arr NULL) //判断开辟是否成功{perror(malloc fail);return 1;}//使用int i 0;for (i 0; i 10; i){p-arr[i] i;}int* tmp (int*)realloc(p-arr,15 * sizeof(int)); //调整结构体大小if (tmp ! NULL) //判断{p-arr tmp;}else{perror(realoc fail);return 1;}//使用for (i 10; i 15; i){p-arr[i] i;}//打印for (i 0; i 15; i){printf(%d , p-arr[i]);}//释放free(p-arr);p-arr NULL;free(p);p NULL;return 0;
}代码一和代码二可以使用了柔性数组但是代码一有两个好处
⽅便内存释放 代码一 示意图为连续内存只是为了区分划分为了几块红色部分为柔性数组调整大小的部分 代码二 示意图为连续内存只是为了区分划分为了几块红色部分为柔性数组调整大小的部分 代码一的空间是一次性在堆区上开辟的而代码二是先开辟结构体的空间再开辟柔性数组的空间的而既然是开辟的空间就需要使用free来释放否则有可能导致内存泄漏而代码一只需要一次释放而代码二中结构体往往知道释放但是结构体成员也需要释放容易被忽视所以如果我们把结构体的内存以及其成员要的内存⼀次性分配好了并返回给⼀个结构体指针做⼀次free就可以把所有的内存也给释放掉
2.这样有利于访问速度 代码一中是一块连续的内存连续的内存有益于提⾼访问速度也有益于减少内存碎⽚。只是相较于代码二速度会快一点其实我个⼈觉得也没多⾼了反正你跑不了要⽤做偏移量的加法来寻址