2011-11-29 9 views
11

Mam program ANSI C składający się z dwóch plików. Pierwszy plik zawiera funkcję main(), a drugi plik zawiera inne funkcje, które wywołuje pierwszy plik. Przed definicji main() funkcji, jakie umieścił następujący kod:Jak uczynić globalną stałą (praca z wieloma plikami) w programie C?

#define PI 3.14159265358979323846 

ale 2. Plik nie widział tej zmiennej. Pierwszy plik widzi to dobrze. Następnie umieściłem ten sam wiersz w drugim pliku (zachowując go w pierwszym pliku, jak wyżej), przed definicjami funkcji, ale wciąż drugi plik go nie widzi. Rzeczy zawsze kompilują się dobrze, ale gdy śledzimy zmienną PI w gdb, pokazuje ona, w jaki sposób PI jest stałą globalną widoczną dla wszystkich plików skompilowanych w aplikacji?

EDIT/UPDATE:

Na podstawie odpowiedzi do tej pory stworzyłem następujący plik:

myheader.h

#ifndef my_header_stuff 
#define my_header_stuff 
    #define PI 3.1415926535897932384626433832795 
#endif 

oraz w dwóch plikach chcę aby zobaczyć tę stałą wartość PI, dodałem ten plik w następujący sposób:

file1.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
int main(void) { 
    etc... 
} 

i file2.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
double interesting_function(void) { 
    etc... 
} 

Pytania:

  1. Kiedy używać GDB do debugowania, b PI zwraca (w obu plikach, sam wynik) „No symbol "PI" w obecnym kontekście ". Jednak matematyka w zależności od PI jest obliczana poprawnie. Czy istnieje sposób, aby wyświetlić PI w gdb?

  2. Czy mogę dołączyć również dwie linie dla stdio i stdlib w pliku myheader.h?

  3. Czy mogę dołączyć także prototypy funkcji do pliku myheader.h? Jeśli tak, a następnie powiedzmy, że tworzę plik 3 .c, który nie wymaga żadnego z tych prototypów, ponieważ nie korzysta z tych funkcji, czy wyrządzono jakąkolwiek szkodę?

+0

Zawsze umieszczaj wszystkie definicje w plikach .c i deklaracjach (w tym makrach) w plikach .h.To powinno rozwiązać problem w 99% przypadków. – JosephH

+0

Dzięki JosephH, czy możesz mi pomóc w tej mechanice? Zobacz moją próbę powyżej. – ggkmath

+0

Zobacz odpowiedź, którą właśnie napisałem: – JosephH

Odpowiedz

3
  1. To normalne, że definicja makro nie pojawia się w GDB. Dzieje się tak, ponieważ GCC zastępuje każdą wartość PI rzeczywistą wartością pi.
  2. Tak. W twoim przypadku nie boli. Jeśli plik .h zawiera prototyp (zwykle nazywane są one deklaracjami), który używa typu zdefiniowanego gdzie indziej, można po prostu #include w pliku nagłówkowym
  3. Tak. Możesz zadeklarować, co zawsze działa prototyp, który chcesz i nie zaszkodzi, jeśli chodzi o funkcjonalność twojego programu. Kompilator nawet nie sprawdza istnienia definicji tych funkcji, chyba że faktycznie wywołasz je z innego miejsca.
+0

Dzięki JosephH !!! Kolejne pytanie ... Pierwotnie umieściłem # definicję bezpośrednio w każdym pliku, który wydawał się działać poprawnie w file1.c, ale nie file2.c (brak błędów kompilacji, ale matematyka przyniosła szalenie błędny wynik). Używanie #include jest podobne do wycinania i wklejania zawartości do pliku, prawda? Dlaczego podejście myheader.h daje różne wyniki - czy oba rozwiązania nie polegają tylko na "#define NAME value"? Lub, jeśli nie możesz tego wyjaśnić, może to był mój błąd w debugowaniu. – ggkmath

+0

Nie sądzę, aby uzyskać różne wyniki. Czy możesz sprawdzić jeszcze raz? – JosephH

2

Chciałbym zadeklarować PI w pliku nagłówka i obejmują ten plik nagłówka do wszystkich plików źródłowych

należy umieścić deklaracje funkcji, makr w pliku nagłówkowym (a może kilka prostych funkcji inline) Wdrażanie powinny być umieszczone w plikach .c

// I edytowany odpowiedź do odpowiedzi na twój komentarz

+0

Czy prototypy funkcji ze wszystkich plików również powinny być umieszczone w pliku nagłówkowym? Zacząłem to robić, a potem upuściłem, kiedy empirycznie odkryłem, że funkcje, które nie są wywoływane w konkretnym pliku, nie muszą mieć tam swoich prototypów, a następnie zastanawiałem się, czy coś może się zepsuć, lub być nieefektywne, jeśli istnieje taka nadmiarowość. – ggkmath

+0

Edytowałem moją odpowiedź –

+0

Dzięki Jan. Czy mógłbyś użyć #define PI 3.14159 do zadeklarowania go w nagłówku? Jeśli tak, to nie wstawiłbym tego, jak obecnie go mam? Jeśli nie, w jaki sposób? – ggkmath

1

można utworzyć zmienną globalną.

//file1.c 
int my_global; 


//file2.c 
extern int my_global; 
//code using my_global... 

Należy pamiętać, że korzystanie z preprocesora jest w większości przypadków zniechęcane.

Należy również pamiętać, że definicja M_PI proponowana przez innych nie jest dostępna w najnowszym standardzie C (C99), więc nie można na niej polegać.

+0

Dla wartości pi? –

+0

Czy oba są umieszczone przed definicjami funkcji? – ggkmath

+0

@ggkmath Tak, jeśli chcesz używać * my_global * przez te funkcje. – Beginner

2

Makro nie jest zmienną i nie pojawi się w gdb jako zmienna. Wszystko układa się dobrze, ponieważ działają dobrze; masz po prostu złe oczekiwania na gdb.

Ogólnie rzecz biorąc, makro, które jest potrzebne w więcej niż jednym miejscu, powinno zostać zdefiniowane w pliku nagłówkowym, który jest dołączany wszędzie tam, gdzie jest potrzebny; na przykład makro M_PI jest już zdefiniowane jako pi w standardzie obejmują math.h.

Inna rzecz, że można zrobić, to mieć const int PI = 3.14159etcetc; w jednym pliku i extern const int PI; we wszystkich innych, ale jest to uciążliwe, ponieważ wymaga określenia wartości istnieć w dokładnie jedną jednostkę kompilacji.

+1

Powiedziałbym, że posiadanie wartości stałej w jednym miejscu jest w rzeczywistości plus ...;) –

+0

To niefortunne, ale 'M_PI' nie jest standardem c. – u0b34a0f6ae

0

Jeśli pracujesz tylko ze standardowych definicji matematycznych, standardowy plik header math.h ma kilka dobrych:

#include <math.h> 
    ... 
double area = radius * radius * M_PI; 

Definiowanie globalnych stałe, istnieje wiele metod, odpowiednio wyjaśnione w innych odpowiedzi.

+0

To niefortunne, ale 'M_PI' nie jest standardem c. – u0b34a0f6ae

-1

preprocessor direct zostanie zastąpiony przez rzeczywisty kod przed kompilacją, więc w twoim przypadku PI pierwszego pliku zostanie zastąpiony przez 3.14 ... i nie ma symbolu PI w tabeli symboli pierwszej tłumaczonej jednostki. więc gdb nie powie żadnego symbolu "PI".

Jeśli chcesz użyć #define i nie chcesz używać pliku nagłówkowego, potrzebujesz #deine PI na początku każdego pliku.

0

Byłoby bardzo miło, gdybyś utworzył plik nagłówkowy dla pliku, który jest zawarty w głównym pliku źródłowym, i jest to również dobra praktyka i poprawisz swoje umiejętności językowe. Wyobraźmy sobie, że mamy plik źródłowy z funkcji, zmiennych globalnych i stałych, które będą nam potrzebne w głównym pliku źródłowego, możemy utworzyć plik nagłówka dla tego pliku i umieścić te funkcje tam:

#ifndef _FILE_H 
#define _FILE_H 

#include "file.h" 
#define PI 3.14 
/** 
    *functions protypes here or other constants or globlal variables 
    */ 
    void do_something(char **param1, int *param2); 

#endif 

w twojej " file.c”plik należy wykonać folowing:

#inlcude "file.h" 

void do_something(char **param1, int *param2) 
{ 

    /** 
    *do something 
    */ 
} 

W swojej "main.c" plik należy zrobić:

#include "file.h" 

/** 
    *Now you can use "PI" 
    */ 

mam nadzieję, że pomogłem jakoś.

Powiązane problemy