C语言可变长数组

前言:

通常,数组变量的长度必须有常量表达式进行定义,但是在C99中,有时候也可以使用非常量表达式

1.代码演示:

#include<stdio.h>

int main(void){
	int i, n;
	
	printf("你想颠倒多少个数字?");
	scanf("%d",&n);
	
//	printf("n=%d\n",n);//调试 
	int a[n];//C99 only
	
	printf("请输入%d个整数:",n);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);//录入数字 
	}
	
//	printf("n=%d\n",n);//调试 
	printf("颠倒输出:");
	for(i=n-1;i>=0;i--){
		printf(" %d",a[i]);//空格分开数字 
	} 
	printf("\n");
	
	return 0;
} 

2.运行结果:

你想颠倒多少个数字?12
请输入12个整数:1 2 3 4 5 6 7 8 9 10 11 12
颠倒输出: 12 11 10 9 8 7 6 5 4 3 2 1

--------------------------------
Process exited after 13.18 seconds with return value 0
请按任意键继续. . .

3.原理解释:

  • 上面程序的数组a[n]是一个变长数组(VLA),变长数组具有特征如下:
    1. 变长数组的长度是在程序执行时计算的,而非如常规那样在程序编译时计算
    2. 主要优点是不必在构造数组时随便给定一个长度,程序在执行过程中可以准确计算出所需元素个数,避免过长(浪费资源)或过短(溢出出错)。
    3. 变长数组的长度不一定要用变量来指定,任意表达式都可以
      int a[3*i+5];
      int b[j+k];
    4. 变长数组的主要限制是它们没有静态存储期限(下面详细讲)
    5. 变长数组没有初始化式(很自然,没有固定数量自然不能初始化)
    6. more……

4.静态存储期限

  • 变量都是有存储期限的,也就是它们的生命周期,分为自动存储期限静态存储期限
  • 拥有自动存储期限的变量在所属块被执行时获得内存单元,并在块终止时释放内存单元。我们平时随手定义的变量都属于此范畴,生命周期在{}中。
  • 静态存储期限的变量则不需要考虑变量声明的位置,static变量只在程序执行时被初始化一次,然后全程都可以使用,存储位置一直没有改变,但是千万不要以为它和全局变量一样,局部静态存储期限的变量任然是块内可见,并且全局静态变量还限制了只有本源文件内可见,其他源文件不可见。总之,静态存储期限把变量的位置限制固定,但是并没有提升其可见区域。
  • 如下是一个静态数组的妙用,仔细体会:
#include<stdio.h>
void fillArry();

int main(void){
	
	int i;
	
	for(i=0;i<12;i++)
	{
		fillArry(); //此处不需要填入任何传递值,也不需要任何返回值,降低了耦合性 
	} 
	return 0;
}

void fillArry(){
	static int j=0;//用于自增 
	static int a[12]={0};//用于记住上次调用的赋值
	a[j]=j;
	j++;//j=12时,数组已经赋值完毕 
	while(j==12){
		int i; 
		for(i=0;i<12;i++){
		printf("%d ",a[i]); //最后把静态数组输出,以验证每次调用都延续之前的结果	
		} 
		j++;
		 
	}	
} 

输出结果:

0 1 2 3 4 5 6 7 8 9 10 11
--------------------------------
Process exited after 0.03233 seconds with return value 0
请按任意键继续. . .
  • 以上是静态存储期限的妙用,静态存储期限变量会固定存储位置,这也就意味着,其存储由栈转移到静态存储区,可变长数组的长度都不固定,肯定没法放在固定的位置,这也从一个角度理解了为什么可变长数组不可以由静态存储期限。

版权声明:本文为qq_33547321原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。