Intereting Posts
Реализация перенаправления ввода / вывода в оболочке Linux с использованием C Что не так с моим набором символов (Win32 API) Есть ли ограничение на стек памяти? Вызов метода Rust из C с параметрами массива Как скомпилировать дополнительные исходные файлы в cmake после процесса сборки код производителя производителя необработанных ошибок linux debug В C, почему «подписанный int» быстрее, чем «unsigned int»? Преобразование строкового массива в шестнадцатеричные числа в C предотrotation закрытия файла exe Эмуляция переменной бит-сдвига с использованием только постоянных сдвигов? C: окончательная правда о rand, random и arc4random Печать дочерних процессов с помощью pid (MINIX) Почему стандарт C оставляет неопределенные переменные неопределенными? порядок SIGCONT и SIGHUP отправлен в группу процессов осиротевших linux Как разгрузить конкретный stream одного приложения в определенные ядра Xeon Phi?

Почему мы используем указатели для объектов, а не только значение объекта напрямую?

Я смущен, почему в этом учебном курсе они используют Node *next вместо того, чтобы просто создавать Node node типа Node node . Почему это? То же самое с другими объектами, такими как char *string .

Я понимаю, что указатели – это переменные, которые содержат адрес, поэтому они содержат адреса, значение которых является Node или char , правильно? Но зачем держать их адрес, а не просто писать им напрямую?

Следующий код полностью прав, верно?

 typedef struct { int health; } Boss; Boss bigBoss; bigBoss.health = 40; Boss newBoss; newBoss.health = 100; bigBoss = newBoss; 

Почему это не традиционный способ? В чем преимущество указателя?

Для обновления памяти

Ваше задание копирует контент из структуры, но есть еще две различные структуры:

 #include typedef struct { int health; } Boss; int main() { Boss bigBoss; bigBoss.health = 40; Boss newBoss; newBoss.health = 100; bigBoss = newBoss; bigBoss.health = 1; newBoss.health = 2; printf("%d %d\n", bigBoss.health, newBoss.health); } 
 1 2 

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

 #include typedef struct { int health; } Boss; void fail_attack( Boss boss ) { boss.health -= 10; } void succeed_attack( Boss *boss ) { boss->health -= 10; } int main() { Boss bigBoss; bigBoss.health = 40; fail_attack( bigBoss ); printf( "after fail_attack, health: %d\n", bigBoss.health ); succeed_attack( &bigBoss ); printf( "after succeed_attack, after succeed_attack, health: %d\n", bigBoss.health ); } 
 after fail_attack, health: 40 after succeed_attack, health: 30 

Чтобы уменьшить стоимость передачи параметров

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

Для самореферентных типов

Экземпляр структуры – это просто блок памяти, заполненный полями, объявленными в структуре. Насколько велика капля памяти? Ну, он должен быть, по крайней мере, достаточно большим, чтобы держать поля и, возможно, немного больше для выравнивания памяти. Некоторые структуры данных, содержащие ссылки на другие экземпляры одной и той же структуры данных (например, связанные списки и деревья, являются одними из самых ранних обнаруженных структур данных). Насколько велик узел связанного списка, чтобы удерживать элемент и следующий узел? Ну, размер (узел) = размер (элемент) + размер (узел). Это явно не сработает. С другой стороны, указатель представляет собой фиксированный размер, поэтому мы можем иметь узел, который имеет элемент и указатель на другой узел.