1

我正在尝试引入一个字符串并将其逐个字符地分配给一个链接列表,声明如下:

type lstring is private;
type lstring_node;
type lstring_access is access lstring_node;
type lstring_node is
    record
        Char : character;
        Position : integer;
        Next : lstring_access;
    end record;

private
   type lstring is 
      record
          First : lstring_access := null;
      end record;

分配它的功能如下:

function toLstring (Input : string) return lstring is
    LStr : lstring;
    Current : lstring_access;
begin
    -- Set the first item of LStr as Current.
    -- LStr will from now on inherit the items of Current.
    LStr.First := new lstring_node;
    Current := LStr.First;

    -- Iterate through the string and add it to the lstring.
    for I in 1..Input'Length loop
        if I /= 1 then
            Current := new lstring_node;
        end if;
        Current.Char := Input(I);
        Ada.Text_IO.Put(Current.Char);
        Current.Position := I;
        Current := Current.Next;
    end loop;

    -- Return the new lstring.  
    return LStr;
end toLstring;

我通过调试知道 for 循环工作得很好,并且元素被分配给 Current 就好了。但由于某种原因,这些项目没有被添加到 LStr。我需要在 for 循环之后声明一些东西来完成它吗?我的印象是,由于 Current 被分配给 LStr.First,LStr 将继承附加列表的其余部分。我错了吗?

谢谢

4

1 回答 1

3

在循环结束时,您将Current.Next(此时为空)分配给Current. 这是一个价值副本。在下一次迭代中更改的值Current不会更改Next前一个节点中的值。(注意Current.CharandCurrent.Next是实际上会执行Current.all.Char/的隐式取消引用Next,但Current := new lstring_node不是取消引用,因为它会更改引用的值。)

相反,您应该分配new lstring_nodeNext然后推进您的Current参考:

for I in Input'Range loop
    Current.Char := Input(I);
    Ada.Text_IO.Put(Current.Char);
    Current.Position := I - Input'First + 1;
    if I /= Input'Last then
        Current.Next := new lstring_node;
        Current := Current.Next;
    end if;
end loop;

请注意,我更改了循环范围(字符串不需要从 1 开始)并调整了位置计算,因此您最终会在列表中得到一个基于 1 的位置索引。

于 2013-03-15T07:11:12.760 回答