LINUX.ORG.RU

Как объявить extern struct


0

1

Здравствуйте, не сочтите за наглость, как объявить структуры first и last чтобы к ним можно было обращаться из любого файла? я совсем запутался с обьявлениями в заголовочных файлах, и сама структура как бы не «глобальна»

//global.h

#ifndef ALL_H
#define ALL_H

    extern struct point {
        int x;
        int y;
    } first, last;
    
    extern void first_inc_y();
    extern void first_inc_x();

#endif
//main.c

#include "global.h"
#include <stdio.h>

int main(){
	first.y = 0;                // доступно из main
	first.x = 0;
	first_inc_x();
	printf("%d\n",last.x);     // доступно из main
	return 0;
}
//new.c

#include  "global.h"

void first_inc_y(){
    first.y += 1;           // доступно из new
}
//step.c

#include  "global.h"

void first_inc_x(){
    first.x += 1;           // доступно из step
}


Последнее исправление: sadavod (всего исправлений: 2)

гдето объявляете структуру как обычно, struct point {} first, last;

в местах использования объявляете как extern struct point first;

x0r ★★★★★
()
Ответ на: комментарий от x0r

спасибо за такой оперативный ответ, на данном коде не затруднит показать как это делается по «человечески» т.е. правильно?

sadavod
() автор топика

Можно, кстати, сделать через typedef:

    typedef struct point {
        int x;
        int y;
    } myPoint;
    extern myPoint first, last;
А в main:
myPoint first, last;

Eddy_Em ☆☆☆☆☆
()

> как объявить структуры first и last чтобы к ним можно было обращаться из любого файла?

напиши

struct point first, last;
в любом из *.c-файлов, на твоё усмотрение. можешь даже инициализировать их там начальными значениями.

arsi ★★★★★
()
Ответ на: комментарий от Eddy_Em

а при чем тут typedef ?

вот так тоже можно

    struct point {
        int x;
        int y;
    } myPoint;
    extern struct myPoint first, last;

более того, еще сам Линус говорил, что typedef struct в Си это зло, так как не позволяет отличить простой тип от составного.

Reset ★★★★★
()
Ответ на: комментарий от sadavod

по скольку в данном случае оно в хедере, то препроцессор воткнет код из хедера в сырцы с #include «global.h» и вы получите extern ... в каждом модуле. имхо оно даже не слинкуется.

т.е. надо чтото такое:

//global.h

#ifndef ALL_H
#define ALL_H

    struct point {
        int x;
        int y;
    };

    void first_inc_y();
    void first_inc_x();

#endif
//main.c

#include "global.h"
#include <stdio.h>

struct point first, last;

int main(){
   first.y = 0;
   first.x = 0;
   first_inc();
   printf("%d\n",last.x);
   return 0;
}
//new.c

#include "global.h"

void first_inc_y(){
    first.y += 1;
}
//step.c

#include "global.h"

void first_inc_x(){
    first.x += 1;
}
// hui.c

#include "globals.h"

extern struct point first, last;
extern void first_inc_y();
extern void first_inc_x();

void
foobar()
{
    last.x++;
    first_inc_x();
    first.y++;
    first_inc_y();
}
x0r ★★★★★
()
Ответ на: комментарий от arsi

а им не надо дописывать типа они внешнии?

extern struct point first, last;

и саму структуру нет надобности делать с extern, мне нужны структуры как бы правилоно выразиться «глобальные» , т.е. одна из них может изменить свои переменные в любом файле, и эти изменения хотелось бы увидеть так же во всех файлах.

Прошу извинить что так тупо объясняю.

sadavod
() автор топика
Ответ на: комментарий от sadavod

> а им не надо дописывать типа они внешнии?

extern экспортирует существующие символы из какого-то (неизвестно какого) источника. он не вводит их.

без extern (и без static, ессесно) ты как раз и вводишь эти символы как глобальные. хотя есть нюансы, но тебе пока о них лучше не знать ;)

arsi ★★★★★
()
Ответ на: комментарий от Reset

так как не позволяет отличить простой тип от составного.

лично мне больше нравится с typedef

true_admin ★★★★★
()
Ответ на: комментарий от arsi

фуффф разобрался вроде-бы, спасибо что помогли!

sadavod
() автор топика
Ответ на: комментарий от Reset

сам Линус говорил, что typedef struct в Си это зло

Зато удобно. И GTK - тому пример :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Reset

> более того, еще сам Линус говорил, что typedef struct в Си это зло, так как не позволяет отличить простой тип от составного.

IMO, Линус тут немного не прав. Зачем различать простые и составные типы?
User defined тип - это чёрная коробка, торчащая наружу парой функций, которые «знают» как работать с типом и как его преобразовать при необходимости в простые типы (если возможно). Если подходить с таким паттерном, то изменения внутри типа будут практически прозрачны для остального приложения - вплоть до смены union, enum на struct или на любой другой простой тип (and vice versa).

Slavaz ★★★★★
()

>> как объявить структуры first и last чтобы к ним можно было обращаться из любого файла

Объявление объекта как extern означает, что он определён где-то в другом месте и линкуется при сборке объектных файлов. В вашем примере две структуры объявлялись в заголовочном файле, в определении типа struct point extern можно опустить.

Вам нужно было в одном из .c файлов определить first и last, а в global.h оставить extern struct point first, last.

сама структура как бы не «глобальна»

чтобы сделать объект глобальным его нужно определить один раз и вне какой-либо функции

sched
()
Ответ на: комментарий от Slavaz

разрешите еще вопрос, не нахожу ответа у гула, можно структуры влаживать друг в друга, чтобы получать новые более сложные?

типа poin.trapecia.height = 10;

struct point {
        int x1;
        int y1;
        int x2;
        int y1;
        int x3;
        int y3;
        int x4;
        int y4;
      struct def {
                int height;
                int widtch;
      };
} trapecia;

как тогда они объявляться должны?

sadavod
() автор топика
Ответ на: комментарий от Reset

сам Линус говорил, что typedef struct в Си это зло, так как не позволяет отличить простой тип от составного.

зато без этого писать на сях ооп еще неудобнее =)

stevejobs ★★★★☆
()
Ответ на: комментарий от sadavod

разрешите еще вопрос, не нахожу ответа у гула, можно структуры влаживать друг в друга, чтобы получать новые более сложные?

Вариант первый. Объявить два типа. Внутри второго типа использовать поле первого типа:

typedef struct {float x, y, z;} point_t;
typedef struct {point_t start, end;} segment_t;

segment_t some_segment;
segment_t another_segment;

Вариант второй. Если нам не нужны отдельные типы для использования в разных местах, объявляем так:

struct {
  struct {
    int left, top, right, bottom;
  } box;
  int z;
} window_position;
geekless ★★
()
Ответ на: комментарий от cipher

как ни странно, почти все крупные проекты на сях используют ооп

Reset ★★★★★
()
Ответ на: комментарий от Slavaz

Впервые вижу так много комметариев в коде и пример, очень даже интересный, много из него почерпнул, а по сути typedef просто сокращалка слов, своего рода shot url для кода.

sadavod
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.