为什么编译器在过程定义中给出错误?

问题描述 投票:0回答:1

我有这个用于方阵编程语言 Pascal 的程序,我正在尝试在 PascalABC IDE 中编译它。

program SquareMatrix;

const
  N = 3;

type
  Matrix = array[1..N, 1..N] of Real;

procedure ReplaceNegativeDiagonalElementsByAbsoluteValue(var matrix: Matrix);
begin
  for var i := 1 to N do
  begin
    if matrix[i, i] < 0 then
      matrix[i, i] := abs(matrix[i, i]);
  end;
end;

procedure ReadMatrixFromFile(var matrix: Matrix; fileName: string);
var
  f: TextFile;
begin
  AssignFile(f, fileName);
  Reset(f);
  for var i := 1 to N do
  begin
    for var j := 1 to N do
      Read(f, matrix[i, j]);
    ReadLn(f);
  end;
  CloseFile(f);
end;

procedure WriteMatrixToFile(matrix: Matrix; fileName: string);
var
  f: TextFile;
begin
  AssignFile(f, fileName);
  Rewrite(f);
  for var i := 1 to N do
  begin
    for var j := 1 to N do
      Write(f, matrix[i, j]:4:1, ' ');
    Writeln(f);
  end;
  CloseFile(f);
end;

var
  originalMatrix, newMatrix: Matrix;

begin
  ReadMatrixFromFile(originalMatrix, 'original_matrix.txt');
  newMatrix := originalMatrix;
  ReplaceNegativeDiagonalElementsByAbsoluteValue(newMatrix);
  WritetMatrixToFile(newMatrix, 'new_matrix.txt');
end.

但是它在过程定义行中给出了错误“预期类型”:

procedure ReplaceNegativeDiagonalElementsByAbsoluteValue(var matrix: Matrix);

如何在代码中解决这个问题? Matrix 类型是否包含错误,或者什么?

delphi matrix pascal turbo-pascal
1个回答
0
投票

问题是您只能在一个块内声明一次 any 标识符。 块是

begin … end
加号,前面是(可选)声明。

program blockDemo;
label                     (* ──┐                                   *)
    9999;                 (*   │                                   *)
const                     (*   │                                   *)
    answer = 42;          (*   │                                   *)
type                      (*   │                                   *)
    natural = 1..maxInt;  (*   ├─  This entire thing is one block. *)
var                       (*   │                                   *)
    i: integer;           (*   │                                   *)
begin                     (*   │                                   *)
9999:                     (*   │                                   *)
    ;                     (*   │                                   *)
end                       (* ──┘                                   *)
.

现在让我们插入一个例程。

program nestedBlockDemo;
var
    n: integer;
procedure doSomething;    (* still belongs to the “outside” block. *)
    var                   (* ──┐                                   *)
        n: integer;       (*   │ This is a different block.        *)
    begin                 (*   │ No harm in declaring `n` again.   *)
    end;                  (* ──┘                                   *)
begin
end.

请注意,例程头“不是例程定义块”(“嵌套”块)的“一部分”。 因此您不能再次使用已经声明的标识符。

此外,正如
AmigoJack 已经指出的那样

,在 Pascal 中只有标识符的拼写才有意义。 在指定标识符时,字母的字体、颜色、大小写等并不重要。 这意味着从开始 type Matrix = array[1..N, 1..N] of Real;

从今往后,直到各个块的
end

matrix
𝕄a𝙩ri𝑥
matrix
的任何变体都指代
一个且相同的
标识符。 因此,当您的处理器读取时 procedure ReplaceNegativeDiagonalElementsByAbsoluteValue(var matrix:

直到那时,处理器可能会认为 
matrix

是一种数据类型并相应地抱怨。

在数据类型名称前加上
T

的建议是个糟糕的建议。 Pascal 的强类型系统已经存储了标识符是否表示数据类型、变量、例程等的信息。 因此,无需以书面形式“复制”此信息。 相反,请使用描述性词语,例如。 G。该参数可以称为

sample
。 这允许您稍后从参数名称独立地更改数据类型。
:某些处理器确实允许在该位置隐藏标识符。

© www.soinside.com 2019 - 2024. All rights reserved.