在C中查找数组中索引的地址

时间:2014-11-13 01:31:20

标签: c arrays memory-address

给定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]

的位置

但我不知道我是否正确。但我的数学对我来说似乎很合理。

3 个答案:

答案 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)维数组,如果用作其他数组,则该数组本身将转换为指针。一个左值。 由此得出,数组以行主顺序存储(最后一个下标变化最快)。