[英]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
作为第一行的大小的输出,而*a
是0th
0th
行的0th
元素的基地址,并且它的类型是指向整数的指针。 和a
指向第一行本身。 为什么会这样?
*a
是0行a
,并且该行是5个的阵列int
。
在大多数表达式中,数组会自动转换为指向其第一个元素的指针。 因此,当你在诸如int *x = *a;
类的语句中使用*a
时int *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]
)。 *a
和a[0]
都具有“5元素数组int
”; 因此, sizeof a[0]
sizeof *a
和sizeof 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个字节。
类似地,如果将*a
或a[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
列。
*a
是1st
列的地址,我们有5
列,所以当你尝试这个时:
sizeof(*a);
输出将是20
=>( 5
列)*( int pointer
,即4
字节))。
2D阵列被视为一维阵列的阵列。 也就是说,2D阵列中的每一行都是一维阵列。 对于给定的2D数组A,你可以想到int A [m] [n]
解除引用可以被认为如下,
A[i][j] = *(A[i] + j) = *(*(A+i) + j)
所以当你说* A时,它意味着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.