我不明白为什么这个函数"从列表中返回一个指针"

22 c++ pointers linked-list singly-linked-list

我正在阅读的书,链接列表数据结构简介(演示文稿21),有2个链表的例子.这是第一个:

EnemySpaceShip* getNewEnemy ()
{
    EnemySpaceShip* p_ship = new EnemySpaceShip;
    p_ship->x_coordinate = 0;
    p_ship->y_coordinate = 0;
    p_ship->weapon_power = 20;
    p_ship->p_next_enemy = p_enemies;
    p_enemies = p_ship;
    return p_ship;
}
Run Code Online (Sandbox Code Playgroud)

链接列表的第二个示例是这样的:

EnemySpaceShip* addNewEnemyToList (EnemySpaceShip* p_list)
{
    EnemySpaceShip* p_ship = new EnemySpaceShip;
    p_ship->x_coordinate = 0;
    p_ship->y_coordinate = 0;
    p_ship->weapon_power = 20;
    p_ship->p_next_enemy = p_list;
    return p_ship;
}
Run Code Online (Sandbox Code Playgroud)

然后这本书写道:

请注意,此函数不同,getNewEnemy因为它返回指向列表的指针,而不是新的敌人.

我不明白的是他的意思是"第二个函数返回一个指向列表的指针"和"第一个函数返回新的敌人".我以为他们都创造了一个叫做的新敌人p_ship(既是指针又是新敌人)并将其归还.这句话是什么意思?

Cor*_*mer 20

这是重要的路线

p_ship->p_next_enemy = p_list;
Run Code Online (Sandbox Code Playgroud)

请注意,它p_ship有一个指针,p_next_enemy它本身就是一个EnemySpaceShip*.因此,如果你一遍又一遍地调用这个函数,你最终会得到一个链表.您可以从第一个开始EnemySpaceShip*并在循环中遍历所有这些,例如

EnemySpaceShip* p_ship = p_first_ship;    // assume this was known
while (p_ship->p_next_enemy != nullptr)
{
    p_ship = p_ship->p_next_enemy;
    // p_ship has now advanced one element of your linked list
}
Run Code Online (Sandbox Code Playgroud)

此外,由于这些船只的添加顺序,如果您addNewEnemyToList多次调用,最后一次调用它,您实际上会获得指向链表中第一艘船的指针.这就是为什么作者说"它返回一个指向列表的指针".

  • 都是真的.这是非常奇怪的措辞.OP是正确的,返回的是指向新船的指针.只是在后一种情况下,该船是侵入性链表的一部分.(并添加到开始wtf) (8认同)
  • 关于构建链表的问题似乎并不是关于书籍作者的评论,这表明两个函数的返回值存在质的不同.正如@Vlad所示,没有. (4认同)

Vla*_*cow 13

我认为这句话没有任何意义.

这些功能之间只有一个区别.在第一个函数中,船只列表相对于函数是全局的.也许它是类的数据成员,函数是可以访问类的数据成员的类的成员函数.或者实际上列表是在全局命名空间中声明的.

在第二个函数中,列表作为参数传递给函数.

这两个函数返回指向列表的第一个节点的指针.

如果要从函数中删除不重要的代码并使列表的名称相同,那么您将获得

EnemySpaceShip* getNewEnemy ()
{
    EnemySpaceShip* p_ship = new EnemySpaceShip;
    //...
    p_ship->p_next_enemy = p_enemies;
    p_enemies = p_ship;
    return p_ship;
}


EnemySpaceShip* addNewEnemyToList (EnemySpaceShip* p_enemies)
{
    EnemySpaceShip* p_ship = new EnemySpaceShip;
    //...
    p_ship->p_next_enemy = p_enemies;
    return p_ship;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,函数仅在一个语句中有所不同

p_enemies = p_ship;
Run Code Online (Sandbox Code Playgroud)

在第一个函数中存在(因为它可以访问原始列表本身)并且在第二个函数中不存在,因为该函数只有列表头部的副本(更改原始列表头部的副本)不改变原始头本身,因为参数是函数的局部变量).

您可以通过以下方式调用这两个函数

p_enemies = getNewEnemy();

p_enemies = addNewEnemyToList( p_enemies );
Run Code Online (Sandbox Code Playgroud)

因此,p_enemies将与添加节点的列表相同.

仅在第一个函数中,该函数内的列表也发生了变化; 在第二个函数中,您需要将返回指针分配给列表,因为在函数内,列表本身不会更改.

因此,我可以得出结论,这句话只会让读者感到困惑.它应该以某种方式重写,以明确作者将要说的内容.:)在初学者的书中,所有句子都清楚是非常重要的.