Powinny wejść definicje struct.h lub.plik c?

Widziałem zarówno pełne definicje struct s w nagłówkach, jak i tylko deklaracje-czy jest jakaś przewaga jednej metody nad drugą?

Jeśli to robi różnicę, Zwykle wpisuję taką strukturę w .h

typedef struct s s_t;

Edit

Aby było jasne, opcjami są deklaracja w pliku nagłówkowym i definicja w klasie lub zarówno deklaracja, jak i definicja w pliku nagłówkowym. Oba powinny skutkować tą samą użytecznością, nawet jeśli jeden jest przez linkowanie, nie powinien oni?


Widzę wiele prawie duplikatów, np. tutaj ale nie ma dokładnych dopasowań. Proszę mnie poprawić, jeśli się mylę w tym względzie.

Author: Community, 2011-06-11

6 answers

Prywatne struktury dla tego pliku powinny znaleźć się w .plik c, z deklaracją w .plik h, jeśli są one używane przez jakiekolwiek funkcje w .h .

Struktury publiczne powinny iść w .plik H.

 81
Author: τεκ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 16:11:09

Oba powinny skutkować tą samą użytecznością, nawet jeśli jeden jest przez połączenie, prawda?

Nie, Nie, Jeśli rozważasz inne .pliki c zawierające ten sam nagłówek. Jeśli definicja struktury nie jest widoczna dla kompilatora, szczegóły tej definicji nie mogą być użyte. Deklaracja bez definicji (np. just struct s;) powoduje niepowodzenie kompilatora, jeśli coś próbuje zajrzeć do wnętrza struct s, jednocześnie pozwalając mu na np. kompilację struct s *foo; (o ile foo nie jest później zdelegalizowana).

Porównaj te wersje api.h i api.c:

Definition in header:                 Definition in implementation:
+---------------------------------+   +---------------------------------+
| struct s {                      |   | struct s;                       |
|     int internal;               |   |                                 |
|     int other_stuff;            |   | extern void                     |
| };                              |   | api_func(struct s *foo, int x); |
|                                 |   +---------------------------------+
| extern void                     |   +---------------------------------+
| api_func(struct s *foo, int x); |   | #include "api.h"                |
+---------------------------------+   |                                 |
+---------------------------------+   | struct s {                      |
| #include "api.h"                |   |     int internal;               |
|                                 |   |     int other_stuff;            |
| void                            |   | };                              |
| api_func(struct s *foo, int x)  |   |                                 |
| {                               |   | void                            |
|     foo->internal = x;          |   | api_func(struct s *foo, int x)  |
| }                               |   | {                               |
+---------------------------------+   |     foo->internal = x;          |
                                      | }                               |
                                      +---------------------------------+

Ten klient API działa z jedną z wersji:

#include "api.h"

void good(struct s *foo)
{
    api_func(foo, 123);
}

Ten grzebie w szczegółach implementacji:

#include "api.h"

void bad(struct s *foo)
{
    foo->internal = 123;
}

, która będzie działać z wersją "definition in header", ale nie z wersją "definition in implementation", ponieważ w tym ostatnim przypadku kompilator nie ma widoczności układu struktury:

$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$

Tak więc " definicja w implementacji" wersja chroni przed przypadkowym lub celowym nadużyciem prywatnych szczegółów implementacji.

 55
Author: Matthew Slattery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 17:18:26

Jeśli struktura ma być używana przez inne jednostki kompilacji (.pliki c), umieść go w pliku nagłówkowym, dzięki czemu możesz dołączyć ten plik nagłówkowy wszędzie tam, gdzie jest to potrzebne.

Jeśli struktura jest używana tylko w jednej jednostce kompilacji (.plik c), umieszczasz go w tym .plik C.

 5
Author: nos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 16:10:30

Chodzi o to, że umieszczenie go w pliku nagłówkowym pozwala na użycie struktury (lub innej definicji) z wielu plików źródłowych, po prostu przez włączenie tego pliku nagłówkowego.

Ale jeśli jesteś pewien, że będzie używany tylko z jednego pliku źródłowego, to naprawdę nie robi to żadnej różnicy.

 1
Author: Jonathan Wood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 16:10:29

Umieściłem je w pliku C, aby uczynić go bardziej zorientowanym obiektowo, zobacz ten artykuł .

 0
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 16:09:28

Ogólnie rzecz biorąc, nie wydaje mi się, że to robi wielką różnicę, czy umieścisz je w nagłówku, czy w plikach źródłowych. Jeśli jednak potrzebujesz dostępu do elementów struktury z wielu plików źródłowych, łatwiej jest umieścić ją w pliku nagłówkowym i dołączyć ją z innych plików, w których struktura jest potrzebna.

 -2
Author: Frxstrem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-11 16:15:25