我有一个问题。假设我有一个结构,比如说:
struct myData
{
int a;
int b
} x, y ;
然后,我创建一个指向x的指针,例如:
myData * x_ptr = &x;
所以我知道x_ptr指向存储x的内存位置。所以我可以找到整个结构的内存位置。但是,假设我想找到struct变量x的成员a的内存位置。我该怎么做?
对我来说,做这样的事情似乎很自然:
x_ptr.a
现在,我知道这不行。当我想象变量如何存储在计算机的内存中时,我想到的是一个带有内容的盒子。所以对于一个结构,它将是一个更大的盒子,其中包含两个成员,在我的例子中 a 和 b 。那么, a 和 b 的内存位置是否与整个“框”的内存位置相同? 这就是为什么我无法访问x.a的内存位置?
我正在努力理解指针,我很快就知道事情是如何运作的,但这让我感到困扰。请问有人能回答我吗?谢谢! :)
答案 0 :(得分:1)
很简单
a的内存位置为&x_ptr->a;
答案 1 :(得分:0)
int *x_a_ptr = &(x_ptr->a);
现在x_a_ptr
是指向a
的指针,x_ptr
是x_ptr
指向的结构的一部分。
我认为在这种情况下,x_a_ptr
和b
的价值可能相同。但如果你有一个指向x_ptr
的指针,它的值与&(x_ptr->a)
不同。
顺便说一下,您可以&(x.a)
而不是{{1}}。
答案 2 :(得分:0)
对于POD类型(POD表示普通旧数据),struct
成员通常在内存中线性排列,有时在成员之间使用填充以满足类型的对齐约束。
在您的示例中,x_ptr
指向struct
的第一个字节,以及struct
的第一个成员。实际上,您可以安全地将指向结构的指针转换为指向第一个成员的结构。
当您说x_ptr->a
或x_ptr->b
时,编译器会根据struct
的布局在解除引用之前为指针添加偏移量。
您可以通过说出struct
或&(x.a)
来直接指向&(x.b)
的成员。
答案 3 :(得分:0)
有关其内存结构的类和结构的规则是相当直接的:
myData * x_ptr = &x; // pointer to x
x_ptr->a = 5; // sets a to 5
int* a = (int*)&x; // since a is the first element, this will set a to the address of x.a
int* b = &(x.a); // this will also give you the address of x.a
答案 4 :(得分:0)
如果要查找子对象的地址,可以只获取子对象的地址,例如:
&x.a
或
&x_ptr->a
如果你想相对于一个指针采用a
的地址,你可以使用
int myData::*a_ptr = &myData::a;
这定义了指向成员的指针,它可以与对象或指针一起使用来访问成员,例如。
int val0 = x.*a_ptr;
int val1 = x_ptr->*a_ptr;
如果这些没有任何意义,那么暂时忽略指向成员的指针(它们在现实生活中很少出现,部分原因是几乎没有任何C ++程序员知道它们)。
答案 5 :(得分:0)
正如其他人所说,它是&(x_ptr->a)
。要解释发生了什么,您必须了解表达式是否是指针,以及如何在两者之间移动。以下是一些获得直觉的例子:
myData dataOnStack; // dataOnStack lives on the stack
int a = dataOnStack.a; // we can directly reach for members
// this is just a pointer to struct we made earlier
myData * dataPtr = &onStack;
// here we dereference the pointer, and copy to the stack
myData copyOnStack = *dataPtr;
// again we can directly reach inside our copy
a = copyOnStack.a
// given a pointer, we can dereference and reach inside it using ->
// here, the whole expression dataPtr->a is not a pointer, because
// we have dereferenced dataPtr.
a = dataPtr->a;
// to finally answer your question, we can move back to the "pointer world"
// by taking the address of the previous expression
int* aPtr = &(dataPtr->a);
// alternatively, instead of going through the pointer, since
// we have the original struct on the stack we can just do this:
aPtr = &dataOnStack.a;