例解GNU C之零长数组与变长数组

前言:计算机语言是编译器和程序员交流的依据和规范,GNU C是GCC特有的功能,在Linux内核中被广泛应用。

    帮助文档:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions

 

    1、零长数组

    GNU C允许声明长度为零的数组,但它只能被用于结构体的最后一个成员。

    举例,如清单1: 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. struct line {  
  5.     int length;  
  6.     char contents[0];  
  7. };  
  8.   
  9. int main(void)  
  10. {  
  11.     int i, count = 9;  
  12.     char letter = 'A';  
  13.   
  14.     struct line *thisline = (struct line *)malloc(sizeof(struct line) + count);  
  15.       
  16.     thisline->length = count;  
  17.     for (i = 0; i < count; i++)  
  18.     thisline->contents[i] = letter++;  
  19.       
  20.     printf("sizeof(struct line) = %d\n"sizeof(struct line));  
  21.       
  22.     for (i = 0; i < thisline->length; i++)  
  23.     printf("%c ", thisline->contents[i]);  
  24.     printf("\n");  
  25.       
  26.     return 0;  
  27. }  

    例子输出结果: 

  1. sizeof(struct line) = 4  
  2. A B C D E F G H I   

    如例子中的第6行,contents就是一个零长数组,在sizeof看来它所占的空间为零。

    在ISO C99中,使用变长数组也可以实现同样的功能,如清单2: 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. struct line {  
  5.     int length;  
  6.     char contents[];  
  7. };  
  8.   
  9. struct line thisline = { 5, {'1''2''3''4''5' } };  
  10.   
  11. int main(void)  
  12. {  
  13.     int i;  
  14.       
  15.     printf("sizeof(struct line) = %d\n"sizeof(struct line));  
  16.     printf("sizeof(thisline) = %d\n"sizeof(thisline));  
  17.       
  18.     for (i = 0; i < thisline.length; i++)  
  19.     printf("%c ", thisline.contents[i]);  
  20.     printf("\n");  
  21.       
  22.     return 0;  
  23. }  

    例子输出结果: 

  1. sizeof(struct line) = 4  
  2. sizeof(thisline) = 4  
  3. 1 2 3 4 5   

    变长数组是不完全数据类型,不能使用sizeof获得它的大小。

    注意,此结构体的变量必须在函数外定义和初始化,否则会报错: 

  1. error: non-static initialization of a flexible array member  
  2. error: (near initialization for 'thisline')  

    不能使用这样的形式: 

  1. struct mystruct {  
  2.     int arr[];  
  3. };  

    否则会报错: 

  1. error: flexible array member in otherwise empty struct  

    2、变长数组

    在支持变长数组之前,C语言数组的大小是在声明时确定的(下标是一个常量表达式)并一直保持不变。所谓变长数组就是指数组的大小可以在运行时指定,如清单3: 

  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int i;  
  6.   
  7.     scanf("%d", &i);  
  8.   
  9.     int arr[i];  
  10.   
  11.     printf("sizeof(arr[%d]) = %d\n", i, sizeof(arr));  
  12.   
  13.     return 0;  
  14. }  

    例子输出结果: 

  1. sizeof(arr[6]) = 24 //输入数字6  
  2.   
  3. sizeof(arr[9]) = 36 //输入数字9  

    输入不同的值,数组的大小随之改变。

    变长数组作为参数进行传递的例子,如清单4: 

  1. #include <stdio.h>  
  2.   
  3. int sum(int num, int arr[num])  
  4. {  
  5.     int i, total = 0;  
  6.   
  7.     for (i = 0; i < num; i++)  
  8.     total += arr[i];  
  9.   
  10.     return total;  
  11. }  
  12.   
  13. int main(void)  
  14. {  
  15.     int a[] = {1, 2, 3, 4};  
  16.     int b[] = {5, 6, 7, 8, 9, 10};  
  17.   
  18.     printf("a[] total value: %d\n", sum(sizeof(a)/sizeof(a[0]), a));  
  19.     printf("b[] total value: %d\n", sum(sizeof(b)/sizeof(b[0]), b));  
  20.   
  21.     return 0;  
  22. }  

    例子输出结果: 

  1. a[] total value: 10  
  2. b[] total value: 45  

    函数sum形参中的arr可以匹配任意的一维整型数组。

    注意,num一定要声明在变长数组arr之前。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值