Несоответствие типа указателя, предупреждающее в примере от K&R C [дубликат]

Ваша проблема в том, что каждый раз, когда вы делаете Person(need_player), вы создаете отдельный Person объект. Даже если вы используете тот же name, это не тот же объект, что и раньше, и у него будет отдельный список в качестве атрибута hand.

Чтобы избежать воссоздания ваших игроков снова и снова, вы должны создать их заранее и поместить их в список или словарь:

# up front, create the players (perhaps by prompting, but here hard-coded)
players = {"alice": Person("Alice"), "aob": Person("Bob")}

# later, you can look them up by name:
player_need = input("Which player needs a card?").lower()
players[player_need].get_add_card()
print(players[player_need]).hand)

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

7
задан Community 23 May 2017 в 12:31
поделиться

3 ответа

Хотя можно неявно бросить символ* к пустоте*, Вы не можете сделать того же для указателя функции с теми типами (без предупреждения). Компилятор более тщателен с соответствием типа на функциональных подписях.

Не говоря уже о том, что, что происходит внутри, qsort был бы противоположным: то есть, пустота* была бы брошена к символу* в numcmp и символе константы* в strcmp.

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

Например:

static int strcmp_wrapper(void* s1, void* s2) {
  return strcmp((char*)s1, (char*)s2);
}

static int numcmp_wrapper(void* n1, void* n2) {
  return numcmp((char*)n1, (char*)n2);
}

qsort((void **) lineptr, 0, nlines-1,
      (numeric ? numcmp_wrapper : strcmp_wrapper));

И современная подпись для qsort

void
qsort(void *base, size_t nel, size_t width,
      int (*compar)(const void *, const void *));

Проблема const кажется, не играет роли в Вашем вопросе, но K&R не имел const.

7
ответ дан 6 December 2019 в 23:13
поделиться

Один способ попытаться диагностировать его состоит в том, чтобы видеть то, что происходит, если Вы заменяете выражение?: со всего одним из двух.

Если это только происходит для strcmp и не numcmp, то это могло очень хорошо быть из-за константы char*. Я думаю, что, в то время как символ* может всегда преобразовываться в пустоту*, Вы не можете преобразовать символ константы* для освобождения* как "безопасно".

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

1
ответ дан 6 December 2019 в 23:13
поделиться

Короткий ответ: K&R не знал C.

Длинный ответ: Они были затруднены тем, что, когда они запустили, никто не знал C, таким образом, они были видом составления его, когда они продвинулись.

(Немного) меньше легкомысленной формы длинного ответа: язык развился (некоторые сказали бы измененный), вполне немного, так как K&R был записан, но если Вы не получили версию электронной книги с динамическим превращающимся примером, примеры в Вашей копии K&R не будут не отставать "новый и утвержденный" ("теперь еще с большим количеством ANSI!") язык.

3
ответ дан 6 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: