我了解到,当我们在数组名称上使用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
作为输出,它是第一行的大小,而*a
是0th
行的0th
元素的基址,及其type是指向整数的指针。 a
指向第一行本身。为什么会这样?
答案 0 :(得分:6)
*a
是a
的第0行,该行是五个int
的数组。
在大多数表达式中,数组会自动转换为指向其第一个元素的指针。因此,当您在诸如*a
之类的语句中使用int *x = *a;
时,*a
将转换为指向其第一个元素的指针。这导致指向int
的指针,该指针可以分配给x
。
但是,当数组是sizeof
运算符,一元&
运算符或_Alignof_
运算符的操作数时,它不会转换为指向其第一个元素的指针。另外,作为用于初始化数组的字符串文字的数组不会转换为指针(因此,在char foo[] = "abc";
中,"abc"
被用作初始化foo
的数组;它不会转换为指针)。
答案 1 :(得分:5)
*a
不是指针,而是int[5]
,它与您假设四个字节的20
对int
的阅读保持一致。
答案 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]
相同)。 *a
和a[0]
的类型均为“ int
的5元素数组”;因此sizeof *a
和sizeof a[0]
都应产生5 * sizeof (int)
。
但是...
如果您将a
传递给函数,例如
foo( a );
然后a
是sizeof
或一元&
运算符的操作数 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
列中。
*a
是1st
列的地址,我们有5
列,因此,当您尝试这样做时:
sizeof(*a);
输出将为20
=>(5
列)*(int pointer
,即4
字节)。
答案 4 :(得分:0)
2D数组被视为1D数组的数组。也就是说,二维数组中的每一行都是一维数组。对于给定的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]。
&,因为第一行有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?