Указатели в C не работают должным образом

Я пытаюсь решить набор задач Гарварда CS50, и я застрял на очень простой жадной проблеме поиска наименьшего количества монет для заданной сдачи, если монеты доступны только в номиналах 25c, 10c, 5c и 1c. Хотя указатели на самом деле не нужны для этой проблемы, и даже наличие отдельной функции, вероятно, является излишним, я пытаюсь лучше понять указатели, реализовав их здесь, однако я не получаю желаемого результата для «монет». по какой-то причине. Операторы printf после вызовов функций до и после предназначены для целей отладки. Пример вывода приведен после кода.

Вот код:

#include <stdio.h>
#include <cs50.h>

void denomination(float* change, int* coins, int den);

int main(void){

    float change;
    do{
        printf("How much change is owed?\n");
        change = GetFloat();
    }while(change < 0);

    int coins; //number of coins in total to be given in change

    if(change == 0){
        coins = 0;
        printf("%d\n", coins);
    }else{
        change = change * 100; //converting to cents
        denomination(&change, &coins, 25);
        printf("Inside else:: Change: %f, Coins: %d\n", change, coins);
        denomination(&change, &coins, 10);
        printf("Inside else:: Change: %f, Coins: %d\n", change, coins);
        denomination(&change, &coins, 5);
        printf("Inside else:: Change: %f, Coins: %d\n", change, coins);
        denomination(&change, &coins, 1);
        printf("Inside else:: Change: %f, Coins: %d\n", change, coins);
        printf("%d\n", coins);
    }
    return 0;
}

void denomination(float* change, int* coins, int den){
    int tmp; 
    tmp = (*change/den);
    printf("Temp: %d\n", tmp);
    *coins = *coins + tmp;
    *change = *change - (tmp*den);
}

Вот результат:

How much change is owed?
0.41
Temp: 1
Inside else:: Change: 16.000000, Coins: 134516108
Temp: 1
Inside else:: Change: 6.000000, Coins: 134516109
Temp: 1
Inside else:: Change: 1.000000, Coins: 134516110
Temp: 1
Inside else:: Change: 0.000000, Coins: 134516111
134516111

Я не понимаю, почему «сдача» работает так, как хотелось бы, а «монеты» — нет.


person user2278764    schedule 17.09.2014    source источник
comment
Каково начальное значение coins?   -  person n. 1.8e9-where's-my-share m.    schedule 17.09.2014
comment
Я заметил, что change = GetFloat();; содержит две точки с запятой, я знаю, что это не проблема и вполне приемлемо, но, вероятно, не предназначено для удобочитаемости.   -  person jacob    schedule 17.09.2014
comment
В вашем предложении else инициализируйте монеты до 0, прежде чем вы начнете их использовать. И FWIW, я бы сделал первый параметр change целым, так как вы все равно считаете целочисленные значения (центы). Это позволяет избежать некоторых проблем, с которыми вы можете столкнуться при работе с плавающей запятой.   -  person Rudy Velthuis    schedule 17.09.2014


Ответы (3)


Сначала удалите цикл while в функции.

void denomination(float* change, int* coins, int den)
{
    int tmp;
    tmp = (*change/den);
    printf("Temp: %d\n", tmp);
    *coins = *coins + tmp;
    *change = *change - (tmp*den);
}

Потому что вы уже делите, поэтому получаете общее количество монет только за один раз.

Итак, прежде всего, нет необходимости в петле.

Затем вместо удаления только одного ден вы должны удалить общую сумму, которая будет кратна монетам tmp, которые будут предоставлены.

Итак, исправлено следующее утверждение в вашей функции.

*change=(*change-(tmp*den));

Во-вторых, инициализируйте переменную монет.

Как я думаю, это дает некоторую ценность мусора.

Поэтому инициализируйте его нулем в main.

int Coins=0;
person Nirav Kamani    schedule 17.09.2014
comment
Зачем мне удалять цикл while в функции? Если переданная сдача составляет 52 цента, а ден — 25, то она должна пройти дважды, чтобы получить 2 монеты номиналом 25 центов. - person user2278764; 17.09.2014
comment
Ах я вижу. Понятно. Спасибо! - person user2278764; 17.09.2014
comment
Вы получаете общее количество монет, используя оператор tmp = (*change/den); что идеально, поэтому нет необходимости использовать цикл. - person Nirav Kamani; 17.09.2014
comment
Пожалуйста, удалите цикл и исправьте код, как я указал. Пожалуйста, напишите свой ответ в комментарии, удалили ли вы цикл или нет? так как это поможет и другим. - person Nirav Kamani; 17.09.2014
comment
Я удалил цикл и внес другие изменения, которые вы предложили. Программа работает сейчас. Спасибо - person user2278764; 18.09.2014

Цикл while должен быть оставлен с ненулевым значением change (по мере достижения ветви else), но coins инициализируется только в ветви if выше. В целом поведение неопределенное.

person Codor    schedule 17.09.2014

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

person Hillel    schedule 17.09.2014