• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[C] Modułowość w języku C, czyli scalanie ze sobą niezależnych obiektów programu.

Object Storage Arubacloud
0 głosów
806 wizyt
pytanie zadane 11 grudnia 2017 w C i C++ przez Tomek Wilnowski Użytkownik (610 p.)
edycja 16 grudnia 2017 przez Tomek Wilnowski

To pytanie może jest teoretyczny, ale odpowiedź na nie jest dla mnie bardzo ważna.

Mam jeden problem z którym w żaden sposób nie jestem w stanie sobie poradzić. Dotyczy on połączenia ze sobą niezależnych elementów programu na zasadzie takiej, że zadeklarowane w nim zmienne i funkcje giną w momencie przekierowania do innego pliku tzw. wywołania innej funkcji która jest zadeklarowana w zupełnie innym pliku i jest zupełnie niezależna, bo już odpowiada za inną funkcjonalność programu.

plik_1 wywołuje plik_2

plik_2 wywołuje plik_1 (w taki sposób, aby nie widać było że funkcja będąca w pliku_1 została już wywołana )

Jak to zrobić ?  Ja próbowałem na różne sposoby czyszczenie pamięci system("clear"); ale nic [...] Aby ten problem przedstawić jak najjaśniej to program wygląda schematycznie następująco:

Katalogi i pliki:


______style                                    /* Katalog przechowujący elementy odpowiadające za grafikę tego programu */
| funkcjonalność_1.c           /* Deklaruje tutaj zmienne statyczne co to mi daje? */
| funkcjonalność_2.c           
| funkcjonalność_3.c [...]
|main.c                                   /* Ten plik tylko uruchamia cały ten program */
|nagłówek.h                         /* Jest to plik przechowujący deklaracje wszystkich funkcji znajdujących się w tym konkretnym katalogu */
/*funkcjonalność_1.c*/
void procedura_1(){ 
/*jakaś instrukcja, która po wprowadzeniu jakiś danych przez użytkownika odpala mi funkconalność_2.c*/
 }
/*funkcjonalność_2.c*/
void procedura_2(){ 
/*jakaś instrukcja, która po wprowadzeniu jakiś danych przez użytkownika odpala mi funkconalność_1.c tak jakby 1 nigdy się nie wykonało*/
 }

Jak pisać tego typu projekty w zwykłym języku C z uwagi na to że nie jest to język obiektowy. Jak deklarować zmienne funkcję zapewniać komunikację między konkretnymi jego funkcjami zmiennymi procedurami funkcjonalnościami? Jak kompilować ten program gdzie całe katalogi tworzą mi jeden oddzielny element programu, aby później móc to scalić w jeden plik wykonywalny?

2 odpowiedzi

0 głosów
odpowiedź 11 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
Tomku, zapoznaj się z literaturą przedmiotu. Twoje pytania są jednocześnie podstawowe i wymagające tłumaczenia w dużej ilości tekstu. Prata będzie dobry...
komentarz 11 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
Ja tego nie chcę zrobić w języku C++ tylko w C, to jest ta różnica. Tutaj nie mam klas obiektów. Mam nadzieje że dzisiaj się już dowiem jak to zrobić. Studenci na informatyce zwykłemu proceduralnemu C poświęcają mało uwagi i wchodzą niemal od razu w obiektowy C++. Dzisiaj mam zajęcia z doktorem, który prowadzi z nami te zajęcia to się go zapytam po wykładzie jak to zrobić, lecz  zachęcam również was do odpowiedzi na to pytanie.
komentarz 11 grudnia 2017 przez j23 Mędrzec (194,920 p.)

Ja tego nie chcę zrobić w języku C++ tylko w C, to jest ta różnica.

W kwestii kompilacji plików to tutaj nie widzę różnicy.

0 głosów
odpowiedź 11 grudnia 2017 przez criss Mędrzec (172,590 p.)

W C/C++ pliki nie mają żadnego znaczenia dla działania programu. One służą tylko do wygodnego rozłożenia kodu. Oczywiście zostało to wzięte pod uwagę w języku i stad np. słówko extern pozwalające na utworzenie zmiennej globalnej dla całego programu.

Kod dzielimy na dwa rodzaje plików: naglowkowe (*.h) i źródłowe (*.c). Pliki nagłówkowe nie są samodzielnie kompilowane. Stanowią one tylko zawartość doklejaną  (dosłownie) do kompilowanych plików źródłowych poprzez #include. Zawartością tą, w przypadku C, są deklaracje. Cały proces kompilacji opiera się na deklaracjach. Jeśli jakaś funkcja woła inną  (będącą w innym pliku) to do kompilacji wystarczy deklaracja że wołana funkcja istnieje. Kompilator ufa ci ze tak jest. Jeśli tak nie jest, to dostaniesz błąd przy linkowaniu  (brak definicji zadeklarowanej funkcji). Dlatego w plikach nagłówkowych mamy deklaracje. Po prostu doklejamy je tam gdzie trzeba za pomocą #include i mamy spokój zamiast za każdym je pisać. Obejrzyj filmiki nt. kompilacji i linkowania stąd - https://m.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb - i wszystko powinno się rozjaśnić :) Sorry ze link do strony mobilnej, jestem na telefonie.

komentarz 11 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
edycja 11 grudnia 2017 przez Tomek Wilnowski

Dzięki wielkie, że to piszesz i jesteś zainteresowany moim pytaniem, ale problem jest trochę niestety innego kalibru. To wszystko co piszesz jest racją i ja od początku próbując połączyć ze sobą powyższe pliki idę w tym właśnie kierunku. Dla bardziej wtajemniczonych próbuję zastosować model gwiazdy i rozbić funkcjonalności na mniejsze niezależne problemy z których buduję ten jeden.

Powyższy program kompiluję standardowo w konsoli (gcc main.c -I katalog gdzie znajdują się pliki -Wall -l biblioteka -l biblioteka -l biblioteka -std=c99 ). Jeśli chodzi o kompilację szukam odpowiedzi na pytanie jak skompilować tylko część programu tzw. tylko jeden moduł a potem z nich stworzyć jeden plik wykonywalny. To piszę tylko tak z ciekawości, abym mógł wiedzieć więcej i nie jest to w tej chwili najważniejsze.

Przejdźmy w tej chwili do głównego problemu z którym się spotkałem i naprawdę już długo się z nim zmagam i znajdę choćby nie wiem co jego rozwiązanie. Jeszcze raz podkreślę proceduralnie, bo jest to język C.

Wywołuję funkcję która ma mi otworzyć jedno okienko. Po ingerencji użytkownika podmieniam to okienko ta bardzo podobne, ale ze zmienionymi parametrami (zawartością zmiennych). W tym celu przed wywołaniem nowej funkcji która podmienia mi to okienko czyszczę wszystkie zmienne, (tak jakbym chciał wyłączyć program), a po otwarciu mojego pliku od nowa wszystko inicializuję, czyli zmienne wskaźnikowe i odpalam podmienione już okienko.

Wszystko działa super! Tylko, że chwila chwila, miał to być zupełnie niezależny plik, ale ja tylko w tej funkcji tak samo z czyszczeniem chcę wywołać funkcję z której tą funkcję wywołałem napotykam na błąd w postaci "nie możesz zadeklarować zmiennej która została już zadeklarowana" i kompilator wywala mi masę innych błędów których jest naprawę sporo, dlatego nie chciałem dawać, ale oto one:

gcc  main.c -I include/ -I include/windows/menu/ -I include/windows/menu/style/ -o main -Wall -std=c99 -l ncurses -l menu
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c: In function ‘sterowanie_one’:
include/windows/menu/create_menu_one.c:123:3: warning: implicit declaration of function ‘sterowanie_exif’ [-Wimplicit-function-declaration]
   sterowanie_exif();
   ^
include/windows/menu/create_menu_one.c:127:3: warning: implicit declaration of function ‘create_menu_graphic’ [-Wimplicit-function-declaration]
   create_menu_graphic();
   ^
In file included from include/windows/menu/func_menu.h:6:0,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_exif.c: In function ‘create_menu_exif’:
include/windows/menu/create_menu_exif.c:101:9: error: ‘include’ undeclared (first use in this function)
         include/windows/menu/func_menu.h:6:0
         ^
include/windows/menu/create_menu_exif.c:101:9: note: each undeclared identifier is reported only once for each function it appears in
include/windows/menu/create_menu_exif.c:101:17: error: ‘windows’ undeclared (first use in this function)
         include/windows/menu/func_menu.h:6:0
                 ^
include/windows/menu/create_menu_exif.c:101:25: error: ‘menu’ undeclared (first use in this function)
         include/windows/menu/func_menu.h:6:0
                         ^
include/windows/menu/create_menu_exif.c:101:30: error: ‘func_menu’ undeclared (first use in this function)
         include/windows/menu/func_menu.h:6:0
                              ^
include/windows/menu/create_menu_exif.c:101:41: error: expected ‘;’ before ‘:’ token
         include/windows/menu/func_menu.h:6:0
                                         ^
include/windows/menu/create_menu_exif.c: At top level:
include/windows/menu/create_menu_exif.c:115:13: warning: conflicting types for ‘sterowanie_exif’
 static void sterowanie_exif(){
             ^
include/windows/menu/create_menu_exif.c:115:13: error: static declaration of ‘sterowanie_exif’ follows non-static declaration
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:123:3: note: previous implicit declaration of ‘sterowanie_exif’ was here
   sterowanie_exif();
   ^
In file included from include/windows/menu/func_menu.h:7:0,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_graphic.c:9:6: warning: conflicting types for ‘create_menu_graphic’
 void create_menu_graphic(){
      ^
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:127:3: note: previous implicit declaration of ‘create_menu_graphic’ was here
   create_menu_graphic();
   ^
In file included from include/windows/create_menu_window.c:2:0,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:10:12: error: redefinition of ‘wybor’
 static int wybor = 0;
            ^
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:10:12: note: previous definition of ‘wybor’ was here
 static int wybor = 0;
            ^
In file included from include/windows/create_menu_window.c:2:0,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:12:13: error: redefinition of ‘create_menu_one’
 static void create_menu_one(){
             ^
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:12:13: note: previous definition of ‘create_menu_one’ was here
 static void create_menu_one(){
             ^
In file included from include/windows/create_menu_window.c:2:0,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:120:13: error: redefinition of ‘sterowanie_one’
 static void sterowanie_one(){
             ^
In file included from include/windows/menu/create_menu_exif.c:7:0,
                 from include/windows/menu/func_menu.h:6,
                 from include/windows/menu/create_menu_one.c:6,
                 from include/windows/create_menu_window.c:2,
                 from include/open.c:2,
                 from main.c:2:
include/windows/menu/create_menu_one.c:120:13: note: previous definition of ‘sterowanie_one’ was here
 static void sterowanie_one(){
             ^
makefile:2: polecenia dla obiektu 'all' nie powiodły się
make: *** [all] Błąd 1

W skrócie powyższe błędy dotyczą tego że funkcja została już wcześniej zadeklarowana. Pliki łączę według schematu:

naglowek.h

plik_1.c /* zaimportowany nagłówek zawierający plik_1 i plik_2 (deklaracje funkcji) przy czym oczywiście pisz:*/

#ifndef CREATE_MENU_H
#define CREATE_MENU_H

/* Jakieś instrukcje dla preprocesora typu np. #include */

#endif

plik_2.c  /* W którym również importuje ten sam plik naglówkowy.h */

W pliku nr 1 czyli create_menu_one.c wygląda to tak:

#include <ncurses.h>
#include <menu.h>
#include <stdlib.h>
#include <stdbool.h>

#include "func_menu.h"
#include "style/func_style.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

static int wybor = 0;

static void create_menu_one(){

static char *choices[] = {
			"Analiza Exif",
			"Analiza graficzna",
			"Analiza zgromadzonych danych",
			"Pomoc",
			"Exit",
			(char *)NULL,
		};
	
	ITEM **my_items;
	MENU *my_menu;
	WINDOW *my_menu_win;

	initscr();
	cbreak();
         noecho();
         keypad(stdscr, TRUE);
	
	/* Utworzenie podstawowego okna*/
	my_menu_win = newwin(10, 40, 4, 4);
         keypad(my_menu_win, TRUE);

	/* Wyświetlenie pomocy dla menu */
	attron(COLOR_PAIR(2));
         mvprintw(LINES - 2, 0, "Mozesz urzyc strzalek oraz klawisza enter");
         mvprintw(LINES - 1, 0, "Wcisniecie klawisza F1 powoduje wyjscie z 		programu");
         attroff(COLOR_PAIR(2));

	/* Ustawienie parametrów graficznych okna */
         style_window_colors(my_menu_win);
	
	int n_choices = 0;
	n_choices = ARRAY_SIZE(choices);
       	my_items = (ITEM **)calloc((n_choices), sizeof(ITEM *));

	for(int i = 0; i < n_choices; i++){
		my_items[i] = new_item(choices[i], choices[i]);
	}

	/* Utworzenie menu one */
         my_menu = new_menu((ITEM **)my_items);

	/* Ustawienie opcji menu one tak, aby nie wyświetlała opisu*/
         menu_opts_off(my_menu, O_SHOWDESC);

	/* Ustawienie kolorow i parametrow czcionki*/
	style_menu(my_menu);

	/* Ustawienie kolejnosci wyswietlanych okien */
         set_menu_win(my_menu, my_menu_win);
         set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
         set_menu_format(my_menu, 5, 1);

         /* Przypięcie menu do okna */
         post_menu(my_menu);

	/* Przypięcie okna */
         wrefresh(my_menu_win);

	/* funcka (my_menu_win, my_menu) */

	int c;
         while((c = getch()) != 10 )
         {       switch(c)
                 {       case KEY_DOWN:
                                 menu_driver(my_menu, REQ_DOWN_ITEM);
                                 break;
                         case KEY_UP:
                                 menu_driver(my_menu, REQ_UP_ITEM);
                                 break;
                         case KEY_NPAGE:
                                 menu_driver(my_menu, REQ_SCR_DPAGE);
                                 break;
                         case KEY_PPAGE:
                                 menu_driver(my_menu, REQ_SCR_UPAGE);
                                 break;
		       case 10: /* Enter */
                                 move(20, 0);
        	   		      clrtoeol();
			      if( item_name(current_item(my_menu)) == choices[0]){
					wybor = 0;
			      }
			      if( item_name(current_item(my_menu)) == choices[1]){
					wybor = 1;
			      }
			      if( item_name(current_item(my_menu)) == choices[2]){
					wybor = 2;
			      }
			      if( item_name(current_item(my_menu)) == choices[3]){
					wybor = 3;
			      }
			      if( item_name(current_item(my_menu)) == choices[4]){
					wybor = 4;
			      }
			      break;
                 }

                 wrefresh(my_menu_win);
         }
         
         pos_menu_cursor(my_menu);
	unpost_menu(my_menu);
         free_menu(my_menu);
	endwin();
}

static void sterowanie_one(){
	create_menu_one();
	if( wybor == 0){
		sterowanie_exif();
	}		
	
	if( wybor == 1){
		create_menu_graphic();
	}
	
	/*if( item_name(current_item(my_menu)) == choices[2]){
		unpost_menu(my_menu);
      
		create_menu_date();
	}
	if( item_name(current_item(my_menu)) == choices[3]){
		unpost_menu(my_menu);
     
		help();
	}
	if( item_name(current_item(my_menu)) == choices[4]){
		unpost_menu(my_menu);
      
		exit();
	} */
	
	system("clear");
}
Czyszczenie jest w liniach 113-118
komentarz 11 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
edycja 11 grudnia 2017 przez Tomek Wilnowski

Plik nr 2 wygląda tak:


#include <ncurses.h>
#include <menu.h>
#include <stdlib.h>

#include "func_menu.h"
#include "style/func_style.h"
#include "create_menu_one.c"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

static int wybor_2 = 0;

static void create_menu_exif(){
 	char *choices[] = {
                  	"Pszeszukanie dysku w poszukiwaniu danych exif",
			"Zapis znalezionych scierzek do pliku",
			"Usuniecie danych exif",
			"Cofnij",
			(char *)NULL,
		};

	ITEM **my_items;
	MENU *my_menu;
	WINDOW *my_menu_win;

	initscr();
	cbreak();
         noecho();
         keypad(stdscr, TRUE);
	
	/* Utworzenie podstawowego okna*/
	my_menu_win = newwin(10, 40, 4, 4);
         keypad(my_menu_win, TRUE);

	/* Wyświetlenie pomocy dla menu */
	attron(COLOR_PAIR(2));
         mvprintw(LINES - 2, 0, "Mozesz urzyc strzalek oraz klawisza enter");
         mvprintw(LINES - 1, 0, "Wcisniecie klawisza F1 powoduje wyjscie z 		programu");
         attroff(COLOR_PAIR(2));

	/* Ustawienie parametrów graficznych okna */
         style_window_colors(my_menu_win);
	
	int n_choices = 0;
	n_choices = ARRAY_SIZE(choices);
        	my_items = (ITEM **)calloc((n_choices), sizeof(ITEM *));

	for(int i = 0; i < n_choices; i++){
		my_items[i] = new_item(choices[i], choices[i]);
	}

	/* Utworzenie menu one */
         my_menu = new_menu((ITEM **)my_items);

	/* Ustawienie opcji menu one tak, aby nie wyświetlała opisu*/
         menu_opts_off(my_menu, O_SHOWDESC);

	/* Ustawienie kolorow i parametrow czcionki*/
	style_menu(my_menu);

	/* Ustawienie kolejnosci wyswietlanych okien */
         set_menu_win(my_menu, my_menu_win);
         set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
         set_menu_format(my_menu, 5, 1);

         /* Przypięcie menu do okna */
         post_menu(my_menu);

	/* Przypięcie okna */
         wrefresh(my_menu_win);

int c;
         while((c = getch()) != 10 )
         {       switch(c)
                 {       case KEY_DOWN:
                                 menu_driver(my_menu, REQ_DOWN_ITEM);
                                 break;
                         case KEY_UP:
                                 menu_driver(my_menu, REQ_UP_ITEM);
                                 break;
                         case KEY_NPAGE:
                                 menu_driver(my_menu, REQ_SCR_DPAGE);
                                 break;
                         case KEY_PPAGE:
                                 menu_driver(my_menu, REQ_SCR_UPAGE);
                                 break;
		       case 10: /* Enter */
                                 move(20, 0);
        	   		      clrtoeol();
			      if( item_name(current_item(my_menu)) == choices[0]){
					wybor_2 = 0;
			      }
			      if( item_name(current_item(my_menu)) == choices[1]){
					wybor_2 = 1;
			      }
			      if( item_name(current_item(my_menu)) == choices[2]){
					wybor_2 = 2;
			      }
			      if( item_name(current_item(my_menu)) == choices[3]){
					wybor_2 = 3;
			      }
		      include/windows/menu/func_menu.h:6:0
		      break;
                 }

                 wrefresh(my_menu_win);
         }
	
	pos_menu_cursor(my_menu);
	unpost_menu(my_menu);
         free_menu(my_menu);
	endwin();
	system("clear");
}

static void sterowanie_exif(){
	create_menu_exif();
	if( wybor_2 == 0){
		//create_menu_exif();
	}		
	
	if( wybor_2 == 3){
		sterowanie_one();
	}
	
	/*if( item_name(current_item(my_menu)) == choices[2]){
		unpost_menu(my_menu);
      
		create_menu_date();
	}
	if( item_name(current_item(my_menu)) == choices[3]){
		unpost_menu(my_menu);
     
		help();
	}
	if( item_name(current_item(my_menu)) == choices[4]){
		unpost_menu(my_menu);
      
		exit();
	} */
	
	system("clear");
}

Czyszczenie jest w liniach od 108-112.

Problem jest przy ponownym wywołaniu tej samej funkcji, a te funkcje mają się po prostu podmieniać.

komentarz 12 grudnia 2017 przez j23 Mędrzec (194,920 p.)

Jeśli chodzi o kompilację szukam odpowiedzi na pytanie jak skompilować tylko część programu tzw. tylko jeden moduł a potem z nich stworzyć jeden plik wykonywalny.

Kompilujesz moduł do pliku obiektowego wywołaniem:

gcc -c plik1.c plik2.c plik3.c ... -o nazwa_modulu.o

Później aplikację składasz wywołaniem:

gcc nazwa_modulu1.o nazwa_modulu2.o ... -o aplikacja

komentarz 12 grudnia 2017 przez criss Mędrzec (172,590 p.)
@OP:

Słuchaj, jeśli byś wszystko robił wg tego co napisałem w odpowiedzi, to wszystko byłoby ok. Nie wiem dlaczego uważasz, że problem jest "innego kalibru".

Btw.: 2. plik, linia 101. Co to tam robi?

Ciężko pomagać z zewnątrz w temacie wielu plików.. musiałbym sobie jakoś odtworzyć twoja strukturę plików , #include-y itd. I jeszcze jedno: dlaczego próbujesz includowac plik c? Pisałem do czego służą pliki nagłówkowe i #include. Takie dziwne zabawy nigdy się dobrze nie kończą. Prawdopodobnie z tego wynika przynajmniej część tych błędów redefinicji.
komentarz 15 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
edycja 16 grudnia 2017 przez Tomek Wilnowski

Dobra z racji tego że problem udało mi się już rozwiązać to z góry opiszę jak to zrobiłem, dziękuję wam również za pomoc, bo mieliście rację, ale to nie było wszystko co trzeba było zrobić.

Schemat programu:

main.c
main.h
|
|____pierwszy_moduł
|        |
|        |_____pierwszy_plik.c
|        |_____drugi_plik.c
|        |_____trzeci_plik.c
|        |_____nagłówek.h
|
|____drugi_moduł
|        |
|        |_____pierwszy_plik.c
|        |_____drugi_plik.c
|        |_____nagłówek.h
|
|____pomoc

W pliku nagłówkowym deklarujemy zmienne statyczne wskaźnikowe, których używamy we wszystkich plikach danego modułu. Jeśli chcemy wykonać czyli po prostu odnieść się do innego pliku z danego modułu to czyścimy pamięć, ustawione w naszej funkcji zmienne czyścimy lub usuwamy jeśli można, a nasze statyczne wskaźniki ustawiamy na NULL, abyśmy mogli ich znowu użyć i zmienić ich wartość w naszej aktualnie używanej funkcji.

pliki z rozszerzeniem " .c" wyglądają tak:

#include "nagłówek.h"

void pierwsza_funkcja(){
       /* nasza wykonywana procedura */
}

pliki nagłówkowe z rozszerzeniem " .h" wyglądają tak:

#ifndef PIERWSZY_NAGŁÓWEK
#define PIERWSZY_NAGŁÓWEK

/* importujemy biblioteki które są widoczne tak jakby było powsadzane w każdy plik typu .c z naszego modułu */
#include <stdlib.h>
#include <string.h>

/* dodatkowo można zaimportować nagłówki zewnętrznych bibliotek */

/" deklarujemy zmienne statyczne wskaźnikowe "/
static typ *pierwsza_zmienna;
static typ *druga_zmienna;

/* tutaj trzeba dodać nagłówkowe deklaracje wszystkich funkcji których użyło się w module */
void pierwsza_funkcja();

#endif

Kompilacja programu wygląda tak:

1. Możemy spróbować skompilować cały program poleceniem:

gcc main.c pierwszy_moduł/pierwszy_plik.c pierwszy_moduł/drugi_plik.c -l zewnętrzna_biblioteka -l zewnętrzna_biblioteka -o nazwa_pliku_wynikowego - Wall

/* nie trzeba linkować dla naszego kompilatora plików nagłówkowych */

2. Kompilując część programu, robimy to poleceniem podanym przez j23

komentarz 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
Na głowie to postawiłeś. Metodą prób i błędów, stworzyłeś niezłego potwora. Nie hermetyzuje wskaźników i bazuje (jak widzę) na "dobrej woli konsolidatora".

Wróć do rozdziałów o łączności zewnętrznej i wewnętrznej, static/extern, definicja/deklaracja. Tą drogą radzę Ci nie idź.
komentarz 16 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
Hermetyzacja dotyczy programowania obiektowego a nie proceduralnego. Szukałem na temat programowania proceduralnego na prawdę długo materiałów (3 tygodnie). Znalazłem w internecie jeden komentarz który naprowadził mnie na tego typu rozwiązanie.

Później przeanalizowałem kody programów napisanych procedura lnie w C na githab, bo nie mogłem znaleźć w bibliotece dobrych podręczników które też mi nie pomagały. Były tam książki stare o tym jak opisywać mikro kontrolery, ale nie o tym jak pisać duże programy.

Grzebiąc na githab doszedłem do tego jak pliki się komunikują w proceduralnym C. Modułowość ty tworzysz sobie sam  i ona nie ma nic wspólnego z modułowością obiektową. Każda twoja funkcja w programie tak na prawdę jest najwyżej zależna tylko od plika nagłówkowego .h w którym siedzą wszystkie deklaracje innych funkcji które masz zapisane w swoim katalogu w którym znajdują się te funkcje i ten plik .h.

Ten schemat który dałem to jest kwintesencja tego wszystkiego, pominąłem tam jeden pliczek main.h który trzeba zaimportować w main.c ale to już poprawiam.

Tutaj żągluje się wywołaniami funkcji, zbiór funkcji tworzą jeden program.

Na programowanie obiektowe przyjdzie czas innym razem.
komentarz 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)

Hermetyzacja dotyczy programowania obiektowego a nie proceduralnego.

Bzdura. Biblioteki czyli moduły podlegają hermetyzacji. A już szczególnie w takim języku jak C który ma ograniczenia przestrzeni nazewniczych. Otwórz dowolny nagłówek biblioteki standardowej i popatrz jak jest zbudowany. Szukasz materiałów na ten temat, zadaj pytanie.

komentarz 16 grudnia 2017 przez Tomek Wilnowski Użytkownik (610 p.)
Możliwe ja przed chwilą na Wikipedii znalazłem notkę o hermetyzacji, bo nie wiedziałem co znaczy to słowo. Znalazłem, że jest to jedno z założeń programowania obiektowego, ale dobra co w takim razie proponowałbyś zrobić tutaj proceduralnie? Pokaż na początek schemat plików taki jaki ja zrobiłem a potem je opisz.
komentarz 16 grudnia 2017 przez mokrowski Mędrzec (155,460 p.)
Dostałeś odpowiedź via prv.

Podobne pytania

0 głosów
0 odpowiedzi 262 wizyt
pytanie zadane 20 stycznia 2023 w C i C++ przez Zuzan Początkujący (390 p.)
0 głosów
1 odpowiedź 183 wizyt
+1 głos
1 odpowiedź 190 wizyt

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...