0
void EventsStack::push(Event *e){
    EventNode *q = new EventNode();
    q->data = e;
    q->next = _top;
    _top = q;
}

void main() {
    EventsStack eventStack;
    Event e1(1);
    eventStack.push(&e1);
    Event e2(2);
    eventStack.push(&e2);
}

第一个问题:我什么时候做

eventStack.push(&e1);

我是否将 e1 的地址发送到 push 函数,而 push 函数将其作为指针接收?好像我在做:

Event *e = 1000 (1000 is the offset (address) of e1 for example on the stack)

?

第二个问题:我被要求在运行 main 函数时说明堆栈。当我到达线路时

eventStack.push(&e1);

是否将 4 字节返回地址和指向 e1 的 4 字节指针分配为函数的激活帧,或者在这种情况下没有激活帧,因为 eventStack 是 EventsStack 类的对象,并且 push 是其成员函数之一?

4

2 回答 2

1

关于您的第一个问题:表达式&e1采用 的地址e1,它是一个指针。换句话说,e1 有 type Event,并且&e1有 typeEvent*和一个值,这样取消引用它(一元运算*符)将具有与 using 相同的效果e1。这是您传递给 push 函数的内容。

并且指针不能只是堆栈上的偏移量,因为它必须可以从其他地方访问对象,而堆栈不一定可用。大多数现代台式机使用线性寻址,这意味着指针只是一个整数,但情况并非总是如此,在某些嵌入式处理器上可能并非如此(并且由于历史原因在某些大型机上)。

关于第二个问题:形式上,完全没有说明函数是如何调用的。必要的是编译器将返回地址和参数放在被调用函数可以找到它们的地方。在表达式eventStack.push( &e1 )中,函数有两个参数,地址eventStack(将成为 this函数中的指针)和表达式&e1。编译器如何传递这些变化很大,几乎总是取决于它们的类型,但通常,在大多数现代机器上,如果前 3 到 5 个参数适合(并且您传递的两个地址都适合),则它们将进入机器寄存器,因此推送到机器堆栈上的所有内容都是返回地址。并且参数通常不被视为当前帧的一部分,尽管在一些较旧的处理器上,编译器确实如此对待它们。(你说你被“要求说明堆栈”。这个问题是指特定的机器架构,还是什么?堆栈上实际发生的事情在编译器之间会有很大差异,Linux 下的 g++ 通常会做一些与 Visual 完全不同的事情工作室,即使在同一处理器上运行。)

于 2013-02-05T18:54:55.553 回答
0

关于您的第一个问题,是的:&运算符产生您的事件的内存地址。

至于你的第二个问题,嗯,很复杂。您所做的描述似乎表明了堆栈如何工作的潜在混淆。我强烈建议您阅读有关该主题的一些介绍性材料,这将使您有更深入的理解。

如果你去谷歌一下,几个小时后你就可以回答你自己的问题了:)。

于 2013-02-05T18:25:39.847 回答