#include <stdio.h>
// определяем способы общения животных
void woof() {
printf("Woof woof! Bark!\n");
}
void meow() {
printf("Meow! Nya!\n");
}
// определяем собаку
typedef struct Dog {
char* name;
// в структуре нельзя определять функции,
// но можно определить
void (*say)(); // указатель на функцию
//void * say(); // вот так не получится, это будет определение функции,
// возвращающей указатель на void
} Dog;
// функция, возвращающая новую собаку с заданным именем
Dog createDog(char* name) {
Dog dog;
dog.name = name;
dog.say = &woof; // назначаем адрес функции собачьего лая
return dog;
}
int main(void) {
Dog dog = createDog("Sharik"); // создаем новую собаку с именем Шарик
dog.say(); // даем команду голос
dog.say = &meow; // а что если поменять команду?
dog.say(); // теперь собака мяукает!
dog.say = &woof; // возвращаем обратно
// а здесь просто пример работы с указателем на собаку...
Dog* dog_ptr = &dog; // создаем указатель на собаку
// находящуюся по адресу &dog
// даем команду голос...
//dog_ptr.say(); // не правильно! dog_ptr это всего лишь
// адрес собаки, а не сама собака
// сперва нужно получить собаку по
// адресу с помощью оператора *
//*dog_ptr.say(); // уже лучше, вот только компилятор
// сначала попытается поискать say в
// адресе, и только потом поймет, что
// по этому адресу нужно обратиться *
(*dog_ptr).say(); // вот теперь компилятор сначала получит
// собаку по адресу, т.к. скобки имеют
// более высокий приоритет,
// а затем найдет функцию say()
dog_ptr->say(); // эта запись эквивалентна предыдущей
return 0;
}