"Why are pointers expected in structures?"
They are not. They are also not unexpected.
This construction is however:
struct {
    int age;
    char name[]; //just an array                <- A BOMB
    char gender; //just a character (M for male and F for female)
} person;
You here have an instance (person) of an anonymous struct with a flexible array. Old-school structs with this setup had their last member declared as type identifier[1];.
[1] was historically used because a zero element array has never been valid in standard C (although accepted as a language extension by some compilers).
The C99 standard made char name[] legal by allowing indexing such an array if it's made the last element in a struct. The name[] member in your struct is not.
The purpose of the flexible array was to let writing to such an array be legal to let the programmer (or a called function) pre-allocate memory and have functions return an unknown amount of elements by writing their result in that memory.
If your struct is accepted by a compiler, a funcion using it will overwrite gender when writing more than zero chars to name as an answer.
This would be a definition (and typedef) with the potential of being used properly:
typedef struct person_ {
    int age;
    char gender;
    struct person_ *next;  // points somewhere after the '\0' in name[] or NULL
    char name[];           // Pre C99 "char name[1];" was often seen
} person;                  // a typedef, not an instance here