Я пишу программу, которая показывает разницу в процентах для доходов мобильной компании

#c

#c

Вопрос:

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

 Enter Revenue for 2017: 100000 
Enter Revenue for 2018: 250000
Enter Revenue for 2018: 150000 
Enter Revenue for 2018: 150000 

Year % Remark
 Increase 150 2018 
Decrease 40- 2019 
 Unchange" 0,0 2020
  
 #include <stdio.h>

int main() {
    printf("--------------------------------------------------n ");
    printf("Mobile Company Revenue Percentagen ");
    printf("--------------------------------------------------n ");
      int  i;
    float Revenue[4], sum = 0.0, avg;
    float rev1,rev2,rev3,rev4;
    printf("Enter Revenue for 2017: ");
        scanf("%f", amp;rev1);
    printf("Enter Revenue for 2018: ");
        scanf("%f", amp;rev2);
    printf("Enter Revenue for 2018: ");
        scanf("%f", amp;rev3);
    printf("Enter Revenue for 2018: ");
    scanf("%f", amp;rev4);

     

    for (i = 0; i < 5;   i) {
        sum  = Revenue[i];
    }

    avg = sum / sizeof(Revenue);
    printf("Average = %.2f", avg);
    return 0;
}
  

Комментарии:

1. for (i = 0; i < 4; i) ошибка по одному. Допустимые индексы для Revenue 0 сквозные 3 , нет 4 . Кроме того, все элементы Revenue неинициализированы и попытка доступа к ним sum = Revenue[i]; вызывает неопределенное поведение . Всегда инициализируйте свои массивы, например float Revenue[4] = {0}; . Вы не можете правильно использовать какую-либо функцию ввода без проверки возврата . В противном случае у вас нет возможности узнать, был ли ввод успешным или неудачным. avg Требуется sum / (sizeof Revenue / sizeof *Revenue ). Почему sizeof Revenue == 20

2. Пришло время узнать о массивах и for циклах. Вы почти используете их здесь, но, похоже, вы пропустили и вместо этого объявили кучу несвязанных переменных.

3. Вам нужно задать конкретный вопрос. Какая конкретная проблема у вас есть, которая мешает вам продвигать код?

4. Прежде всего, float это небезопасно, поскольку это приводит к снижению производительности и является менее точным, чем double .

Ответ №1:

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

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

     int  nelem = sizeof Revenue/sizeof *Revenue;
  

(примечание: правильный тип будет size_t , но C int также допускает возврат)

Установив количество элементов, вы можете выполнить цикл соответствующее количество раз и вычислить среднее значение с соответствующим делителем, например

     for (i = 0; i < nelem; i  )
        sum  = Revenue[i];
    avg = sum / nelem;
    
    printf ("nAverage = %.2fn", avg);
  

Теперь давайте посмотрим на входные данные. Вы не сможете правильно использовать любую функцию пользовательского ввода, если не проверите возврат. В противном случае у вас нет способа определить, был ли ввод успешным или неудачным. Кроме того, для пользователя вполне допустимо отменить ввод, создав руководство EOF Ctrl dили Ctrl zв Windows). Поэтому вы должны справиться с этим случаем. Вам также необходимо удалить 'n' left в stdin by scanf() на случай, если следующий ввод в вашей программе будет с функцией ввода, которая не отбрасывает начальные пробелы.

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

 /* display prompt and return float (exit on manual EOF) */
float getfloat (const char *prompt)
{
    float f = 0;
    
    while (1) {     /* loop continually until valid float provided by user */
        if (prompt)                             /* prompt if not NULL */
            fputs (prompt, stdout);
        int rtn = scanf ("%f", amp;f);             /* read float, save return */
        if (rtn == EOF) {                       /* check for manual EOF */
            puts ("(user canceled input)");
            exit (EXIT_SUCCESS);
        }
        empty_stdin();                          /* empty to end of line */
        if (rtn == 1)                           /* if good input, break loop */
            break;
        
        fputs ("  error: invalid float input.n", stderr);  /* handle error */
    }
    
    return f;       /* return float value */
}
  

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

empty_stdin() Вспомогательная функция, вызванная getfloat() выше, просто отбрасывает любые посторонние символы stdin до следующего 'n' или EOF в зависимости от того, что произойдет раньше. Таким образом, если пользователь вводит что-то вроде "Lots of money" вместо действительной суммы, это удаляется stdin до вашей следующей попытки ввода. Ничего больше не требуется, чем:

 /* simple helper to clear stdin */
void empty_stdin (void)
{
    int c = getchar();
    
    while (c != 'n' amp;amp; c != EOF)
        c = getchar();
}
  

Теперь ваша main() функция сводится к фрагменту читаемого кода, который позволяет получить четыре float значения и вычислить среднее значение, например

 int main (void) {
    
    float Revenue[4] = {0}, sum = 0.0, avg = 0;
    int  i, nelem = sizeof Revenue/sizeof *Revenue;
    
    puts ("--------------------------------------------------n"
          "Mobile Company Revenue Percentagen"
          "--------------------------------------------------n ");
    
    Revenue[0] = getfloat ("Enter Revenue for 2017: ");
    Revenue[1] = getfloat ("Enter Revenue for 2018: ");
    Revenue[2] = getfloat ("Enter Revenue for 2019: ");
    Revenue[3] = getfloat ("Enter Revenue for 2020: ");

    for (i = 0; i < nelem; i  )
        sum  = Revenue[i];
    avg = sum / nelem;
    
    printf ("nAverage = %.2fn", avg);
}
  

(Я составил годы с тех пор, как вы 2018 указали 3 из 4 лет)

Вам нужен только один вызов функции вывода, чтобы вывести столько строк, сколько вам нужно. Если не требуется преобразование (например "%f" , и т. Д.), То Нет необходимости использовать функцию variadic printf() . Просто используйте puts() (или fputs() , если вам нужен конечный контроль.

Пример использования / вывода

 $ ./bin/mobileco
--------------------------------------------------
Mobile Company Revenue Percentage
--------------------------------------------------

Enter Revenue for 2017: 100
Enter Revenue for 2018: 200
Enter Revenue for 2019: 300
Enter Revenue for 2020: 400

Average = 250.00
  

Если пользователь вводит неверный ввод, программа не примет его, например:

 $ ./bin/mobileco
--------------------------------------------------
Mobile Company Revenue Percentage
--------------------------------------------------

Enter Revenue for 2017: A whole lot of $Money$ :)
  error: invalid float input.
Enter Revenue for 2017: 100
Enter Revenue for 2018: 200
Enter Revenue for 2019: three-hundred
  error: invalid float input.
Enter Revenue for 2019: 300
Enter Revenue for 2020: 400

Average = 250.00
  

Вычисление процента — изменение дохода между годами

В ответ на ваш комментарий ниже, вы можете вычислить процентное увеличение или процентное уменьшение от среднего дохода, используя формулу процентного изменения. Для вычисления значения у вас есть original new значение и. При вычислении изменения от среднего значения ваше original значение является средним, а new значение — доходом за год. Вам нужно применить либо формулу увеличения в процентах, если доход превышает средний, либо формулу уменьшения в процентах, если доход ниже среднего.

Формулы для увеличения и уменьшения процентов следующие:

 pct_increase = (new - original) / original * 100;
  

и

 pct_decrease = (original - new) / original * 100;
  

Вы можете просто создать функцию изменения процента и проверить original значения new и, применить правильную формулу и вернуть это значение. Например:

 /* percent change between new_value and orig_value */
float percentchg (const float new_value, const float orig_value)
{
    if (new_value < orig_value)
        return (orig_value - new_value) / orig_value * 100.;
    
    return (new_value - orig_value) / orig_value * 100.;
}
  

(примечание: поскольку new это ключевое слово C , лучше избегать его использования в вашем коде, на случай, если ваш код будет включен позже как часть программы на C , хотя есть способы заставить его работать)

Затем, main() чтобы вычислить процентное изменение за каждый год, вы должны сделать:

     ...
    printf ("nAverage = %.2fnn", avg);
    
    for (i = 0; i < nelem; i  )
        printf ("year %d revenue: %.2f%% (%s) from averagen", i   1,
                percentchg (Revenue[i], avg),
                Revenue[i] < avg ? "decrease" : "increase");
  

(примечание: троичный используется для определения того, выводить "decrease" или "increase" как часть вывода. Троичный — это всего лишь короткая рука if (condition) { if_true } else { if_false } , для которой синтаксис:

 condition ? if_true : if_false
  

который вы можете видеть включенным в качестве параметра printf() функции, предоставляющей входные данные для спецификатора "%s" формата)

Новый пример вывода

 $ ./bin/mobileco
--------------------------------------------------
Mobile Company Revenue Percentage
--------------------------------------------------

Enter Revenue for 2017: 100
Enter Revenue for 2018: 200
Enter Revenue for 2019: 300
Enter Revenue for 2020: 400

Average = 250.00

year 1 revenue: 60.00% (decrease) from average
year 2 revenue: 20.00% (decrease) from average
year 3 revenue: 20.00% (increase) from average
year 4 revenue: 60.00% (increase) from average
  

Полный код

Если бы вы помогли увидеть код compete после обновления, то есть:

 #include <stdio.h>
#include <stdlib.h>

/* simple helper to clear stdin */
void empty_stdin (void)
{
    int c = getchar();
    
    while (c != 'n' amp;amp; c != EOF)
        c = getchar();
}

/* display prompt and return float (exit on manual EOF) */
float getfloat (const char *prompt)
{
    float f = 0;
    
    while (1) {     /* loop continually until valid float provided by user */
        if (prompt)                             /* prompt if not NULL */
            fputs (prompt, stdout);
        int rtn = scanf ("%f", amp;f);             /* read float, save return */
        if (rtn == EOF) {                       /* check for manual EOF */
            puts ("(user canceled input)");
            exit (EXIT_SUCCESS);
        }
        empty_stdin();                          /* empty to end of line */
        if (rtn == 1)                           /* if good input, break loop */
            break;
        
        fputs ("  error: invalid float input.n", stderr);  /* handle error */
    }
    
    return f;       /* return float value */
}

/* percent change between new_value and orig_value */
float percentchg (const float new_value, const float orig_value)
{
    if (new_value < orig_value)
        return (orig_value - new_value) / orig_value * 100.;
    
    return (new_value - orig_value) / orig_value * 100.;
}

int main (void) {
    
    float Revenue[4] = {0}, sum = 0.0, avg = 0;
    int  i, nelem = sizeof Revenue/sizeof *Revenue;
    
    puts ("--------------------------------------------------n"
          "Mobile Company Revenue Percentagen"
          "--------------------------------------------------n ");
    
    Revenue[0] = getfloat ("Enter Revenue for 2017: ");
    Revenue[1] = getfloat ("Enter Revenue for 2018: ");
    Revenue[2] = getfloat ("Enter Revenue for 2019: ");
    Revenue[3] = getfloat ("Enter Revenue for 2020: ");

    for (i = 0; i < nelem; i  )
        sum  = Revenue[i];
    avg = sum / nelem;
    
    printf ("nAverage = %.2fnn", avg);
    
    for (i = 0; i < nelem; i  )
        printf ("year %d revenue: %.2f%% (%s) from averagen", i   1,
                percentchg (Revenue[i], avg),
                Revenue[i] < avg ? "decrease" : "increase");
}
  

Просмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.

Комментарии:

1. спасибо, как показать разницу в процентах для доходов мобильной компании??

2. Из-за того, что вы имеете в виду за каждый год, например, между 2017-2018, а затем 2018-2019 и т. Д.? То есть, как только у вас будет среднее значение, вы захотите узнать разницу в процентах за каждый год?

3. @Fedaa — Я обновил ответ, чтобы включить вычисления изменения процента.