简体   繁体   English

C中sizeof运算符的参数

[英]Parameters in the sizeof operator in C

I understand that when we use sizeof operator on an array name, it gives the total size of the array in bytes. 我知道当我们在数组名称上使用sizeof运算符时,它会以字节为单位给出数组的总大小。 For example 例如

int main(int argc, const char * argv[]) {
    int a[][5] = {
        {1,2,3,4,5},
        {10,20,30,40,50},
        {100,200,300,400,500}
    };

    int n=sizeof(a);
    printf("%d\n",n);

}

It gives 60 as output for 15 elements of the array. 它为阵列的15 elements提供60作为输出。 But when I write 但是当我写作

int n=sizeof(*a);

It gives 20 as the output that is the size of the first row while *a is the base address of the 0th element of the 0th row, and its type is a pointer to an integer. 它给出20作为第一行的大小的输出,而*a0th 0th行的0th元素的基地址,并且它的类型是指向整数的指针。 And a points to the first row itself. a指向第一行本身。 Why is this happening? 为什么会这样?

*a is row 0 of a , and that row is an array of five int . *a是0行a ,并且该行是5个的阵列int

In most expressions, an array is automatically converted to a pointer to its first element. 在大多数表达式中,数组会自动转换为指向其第一个元素的指针。 Thus, when you use *a in a statement such as int *x = *a; 因此,当你在诸如int *x = *a;类的语句中使用*aint *x = *a; , *a is converted to a pointer to its first element. *a被转换为指向其第一个元素的指针。 That results in a pointer to int , which may be assigned to x . 这导致指向int的指针,可以将其指定给x

However, when an array is the operand of a sizeof operator, a unary & operator, or an _Alignof_ operator, it is not converted to a pointer to its first element. 但是,当数组是sizeof运算符,一元&运算符或_Alignof_运算符的操作数时,它不会转换为指向其第一个元素的指针。 Also, an array that is a string literal being used to initialize an array is not converted to a pointer (so, in char foo[] = "abc"; , "abc" is used as an array to initialize foo ; it is not converted to a pointer). 另外,一个用于初始化数组的字符串文字的数组不会转换为指针(因此,在char foo[] = "abc";"abc"用作初始化foo的数组;它不是转换为指针)。

*a不是一个指针,它是一个int[5] ,它与你读取20假设一致,假定一个4字节的int

Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array. 除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则将将“N元素数组T ”的表达式转换为(“衰减”)到表达式“指向T指针”,表达式的值将是数组的第一个元素的地址。

The expression a has type "3-element array of 5-element array of int "; 表达 a具有类型“3元素数组5-元件的阵列的int ”; thus, sizeof a should yield 3 * 5 * sizeof (int) . 因此, sizeof a应该产生3 * 5 * sizeof (int)

The expression *a is the same as the expression a[0] ( a[i] is defined as *(a + i) - *a is the same as *(a + 0) , which is the same as a[0] ). 表达式*a与表达式a[0]a[i]定义为*(a + i) - *a*(a + 0)相同,与a[0]相同a[0] )。 Both *a and a[0] have type "5-element array of int "; *aa[0]都具有“5元素数组int ”; thus sizeof *a and sizeof a[0] should both yield 5 * sizeof (int) . 因此, sizeof a[0] sizeof *asizeof a[0]都应该产生5 * sizeof (int)

However... 然而...

If you pass a to a function, such as 如果你传递a给一个函数,如

foo( a );

then a is not the operand of the sizeof or unary & operators, and the expression will be converted from type "3-element array of 5-element array of int " to "pointer to 5-element array of int ": 那么a 不是 sizeof或一元&运算符的操作数,表达式将从类型“5元素数组的int元素3”转换为“指向5元素数组的int ”:

void foo( int (*a)[5] ) { ... }

If you computed sizeof a in function foo , you would not get 5 * sizeof (int) , you would get sizeof (int (*)[5]) , which, depending on the platform, would be 4 to 8 bytes. 如果你计算sizeof a函数foo sizeof a ,你就不会得到5 * sizeof (int) ,你会得到sizeof (int (*)[5]) ,这取决于平台,将是4到8个字节。

Similarly, if you passed *a or a[i] to a function, what the function actually receives is a pointer to int , not an array of int , and sizeof will reflect that. 类似地,如果将*aa[i]传递给函数,函数实际接收的是指向int的指针,而不是int数组,而sizeof将反映出来。

In this 2d array *a is a pointer because when you print it, its seems an address (but it is the 1st column address) : 在这个2d数组中*a是一个指针,因为当你打印它时,它似乎是一个地址(但它是1st列地址):

printf("%d\n", *a);

Output : 9435248 产量: 9435248

So : 所以:

for(int i = 0;i < 3;i++)
    printf("%d\n", *a[i]);

The output is : 输出是:

1
10
100

When you use of *a like this : *a[3] its means you are in 3rd row and 1st column by default. 当您使用*a*a[3]表示您默认位于3rd行和1st列。

*a is the address of 1st column and we have 5 column, so when you try this : *a1st列的地址,我们有5列,所以当你尝试这个时:

sizeof(*a);

Output will be 20 => ( 5 column) * ( int pointer which is 4 byte)). 输出将是20 =>( 5列)*( int pointer ,即4字节))。

A 2D array is viewed as an array of 1D arrays. 2D阵列被视为一维阵列的阵列。 That is, each row in a 2D array is a 1D array. 也就是说,2D阵列中的每一行都是一维阵列。 For a given 2D array A, int A[m][n] you can think of 对于给定的2D数组A,你可以想到int A [m] [n]

  • A[0] as the address of row 0 A [0]作为第0行的地址
  • A[1] as the address of row 1 etc & so on. A [1]作为第1行的地址等等。

Dereferencing can be thought of as below, 解除引用可以被认为如下,

 A[i][j] = *(A[i] + j) = *(*(A+i) + j)

So when you say *A, it means A[0] which gives you the address of 1st row & not the 1st element of the matrix. 所以当你说* A时,它意味着A [0],它给你第一行的地址而不是矩阵的第一个元素。

  • Dereference of A or *A gives the address of row 0 or A[0]. 取消引用A或* A给出行0或A [0]的地址。
  • Dereference of A[0] gives the first entry of A or A[0][0] that is A [0]的解引用给出A或A [0] [0]的第一个条目

    **A = A[0][0]. ** A = A [0] [0]。

& since you have 5 elements in the 1st row the size if 20 bytes. &因为第1行有5个元素,大小为20个字节。

Sizeof returns the size of the variable in memory expressed in bytes. Sizeof以字节为单位返回内存中变量的大小。 This includes padding (unused bytes added by a compiler to a structure to improve performance). 这包括填充(编译器向结构添加的未使用字节以提高性能)。 Your array has 15 elements of size 4. The sizeof an integer in memory is 4 in you case. 你的数组有15个大小为4的元素。在你的情况下,内存中整数的大小为4。 You can easily verify this by running: 您可以通过运行以下命令轻松验证:

printf("sizeof an integer: %zu\n", sizeof(int));

It is always a good idea to use standard int types. 使用标准int类型总是一个好主意。

#inlcude <stdint.h>
uint32_t a[][5] = {
    {1,2,3,4,5},
    {10,20,30,40,50},
    {100,200,300,400,500}
};

This will produce exactly the same code but wil clearly show the memory size of the (32 bit) integer. 这将生成完全相同的代码,但会清楚地显示(32位)整数的内存大小。 In your case uint8_t (unsigned int of 8 bit) might be more appropriate. 在你的情况下,uint8_t(8位的unsigned int)可能更合适。 You can read more here . 你可以在这里阅读更多。 To get the number of elements you should devide the total memory of the array by the sizeof an element. 要获取元素的数量,您应该通过元素的大小来分配数组的总内存。

sizeof(a)/sizeof(a[0])

You can also use a macro to do this: 您还可以使用宏来执行此操作:

#define ARRAY_LENGTH(array)(sizeof(array)/sizeof(array[0]))
/*ARRAY_LENGTH(a) will return 15 as expected.*/

You can also look for an answer here: How can I find the number of elements in an array? 你也可以在这里寻找答案: 我怎样才能找到数组中的元素数量?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM