分类: C/C++
2012-04-25 13:00:45
C9X的可变长度数组是码农的福音。
int n;
scanf("%d", &n);
int a[n];
printf("%d", sizeof(a)/sizeof(a[0]));
由于它的存在,alloca这种东西就out了。使用alloca会得到编译警告。
如果说数组的Compound Literal带来很多便利的话:
int a[] = { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
...
(注:for循环里的初始化(int i = 0)由C99支持。)
那么数组的Desinated Initailizers带来的是幸福:
int b[] = { [0 ... 9] = 1, [4] = 2, [5 ... 7] = 3, [55] = 55 };
b的值:{1 1 1 1 2 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55}
但是C99没有提供范围下标:b[3 ... 5] = 7;是不合法的。
顺带一提,C中a[i]与i[a]是等价的。
C99允许的数组的修饰符有:static, restrict, const和volatile。它们可以出现在数组下标符“[ ]”里。
int a[const]、int a[restrict]、和int a[volatile]都是修饰数组指针a的,和修饰其它变量时意义相同。
static是一种优化建议,它向编译器表示数组指针不为空,且至少有n个元素:
void print(int b[static 10])
{
for (int i = 0; i < 10; i++)
printf("%d ", b[i]);
}
注意,这个修饰符并不会让编译器检查传入的数组是否真的有n个元素。
参数中的可变长度数组
在声明的函数原型中使用“*”:
void f(int [*][*], int, int);
定义中使用老式的参数声明:
void f(a, m, n)
int m;
int n;
int a[m][n];
{
}
int a[3][5];
f(a, 3, 5);
另一种等价的方式是:
void g(int *ap, int m, int n)
{
int (*a)[m][n] = (int (*)[m][n])ap;
}
int a[3][5];
g(&aa[0][0], 3, 5);