没有sizeof运算符的数组大小

您所在的位置:网站首页 sozeof指针 没有sizeof运算符的数组大小

没有sizeof运算符的数组大小

2023-03-15 15:32| 来源: 网络整理| 查看: 265

我想了解下面的程序,但我不清楚.

#include int main() { int a[]={1,2,3,4,5,6,9}; printf("sizeof array is %d\n",sizeof(a)); printf("size of array using logic is %d\n",((&a)[1]-a)); printf("value of (&a)[1] is %p \n",(&a)[1]); printf("value of a is %p \n",a); printf("address of a[0] is %p\n",&a[0]); printf("address of a[1] is %p\n",&a[1]); printf("address of a[2] is %p\n",&a[2]); printf("address of a[3] is %p\n",&a[3]); printf("address of a[4] is %p\n",&a[4]); printf("address of a[5] is %p\n",&a[5]); printf("address of a[6] is %p\n",&a[6]); }

上面的代码输出是:

sizeof array is 28 size of array using logic is 7 value of (&a)[1] is 0x7ffc4888e78c value of a is 0x7ffc4888e770 address of a[0] is 0x7ffc4888e770 address of a[1] is 0x7ffc4888e774 address of a[2] is 0x7ffc4888e778 address of a[3] is 0x7ffc4888e77c address of a[4] is 0x7ffc4888e780 address of a[5] is 0x7ffc4888e784 address of a[6] is 0x7ffc4888e788

我不清楚为什么((&a)[1]-a))在第二次印刷声明中返回7; 它应该0x7ffc4888e78c - 0x7ffc4888e770是0x1c28个阵列的总大小.

作为参考,我还尝试了打印(&a)[1]和您可以在代码中看到的值.我也尝试过调试.

1> Carter..:

如果你投(&a)[1]并a以long计算之前,那么你会得到你预期的结果.正如haccks评论的那样,你正在计算指针差异.

// These two sizes will be the same printf("sizeof array is %ld\n",sizeof(a)); printf("size of array using logic is %ld\n",((long)(&a)[1]-(long)a));

解释数学

在这种情况下发生的事情&a被认为是类型int(*)[7].

然后,您参考(&a)[1],转换为*((&a)+1).在英语中,这意味着"在开始之后给我记忆1.a" 正如&a恰好是类型int(*)[7],即点位于阵列的端部.

当你减去a指向数组开头的指针时,你正在执行指针运算并取一个大小为a的基数int(因为它a是一个int数组).所以表达式((&a)[1]-a)计算的int是(&a)[1]和之间的数量a.

可以在此处找到有关指针算法的概述.

不要强制转换为`long`,[使用`ptrdiff_t`并使用`%td`或`off_t`打印并使用'%jd`打印](http://stackoverflow.com/q/586928/995714) 呀谢谢,但没有类型转换我得到7,这对我来说仍然不清楚.所有说它与sizeof(a)/ sozeof(a [0])相同.但是告诉它类似于这是好的,但同时调试如何才能清楚地理解这种差异.

2> haccks..:

(&a)[1]是数组之后的内存位置的地址a,即0x7ffc4888e788.(&a)[1]是类型的int *.转换后,a将是类型int *.它相当于(&a)[0].

标准说:

C11-§6.5.6/ 9:

当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异.

差异(&a)[1]-a给出了数组中元素的数量a.请注意,a 在这个表达式是数组元素的地址a[0],衰变后,而这个地址等同于数组的地址a,虽然&a并a[0]具有不同的类型.

您可以将这种差异视为(&a)[1]-(&a)[0]或&a[7] - &a[0].

sizeof(a)给出为数组分配的内存大小a.sizeof(a)/sizeof(a[0])将给出数组元素的数量a.

如果你可以在(&a)[x]和&a [x]之间加上一个小注释,这将对未来的观众有所帮助:-) @CherubimAnand; 在投射之后它不再是指针差异,而是整数差异."0 - 4"的整数差异将给出"4",而指针差异将给出"1"(假设"长"大小为"4").

3> Yakk - Adam ..:

所以指针不是整数.当然,您可以通过将它们转换为整数类型将它们转换为整数,或者向它们添加整数以将它们滑动.但它们不是整数.

如果你做了任何线性代数,指针就像整数的数学向量.

p1-p2之间的距离为p1和p2,添加到所需要的整数p2达到p1.

向指针添加整数时,必须注意指针的类型.如果指针指向大小为4的对象,则每次向指针添加1时,其数字地址将增加4而不是1.

当你减去两个指针时,同样的事情也是如此.

这里的关键部分是内存中地址的数值很重要,但类型对于理解发生的事情同样重要.

这里发生的第二个奇怪的事情是,数组会在一滴帽子的情况下衰减成指向第一个元素的指针.然而,它们并不是指向第一个元素的指针,它们只是很容​​易转换成它们.

所以当我们这样做时:

(&a)[1]

我们正在采取的地址a.地址a是类型的指针int(*)[7].它是指向数组的指针,而不是指向数组第一个元素的指针.不同之处在于指针的类型.这7很重要.

然后我们使用[] 指针.如果你有一个指针或数组p和一个值v,p[v]则定义为*(p+v).如果你这样做会导致幽默v[p],但这并不重要.

让我们pa代表(&a).然后pa[1]就是*(pa + 1).

现在,pa是一个指向数组的指针(不是指向数组的第一个元素).因此,+1将数组的完整大小(sizeof(int)*7)添加到数值.

所以pa+1是指向一个结尾的a指针,并且是指向数组的指针类型.

然后我们取消引用,并在数组结束后立即得到大小为7的不存在的数组a.

然后我们减去a.

(&a)[1]-a

这就是指针衰减的地方.-数组上没有操作,但-指针上有一个操作.因此,C语言有助于将每个数组衰减为指向其第一个元素的指针.

指向第一个元素的指针a是&a[0].

结束后立即将指针尺寸7的阵列的第一个元素a是... &a[7].

这两个指针都是类型的int*.当你减去两个int*s时,你得到它们的数字指针值,除以sizeof(int).在这种情况下,这很容易 - 7.

如果我们看一下这可能会更容易:

(&a)[1]-(&a)[0]

要么

*(&a+1)-*(&a+0)

&a是指向a"指向大小为7 的数组的指针"类型的数组的指针.我们向它添加1,在一个case中获得指向数组的指针,在另一种情况下获得0.

然后我们回到数组,然后减去.减法触发衰减到指向第一个元素的指针,因此我们在a结束后立即得到一个指向该元素的指针,并指向一个指向第一个元素的指针.

&a[7]-&a[0]

是的

&*(a+7)-&*(a+0)

现在&*对已经指针的东西(它们在那一点上)没有任何作用,所以:

(a+7)-(a+0)

那么问题就变成了,您需要添加多少a+0才能达到目标a+7.毫不奇怪,答案是7:

(a+7) = (a+0)+7

这就是显示的内容.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3