为什么数组参数的大小与main中的大小不同?

Chr*_*_45 101 c arrays function sizeof

为什么作为参数发送的数组的大小与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));
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*rav 100

将数组类型传递给函数时,会隐式转换为指针类型.

所以,

void PrintSize(int p_someArray[10]) {
    printf("%zu\n", sizeof(p_someArray));
}
Run Code Online (Sandbox Code Playgroud)

void PrintSize(int *p_someArray) {
    printf("%zu\n", sizeof(p_someArray));
}
Run Code Online (Sandbox Code Playgroud)

是等价的.所以你得到的是价值sizeof(int*)

  • 您需要将数组的大小作为单独的参数传递.那么数组的大小将是sizeof(*p_someArray)*length (12认同)
  • Minor nit:`sizeof`操作符返回一个类型为`size_t`的对象,因此您应该使用`%zu`(C99)打印它,或者如果在`printf中使用上面的'%d`,则将其强制转换为`int` `来电. (12认同)
  • Alok的陈述是正确的.在printf(..)中使用不正确的格式说明符是UB. (4认同)
  • @Chris_45:C 没有引用,但在 C 中,您可以通过指向整个数组的指针传递数组,如:`void PrintSize(int (*p_someArray)[10])`。在函数内部,您可以使用解引用运算符“*”来访问数组:“sizeof(*p_someArray)”。这与在 C++ 中使用引用具有相同的效果。 (3认同)
  • 在 C++ 中,您可以通过引用函数来传递数组,但在 C 中不能这样做。 (2认同)

use*_*312 18

它是一个指针,这就是为什么它是一个常见的实现,将数组的大小作为第二个参数传递给函数


Pet*_*ham 16

正如其他人所说,当用作函数参数时,数组会衰减到指向第一个元素的指针.还值得注意的是,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] ) );
}
Run Code Online (Sandbox Code Playgroud)


S.C*_*sen 12

因此,您需要将数组的长度作为第二个参数传递.当您编写代码时,您既要声明一个常量大小的数组,然后将该数组传递给函数,那么让数组长度常量显示在代码中的几个位置是很痛苦的...

K&R救援:

#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) 
Run Code Online (Sandbox Code Playgroud)

所以现在你可以这样做:

int a[10];
...
myfunction(a, N_ELEMENTS(a));
Run Code Online (Sandbox Code Playgroud)


Ara*_*raK 5

因为数组在作为参数传递时会衰减为指针.这就是C的工作原理,尽管你可以通过引用传递C++中的"数组"并克服这个问题.请注意,您可以将不同大小的数组传递给此函数:

 // 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
Run Code Online (Sandbox Code Playgroud)


Ale*_* C. 5

在 C++ 中,您可以为此目的通过引用传递数组:

void foo(int (&array)[10])
{
    std::cout << sizeof(array) << "\n";
}
Run Code Online (Sandbox Code Playgroud)


Wal*_*ter 5

你发现的行为实际上是C语言中的一个大问题.每当您声明一个带有数组参数的函数时,编译器都会忽略您并将参数更改为指针.所以这些声明都表现得像第一个:

void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
Run Code Online (Sandbox Code Playgroud)

a将是所有四种情况下指向int的指针.如果将数组传递给func,它将立即衰减为指向其第一个元素的指针.(在64位系统上,64位指针的大小是32位int的两倍,因此您的sizeof比率返回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 */
}
Run Code Online (Sandbox Code Playgroud)

或者通过传递指向数组的指针:

void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints 5 */
}
Run Code Online (Sandbox Code Playgroud)

如果数组大小不是编译时常量,则可以将指针到数组技术与C99可变长度数组一起使用:

void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints n */
}
Run Code Online (Sandbox Code Playgroud)