博客列表 >C语言中长度为0的数组详解

C语言中长度为0的数组详解

**沐曦??
**沐曦??原创
2021年10月13日 11:43:242083浏览

概述
长度为0的数组在标准c和c++中是不合法的,但是在gcc中是可行的。
长度为0数组它的最典型的用法就是位于结构体中的最后一项。

使用方式
如下面的例子,分别使用长度为0的数组和指针声明结构体,实现可变长度的数组功能:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. struct test1
  66. {
  67. int a;
  68. int b[0];
  69. };
  70. struct test2
  71. {
  72. int a;
  73. int *b;
  74. };
  75. struct test3
  76. {
  77. int a;
  78. int reserved;//占位符,64位系统中保证结构体字节对齐,test2中是由编译器对齐的,所以两个结构体占用空间相同
  79. int *b;
  80. };
  81. int main()
  82. {
  83. struct test1 *var1;
  84. struct test2 *var2;
  85. int iLength = 10;
  86. int i;
  87. printf("the length of struct test1:%d\n",sizeof(struct test1));
  88. printf("the length of struct test2:%d\n",sizeof(struct test2));
  89. printf("the length of struct test3:%d\n",sizeof(struct test3));
  90. var1=(struct test1*)malloc(sizeof(struct test1) + sizeof(int) * iLength);
  91. var1->a=iLength;
  92. for(i=0; i < var1->a; i++)
  93. {
  94. var1->b[i]=i;
  95. printf("var1->b[%d]=%d\t", i, var1->b[i]);
  96. }
  97. printf("\n");
  98. printf("p var1 = %p\n", var1);
  99. printf("p var1->a %p\n", &var1->a);
  100. printf("var1->b %p\n", var1->b);
  101. printf("p var1->b %p\n", &var1->b);
  102. printf("p var1->b[0] %p\n", &var1->b[0]);
  103. printf("p var1->b[1] %p\n", &var1->b[1]);
  104. printf("\n\n");
  105. var2=(struct test2*)malloc(sizeof(struct test2));
  106. var2->a=iLength;
  107. var2->b=(int *)malloc(sizeof(int) * iLength);
  108. for(i=0; i < var2->a; i++)
  109. {
  110. var2->b[i]=i;
  111. printf("var2->b[%d]=%d\t", i, var2->b[i]);
  112. }
  113. printf("\n");
  114. printf("p var2 = %p\n", var2);
  115. printf("p var2->a %p\n", &var2->a);
  116. printf("var2->b %p\n", var2->b);
  117. printf("p var2->b %p\n", &var2->b);
  118. printf("p var2->b[0] %p\n", &var2->b[0]);
  119. printf("p var2->b[1] %p\n", &var2->b[1]);
  120. free(var1);
  121. free(var2->b);
  122. free(var2);
  123. return 0;
  124. 64linux系统中运行结果
  125. 1
  126. 2
  127. 3
  128. 4
  129. 5
  130. 6
  131. 7
  132. 8
  133. 9
  134. 10
  135. 11
  136. 12
  137. 13
  138. 14
  139. 15
  140. 16
  141. 17
  142. the length of struct test1:4
  143. the length of struct test2:16
  144. the length of struct test3:16
  145. var1->b[0]=0 var1->b[1]=1 var1->b[2]=2 var1->b[3]=3 var1->b[4]=4 var1->b[5]=5 var1->b[6]=6 var1->b[7]=7 var1->b[8]=8 var1->b[9]=9
  146. p var1 = 0x55eb1a7d7670
  147. p var1->a 0x55eb1a7d7670
  148. var1->b 0x55eb1a7d7674
  149. p var1->b 0x55eb1a7d7674
  150. p var1->b[0] 0x55eb1a7d7674
  151. p var1->b[1] 0x55eb1a7d7678
  152. var2->b[0]=0 var2->b[1]=1 var2->b[2]=2 var2->b[3]=3 var2->b[4]=4 var2->b[5]=5 var2->b[6]=6 var2->b[7]=7 var2->b[8]=8 var2->b[9]=9
  153. p var2 = 0x55eb1a7d76b0
  154. p var2->a 0x55eb1a7d76b0
  155. var2->b 0x55eb1a7d76d0
  156. p var2->b 0x55eb1a7d76b8
  157. p var2->b[0] 0x55eb1a7d76d0
  158. p var2->b[1] 0x55eb1a7d76d4
  159. 使用长度为0的数组可以比指针更方便地进行内存的管理。

结构体test1在分配内存时,则是采用一次分配的原则,一次性将所需的内存全部分配给它,释放也是一次释放。数组和结构体的内存是连续的。
结构体test2在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为0的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。

总结
长度为0的数组并不占有内存空间,而指针方式需要占用内存空间。

对于长度为0的数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。

对于长度为0的数组元素的访问可正常采用数组方式进行。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议