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?