sizeof如何知道数组的大小?(复制)

时间:2022-01-22 21:28:26

This question already has an answer here:

这个问题已经有了答案:

I have codes as following:

我的代码如下:

main() {
    int array[5] = {3,6,9,-8,1};
    printf("the size of the array is %d\n", sizeof(array));
    printf("the address of array is %p\n", array);
    printf("the address of array is %p\n", &array);
    int * x = array;
    printf("the address of x is %p\n", x);
    printf("the size of x is %d\n", sizeof(x));
}

The output is

输出是

the size of the array is 20
the address of array is 0x7fff02309560
the address of array is 0x7fff02309560
the address of x is 0x7fff02309560
the size of x is 8

I know the variable array will be seen as a pointer to the first element of the array, so I understand the the size of x is 8. But I don't know why the size of the array is 20. Isn't it should be 8 (in a 64-bits machine)?

我知道变量数组会被看作是数组第一个元素的指针,所以我知道x的大小是8。但是我不知道为什么数组的大小是20。是不是应该是8(在64位机器中)?

Besides how does the program know that it is 20? As far as I know in C it doesn't store the number of elements. How come the sizeof(array) and sizeof(x) is different? I tracked several posts pertaining to array decaying but no idea on this problem.

再说,程序怎么知道是20呢?就我所知,在C中它不存储元素的数量。为什么sizeof(数组)和sizeof(x)是不同的?我跟踪了一些与阵列衰减有关的文章,但对这个问题一无所知。

7 个解决方案

#1


12  

The name of an array decays to a pointer to the first element of the array in most situations. There are a couple of exceptions to that rule though. The two most important are when the array name is used as the operand of either the sizeof operator or the address-of operator (&). In these cases, the name of the array remains an identifier for the array as a whole.

在大多数情况下,数组的名称会衰减到指向数组第一个元素的指针。但这条规则有几个例外。最重要的两个是当数组名用作sizeof运算符或运算符(&)的address时。在这些情况下,数组的名称仍然是整个数组的标识符。

For a non-VLA array, this means that the size of the array can be determined statically (at compile time) and the result of the expression will be the size of the array (in bytes), not the size of a pointer.

对于非vla数组,这意味着可以静态地(在编译时)确定数组的大小,表达式的结果将是数组的大小(以字节为单位),而不是指针的大小。

When you take the address of the array, you get the same value (i.e., the same address) as if you'd just used the name of the array without taking the address. The type is different though--when you explicitly take the address, what you get is a pointer of type "pointer to array of N items of type T". That means (for one example) that while array+1 points to the second element of the array, &array+1 points to another array just past the end of the entire array.

当您取数组的地址时,您将得到相同的值(即。,相同的地址)就好像你只是使用了数组的名称而没有使用地址一样。但是类型不同——当您显式地获取地址时,您得到的是一个类型为“指向N个类型为T的数组的指针”的指针。这意味着(例如)数组+1指向数组的第二个元素,&数组+1指向整个数组末尾的另一个数组。

Assuming an array of at least two items, *(array+1) will refer to the second element of the array. Regardless of the array size, &array+1 will yield an address past the end of the array, so attempting to dereference that address gives undefined behavior.

假设数组中至少有两个条目,*(数组+1)将指向数组的第二个元素。无论数组大小如何,&array+1将产生一个地址,该地址超过数组的末尾,因此尝试去引用该地址会产生未定义的行为。

In your case, given that the size of the array is 20, and the size of one element of the array is 4, if array was, say, 0x1000, then array+1 would be 0x1004 and &array+1 would be 0x1014 (0x14 = 20).

在您的例子中,给定数组的大小为20,数组的一个元素的大小为4,如果数组为0x1000,那么数组+1将是0x1004,而数组+1将是0x1014 (0x14 = 20)。

#2


14  

Your array has a static length so it can be determined at compile time. Your compiler knows the sizeof(int) = 4 and your static array length [5]. 4 * 5 = 20

数组具有静态长度,因此可以在编译时确定它。编译器知道sizeof(int) = 4和静态数组长度[5]。4 * 5 = 20

Edit: Your compilers int is probably 32-bit, but addressing 64-bit. That is why sizeof(pointer) returns 8.

编辑:编译器int可能是32位的,但寻址是64位的。这就是为什么sizeof(指针)返回8。

#3


9  

Note that sizeof is not a library function. sizeof is

注意,sizeof不是一个库函数。运算符是

a compile-time unary operator [...] that can be used to compute the size of any object
K&R

编译时一元运算符[…可以用来计算任何对象K&R的大小

So sizeof doesn't know how big the array is, the compiler knows how big the array is, and by definition

所以sizeof不知道数组有多大,编译器知道数组有多大,根据定义

when applied to an array, the result is the total number of bytes in the array.
K&R

当应用到数组时,结果就是数组中字节的总数。k和r

#4


7  

A pointer and an array are 2 different data types.

指针和数组是两种不同的数据类型。

Array can hold elements of similar data type. The memory for array is contiguous.

数组可以保存类似数据类型的元素。数组的内存是连续的。

Pointer is used to point to some valid memory location.

指针用于指向某个有效的内存位置。

sizeof(type) gives you the number of bytes of the type you pass.

sizeof(类型)给出了您传递的类型的字节数。

Now if you pass array then the compiler knows that this is an array and number of elements in it and it just multiplies that many elements with the respective data-type size value.

如果你通过数组,编译器就会知道这是一个数组和元素的数量它只是将很多元素乘以相应的数据类型大小值。

In this case:

在这种情况下:

5*4 = 20

Again the sizeof(int) or sizeof(pointer) is platform dependent. In this case you are seeing sizeof(pointer) as 8.

同样,sizeof(int)或sizeof(指针)是基于平台的。在这种情况下,可以看到sizeof(指针)为8。

#5


4  

No, arrays do not decay as operands of the sizeof operator. This is one of the few places where arrays don't decay. If an int is 4 bytes on your machine, then the total number of bytes of the array should be 20 (4 * 5). We don't even need an object to test this.

不,数组不会作为sizeof运算符的操作数衰减。这是数组不会衰变的少数几个地方之一。如果你的机器上有一个整数4个字节,那么数组的总字节数应该是20(4 * 5)。

sizeof(int[5]) // 20
sizeof(int*)   // 8 on a 64-bit machine

#6


2  

C11: 6.5.3.4 (p2)

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. [...]

sizeof运算符产生其操作数的大小(以字节为单位),它可以是一个表达式或一个类型的圆括号名。大小由操作数的类型决定。[…]

In the declaration

宣言

int array[5]  

the type of array is an array of 5 ints. The compiler will determine the size of array from this type.

数组的类型是一个5英寸的数组。编译器将从该类型中确定数组的大小。

#7


0  

Try this

试试这个

int x = sizeof(array)/sizeof(int);
printf("the size of the array is %d\n", x);

#1


12  

The name of an array decays to a pointer to the first element of the array in most situations. There are a couple of exceptions to that rule though. The two most important are when the array name is used as the operand of either the sizeof operator or the address-of operator (&). In these cases, the name of the array remains an identifier for the array as a whole.

在大多数情况下,数组的名称会衰减到指向数组第一个元素的指针。但这条规则有几个例外。最重要的两个是当数组名用作sizeof运算符或运算符(&)的address时。在这些情况下,数组的名称仍然是整个数组的标识符。

For a non-VLA array, this means that the size of the array can be determined statically (at compile time) and the result of the expression will be the size of the array (in bytes), not the size of a pointer.

对于非vla数组,这意味着可以静态地(在编译时)确定数组的大小,表达式的结果将是数组的大小(以字节为单位),而不是指针的大小。

When you take the address of the array, you get the same value (i.e., the same address) as if you'd just used the name of the array without taking the address. The type is different though--when you explicitly take the address, what you get is a pointer of type "pointer to array of N items of type T". That means (for one example) that while array+1 points to the second element of the array, &array+1 points to another array just past the end of the entire array.

当您取数组的地址时,您将得到相同的值(即。,相同的地址)就好像你只是使用了数组的名称而没有使用地址一样。但是类型不同——当您显式地获取地址时,您得到的是一个类型为“指向N个类型为T的数组的指针”的指针。这意味着(例如)数组+1指向数组的第二个元素,&数组+1指向整个数组末尾的另一个数组。

Assuming an array of at least two items, *(array+1) will refer to the second element of the array. Regardless of the array size, &array+1 will yield an address past the end of the array, so attempting to dereference that address gives undefined behavior.

假设数组中至少有两个条目,*(数组+1)将指向数组的第二个元素。无论数组大小如何,&array+1将产生一个地址,该地址超过数组的末尾,因此尝试去引用该地址会产生未定义的行为。

In your case, given that the size of the array is 20, and the size of one element of the array is 4, if array was, say, 0x1000, then array+1 would be 0x1004 and &array+1 would be 0x1014 (0x14 = 20).

在您的例子中,给定数组的大小为20,数组的一个元素的大小为4,如果数组为0x1000,那么数组+1将是0x1004,而数组+1将是0x1014 (0x14 = 20)。

#2


14  

Your array has a static length so it can be determined at compile time. Your compiler knows the sizeof(int) = 4 and your static array length [5]. 4 * 5 = 20

数组具有静态长度,因此可以在编译时确定它。编译器知道sizeof(int) = 4和静态数组长度[5]。4 * 5 = 20

Edit: Your compilers int is probably 32-bit, but addressing 64-bit. That is why sizeof(pointer) returns 8.

编辑:编译器int可能是32位的,但寻址是64位的。这就是为什么sizeof(指针)返回8。

#3


9  

Note that sizeof is not a library function. sizeof is

注意,sizeof不是一个库函数。运算符是

a compile-time unary operator [...] that can be used to compute the size of any object
K&R

编译时一元运算符[…可以用来计算任何对象K&R的大小

So sizeof doesn't know how big the array is, the compiler knows how big the array is, and by definition

所以sizeof不知道数组有多大,编译器知道数组有多大,根据定义

when applied to an array, the result is the total number of bytes in the array.
K&R

当应用到数组时,结果就是数组中字节的总数。k和r

#4


7  

A pointer and an array are 2 different data types.

指针和数组是两种不同的数据类型。

Array can hold elements of similar data type. The memory for array is contiguous.

数组可以保存类似数据类型的元素。数组的内存是连续的。

Pointer is used to point to some valid memory location.

指针用于指向某个有效的内存位置。

sizeof(type) gives you the number of bytes of the type you pass.

sizeof(类型)给出了您传递的类型的字节数。

Now if you pass array then the compiler knows that this is an array and number of elements in it and it just multiplies that many elements with the respective data-type size value.

如果你通过数组,编译器就会知道这是一个数组和元素的数量它只是将很多元素乘以相应的数据类型大小值。

In this case:

在这种情况下:

5*4 = 20

Again the sizeof(int) or sizeof(pointer) is platform dependent. In this case you are seeing sizeof(pointer) as 8.

同样,sizeof(int)或sizeof(指针)是基于平台的。在这种情况下,可以看到sizeof(指针)为8。

#5


4  

No, arrays do not decay as operands of the sizeof operator. This is one of the few places where arrays don't decay. If an int is 4 bytes on your machine, then the total number of bytes of the array should be 20 (4 * 5). We don't even need an object to test this.

不,数组不会作为sizeof运算符的操作数衰减。这是数组不会衰变的少数几个地方之一。如果你的机器上有一个整数4个字节,那么数组的总字节数应该是20(4 * 5)。

sizeof(int[5]) // 20
sizeof(int*)   // 8 on a 64-bit machine

#6


2  

C11: 6.5.3.4 (p2)

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. [...]

sizeof运算符产生其操作数的大小(以字节为单位),它可以是一个表达式或一个类型的圆括号名。大小由操作数的类型决定。[…]

In the declaration

宣言

int array[5]  

the type of array is an array of 5 ints. The compiler will determine the size of array from this type.

数组的类型是一个5英寸的数组。编译器将从该类型中确定数组的大小。

#7


0  

Try this

试试这个

int x = sizeof(array)/sizeof(int);
printf("the size of the array is %d\n", x);