c中数组的大小

一个让我烦恼的简单问题。 假设我在main中定义了一个数组,如int arr[5] 。 现在,如果我仍然在main中并且我设置int i = sizeof(arr)/sizeof(arr[0])然后我被设置为5,但是如果我将数组作为函数参数传递并且完全相同在这个函数中计算,我得到一个不同的数字。 这是为什么? 起初我认为它是因为在一个函数arr是一个指针,但据我所知, arr也是一个指针在主内部!

此外,如果我做一些非常相似的事情,我只是动态地初始化数组,我得到了奇怪的结果:

 int *arr = (int*) malloc(sizeof(int) * 5); int length = sizeof(*arr) / sizeof(arr[0]); printf("%d\n",length); 

输出为1 。 有什么想法吗? 提前致谢!

C数组不会在任何地方存储它们自己的大小,因此sizeof只能在编译时知道大小时以您期望的方式工作。 malloc()被编译器视为任何其他函数,因此sizeof不能告诉arr指向数组的第一个元素,更不用说它有多大了。 如果需要知道数组的大小,则需要将其显式传递给函数,或者作为单独的参数传递,或者使用包含指向数组及其大小的指针的结构。

这是因为arr现在是一个指针,它可以指向单个int或函数只是不知道的1000个int的数组。 您必须将数组的大小传递给函数。

在main arr中声明为int [5],因此大小可以由编译器计算。

我不明白第一个问题(请发一些代码),但第二个问题:

 sizeof(*arr) ; // is sizeof(int) as arr is of type "int *" sizeof(arr[0]) ; // is sizeof(int), as arr[0] is the first // item of an array of int 

事实上, *arrarr[0]意思完全相同,但说的不同。 实际上,假设n是一个索引: *(arr + n)arr[n]相同。

据我所知,arr也是主要内部的指针!

那是错误的。 在main ,你定义了int arr[5]arr是一个数组,而不是一个指针。 它的大小等于数组的大小,所以5*sizeof(int) 。 当您将其作为函数参数传递时,该参数的类型为int* ,因此在函数内部,您将获取int*而不是int[5]

这里的输出是1.任何想法为什么?

这次, arr确实是一个指针,因为你声明它是int *arr 。 但无论哪种方式,无论是int *arr还是int a[5]*arrarr[0]意味着完全相同:第一个元素。 所以当然它们具有相同的大小,而sizeof(*arr) / sizeof(arr[0])是1。

这是因为已知大小的数组与指向未知大小的数组的指针之间存在差异。 sizeof在编译时完成,编译器不可能事先告诉动态创建的内存区域的大小。

您应该了解静态和动态数组之间的区别。 静态数组是intfloatdouble等类型。它们是不同的。 甚至

 int a[10]; 

有一个不同的类型

 int b[11]; 

在编译时,静态数组中的元素数是已知的, sizeof运算符返回它们占用的字节数。

使用已初始化的指针,要么指向某个变量,要么指向已分配的内存,它在运行时显然指向它们的位置,并且编译器无法确定该数组的大小。未来。 因此,指针的sizeof为您提供4(或64位系统中的8)。

请注意, sizeof运算符在编译时运行,而不是在运行时运行。

如果您需要知道已分配内存的大小(通过malloc ),您别无选择,只能将数组的大小保存在另一个变量中,例如在您执行malloc