提问人:Chris_45 提问时间:12/29/2009 最后编辑:LundinChris_45 更新时间:11/7/2018 访问量:76013
为什么数组参数的大小与 main 中的大小不同?
Why isn't the size of an array parameter the same as within main?
问:
为什么作为参数发送的数组的大小与 main 中的大小不同?
#include <stdio.h>
void PrintSize(int p_someArray[10]);
int main () {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* As expected, 40 */
PrintSize(myArray);/* Prints 4, not 40 */
}
void PrintSize(int p_someArray[10]){
printf("%d\n", sizeof(p_someArray));
}
答:
当您将数组类型传递给函数时,数组类型将隐式转换为指针类型。
所以
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
和
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
是等价的。所以你得到的是 sizeof(int*)
的值
评论
sizeof
size_t
%zu
int
%d
printf
void PrintSize(int (*p_someArray)[10])
*
sizeof(*p_someArray)
数组的大小很松散。在大多数情况下,数组是指向内存的指针。声明中的大小只告诉编译器为数组分配多少内存 - 它与类型无关,因此 sizeof() 没有什么可继续的。
评论
因为数组在作为参数传递时会衰减为指针。这就是 C 的工作方式,尽管您可以通过引用在 C++ 中传递“数组”并克服此问题。请注意,您可以将不同大小的数组传递给此函数:
// 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
在 C 语言中,没有方法可以确定 未知数组的大小,因此数量需要 被传递以及指向第一个元素的指针。
评论
char[]
该行为是设计使然。
函数参数声明中的相同语法与局部变量定义中的语法完全不同。
原因在其他答案中有所描述。
不能将数组传递给函数。
如果你真的想打印大小,你可以传递一个指向数组的指针,但它根本不是通用的,因为你还需要为函数定义数组大小。
#include <stdio.h>
void PrintSize(int (*p_anArray)[10]);
int main(void) {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* as expected 40 */
PrintSize(&myArray);/* prints 40 */
}
void PrintSize(int (*p_anArray)[10]){
printf("%d\n", (int) sizeof(*p_anArray));
}
正如其他人所说,当用作函数参数时,数组会衰减为指向其第一个元素的指针。还值得注意的是,sizeof 不计算表达式,并且在与表达式一起使用时不需要括号,因此您的参数实际上根本没有被使用,因此您不妨用类型而不是值来编写 sizeof。
#include <stdio.h>
void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );
int main ()
{
int myArray[10];
printf ( "%d\n", sizeof myArray ); /* as expected 40 */
printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
PrintSize2 ( 0 ); /* prints 40, someArray unused */
}
void PrintSize1 ( int someArray[][10] )
{
printf ( "%d\n", sizeof someArray[0] );
}
void PrintSize2 ( int someArray[10] )
{
printf ( "%d\n", sizeof ( int[10] ) );
}
它是一个指针,这就是为什么将数组的大小作为第二个参数传递给函数是一种常见的实现
因此,您需要将数组的长度作为第二个参数传递。当你在编写代码时,你既声明了一个恒定大小的数组,然后又将该数组传递给一个函数,那么让数组长度常量在代码中出现几个位置是一件很痛苦的事情......
K&R 来救援:
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
所以现在你可以做,例如:
int a[10];
...
myfunction(a, N_ELEMENTS(a));
评论
在 c++ 中,你可以通过引用传递一个数组来达到这个目的:
void foo(int (&array)[10])
{
std::cout << sizeof(array) << "\n";
}
评论
你发现的行为实际上是 C 语言中的一个大疣。每当您声明采用数组参数的函数时,编译器都会忽略您并将该参数更改为指针。因此,这些声明的行为都与第一个声明类似:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
在所有四种情况下,a 都是指向 int 的指针。如果将数组传递给 func,它将立即衰减为指向其第一个元素的指针。(在 64 位系统上,64 位指针的大小是 32 位 int 的两倍,因此 sizeof ratio 返回 2。
此规则的唯一目的是保持与不支持将聚合值作为函数参数传递的历史编译器的向后兼容性。
这并不意味着不可能将数组传递给函数。您可以通过将数组嵌入到结构中来绕过这个疣(这基本上是C++ 11的std::array的目的):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
或者通过传递指向数组的指针:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
如果数组大小不是编译时常量,则可以将指针到数组技术用于 C99 可变长度数组:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}
在C语言中,当你将数组作为参数传递给函数时,它会自动转换为指针,从一个函数传递另一个函数的数组称为引用调用。这就是被调用函数仅接收指向函数第一个元素的指针的原因
fun(int a[]) 类似于 fun(int *a) ;
因此,当您打印数组的大小时,它将打印第一个元素的大小。
评论
在 'C' 编程语言中,'sizeof()' 是运算符,他以字节为单位返回对象的大小。'sizeof()' 运算符的参数必须是左值类型(integer,float number,struct,array)。因此,如果你想知道一个数组的大小(以字节为单位),你可以做得非常简单。只需使用'sizeof()'运算符,并为其参数使用数组名称。例如:
#include <stdio.h>
main(){
int n[10];
printf("Size of n is: %d \n", sizeof(n));
}
在 32 位系统上的输出将是: n 的大小为:40.因为 32 系统上的无整数是 4 字节。在 64x 上,它是 8 字节。在本例中,我们在一个数组中声明了 10 个整数。所以结果是 '10 * sizeof(int)'。
一些提示:
如果我们有一个像这样声明的数组 'int n[]={1, 2, 3, ...155..};'. 所以我们想知道这个数组中存储了多少个元素。 使用这个算法:
sizeof(name_of_the_array) / sizeof(array_type)
产品代码: #include
主(){
int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;
}
评论
sizeof(n)
sizeof(arg)
int[10]
评论