461

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

ProgramBandera написав:

так як NumberString масив
      // починається з нуля то від довжини віднімаєм одиницю

А в чому логіка? Маєте 5 яблук з номерами від 0 до 4, скільки у вас яблук?

Подякували: Torbins, ProgramBandera2

462

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

Якщо вам треба лише одну букву, то краще зробити

NumberString: Array Of Char;
Подякували: ProgramBandera1

463

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

ProgramBandera написав:

так як NumberString масив
      // починається з нуля то від довжини віднімаєм одиницю

Стривайте, якщо пам'ять не підводить, то в Pascal та Delphi перший символ в типі String має індекс 1, а під індексом 0 зберігається значення довжини строки. Тож якщо NumberString то тип String то не треба віднімати один, це не С-подібна мова, де перший символ під індексом 0, а кінець строки позначають 0x00. (так, тип String займає на один байт більше в пам'яті ніж вказуєш довжину при оголошенні).

464

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

HetmanNet написав:

якщо NumberString то тип String

А якщо це не String, а те, що в коді написано?

465

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

koala написав:
HetmanNet написав:

якщо NumberString то тип String

А якщо це не String, а те, що в коді написано?

Як знайду код то скажу..

466

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

Підказка: він на попередній сторінці

467 Востаннє редагувалося ProgramBandera (07.01.2023 01:28:19)

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

З Різдвом (за старим стилем) панове програмісти!
Допоможіть будь-ласка розв'язати проблему з перетворенням динамічного масиву в число!
Почну по порядку описувати проблему.

Є глобальна змінна в яку заносяться символи які вводить користувач наприклад через Edit

Прихований текст

(поки що припустимо що користувач вводить тільки цифри)

.

var
  NumberString: Array Of Char;

Я написав процедуру яка заповняє цей масив

Procedure InputArrayOfDigit(StrNumber: String);
Var
  I,                                                     // Лічильник для масиву
  NumberOfDigits: Integer;                             // Кількість цифр в числі
Begin
  If StrNumber = '' Then                  // Якщо параметр StrNumber порожній то
    Abort                                                  // виходимо з функції
  Else                                                                 // Інакше
    Begin
      // Визначаємо кількість цифр в параметрі
      NumberOfDigits := Length(StrNumber);
      // Задаємо відповідну довжину динамічного масиву
      SetLength(NumberString, NumberOfDigits);
      // Заповняємо цифрами дин. масив
      For I := 0 To NumberOfDigits Do
        NumberString[i]:= StrNumber[I + 1];
    End;
End;
Прихований текст

Для її перевірки написав зворотню функцію:

Function OutputArrayOfDigit(NumStr: Array Of Char): String;
Var
  I: Integer;
Begin
  For I := Low(NumStr) To High(NumStr) Do
    Result := Result + NumStr[i]
End;

Перевірив, чудово все працює (поки що), тобто масив заповняється правильно!

Далі мені потрібно цей динамічний масив перетворити в число, для цього є чудова формула:
Розряд 0 * (10 в степені розряду) + Розряд 1 * (10 в степені розряду)...
Наприклад 123 по формулі виходить (3*10^0 = 3 додати 2*10^1 = 20 додати 1*10:3 = 100. І того виходить 1 + 20 + 100 = 123

І от в наступній функції якась проблема:

Function StrToNumber (NumStr: Array of Char): Extended;
Var
  I,                                                          // Лічильник циклу
  j: Integer;                                                   // Номер розряду
Begin
  j := 0;                                        // Для j задаємо нульовий степінь
                                 // Так як масив в нас заповнений з ліва на право,
                                            //а число формується з права на ліво
                          // Для І від найбільшого елементу масиву до найменшого
  For I := High(NumStr) To Low(NumStr) Do
    Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
      Result := StrToInt(NumStr[i]) * IntPower(10, j);
      j := j + 1;                                  // Додаємо до степеня одиницю
    End;
End;

Перевірку робив кліком по кнопці:

Procedure TForm2.Button1Click(Sender: TObject);
Begin
  InputArrayOfDigit(Edit1.Text);

  Memo1.Lines.Add(FloatToStr(StrToNumber(NumberString)));
  Edit1.Clear
End;

Після компіляції як вводжу в Edit (наприклад 123) вискакує помилка
https://replace.org.ua/uploads/images/6671/77f074aee5829e8a100c7ecf19b1cd54.bmp
Підкажіть в чому проблема?

468

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

Тут проблем багато. Почнемо з простого питання: чим саме вас не влаштовує string як тип NumberString?
Уважно перевірте параметри циклів. Мабуть, там

For I := 0 To NumberOfDigits-1 Do

І

For I := High(NumStr) DownTo Low(NumStr) Do
Подякували: leofun01, ProgramBandera2

469 Востаннє редагувалося ProgramBandera (07.01.2023 09:55:51)

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

koala написав:

Тут проблем багато. Почнемо з простого питання: чим саме вас не влаштовує string як тип NumberString?

Вітаю пане koala. Я на початку пробував із типом string там  теж була якась помилка коли виводив масив в memo за допомогою функції OutputArrayOfDigits. Тому за порадою пана Torbins змінив на тип Char. І все запрацювало!

koala написав:

Уважно перевірте параметри циклів. Мабуть, там

For I := 0 To NumberOfDigits-1 Do

Тут я робив раніше ту ж помилку і ви мене виправили В верху цієї сторінки. Тут (напевно) все гаразд так як масив заповнюється. перевірено зворотньою функцією.

koala написав:

І

For I := High(NumStr) DownTo Low(NumStr) Do

Спробував DownTo та ж сама проблема лишилася.

Function StrToNumber (NumStr: Array of Char): Extended;
Var
  I,                                                          // Лічильник циклу
  j: Integer;                                                   // Номер розряду
Begin
  j := 0;                                        // Для j задаємо нульой степінь
                                 // Так як сив в нас заповнений з ліва на право,
                                            //а число формується з права на ліво
                          // Для І від найбільшого єлементу масиву до найменшого
  For I := High(NumStr) DownTo Low(NumStr) Do
  Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
    Result := StrToInt(NumStr[i]) * IntPower(10, j);
    j := j + 1;                                    // Додаємо до степеня одиницю
  End;
End;

Я думаю помилка десь в тілі циклу ось тут:

For I := High(NumStr) To Low(NumStr) Do
    Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
      Result := StrToInt(NumStr[i]) * IntPower(10, j);
      j := j + 1;                                  // Додаємо до степеня одиницю
    End;

Та не можу зрозуміти де саме. Думка така що не правильно переводжу тип Char в тип String.

      Result := StrToInt(NumStr[i]) * IntPower(10, j);
      j := j + 1;                                  // Додаємо до степеня одиницю

470

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

Result:=result+...
Подякували: ProgramBandera1

471

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

koala написав:
Result:=result+...

Ну ось коли вводжу проміжну змінну Num: Extended; то працює:

Var
  I,                                                          // Лічильник циклу
  j: Integer;                                                   // Номер розряду
  Num: Extended;
Begin
  j := 0;                                        // Для j задаємо нульой степінь
  Num := 0;
                                 // Так як сив в нас заповнений з ліва на право,
                                            //а число формується з права на ліво
                          // Для І від найбільшого єлементу масиву до найменшого
  For I := High(NumStr) DownTo Low(NumStr) Do
  Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
    Num := Num + StrToInt(NumStr[i]) * IntPower(10, j);
    j := j + 1;                                    // Додаємо до степеня одиницю
  End;
  Result := Num
End;

А без неї ніяк. Result:=result+... не працює взагалі чомусь. Щоб не вводити зайву змінну можливо якось рекурсію зробити.
Вибачайте що в свято відбираю у вас час, та можливо порадите щось.

472

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

Бо початкове значення не задаєте

Подякували: ProgramBandera, leofun012

473

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

koala написав:

Бо початкове значення не задаєте

Function StrToNumber (NumStr: Array of Char): Extended;
Var
  I,                                                          // Лічильник циклу
  j: Integer;                                                   // Номер розряду
Begin
  j := 0;                                        // Для j задаємо нульой степінь
  Result := 0;
                                 // Так як сив в нас заповнений з ліва на право,
                                            //а число формується з права на ліво
                          // Для І від найбільшого єлементу масиву до найменшого
  For I := High(NumStr) DownTo Low(NumStr) Do
  Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
    Result := Result + StrToInt(NumStr[i]) * IntPower(10, j);
    j := j + 1;                                    // Додаємо до степеня одиницю
  End

End;

Дякую пане koala. Дай боже вам здоров'я і грошей багато. Гарних свят!!!

Подякували: Chemist-i1

474

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

ProgramBandera написав:

Я на початку пробував із типом string там  теж була якась помилка коли виводив масив в memo за допомогою функції OutputArrayOfDigits. Тому за порадою пана Torbins змінив на тип Char.

Я це порадив, коли побачив у вас масив рядків, в кожний елемент якого ви записували по одному символу. Цей масив дійсно легко можна замінити на один єдиний рядок.

Подякували: koala, ProgramBandera, leofun013

475 Востаннє редагувалося Droid 77 (08.01.2023 22:57:39)

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

ProgramBandera написав:
Memo1.Lines.Add(FloatToStr(StrToNumber(NumberString)));

Вас це не засмутчює?
Скрізь цілі, а тут раптом на старті флоати в рядок ...

476

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

ви плутаєте довжину з номером останнього елемента, причому всюди, де можливо

      NumberOfDigits := Length(Edit2.Text);
      SetLength(NumberString, NumberOfDigits-1);//довжина NumberString на 1 менша, ніж довжина Edit2.Text
      For I := 0 To NumberOfDigits Do //цикл повторюється NumberOfDigits+1 разів - на 2 більше, ніж символів у NumberString
      Begin
        NumberString[i]:= Edit2.Text[I+1];//останній символ стрічки копіюється за межі NumberString;
        // остання ітерація бере символ за межами стрічки і пхає його за межі масиву
      End;

Вам уже сказали: замініть NumberString з масива на стрічку; порада про масив була через те, що ви використовували масив стрічок, тобто порадою було замінити String на Char, а масив - це ваша ідея.

Подякували: ProgramBandera, leofun012

477 Востаннє редагувалося ProgramBandera (09.01.2023 23:16:44)

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

Гаразд? давайте виведемо перевірку в Memo.
Глобальна змінна:

var
  Form2: TForm2;
  NumberString: Array Of Char;

Ось процедура заповнення масиву (модифікована під Мемо):

Procedure TForm2.InputArrayOfDigit(StrNumber: String);
Var
  I,
  dovmas,                                                     // Лічильник для масиву
  NumberOfDigits: Integer;                             // Кількість цифр в числі
Begin
  If StrNumber = '' Then                  // Якщо параметр StrNumber порожній то
    Abort                                                  // виходимо з функції
  Else                                                                 // Інакше
    Begin
      NumberOfDigits := 0;
      dovmas := 0;
      // Визначаємо кількість цифр в параметрі
      NumberOfDigits := Length(StrNumber);
      // Задаємо відповідну довжину динамічного масиву
      SetLength(NumberString, NumberOfDigits);
      dovmas := Length(NumberString);
      // Заповняємо цифрами дин. масив
      For I := 0 To NumberOfDigits Do
        NumberString[i]:= StrNumber[I + 1];
    End;
    Memo1.Lines.Add(IntToStr(NumberOfDigits) + '       // це кількість символів в Edit');
    Memo1.Lines.Add(IntToStr(dovmas) + '       // це довжина масиву');
End;

А ось функція виводу масиву(для перевірки):

Function OutputArrayOfDigit(NumStr: Array Of Char): String;
Var
  I: Integer;
Begin
  For I := Low(NumStr) To High(NumStr) Do
    Result := Result + NumStr[i]
End;

Клік по кнопці:

procedure TForm2.Button1Click(Sender: TObject);
begin
 InputArrayOfDigit(Edit1.Text);
 Memo1.Lines.Add (OutputArrayOfDigit(NumberString) + '       // це те що я ввів в Edit')

end;

1)Вводжу в Edit 123456
2)Клікаю
3)В Memo виводить:
6             // це кількість символів в Edit
6             // це довжина масиву
123456     // це те що я ввів в Edit


koala написав:

ви плутаєте довжину з номером останнього елемента, причому всюди, де можливо

      NumberOfDigits := Length(Edit1.Text);
      SetLength(NumberString, NumberOfDigits-1);//довжина NumberString на 1 менша, ніж довжина Edit1.Text

Чому тут має бути NumberOfDigits-1??? Якщо функція Length рахує символи в масиві без нульового. В мемо ми це побачили, вивели туди значення NumberOfDigits, воно дорівнює 6. Якщо я ставлю NumberOfDigits-1  в Edit набираю 123456 то виводить:
6       // це кількість символів в Edit
5       // це довжина масиву
12345       // це те що я ввів в Edit
Без одного символу. Куди він дівся?


koala написав:
       For I := 0 To NumberOfDigits Do //цикл повторюється NumberOfDigits+1 разів - на 2 більше, ніж символів у NumberString
      Begin
        NumberString[i]:= Edit2.Text[I+1];//останній символ стрічки копіюється за межі NumberString;
        // остання ітерація бере символ за межами стрічки і пхає його за межі масиву
      End;

Якщо воно його пхає за межі масиву, то чому коли я виводжу функцією OutputArrayOfDigit масив в Мемо мені виводяться усі 6 символів 123456??? Тут поясніть докладніше будь ласка!!!

koala написав:

Вам уже сказали: замініть NumberString з масиву на стрічку; порада про масив була через те, що ви використовували масив стрічок, тобто порадою було замінити String на Char, а масив - це ваша ідея.

Це була хороша порада!

P.S. Масив мені потрібен! Мене вже дістала ця коротка математика в Delphi. Чому діти в п'ятому класі можуть письмово в стовпчик додавати, віднімати, множити і ділити числа будь якої довжини, а тут, коли я обчислюю сталу Планка, вискакує ось така штука 6.62607015E-34. Як мені буде потрібно я напишу функцію для переводу в стандартне число, і заміню Е на 10.
От я вирішив написати (Модуль) функції які будуть працювати як додавання, віднімання і т.д. в стовпчик. Тут мені буде потрібен динамічний масив (я надіюсь він буде безмежної довжини) типу Char та динамічний масив типу Integer для обчислення цілих. І ніяких типів Extended з їхніми 6.62607015E-34.

478 Востаннє редагувалося ProgramBandera (09.01.2023 23:13:50)

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

Ось повний (пробний) модуль і він працює:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus,
  Vcl.StdCtrls, Vcl.ExtCtrls, System.Math, All_Numbers;

type
  TForm2 = class(TForm)
    Image1: TImage;
    Panel1: TPanel;
    Button1: TButton;
    Edit1: TEdit;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Memo1: TMemo;
    Sound: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Procedure InputArrayOfDigit(StrNumber: String);
  end;

var
  Form2: TForm2;
  NumberString: Array Of Char;

implementation

{$R *.dfm}

{Фунція знаходження натурального числа з масиву чисел, яка також не потрібна, бо працює не коректно. Всерівно зявляється Е}
Function StrToNumber (NumStr: Array of Char): Extended;
Var
  I,                                                          // Лічильник циклу
  j: Integer;                                                   // Номер розряду
Begin
  j := 0;                                        // Для j задаємо нульой степінь
  Result := 0;
                                 // Так як сив в нас заповнений з ліва на право,
                                            //а число формується з права на ліво
                          // Для І від найбільшого єлементу масиву до найменшого
  For I := High(NumStr) DownTo Low(NumStr) Do
  Begin
              // Переводимо цифру з тексту в інтежер і множимо на 10 в степені 0
    Result := Result + StrToInt(NumStr[i]) * IntPower(10, j);
    j := j + 1;                                    // Додаємо до степеня одиницю
  End

End;

Procedure TForm2.InputArrayOfDigit(StrNumber: String);
Var
  I,
  dovmas,                                                     // Лічильник для масиву
  NumberOfDigits: Integer;                             // Кількість цифр в числі
Begin
  If StrNumber = '' Then                  // Якщо параметр StrNumber порожній то
    Abort                                                  // виходимо з функції
  Else                                                                 // Інакше
    Begin
      NumberOfDigits := 0;
      dovmas := 0;
      // Визначаємо кількість цифр в параметрі
      NumberOfDigits := Length(StrNumber);
      // Задаємо відповідну довжину динамічного масиву
      SetLength(NumberString, NumberOfDigits);
      dovmas := Length(NumberString);
      // Заповняємо цифрами дин. масив
      For I := 0 To NumberOfDigits Do
        NumberString[i]:= StrNumber[I + 1];
    End;
    Memo1.Lines.Add(IntToStr(NumberOfDigits) + '       // це кількість символів в Edit');
    Memo1.Lines.Add(IntToStr(dovmas) + '       // це довжина масиву');
End;

Function OutputArrayOfDigit(NumStr: Array Of Char): String;
Var
  I: Integer;
Begin
  For I := Low(NumStr) To High(NumStr) Do
    Result := Result + NumStr[i]
End;

procedure TForm2.Button1Click(Sender: TObject);
Var
  Num: TNumbers;
begin
 InputArrayOfDigit(Edit1.Text);
 Memo1.Lines.Add (OutputArrayOfDigit(NumberString) + '       // це те що я ввів в Edit')

end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Image1.Canvas.Brush.Color := clWhite;
end;

end.
Подякували: koala1

479

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

А 1/3 як обчислюватимете?

480 Востаннє редагувалося ProgramBandera (10.01.2023 09:00:43)

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

koala написав:

А 1/3 як обчислюватимете?

Як і письмово, в стовпчик, періодом. Там треба буде ввести обмеження на період. Над обмеженням я ще поміркую.
В мене буде в модулі об'єкт з полями
1) Для знаку числа
2) Для цілої частини числа
3) Для позиції коми в числі
4) Для десяткової частини числа

То що з масивами? Вірно все з довжиною?