Skip to main content
LibreTexts - Ukrayinska

2.2: Програма

  • Page ID
    30542
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)

    Ось (перша спроба) специфікація для програми:

    Програма запропонує користувачеві значення джерела напруги постійного струму, номінальне значення резистора та допуск резистора. Потім він роздрукує значення струму і розсіювання потужності на основі номінальних, мінімальних і максимально прийнятних значень резистора.

    Непогано, але нам потрібно його доопрацювати. По-перше, програми командного рядка зазвичай потребують певної форми повідомлення про запуск або роздрукувати з напрямків. Пам'ятайте, що це не керовані GUI програми з меню «Довідка». По-друге, завжди запитувати вхідні значення із зазначенням очікуваних одиниць. Якщо програма очікує Ом, але користувач вводить в кілоом ом, там буде проблема. Якщо немає вагомих причин цього не робити, завжди використовуйте базові одиниці (наприклад, ом проти кілоом ом).

    Ось наша вишукана специфікація:

    Програма спочатку дасть користувачеві відповідні напрями/пояснення використання. Програма запропонує користувачеві значення джерела напруги постійного струму в вольтах, номінальне значення резистора в Омах і допуск резистора у відсотках. Потім він роздрукує значення струму в амперах і розсіювання потужності у ватах на основі номінальних, мінімальних і максимально прийнятних значень резистора.

    Зауважте, що ми вказали допуск у відсотках, а не як фактор. Це пов'язано з тим, що типовий користувач буде готовий ввести 10 для 10%, а не 0,1. Ви можете використовувати цю специфікацію для створення псевдокоду або блок-схеми. Ось можливий псевдокод:

    1. Роздрукуйте вказівки для користувача.

    2. Підкажіть користувачеві напругу (в вольтах) і отримайте значення.

    3. Підкажіть користувачеві опір (в Омах) і отримайте значення.

    4. Підкажіть користувачеві толерантність (у відсотках) та отримайте значення.

    5. Визначте максимальне і мінімальне значення опору.

    6. Обчисліть струми виходячи з трьох опорів.

    7. Розрахуйте потужності, виходячи з трьох опорів.

    8. Вивести заголовок для значень.

    9. Роздрукуйте значення.

    Звичайно, ви можете вибрати альтернативний алгоритм або метод рішення. Наприклад, ви можете надрукувати заголовок перед розрахунками, а потім вивести значення після кожного розрахунку. Ви можете віддати перевагу змінити формат так, щоб ви отримували рядки для кожного резистора, а не для струму та потужності. Ви навіть можете вибрати зовсім інший підхід, використовуючи цикли та/або масиви. У кожному підході будуть плюси і мінуси. Найчастіше питання не «Чи можна вирішити цю проблему?» а скоріше «Який найефективніший спосіб вирішення цієї проблеми?» Розширте трохи передбачливості, перш ніж почати кодування.

    Виходячи з вищевказаного псевдо коду, під рахунок повинна відповідати наступна програма. Його ми уточнимо пізніше. Зверніть увагу на використання double, оскільки ми, швидше за все, матимемо дробові значення, з якими слід мати справу.

    #include <stdio.h>
    
    int main( void )
    {
          double v, tol;
          double rnom, rlow, rhigh;
          double inom, ilow, ihigh;
          double pnom, plow, phigh;
    
          printf(“This program determines current and power.\n”);
    
          printf(“Please enter the voltage source in volts.\n”);
          scanf(“%lf”, &v);
          printf(“Please enter the nominal resistance in ohms.\n”);
          scanf(“%lf”, &rnom);   
          printf(“Please enter the resistor tolerance in percent.\n”);
          scanf(“%lf”, &tol);    
    
          tol = tol/100.0;  /* turn tolerance into a factor */
          rlow = rnom – rnom*tol;
          rhigh = rnom + rnom*tol;
          inom = v/rnom;
          ihigh = v/rlow;
          ilow = v/rhigh;
    
          pnom = v * inom;
          plow = v * ilow;
          phigh = v * ihigh;
    
          printf(“Resistance (ohms)  Current (amps)  Power (watts)\n”);
          printf(“%lf     %lf      %lf\n”, rnom, inom, pnom );
          printf(“%lf     %lf      %lf\n”, rhigh, ilow, plow );
          printf(“%lf     %lf      %lf\n”, rlow, ihigh, phigh );
    }
    

    Застереження тут: Зверніть увагу, що змінна ihigh - це найвищий струм, а не струм, пов'язаний з найвищим резистором. Це може зробити роздрукований код здаватися неправильним. Це гарне місце для деяких коментарів! Також початкові «напрямки» в кращому випадку є скупими. У будь-якому випадку, введіть і створіть код вище і переконайтеся, що він працює.

    Можливо, ви помітили, що в цьому коді є трохи повторення у вигляді розрахунків і роздруківок. Це може бути зручніше, якщо ми створили функції для їх обробки. Наприклад, ми могли б створити функцію для обчислення струму:

    double find_current( double voltage, double resistance )
    {
          double current;
    
          current = voltage/resistance;
          return( current );
    }
    

    Ви також можете зробити це за один крок:

    double find_current( double voltage, double resistance )
    {
          return( voltage/resistance );
    }
    

    Оновлення програми виробляє наступне:

    #include <stdio.h>
    
    double find_current( double voltage, double resistance )
    {
          return( voltage/resistance );
    }
    
    int main( void )
    {
          double v, tol;
          double rnom, rlow, rhigh;
          double inom, ilow, ihigh;
          double pnom, plow, phigh;
    
          printf(“This program determines current and power.\n”);
    
          printf(“Please enter the voltage source in volts.\n”);
          scanf(“%lf”, &v);
          printf(“Please enter the nominal resistance in ohms.\n”);
          scanf(“%lf”, &rnom);   
          printf(“Please enter the resistor tolerance in percent.\n”);
          scanf(“%lf”, &tol);    
    
          tol = tol/100.0;  /* turn tolerance into a factor */
          rlow = rnom – rnom*tol;
          rhigh = rnom + rnom*tol;
    
          inom = find_current( v, rnom );
          ihigh = find_current( v, rlow );
          ilow = find_current( v, rhigh );
    
          pnom = v * inom;
          plow = v * ilow;
          phigh = v * ihigh;
    
          printf(“Resistance (ohms)  Current (amps)  Power (watts)\n”);
          printf(“%lf     %lf      %lf\n”, rnom, inom, pnom );
          printf(“%lf     %lf      %lf\n”, rhigh, ilow, plow );
          printf(“%lf     %lf      %lf\n”, rlow, ihigh, phigh );
    }
    

    Це, здається, не є значним поліпшенням. Насправді, це просто здається довшим! Це правда, але продовжити ідею на мить. Що робити, якщо в обчисленні для струму задіяний десяток рядків коду замість одного? Цей новий формат заощадить значний простір коду. Зверніть увагу, що це не просто питання збереження деякого набору тексту, а скоріше в економії пам'яті, використовуваної виконуваним файлом. Це особливо важливо при використанні обмежених вбудованих систем з лише невеликим обсягом доступної пам'яті.

    Зауважте, що нова функція була додана перед main (). Цього не потрібно. Ми також могли б додати його після main (), але в цьому випадку нам доведеться додати прототип функції, щоб компілятор знав, чого очікувати, коли він побачив виклик функції в main (). Це виглядало б приблизно так:

    #include <stdio.h>
    
    /* this is the prototype so the compiler can do type checking */
    
    double find_current( double voltage, double resistance );
    
    int main( void )
    {
          ....
    }
    
    double find_current( double voltage, double resistance )
    {
          return( voltage/resistance );
    }
    

    Змініть програму, щоб використовувати цю нову поточну функцію обчислення та протестувати її. Як тільки це буде завершено, змініть програму ще раз, щоб використовувати функцію для обчислення потужності, а інший, щоб роздрукувати три значення. Використовуйте поточну функцію обчислення як орієнтир. Перевірте це при наступних значеннях: джерело 12 вольт з 100 Ом, 5% резистор. Нарешті, розглянемо, що може піти не так з програмою. Що буде, якби ми користувач ввів 0 для значення резистора? Як ви могли обійти цю проблему?