给定C:int a [2] [3] [4] [5]中数组的定义,并且[0] [0] [0] [0]的地址为1000,地址是什么[1] [1] [1] [1] [1],假设一个int占用4个字节。
我得到了:
(3 * 4 * 5 * 4bytes)+(4 * 5 * 4bytes)+(5 * 4bytes)+ 4bytes = 344
344 + 1000 = 1344 [1] [1] [1] [1]
的位置
但我不知道我是否正确。但我的数学对我来说似乎很合理。
答案 0 :(得分:3)
只要打印变量的地址,你就会看到它!:
#include <stdio.h>
int main() {
int a[2][3][4][5];
printf ("Size of int %d\n", sizeof(int));
printf("Adress of the frist element \t%p\n", &a[0][0][0][0]);
printf("Adress of x element \t\t%p\n", &a[1][1][1][1]);
printf ("In decimal: \t\t\t%d\n", &(a[0][0][0][0]));
printf ("In decimal: \t\t\t%d\n", &(a[1][1][1][1]));
printf("Difference between the adresses %d", (char *)&a[1][1][1][1] - (char *)&a[0][0][0][0]);
return 0;
}
之后你可以检查你是否正确!
当你看到你的权利时!它是334
答案 1 :(得分:3)
你的数学是正确的。您可以通过减去两个地址来检查,但不要忘记指针算术将识别类型大小,因此您必须将地址强制转换为大小为字节的char:
( char* )&a[1][1][1][1] - ( char* )&a[0][0][0][0]
给出了字节差异。然后只需添加起始地址即可获得答案。
答案 2 :(得分:0)
这样的事情很容易检查(a):
#include <stdio.h>
int main (void) {
int a[2][3][4][5];
// Ignore incorrect format specifiers for now.
printf ("%d\n", sizeof(int));
printf ("%d\n", &(a[0][0][0][0]));
printf ("%d\n", &(a[1][1][1][1]));
printf ("%d\n", (int)&(a[1][1][1][1])
- (int)&(a[0][0][0][0])
+ 1000);
return 0;
}
,输出结果为:
4
2665056
2665400
1344
请注意最终int
中指向printf
值的指针的转换。如果没有这个,1000
将缩放为int *
,给出错误的值。
所以,是的,底线,你的推理是正确的。
(a)这不是总是的情况,因为C语言的某些方面可能因实现(实现指定的行为)或他们想要的任何方式而不同(undefined)行为)。
令人高兴的是,C11 6.5.2.1 Array subscripting
中标准专门指定了数组的布局:
2 /后缀表达式后跟方括号
[]
中的表达式是数组对象元素的下标名称。下标运算符[]
的定义是E1[E2]
与(*((E1)+(E2)))
相同。由于适用于二进制+
运算符的转换规则,如果E1
是一个数组对象(等效地,指向数组对象的初始元素的指针),并且E2
是一个整数,E1[E2]
指定E2-th
的{{1}}元素(从零开始计算)。3 /连续的下标运算符指定多维数组对象的元素。如果
E1
是维度为E
的n维数组(n> = 2),则i * j * ... * k
(用作除左值之外的值)将转换为指向(n)的指针 - 1)维度为E
的维数组。如果将一元j * ... * k
运算符显式地应用于此指针,或者作为预订的结果隐式应用,则结果是引用的(n-1)维数组,如果用作其他数组,则该数组本身将转换为指针。一个左值。 由此得出,数组以行主顺序存储(最后一个下标变化最快)。