logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

pytanie na temat tworzenia plików *.h w keilu itp

mototest 24 Sie 2006 21:36 1203 5
REKLAMA
  • #1 2949748
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    Witam

    nie jestem jeszcze biegły w C i mam takie pytanie :

    jak tworzę plik np. "funkcje.h" i umieszczam w nim funkcje które wcześniej miałem w głównym pliku "program.c" to w programie głównym miałem zmienne globalne które działały w tych funkcjach, a które nie działają teraz w pliku "funkcje.h"

    czy nie da się zrobić żeby zmienne globalne były widzialne w pliku funkcje.h ? albo jak to zrobic ? bo mam tam np. tablicę która jest mi potrzebna wszędzie w programie.

    dzięki
    Bogdan
  • REKLAMA
  • #2 2950538
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    Z zasady w plikach .h nie umieszcz się kodu, a jedynie deklaracje i makra.

    W pliku .h zadeklaruj zmienne globalne jako extern.

    Zrób dwa pliki .c, w obu zainclude'uj plik .h a w jednym z nich umiesc definicję zmiennej globalnej, ale już bez extern. W pliku .h powinny znaleźć się także prototypy funkcji, które mają być dostępne "z zewnątrz"

    Ogólnie wszystko co globalne powinno sie deklarowac w pliku .h include'owanym przez wszystkie pliki .c, które tych zmiennych potrzebują

    Taki przyklad:
    plik1.c
    #include "defs.h"
    char tablica[] = {1,2,3,4,5};
    void funkcjaX1(void) {
    }
    
    void funkcjaX2(void) {
      funkcjaY1();
      funkcjaY2(); /* spowoduje wygenerowanie błędu, bo prototyp tej funkcji nie został zadeklarowany wcześniej (w defs.h) */
    }

    plik2.c
    #include "defs.h"
    
    void funkcjaY1(void) {
    char zzz;
      zzz = tablica[2];
    }
    void funkcjaY2(void) {
      funkcjaY1();
      funkcjaX1();
    }

    defs.h
    
    extern char tablica[];
    extern void funkcjaX1(void);
    extern void funkcjaY1(void);
    


    Taka konstrukcja powoduje że zmienna tablica oraz funkcje funkcjaX1 i funkcjaY1 dostępne są wszędzie, ponadto funkcje funkcjaX1 i funkcjaX2 dostępne są z poziomu pliku plik1.c, natomiast funkcjaY1 i funkcjaY2 dostępne są z poziomu pliku plik2.c.
  • REKLAMA
  • #3 2953133
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    dzięki ,jutro spróbuję się tym pobawić, na pewno będą jeszcze problemy...
    jak to za pierwszym razem

    Dodano po 26 [minuty]:

    już tesuję, ale nic mi to nie działa na moich przykładach, jeśli mam dwa pliki *.c to obojętnie gdzie daję pętlę main() ?
    jeśli deklaruję zmienne globalne w pliku *.h to muszę znowu je deklarować w poszczególnych plikach *.c ?

    czy jeśli stosuję :
    #include <ADuC842.h>
    #include <stdio.h>
    #include <math.h>

    to muszę te wszystkie include wpisywać wszędzie w każdym pliku *.c i *.h ?
    czy pliki *.c inne niż ten w którym jest main() też trzeba inkludować ?
  • REKLAMA
  • #4 2953878
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    includ-y dopisujesz tylko w tych plikach w który używasz określonych funkcji bibliotecznych lub rejestrów procka, których prototypy są zawarte w *.h. Jednak przy bardziej złożonych projektach terzeba to robić w przemyślany sposób bo kompilator będzie zgłaszłam błąd redefinicji. Szczególnie trzeba uważać na definicje rejestrów.
    np. jeden plik zawiera #include <ADuC842.h>
    a drugi <reg52.h> to compilując je każdy osobno
    nie będzie błędów ale nie da się tego połączyć w całość.

    plików *.c nie includuje się - tylko tworzy się plik *.h z prototypami funkcji które będą używane przez
    inne moduły i tylko to się includuje
  • REKLAMA
  • Pomocny post
    #5 2953971
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    mototest napisał:
    jeśli mam dwa pliki *.c to obojętnie gdzie daję pętlę main() ?

    Tak, byle by gdzieś była, tylko przy kompilacji trzeba uważać.
    Plik bez main() można skompilować tylko do postaci pliku linkowalnego (.o), czyli w wiekszosci kompilatorow z opcją -c.
    Potem oczywiście poskładać wszystko za pomocą linkera.
    Można też kompilować wszystkie pliki za jednym zamachem, na przykład tak to wygląda w gcc:
    gcc -o plik_wynikowy plik1.c plik2.c

    mototest napisał:
    jeśli deklaruję zmienne globalne w pliku *.h to muszę znowu je deklarować w poszczególnych plikach *.c ?

    Nie. Deklaracji (z extern) może być kilka, ważne żeby się zgadzały co do typu. Natomiast definicja może być tylko jedna, w dowolnym z plików .c

    mototest napisał:
    czy jeśli stosuję :
    #include <ADuC842.h>
    #include <stdio.h>
    #include <math.h>

    to muszę te wszystkie include wpisywać wszędzie w każdym pliku *.c i *.h ?

    Nie. Tylko w tych plikach, w których są potrzebne. Jeżeli jakiś plik nie korzysta z funkcji matematycznych, ani zdefiniowanych w math.h stałych/makr to nie musisz include'ować pliku math.h.


    mototest napisał:
    czy pliki *.c inne niż ten w którym jest main() też trzeba inkludować ?

    Nie. To zrobi za Ciebie linker po skompilowaniu każdego pliku z osobna do pliku linkowalnego.
    Po to właśnie jest plik .h zawierający prototypy funkcji, żeby np. funkcje z pliku plik1.c "wiedziały", że funkcje znajdujące się w pliku plik2.c będą dostępne, a typ zwracany przez te funkcję i jej argumenty zadeklarowane są w pliku .h. Tu ważny jest atrybut extern, który sygnalizuje, że definicja funkcji może znajdować się w innym pliku, przez co ciało funkcji nie jest aktualnie dostępne.

    Napisz, jakie błędy wyświetla kompilator.
    Dobrze było by też gdybyś załączył kod źródłowy, a przynajmniej fragmenty plików w których znajdują się deklaracje i definicje.
  • #6 2987181
    mototest
    Poziom 19  
    Posty: 440
    Ocena: 4
    Wszystko zadziałało, uporałem się z tym ,dzieki za pomoc
REKLAMA