Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование с нуля - это совсем просто! 45) Продолжаем.


Информационный Канал Subscribe.Ru

 
Школа программирования

Программирование с нуля - это совсем просто!

45) Продолжаем.

Ответы.

* почему не работает While(0.98*intForest != intSosna); в Си?

Во-первых, в Си есть различия между болшими и маленькими буквами, поэтому While и while - не одно и то же. Операторы маленькими всегда пишутся, while.

Потом, нельзя сравнивать дробные на равенство. С большой вероятностью неправильно сравнятся даже близкие числа. Надо брать   <= или >= , в зависимости от условия, иначе будет зацикленность бесконечная.

* Я когда книгу покупала, к ней дискета с программами прилагалась(архив), я её открываю, код посмотреть могу, а форма только описание и предупреждение там появляется "Не удаётся найти указанный файл".

Форму сохраняем в один каталог с файлом кода, у нее расширение .dfm делаем, а у кода - .pas, и потом открываем в Дельфи pas-файл, и форма автоматом цепляется. Для переключения между кодом и формой жмете кнопку F12 в Дельфи/C++Builder.

* Ставлю точку прерывания на строку, начало внутреннего цикла. Там где сравниваются соседние числа.Нажимаю F8. Дождалась момента, когда запустилась сама программа и надо нажать кнопку " начало сортировки". Нажимаю. Окно программы на втором плане, на первом - редактор кода. Нажимаю опять F8, что бы продолжить тестирование.Выполнилось несколько шагов, а теперь я хочу прервать тестирование, закрыть окно программы и подкорректировать (например) сам код.

Надо остановить процесс отладки, полностью сбросить пошаговый режим. Для этого либо продолжаем программу, запускаем ее дальше работать - F9, и закрываем уже ее саму, как обычно, либо из Дельфи - комбинация клавиш Ctrl+F2, команда Run - Program Reset.

Это надо делать обязательно, аккуратно, иначе Дельфи зависает просто.

* Если я не ошибаюсь, то я вроде как знаю, что такое " Хелп". Это когда начинаешь печатать название какого-либо компонента, ставишь точку и появляется окно со списком всякой-всячины. Это????? Просто я этим иногда пользуюсь, когда печатать неохота.

Хелп зовется из меню - Help - Delphi Help. Справочное руководство обычное. Очень полезная вещь! К нему можно и нужно обращаться, чтобы справку по стандартным функциям например получить. Их множество, тысячи :)

А как найти? Минимальное знание английского нужно конечно. Допустим, хотим узнать, как в строке переставить все символы в обратном порядке, от последнего к первому.

Для этого вызваем хелп, на закладке Contents выбираем пункт Delphi Objects and Component References. Далее, мне лично больше нравится пункт Categorical Routines Listing - список подпрограмм по категориям. Нам нужно что-то со словом string, вот находим string formatting и string handling. Formatting - это что-то из области форматирования (кто Си знает, помнит функцию printf() с заданием формата вывода), а вот string handling - это то, что нам и надо. Только таких групп там две, у первой приписка - (null-terminated).

В Дельфи есть еще один тип строк, называется завершающиеся нулем. Он введен для совместимости с форматом хранения строк в Си (последовательность символов, кончающаяся символом с кодом ноль). Его мы изучать в обозримом будущем не будем.

Нужен нам другой раздел, без null-terminated. Заглядываем в него, там пошли названия функций. Как будет "переставить"? Наверное, resort, rechange, reverse... Просматриваем, и - о, удача! AnsiReverseString. Смотрим описание - да, то, что надо.

Можно было зайти на закладку Find, поиск, и набрать там reverse - AnsiReverseString показалась бы первой в списке.

То есть главное - как в яндексе :) запрос грамотно сформулировать.

Ну и просто хелп просматривать полезно. Как изучающие другие языки любят словари просматривать в поиске знакомых :) (более продвинутые - незнакомых :) слов, так и нормальные программисты любят делать RTFM :)

  * Выдает ошибку:

  a:=0; // этот цикл записыват данные из списка 1
            //в список 2
            for a:= a to ListBox1.Count do
            begin
               St:= ListBox1.Items.Strings[a];
               ListBox2.Items.Add( St );
           end;

Это частая ошибка, сам так, бывает, ошибаюсь :)

Нумерация элементов в Items с нуля, поэтому если их 10, то индексировать можно от 0 до 9 (а не 10 - это же на 1 больше, чем реальное число элементов):

  for a:= a to ListBox1.Count -1 do
                              ^^
  надо добавить. Только лучше не

For a:= a ...

a

For a:= 0 to ...

* Как выделить определенный элемент на форме сразу?

На элемент управления можно ставить фокус. ВО-первых, есть свойство TabOrder, в каком порядке обходятся курсором элементы на форме при нажатии TAB. У кого значение TabOrder=0, тот первым будет выделен. Потом, можно явно указывать фокус так:

  Edit1.SetFocus;
  ListBox1.SetFocus;

Метод SetFocus элемента управления вызывается, без параметров.

* Тоже хотел узнать,как это сделать из всплывающей подсказки, а она чего-то не всплыла.

Всплывающая подсказка (желтое окошечко при наведении курсора мышки на элемент) задается в свойстве элемента Hint, и при этом надо свойство ShowHint перевести в true.

при очередном скачивании архива с предыдущими выпусками занятий "Программирование с нуля" мой антивирус выявил трояна под миловиндым именем "copy me" в задании 13 и на странице с таким же выпуском тоже. мнето это уже както по боку а вот вам будет не посебе, узнать что на вашем сайте сидит какая то тварь. антивируная у меня BitDefender home v6.4.1 к стати не плохой. всегда объявляет, какая пога имеет вирус, а какая использует его компоненты и по этому лечению не подлежит. извините если что не так может быть и у пограммы могут быть ошибки.

Антивирусы обычно перестраховываются :) Можно взять любой текстовый файл, назвать его типа "clare.exe", и сторожа его сочтут за вирус. Они же просто проверяют, допустим, название файла, или есть ли в файле некая ключевая последовательность символов, и вот в том уроке исходный текст программы, абракадабря :) была сочтена за шаблон вируса.

* Если я напишу (z у меня Real):

  z:= 144;
  WriteLn( ' Kvadratnyi koren budet: ' , sqrt(z));

то он мне выдаст не 12, а 1.2! Так со всеми числами! Как это предотвратить?
Eugenijus

Да, это формат вывода такой, дробный. Скоро объясню работу с форматами вывода, а пока можете временно такую схему примерно использовать:

  var s: string;
      x: real;
  ...
  x := 3.14;
  s := format( ' %2.2f ' ,[ x ]);

Вот такая хитрая запись :) Берется x и аккуратно проеобазовывается в строку "3.14". Для сишников функция format() напоминает уже упомянутый printf(). Сначала следует строка формата, потом подставляемый в нее набор значений. Только он еще в квадратные скобки берется.

* Как сформировать число в диапазоне от -1 до 1 , для одной из последних задач?

Берем генератор случ. чисел от 0 до 99, делим что получилось на 50 и вычитаем единицу.

* По N 34 - какая разница, стобцы или строки менять? Главное, аккуратно сообразить, какой элемент на какой меняется. Представляем табличку, в цикле счетчика n до длины строки/стоблца (они одинаковые по длине) элемент (i,n) меняем на (n,j). Попарно.

Ну или можно в отдельный одномерный массив, вспомогательный, записать стобец, на его место - строку, а потом миссив - в строку.

* ПОДСКАЖИТЕ ПОЖАЛУЙСТА КДЕ МОЖНО СКАЧАТЬ Microsoft Visual Studio .NET 2003 и Borland Delphi 7. ГОРД У НАСНЕ БОЛЬШОЙ И ДИСКИ НАИТИ ТРУДНО, А В ИНЕТЕ ИЛИ НЕ РАБОТАЕТ ИЛИ ПЛАТНО. ЕСЛИ У ВАС ЕСТЬ ПРИШЛИТЕ ПОЖАЛУЙСТА ССЫЛКИ ГДЕ МОЖНО БЫЛО БЫ СКАЧАТЬ ЭТИ ПРОГРАММЫ

Насчет Дельфи, можно скачать триал-версию с сайта Борланда -

http://borland.com/products/downloads/download_delphi.html

Правда, она большая, 170 мб.

Кроме того, учиться, упражнения можно делать в старых версиях, таких программах, как Turbo Pascal или Turbo C. Они работают в дос-окошке (консольные :), текстовые, но для изучения очень хорошо подходят. Windows-программы делать в них практически нереально, а вот консольные - сколько угодно, произвольной сложности.

http://www.softportal.com/downloadsubsection/37

1)Как сделать так чтобы программы в делфи были определенного рызмера и их нельзя растягивать?
Артём

В свойстве BorderStyle указываете bsDialog, размер просто задаете в дизайнере.

* 2)Как сделать так чтобы при нажатии на кнопку отнималось число из счетчика?

По одной кнопке инициализируете счетчик, по другой увеличиваете.

var n: Integer;

обработчик первой кнопки:

...
n := 0;

обработчик второй кнопки:

...
n := n + 1;

Вопрос 1. Номера заданий не по порядку - ошибка рассылки или специально так. Если ошибка, то слова 31 "в такой же матрице+" относятся к 28 или к 30?

Нет, не ошибка. Я их придумывал в порядке номеров, а потом сортировал по темам.

33. КАК ЗАПОЛНИТЬ ТАБЛИЦУ СЛУЧАЙНЫМИ СИМВОЛАМИ? Я вижу лишь один способ: Rnd*100, а потом переводить по таблице ASCII. Этот способ верен или подразумевается некий иной?

Как работать с символами в Бейсике, было в 40 выпуске. Только случайное в правильном диапазоне должно быть.

32. Как определить четное число или нечетное. Если нечетное разделить на 2, то получится не целое+ Но я слышал в Паскале есть функция ODD(), которая возврашает TRUE или FALSE. Может и в Бэйсике есть подобная+?

Ведь говорю же я всем, делать, ничего не пропуская! Постоянно! :) Именно потому, что все эти вещи обсуждались давно уже, еще на заре занятий. Вот и всплывает незнание элементарных вещей на старших занятиях.

И каждый раз спрашивают одно и то же, о чем писалось неоднократно. Вот не буду подсказывать, ройтесь сами в старых выпусках.

Делить надо целые числа так, чтобы остаток целый оставался, по нему и определяете.

39 Делители находить по тому же принципу, что и в 32 - четное?

Это уж как сами сделаете. МНого разных способов есть.

38 Заменять, то есть, надо только знаки , . ! ?"

Знаки, которые заданы строкой-параметром. Что в ней будет, заранее мы не знаем.

Ответы на задания.

Хочу сообщить, что эти строители вырубили 50% леса! Вот код моего консольного приложения (опять же в Basic .Net 2003)

  Module Module1
      Sub Main()
          Dim intForest, intSosna, intRest As Integer
          intForest = 100
          intSosna = 0.99 * intForest
          do
              intForest = intForest - 1
              intSosna = intSosna - 1
          Loop Until intSosna = 0.98 * intForest
          intRest = 100 - intForest
          Console.Write("Virubili " & intRest & "% lesa!")
          Console.ReadLine()
      end Sub
  end Module

На Си:

                  static void Main(string[] args)
                  {
                          double intForest, intSosna, dbProcent;
                                                  intForest = 100;
                          intSosna = 0.99 * intForest;
                          while( 0.98*intForest != intSosna)
                          {
                                          intForest = intForest - 1;
                                  intSosna = intSosna - 1;
                          }
                          dbProcent = 100 - intForest;
          Console.WriteLine(intForest);
                  Console.ReadLine();
                  
                  }

Максим Кибермаксович :)

  26. Про лес. Логическое решение тут, что-то вроде этого будет:
   Деревьев в лесу всегда на одно больше, чем сосен.
  Допустим в лесу изначально 100 деревьев. Тогда 1 дерево – это один
  процент, и вопрос можно поставить по
  другому: «Сколько должно быть деревьев, чтобы 1 дерево
  составляло 2 %?». Очевидно, что деревьев должно быть
  50, т.е. в два раза меньше.

  Теперь программа:

  #include <vcl.h>
  #pragma hdrstop

  #include "Unit1.h"
  //---------------------------------------------------------------------------
  #pragma package(smart_init)
  #pragma resource "*.dfm"

  int pine;
  float tree,percent;
  AnsiString str;

  TForm1 *Form1;
  //---------------------------------------------------------------------------
  __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
  {
  }
  //---------------------------------------------------------------------------
  //Кнопка "Сажать"
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
       randomize();
       percent=0.99; //Первоначальный % сосен в лесу
       tree=random(9900)+100; //Растим деревья
       pine=tree*percent; //Считаем сосны
       LabTrees->Caption=tree; //Печать деревьев
       str=pine;
       str+=" (99 %)";
       LabPines->Caption=str; //Печать сосен
       Label3->Caption=""; //Очистка строки сообщения
       Button2->Enabled=true; //Разрешить кнопку "Рубить"
  }
  //---------------------------------------------------------------------------
  //Кнопка "Рубить"
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       int srubili;
       srubili=0;

       while (percent>0.98) { //Рубить пока сосен >98%:
            pine--; //Рубаем сосну
            tree--; //Уменьшаем кол-во деревьев
            srubili++; //Срубленные деревья
            percent=pine/tree; //Новый процент
       }
       LabTrees->Caption=tree;
       str=pine;
       str+=" (98 %)";
       LabPines->Caption=str;
       percent=srubili*100/(srubili+tree); //Процент срубленных деревьев
       str="Срубили "; //Создание сообщения
       str+=srubili;
       str+=" сосен.\nЭто ";
       str+=FloatToStrF(percent,ffFixed,10,2);
       str+=" % всех деревьев!";
       Label3->Caption=str; //Вывод сообщения
       Button2->Enabled=false;
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::N2Click(TObject *Sender)
  {
       Close();
  }
  //---------------------------------------------------------------------------
  //Справка
  void __fastcall TForm1::N4Click(TObject *Sender)
  {
       ShowMessage("Леспромхоз решил вырубить сосновый лес, но
  экологи запротестовали.\nТогда директор
  леспромхоза всех успокоил,сказав:\n ' В лесу 99 процентов сосен.
  Мы будем рубить только сосны.\nПосле рубки
  сосны будут составлять 98 процентов всех деревьев ' .\n Какую
  часть леса вырубит леспромхоз? ");
  }
  //---------------------------------------------------------------------------
  //О программе
  void __fastcall TForm1::N5Click(TObject *Sender)
  {
       ShowMessage("ЛЕС\nВерсия 1.0\nАвтор: Федотова
  Екатерина\n2005 г.");
  }

  ПРОВЕРКА
  1) Посадили 4225 деревьев, из них 4182 сосен. После рубки:
  деревьев 2149, сосен 2106. Срублено 2076
  (49,14%)
  2) Посадили 6689 деревьев, из них 6622 сосен. После рубки:
  деревьев 3349, сосен 3282. Срублено 3340
  (49,93%)
  Екатерина

  Задание 26 Про сосны.
  Я её в уме быстрее решила. Пока с шифром возилась в перерывах
  решение и набросала.
  Х - все деревья
  0,99*Х - сосны
  Y - вырубили сосен
  (0,99*Х-Y) - осталось сосен
  (X-Y) - осталось деревьев
   
  (0,99*Х-Y) составляет 98% от (Х-Y) => (0,99*X-Y)=0,98*(X-Y) =>
  0,99*X-Y=0,98*X-0,98*Y =>
   
  0,99*X-0,98*X=Y-0,98*Y => 0,01*X=0,02*Y => 0,01*X*100= 0,02*Y*100
  => X=2*Y => Y=1/2X
   
  Вывод: вырубили половину леса.
   
  Вот тоже самое в консольном варианте:
   
  uses
    SysUtils;
   var vd,ostd,sosn, p:real;//было деревьев, осталось,
                                    // количество сосен,
  begin
  randomize;
   // честно говоря нули от "балды" поставила. кто его знает сколько
  в лесу деревьев
    vd:=random(10000000000)+100000000;// предполагаемое количество
                                                            // деревьев в лесу
    sosn:=vd*0.99; // количество сосен 99% всех
  деревьев
    ostd:=vd; // первоначальное значение
  оставшихся
                                                           // деревьев
    while sosn/ostd>=0.98 do // делать пока сосны не будут
  составлять 98%
                                                         // оставшихся деревьев
      begin
        sosn:=sosn-1; // вырубаем по одной сосне
        ostd:=ostd-1; // количество деревьев в лесу
                                                           // тоже уменьшается с каждой
  вырубленной сосной
      end;
      p:=(vd-ostd)/vd; // процент вырубленных сосен от
  первоначального
                                                           // количества всех деревьев в лесу
      writeln( FloatToStrF(p, ffFixed,4,2)); // вывод результата
   readln;
  end.
  Лена

Вот вам и женская логика :)

23-e - сортирвока.

  procedure TForm1.Button1Click(Sender: TObject);
  var d:array[1..15] of integer;
  var n,i,z : integer;
  begin
    rez1.caption:= ' числа ' ;
  for n:=1 to 15 do d[n]:=random(1000)+1;
   for n:=1 to 15 do
      rez1.caption:=rez1.caption+^m+inttostr(d[n]);
  i:=2;
  while i<=15 do begin//while
  for n:=15 downto i do begin //for
   if d[n]<d[n-1] then begin// if
     z:=d[n]; d[n]:=d[n-1]; d[n-1]:=z; end; //if
     end; //for
     i:=i+1;
    end; //while
    rez2.caption:= ' результат ' ;
    for n:=1 to 15 do
      rez2.caption:=rez2.caption+^m+inttostr(d[n]);
  end;
  Алексей

  Еще один вариант:

  var d:array [1..33] of integer;
     var x:array [1..33] of integer;
     i,n,y,sum1,sum2 : integer;
  begin
       randomize;
      for n:=1 to 33 do begin//for
      d[n]:=random(250)-125;
      while (d[n]=0) do d[n]:=random(250)-125; end; //for
       i:=1;
  while (i<=33) do begin//while
  y:=1;
  for n:=1 to 33 do if d[n]<d[i] then y:=y+1;
  x[y]:=d[i]; i:=i+1; end; //while
  y:=1;
  writeln(y, ' znachenie= ' ,d[y], ' ' ,y, ' znachenie= ' ,x[y]);
  for y:=2 to 33 do begin
        if x[y]=0 then x[y]:=x[y-1];
    writeln(y, ' znachenie= ' ,d[y], ' ' ,y, ' znachenie= ' ,x[y]);end;
     sum1:=0; sum2:=0;
     for y:=1 to 33 do begin
     sum1:=sum1+d[y]; sum2:=sum2+x[y]; end;
     writeln( ' cymma1= ' ,sum1, ' cymma2= ' ,sum2);
  readln;
   
    end.
  У этого способа одно достоинство-он не изменяет первоначальный
  массив.


Элементы управления

Насчет списка еще. Как мы делали для кнопки обработчик нажатия, так для списка можно отслеживать выбор какого-то элемента мышкой. Для этого в инспекторе объектов на закладке Events, где задаются события текущего объекта, которые можно обрабатывать, дважды щелкнем на строчке OnClick (событие, возникающее при щелчке мышкой на списке), и создастся обработчик такого щелчка (сначала надо выделить конечно сам список на форме).

В этом обработчике можно с помощью свойства ItemIndex сразу узнать, какой элемент был выделен. Это удобно, например, когда у нас есть список заданий, и мы хотим, когда выбрали в списке упражнений элемент-название, динамически показывать, например, в поле-надписи или многострочном поле (далее см.) подробное описание соответствующего упражнения.

Возвращаясь к вышеупомянутому примерчику со счетчиком - инициализируем и увеличиваем по кнопке. Часто бывает, что инициализация нужна всего один раз, перед началом работы программы. У формы есть событие (вкладка Events инспектора) под названием OnCreate (в момент создания). Создаем обработчик этого события и в него записываем все нужные начальные настройки. Они вызовутся только один раз, в момент, когда программа запущена, а форма еще не появилась (не создалась). Можете поставить в таком обработчике точку прерывания и посмотреть, когда она сработает.

Многострочное поле. Memo.

Схоже с объектом Edit, только позволяет редактировать не одну строчку, а много. Текстовый редактор своеобразный.

Основное свойство - Lines, массив строк, напоминает Items у списка.

Очистка содержимого:

Memo1.Lines.Clear;

Memo1 - это имя компонента Memo по умолчанию, если его положить на форму.

Обратиться к любой строке можно по ее номеру (нумерация с нуля начинается!) :

  Memo1.Lines[0] := ' Это первая строка! ' ;

Добавление строки - известным уже методом Add:

  Memo1.Lines.Add( ' эту строку добавляем в конец... ' );

Можно сохранить все содержимое Memo в текстовый файл (указываем полный/относительный к нему путь):

  Memo1.Lines.SaveToFile( 'c:\txt\memotekst.txt' );

Число строк - метод Count:

n := Memo1.Lines.Count; // текущее число строк в Memo

Свойство WordWrap задает, будут ли слова переноситься на новую строчку, если строка не уместилась в длину в окне Memo. При этом, даже если перенос будет автоматически, считается строка все равно одной целой, при автопереносе новые строки в Lines не появляются.

Свойство ReadOnly задает, доступно ли содержимое поля для редактирования, или же только для просмотра и выделения/копирования.


Напоминаю - сложности с задачами я объясняю индивидуально только тем, кто выполняет все задания, начиная с первого, и присылает по каждому отчет и исходные тексты всех примеров.

Фразы типа "я все понял!" без практического подтверждения своим собственным правильным кодом не принимаются :)


(c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса тут:
http://russianenterprisesolutions.com/sbo/

 

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull
Отписаться

В избранное