문제

원래 글로벌 변수로 정의 된 배열 [1..1000]이있었습니다. 그러나 지금 나는 그것을 1000이 아닌 n이어야하며 나중에 N을 찾지 못합니다. 배열을 채우기 전에 N이 무엇인지 알고 있지만 글로벌이어야하므로 런타임에 글로벌 배열의 크기를 정의하는 방법이 필요합니다.

컨텍스트는 파일에서 바이트의 선형 변환으로 배열을 채우는 것입니다. 누군가가 파일을 열기를 원하고 파일의 크기가 될 때까지 파일이 얼마나 큰지 모르겠습니다.

도움이 되었습니까?

해결책

Delphi 4에서 Delphi는 지원합니다 동적 배열. 실행 시간에 크기를 수정할 수 있으며 이전 크기의 다른 요소로 저장된 데이터를 유지합니다. 레코드 및 기타 어레이를 포함하여 균질 한 유형의 요소를 보유 할 수 있습니다. "정적"배열을 선언하는 것과 동일한 동적 배열을 선언 할 수 있지만 배열 경계를 생략 할 수 있습니다.

var
  ArthurArray: array of TForm;

정적 배열을 사용하면 하단 및 상한을 모두 지정할 수 있지만 동적 배열의 낮은 인덱스는 항상 0입니다. 높은 지수는 다음에 의해 제공됩니다 High 배열의 길이보다 항상 하나를 반환하는 함수. 동적 배열의 경우 x, High(x) = Length(x)-1.

로컬 절차를 포함한 모든 코드로 글로벌 변수에 액세스 할 수 있습니다.

동적 배열 유형의 전역 변수는 비어 있는 정렬. 길이는 0이고 High 해당 배열에서 호출되는 것은 -1입니다. Low 이 배열에서 여전히 0이 반환됩니다.

언제든지 동적 배열 크기를 조정할 수 있습니다. 사용 SetLength 문자열로 할 수있는 것처럼 기능 :

var
  NumElements: Integer;
begin
  NumElements := GetNumberOfArthurForms();
  SetLength(ArthurArray, NumElements);
end;

다차원 배열이있는 경우 루프에서 길이를 설정할 수 있습니다.

var
  matrix: array of array of Double;
  i: Integer;
begin
  SetLength(matrix, height);
  for i := 0 to height - 1 do
    SetLength(matrix[i], width);
end;

모든 내부 배열의 길이를 한 번에 설정하기위한 바로 가기가 있습니다.

begin
  SetLength(matrix, height, width);
end;

내가 언급했듯이, 동적 배열은 당신이 그것들을 조정할 때 그들의 이전 값을 유지합니다.

var
  data: array of string;
begin
  SetLength(data, 2);
  data[1] := 'foo';
  SetLength(data, 20);
  Assert(data[1] = 'foo');
end;

하지만 당신이라면 줄이다 배열, 새로운 마지막 요소를 넘어서있는 모든 요소는 영원히 사라졌습니다.

begin
  SetLength(data, 20);
  data[15] := 'foo';
  SetLength(data, 2);
  // data[15] does not exist anymore.
  SetLength(data, 16);
  writeln(data[15); // Should print an *empty* line.
end;

위의 시연은 현악기를 사용했습니다. 줄은 델파이에서 특별합니다. 그들은 참조 수를 통해 컴파일러에 의해 관리됩니다. 이로 인해 유형 문자열의 새로운 동적 배열 요소가 비어 있도록 초기화됩니다. 그러나 대신 정수를 사용했다면 새로운 요소의 값을 보장 할 수 없습니다. 그것들은 0 일지 모르지만 독립형 로컬 변수의 초기 값과 마찬가지로 다른 것일 수도 있습니다.

Delphi 7 도움말 파일은 매우 좋습니다. 동적 배열에 대해 자세히 알아보십시오. 델파이 설치와 지난 10 년 동안 생성 된 거의 모든 델파이 코드 예제에서 제공되는 VCL 및 RTL 소스 코드 전체에서 사용에 대한 시연을 찾을 수 있습니다.

다른 팁

먼저 질문의 첫 번째 부분에 대한 일반적인 답변이 있습니다.

배열이 더 이상 정적이 아닌 경우 TLIST, TSTRINGLIST 또는 CONTNRS 장치의 많은 컨테이너 클래스 중 하나를 사용하는 것을 고려할 수 있습니다.

그들은 당신이하는 일을 더 잘 나타내고, 필요할 수있는 추가 기능을 제공 할 수 있으며, 예를 들어 정렬 또는 이름/값 쌍이 필요하며, 필요한대로 동적으로 성장하며 매우 최적화되었습니다.


그런 다음 당신은 말했습니다.

"컨텍스트는 파일에서 바이트의 선형 변환으로 배열을 채우고 있습니다. 누군가가 파일을 열고 싶고 파일의 크기가 될 때까지 파일이 얼마나 큰지 모르겠습니다."

특정 문제의 경우 다음을 사용하여 파일에 바이트를로드합니다.

  MyFileStream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
  Size := MyFileStream.Size - MyFileStream.Position;
  SetLength(Buffer, Size);
  MyFileStream.Read(Buffer[0], Size);

그런 다음 PCHA 포인터를 사용하여 각 문자 또는 각 바이트를 버퍼의 각 바이트를 하나씩 통과하고 필요한 방식으로 변환 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top