#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)
我的问题:
在C语言中没有"数组指针"这样的东西.
尺寸不存储在任何地方.a
不是指针,a
是类型的对象int[3]
,这是编译器在编译时熟知的事实.因此,当您要求编译器sizeof(a) / sizeof(*a)
在编译时计算时,编译器知道答案是3
.
当您传递a
给函数时,您有意要求编译器将数组类型转换为指针类型(因为您将函数参数声明为指针).对于指针,您的sizeof
表达式会产生完全不同的结果.
- 声明"a"时存储的长度(计数/大小)信息在哪里?
它不存储在任何地方.的sizeof
操作者(在所使用的COUNT()
宏)时,它的给定的一个真正的阵列作为操作数(因为它是在所述第一返回整个数组的大小printf()
)
- 当"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)