Ваша проблема в том, что каждый раз, когда вы делаете 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)
Вам, вероятно, понадобится больше логики, чтобы избежать ошибок, если Пользователь вводит неизвестное имя, но это должно дать вам общее представление.
Хотя можно неявно бросить символ* к пустоте*, Вы не можете сделать того же для указателя функции с теми типами (без предупреждения). Компилятор более тщателен с соответствием типа на функциональных подписях.
Не говоря уже о том, что, что происходит внутри, 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
.
Один способ попытаться диагностировать его состоит в том, чтобы видеть то, что происходит, если Вы заменяете выражение?: со всего одним из двух.
Если это только происходит для strcmp и не numcmp, то это могло очень хорошо быть из-за константы char*. Я думаю, что, в то время как символ* может всегда преобразовываться в пустоту*, Вы не можете преобразовать символ константы* для освобождения* как "безопасно".
Если это с обоими, то, возможно, это о некоторой проблеме с указателями функции, где, имея символ* преобразованный в пустоту* работы, но подписи должны быть идентичными и имеющими пустотами вместо символов, являются проблемой.
Короткий ответ: K&R не знал C.
Длинный ответ: Они были затруднены тем, что, когда они запустили, никто не знал C, таким образом, они были видом составления его, когда они продвинулись.
(Немного) меньше легкомысленной формы длинного ответа: язык развился (некоторые сказали бы измененный), вполне немного, так как K&R был записан, но если Вы не получили версию электронной книги с динамическим превращающимся примером, примеры в Вашей копии K&R не будут не отставать "новый и утвержденный" ("теперь еще с большим количеством ANSI!") язык.