Skocz do zawartości

Problem Ze Zdefiniowanymi, Własnymi, Zmiennymi Globalnymi


Subaru

Rekomendowane odpowiedzi

Witam

 

Dłubałem ostatnio jak pozwolić na używanie zmiennych w pliku .c przypiętym do main.c aby nie inicjować ich na nowo w jednym i drugim pliku, doczytałem lekturkę o zmiennych globalnych wywoływanych słowem "extern" np.

extern int x[20];

Ta część działa bez zarzutu, problem dopiero pojawia się przy zmiennej zdefiniowanej w pliku .h razem z własnym typem, który wygląda tak:

struct Cardtype {
   u32 indexnr;
   char name[32];
   char type[16];
//i pare innych zmiennych
};

Zaś deklaracja zmiennej a nawet tablicy tak: (w telegraficznym skrócie)

struct Cardtype Cards[]=

{

{1,"Fox Empire","castle"}, //plus te pare zmiennych z typu powyzej, chodzi o schemat

//tutaj jest 70 wpisow generalnie 1-70

};[/code]

Wezwanie zmiennej robię tak jak pozostałe w pliku main.c

extern struct Cardtype Cards[];

Jednakże zwraca to następujący błąd

main.c:16: error: array type has incomplete element type

Próbowałem podawać rozmiar tablicy na sztywno (nie jest mi jakoś specjalnie potrzebna dynamiczna tak po prawdzie), cudowałem różne rzeczy, zero efektu

Rozwiązanie pewnie znowu się okaże jakieś dziecinnie łatwe, ale niestety nie mogę na nie wpaść

 

Bardzo proszę o pomoc, jestem otwarty na wszelkie pomysły byleby przebrnąć przez to jakoś :)

 

Pozdrawiam i życzę miłego dnia/wieczoru/nocy/inne*

* - niepotrzebne skreślić

 

Subaru

Odnośnik do komentarza
Udostępnij na innych stronach

Za duzo do dodania raczej nie ma (bowiem np. kod wczytujacy tlo tutaj nie ma nic do rzeczy, prawda?)

Plik Cards.h wyglada tak

#ifndef __CARDS__
#define __CARDS__

struct Cardtype {
   u32 indexnr;
   char name[32];
   char type[16];
   char race[16];
   char element[8];
   u32 cost;
   u32 atk;
   u32 def;
   u32 speed;
   u32 flow;
};

struct Cardtype Cards[]=
{
{1,"Elven Ritualist","creature","neutral","none",3,1,1,2,3},
//tu jest pozostale 69 kart, nie ma sensu chyba przytaczac ich, bowiem strukture maja taka sama
}

 

Nastepnie mamy main.c

W nim chcemy wywolac ta zmienna poprzez

extern struct Cardtype Cards[];

Wynika to z tego, iz potrzebuje w main.c wywolac wypisanie tego co znajduje sie w takiej abominacji:

Cards[(deck1a[4])].name

deck1a zostal zalaczony tez przez extern i jest w porzadku, wyglada to tak

extern u8 deck1a[20];

(u8 to jak latwo domyslic sie unsinged 8-bit, czyli zakres 0-255, tego typu zmienne sa w tych libkach zdefiniowane odgórnie, nie musze ich tworzyc od nowa, sa u8, s8, u16, s16, u32, s32 acz wciaz dzialaja takie jak int czy char)

Jedyna róznica, która moze jest tu kluczowa(?), to taka, ze deck1a jest zdefiniowany nie w pliku naglówkowym a w pliku battle.c oczywiscie dolaczonym w main poprzez:

#include "battle.c"

Zas sam deck1a wyglada w pliku battle.c tak:

u8 deck1a[20] = {15, 15, 22, 22, 22, 22, 29, 29, 33, 33, 33, 33, 34, 34, 34, 34, 40, 40, 40, 40 };

 

Uff, ale sie nakopiowalem, czy tyle wystarczy?

Odnośnik do komentarza
Udostępnij na innych stronach

Nie chce mi sie analizowac tego co wkleiles, ale z tymi strukturami zawsze sa problemy. Uproszczony dzialajacy przyklad.

Plik naglówkowy:

typedef struct
{
int pole;
int pole2;
} struktura;

A w kodzie zródlowym uzywasz w ten sposób:

struktura moja_struktura[6];
int i;
for (i=0; i<sizeof(moja_struktura)/sizeof(moja_struktura[0]); i++)
{
moja_struktura[i].pole = 10;
moja_struktura[i].pole2 = 10;
}

Oczywiscie mozna tez w inne sposoby odwolywania sie do tej struktury, ale ten jest taki najlatwiejszy do zrozumienia, bo operujesz na indeksach.

 

Btw. jesli to jest taki projekt hobbystyczny i nie musisz pisac tej aplikacji w C to sobie odpusc ten jezyk. Szkoda Twojego czasu i zycia. Wybierz inny jezyk, np. Pythona, gdzie nie bedziesz musial sie zastanawiac przez dwa dni jak uzywac listy czy innej struktury :) Plus jest tez taki, ze w krótszym czas nauczysz sie wiecej niz walczac latami z segfaultami w C.

Odnośnik do komentarza
Udostępnij na innych stronach

Cześć.

 

Nie podpinaj plików .c do innych plików .c poprzez #include! :) Po prostu niech wszystkie tego typu pliki znajdą się w projekcie (jakiegokolwiek IDE używasz) a tym już zajmie się sam linker. #include używaj tylko i wyłącznie do dołączenia plików nagłówkowych w których powinny się znajdywać tylko i wyłącznie deklaracje:

-stałych

-prototypów funkcji (i tylko prototypów)

-struktur

-typów zmiennych

-klas (ostatnie w przypadku C skreślić :P).

Taka podstawa, do dobrego napisania projektu ;)

 

Extern służy do zaimportowania zmiennej zadeklarowanej w innym pliku .c, ale ten plik nie powinien być wcale dołącony przez #include. W takim przypadku extern jest zupełnie zbędny. Niech plik .c po prostu będzie w projekcie (żeby został skompilowany i dołączony przez linker), a będzie OK. Twój kod nie chce działać, bo kompilatorowi brakuje w danym pliku deklaracji struktury Cardtype. A Cardtype nie możesz dołączyć poprzez include, bo wtedy dołączysz na sztywno i dane i extern będzie zbędny.

 

Moja porada ;) Zrobić 2 pliki:

 

cards.h

#ifndef __CARDS__
#define __CARDS__

struct Cardtype {
 u32 indexnr;
 char name[32];
 char type[16];
 char race[16];
 char element[8];
 u32 cost;
 u32 atk;
 u32 def;
 u32 speed;
 u32 flow;
};

#endif

(czyli w pliku nagłówowym wyłącznie deklaracja struktury, bez danych)

 

Oraz plik cards.c

#include "cards.h"

struct Cardtype Cards[]= {
{1,"Elven Ritualist","creature","neutral","none",3,1,1,2,3},
....
}

czyli deklaracja danych.

 

I teraz w każdym pliku .c w którym się chcemy odnieść:

#include "cards.h"
//koniecznie, bo deklaracja struktury jest potrzebna do externa

extern struct Cardtype Cards[];

//no i mamy do dyspozycji Cards

 

I wszystko :)

 

Btw. jeśli to jest taki projekt hobbystyczny i nie musisz pisać tej aplikacji w C to sobie odpuść ten język. Szkoda Twojego czasu i życia. Wybierz inny język, np. Pythona, gdzie nie będziesz musiał się zastanawiać przez dwa dni jak używać listy czy innej struktury :) Plus jest też taki, że w krótszym czas nauczysz się więcej niż walcząc latami z segfaultami w C.

 

Oj tam, C i C++ tylko na początku są brutalne, jak zrozumie się dokładnie zasady działania to programuje się całkiem przyjemnie ;) Zwłaszcza, że do gier to w sumie jak na razie jedyne 'słuszne' rozwiązania. Inna sprawa, że do czegoś bardziej złożonego poniżej C++ bym nie schodził... W C strasznie brakuje klas...

 

Pozdrawiam

Odnośnik do komentarza
Udostępnij na innych stronach

thof - Gdybym mógl sie z tego typu projektem gdziekolwiek przerzucic to w pierwszej kolejnosci by poszedl SDL, Python jest potezny, ale nie wiem czy dalby(m) rade ten akurat projekt przelozyc w taka sama postac do Pythona (a jesli nawet to jakim kosztem...)

 

jszubiak - niestety tez nie, wtedy madralinski kompilator pluje sie o cos inne

main.c:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Cards'

 

Miszcz - raczej wina gdzies lezy u mnie, jakby nie patrzec jest to pierwszy BARDZO powazny projekt, w którym uzywam wiecej plików niz jeden main.c (byl kiedys projekt z jednym plikiem naglówkowym extra ale problemów nie bylo) No i jeszcze to slepe przestukiwanie przykladów z pliku do pliku...

 

l0ud - <dwukropek tu>

- gdziezbym smial podpinac plik .c przez #include...dobra osmielilem sie raz i po tym co mi wypisal kompilator stwierdzilem, ze gdyby tylko mógl to by rzucal co drugie slowo przeklenstwo jakies za takie cos

- jesli gedit mozna nazwac jakims IDE ;)

- Kod pisze domyslnie w trybie C, teoretycznie moge "przemianowac" to na C++, ale jak sobie przypomne jak ludzie na forum jeczeli, ze zmienili co trzeba i dalej nie dziala to wole zostac tu gdzie jestem

 

Zastosowalem Twoja metode (co sie naplulem z kompilatorem to moje), ale udalo sie! Skompilowalo sie, sprawdzam wlasnie czy wywolanie bedzie poprawne, ale raczej powinno bez zarzutów :)

 

Problem rozwiazany

 

Leciutki offtopic pozwole sobie wtracic jeszcze, l0ud avatar zapewne nie jest wyborem przypadku u Ciebie? ;)

Odnośnik do komentarza
Udostępnij na innych stronach

thof - Gdybym mógl sie z tego typu projektem gdziekolwiek przerzucic to w pierwszej kolejnosci by poszedl SDL, Python jest potezny, ale nie wiem czy dalby(m) rade ten akurat projekt przelozyc w taka sama postac do Pythona (a jesli nawet to jakim kosztem...)

Jesli chodzi o SDL to zobacz pygame. Jezyk programowania to jezyk programowania, wiec kazdy projekt mozna napisac w dowolnym jezyku, inna sprawa, ze czesto nie ma to sensu. Równie dobrze mozesz napisac to w Javie. Pisanie w C jest bardzo, bardzo czasochlonne i zalezy od Ciebie czy chcesz sie koncentrowac przez 90% czasu na zarzadzaniu pamieci w C, czy wolisz ten czas wykorzystac na implementowanie nowych funkcji i wzbogacanie gry w innym jezyku.

Zreszta wystarczy spojrzec na Lua, jezyk skryptowy, który jest bardzo popularny w grach. Ale zeby sie o tym przekonac musialbys spróbowac.

 

W C strasznie brakuje klas...

W C nie brakuje klas, bo klasa to cecha programowania obiektowego. Niby obiekty pojawiaja sie w C (jak np. GObject), ale to nie to samo. Natomiast na pewno nie brakuje bibliotek, bo zdecydowana ich wiekszosc jest napisana wlasnie w C. Prawda jest, ze C od C++ dziela lata swietle, jesli chodzi o wygode programowania, ale to nie znaczy, ze pisanie wszystkiego jak leci w C++ jest dobrym pomyslem. Trzeba próbowac nowych technologii, bo kto stoi w miejscu ten sie cofa.
Odnośnik do komentarza
Udostępnij na innych stronach

OK. Skoro nie uzywasz zadnego IDE (jezeli proste to polecam CodeBlocks), to jezeli bedzie sypalo unresolved reference... etc, to upewnij sie, ze w makefile uwzgledniasz wszystkie pliki .c, a nie tylko main.

 

W C nie brakuje klas, bo klasa to cecha programowania obiektowego.

 

Brakuje w kontekscie pisania gier. Wiadomo, ze obiektów nie ma dlatego, ze z zalozenia nie jest to jezyk obiektowy. Dlatego lepszy do gier jest C++, plus masz chociazby to new i delete.

 

Trzeba próbowac nowych technologii, bo kto stoi w miejscu ten sie cofa.

Natomiast napisac cokolwiek w C poza hello world to trzeba umiec i tyle :P Jako konkretny projekt edukacyjny prosta gra w C nadaje sie jak najbardziej.

 

...raczej nie ciagnal bym tak dyskusji w tym kierunku bo wyjdzie jak zawsze tylko wojenka wysokopoziomowców z niskopoziomowcami :P

 

Pozdrawiam

Odnośnik do komentarza
Udostępnij na innych stronach

Brakuje w kontekscie pisania gier.
A wspomniane SDL to niby w czym jest napisane? No przeciez w C. A Allegro? Tez C.

Poza tym nie wiem jak ma sie new i delete do przydatnosci jezyka...

 

Natomiast napisac cokolwiek w C poza hello world to trzeba umiec i tyle :P
Jakies doswiadczenie mam, bo pisalem aplikacje z wykorzystaniem GTK+, GLib do watków, DBus i innych mniejszych bibliotek, czy programy równolegle, a nawet zdarzylo mi sie debugowac modul pochodzacy z kernela i wydaje mi sie, ze Ty prezentujesz typowe podejscie dla programistów starszej daty: "nie chce mi sie uczyc nic nowego, wiec wole powiedziec, ze to co juz umiem jest najlepsze".
Odnośnik do komentarza
Udostępnij na innych stronach

A wspomniane SDL to niby w czym jest napisane? No przeciez w C. A Allegro? Tez C

Natomiast SFML juz nie. I w sumie.., co z tego? Gry z uzyciem tych bibliotek beda pisane w wiekszosci w c++, bo tak jest po prostu wygodniej. A wygodniej jest wlasnie ze wzgledu na obiektowosc plus wiazace sie z nia ulatwienia typu new i delete. Z czym sie nie zgadzasz?

 

wydaje mi sie, ze Ty prezentujesz typowe podejscie dla programistów starszej daty: "nie chce mi sie uczyc nic nowego, wiec wole powiedziec, ze to co juz umiem jest najlepsze".

Nie zgadzasz sie z twierdzeniem, ze wypadaloby jednak w dzisiejszych czasach znac podstawy C podchodzac do gamedeva? Nigdzie nie dyskryminuje nowych technologii, ale C i C++ w tej dziedzinie beda sie utrzymywaly jeszcze dluuugo, zwlaszcza na konsolach.

 

Pozdrawiam

Odnośnik do komentarza
Udostępnij na innych stronach

Tak czytam czytam te swoje posty tutaj i zastanawialem sie czego zapomnialem dopisac, juz wiem.

Zapomnialem wspomniec, ze problem dotyczy projektu na konsole Nintendo DS a tamtejsze biblioteki sa wlasnie w C (z jakas opcja klepania tego w C++, ale to mordega przelaczyc sie, potem jest ok)

Co prawda interpreter Pythona ktos chyba napisal, ale jesli juz mialbym pisac przez "posrednika" to wziecie wielkie ma jezyk Lua nie wiem czemu, moze po prostu jest latwy do zrozumienia czy co.

Na konsole sie klepie glównie w C/C++ nie ma co do tego watpliwosci, ewentualnie homebrew np. na Wii klepia ludzie z uzyciem SDL (na DS'a chyba SDL tez jest ale glowy nie dam) tudziez portuja prawie na zywca takie gry jak Quake I czy Jazz Jackrabbit. Czy sa interpretery Python, Lua itd. na Wii szczerze mówiac nie wiem, sa za to Emulatory i one jako jedyne/jedne z niewielu zawieraja w sobie Assembler (bo co moze byc lepszego niz interpreter/recompiler danej platformy w Assemblerze?)

 

W kazdym razie, kod zadzialal i dzieki temu uporzadkowalem troche ten caly balagan (kompilator przestal sie czepiac o abominacje rózne), program dziala jak nalezy, nastepnym krokiem bedzie przewijana lista, acz fragment kodu do tego chyba gdzies mam we wstrzymanym projekcie Kirby RPG (system walki przypominal troche Final Fantasy i informacje co sie dzieje, przewijaly sie linijkami od dolu do góry)

 

Jeszcze raz dziekuje wszystkim za pomoc oraz uzytkownikowi l0ud za rozwiazanie problemu i nieladu w kodzie :)

 

Subaru

 

P.S. - balaganik jest nadal, ale kompilator sie nie czepia, program dziala, to na razie niech jest jak jest buehehe

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 weeks later...

skompiluj swój program kompilatorem gcc:

g++ -o program *.h *.c

gdzie *.h i *.c to wszystkie pliki nalezace do projektu, zobacz czy tez wypluje jakis blad

Twój kompilator zglasza ciagle blad w main.c na 16 wierszu, wiec wypadaloby tez podac cala tresc pliku main.c

 

P.S. sorry dopiero zobaczylem, ze odgrzewam starego kotleta :P

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...