C 数组映射选定内存区域

C 数组映射选定内存区域,c,arrays,pointers,casting,C,Arrays,Pointers,Casting,在处理其他问题时,我需要创建指向任意选定内存区域的指针,以便能够查找内存值。这些实验给我带来了有趣的问题和疑问 考虑以下代码: //Some hypothetical memory area simulation unsigned char data[4][4] = { {0x11,0x11,0x11,0x11}, //Memory areas 0x00 - 0x03 {0x22,0x22,0x22,0x22}, //Memory areas 0x04 - 0x07 {0

在处理其他问题时,我需要创建指向任意选定内存区域的指针,以便能够查找内存值。这些实验给我带来了有趣的问题和疑问

考虑以下代码:

//Some hypothetical memory area simulation
unsigned char data[4][4] =
{
    {0x11,0x11,0x11,0x11}, //Memory areas 0x00 - 0x03
    {0x22,0x22,0x22,0x22}, //Memory areas 0x04 - 0x07
    {0x33,0x33,0x33,0x33},
    {0x44,0x44,0x44,0x44},
};

// Structure that wraps byte array
typedef struct
{
    unsigned char TestArr1[4];
    unsigned char TestArr2[4];
    unsigned char TestArr3[4];
    unsigned char TestArr4[4];
}structure_t;

//Pointer to array of 4 chars
unsigned char (*MemLookup1)[4];

structure_t *StructLook;

int main(void)

{
    //Set both tested variables on first address of test array
    MemLookup1 = &data;
    StructLook = &data;
    //Some helpers to visualize results
    unsigned char * temp1, *temp2, *temp3, *temp4, *temp5;
    temp1 = &MemLookup1[0][0];
    temp2 = &MemLookup1[0][1];
    temp3 = &MemLookup1[0][2];
    temp4 = &MemLookup1[0][3];
    temp5 = &MemLookup1[1][0];

}
MemLookup1
声明为指向4个字符数组的指针(根据)。调试器下的结果令我惊讶

TEMP的值如下所示:

*temp1=0x11

*temp2=0x22

*temp3=0x33

*temp4=0x44

*temp5=0x11
//内存区0x04处

价值观

StructLook.TestArr1
0x11,0x11,0x11,0x11

StructLook.TestArr2
0x22,0x22,0x22,0x22

还有一个

问题是:

  • 如何记录和解释指针的“附加”维度特性?注意,指针导航时使用[n][x]符号,即使该指针被声明为一维数组

  • 为什么这样定义的指针内存对齐方式会使值在内存中“垂直”显示?当迭代第一个索引时,即
    &(MemLookup1[1])
    为我们提供
    MemLookup1[0]的地址+指针指向的元素的大小
    ,而不是数组的第二个元素或字符本身

  • 如何创建满足我的要求的数组类型的指针

  • 最后但并非最不重要的一点:当数组缠绕在结构上时,为什么它工作得非常好
    StructLook
    为我提供了我所需要的,对内存单元的线性查找

  • 编辑

    从调试器。
    代码是根据C(MinGW+GDB)编译的

    因为您的代码非常类似C,并且gcc成功编译了它——尽管有警告——所以我将回答C的问题

    首先,我确认您的
    MemLookup1
    声明为指向四个
    无符号字符的数组的指针。我还注意到,您的
    数据
    被声明为一个包含四个
    无符号字符
    的四个数组的数组,因此
    数据
    元素的类型与
    MemLookup1
    指向的类型相同

    现在考虑这个任务:

    MemLookup1 = &data;
    
    右侧是指向四个
    无符号字符数组的指针,左侧是指向四个
    无符号字符数组的指针。这些类型不兼容,因此您的代码不满足简单赋值运算符(由C2011在6.5.16.1/1中表示)的操作数约束,因此程序的行为未定义。类似情况也适用于
    StructLook
    的赋值。正确的赋值应该是
    MemLookup1=data
    MemLookup1=&data[0]
    ,或者类似的

    尽管C并没有定义程序的行为,但如果它可以编译,那么我们确实可以使用调试器来尝试查看在某些特定运行中实际发生的情况。请注意,C不能保证每次运行时都是相同的,甚至程序在某种程度上不会与调试器不兼容,但希望是永恒的

    你在这里摔倒了。您声称通过指针
    MemLookup1
    获得的数据视图与通过指针
    StructLook
    获得的数据视图不同,但调试器窗口图像中显示的表达式并不类似。例如,
    StructLook->TestArr1[1]
    的值与
    *MemLookup1[1]
    的值不一样,这似乎让您感到惊讶,但这是意料之中的

    正如我们已经建立的,
    MemLookup1
    是指向四个
    无符号字符的数组的指针<因此,code>MemLookup1[1]
    在内存中指定
    MemLookup1[0]
    后面的数组。在这种情况下,调试器显示
    MemLookup1
    StructLook
    都是
    数据的别名,因此
    MemLookup1[1]
    是指向
    数据[1]
    的指针,而
    StructLook->TestArr1
    数据[0]
    的别名。数组索引比指针解引用具有更高的优先级,在此上下文中,与大多数其他上下文一样,数组值表达式衰减为指向数组第一个元素的指针,因此
    *MemLookup1[1]
    相当于
    数据[1][0]
    。与
    (*MemLookup1)[1]
    ,这相当于
    数据[0][1]
    。还要注意
    (*MemLookup1)[1]
    的形式与
    MemLookup1
    的声明形式的相似性


    这与
    temp1
    的关系<代码>temp5
    不清楚。您的调试视图没有显示与这些相关的任何表达式。

    不能将<代码>和数据< /代码>分配给<代码> MeMeLoopUp1>代码>……这将不会在C++中编译。事实上,要注意编译器给你的错误——不要尝试“C风格”来摆脱错误。C和C++是不同的语言。选择一个。代码不会编译,因此令我惊讶的是,您从调试器中获得了任何东西…
    MemLookup1=&data格式不正确。注意编译器消息。一些常见的编译器在代码实际上非法时报告“警告”;将警告视为错误,除非您非常确定它们不是。是。这就是我一直在寻找的答案。感谢您关注C指针的微妙问题,而不是警告/非编译问题,这与本主题无关。干杯