为什么不是一个数组参数的大小相同的主要?
为什么不是一个数组的大小作为一个参数发送相同的主?
#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)); }
不 ,数组types在将它传递给函数时会隐式转换为指针types。
所以,
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*)
的值
这是一个指针,这就是为什么将数组的大小作为第二个parameter passing给函数的常见实现
正如其他人所说的,当用作函数参数时,数组会衰减为指向其第一个元素的指针。 值得注意的是,sizeof不会计算expression式,并且在与expression式一起使用时不需要括号,因此您的参数根本就没有被使用,所以您最好使用types而不是值来写入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));
因为数组作为parameter passing时会衰减为指针。 这就是C的工作原理,虽然你可以通过引用在C ++中传递“数组”,并克服这个问题。 请注意,您可以将不同大小的数组传递给此函数:
// 10 is superfluous here! You can pass an array of different size! void PrintSize(int p_someArray[10]);
你发现的行为实际上是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比率返回2.)
这个规则的唯一目的是保持与不支持传递聚合值作为函数参数的历史编译器的向后兼容性。
这并不意味着将数组传递给函数是不可能的。 你可以通过将数组embedded到一个结构体(这基本上是C ++ 11的std :: array的目的)来解决这个问题:
struct array_rly { int a[5]; }; void func(struct array_rly a) { printf("%zd\n", sizeof(aa)/sizeof(aa[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语言中,没有办法确定未知数组的大小,所以需要传递数量以及指向第一个元素的指针。
在c ++中,您可以通过引用传递一个数组来实现这个目的:
void foo(int (&array)[10]) { std::cout << sizeof(array) << "\n"; }
你不能将数组传递给函数。
如果你真的想打印大小,你可以传递一个指向数组的指针,但是它不会是通用的,因为你需要定义函数的数组大小。
#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)); }
在C语言中,当你将数组作为parameter passing给函数时,它会自动转换为指针,从一个函数传递数组,其他函数被称为引用调用。 这就是被调用函数只接收指向函数第一个元素的指针的原因。这就是原因
fun(int a [])类似于fun(int * a);
所以当你打印数组的大小时,它会打印第一个元素的大小。
行为是通过devise。
函数参数声明中相同的语法意味着完全不同于局部variables定义中的语法。
其他原因在其他答案中描述。
在'C'编程中,languange'sizeof()'是运算符,他以字节的forms返回对象的大小。'sizeof()'运算符的参数必须是一个左值types(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系统上的ineteger是4bytes。在64x是8bytes。在这种情况下,我们有10个整数在一个数组中声明。所以结果是'10 * sizeof INT)”。
一些技巧:
如果我们有一个这样的数组声明:'int n [] = {1,2,3,… 155;};'。 所以我们想知道这个数组中有多less个元素被存储。 使用此alghorithm:
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;
}
数组只是松散的大小。 大多数情况下,数组是指向内存的指针。 声明中的大小只告诉编译器为数组分配多less内存 – 它与types没有关联,所以sizeof()没有任何用处。