C语言中sizeof运算符中的参数

时间:2018-07-23 12:02:02

标签: c pointers multidimensional-array sizeof

我了解到,当我们在数组名称上使用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);

}

它给出60作为数组15 elements的输出。但是当我写

int n=sizeof(*a);

它以20作为输出,它是第一行的大小,而*a0th行的0th元素的基址,及其type是指向整数的指针。 a指向第一行本身。为什么会这样?

6 个答案:

答案 0 :(得分:6)

*aa的第0行,该行是五个int的数组。

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

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

答案 1 :(得分:5)

*a不是指针,而是int[5],它与您假设四个字节的20int的阅读保持一致。

答案 2 :(得分:2)

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

表达式 a的类型为“ int的5元素数组的3元素数组”;因此,sizeof a应该产生3 * 5 * sizeof (int)

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

但是...

如果您将a传递给函数,例如

foo( a );

然后asizeof或一元&运算符的操作数 not ,表达式将从类型为“ 3个元素的数组int的5元素数组到“ int的5元素数组的指针”:

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

如果您在函数{{1}中计算了sizeof a,您将得到foo,您将得到5 * sizeof (int),具体取决于平台,则为4到8个字节。

类似地,如果您将sizeof (int (*)[5])*a传递给一个函数,则该函数实际接收的是指向a[i]的指针,而不是int和{的数组{1}}将反映出这一点。

答案 3 :(得分:1)

在此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字节)。

答案 4 :(得分:0)

2D数组被视为1D数组的数组。也就是说,二维数组中的每一行都是一维数组。对于给定的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]。

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

答案 5 :(得分:-1)

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位无符号整数)可能更合适。您可以阅读更多here。要获取元素数量,您应该将数组的总内存乘以元素的大小。

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

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

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

您也可以在这里寻找答案:How can I find the number of elements in an array?