指向数据结构成员的指针

时间:2018-03-12 21:24:10

标签: c++ pointers data-structures

我最近阅读了关于pointers to data structures的C ++教程的一部分,其结构定义为:

struct movies_t {
    string title;
    int year;
};

movies_t * pmovie;

它提到了(*pmovie).title*(pmovie.title)的不同之处。有人能解释一下原因吗?

6 个答案:

答案 0 :(得分:2)

你不能只是交换那种语法,因为两者都意味着不同的东西。

第一种情况,(*pmovie).title表示pmovie是一个指针,你正在取消引用它,然后提取"标题"该对象的字段。等效/更简单的语法是pmovie-> title。

你的第二个案例说," Pmovie是一个对象,而title是指向某个东西的指针。我想取消引用该指针。"

例如:

struct Movie {
    std::string title;
};

Movie movie;
Movie * pmovie = &movie;  // here pmovie is a pointer to a movie
pmovie->title = "Trading Places";
(*pmovie).title = "Trading Places";  // same meaning as line above

VS

struct Movie {
    std::string * title;
};

std::string title;
Movie pmovie;  // here "pmovie" is an insanely named variable for a non-ptr
pmovie.title = &title;

*(pmovie.title) = "V For Vendetta";  // Note, pmovie not a ptr, title is

显然,第二种情况是荒谬的,实际上是一个糟糕的界面(你不希望你的对象界面中有原始指针,无论是内部还是外部拥有对象。)我只给出了示例来说明它们之间的区别是。希望您只在第一种情况下遇到代码。

答案 1 :(得分:1)

第一个取消引用指针pmovie。它相当于

pmovie->title

第二种是非法语法,假设pmovie是一个指针。

答案 2 :(得分:1)

如果pmovie是指针(例如movies_t * pmovie),则访问其成员必须使用-> - 运算符(即pmovie->title)或取消引用指针为了使用. - 符号(即(*pmovie).title,相当于pmovie->title)来解决它。相比之下,*(pmovie.title)完全错误,因为运算符.无法应用于指针。

答案 3 :(得分:0)

在C ++中,就像在数学中一样,复杂表达式的操作按特定顺序进行评估。操作的顺序通常会改变表达式的含义。括号可用于明确指定预期的顺序。例如,RegisterAsmPrinter$(document).on('click', '.ck-editor__editable_inline', function(e) { // do something })

1 + (2 * 3) == 1 + 6 == 7(1 + 2) * 3 == 3 * 3 == 9不同,因为括号会更改操作的顺序。第一个间接(==取消引用)表达式(*pmovie).title,并访问间接结果的成员*(pmovie.title)。第二个访问表达式pmovie的成员title并指向该成员。

现在,鉴于声明title,表达式pmovie格式错误,因为成员访问运算符无法应用于指针。

答案 4 :(得分:0)

当你说(* pmovie).title时,这意味着你首先得到pmovie指向的内容,然后询问它的标题是什么。

当你说*(pmovie.title)时,你首先要求获得电影的标题,然后询问它指向的是什么。第二个是错误的,因为你不能问指针它的标题是什么,因为它只是一个指针,而不是一个真正的movies_t对象。

注意:这仅适用于您发布的特定示例。有时*(pmovie.title)有意义。考虑你有

的情况
struct movies_t {
    // note how I made title a string pointer, not just a string
    string* title; 
    int year;
};

int main(){
    // note that movie_object is NOT a pointer, so *movie_object makes no 
    // sense
    movies_t movie_object;
    // the following expects a string, but 'title' is a string pointer
    // so movie_object.title returns a string pointer. I use * to access the 
    // actual string
    cout << *(movie_object.title) << endl;
}

答案 5 :(得分:0)

它与operator precedence有关。这里,我们讨论的2个运算符是*(解除引用运算符,也称为间接运算符)和.(结构/类成员访问运算符)。它们必须以正确的顺序执行,否则你得到的结果没有意义。

让我们试试一个例子。你去游泳池。你穿上你的泳衣,把所有的东西都放在一个储物柜里,你可以拿一把钥匙上的钥匙。该号码指的是储物柜,并允许您识别它。在某种程度上,它“指向”储物柜(就像指针指向一个变量)。

现在,你即将游泳,你意识到你已经忘记了游泳帽。你记得你把它留在了储物柜里面的顶部抽屉里。因此,您必须:读取钥匙上的数字以找到您的储物柜(并打开它),然后打开顶部抽屉并带上泳帽。如果相反,你取了钥匙的号码,试图打开它的顶部抽屉(是的,钥匙的号码的顶部抽屉!),期望在里面找到一个游泳帽,然后试图读取帽子上的数字以找到它是否有用你的储物柜?当然不是。这没有意义。这意味着执行正确的操作,但是顺序错误,因此错误的对象。

现在,回到你的例子。 pmovie是指向结构的指针。在我们讨论的两个操作(取消引用和成员访问)中,您希望取消引用它以获取结构。您当然不希望访问其中一个成员,因为指针不包含成员而不是键的编号 有抽屉。

同样,struct有成员,在这种情况下,一个名为title。一旦你到了结构(储物柜),你想要访问它的内容(成员title,或带游泳帽的抽屉)。

所以,我们想要做的是清楚:首先我们想要取消引用指针(比如读取键上的数字并找到锁定器),然后,对此操作的结果(结构或锁定器) ),我们想要拿出我们需要的东西(标题或顶部抽屉)。

现在回到C ++:如果你只是写*pmovie.title,你会先执行什么操作,使用*取消引用,或使用.取消成员访问?请注意,您想要的并不一定是您得到的。在这种情况下,它不是:根据C ++的规则,必须首先评估点,因为它具有更高的优先级(为了避免每次都检查表,一个简单的助记符规则就是右边的那个,比如点,优先级比左边的优先级更高。这将导致一个没有意义的操作。

为了确保正确的结果,必须按正确的顺序应用运算符:首先是指针取消引用,获取结构,然后应用成员访问权限。为了确保这一点,我们必须强制编译器按照非默认顺序评估运算符,并且执行此操作的方法是使用括号:通过编写(*pmovie).title,星点在点之前应用,这给出了预期的结果。