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

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

  Все выпуски  

Программирование на Си и С++ с нуля Переменная величина, Оператор присваивания


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

132) Программирование на С++: Множественные поля вывода и ввода, Переменная величина, Оператор присваивания

Вот пример образцового ответа :) :

Учусь на Turbo C2+ Explorere, взятом с сайта Borland.
Никаких проблем с компиляцией и сборкой не было (хотя делал это больше интуитивно, т.к. рекомендаций по этому вопросу в рассылке не было).
Спасибо за третий пример в первом уроке по калькулятору. Из него понял, что работу с простыми дробями забыл: т.е. при записи трехэтажной дроби в строку нужно не тупо делить все подряд, а умножать "на знаменатель знаменателя" :-)).
Когда понял это, повеселился. Остроумный пример. В остальном трудностей не было. Среда помогает отслеживать скобки, поэтому легко.
Привожу правильный код третьего примера (дающий правильный ответ), может кому пригодится:

  Label1 -> Caption = FloatToStrF(
    (329.567-(473*384/3838/354))/(2+3-5+8.8*2*8.8)*
    (0.003+(99999-(-1)*(-2/-4)))
     , ffFixed,5,2);

или вот так, если выставить тип всех данных в дробном виде:

  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);

Ответы по ним несколько отличаются, ввиду указанной в уроке разницы в точности вычислений. Ответ - в экспоненциальной форме.
Частота рассылки 1 раз в неделю - нормальная.
Сергей

Еще ответы:

1: 5493+(422.3-(294549/9-0.7))
Ответ: -26811,00
2: (22*(3924.338/39393 + 238))/((2+4395.454-3*595)/(2373/22))
Ответ: 214,54
3: (329.567-473*384/3838/354)/((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-2/4))))
Ответ:2,1279E5
В третьем задании сначала пропустил одну скобку, но потом переписал заново и все заработало
Дима

Далее.

Решил написать, может кому поможет.
Я тоже столкнулся с проблемой компиляции. Сохранял проект в выбранную мной папку, а при нажатии F9 выскакивало сообщение [Linker Fatal Error] Fatal: Expected a file name
Пробовал менять каталоги по Вашему совету (скорее всего, что-то не так делал), но не помогло. Стал тыркаться:) дальше. Запустил Бильдер и скомпилировал пустую форму. Работает. Тогда сохранил проект (туда, куда он по умолчанию сохраняется, то бишь в папку Bin), а потом все получившиеся файлы проекта (по дате и времени сохранения видно) переместил в нужный мне каталог. Ну и запускал дальше уже файл Project1.bpr
Все остальные манипуляции с проектом уже сохранялись и работали как надо.
Первое задание с дробными числами:

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

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
  Label1->Caption = FloatToStrF(22*(3924.338/39393.0+238)/
  ((2+4395.454-3*595)/(2373/22.0)),ffFixed,15,2);
  }

  void __fastcall TForm1::Button3Click(TObject *Sender)
  {
  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);
  }

Ответы:
-26811,67
216,28
212699,11
Artsemi

Еще.

1. По второй формуле урока N 128 текст на С++ был такой:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  Label1->Caption = FloatToStrF(
  22*(3924.338/39393 + 238)/((2 + 4395.454 - 3*595)/(2373/22)),
  ffFixed,5,2);
  }

Результат получался 214,54.
2. Текст на С++ этой же формулы с учетом дробей:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  Label1->Caption = FloatToStrF(
  22.0*(3924.338/39393.0 + 238.0)/((2.0 + 4395.454 -
  3.0*595.0)/(2373.0/22.0)),
  ffFixed,5,2);
  }

Результат получился 216,28.
Правильно ли я понимаю, что второй результат (216,28) более точный?
Еще хотел спросить насчет экспоненциального формата чисел; у меня как раз результат вычисления третьей формулы получался в виде 2,1279Е5.
Влияет ли формат числа на результаты последующих вычислений, в которых это число используется? То есть, нужно ли число, записанное в экспоненциальном формате, преобразовывать в обычный формат или нет, и, если нужно, то как это сделать?
И еще, укажите, пожалуйста, свой e-mail для отправки отчетов по заданиям, а то приходится отправлять их через рассылку.
Андрей

Мой адрес всегда находится внизу каждого выпуска уже на протяжении 131 выпуска :)
На всякий случай привожу его явно: bobrovsky at russianenterprisesolutions.com

Результат 216,28 более точный или, точнее, правильный.
Формат числа на последующее использование не влияет (или влияет, но слабо). О преобразовании данных мы будем более подробно говорить впоследствии.

Целые числа имеют одну особенность - когда некоторое значение равно максимально допустимому положительному (для диапазона своего типа), и к нему прибавляется единичка, оно становится минимально допустимым отрицательным. Например, было +255, стало -254 :) При этом никаких ошибок не выдается! Так что с диапазонами надо всегда аккуратнее, проверять, прикидывать возможные значения заранее.

Зато теперь вы знаете, откуда берется известный баг в самоходных самокатах Segway - если их разогнать до максимальной скорости, они неожиданно сами переключаются на полный задний ход :) И ездок летит вперед носом.
И на каком языке программирования написано их бортовое программное обеспечение, тоже понятно :)


Некоторые хитрецы уже додумались до следующего шага самостоятельно. В частности, на форме можно разместить несколько кнопок TButton, и для каждой из кнопок создать свой обработчик. Обязательно попробуйте это сделать сами! Такой код прислал Artsemi, можете посмотреть выше.

Кроме того, каждый обработчик может выводить код в отдельное поле вывода - надо только на форме разместить несколько копий компонента TLabel (Label1, Label2, ...). То есть при нажатии на Button1 выводим результат в Label1, при нажатии на Button2 выводим результат в Label2, и так далее. Для этого просто надо посмотреть внимательно на исходный код - и аккуратно заменить номера полей в названиях, Label1 - на Label2, где надо, и так далее.


Команды на языке C++ (в рамках обработчика текущего события, от открывающей скобки до закрывающей) всегда выполняются ПОСЛЕДОВАТЕЛЬНО, ОДНА ЗА ДРУГОЙ. Это простая, но очень важная особенность любого языка программирования. Как мы читаем строчки в тексте, сверху вниз, так и команды выполняются последовательно.

Поэтому мы можем в одном обработчике записать сразу несколько команд вывода результатов, которые выполнятся последовательно. Вот несколько ответов, в которых так и делается (не забудьте только добавить на форму новые поля вывода и правильно их назвать - Label2, Label3):

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

Никаких споров:))) Вот он, unit1.cpp !
Кстати, есть еще такой же файлик, только с тильдой... Это, наверное, резервная копия? Его можно удалить безболезненно?:) Или все-таки будет больно?:))))
И, подозреваю, где-то нужно поставить галочку, чтоб он вообще не появлялся? Так?
Светлана.
ЗЫ: Спасибо!:)

Больно не будет - с тильдой можно удалять, это архивные копии, по которым потом можно просмотреть историю изменений. Но лучше оставить - они переименовываются автоматически.
Все настройки хранятся в двух местах - глобальные для всей системы вызываются командой Tools - Options.
В подразделе Editor Options можно снять галочку (снять, не поставить! :) с пункта Create backup files. Кстати, в разделе Color можно настроить цвета синтаксиса кода С++ в редакторе.
Настройки, относящиеся к текущему проекту, вызываются командой Project - Options.

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

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    Label1->Caption = FloatToStrF(5493+(422.3-294549/9-0.7),ffFixed,5,5);
    Label2->Caption = FloatToStrF(22*(3924.338/39393+238)/
                                  ((2+4395.454-3*595)/(2373/22)),ffFixed,5,5);
    Label3->Caption = FloatToStrF((329.567-473*(384/3838)/354)/
                ((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-2/-4)))),ffFixed,5,5);
    Label4->Caption =
  FloatToStrF(5493+(422.3-294549.0/9.0-0.7),ffFixed,5,5);
    Label5->Caption = FloatToStrF(22*(3924.338/39393.0+238)/
                                  ((2+4395.454-3*595)/(2373.0/22.0)),ffFixed,5,5);
    Label6->Caption = FloatToStrF((329.567-473*(384.0/3838.0)/354.0)/
            ((2+3-5+8.8*2*8.8)/(0.003+(99999-(-1)*(-2.0/-4.0)))),ffFixed,5,5);
  }

                  в Си до правки в Си после правки в Маткаде
                  -26812 -26813 -26813.067
                   214,54 216,28 216.276
                   212790 212700 212701.238

Александр

Еще подобный вариант:

Прочитал урок и понял , что я не правильно выполнил Ваше задание , т.е. выполнил правильно , а отослал только ответы без кода. Решил сразу исправить свою ошибку.
1) -26812,00
2) 216,28
3) 2,127E5

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  Label2 -> Caption = FloatToStr(5493+(422.3-(294549.0/9.0-0.7)));
  Label3 -> Caption =
  FloatToStrF(22*(3924.338/39393.0+238)/((2+4395.454-3*595)/(2373.0/22.
  0)),ffFixed,5,2);
  Label4 -> Caption =
  FloatToStrF((329.567-473*384.0/3838.0/354.0)/((2+3-5+8.8*2*8.8)/(0.003+
  (99999-(-1)*(-2.0/-4.0)))),ffFixed,5,2);
  }

Роман

Как следует, изучите эти примеры! Не просто запоминайте, а поймите идею - где Label2, а где Label4.

Вот такое вот письмо пришло:

Здравствуйте, я читаю вашу рассылку постоянно, но т.к. я РНР вообще не знаю, я ничего не понимаю, что вы пишите.
Последнее что я прочитал был курс РНР отправка писем. У меня есть к вам одна просьба, пожалуста, если вам не трудно, не могли бы Вы написать как сделать форму для сайта. Ну знаете такую, пишешь что нибудь, нажимаешь "Отправить" и письмо к тебе на ящик улетает. Типа "обратная связь". Очень вас прошу напишите код. Очень нужно, заранее спасибо!

Что человеку ответить, подскажите.


Логический тип данных.

Мы выяснили, что в программе все данные относятся к одному из предопределенных типов: int (целое), double (дробное), char (одиночный символ строки), AnsiString (строка, текстовое) и ряду других.

Есть еще один тип, который по каким-то причинам (видимо, в силу своей простоты :) всегда вызывает сложности. Это логический тип, который в С++ называется bool (от английского boolean - логический). Значения этого типа могут принимать только ДВА значения - true (истина, да) или false (ложь, нет). Целые значения типа int могут быть 0, 1, 10, 100, 12345, и еще много других :) , а логических значений - только два. Это понятно?


Переменная величина.

В программировании не так много ключевых понятий, и мы уже познакомились с половиной :) Серьезно. Программирование - это построение программ из простых команд. Сами команды изучить нетрудно, а вот чтобы создавать такие программы, как Windows (лучше Linux :), потребуется написать миллионы команд. Это делают конечно большие коллективы разработчиков. Ну и активно применяются всевозможные вспомогательные библиотеки с готовым кодом и наборы компонентов.

Вот основные понятия программирования: общая структура приложения (в нашем случае - визуально созданная в Проектировщике), данные, типы данных, переменная, оператор присваивания, условный оператор, оператор цикла, массивы, объекты.
Это всё! Остальное уже мелочи.
Сами можете оценить, сколько еще осталось изучить :)

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

Переменная (переменная величина) - это область памяти, в которой хранится результат расчета.

Переменная (ячейка памяти) для удобства получает в программе имя (название). По этому имени обращаются к хранимому в ней значению.

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

Команда определения переменной записывается так:

тип имя-переменной ;

Тип - это тип данных, которые будут храниться в переменной. Если надо хранить целые числа, используем ключевое слово int, если дробные - double и так далее.

Имя переменной - это идентификатор, придуманный разработчиком :) Он должен состоять из латинских букв, цифр и символа подчеркивания. Первой должна идти буква. Примеры определения переменных:

  int i;
  int Privet;
  double Moia_Utochka;
  AnsiString Stroka2;
  char X789;

В переменные можно записывать результаты расчетов. Для этого используется оператор присваивания :

имя-переменной = выражение ;

Например:

  int x;
  x = 5;
  double Y;
  Y = 3.14 + 5;

Старое значение, хранившееся в переменной, стирается.

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

  int x;
  double Y;
  x = 5;
  Y = 3.14 + x;

В переменную Y будет занесено значение 8.14 (3.14 складывается со значением, хранящимся в переменной x).

Команды выполняются последовательно, одна за другой!

В переменную дробного типа можно заносить целые значения (они автоматически преобразуются в дробные), а вот в целые переменные дробные значения занести нельзя.

Вот вариант решения с переменными, который предложил Александр:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  double a;
  Label1->Caption = FloatToStr(5493+(422.3-(294549/9-0.7)));
  a=(22.0*(3924.338/39393.0+238.0)) / ( (2.0+4395.454-3.0*595) / (2373.0/22.0) );
  Label2->Caption = FloatToStr( a );
  a=(2.0+3.0-5.0+8.8*2*8.8)/( 0.003+(99999.0-(-1.0)*(-2.0/-4.0)) );
  Label3->Caption = (329.567-473/0*384.0/3838.0/354.0)/a;
  }

Не удержался от использования буферной переменной, так как знал как это делать еще из Ваших уроков "Школы с нуля".
В уроке Вы упомянули об использовании дробных чисел при расчетах, использовав их, я добился правильного ответа во втором вычислении, но использовав его в третьем, разница между получившимся и данным Вами ответами различались на что-то около 70! Не думал, что погрешности в вычислениях могут достигать таких размеров.
Маленькая просьба: Пожалуйста, вводите иногда в уроки логические задачи, как это было в Школе с нуля.

Понятен код Александра? Обязательно его изучите. Напоминаю - программа выполняется последовательно, с первой команды к последующей, ничего не пропуская!

Оператор присваивания работает так: сначала вычисляется значение выражения справа от =, и затем заносится в переменную, введенную слева от =. Поэтому следующий код:

  int n;
  n = 2;
  n = n + 1;

в конечном итоге запишет в переменную n значение 3. Это ясно? Важно в этом примере разобраться.

Спрашивали, как организовать красивый вывод значений. Во-первых, любой объект (как поле вывода и кнопка, так и сама форма) имеет свойство Color (цвет). Его можно настраивать. Еще одно свойство Font задает шрифт, которым выводится информация.
Во-вторых, имеется компонент StaticText (панель Additional), у которого есть набор свойств, начинающихся с Bevel - они задают его рельефные рамки. Только тогда в коде вместо Label1 пишете везде StaticText1 и так далее.

Насчет логических задач. Практика показывает, что занимающиеся подчас активно берутся за такие задачки, а вот более скучные уроки выполнять ленятся :) Отвлекают задачи от главного процесса, однако. Вот задача, которую удобно решать с помощью С++ :)

где-то нашел на форумах: "Представьте, что вокруг земного шара по экватору обвязана лента. Длинна этой ленты, стало быть, равна длине экватора. Взяли мы эту ленту и пришили к ней еще 1 метр, а затем придали этой ленте форму окружности. Если раньше лента плотно прилегала к земной поверхности, то теперь между лентой и землей образовался зазор. Допустим мы натянули ленту так, чтобы этот зазор был одинаков во всех местах (ну примерно как Сатурн со своими кольцами, так и Земля будет с ленточкой вокруг себя)."
Вопрос: пролезет ли в образовавшийся зазор кошка? :) Результат доказываем с цифрами.
Радиус Земли принимаем, 6400000 метров.


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

Задания.
1. Создайте программу, в которой будут три кнопки и три поля вывода.
По нажатию первой кнопки выводите результат первой формулы в первое поле, по нажатию второй кнопки выводите результат первой и второй формул в первое и второе поля вывода, по нажатию третьей - выводите три результата во все три поля.
Активно применяйте для подготовки кода копирование и вставку.

2. Перепишите программу расчета формул, используя несколько (больше одной :) промежуточных переменных.

3. (повышенной сложности :)
C++Builder позволяет не только выводить данные на экран, но и получать их от пользователя. Для этого предназначен компонент TEdit (поле ввода). Следующий код (объяснять его пока не буду, просто запомните, что он делает) записывает в заданную переменную содержимое поля ввода TEdit (его экземпляра Edit1) в формате double:

  double n;
  n = StrToFloat(Edit1->Text);

В формате целого (int):

  int n;
  n = StrToInt(Edit1->Text);

В поле Edit на форме (в запущенной программе) надо ввести корректное значение числа!!! Если оно дробное - то скорее всего с десятичной ЗАПЯТОЙ (не точкой! точка используется только в коде программы на С++, а запятая как десятичный разделитель при вводе в формы задается в региональных настройках Windows). Иначе возникнет ошибка.

Вот простой пример, в котором по нажатию на кнопку Button1 вводится целое значение из поля Edit1 формы, умножается на два и выводится в поле Label1:

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

   n = n * 2;

   Label1->Caption = IntToStr(n);
  }

Теперь перед вами открываются неограниченные возможности :) - можно например сделать калькулятор или расчет валют.
Если используете несколько копий TEdit, то меняете где надо Edit1 на Edit2, Edit3 и так далее.

Реально вы уже сможете создавать полноценные программы для своей работы, если она связана с вычислениями!
Вводите значения, жмете кнопку, получаете результат.


Немного рекламы.

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

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

Почему эта книга так названа? Потому что она ориентирована не только на разработчиков, но и на тех, кто хочет стать ИТ-менеджером, или уже стал им и желает развиваться дальше. В каждой части книги (кроме первых, посвященных непосредственно языку программирования Delphi) изучаются технологии, которые можно применить для создания программ, а прогаммирование знать не требуется (или требуется, но на минимальном уровне). Учебный курс дает знания, которые нужны ЛЮБОМУ ИТ-менеджеру как базисный уровень - ведь сложно управлять коллективом разработчиков или ИТ-отделом, не владея соответствующими технологиями - а главное, ключевыми понятиями и терминологией, которые в книге выделены особо. Мой курс в сжатом виде, а также в форме готовых ПОШАГОВЫХ алгоритмов и практических примеров дает базовые знания по всем важнейшим направлениям, связанным с разработкой софта. Ну и повышает общий культурный уровень, позволяя "быть в теме". Вообще в этом учебном курсе примерено множество передовых подходов к подаче материала - он обгоняет существующие ИТ-учебники на пару поколений :)

Полное оглавление книги можно найти по ссылке выше.

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

Вот официальная аннотация на мой учебник:
"Книга представляет собой учебный курс для преподавателей и студентов, изучающих разработку информационных систем и программирование на языке высокого уровня. Курс охватывает систему программирования Delphi 2006 и комплекс информационных технологий, реализуемых ее средствами. Операционные платформы курса — Win32 и .NET. Главы книги объединены в восемь тематических разделов. Разделы охватывают: основы программирования на языке Delphi и объектно-ориентированное программирование, работу с базами данных и создание приложений, взаимодействующих с ними, создание клиентских и серверных приложений для Интернета, развертывание многоуровневых приложений, проектирование веб-служб и сервисов. Особое внимание в книге уделено технологиям ускоренной разработки корпоративных бизнес-приложений: шаблонам проектирования, архитектуре, управляемой моделью (MDA), языкам модельного проектирования UML и OCL, технологии ECO. Курс имеет обновленный и расширенный понятийный аппарат, отличается архитектурной целостностью и способностью гибко адаптироваться к реалиям конкретного учебного процесса. Теоретические разделы поддержаны мощным практическим компонентом, который позволяет использовать данную книгу в качестве пособия для дополнительного или самостоятельного образования".


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

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

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


В избранное