以下摘自
C89标准和C99标准C11标准的区别
对数组的增强–可变长数组
C99中,程序员声明数组时,数组的维数可以由任一有效的整型表达式确定,包括只在运行时才能确定其值的表达式,这类数组就叫做可变长数组,但是
只有局部数组才可以是变长的
.可变长数组的维数在数组生存期内是不变的,也就是说,可变长数组不是动态的.可以变化的只是数组的大小.可以使用*来定义不确定长的可变长数组。
因此,windows上不支持以下程序(c98?),但linux gcc就支持(c99),仅仅是因为它们的编译器支持不同的标准,下面我们说那个标准不支持更准确:
int b;
int a[b]; # c98和c99都不支持这种
void test2(int n) {
int a[n];# c98不支持,c99支持,谭浩强说支持但实测的不支持,又是标准惹的祸吧
a[0] = 1;
printf("%d\n", a[0]);
int main() {
int a = 43;
test2(a); # c98不支持,c99支持
return 0;
以下摘自C99可变长数组VLA详解
在程序设计过程中,我们常常遇到需要根据上下文环境来定义数组的情况,在运行期才能确知数组的长度。对于这种情况,C90及C++没有什么很好的办法去解决(STL的方法除外),只能在堆中创建一个内存映像与需求数组一样的替代品,这种替代品不具有数组类型,这是一个遗憾。C99的可变长数组为这个问题提供了一个部分解决方案。可变长数组(variable length array,简称VLA)中的可变长指的是编译期可变,数组定义时其长度可为整数类型的表达式,不再象C90/C++那样必须是整数常量表达式。
以下内容整理自C语言为什么不建议把变量作为数组长度
(1)支持VLA(变长数组)的编译器都大多数在栈上分配,但也有在堆上分配的,如armcc的VLA默认是直接使用系统的malloc,free来实现的,据说armcc的VLA用堆还是用栈是可以配置的,我没有深究,若你不确定你的编译器会以何种方式生成VLA代码的时候,不要假定它是基于栈实现的。这是一个比较容易出BUG的点。要避免这种BUG的方式其实也很简单,那就是避免使用VLA。即当要分配的空间长度上界比较小时,你可以使用固定数组大小的形式分配,浪费一点点不用也没关系;当你要分配空间的长度的上界比较大时,直接使用动态分配malloc等函数。
(2)因为这里面有太多的坑了,如果你不明白其中原理的话,那么你很容易掉坑里面。变长数组的实现是通过动态设置栈顶来实现的,也就是说这个东西还是在栈上而不是在堆里,这就带来了问题:第一,因为栈的大小是有限制的所以你的每次动态声明相当于调用了一次alloca,不知道这东西的可以自己去查下,其实他们的原理是一样的,通过设置栈顶在栈空间分配一块空间。所以动态数组不能太大。第二,这个东西因为实现在栈上面所以跟栈相关的操作都跟他互相有影响,比如上面提到的alloca,这个东西于动态数组的区别在于作用域,alloca在分配在函数内有效,但是动态数组在最内层括号内有效。但是(这里是重点),因为他们都在栈上面,所以一旦动态数组失效后,在其后分配的alloca也会被free,所以会产生很多不可预料的问题。比如这段代码:
int test()
int a = 10;
char *c;
char b[a];
a = 8 * 1024;
c = alloca(a);
char d[a];
memset(c, 0, a);
memset(d, 2, a);
return c[0];
编译运行你会得到一个core dump
以下通过在堆上动态申请空间来替代VAL.
malloc(sizeof(Type) * number)…
calloc(sizeof(Type), number)
p = malloc (sizeof (*p) *number)
1,了解C89标准和C99中数组的区别以下摘自C89标准和C99标准C11标准的区别对数组的增强–可变长数组 C99中,程序员声明数组时,数组的维数可以由任一有效的整型表达式确定,包括只在运行时才能确定其值的表达式,这类数组就叫做可变长数组,但是只有局部数组才可以是变长的.可变长数组的维数在数组生存期内是不变的,也就是说,可变长数组不是动态的.可以变化的只是数组的大小.可以使用*来定义不确定长的可变长数组。因此,windows上不支持以下程序(c98?),但linux gcc就支持(c99),
我们知道,C语言的数组是固定大小的,尽管可以用一个变量来定义数组大小,但是一旦定义了,在大小在运行过程中无法改变。如果一开始就定义一个容量较大的数组,那么由于不知道实际要存放多少元素,可能会造成空间浪费或者还是不够用。所以,本篇博客,我们就用C语言实现一个可以变大小的数组。
先上代码:
头文件array.h
#ifndef _ARRAY_H_
#define _ARRAY_H_
cons...
昨天学习了翁恺老师的可变数组,刚听的时候,是比较懵的,但是在自己跟着老师敲了一遍代码之后,才慢慢理解老师的可变数组的内核。
首先,一个可变数组包括数组的创建,内存的释放,得到数组的大小,访问并修改数组中的某个元素,加上可变数组的生长。
首先定义一个结构体,该结构体包含数组和其array
#include<stdio.h>
#define BLOCK 20
typedef struct {
int *array;
int size;
}A...
在结构体中,data是一个数组名,但该数组没有元素,不占结构体空间(sizeof(struct MyData) = 4),该数组的地址紧随结构体中变量nLen的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容),实现如下:
struct MyData *p = (struct MyData *)malloc(s
在C语言中,数组必须在定义时指定长度,否则编译器会报错。因为在C语言中,数组的长度是数组类型的一部分,编译器需要知道数组的长度才能对其进行正确的内存分配和访问。
如果需要动态分配内存,可以使用malloc函数来实现。例如:
int* arr = NULL; // 定义一个指向整型的指针
int len = 10; // 数组长度
arr = (int*)malloc(len * sizeof(int)); // 分配内存空间
在这个例子中,通过调用malloc函数,动态分配了一个长度为10的整型数组。由于动态数组的长度是在运行时确定的,因此可以在程序运行时根据需要动态地调整数组的大小。但需要注意的是,使用完动态数组后,需要调用free()函数来释放内存,以避免内存泄漏。