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

Клуб профессиональных программистов :: Выпуск #102


Клуб профессиональных программистов "Весельчак У"
Информационная рассылка сайта и форума.  Выпуск No102 (2010-11-01).

Здравствуйте, уважаемые читатели!

Сегодня в выпуске:




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



Команда Клуба «Весельчак У» сердечно поздравляет всех читателей, всех участников и гостей с наступающим праздником — Днем Единения России!


Резюме

В области индустрии информационных технологий получают распространение методологии эффективного управления рисками в разработке ПО и производства качественного ПО. Однако подобные методы пока не получили распространения в области разработки встроенных систем, особенно для систем с ограниченными ресурсами. Сегодня качество встроенного ПО обычно определяется платформенно-зависимыми инструментами тестирования, ориентированными в первую очередь на отладку. В данной статье мы представляем интегрированный набор фундаментальных концепций и методов, не связанных с платформенно-зависимыми инструментами. Фактически наш подход является движущей силой современной разработки встроенного ПО. Результат применения этих стратегий — хороший дизайн, пригодные для автоматического тестирования системы и значительное уменьшение числа программных дефектов. Примеры с использованием 8-битной системы с 16К программной памяти и 256 байтами ОЗУ наглядно иллюстрируют данные идеи.

Ключевые слова: пригодная для тестирования разработка, микропрограммирование, качество ПО, тестирование ПО.


1. Введение

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

Встроенное ПО стоит особняком в программном мире. Системы IT высокого уровня обычно работают в «чистом» окружении и мало контактируют с физическим миром. Хотя в принципе последствия любой ошибки обходятся дорого, ошибку в ПО персонального компьютера или большом корпоративном приложении обычно относительно легко исправить. Напротив, дефект во встроенном ПО топливного инжектора в автомобиле может вызвать массовый и дорогостоящий отзыв продукции. Гораздо более тяжелые последствия может иметь вполне реальная перспектива человеческой смерти по причине дефекта ПО. Возможности, сложность и распространенность встроенных систем постоянно возрастают, а с ними возрастают возможность и вероятность весьма дорогостоящих дефектов ПО.

Эффективные методологии управления рисками при разработке ПО и производства качественного ПО понемногу начинают укореняться в промышленности. Например, методы под общим названием «гибкие методологии» (“Agile Methodologies”) постепенно обретают сторонников [1]. Многочисленные примеры и наш собственный опыт разработки свидетельствуют о том, что «гибкие» методы уменьшают количество ошибок на порядок и более по сравнению с традиционным подходом. Среди этих методов особенно выделяется TDD. TDD на первый взгляд может показаться нелогичным: он требует написания тестового кода перед тем, как будет написан подлежащий тестированию функциональный код. Применение TDD означает, что в процессе разработки ПО оно в любой момент может быть протестировано автоматизированными средствами. Разработка тестируемого кода в рамках TDD — более важная задача, чем разработка «хорошего» кода, поскольку тестируемый код — это и есть хороший код.

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

Основные шаги при применении TDD:

  • Выделить часть функциональности системы для реализации (одну функцию или метод).
  • Написать тест для проверки этой функциональности.
  • Написать заглушку вместо тестируемого функционального кода (чтобы код теста мог скомпилироваться).
  • Скомпилировать; запустить тест и убедиться, что он выдает ошибку.
  • Дополнить функциональный код.
  • Скомпилировать; запустить тест.
  • Произвести рефакторинг функционального кода.
  • Повторять шаги 6 и 7 до тех пор, пока тест не пройдет, а функциональный код не будет реализован «чисто».
  • Повторять шаги 1-8 до тех пор, пока все функции не будут реализованы.

В данной статье мы исходим из опыта работы с системами с ограниченными ресурсами, которые не могут позволить себе роскошь в виде операционной системы или объектно-ориентированного языка (например, C++ или Java). В таком контексте применение TDD обычно считалось чересчур сложным. Казалось, что непосредственное взаимодействие программы с оборудованием в сочетании с ограниченными ресурсами для запуска тестового инструментария воздвигают непреодолимый барьер. Мы покажем, как применение нового паттерна проектирования ПО и многоуровневой стратегии тестирования вносит эффективность TDD даже в проектирование встроенного ПО нижнего уровня (а после расширения — любой встроенной системы).

Хотя важность тестирования встроенного ПО не подвергается сомнению, тестовые методики обычно тесно привязаны к специфическим инструментам или платформам [2]. Предлагаемые нами здесь концепции не имеют такой привязки.



Целиком можно прочесть на нашем сайте в разделе «Инструменты и технологии проектирования ПО::Переводы»

  • Программирование :: Общий
  • Для проведения лабораторной работы мне нужен profiler для любого языка программирования.

    Требования:
    1) Чем проще, тем лучше. Если он будет выдавать одну табличку с количеством выполнения каждой строчки кода - этого достаточно. Но принимаются любые варианты, удовлетворяющие требованию 2.
    2) Он должен не иметь инсталлятора. Если кто-то знает какие-нибудь online-профайлеры (например, для JavaScript), тоже можно.

    Кто что может посоветовать?
  • Задача: из файла с логами на удаленном сервере быстро выцепить записи за указанный интервал времени
    Формат файла (файлы организуются посуточно):
    датавремя:всякаяерунда

    на входе задачи - интервал времени дата1-дата2. Нужно выбрать все строки из файла после дата1 но до дата2.
    Проблем несколько:
    * дата1 и дата2 могут явно не присутствовать в файлах (то есть, заданного 12:20:08 нет, но 12:20:11 уже есть)
    * строки могут вообще не содержать даты (тогда нужно считать, что они относятся к предыдущей дате)
    * логи лежат на удаленном сервере, и желательно обрабатывать это все там. Соединение будет устанавливаться через SSH, на сервере стоит либо w2k3/Cygwin, либо RedHat (пока для RH задачу пропустим, но перспектива есть)
    * идея внедрить на сервер приложение или скрипт, а затем выполинть мне нравится в меньшей степени, чем идея выполнить одну, пусть даже большую составную команду.
    * опыта с *nix-системами у меня довольно мало и среди всех команд я ориентируюсь плохо

    Раньше похожую задачу я решал через grep/sed (парсил конфиги), этих инструментов хватало... В принципе, можно через grep попробовать реализовать и эту задачу, но проблема с непрерывностью дат меня смущает - как задать диапазон через регулярное выражение?

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

    Прошу подсказать - у кого какие мысли - в каком направлении двигаться?
  • Программирование :: .NET технология от и до
  • День добрый. при связке wsHttpBinding прокси-клиент создается один раз, пока я его не закрою. В сильверлайте используется связка httpBaseBinding. И там каждый раз при вызове метода прокси создается заново. Отслеживал, используя вот такой простой код. В сильверлайте при клике не кнопку вызываю метод GetDate - время всегда меняется...

    Код:
     [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            string GetDate();

        }

    Код:
        public class Service1 : IService1
        {
            private DateTime now;
            public Service1()
            {
                now = DateTime.Now;
            }
            public string GetDate()
            {
                return now.ToString();
            }
        }


    Но что делать, если мне нужно в одном методе передать данные, в другом их обработать и результат получить в третьем?
  • Программирование :: С/С++ :: ANSI С/С++
  • Доброго времени суток, ув. форумчане.
    Прошу вашей помощи в решении одной задачи.
    Необходимо программу, обрабатывающую двусвязные списки, настроить для работы с односвязными списками.
    Листинг программы:
    Код:
    #include <iostream>
    #include <conio.h>
    #include <stdlib.h>
    #include <cstring>

    using namespace std;

    struct base {
      char fio [30]; // ФИО сотрудника
      char bolezn [50]; // Название болезни
      int dlit;         // Длительность болезни
      base *prev;       // Указатель на предыдущую запись
      base *next;       // Указатель на следующую запись
    };

    base *first = NULL; // Указатель на начало списка
    base *last = NULL;  // Указатель на конец списка


    int List (void);   

    void AddItem (void)
    {
      base *db;

      // создаем новую структуру
      db = new base;
      // заполняем её
      cout << "Введите фамилию сотрудника: ";
      cin >> db->fio;
      cout << "Введите название болезни: ";
      cin >> db->bolezn;
      cout << "Введите длительность болезни: ";
      cin >> db->dlit;
      // добавляем в список
      if (last != NULL) // если список уже существует
      {
        db->prev = last;
        db->next = NULL;
        last->next = db;
        last = db;
      }
      else              // если список ещё не создан
      {
        db->prev = NULL;
        db->next = NULL;
        first = db;
        last = db;
      };
    }


    void DeleteItem (void)
    {
      // выводим список всех структур
      int i = List ();
      int num;

      cout << "Введите номер удаляемой записи ";
      cin >> num;
      if (num < 1 || num > i) return;

      base *db = first;
      // находим указатель на удаляемую структуру
      for (i = 1; i < num; i++)
      {
        db = db->next;
      }
      // удаляем её
      if (db)
      {
        if (db->prev) db->prev->next = db->next;
        if (db->next) db->next->prev = db->prev;
        if (db == first) first = first->next;
        if (db == last) last = last->prev;
        delete db;
      };
    }


    void Input (void)
    {
      bool enough = false;

      do
      {
        AddItem (); // заполняем очередную структуру
        cout << "Продолжить ввод информации? (y/n)" << endl;
        if (getch () == 'n') enough = true;
      }
      while (!enough);
    }


    void Find (void)
    {
      base *db = first;
      char name[20]=" ";
      int i=0;
      cout<<"Введите название болезни :";
      cin>>name;
      cout << "Результаты поиска:" << endl;
      while (db)
      {
        if (!strcmp(db->bolezn,name)) // проверяем запись
        {
    cout << db->fio << " "
    << db->bolezn << " "
    << db->dlit << endl;
    i++;
        }
        db = db->next; // переходим к следующей записи
      }
      if (i==0)cout<<"Поиск не дал результата";
    }


    int List (void)
    {
      base *db = first;
      int i = 0;

      cout << endl << "В списке содержатся:" << endl;
      while (db)
      {
        i++;
        cout << i << ". " << db->fio << " " << db->bolezn << " " << db->dlit << endl;
        db = db->next;
      }
      return i;
    }


    int Menu (void)
    {
      char ch = 0;

      // Выводим список возможных вариантов выбора
      cout << "Ваш выбор:" << endl;
      cout << "1. Сформировать список" << endl;
      cout << "2. Печать списка" << endl;
      cout << "3. Добавить в список" << endl;
      cout << "4. Удалить из списка" << endl;
      cout << "5. Поиск в списке" << endl;
      cout << "6. Выход" << endl;

      // ожидаем нажатия правильной клавиши
      while (ch < '1' || ch > '6')
      {
        ch = getch ();
      }

      // осуществляем выбор согласно набраной клавише
      switch (ch)
      {
        case '1': Input (); break;
        case '2': List (); break;
        case '3': AddItem (); break;
        case '4': DeleteItem (); break;
        case '5': Find (); break;
        case '6': return 0;
      };
      return 1;
    }

    int main (void)
    {
    while (Menu ()); // цикл, пока пользователь не выбрал Выход
    return 0;
    }
    Мои попытки перевести хотя бы функцию ввода не увенчались никакими успехами.
    Код:
      if (first == NULL) 
      { first=db;
        first->next=NULL;
       
      }
      else             
      {
       db->next=last->next;
       last->next=db;
      };
    }
    Ткните носом, как это дело хоть примерно должно выглядеть
  • Программирование :: Delphi
  • Всем Привет! :oh:
    У меня задание создать клиентское положение для больницы. Программа сложная, трудности начались с самого начала. Возможно, вопросов будет много. Но пока что только один.
    По щелчку в DBGrid (там отображается ФИО пациентов) в Memo должен отображаться адрес и телефон этого пациента.
    Вот
    Код:
    procedure TForm1.DBGrid2CellClick(Column: TColumn);
    begin
    ADOQuery5.Active:=False;
    ADOQuery5.Close;
    ADOQuery5.SQL.Clear;
    ADOQuery5.SQL.Add('SELECT * FROM Patient');
    ADOQuery5.Open;
    ADOQuery5.Active:=True;
    Memo4.Lines.Add(ADOQuery5.FieldByName('Sity').AsString);
    Memo4.Lines.Add(ADOQuery5.FieldByName('Street').AsString);
    Memo4.Lines.Add(ADOQuery5.FieldByName('Home').AsString);
    Memo4.Lines.Add(ADOQuery5.FieldByName('Kv').AsString);
    Memo4.Lines.Add(ADOQuery5.FieldByName('P_Kont_Phone').AsString);
    end;
    Но у меня отображается в Memo только запись, которая в акцессе в таблице первая записана. А их там 25 штук разных адресов, при каждом щелчке на другом пациенте должен отбражаться его адрес. Что делать?  :(
  • Программирование :: Java
  • Как работает assertNotNull?
    Мне чтобы проверить, что boolean функция принимает значение, то есть ничего не падает, это можно использовать?
  • Программирование :: Программирование 1С :: 1С 7.x
  • Добрый день
    Есть справочник товара (Справочник.Товар), нужно чтобы в форме списка была колонка с остатками товара. Вот как сделать, чтобы при открытии можно было заполнить значениями эту колонку? Т.е. меня интересует как именно присвоить полям колонки значения, пробовал сделать это на подобии того, как это можно в табличной части документа - пробежавшись по всем строкам - но не выходит, поскольку конструкция
    Код:
    ВыбратьЭлементы();
    Пока ПолучитьЭлемент() = 1 цикл
    ...
    КонецЦикла;
    выдает ошибку
    Код:
    ВыбратьЭлементы();
    {Справочник.Товар.ФормаСписка.ФормаСписка.Модуль(70)}: Объект не может быть перепозиционирован!
  • Здравствуйте, интересует, как можно реализовать отображение какого-либо реквизита справочника при выборе его в форме диалога в отличие от Кода или Наименования
    Если я справочнике я не заполняю наименование (а отображение стоит в виде наименования, хотя не важно, хоть и кода), то при выборе определенного справочника в форме появляется значение ПУСТО "< >", а хочется что бы отображался определенный реквизит этого справочника.

    Например, есть справочник "адреса"
    В нем реквизиты : Код, Наименование, Улица, Дом

    Код заполняется автоматически, Наименование не заполняется (ну, не хочу).
    Основное представление стоит в виде наименования - от чего и отображение пустое.
    А хочется отображение -  Улица + ", " +  Дом

     
  • Операционные системы :: Windows
  • Кто управляет разрешениями на доступ к разделам реестра и почему?
  • Операционные системы :: Embedded systems
  • Привет всем!
    Столкнулся с проблемой включения WiFi адаптера.
    Адаптер AR6K_SD1 в реестре:

    [HKEY_LOCAL_MACHINE\Comm\AR6K_SD1]
    Display Name=AR6000 WLAN Adapter SD
    Group=NDIS
    ImagePath=ar6k_ndis_sdio.dll
    Wireless=1

    [HKEY_LOCAL_MACHINE\Comm\AR6K_SD1\Parms]
    powerSaveMode=2
    currentPowerState=1
    BusType=0
    BusNumber=0
    BtCoexAntConfig=0
    eepromFile=NULL

    Пытался через SetDevicePower(szName, POWER_NAME, PwrDeviceUnspecified) - включение, и SetDevicePower(szName, POWER_NAME, D4) - выключение.
    где szName={98C5250D-C29A-4985-AE5F-AFE5367E5006}\AR6K_SD1.

    Проблема в том, что при перезагрузке, когда адаптер выключен, функция включения не работает. Если включить через навигатор WiFi, то SetDevicePower начинает работать и на включение, и на выключение.

    Как я понял, проблема в том, что адаптер необходимо сначала активировать.
    Проверил регистр до включения WiFi и после - разница в том, что появляется
    новый ключ
    [HKEY_LOCAL_MACHINE\Drivers\Active\103]
    Hnd=3582778688
    Name=DRG1:
    Key=\Drivers\SDCARD\ClientDrivers\Custom\MANF-0271-CARDID-0201-FUNC-1
    BusParent=3489963616
    InterfaceType=0
    BusName=SDBus_1_0_1
    ClientInfo=686337

    Сам ключ [HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Custom\MANF-0271-CARDID-0201-FUNC-1] выглядит так
    Dll=ar6k_ndis_sdio.dll
    Prefix=DRG

    В общем, тогда пробовал до вызова SetDevicePower на включение вызывать
    handle = ActivateDevice(L"\\Drivers\\SDCARD\\ClientDrivers\\Custom\\MANF-0271-CARDID-0201-FUNC-1",NULL);
    на что выдавало handle=NULL, а GetLastError()=110(ERROR_OPEN_FAILED
    )

    В общем, больше пока ничего в голову не пришло.

    Если есть идеи, пишите, буду благодарен.
  • Направления программирования :: Сети
  • Доброго времени суток.
    Не знает ли кто, где возможно добыть класс или библиотеку (под windows) для сборки ip-датаграмм?
    Язык С++.
  • Направления программирования :: Web :: HTML/DHTML
  • В атаче текст нашей рассылки №100 и картинки дефектов отображения.

    Сразу скажу, что создал приложение я в старом SeaMonkey, в FF 3 и ThunderBird 2 и 3 (уже по самой рассылке). Трудности есть в IE и, наверняка, в чем-то еще.

    На первой картинке проблема в расширении страницы (в IE7). На второй — расползание блоков кода (IE6).  Других проблем пока не замечали.

    Просьба потестить и посоветовать, как исправить дефекты. Переделывать не нужно — нужно только подправить.
  • Практические разделы :: Базы данных
  • иИмеется вот такой код встроенной процедуры для интербейсовской базы (СУБД- FireBird 1.5)
    (на названия идентификаторов не смеяться, они мне по наследству достались :) )



    Код:
    CREATE PROCEDURE PR_SHOWLOG_GET_MESSAGES(
        ID_TOLOADRFOMEXCLUDING BIGINT,
        ID_MAX BIGINT,
        MESSFILTER_BARR VARCHAR(513),
        MESSFILTER_LARS VARCHAR(37),
        MESSFILTER_REST SMALLINT)
    RETURNS (
        MESSAGE_ID BIGINT,
        QUIT_DATE TIMESTAMP,
        DMESSAGE TIMESTAMP,
        NOMER SMALLINT,
        RAZDEL SMALLINT,
        MESS_TYPE SMALLINT,
        QUIT_REASON SMALLINT,
        COLOR SMALLINT,
        NUA_TYPE SMALLINT,
        NEW_COD_X77_MESS SMALLINT,
        DATAWORD INTEGER,
        CANAL_NUMBER SMALLINT,
        CANALNUMBER_PER SMALLINT,
        POWER_LEVEL VARCHAR(2),
        USERID SMALLINT,
        OPERID SMALLINT,
        F_18_GUARDEDNOW SMALLINT,
        TAGPOINTID32 INTEGER,
        NON_TECH_SMS_COUNT SMALLINT,
        ADR_GUID_M4S VARCHAR(32),
        CHOP_NUM_M4S SMALLINT,
        DELTA_TIME_CHOP_M4S INTEGER)
    AS
     begin
        -- :messfilter_barr имеет вид '~dec1~dec2~dec3~' (например, '~20~45~17~')
        -- :messfilter_Lars имеет вид '~dec1~dec2~dec3~'
       for
       SELECT
             MESSAGE_ID
           , DMESSAGE
           , MESS_TYPE
           , NUA_TYPE
           , COLOR
           , NOMER
           , RAZDEL
           , USERID
           , OPERID
           , QUIT_DATE
           , QUIT_REASON
           , CANAL_NUMBER
           , CANALNUMBER_PER
           , POWER_LEVEL
           , DATAWORD
           , NEW_COD_X77_MESS
           , F_18_GUARDEDNOW
           , TAGPOINTID32
           , NON_TECH_SMS_COUNT
           , ADR_GUID_M4S
           , CHOP_NUM_M4S
           , DELTA_TIME_CHOP_M4S
       FROM MESS_LOG
       WHERE
            MESSAGE_ID>:ID_toLoadrfomExcluding
        AND MESSAGE_ID<=:ID_Max
        AND (
                     (nua_type!=78) -- !='N'
                 AND (nua_type!=85) -- !='U'
                 AND (nua_type!=65) -- !='A'
               OR
                     (nua_type=85 OR nua_type=65) -- ='U' OR ='A'
                 AND (:messfilter_Rest IS NULL OR :messfilter_Rest=1)
               OR
                 nua_type=78 -- ='N'
                 AND (mess_type!=92) -- != cNT_4p2_CMD_92_txt
                 AND (:messfilter_barr IS NULL OR :messfilter_barr CONTAINING '~'||mess_type||'~') -- ... OR '~20~45~17~'CONTAINING ~17~
               OR
                 nua_type=78 -- ='N'
                 AND (mess_type =92) -- =cNT_4p2_CMD_92_txt
                 AND (:messfilter_Lars is NULL or :messfilter_Lars containing '~'||typefor_clientfilter||'~')
            )
       ORDER BY MESSAGE_ID DESC
       into
            :MESSAGE_ID
           ,:DMESSAGE
           ,:MESS_TYPE
           ,:NUA_TYPE
           ,:COLOR
           ,:NOMER
           ,:RAZDEL
           ,:USERID
           ,:OPERID
           ,:QUIT_DATE
           ,:QUIT_REASON
           ,:CANAL_NUMBER
           ,:CANALNUMBER_PER
           ,:POWER_LEVEL
           ,:DATAWORD
           ,:NEW_COD_X77_MESS
           ,:F_18_GUARDEDNOW
           ,:TAGPOINTID32
           ,:NON_TECH_SMS_COUNT
           ,:ADR_GUID_M4S
           ,:CHOP_NUM_M4S
           ,:DELTA_TIME_CHOP_M4S
       do suspend;
     
     end
     

     все RETURN параметры - это поля из таблицы MESS_LOG. Записей в таблице очень много, поэтому хочется узнать, можно ли оптимизировать запрос.


    Собственно, интересует именно громоздкий момент условия

    Код:
        -- :messfilter_barr имеет вид '~dec1~dec2~dec3~...~' (например, '~20~45~17~')
        -- :messfilter_Lars имеет вид '~dec1~dec2~dec3~...~'
    ...
    ...
        AND (
                     (nua_type!=78) -- !='N'
                 AND (nua_type!=85) -- !='U'
                 AND (nua_type!=65) -- !='A'
               OR
                     (nua_type=85 OR nua_type=65) -- ='U' OR ='A'
                 AND (:messfilter_Rest IS NULL OR :messfilter_Rest=1)
               OR
                 nua_type=78 -- ='N'
                 AND (mess_type!=92) -- != cNT_4p2_CMD_92_txt
                 AND (:messfilter_barr IS NULL OR :messfilter_barr CONTAINING '~'||mess_type||'~') -- ... OR '~20~45~17~'CONTAINING ~17~
               OR
                 nua_type=78 -- ='N'
                 AND (mess_type =92) -- =cNT_4p2_CMD_92_txt
                 AND (:messfilter_Lars IS NULL OR :messfilter_Lars CONTAINING '~'||typefor_clientfilter||'~')
            )

    строки messfilter_barr и messfilter_Lars формируются программой и передаются как параметры процедуры. Они задают фильтрацию записей по полю mess_type


    сам не знаю, как запрос можно оптимизировать, но чувствую, что это возможно

    PS вложенные запросы тут, в FB1.5, не работают.
     
  • Учимся программировать :: Срочно пАмАгите!!!
  • В общем тема по теории автоматов:
    Задание такое:
    Есть автомат с газетами, газета стоит 15 рублей, автомат принимает только монеты по 10 и по 5 рублей. Если в автомат опускают 15 рублей, то он дает газету, а если дают 20 рублей, то автомат дает газету и сдачу 5 рублей.
    Помогите составить таблицу переходов, выхода и возбуждения, или хотя бы скажите как начать.  :confused:
  • Люди, подскажите, как быть. Мне надо сделать программу на Dev-cpp, но немного не понимаю как.

    Дана строка. Исключить из нее подстроку, расположенную между самой левой открывающейся скобкой «(» и самой правой закрывающейся скобкой «)». Сами скобки должны быть также исключены.

    Как сделать массив от '(' до ')' ?
    В общем, помогите кто чем может?
    Я начал
    Код: (c++)
    #include <string.h>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #define SIZE 255
    int main()
    {
        char s[SIZE], sn[SIZE], sk[SIZE];
        
        printf ("введите буквенные элементы строки перед, после и в самих скобках \n");
        scanf ("%s",s);
        for(int i=0; i<strlen(s); i++)
        {
    if(s[i]=='(');

    if (s[i]==')');
        
        }    
        
    getch();
    return 0;
        
    }

А теперь прощаемся с Вами до следующего выпуска.


С уважением, команда Клуба.


В избранное