501

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Вітаю панове! Питання: чому не заповняються поля типу TNumber?

В мене є тип:

Type                                                   // Оголошуємо тип - Число
  TNumber = Record
    MathematicalSign: Char;               // Математичний знак числа
    IntegerPartNumber: String;            // Ціла частина числа
    LengthIntegerPartNumber: Cardinal;    // Довжина цілої частини числа
    ComaPosition: Cardinal;               // Позиція коми в числі
    DecimalPartNumber: String;            // Десяткова частина числа
    LengthDecimalPartNumber: Cardinal;    // Довжина десяткової частини числа
    NumberType: String;                   // Тип числа
  End;

Я створив процедуру ComponentsOfNumber:

Procedure ComponentsOfNumber(PNumber: String; POperand: TNumber);
{
Процедура ComponentsOfNumber розбиває число на його компоненти: знак, цілу та
десяткову частини. Знаходить довжину цілої та десяткової частини, а також
визначає яке це число: натуральне, ціле чи дійсне
}
Begin

  If PNumber[1] = '-' Then  // Якщо першим символом операнда являється знак - то
    Begin
      PNumber := AbsoluteValue(PNumber);                 // Видаляємо знак мінус
      POperand.MathematicalSign := '-'       // Ініціалізуємо знак числа в мінус
    End
  Else                                                                 // Інакше
    POperand.MathematicalSign := '+';         // Ініціалізуємо знак числа в плюс

  If Pos(',', PNumber) <> 0 Then                // Якщо в числі присутня кома то
    Begin
      POperand.ComaPosition := Pos(',', PNumber);        // Задаємо позицію коми
                                          // Задаємо довжину цілої частини числа
      POperand.LengthIntegerPartNumber := POperand.ComaPosition - 1;
                                                   // Задаємо цілу частину числа
      POperand.IntegerPartNumber := Copy(PNumber, 1,
                                              POperand.LengthIntegerPartNumber);
                                     // Задаємо довжину десяткової частини числа
      POperand.LengthDecimalPartNumber := Length(PNumber) -
                                                          POperand.ComaPosition;
                                              // Задаємо десяткову частину числа
      POperand.DecimalPartNumber := Copy(PNumber, POperand.ComaPosition + 1,
                                             POperand.LengthDecimalPartNumber)
    End
  Else   // Якщо в числі коми немає
    Begin
      POperand.LengthIntegerPartNumber := Length(PNumber);
      POperand.IntegerPartNumber := PNumber;
      POperand.ComaPosition := 0
    End;

  If Not(POperand.ComaPosition = 0) Then        // Якщо в числі присутня кома то

    If (POperand.MathematicalSign = '-') Then //Якщо в числі присутній знак - то
      POperand.NumberType := 'Дійсне відємне число'   // Число дійсне відємне
    Else                                                               // Інакше
      POperand.NumberType := 'Дійсне додатне число'      // Число дійсне додатне

  Else                                             // Інакше, якщо кома відсутня

    If (POperand.MathematicalSign = '-') Then //Якщо в числі присутній знак - то
      POperand.NumberType := 'Ціле число'     // Число ціле
    Else                                         // Інакше, якщо мінус відсутній
      POperand.NumberType := 'Натуральне число'              // Число натуральне
End;

Я цю процедуру хочу використати в функції Add:

Function Add(PFirstOperand, PSecondOperand: String): String;
                                    // Функція додавання двох раціональних чисел
Var
  I,                                                      // Лічильник для циклу
  LLengthFirstOperand,                         // Кількість цифр першого доданку
  LLengthSecondOperand,                        // Кількість цифр другого доданку
  LLength,                                           // Кількість ітерацій циклу
  LDigitInMemory,                                             // Цифра в пам'яті
  LSum,                       // Сума чисел які додаються у відповідному розряді
  LDigit1, LDigit2: integer;                       // Цифри відповідного розряду

  LNumberOne: TNumber;                                          // Перший операнд
  LNumberTwo: TNumber;                                         // Другий операнд

Begin

          {Розбираємо перший  та другий операнди як число на складові}
  ComponentsOfNumber(PFirstOperand,LNumberOne);
  ComponentsOfNumber(PSecondOperand, LNumberTwo);



// Перевіримо чи заповнені поля!

Result := 'Оп1 Знак: ' + LNumberOne.MathematicalSign +
#13#10 +
'Оп1 Ціла частина: ' + LNumberOne.IntegerPartNumber +
#13#10 +
'Оп1 Довжина цілої частини: ' + IntToStr(LNumberOne.LengthIntegerPartNumber) +
#13#10 +
'Оп1 Позиція коми: ' + IntToStr(LNumberOne.ComaPosition) +
#13#10 +
'Оп1 Десяткова частина: ' + LNumberOne.DecimalPartNumber +
#13#10 +
'Оп1 Довжина десяткової частини: ' + IntToStr(LNumberOne.LengthDecimalPartNumber) +
#13#10 +
'Оп1 Визначення числа: ' + LNumberOne.NumberType +
#13#10 +
'Ціла частина другого операнда: ' + LNumberTwo.IntegerPartNumber;

//  Leveling(LNumberOne, LNumberTwo);
{************************Обробка логіки додавання чисел************************}


{******************************************************************************}



//                                           // знаходимо довжину кожного з рядків
//  LLengthFirstOperand := Length(PFirstOperand);
//  LLengthSecondOperand := Length(PSecondOperand);
//                              // Визначаємо максимальну кількість ітерацій циклу
//  LLength := Maximum(LLengthFirstOperand,LLengthSecondOperand);
//                                                         // Ініціалізуємо змінні
//  LDigitInMemory := 0;
//  Result := '';
//    // Проходимо від кінця до початку кожного рядка та додаємо значення розрядів
//  For I := 1 To LLength Do
//  Begin
//                         // Отримуємо цифру відповідного розряду першого доданку
//    If (I <= LLengthFirstOperand) Then
//      LDigit1 := StrToInt(PFirstOperand[LLengthFirstOperand - I + 1])
//    Else                             // Якщо розряду не існує то присвоюємо нуль
//      LDigit1 := 0;
//                         // Отримуємо цифру відповідного розряду другого доданку
//    If (I <= LLengthSecondOperand) Then
//      LDigit2 := StrToInt(PSecondOperand[LLengthSecondOperand - I + 1])
//    Else                             // Якщо розряду не існує то присвоюємо нуль
//      LDigit2 := 0;
//              //Додаємо відповідні розряди і якщо є, то десятки які були в пам'яті
//    LSum := LDigit1 + LDigit2 + LDigitInMemory;
//       // Якщо результат дорівнює або перевищує 10 то десятки заносимо в пам'ять
//    LDigitInMemory := LSum Div 10;
//                                // У відповідь заносимо остачу від ділення на 10
//    Result := IntToStr(LSum Mod 10) + Result
//  End;
//  // Якщо в пам'яті шились десятки то додаємо їх до відповіді
//  If LDigitInMemory > 0 Then
//    Result := IntToStr(LDigitInMemory) + Result;

End;

І от коли я її перевіряю  виводячи в Мемо1:

procedure TMainForm.Button1Click(Sender: TObject);
var
 Sample: String;
begin
  Sample := 'Проба!';
  Memo1.Lines.Add(Sample);
  Memo1.Lines.Add(Add(Edit2.Text, Edit3.Text));
end;

Мені виводиться якесь сміття яке лежить в пам'яті. Коли я не використовую процедуру ComponentsOfNumber а описую її код прямо в функції Add то все гаразд:

Function Add(PFirstOperand, PSecondOperand: String): String;
                                    // Функція додавання двох раціональних чисел
Var
  I,                                                      // Лічильник для циклу
  LLengthFirstOperand,                         // Кількість цифр першого доданку
  LLengthSecondOperand,                        // Кількість цифр другого доданку
  LLength,                                           // Кількість ітерацій циклу
  LDigitInMemory,                                             // Цифра в пам'яті
  LSum,                       // Сума чисел які додаються у відповідному розряді
  LDigit1, LDigit2: integer;                       // Цифри відповідного розряду

  LNumberOne: TNumber;                                         // Перший операнд
  LNumberTwo: TNumber;                                         // Другий операнд

Begin

          {Розбираємо перший  та другий операнди як число на складові}  

If PFirstOperand[1] = '-' Then  // Якщо першим символом операнда являється знак - то
    Begin
      PFirstOperand := AbsoluteValue(PFirstOperand);                 // Видаляємо знак мінус
      LNumberOne.MathematicalSign := '-'       // Ініціалізуємо знак числа в мінус
    End
  Else                                                                 // Інакше
    LNumberOne.MathematicalSign := '+';         // Ініціалізуємо знак числа в плюс

  If Pos(',', PFirstOperand) <> 0 Then                // Якщо в числі присутня кома то
    Begin
      LNumberOne.ComaPosition := Pos(',', PFirstOperand);        // Задаємо позицію коми
                                          // Задаємо довжину цілої частини числа
      LNumberOne.LengthIntegerPartNumber := LNumberOne.ComaPosition - 1;
                                                   // Задаємо цілу частину числа
      LNumberOne.IntegerPartNumber := Copy(PFirstOperand, 1,
                                              LNumberOne.LengthIntegerPartNumber);
                                     // Задаємо довжину десяткової частини числа
      LNumberOne.LengthDecimalPartNumber := Length(PFirstOperand) -
                                                          LNumberOne.ComaPosition;
                                              // Задаємо десяткову частину числа
      LNumberOne.DecimalPartNumber := Copy(PFirstOperand, LNumberOne.ComaPosition + 1,
                                             LNumberOne.LengthDecimalPartNumber)
    End
  Else   // Якщо в числі коми немає
    Begin
      LNumberOne.LengthIntegerPartNumber := Length(PFirstOperand);
      LNumberOne.IntegerPartNumber := PFirstOperand;
      LNumberOne.ComaPosition := 0
    End;

  If Not(LNumberOne.ComaPosition = 0) Then        // Якщо в числі присутня кома то

    If (LNumberOne.MathematicalSign = '-') Then //Якщо в числі присутній знак - то
      LNumberOne.NumberType := 'Дійсне відємне число'   // Число дійсне відємне
    Else                                                               // Інакше
      LNumberOne.NumberType := 'Дійсне додатне число'      // Число дійсне додатне

  Else                                             // Інакше, якщо кома відсутня

    If (LNumberOne.MathematicalSign = '-') Then //Якщо в числі присутній знак - то
      LNumberOne.NumberType := 'Ціле число'     // Число ціле
    Else                                         // Інакше, якщо мінус відсутній
      LNumberOne.NumberType := 'Натуральне число';              // Число натуральне

  ComponentsOfNumber(PSecondOperand, LNumberTwo);

// Перевіримо чи заповнені поля!

Result := 'Оп1 Знак: ' + LNumberOne.MathematicalSign +
#13#10 +
'Оп1 Ціла частина: ' + LNumberOne.IntegerPartNumber +
#13#10 +
'Оп1 Довжина цілої частини: ' + IntToStr(LNumberOne.LengthIntegerPartNumber) +
#13#10 +
'Оп1 Позиція коми: ' + IntToStr(LNumberOne.ComaPosition) +
#13#10 +
'Оп1 Десяткова частина: ' + LNumberOne.DecimalPartNumber +
#13#10 +
'Оп1 Довжина десяткової частини: ' + IntToStr(LNumberOne.LengthDecimalPartNumber) +
#13#10 +
'Оп1 Визначення числа: ' + LNumberOne.NumberType +
#13#10 +
'Ціла частина другого операнда: ' + LNumberTwo.IntegerPartNumber;
//  Leveling(LNumberOne, LNumberTwo);
{************************Обробка логіки додавання чисел************************}


{******************************************************************************}



//                                           // знаходимо довжину кожного з рядків
//  LLengthFirstOperand := Length(PFirstOperand);
//  LLengthSecondOperand := Length(PSecondOperand);
//                              // Визначаємо максимальну кількість ітерацій циклу
//  LLength := Maximum(LLengthFirstOperand,LLengthSecondOperand);
//                                                         // Ініціалізуємо змінні
//  LDigitInMemory := 0;
//  Result := '';
//    // Проходимо від кінця до початку кожного рядка та додаємо значення розрядів
//  For I := 1 To LLength Do
//  Begin
//                         // Отримуємо цифру відповідного розряду першого доданку
//    If (I <= LLengthFirstOperand) Then
//      LDigit1 := StrToInt(PFirstOperand[LLengthFirstOperand - I + 1])
//    Else                             // Якщо розряду не існує то присвоюємо нуль
//      LDigit1 := 0;
//                         // Отримуємо цифру відповідного розряду другого доданку
//    If (I <= LLengthSecondOperand) Then
//      LDigit2 := StrToInt(PSecondOperand[LLengthSecondOperand - I + 1])
//    Else                             // Якщо розряду не існує то присвоюємо нуль
//      LDigit2 := 0;
//              //Додаємо відповідні розряди і якщо є, то десятки які були в пам'яті
//    LSum := LDigit1 + LDigit2 + LDigitInMemory;
//       // Якщо результат дорівнює або перевищує 10 то десятки заносимо в пам'ять
//    LDigitInMemory := LSum Div 10;
//                                // У відповідь заносимо остачу від ділення на 10
//    Result := IntToStr(LSum Mod 10) + Result
//  End;
//  // Якщо в пам'яті шились десятки то додаємо їх до відповіді
//  If LDigitInMemory > 0 Then
//    Result := IntToStr(LDigitInMemory) + Result;

End;

Підкажіть як вирішити таке питання, бо процедура ComponentsOfNumber потрібна не тільки для функції Add?

502 Востаннє редагувалося ProgramBandera (17.03.2023 23:49:54)

Re: Програма розв'язування задач з фізики! Для учнів 7-го класу.

Попереднє питання знято. Щоб процедура ComponentsOfNumber правильно заповнювала поля об'єкту TNumber в наступній функції, необхідно змінити тип параметра POperand: TNumber на var.

Procedure ComponentsOfNumber(PNumber: String; Var POperand: TNumber);
Подякували: koala, Torbins2