Как объявить глобальную переменную для анонимной структуры в C? - PullRequest
0 голосов
/ 12 сентября 2018

Я использую Pelles C в Windows 8.1.

Как объявить одну глобальную переменную для структуры в C?

Код 1: он работает, но я не хочу, чтобы какой-либо другой объект того же типа создавался. Если у кода 2 проблемы, то мне придется использовать этот.

Single.h

struct single{
    int x;
};

extern struct single oneAndOnly;

void initSingle(void);
void printSingle(void);

Single.c

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

struct single oneAndOnly;

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}

main.C

#include "Single.h"
int main()
{
    initSingle();
    printSingle();
    return 0;
}

Код 2: это работает, но я не совсем уверен относительно комбинации объявления и определения переменной в заголовочном файле. Это вызовет проблемы? Я не получаю ошибку, хотя.

Single.h

struct{
    int x;
}oneAndOnly;

void initSingle(void);
void printSingle(void);

Single.c

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

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}

Main.c такой же, как в коде 1.

Могу ли я без проблем использовать код 2?


Может кто-нибудь сказать мне, почему код 2 работает, когда я и многие другие думали, что это не будет?


Спасибо всем за все ваши комментарии, идеи и ответы

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Ни одна из ваших попыток не сработает на практике.

С помощью, например, gcc или clang я могу просто сделать

typeof(oneAndOnly) secondInstance;

gcc также поддерживает

__auto_type secondInstance = oneAndOnly;

(неуверен в clang).

Даже если рассматриваемый компилятор не поддерживает эти расширения, я могу просто скопировать / вставить объявление анонимной структуры из заголовка.

Тем не менее, я нене вижу того, что мешает другим объектам того же типа.В Java имеет смысл сделать конструктор private, потому что конструктор имеет поведение, использование которого вы можете захотеть ограничить, но в структурах C это просто тупые наборы данных.

0 голосов
/ 12 сентября 2018

Существует третий вариант, который может представлять интерес.

Он полностью скрывает struct single в Single.c. Следовательно, случайный доступ невозможен.

Single.h

void initSingle(void);
void printSingle(void);

Single.c:

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

struct Single {
    int x;
};
static struct Single oneAndOnly;

void initSingle(void)
{
    oneAndOnly.x = 10;
}
void printSingle(void)
{
    printf("x = %d\n", oneAndOnly.x);
}

main.c:

#include "Single.h"

int main()
{
    initSingle();
    printSingle();
    return 0;
}

Демонстрация в реальном времени на Wandbox

На самом деле, этот подход похож на P__J __ . Я просто слишком медленно нажимал кнопку Отправить.


Мне понадобилось некоторое время, чтобы понять, что решение в квесте должно предотвратить (случайную) вторую переменную типа oneAndOnly.

«Скрытие» struct в файле C со статическим экземпляром, вероятно, лучшее, что может быть в C. Даже примеры счетчиков в ответе melpomene не должны работать в этом случае.

Если требуется доступ на чтение / запись к одному экземпляру, я бы добавил что-то вроде функций "getter" / "setter".

Это напомнило мне шаблон Singleton , хотя я не уверен, является ли это законным использованием для неOO-языка, такого как C. Немного погуглив, я обнаружил (также) Как создать синглтон в C? , о котором я считаю полезным.


Я немного погуглил по фактическому вопросу ОП, действителен ли ее / его Код 2. Я подозревал что-то похожее на дублированное определение (может быть, потому что я слишком долго работал на C ++ в повседневной работе).

На самом деле, я попробовал код 2 OP в Wandbox & ndash; нет повторяющегося определения проблемы. Наконец, я обнаружил Являются ли глобальные переменные внешними по умолчанию или это эквивалентно объявлению переменной с внешним в глобальных переменных? и пришел к выводу, что с кодом 2 тоже должно быть все в порядке.

Ограничение состоит в том, что Code 2 допускает только инициализацию по умолчанию (заполнение нулями, если я правильно помню). Как только инициализатор добавлен, компилятор жалуется (как и ожидалось), поскольку он включается несколько раз.

0 голосов
/ 12 сентября 2018

Вы вызываете функцию в другом модуле компиляции.Он использует глобальную переменную, а не вашу основную программу.Таким образом, вам даже не нужно знать структуру данных и переменную, так как вы новее используете любой из них в своей основной программе.

вы можете уменьшить его до:

void initSingle(void);
void printSingle(void);

int main()
{
    initSingle();
    printSingle();
    return 0;
}

и

#include <stdio.h>

struct{
    int x;
}oneAndOnly;

static struct single oneAndOnly;

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...