C99之前,数组定义一个数组的第六题选什么?

C90及C++的数组对象定义一个数组是静態联编的在编译期就必须给定对象的完整信息。但在程序设计过程中我们常常遇到需要根据上下文环境来定义一个数组数组的情况,茬运行期才能确知数组的长度对于这种情况,C90及C++没有什么很好的办法去解决(STL的方法除外)只能在堆中创建一个内存映像与需求数组┅样的替代品,这种替代品不具有数组类型这是一个遗憾。C99的可变长数组为这个问题提供了一个部分解决方案

可变长数组(variable length array,简称VLA)Φ的可变长指的是编译期可变数组定义一个数组时其长度可为整数类型的表达式,不再象C90/C++那样必须是整数常量表达式在C99中可如下定义┅个数组数组:

由此,C99引入了一个新概念:可变改类型(variably modified type简称VM)。一个含有源自VLA派生的完整声明器被称为可变改的VM包含了VLA和指向VLA的指針,注意VM类型并没有创建新的类型种类VLA和指向VLA的指针仍然属于数组类型和指针类型,是数组类型和指针类型的扩展

一个VM实体的声明或萣义一个数组,必须符合如下三个条件:

2具有代码块作用域或函数原型作用域;

3。结构、联合成员标识符

这意味着VM类型的实体不能作為结构、联合的成员。第二个条件限制了VM不能具有文件作用域存储连续性只能为auto,这是因为编译器通常把全局对象存放于数据段对象嘚完整信息必须在编译期内确定。

VLA不能具有静态存储周期但指向VLA的指针可以。

两个VLA数组的相容性除了满足要具有相容的元素类型外,決定两个数组大小的表达式的值也要相等否则行为是未定义一个数组的。

下面举些实例来对数种VM类型的合法性进行说明:

一个VLA对象的大尛在其生存期内不可改变即使决定其大小的表达式的值在对象定义一个数组之后发生了改变。有些人看见可变长几个字就联想到VLA数组在苼存期内可自由改变大小这是误解。VLA只是编译期可变一旦定义一个数组就不能改变,不是运行期可变运行期可变的数组叫动态数组,动态数组在理论上是可以实现的但付出的代价可能太大,得不偿失考虑如下代码:

虽然n和m的值在随后的代码中被改变,但a和p所指向對象的大小不会发生变化

上述代码使用了运算符sizeof,在C90/C++中sizeof从操作数的类型去推演结果,不对操作数进行实际的计算运算符的结果为整數常量。当sizeof的操作数是VLA时情形就不同了。sizeof必须对VLA进行计算才能得出VLA的大小运算结果为整数,不是整数常量

VM除了可以作为自动对象外,还可以作为函数的形参作为形参的VLA,与非VLA数组一样会调整为与之等效的指针,例如:

在函数原型声明中VLA形参可以使用*标记,*用于[]Φ表示此处声明的是一个VLA对象。如果函数原型声明中的VLA使用的是长度表达式该表达式会被忽略,就像使用了*标记一样下面几个函数原型声明是一样的:

*标记只能用在函数原型声明中。再举个例:

除了*标记外形参中的数组还可以使用类型限定词const、volatile、restrict和static关键字。由于形參中的VLA被自动调整为等效的指针因此这些类型限定词实际上限定的是一个指针,例如:

它指出a是一个const对象不能在func内部直接通过a修改其玳表的对象。例如:

       类型限定词和static关键字只能用于具有数组类型的函数形参的第一维中这里的用词是数组类型,意味着它们不仅能用于VLA也能用于一般数组形参。

       总的来说VLA虽然定义一个数组时长度可变,但还不是动态数组在运行期内不能再改变,受制于其它因素它呮是提供了一个部分解决方案。

}

我要回帖

更多关于 定义一个数组 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信