繁体   English   中英

C中sizeof运算符的参数

[英]Parameters in the sizeof operator in C

我知道当我们在数组名称上使用sizeof运算符时,它会以字节为单位给出数组的总大小。 例如

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);

}

它为阵列的15 elements提供60作为输出。 但是当我写作

int n=sizeof(*a);

它给出20作为第一行的大小的输出,而*a0th 0th行的0th元素的基地址,并且它的类型是指向整数的指针。 a指向第一行本身。 为什么会这样?

*a是0行a ,并且该行是5个的阵列int

在大多数表达式中,数组会自动转换为指向其第一个元素的指针。 因此,当你在诸如int *x = *a;类的语句中使用*aint *x = *a; *a被转换为指向其第一个元素的指针。 这导致指向int的指针,可以将其指定给x

但是,当数组是sizeof运算符,一元&运算符或_Alignof_运算符的操作数时,它不会转换为指向其第一个元素的指针。 另外,一个用于初始化数组的字符串文字的数组不会转换为指针(因此,在char foo[] = "abc";"abc"用作初始化foo的数组;它不是转换为指针)。

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

除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则将将“N元素数组T ”的表达式转换为(“衰减”)到表达式“指向T指针”,表达式的值将是数组的第一个元素的地址。

表达 a具有类型“3元素数组5-元件的阵列的int ”; 因此, sizeof a应该产生3 * 5 * sizeof (int)

表达式*a与表达式a[0]a[i]定义为*(a + i) - *a*(a + 0)相同,与a[0]相同a[0] )。 *aa[0]都具有“5元素数组int ”; 因此, sizeof a[0] sizeof *asizeof a[0]都应该产生5 * sizeof (int)

然而...

如果你传递a给一个函数,如

foo( a );

那么a 不是 sizeof或一元&运算符的操作数,表达式将从类型“5元素数组的int元素3”转换为“指向5元素数组的int ”:

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

如果你计算sizeof a函数foo sizeof a ,你就不会得到5 * sizeof (int) ,你会得到sizeof (int (*)[5]) ,这取决于平台,将是4到8个字节。

类似地,如果将*aa[i]传递给函数,函数实际接收的是指向int的指针,而不是int数组,而sizeof将反映出来。

在这个2d数组中*a是一个指针,因为当你打印它时,它似乎是一个地址(但它是1st列地址):

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

产量: 9435248

所以:

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

输出是:

1
10
100

当您使用*a*a[3]表示您默认位于3rd行和1st列。

*a1st列的地址,我们有5列,所以当你尝试这个时:

sizeof(*a);

输出将是20 =>( 5列)*( int pointer ,即4字节))。

2D阵列被视为一维阵列的阵列。 也就是说,2D阵列中的每一行都是一维阵列。 对于给定的2D数组A,你可以想到int A [m] [n]

  • A [0]作为第0行的地址
  • A [1]作为第1行的地址等等。

解除引用可以被认为如下,

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

所以当你说* A时,它意味着A [0],它给你第一行的地址而不是矩阵的第一个元素。

  • 取消引用A或* A给出行0或A [0]的地址。
  • A [0]的解引用给出A或A [0] [0]的第一个条目

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

&因为第1行有5个元素,大小为20个字节。

Sizeof以字节为单位返回内存中变量的大小。 这包括填充(编译器向结构添加的未使用字节以提高性能)。 你的数组有15个大小为4的元素。在你的情况下,内存中整数的大小为4。 您可以通过运行以下命令轻松验证:

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

使用标准int类型总是一个好主意。

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

这将生成完全相同的代码,但会清楚地显示(32位)整数的内存大小。 在你的情况下,uint8_t(8位的unsigned int)可能更合适。 你可以在这里阅读更多。 要获取元素的数量,您应该通过元素的大小来分配数组的总内存。

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

您还可以使用宏来执行此操作:

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

你也可以在这里寻找答案: 我怎样才能找到数组中的元素数量?

暂无
暂无

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

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