простая программа для внесения изменений на C; Не понимаю инициализацию

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

Программа предназначена для подсказки кассиру цены, выставленной суммы, расчета сдачи и сообщения кассиру, сколько каждой купюры / монеты нужно вернуть. Код от void main(void) до change=round был предоставлен моим инструктором. Я понимаю, что именно так я должен превратить двойное число в целое. Потребовалось много времени, чтобы понять, что lf — единственный формат, который будет работать для моих сканов, и мой инструктор специально попросил использовать множество определений.

Когда программа запускается, она успешно запрашивает цену и уплаченную сумму, но сдача всегда выводится на -2 147 483 648 (что, как я знаю, является наименьшим значением для целого числа). Однако я не знаю, почему он выбирает именно это значение. Математика для сдачи = раунда, где рассчитывается платно-стоимость, была предоставлена ​​моим инструктором, и я не играл с ней.

Кроме того, мой компилятор выдает мне предупреждение «_____ используется неинициализированным для этой функции» для «двадцатых, десятков, пятерок» и т. д., перечисленных в //Списке изменений. Я думал, что инициализировал их, когда перечислил их как int вверху? То, как мой инструктор до сих пор описывал вещи, казалось мне немного эзотерическим, поэтому я уверен, что просто упускаю что-то очень простое. Любые объяснения разницы между int и int* или почему %f не будет работать там, где я с тех пор указал %lf, также будут очень признательны, поскольку они были для меня предыдущими головными болями, и вознаграждены бонусными интернет-баллами.

Заранее спасибо. Надеюсь, я правильно отформатировал.

#include <stdio.h>
#define TWENTY 2000
#define TEN 1000
#define FIVE 500
#define SINGLE 100
#define QUARTER 25
#define DIME 10
#define NICKEL 5
#define PENNY 1


    void main(void)
{
    int round(double num)
        {
        return (int) (num + 0.5);
        }
    int  change, // to be paid, in cents
         twenties, tens, fives, singles, quarters, dimes, nickels, pennies;    
                 //bills and coins used 
    double cost, // item cost, in dollars and cents
           paid; // amount paid, in dollars and cents

        change = round((paid - cost) * 100.0);


//Ask for cost
printf("Enter amount cost ($): ");
scanf("%lf", &cost);

//Ask for amount paid
printf("Enter amount tendered ($): ");
scanf("%lf", &paid);

//Change list
printf("Change is: %d\n", change);
printf("$20 bills: %d\n", twenties);
printf("$10 bills: %d\n", tens);
printf("$5 bills: %d\n", fives);
printf("$1 bills: %d\n", singles);
printf("Quarters: %d\n", quarters);
printf("Dimes: %d\n", dimes);
printf("Nickels: %d\n", nickels);
printf("Pennies: %d\n", pennies);

//Calculations
twenties = (change / TWENTY);
change = (change % TWENTY);
tens = (change / TEN);
change = (change % TEN);
fives = (change / FIVE);
change = (change % FIVE);
singles = (change / SINGLE);
change = (change % SINGLE);

}

person Keapora    schedule 08.03.2015    source источник
comment
Это, безусловно, самый неправильный код с отступом, который я когда-либо видел. Вам действительно удалось взять каждую строку и поместить ее в неправильный отступ, это замечательно!   -  person barak manos    schedule 08.03.2015
comment
C&P, скомпилировал и у меня заработало. Вы что-то изменили при публикации? Вы компилируете в Linux или Windows? (Ну, "сработало", результаты не очень)   -  person Btc Sources    schedule 08.03.2015
comment
@barakmanos LOL отлично. Я всегда знал, что я исключительный... :'^) Спасибо за предупреждение.   -  person Keapora    schedule 09.03.2015
comment
@BtcSources Я ничего не менял, но я так долго возился с этим, я думаю, что написал, что не будет работать, думая, что все еще есть серьезные ошибки. И я компилирую в Windows. Если я не могу этого сделать, мне, вероятно, не стоит трогать Linux ;) Спасибо за проверку.   -  person Keapora    schedule 09.03.2015
comment
Инструктор должен быть расстрелян за использование void main(void) , а вложенная функция int round(double num) не компилируется в стандартном C. Вы должны распечатать результаты после того, как вы их вычислили, а не раньше.   -  person Jonathan Leffler    schedule 09.03.2015


Ответы (1)


Основная проблема заключается в том, что вы действительно печатаете неинициализированные переменные:

// Here they are:
int  change, twenties, tens, fives, singles, quarters, dimes, nickels, pennies;

// Then you print it out, still unitialized:
printf("$20 bills: %d\n", twenties);

// Then you give it a value
twenties = (change / TWENTY);

Операторы внутри блока происходят в том же порядке, что и операторы. Присваивание представляет собой немедленный расчет; это не установка формулы для будущего (или прошлого) применения.

Чтобы исправить это, вам нужно переместить все операторы присваивания (twenties = и т. д.) до операторов printf.

Вы делаете ту же ошибку с change. Сначала вы пишете:

// here "paid" and "cost" are uninitialized
change = round((paid - cost) * 100.0);

а затем вы даете им значения:

// too late, horse has bolted
scanf("%lf", &cost);
scanf("%lf", &paid);

Суммы должны быть введены до расчета сдачи. Что должно быть до того, как монеты будут рассчитаны из сдачи.

Еще одна вещь заключается в том, что функция round должна быть перемещена до начала main(). В стандарте C запрещено иметь вложенные определения функций.

person M.M    schedule 08.03.2015
comment
БЛАГОДАРЮ ВАС. Да, я думал, что это будет очень просто. Теперь, когда вы объясняете это таким образом, это имеет полный смысл. После перестановки работает отлично. Большое спасибо за вашу помощь. - person Keapora; 09.03.2015