struct lista{
struct osoba_t {
char *nazwisko;
char *imie[5];
};
int numer;
osoba_t uczen[20];
osoba_t nauczyciel[5];
} klasa;
Po prostu użyłem twojej struktury z nazwiskiem i imieniem do stworzenie dodatkowej tablicy `nauczyciel`. Tablica jets konwertowalna na wskaźnik, więc można napisać `(klasa.nauczyciel+4)->nazwisko;` To co do punktu b).
Co do punktu e): funkcji składowych w języku C nie można tworzyć, więc pewnie chodziło o wskaźnik do funkcji. Wyglądałoby to tak:
struct lista{
//...
typedef size_t(*fptr_t)(const char*); // alias dla typu wskaznika na funkcje zwracającą size_t i przyjmującą jeden arg. typu const char*
fptr_t strlen;
} klasa;
klasa.strlen = &strlen;
size_t oraz const char* bo taką sygnature ma `strlen` z C stdlib.
Oraz jak można przypisać tym polom wartości poza zwykłym przypisaniem typu: klasa.uczen[1].nazwisko = "nowak"; ?
Generalnie ja bym zrobił tak, żeby `imie` i `nazwisko` nie były wskaźnikami, ale tablicami o jakiejś tam wystarczającej długości. Wtedy możesz sobie do nich przekopiowywać używając najlepiej strcpy. Jak ja to widze:
#define MAX_LEN 100
struct lista{
struct osoba_t {
char nazwisko[MAX_LEN];
char imie[5][MAX_LEN];
};
int numer;
osoba_t uczen[20];
osoba_t nauczyciel[5];
} klasa;
strcpy(klasa.uczen[4].imie[2], "whatever");
Note:
Pamiętaj, że w przypadku gdy `nazwisko` jest typu char*, to przypisanie w stylu klasa.uczen[0].nazwisko = "blahblah"; nie kopiuje stringa, tylko przypisuje do wskaźnika `nazwisko` adres do stringa "blahblah" który znajduje się w pamięci readonly. Więc dla bezpieczeństwa najlepiej, żeby nazwisko wtedy było typu const char*. Dlatego IMO rozwiązanie z tablicami i strcpy jest lepsze. No i pewnie może posłużyć jako ten alternatywny sposób przypisania o który pytałaś.
Wybacz, że tyle gotowego kodu, ale mam nadzieję, że razem z wytłumaczeniem jest ok.