如何使用varargs打印出字符串?

时间:2015-10-16 22:48:55

标签: delphi delphi-xe8

如何使用varargs打印多个字符串?我试过这个,但我无法确定数组的大小。它只是打印垃圾。

program Project1;

{$APPTYPE CONSOLE}
{$POINTERMATH ON}

function _Print(const S: String): string; cdecl;
var
  Args: Array[0..100] of Pointer absolute S;
  I: Integer;
begin
  I := 0;
  while Args[I] <> nil do
  begin
    WriteLn(PString(@Args[I])^);
    Inc(I);
  end;
end;

const Print: function(const S: String): string; cdecl varargs = _Print;

var
  A, B: String;
begin
  A := 'ABC';
  B := 'CDE';
  Print(a, b, 'asdasd', 'fasd', ' ')
end.

1 个答案:

答案 0 :(得分:3)

varargs函数没有自动方式来确定传递的参数数量,因为只有调用者知道它在调用堆栈上放置了多少参数。该函数必须通过以下方式手动确定参数:

  1. 要求调用者将实际参数数作为固定参数传递:

    function _Print(NumStrings: Integer; const Strings: string): string; cdecl;
    var
      Args: Array[0..100] of Pointer absolute Strings;
      I: Integer;
    begin
      for I := 0 to NumStrings-1 do
      begin
        WriteLn(PString(@Strings[I])^);
      end;
    end;
    
    const
      Print: function(NumStrings: Integer; const Strings: string): string; cdecl varargs = _Print;
    
    var
      A, B: String;
    begin
      A := 'ABC';
      B := 'CDE';
      Print(5, a, b, 'asdasd', 'fasd', ' ');
    end.
    
  2. 将一个哨兵值放在参数列表的末尾,该函数可以查找该值。您的函数已经为此编码(它正在寻找nil指针),所以只需传递一个:

    Print(a, b, 'asdasd', 'fasd', ' ', nil);
    
  3. 话虽如此,任何一种方法都会受到调用者错误的影响,因此如果误用会有潜在危险,这就是为什么varargs - 样式函数不经常使用的原因。您应该考虑使用 open-array 参数:

    program Project1;
    
    {$APPTYPE CONSOLE}
    {$POINTERMATH ON}
    
    function _Print(const Args: array of string): string;
    var
      I: Integer;
    begin
      for I := Low(Args) to High(Args) do
      begin
        WriteLn(Args[I]);
      end;
    end;
    
    const
      Print: function(const Args: array of string): string = _Print;
    
    var
      A, B: String;
    begin
      A := 'ABC';
      B := 'CDE';
      Print([a, b, 'asdasd', 'fasd', ' ']);
    end.