C99允许我们在任何地方定义变量,并且支持不定长数组的定义,即,我们可以使用变量来定义我们的数组。这就使得我们可以在程序运行过程中根据实际需要来定义数组长度。

变长数组被当做特殊的局部变量,相对于普通局部变量,它的位置总是在栈的低地址处。

摘自http://hi.baidu.com/zotin/item/a7149aad7003d99f14107366的一个例子,进行了少许的修改,源文件名字为varray.c:

#include <stdio.h>
#include <stdlib.h>
#define println(fmt, ...) printf(fmt "\n" ,##__VA_ARGS__)int main()
{int n;println("input a natural number:");scanf("%d", &n);int nums[n-1];for(int i=0; i<n; i++)nums[i] = i+2;for(int i=2; i<n/2; i++)if(nums[i-2] > 0){for(int j=i*2; j<n; j+=i)nums[j-2] = 0;}println("the prime numbers litter than %d:", n);int lineCount = 0;for(int i=2; i<n; i++)if(nums[i-2] > 0) {printf("%4d ", i);if(lineCount++ == 10) {printf("\n");lineCount = 0;}}printf("\n");return 0;
}

使用我常用的gcc进行编译:gcc -g -o varr varray.c --std=c99

注:如果不使用--std=c99选项,将导致编译错误。现将错误放在下面,仅供参考:

varray.c: In function ‘main’:
varray.c:11: error: ‘for’ loop initial declaration used outside C99 mode
varray.c:14: error: redefinition of ‘i’
varray.c:11: error: previous definition of ‘i’ was here
varray.c:14: error: ‘for’ loop initial declaration used outside C99 mode
varray.c:17: error: ‘for’ loop initial declaration used outside C99 mode
varray.c:24: error: redefinition of ‘i’
varray.c:14: error: previous definition of ‘i’ was here
varray.c:24: error: ‘for’ loop initial declaration used outside C99 mode

gcc默认是C89,如果使用C99新特性,需要添加C99选项。

关于变长数组http://bbs.csdn.net/topics/90350681中有这样的说法:

当有多个变长数组分配时,也就是编译器不能用仅有的几个寄存器保存当前的esp时,编译器就会划分一块区域(这块区域也在栈中,而且是先于变长数组分配划分好的)来记录每个数组的首地址。例如,我昨晚试验的程序有9个变长数组,前三个数组的首地址存在三个通用寄存器中,而后面的6个的首地址则放在比如说ebp-40,ebp-44,ebp-48...的位置。然后如果引用第四个数组的元素,比如源代码是ar4[1] = 1;编译器会先取ebp-40的内容到一个临时寄存器,再用该值索引数组。也就是有类似如下的汇编代码:
movl (%ebp-40), %eax
movl $1,        4(%eax)

也就是说,从一个单一的概念模型上来说,对于碰到变长数组的情形,编译器可以按一个指针的大小为其预留一个slot,然后到运行的时候esp-eax分配了空间以后,把当前esp,即数组的首地址放入到这个slot中。以后对数组的引用,就要进行两次访存,一次取到数组的首地址,一次访问真正的数组元素。这与以前的数组访问的开销是不同的,以前的数组元素访问之需要一次访存操作,而变长数组的下标访问有点类似于指针的下标访问了。

变长数组的存储分配是在运行时,并且访问也需要两次访存,比原来的数组访问开销要大,但它与动态分配malloc还是有区别的。由于变长数组分配在栈中,只需要改变esp的值就能达到分配的目的,而malloc分配则需要runtime system来进行heap management,也就是说分配的时候需要一定的search operation来得到一块连续的存储,而释放的时候也要执行相应的代码来使得这块存储available for future use。所以,变长数组的开销还是小于malloc的。

变长数组-C99新特性相关推荐

  1. c99变长数组_你学过数组,那你知道柔性数组吗?

    1 引言 定长数组包 在平时的开发中,缓冲区数据收发时,如果采用缓冲区定长包,假定大小是 1k,MAX_LENGTH 为 1024.结构体如下: // 定长缓冲区struct max_buffer{ ...

  2. C99中的变长数组(VLA)

    处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...

  3. c99变长数组_C语言变长数组使用详解

    看如下代码: #include typedef struct { int len; int array[]; }SoftArray; int main() { int len = 10; printf ...

  4. 通过变长数组(VLA)来看编译器的不同

    2019独角兽企业重金招聘Python工程师标准>>> 代码一: const int x=5; int num[x]; 代码二: int x=5; int num[x]; 代码一能够 ...

  5. 第六章 C语言数组_C语言变长数组:使用变量指明数组的长度

    在<C语言的三套标准:C89.C99和C11>一节中我们讲到,目前经常使用的C语言有三个版本,分别是 C89.C99 和 C11.C89(也称 ANSI C)是较早的版本,也是最经典的版本 ...

  6. C语言高级教程-C语言数组(六):变长数组

    C语言高级教程-C语言数组(六):变长数组 一.本文的编译环境 二.一维数组在执行期间确定长度 三.二维数组在执行期间确定长度 四.一维变长数组实例 五.完整程序 5.1 Main.h 文件程序 5. ...

  7. 数组的定义,一维数组,二维数组与变长数组

    目录 1.数组 2.一维数组 3.二维数组 5.数组的大小 6.遍历数组 7.数组常见错误 1.数组 简介:是一种容器 <类型> 变量名称[元素数量] ( c99之前元素数量必须是整数) ...

  8. C语言变长数组(柔性数组)

    变长数组(柔性数组) C99支持变长数组,定义时可以不指定数组长度,分配时再根据实际长度进行分配. 变长数组一般只能放在结构体的最后一个成员, 在变长数组之前至少得有一个结构体成员 且一个结构体只能有 ...

  9. MODE —— 计算10个分数的平均值(知识点: 数组 变长数组)

    数组是一个数目固定,类型相同的数据项,数组中的数据项称为元素.数组中的元素都是int.long.或者其他类型. 声明一个数组时,要给编译器提供为数组分配内存所需要的所有信息,包括值的类型(决定每个元素 ...

最新文章

  1. R语言聚类分析--cluster, factoextra
  2. iOS之深入解析KVO的底层原理
  3. solr源码导入eclipse
  4. ConcurrentLinkedQueue
  5. java setDataSource 报红
  6. .net框架读书笔记---CLR内存管理\垃圾收集(二)
  7. python memoryview_memoryview的用法
  8. ffmpeg windows版本交叉编译方法
  9. java做后台移动端QQ第三方登录
  10. Java二叉树的建立
  11. Linux学习笔记(三) -- Visual Studio Code 的安装与卸载
  12. 问的书写规则是什么意思_汉字笔顺的书写规则是什么
  13. 贴吧签到php,贴吧自动签到 – 前端开发,JQUERY特效,全栈开发,vue开发
  14. Java 初中级程序员如何快速成长?
  15. oracle 两表数据对比---minus
  16. CF1400:1490E、448B、1462FD、650A、1380B、1451C
  17. Android读写日历,android – 读写日历
  18. jdbc是什么(jdbc是什么设计模式)
  19. Factory IO仿真工厂与西门子博途软件联动仿真
  20. 无法初始化Qt平台插件

热门文章

  1. PDF文件有密码怎么办 PDF密码解除的方法
  2. 分子反应动力学有哪些最新发表的毕业论文呢?
  3. 阿里如何定义团队的研发效能? 1
  4. 重定向java_JAVA 中 重定向
  5. java源码怎么使用,系列篇
  6. 目前家用计算机的运算速度每秒,现代个人计算机运算速度最高可达每秒()
  7. Oracle数据库注入-墨者学院(SQL手工注入漏洞测试(Oracle数据库))
  8. 《产品经理面试攻略》PART 11:BAT招聘真题
  9. 芯动A11算力2000M以太坊矿机机皇
  10. 世上无难事,只怕有心人!