数组指针如何存储其大小?

Lio*_*ion 4 c arrays pointers

#include "stdio.h"

#define COUNT(a) (sizeof(a) / sizeof(*(a)))

void test(int b[]) {
  printf("2, count:%d\n", COUNT(b));
}

int main(void) {
  int a[] = { 1,2,3 };

  printf("1, count:%d\n", COUNT(a));
  test(a);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果很明显:

1, count:3
2, count:1
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 声明"a"时存储的长度(计数/大小)信息在哪里?
  2. 当"a"传递给test()函数时,为什么长度(计数/大小)信息会丢失?

AnT*_*AnT 7

在C语言中没有"数组指针"这样的东西.

尺寸不存储在任何地方.a不是指针,a是类型的对象int[3],这是编译器在编译时熟知的事实.因此,当您要求编译器sizeof(a) / sizeof(*a)在编译时计算时,编译器知道答案是3.

当您传递a给函数时,您有意要求编译器将数组类型转换为指针类型(因为您将函数参数声明为指针).对于指针,您的sizeof表达式会产生完全不同的结果.

  • @SiegeX:标准明确指出参数声明中的“int b[]”相当于“int *b”。这不是“数组类型衰减”的一个实例。参数可以“衰减”,但参数声明由标准的单独部分描述的不同“过程”涵盖。 (2认同)

Mic*_*urr 5

  1. 声明"a"时存储的长度(计数/大小)信息在哪里?

它不存储在任何地方.的sizeof操作者(在所使用的COUNT()宏)时,它的给定的一个真正的阵列作为操作数(因为它是在所述第一返回整个数组的大小printf())

  1. 当"a"传递给test()函数时,为什么长度(计数/大小)信息会丢失?

不幸的是,在C中,函数的数组参数是虚构的.数组不会传递给函数; 该参数被视为一个指针,并且在函数调用中传递的数组参数被"衰减"为一个简单的指针.的sizeof运算符返回指针,它具有与被用作一个参数数组的大小没有相关性的大小.

作为旁注,在C++中,您可以将函数参数作为对数组的引用,在这种情况下,完整数组类型可供函数使用(即,参数不会衰减为指针sizeof并将返回完整数组的大小).但是,在这种情况下,参数必须与数组类型完全匹配(包括元素数),这使得该技术最常用于模板.

例如,以下C++程序将执行您期望的操作:

#include "stdio.h"

#define COUNT(a) (sizeof(a) / sizeof(*(a)))

template <int T>
void test(int (&b)[T]) {
  printf("2, count:%d\n", COUNT(b));
}

int main(int argc, char *argv[]) {
  int a[] = { 1,2,3 };

  printf("1, count:%d\n", COUNT(a));
  test(a);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)