Почему мы не можем инициализировать элементы внутри структуры? - PullRequest
48 голосов
/ 22 октября 2008

Почему мы не можем инициализировать элементы внутри структуры?

пример:

struct s {
   int i = 10;
};

Ответы [ 6 ]

38 голосов
/ 22 октября 2008

Если вы хотите инициализировать нестатические элементы в struct декларации :

В C ++ (не в C) structs почти синонимичны классам и могут иметь члены, инициализированные в конструкторе.

struct s {
    int i;

    s(): i(10)
    {
    }
};

Если вы хотите инициализировать экземпляр :

В C или C ++:

struct s {
    int i;
};

...

struct s s_instance = { 10 };

C99 также имеет функцию, называемую назначенными инициализаторами:

struct s {
    int i;
};

...

struct s s_instance = {
    .i = 10,
};

Существует также расширение GNU C, которое очень похоже на инициализаторы, обозначенные C99, но лучше использовать что-то более переносимое:

struct s s_instance = {
    i: 10,
};
33 голосов
/ 22 октября 2008

Прямой ответ заключается в том, что определение структуры объявляет тип, а не переменную, которую можно инициализировать. Ваш пример:

struct s { int i=10; };

Это не объявляет какую-либо переменную - оно определяет тип. Чтобы объявить переменную, вы должны добавить имя между } и ;, а затем инициализировать его:

struct s { int i; } t = { 10 };

Как отметили Шекеры, в C99 вы также можете использовать назначенные инициализаторы (что является замечательным улучшением - однажды C догонит другие функции, которые Fortran 66 имел для инициализации данных, в основном повторяя инициализаторы заданным числом раз). С этой простой структурой нет никакой выгоды. Если у вас есть структура, скажем, с 20 членами, и вам нужно только инициализировать один из них (скажем, потому что у вас есть флаг, который указывает, что остальная часть структуры инициализирована или нет), это более полезно:

struct s { int i; } t = { .i = 10 };

Эта нотация также может использоваться для инициализации союзов, чтобы выбрать, какой элемент объединения инициализируется.

13 голосов
/ 31 мая 2016

Обратите внимание, что в C ++ 11 теперь разрешено следующее объявление:

struct s {
   int i = 10;
};

Это старый вопрос, но он занимает высокое место в Google и может быть уточнен.

8 голосов
/ 22 октября 2008

Редактировать: Первоначально вопрос был помечен c++, но автор сказал, что он касается c, поэтому я пометил вопрос, но я оставляю ответ, хотя ...

В C ++ struct - это просто class, по умолчанию public вместо private для членов и наследования.

C ++ только позволяет встроенным элементам static const быть встроенными, другие члены должны быть инициализированы в конструкторе, или struct является POD в списке инициализации (при объявлении переменной) .

struct bad {
    static int answer = 42; // Error! not const
    const char* question = "what is life?"; // Error! not const or integral
};

struct good {
    static const int answer = 42; // OK
    const char* question;
    good() 
        : question("what is life?") // initialization list
        { }
};

struct pod { // plain old data
    int answer;
    const char* question;
};
pod p = { 42, "what is life?" };
2 голосов
/ 14 марта 2016

Мы не можем инициализировать, потому что, когда мы объявили какую-либо структуру, чем на самом деле, что мы делаем, просто сообщите компилятору об их наличии, т.е. для этого не выделена память, и если мы инициализируем элемент без памяти для этого. Обычно, что происходит, когда мы инициализируем любую переменную, которая зависит от места, где мы объявили переменную, компилятор выделяет память для этой переменной.

int a = 10;
  • если это автоматически, чем в стековой памяти будет выделяться
  • если это глобально, чем в разделах данных память собирается выделять

Итак, какая память требуется для хранения этих данных, но в случае структуры нет памяти, поэтому невозможно ее инициализировать.

0 голосов
/ 31 мая 2016

Как вы сказали, это просто член, а не переменная. Когда вы объявляете переменную, компилятор также предоставляет пространство памяти для тех переменных, где вы можете поместить значения. В случае a члена структуры компилятор не выделяет для него место в памяти, поэтому вы не можете присвоить значения элементам структуры, если не создадите переменную этого типа структуры.

...