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

Инвестирование с нуля

  Все выпуски  

Программирование на Си и С++ с нуля 134) Ответы на задания или Про отощавшего кота


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

134) Программирование на С++: Ответы на задания или Про отощавшего кота

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

Кстати, существует огромный портал SourceForge.Net, на котором ведется более сотни тысяч проектов, которые распространяются бесплатно и в исходных текстах. Очень полезно изучать, как пишут код мастера :)

Некоторые примеры я сокращал, где код был почти идентичен, оставил лишь наиболее элегантные решения. При этом почти в каждом из них применены приемы, которые мы пока не изучали, но которые весьма важны. Поэтому детально изучите все решения! Какие-то вещи, возможно, пока будут совсем непонятны, просто их пропустите.

Сейчас код форматируется моей старой программкой, которую я делал для курса Дельфи, поэтому пока выделяются не все ключевые слова С++. Со временем я это исправлю :)

Но сначала - классический ответ Юрия.

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double a;
  a = (422.3 - (294549/9 - 0.7));
  Label1->Caption = FloatToStrF ((5493+a) ,ffFixed,5,2);
  }

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
  double a;
  double b;
  double c;
  a = 294549/9 - 0.7 ;
  Label1->Caption = FloatToStrF (5493+(422.3 - a) ,ffFixed,5,2);
  a = (3924.338/39393+238);
  b = (2+4395.454-3*595);
  c = 2373/22;
  Label2->Caption = FloatToStrF( 22.00*a/b*c ,ffFixed,5,2);
  }

  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  double a;
  double b;
  double c;
  double d;
  a = 294549/9 - 0.7 ;
  Label1->Caption = FloatToStrF (5493+(422.3 - a) ,ffFixed,5,2);
  a = (3924.338/39393+238);
  b = (2+4395.454-3*595);
  c = 2373/22;
  Label2->Caption = FloatToStrF( 22.00*a/b*c ,ffFixed,5,2);
  a = ((473.0*384.0/3838.0)/354.0) ;
  c = (2.0+3.0-5+8.8*2.0*8.8);
  b = (0.003+(99999.0-(-1.0)*(-2.0)/(-4.0))) ;
  d = (329.567-a);
  Label3->Caption = FloatToStrF( d/(c/b) ,ffFixed,5,2);
  }

  Пример ?3

  {
  double n;
  n = StrToFloat(Edit1->Text);
  n = n*2;
  Label1->Caption = FloatToStr(n);
  }

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

Задание № 3.Валютный калькулятор.

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double a,b,c;
  a=StrToFloat(Edit1->Text);
  b=StrToFloat(Edit2->Text);
  c=a*b;
  Label1->Caption=FloatToStr(c);
  }

Алексей

Далее - Логическая задача про кошку.

Основа – форма с кнопкой и текстовым полем. Код программы:

  void __fastcall TForm1::Button1Click(TObject *Sender)

  {

  int R;

  double x;

  double p;

  double p1;

  double R1;

  double h;

  R = 6400000;

  x = 3.14;

  p = x*2.0*R;

  p1 = p + 1.0;

  R1 = p1 / (2.0*x);

  h = R1 - R;

  Label1->Caption = FloatToStrF(h, ffFixed,5,2);

  }

Ответ: 0,16м. Для домашней кошки вполне должно хватить.
Тоже самое с цифрами.
Длина экватора = 6400000 * 2 * 3,14 = 40192000м
Длина удлиненной ленты = 40192000 + 1 = 40192001м
Радиус удлиненной ленты = 40192001 / (2 * 3,14) = 6400000,16м
Зазор = 6400000,16 - 6400000 = 0,16м
4. Задание 3. Расчет валют.
Основа – форма с кнопкой, текстовым полем, полем ввода суммы (Sum) и полем ввода курса валюты (Rate) .
Код программы:

  void __fastcall TForm1::Button1Click(TObject *Sender)

  {

  double a;

  double b;

  a = StrToFloat(Sum->Text);

  b = StrToFloat(Rate->Text);

  a = a*b;

  Label1->Caption = FloatToStr(a);

  }

Вопрос. В заданиях 1 и 2 программу можно было бы упростить, если бы переменные объявлялись один раз для всех кнопок сразу. Подскажите, пожалуйста, как это сделать? Андрей.

Это важный и довольно принципиальный момент. Переменные можно определять практически в любом месте программы, но они имеют так называемую область видимости. Если переменная объявлена внутри некоторого блока, выделенного фигурными скобками { } , то она "видима" только внутри этого блока:

  здесь переменная X не "видна"
  {
   double X;
   здесь переменная X "видна"!
  }
  здесь переменная X снова не "видна"

Переменные внутри блока { } называются локальные. Можно также определять глобальные переменные, которые расположены вне любого блока. Тогда они доступны (видимы) и внутри любого блока { } , и там их можно использовать.

Такие глобальные переменные обычно определяются в начальной части файла. А вот локальные переменные вне своего блока { } не видны.

В следующем примере как раз и применен такой прием - переменные a, b и c определены как глобальные. При этом их значение сохраняется между вызовами обработчиков. А локальные переменные каждый раз "создаются" заново внутри каждого блока { } , а по его завершении "уничтожаются".

Задание 2. Здесь использовались промежуточные переменные a,b,c

  double a,b,c;

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
    Label1->Caption = FloatToStrF(5493+(422.3-(294549/9-0.7)),
    ffFixed,5,2);
    a=22*(3924.338/39393+238);
    b=(2+4395.454-3*595)/(2373/22);
    Label2->Caption = FloatToStrF(a/b,ffFixed,5,2);
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
    Label1->Caption = FloatToStrF(5493+(422.3-(294549/9-0.7)),
    ffFixed,5,2);
    a=22*(3924.338/39393+238);
    b=(2+4395.454-3*595)/(2373/22);
    Label2->Caption = FloatToStrF(a/b,ffFixed,5,2);
    a=329.567-473*384/3838/354;
    b=2+3-5+8.8*2*8.8;
    c=0.003+(99999-(-1)*(-2/-4));
    Label3->Caption = FloatToStrF(a/b*c,ffFixed,5,2);
  }

Задание 3. Здесь я попытался сделать калькулятор на простейшие арифметические действия, правда,он получился очень пока ограниченным,что по возможностям вычисления, что по возможностям ввода.Не хватает пока операций со степенями,вычисления корней и других,да и ввод чисел больше 2 не получается.Бесконечно использовать TEdit не интересно,самое большее для калькулятора это один экземпляр нужен,но чтобы сделать так,догадываюсь надо подождать следующих занятий.

   double a,b,sum;

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    a=StrToFloat(Edit1->Text);
    b=StrToFloat(Edit2->Text);
  }

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
   sum=a+b;
  }

  void __fastcall TForm1::Button4Click(TObject *Sender)
  {
    sum=a*b;
  }

  void __fastcall TForm1::Button5Click(TObject *Sender)
  {
    sum=a/b;
  }

  void __fastcall TForm1::Button6Click(TObject *Sender)
  {
    Label1->Caption=FloatToStr(sum);
  }

  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
   sum=a-b;
  }

В современные системы программирования входит большое число так называемых стандартных функций - кусочков кода с собственным именем, и обращение по этому имени вызывает соответствующий код на выполнение. Другими словами, есть стандартная функция с именем sin (синус), и при ее вызове (вводе имени и значения параметра) автоматически происходит вызов кода, рассчитывающего синус. Его результат возвращается обратно в программу. Функция по способу записи похожа на переменную, только значение переменной постоянно хранится в памяти, а значение функции вычисляется во время работы программы. Кроме того, у функции обычно имеются параметры - для вычисления синуса надо задать угол, некоторое число.

Забегая вперед. StrToFloat() - это функция преобразования строкового значения в дробное число. То есть, имеется строка "3,14", чтобы ее преобразовать в дробное значение 3.14, надо вызвать стандартную функцию StrToFloat() с параметром "3,14":

StrToFloat("3,14")

Параметры функции (их может быть несколько) записываются через запятую и всегда заключаются в круглые скобки. Таким способом можно отличить функцию от переменной. Даже если у функции нет ни одного параметра, пара круглых скобой за ее именем обязательна! Результат вызова функции в программе обрабатывается, как и любые другие данные:

  double x;
  x = StrToFloat("3,14");

Параметром функции может быть и переменная:

  AnsiString S;
  double x;
  S = "3,14";
  x = StrToFloat(S);

У компонента TEdit, как мы уже знаем, есть немало свойств. Например, свойство Text хранит введенную в него строку, свойство Color хранит значение цвета итд. В С++ принята запись, согласно которой доступ к свойству A экземпляра компонента B записывается так:

  B->A

Здесь существует множество оговорок, однако на начальном этапе обучения достаточно такого определения. Экземпляр компонента (Edit1, Edit2 как представители компонента, шаблона TEdit) обычно называется объект. На этом понятии построено все объектно-ориентированное программирование, когда в объекте объединяется множество свойств и функций.

Тогда будет понятна запись:

  Edit1->Text

В ней организуется доступ к свойству Text объекта Edit1. Фактически свойство Text - это обычная переменная, только существует она не сама по себе, а внутри объекта Edit1.

Теперь должен быть понятен общий смысл записи:

   Label1->Caption = FloatToStrF(
     2+2,
     ffFixed,5,2);

Label1->Caption - это свойство Caption (строковая переменная) объекта-метки Label1. В него с помощью оператора присваивания заносим значение функции FloatToStrF(), преобразующей дробное значение (параметр) в текствый вид.

2+2 - это параметр (выражение), значение которого преобразуется. ffFixed - это параметр, задающий форму преобразования (с фиксированной точкой, без экспоненты). 5 и 2 - это параметры, задающие точность вывода.

А ведь еще пару занятий назад казалось, что это что-то очень сложное, правда? :)

Задание 4. Здесь сначала находим длину окружности экватора,прибавляем к ней 1 метр и решаем обратную задачу:находим радиус получившегося кольца.У меня ответ: 6400000,15923567.Число пи я взял равным 3,14.Отсюда делаем вывод,что котенок или некрупный(отощавший)взрослый кот преодолел бы это препятствие. Код у меня такой:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    Label1->Caption=FloatToStr(6.28*StrToFloat(Edit1->Text));
  }

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
  Label1->Caption=FloatToStr((6.28*StrToFloat(Edit1->Text)+StrToFloat(Edit2-
  >Text))/6.28);
  }

Константин

У меня в деревне живет огромный рыжий кот Кеша, вот он точно бы не пролез :-)))

По первым двум заданиям выпуска затруднений не возникло. Я продолжаю на одной форме вставлять новые Button и Label поэтому и нумерация их такая.
2. Задание с переменными:

  void __fastcall TForm1::Button9Click(TObject *Sender)
  {
    double a;
    a= 5493+(422.3-(294549/9-0.7));
   Label14->Caption = FloatToStrF(a,ffFixed,5,2);
  }
  //---------------------------------------------------------------------------

  void __fastcall TForm1::Button10Click(TObject *Sender)
  {
    double a, b;
    a= 5493+(422.3-(294549/9-0.7));
    b= (22*(3924.338/39393+238))/((2+4395.454-3*595)/(2373.0/22));
   Label14->Caption = FloatToStrF(a,ffFixed,5,2);
   Label15->Caption = FloatToStrF(b,ffFixed,5,2);
  }
  //---------------------------------------------------------------------------

  void __fastcall TForm1::Button11Click(TObject *Sender)
  {
    double a, b, c;
    a= 5493+(422.3-(294549/9-0.7));
    b= (22*(3924.338/39393+238))/((2+4395.454-3*595)/(2373.0/22));
    c=
  (329.567-473*384/3838/354)/((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-2/4)))
  );
   Label14->Caption = FloatToStrF(a,ffFixed,5,2);
   Label15->Caption = FloatToStrF(b,ffFixed,5,2);
   Label16->Caption = FloatToStrF(c,ffFixed,8,2);
  }
  //---------------------------------------------------------------------------

3. По третьему заданию. Я не совсем понял что там нужно делать, поэтому с учетом материала третьего задания попытался решить логическую задачку.
Вот что получилось:

  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    Double r1, r2, l1, l2, Itog; // определим переменные
    r1 = StrToFloat(R1->Text); // введем радиус земли 6400000
    l1 = 2*3.141592654*r1; // длина окружности земли
  40212385,9712
    Label6->Caption = FloatToStr(l1); // и ее вывод на экран
    l2 = l1 + StrToFloat(Edit1->Text) ; // длина окружности земли с учетом
  приращения 40212385,9712+1=40212386,9712
    Label9->Caption = FloatToStr(l2); // и ее вывод на экран
     r2 = l2 / (2*3.141592654); // радиус второй окружности
     Itog = r2 - r1; // разница между двумя радиусами
     Label10->Caption = FloatToStr(Itog); // вывод разницы на экран
  0,159154943190515
  }
  //---------------------------------------------------------------------------

Результат получился 0,159154943190515 метров
Наверное кошка в такой просвет пролезет свободно
Александр

Александр использовал один удобный прием, который крайне полезен при составлении программ. Он называется комментарий. Код на С++ можно (и нужно!) дополнять комментариями, которые не влияют на работу программы (они просто игнорируются компилятором) но очень нужны самому программисту. Ведь уже за несколько дней интенсивной подготовки кода старые тексты забываются, путаются, и разобраться в них все сложнее и сложнее. На помощь приходят комментарии. Они особо нужны, когда код составляется группой программистов.

Комментарии в С++ бывают двух видов. Однострочный комментарий записывается двумя идущими подряд символами // , и все, что расположено вслед за ними до конца строки, компилятором пропускается.

   double X; // это переменная X :)

Только комментарии надо писать осмысленно :) Вот я написал комментарий неправильно, потому что и так ясно, что X - это переменная. Правильнее - так:

   double X; // размер моей заначки

Второй тип комментария - многострочный. Такой комментарий начинается с пары символов /* , а завершается парой символов */. Все, что расположено между ними, пусть и на нескольких строчках, считается комментарием и игнорируется компилятором.

  /* это..
   комментарий...
   последняя строчка коммента */

Старайтесь всегда использовать комментарии!

Выполнил задание с переменными. Для наглядности:) добавил в начало "затирки".
Артем, который Artsemi.

  ЗАДАНИЕ С ПЕРЕМЕННЫМИ
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double a,b,c;
  Label1->Caption = "";
  Label2->Caption = "";
  Label3->Caption = "";

  a=5493;
  b=422.3;
  c=294549.0/9-0.7;
  Label1->Caption = FloatToStrF(a+b-c, ffFixed,5,2);
  }
  //---------------------------------------------------------------------------

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
  double a,b,c,a1,b1,c1;
  Label1->Caption = "";
  Label2->Caption = "";
  Label3->Caption = "";

  a=5493;
  b=422.3;
  c=294549.0/9-0.7;
  Label1->Caption = FloatToStrF(a+b-c, ffFixed,5,2);

  a1=22*(3924.338/39393+238);
  b1=2+4395.454-3*595;
  c1=2373/22.0;
  Label2->Caption = FloatToStrF(a1/(b1/c1), ffFixed,5,2);
  }
  //---------------------------------------------------------------------------

  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  double a,b,c,a1,b1,c1,a2,b2,c2;
  Label1->Caption = "";
  Label2->Caption = "";
  Label3->Caption = "";

  a=5493;
  b=422.3;
  c=294549.0/9-0.7;
  Label1->Caption = FloatToStrF(a+b-c, ffFixed,5,2);

  a1=22*(3924.338/39393+238);
  b1=2+4395.454-3*595;
  c1=2373/22.0;
  Label2->Caption = FloatToStrF(a1/(b1/c1), ffFixed,5,2);

  a2=329.567-473*384/3838.0/354;
  b2=2+3-5+8.8*2*8.8;
  c2=0.003+(99999-(-1)*(-2/-4.0));
  Label3->Caption = FloatToStrF(a2/(b2/c2), ffFixed,15,2);
  }

Затирки - вещь совершенно правильная, но нельзя забывать, что после записи в переменную нового значения ее старое значение теряется. То есть код вида

   x = 1;
   x = 2;

можно сразу преобразовать в

   x = 2;

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

Вот код по первым двум заданиям, созданный после копирования предыдущего проекта в новую папку. Не только при создании текста проги можно применять копирование:).
Только кнопки не три, а четыре, четвертая reset, чтобы очищать от цифр Label-ы для проверки корректности работы кнопок 1-3. И надписей чуть больше (ещё есть 4-6) для сравнения численных результатов: от появления переменных числа ничуть не изменились, только дробная запись в определении переменной всё равно нужна, иначе возвращается ошибка вычисления, которая в предыдущем задании всплыла.
...

  void __fastcall TForm1::ButtonResetClick(TObject *Sender)
  {
     Label1->Caption = '' ;
     Label2->Caption = '' ;
     Label3->Caption = '' ;
  }

Язык С++ имеет не очень приятную упоминавшуюся особенность свободного преобразования данных разных типов друг в друга, причем компилятор подчас не выдает никаких предупреждений. Вот здесь Александр использовал одинарные кавычки, которые представляют один символ, для записи строки (последовательности символов), для которой нужны двойные кавычки. Увы, не факт, что такое преобразование будет всегда выполнено корректно. Лучше всегда придерживаться записи, не допускающей двусмысленную трактовку.

Для строк - двойные кавычки (а вот в Паскале - Delphi для этого одинарные кавычки применяются).

К вопросу о кошке.
Считаем длину окружности Земли okr1 из ее радиуса r1, взятого из надписи Label3 (надо же видеть исходные данные :).
Считаем длину окружности okr2 после прибавки метра ленты, получая прирост длины ленты из Edit2 (вводит пользователь)
Считаем новый радиус ленты r2
Вычитаем из r2 r1 и сравниваем с 5 сантиметрами (эти звери и не в такие щели пролезают, сам видел) и выводя сообщение в EditRez вместе с величиной щели. Кошка пролезает: щель аж 15.9 см (0.159 в СИ), тут и собака пролезет. Правда, если лента стальная. Если она гибкая, то кошка её своей спиной приподнимет просто и при меньшей щели и пролезет. Или перепрыгнет, нафиг корячиться. И Земля не круглая. Но это уже мелочи.

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
      double r1 = StrToFloat(Label3->Caption);
      double okr1=2*M_PI*r1;
      double okr2=(okr1+StrToFloat(Edit2->Text));
      double r2 = okr2/(2*M_PI);
      if (r2-r1>0.05) EditRez->Text =("кошка пролезет   "+FloatToStrF(r2-r1,ffFixed,5,3));
      else EditRez->Text =("кошка не пролезет   "+FloatToStrF(r2-r1,ffFixed,5,3));
  }

help рулит. Просто набрал pi и получил инструкцию, как его воткнуть вместо моего 3.14 (точность, блин). Не удержался и вспомнил школьный бейсик: нашел после пи ещё и условие, оказывается, и разницы вроде нет. А, применив тип float, получил упомянутое вами переполнение и отрицательную щель для кошки :).
Александр

Про другие нюансы.

В программировании много хитростей. Я пытался осуществить простой ввод/вывод данных по вашему описанию в задании 3:

  void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     int n;
     n = StrToInt(Edit1->Text);
     n = n * 2;
     Label1->Caption = IntToStr(n);
    }

но без умножений и непременно с дробями:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
   double n;
   n = StrToInt(Edit1->Text);
   n = n;
   Panel1->Caption = FloatToStr (n);
   }

при этом, если в последней строке DoubleToStr или IntToStr, то компиляция в этой строке дает ошибку. При FloatToStr компиляция происходит нормально, т.е. ввод/вывод целых чисел до 10-го разряда происходит без сбоев, однако при любых попытках ввести даже простое дробное число Борланд выдает уведомление об ошибке и зависает (см. скрепку).
Что бы это могло значить? Видимо есть какая-то особенность?
Алексей

DoubleToStr() - по-моему, просто нету такой стандартной функции :) FloatToStr() универсальна тем, что дает значение типа float, оно же подходит и для типа double, так как меньше его по диапазону.

Ошибка возникает, когда происходит попытка выполнения функции StrToInt(Edit1->Text). Эта функция предназначена для преобразования из текстового вида в целое значение. Если надо преобразовать в дробное (если в поле Edit1 вводится число с десятичной запятой), используйте функцию StrToFloat().

Я - подписчик на рассылку Программирование на С и С++ с нуля.
Хочу поделиться своими успехами.
Прочитав выпуск номер 132 я выяснил, что кошка свободно пролезет под ленточкой, натянутой вокруг Земли, хотя разница между длинной экватора и ленточки составит всего лишь один метр:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    double pi = 3.1415926535897932384626433832795;
    double Rz;
    double Rlent;
    int Lekv;
    int Llent;
    double Z;

    Lekv = 640000000;
    Rz = (Lekv/pi)/2;
    Llent = Lekv+1;
    Rlent = (Llent/pi)/2;
    Z = Rlent - Rz;

    Label1->Caption = FloatToStrF(Z,ffFixed,15,2);
  }

Z = 0.16м.
Правда, в том мире, где можно запросто обвязать Землю, кошки могут измениться в размерах, так что ответ не такой однозначный, но вот предыдущий код бесспорно можно свести к минимуму:

  .......................
    int deltaL = 1;
    Z = (deltaL/pi)/2;
  .......................

Задание номер 1:

  ...
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
    Label1->Caption = IntToStr(123+9+8+3);
    Label2->Caption = FloatToStrF(34/17+0.76,ffFixed,15,2);
    Label3->Caption = BoolToStr(true);
  }

Кстати, интересно, почему при нажатии на 3-ю кнопку в поле выводится "-1"? Я думал, что будет "true".

Здесь Дмитрий, явно в душе экспериментатор :) , задействовал функцию BoolToStr(). Она предназначена для преобразования в текстовый вид логического значения. Традиционно в С++ логические (булевы) значения представляются во внутреннем, машинном виде, как числа. Ложь - это ноль, а истина - это не ноль :)
Не знаю, правда, почему true получилось -1 (я бы ожидал +1), но главное, что не ноль.
Эта традиция пришла из Си, где булевого типа не было, и во всех логических операциях использовалось сравнение с нулем.

Задание номер 3:
Программа выполняет расчет углов обзора видеокамеры (в градусах) по известным диаметру объектива (в дюймах) и фокусному расстоянию (в мм):

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    double pi = 3.1415926535897932384626433832795;
    double f;
    double D;
    double angleW;
    double angleH;

    f = StrToFloat(Edit1->Text);
    D = StrToFloat(Edit2->Text);
    s = StrToFloat(Edit3->Text);

    D = 25.4*D;
    angleH = (pi*D)/(2*f+2*D);
    angleH = angleH*(180/pi);
    angleW = 0.8*angleH;
    angleH = 0.6*angleW;

    Edit4->Text = FloatToStrF(angleW,ffFixed,15,2);
    Edit5->Text = FloatToStrF(angleH,ffFixed,15,2);
  }

При нажатии на кнопку "расчет", текст из TEditов записывается в переменные, затем производится несложный рассчет, и выводится результат. Конечно, этой программе далеко до совершенства, и польза от неё не велика, но "Путешествие в тысячу миль начинается с одного шага" (пословица).
Спасибо Вам за рассылку.
С наилучшими пожеланиями, Дмитрий.

Следующий ответ.

Выполнил очередные задания , результаты таковы :
В задании про ленту и кошку после расчетов я думаю , что кошка вполне пролезет в образовавшийся зазор ,если её голова пролезет него и если она захочет в него лезть, он по моим расчетам составит 15,9 см. Результат этот я получил таким путём , сначала я высчитал длину ленты плотно прилегающей к экватору. Затем прибавил к этому результату 1 м и высчитал радиус круга полученной длины. После чего отняв от радиуса данного в задаче полученный радиус , узнал какой будет зазор.
А вот код к этой задаче:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double rad1;//данный радиус
  double rad2;//радиус после добавления
  double l1,l2;//длина ленты до и после добавления
  double zazor;//полученный зазор
  double pi;//число пи
  pi = 3.14159265358979324;//из калькулятора
  rad1 = StrToFloat(Edit1->Text);//записываем радиус в переменную
  l1 = (2*pi*rad1);//вычисляем первоначальную длину ленты
  l2 = (l1+1);//лента после добавления
  rad2 = (l2/(2*pi));//радиус полученного круга
  zazor = (rad2-rad1);//зазор для кошки
  Label3 -> Caption = FloatToStrF((zazor*100),ffFixed,3,1)+" см";
  }

При написании этого кода возникла следующая проблема , для использования числа пи , при вычислении длины окружности (формула l = 2*pi*радиус) надо подключать дополнительную библиотеку , а какую и как я не знаю.

Если не ошибаюсь, в стандартных библиотеках С++, подключаемых по умолчанию, константы pi нету, и ее надо вручную вводить (впрочем, несложно запомнить семизначное значение 3.1415927). Кто-нибудь в курсе, есть такая константа?

Задание 3: Я сделал калькулятор :) , считает правильно.

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double rub,dol;//переменные знач. которых вводит пользователь
  dol = StrToFloat(Edit1 -> Text);//курс валюты на который идёт пересчёт
  rub = StrToFloat(Edit2 -> Text);//количество денег , которые нужно
  пересчитать
  Label4->Caption = FloatToStrF(rub/dol,ffFixed,4,2);
  }

Ну вот вроде бы и всё и у меня есть вопрос по поводу Вашей книги Технологии Delphi. Разработка приложений для бизнеса - можно ли её использовать в Delphi 7.
Роман

По Delphi 7 у меня есть отдельный учебный курс: Delphi 7. Учебный курс.

Но он конечно, от курса по Delphi 2006 сильно отстает. Если интересует именно глубокое изучение Delphi 7 , то берите курс по Delphi 7 , но если есть планы постепенно переходить на более продвинутые версии, то лучше более современный курс по технологиям Delphi 2006 (примерно 50-70% технологий совместимы с Delphi 7). А если хотите и Дельфи 7 изучить, и ИТ-менеджером стать, то покупайте обе книги :-)

Отбрасывать дробную часть числа я научился:

  int i;
  double x;
   
  x=StrToFloat(Edit1->Text);
  i=x;
  Label1->Caption=FloatToStr(x);
  Label2->Caption=IntToStr(i);

а вот как бы еще научиться округлять?
На Delphi, например, есть функции Trunc - отбрасывает дробную часть и Round - округляет.
Какие аналоги у них есть в Си?
Валерий

Данный способ отброса дробной части - запись дробного числа в целочисленную переменную, не совсем корректен. Так, разные компиляторы могут выполнять такое преобразование по разному, да и с диапазонами чисел могут быть проблемы. Лучше всегда использовать стандартные функции! Математические функции хранятся в библиотеке math.h. Чтобы ее подключить, надо в начале файла ввести такую команду:

  #include <math.h>

Она размещается там же, где и команда

  #include "Unit1.h"

которая сгенерирована автоматически.

  #include <math.h>
  #include "Unit1.h"

Фактически команда #include означает включение в текущий файл содержимого другого файла (math.h, или Unit1.h). В файлах с расширением .CPP хранится код на языке C++, а в файлах с расширением .H обычно хранятся описания заголовков функций, которые после этого становятся доступны в текущей программе. Мы позже изучим эту тему.

Функция floor(x) формирует наименьшее целое, не превосходящее текущее значение x. Соответственно, вызов floor(x+0.5) всегда округлит x к ближайшему целому.

   int n;
   double x;
   x = 2.51;
   n = floor( x+0.5 ); // в n запишется число 3

Функция ceil() возвращает ближайшее целое, большее текущего значения.

Отправляю Вам свои решения на задания из 131 выпуска рассылки.
Здесь я чуточку усложнил задачу, добавив очистку Labelов и выход из программы...
2) Тоже самое, только с использованием переменных:

  double a,b,c;
  ...   //---------------------------------------------------------------------------
   
  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  a=5493+(422.3-(294549/9.0-0.7));
  Label1->Caption = FloatToStrF(a,ffFixed,15,2);
  b=22*(3924.338/39393.0+238)/((2+4395.454-3*595)/(2373/22.0));
  Label2->Caption = FloatToStrF(b,ffFixed,15,2);
  c=(329.567-473*384/3838.0/354)/((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-
  2/4.0))));
  Label3->Caption = FloatToStrF(c,ffFixed,15,2);
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button4Click(TObject *Sender)
  {
  Label1->Caption = "";
  Label2->Caption = "";
  Label3->Caption = "";
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button5Click(TObject *Sender)
  {
  Close();
  }

Роман

Роман сделал корректную очистку полей-меток - по нажатию на отдельную кнопку. Программирование в современных системах быстрой разработки называется событийно-ориентированным. Подразумевается, что пользователь выполняет некоторые действия с элементами управления (кнопками, переключателями, меню, списками итд), и на эти действия (события в программе) создаются оригинальные обработчики. Так как пользователь может взаимодействовать с элементами управления в произвольном порядке, нередко приходится поломать голову, как синхронизировать процесс решения некоторой задачи с потенциально непредсказуемыми действиями.

Обратите внимание, что Роман использовал функцию Close(), которая вызывается при нажатии на кнопку Button5, а ее действие - это закрытие текущей формы. Таким образом нажание на кнопку Button5 приведет к завершению программы.

Вот доработанный код задачи с подсчетами (он же прикреплен к письму - Podschet.cpp):

  float a,b,c,d,e;
  AnsiString Stroka;
  ...
  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  Label1->Caption = Stroka;
  Label2->Caption = Stroka;
  Label3->Caption = Stroka;

  a=(294549/9-0.7);
  b=5493+(422.3-a);
  Label1->Caption = FloatToStr(b); //-26811

  c=(22.0*(3924.338/39393.0+238.0)) / ( (2.0+4395.454-3.0*595) /
  (2373.0/22.0) );
  Label2->Caption = FloatToStr(c); //216.275726

  d=(2.0+3.0-5.0+8.8*2*8.8)/( 0.003+(99999.0-(-1.0)*(-2.0/-4.0)) );
  e=(329.567-473/0*384.0/3838.0/354.0)/d ;
  Label3->Caption = FloatToStr(e); //212701.235
  }

Все сделано так, как Вы сказали. Единственное, что я добавил - это очищение надписей после каждого нажатия на кнопку.
Также я составил простенькую программу для расчета курса валют (её код тоже добавлен к рассылке - Kurs.cpp):

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    n = StrToFloat(Edit1->Text);
    m = StrToFloat(Edit2->Text);
    b = m*n;
    Label1->Caption = FloatToStr(b);
  }

Также насчет задачи об экваторе и ленте: получается, что зазор не зависит от радиуса и примерно равен 16 см, а значит, в него пролезет кошка. Сначала не хотелось верить (добавить к футбольному мячу и Земле 1 м - одинаковый зазор?), но, рассмотрев вопрос математически(L=2*П*r) и еще раз образно представив это, смирился с 16 см. Хотелось спросить у Вас я прав в своих рассуждениях? Александр

Практика - критерий истины, показала, что вы правы :)

На мой взгляд, не очень ясно было дано задание. Программу надо было писать для случая, когда кнопки Button1,Button2,Button3 нажимаются поочерёдно, или ответ в полях Label1,Label2,Label3 должен по заданию в рассылке появляться именно по произвольно нажатой кнопки - Button1,Button2,Button3.
Я решил сделать программу в которой ответ на решение выражений появлялся в полях Label1,Label2,Label3 при произвольно нажатых кнопках Button1,Button2,Button3. Думаю такая программа будет более гибкой и менее зависима от фактора последовательности нажатия кнопок. (Рис. р1,р2)
Решение всех выражений было занесено под фигурные скобки непонятной мне функции __fastcall TForm1::TForm1(TComponent*Owner), для того чтобы вычисление выражений сразу были подсчитаны. Хотя не думаю, что данное решение очень правильное т.к. вычисление выражений происходит внутри непонятной функции.
Код программы: (Файл Calc.cpp)

  double a;
  double b;
  double v;

  __fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
  {
      a = 5493 + (422.3 - ((294549 / 9) - 0.7));
      b = (22.0*(3924.338 / 39393.0 + 238.0)) /
  ((2.0 + 4395.454 - 3.0*595.0) / (2373.0 / 22.0));
      v = (329.567 - 473*384 / 3838 / 354) / ((2 + 3 - 5 + (8.8*2*8.8)) /
        (0.003 +(99999 - (-1)*(-2 / -4))));
  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
      Label1->Caption = FloatToStr(a);

  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
       Label1->Caption = FloatToStr(a);
       Label2->Caption = FloatToStr(b);

  }
  //---------------------------------------------------------------------------
  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  Label1->Caption = FloatToStr(a);
  Label2->Caption = FloatToStr(b);
  Label3->Caption = FloatToStr(v);

  }

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

Упомянутая функция с хитрым видом __fastcall TForm1::TForm1 - это так называемый конструктор (изучим его, когда доберемся до объектов), она вызывается в самом начале работы программы автоматически и только один раз. Можно также создать обработчик события OnCreate для формы - он также срабатывает однократно в момент создания самой формы. Но после конструктора :)

Теперь перейду к вопросам.
1. В рассылке по программироани номер 132 я увидел такие строки:

      Label1 -> Caption = FloatToStrF(
         (329.567-(473.0*384.0/3838.0/354.0))/(2.0+3.0-5.0+8.8*2.0*8.8)*
         (0.003+(99999.0-(-1.0)*(-2.0/-4.0)))
          , ffFixed,5,2);
      Label1->Caption = FloatToStrF((329.567-473*384/3838.0/354)/
       ((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-2/4.0)))),ffFixed,15,2);
      Label1->Caption = FloatToStrF(5493+(422.3-294549/9-0.7),ffFixed,5,5);

Теперь вопрос: после слова ffFixed, идут разные цифры "5,2"; "5,5"; "15,2", что они означают и для чего необходим "ffFixed"?

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

2. Также в этой рассылке было слово "FloatToStrF" и "FloatToStr" , что они означают?

FloatToStr() - это функция, которая имеет только один аргумент (дробное число) и преобразовывает его в текстовый вид единым универсальным способом (как правило, с экспонентой). Он не очень наглядный, поэтому лучше использовать функцию FloatToStrF(), в которой также можно уточнять итоговое представление числа.

Ответ на логическую задачу.
L=2pR=2*3,14*6400000=40192000 м,
L1=L+1=40192000+1=40192001 м,
L1=2pR1,
R1=L1/2p=40192001/2*3,14=6400000,159 м
A=R1-R=6400000,159-6400000=0,159 м
Ответ: Примерно 16 см. (Кошка должна пролезть).
Ростислав

Далее.

Решил все-таки написать вам отчет по последнему выпуску программирования. Это наверное будет способом упорядочить мысли, которые так и роятся в голове. Я прошел Ваш курс программирования на Делфи и этот курс дается уже намного проще.:) љВысылаю Вам ответы по последним заданиям. Я объединил 1 и 2 задачи, а 3 сделал для задачи про кошку. Там её высота задается.:) Получилось, что кошка не пролезет в этот зазор даже если очень захочет (зазор 4.3е-9 см). И вопрос: как выйти из выполняемый в данный момент процедуры (как в Делфи Exitом)?
У меня после этого урока вдохновение появилось. Смог доделать программу для курсовой работы по физике (около 1000 строк). Спасибо Вам за курс.
И еще. Я попытался применить свои знания в Делфи к языку С++. Вроде получилось.
Максим.

Максим потом прислал код с правильным решением задачки про кошку.

Выход из текущей функции - оператор return. Мы до него доберемся попозже.

Вот так вроде мы явно ничего не изучали, однако в этом уроке введено немало новых и важных определений!

Понятны ли понятия локальной и глобальной переменной, стандартной функции, объекта, комментариев?


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

Школа программирования с нуля
Все предыдущие выпуски базового курса всегда тут:
http://www.infiltration.ru/p/


Вышел мой учебный курс "Технологии Delphi. Разработка приложений для бизнеса".
http://shop.piter.com/book/978591180282/

В книге описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив одну мою книгу, вы существенно сэкономите :) В книге полностью описан язык Delphi (версия 2006, полностью совместимая с Turbo Delphi) для обеих платформ - Win32 и .NET. Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книгу.

Другие мои книги, которые пока доступны в продаже:


Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование


В избранное