【问题标题】:Determining the number of bytes apart for a pointer in memory确定内存中指针的字节数
【发布时间】:2017-02-18 07:42:17
【问题描述】:

我对增加数组的指针然后测量指针位置的字节差异感到困惑。

我知道指针*p 在移动多维数组时会增加数据类型的大小。但是,当使用数组时,thisArray

int thisArray[ 7 ][ 4 ];

应该如何评估thisArrray + 1?我是否同时增加行和列?

我想知道这些指针在内存中的间隔是多少字节。

我知道确切的答案将取决于平台。我正在寻找解决方法,而不是确切的答案。

由于我无法在 cmets 中格式化代码:我将其放在这里:

// 使用 sizeof

#include <stdio.h>

int main(void) {

int tbl[ 7 ][ 4 ];

// Size of tbl
int x = sizeof(*tbl);
printf ( "%d\n" , x);

// Size of tbl + 1;
int y = sizeof(*tbl+1);
printf( "%d\n", y);

//Size apart in bytes
int z = y - x;
printf("%d\n", z);

return 0;
}

【问题讨论】:

  • 标题中问题的实际答案是sizeof(*thisArray)
  • @Dolda2000 这看起来是正确的;编译器提供此错误:q1.c:12:20: 警告:指针操作上的 sizeof 将返回大小为 'int *' 而不是 'int [5]' [-Wsizeof-array-decay] #include int main(void) { int tbl[ 7 ][ 4 ]; // tbl 的大小 int x = sizeof(*tbl); printf ("%d\n" , x); // tbl 的大小 + 1; int y = sizeof(*tbl+1); printf("%d\n", y); //大小以字节为单位 int z = y - x; printf("%d\n", z);返回0; }

标签: c arrays pointers


【解决方案1】:

当您单独使用索引时,它将乘以类型定义的大小。假设你的 int 是 4 个字节,那么每个 int 将在一个 int 类型的数组中相隔 4 个字节。这就是您的第二个或内部索引 (4) 的工作方式。

查看这个好答案: How are multi-dimensional arrays formatted in memory?

要理解第一个索引 (7),请注意二维数组实际上是数组的数组。在我们的示例中,第二个维度是四个元素宽,因此对于第一个索引的每个增量,您将跳过 4x4=16 个字节。所以 thisArray 是内存中的地址,[2][3] 将添加 2x16+3x4=44 字节。这是内存中第 4+4+3=11 个连续点,其中每个点为 4 个字节。

【讨论】:

    【解决方案2】:

    thisArray + 1 应该如何计算?

    thisArray衰减为指针时,指针类型为int (*)[4]thisArray+1的类型是一样的。

    我是否同时增加行和列?

    是的。

    如果你用行列结构查看thisArray的内存,你有:

    thisArray ->       +----+----+----+----+
                       |    |    |    |    |
    thisArray + 1 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 2 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 3 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 4 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 5 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 6 ->   +----+----+----+----+
                       |    |    |    |    |
    thisArray + 7 ->   +----+----+----+----+
    

    如果你想使用数组的遍历元素,你可以使用索引或指针。

    使用索引遍历:

    for ( int i = 0; i < 7; ++i )
    {
       for ( int j = 0; j < 4; ++j )
       {
           // Use thisArray[i][j];
       }
    }
    

    使用指针遍历:

    for ( int (*ptr1)[4] = thisArray; ptr1 < thisArray+7; ++ptr1 )
    {
       for ( int* ptr2 = *ptr1; ptr2 < *ptr1 + 4; ++ptr2 )
       {
           // Use *ptr2
       }
    }
    

    从可读性的角度来看,使用索引来遍历数组更加直观。我强烈建议使用它。

    【讨论】:

    • 您能否解释一下为什么必须在int (*ptr1)[4] 中指定4?谢谢。
    • @c650,表示ptr1 是一个指向4 个ints 数组的指针。指向 4 个ints 数组的指针与指向 5 个ints 数组的指针是不同的类型。因此,您必须准确。
    • 指针只是内存中的一个地址。只要你不越界,你就没事。你有关于这种行为的任何文件吗?
    • @c650,你说的是哪种行为?
    • 您需要指定[4]
    猜你喜欢
    • 1970-01-01
    • 2011-12-17
    • 2019-07-01
    • 2010-09-07
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    相关资源
    最近更新 更多