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
还有一个
问题是:
&(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指针的微妙问题,而不是警告/非编译问题,这与本主题无关。干杯