2016-08-17 31 views
8

Piszę w języku C.Const self-referencyjne struktury

Zdefiniowałem nowy typ (noFunc_menuEntry), który składa się z samo-referencyjnej struktury.

struct noFunc_menuEntry_tag { 
    const char *text; 
    struct noFunc_menuEntry_tag *up_entry; 
    struct noFunc_menuEntry_tag *down_entry; 
    struct noFunc_menuEntry_tag *back_entry; 
    struct noFunc_menuEntry_tag *enter_entry; 
}; 
typedef struct noFunc_menuEntry_tag noFunc_menuEntry; 

muszę zdefiniować serię zmiennej tak:

menuEntry_1 = {title_1, &menuEntry_2, &menuEntry_4, &menuEntry_1, &menuEntry_5}; 
menuEntry_2 = {title_2, &menuEntry_3, &menuEntry_1, &menuEntry_1, &menuEntry_6}; 

i tak dalej.

Muszę więc oddzielić deklarację i definicję zmiennej, ponieważ każda zmienna zależy od innych zmiennych. W pliku nagłówkowym Pisałem deklarację

noFunc_menuEntry menuEntry_1, menuEntry_2, menuEntry_3, menuEntry_4, menuEntry_5, menuEntry_6; 

etc ..., a w pliku .c w funkcji I już zainicjowane zmienne:

void menu_init(void) 
{ 
     menuEntry_1.text = title; 
     menuEntry_1.up_entry = &menuEntry_2 
} 

i tak dalej dla inni członkowie i zmienne.

Jednak chcę moje zmienne być const:

const noFunc_menuEntry menuEntry_1, menuEntry_2, menuEntry_3, menuEntry_4, menuEntry_5, menuEntry_6; 

Więc moje pytanie jest o separing deklaracji i definicji const zmiennych typu I już zdefiniowane. Jak mogę zrobić? Czy robię coś źle?

Naturalnie, jeśli po prostu dodaję const w deklaracji, kompilator zgłosi błąd podczas inicjowania zmiennych (próbuję pisać zmienne tylko do odczytu).

+0

Jeśli już init zmiennych przez 'menuEntry_1 = {TITLE_1, & menuEntry_2, & menuEntry_4, & menuEntry_1, & menuEntry_5};', dlaczego chcesz zainicjować je ponownie w 'menu_init'? – user694733

+0

Ponieważ twoja struktura zawiera * wskaźniki * do tych (globalnych) zmiennych, wierzę, że powinieneś być w stanie po prostu zdefiniować je i zainicjować w jednej linii, tj. Nie ma potrzeby posiadania funkcji do inicjalizacji.To prawda, że ​​* "każda zmienna zależy od innych zmiennych" *, ale jeśli zmienisz zawartość 'menuEntry_1', to nie znaczy, że zmieni się" menuEntry_1 ". – Groo

+0

@ user694733: Inicjuję zmienne w 'menu_init', jeśli nie używam ich jako' const', ale jeśli muszą to być 'const' naturalnie nie używam' menu_init'. Szukałem właściwej drogi, by to zrobić! – BzFr

Odpowiedz

6

Jeśli chcesz, aby te zmienne miały postać const, musisz wykonać inicjalizację bez funkcji.

Ale najpierw niech obsłużyć const w definicji typu:

typedef struct noFunc_menuEntry_tag noFunc_menuEntry; 
struct noFunc_menuEntry_tag { 
    const char *text; 
    const noFunc_menuEntry *up_entry; 
    const noFunc_menuEntry *down_entry; 
    const noFunc_menuEntry *back_entry; 
    const noFunc_menuEntry *enter_entry; 
}; 

Następnie deklaracje dla pliku nagłówka:

extern const noFunc_menuEntry menuEntry_1; 
extern const noFunc_menuEntry menuEntry_2; 
... 

i wreszcie definicji i inicjalizacji w pliku źródłowym:

const noFunc_menuEntry menuEntry_1 = {title_1, &menuEntry_2, &menuEntry_4, &menuEntry_1, &menuEntry_5}; 
const noFunc_menuEntry menuEntry_2 = {title_2, &menuEntry_3, &menuEntry_1, &menuEntry_1, &menuEntry_6}; 
... 
6

Można było use an array, ponieważ kilka item_i oznacza, że ​​być może trzeba.

typedef struct noFunc_menuEntry_tag { 
    const char *text; 
    const struct noFunc_menuEntry_tag *up_entry; 
    const struct noFunc_menuEntry_tag *down_entry; 
    const struct noFunc_menuEntry_tag *back_entry; 
    const struct noFunc_menuEntry_tag *enter_entry; 
} noFunc_menuEntry; 


int main(void) { 
    const noFunc_menuEntry menuEntry[4] = { 
     {"", &menuEntry[0], &menuEntry[1], &menuEntry[2], &menuEntry[3]}, 
     {"", &menuEntry[0], &menuEntry[1], &menuEntry[2], &menuEntry[3]}, 
     {"", &menuEntry[0], &menuEntry[1], &menuEntry[2], &menuEntry[3]}, 
     {"", &menuEntry[0], &menuEntry[1], &menuEntry[2], &menuEntry[3]}, 
    }; 
    return 0; 
} 
+1

Myślę, że jest to czysty sposób na wykonanie tego zadania. – haccks

1

Użyj extern const w deklaracji w nagłówku. extern zadeklaruje tylko zmienną do użycia w programie, bez przydzielania pamięci. Następnie postępuj zgodnie ze zdefiniowaniem w głównym const noFunc_menuEntry menuEntry_1 = {title_1, &menuEntry_2, &menuEntry_4, &menuEntry_1, &menuEntry_5}; .. so on