2008-10-22 2 views
43

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

пример:

struct s { 
    int i = 10; 
}; 
+1

Потому что это определение, а не декларация – Archmede 2017-05-01 23:18:05

+1

С недавним C++ мы можем - см. Ответы ниже. (Недавний, как в последние десятилетия C++.) Я знаю, что этот вопрос был исправлен C, но ответы на C++ - это то, что многие из нас ищут ... – sage 2017-06-20 16:22:56

ответ

34

Если вы хотите инициализировать нестатические членов в 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 desig NAT, Инициализаторы, но это лучше использовать что-то более портативное:

struct s s_instance = { 
    i: 10, 
}; 
+0

Не могли бы вы рассказать о своем последнем примере? – barnes 2016-02-03 04:01:48

8

Edit: Вопрос изначально был помечен 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?" }; 
32

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

struct s { int i=10; }; 

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

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

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

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

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

2

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

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

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

+1

Хотя ваш ответ кажется приятным, вы должны попытаться сделать его более понятным, исправляя свои формулировки, например! – gsamaras 2016-03-14 18:20:09

8

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

struct s { 
    int i = 10; 
}; 

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

0

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

Смежные вопросы