Подтвердить что ты не робот

Различия между инициализацией, определением, объявлением переменной

Прочитав question, я знаю различия между декларацией и определением. Значит ли это означает, что определение равно объявлению плюс инициализация?

4b9b3361

Ответ 1

Декларация

Декларация, как правило, относится к введению нового имени в программе. Например, вы можете объявить новую функцию, описав ее "подпись":

void xyz();

или объявить неполный тип:

class klass;
struct ztruct;

и, что не менее важно, объявить объект:

int x;

В стандарте С++ описывается в §3.1/1 как:

Объявление (раздел 7) может ввести одно или несколько имен в единицу перевода или имена редизайна, введенные предыдущими объявлениями.

Определение

Определение - это определение ранее объявленного имени (или это может быть как определение, так и объявление). Например:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

В частности, стандарт С++ определяет его в § 3.1/1 как:

Объявление - это определение, если оно не объявляет функцию без указания тела функций (8.4), содержит спецификатор extern (7.1.1) или спецификацию привязки25 (7.5) и ни инициализатор, ни тело функции, он объявляет статический член данных в определении класса (9.2, 9.4), это объявление имени класса (9.1), это непрозрачное объявление enum (7.2), оно является параметром шаблона (14.1), оно объявление параметра (8.3.5) в объявлении функции, которое не является декларатором определения функции, или оно является объявлением typedef (7.1.3), декларацией alias (7.1.3), декларацией использования (7.3.3), static_assert-декларация (раздел 7), объявление атрибута (раздел 7), декларация с пустым (раздел 7) или директива using (7.3.4).

Инициализация

Инициализация означает "присвоение" значения во время построения. Для общего объекта типа T он часто встречается в форме:

T x = i;

но в С++ это может быть:

T x(i);

или даже:

T x {i};

с С++ 11.

Заключение

Значит ли это означает, что определение равно объявлению плюс инициализация?

Это зависит. О чем вы говорите. Если вы говорите об объекте, например:

int x;

Это определение без инициализации. Вместо этого, это определение с инициализацией:

int x = 0;

В определенном контексте не имеет смысла говорить о "инициализации", "определении" и "декларации". Если вы говорите о функции, например, инициализация не означает много.

Итак, ответ нет: определение автоматически не означает декларацию плюс инициализацию.

Ответ 2

Декларация говорит, что "эта вещь существует где-то":

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

Определение говорит, что "эта вещь существует здесь, запомните ее":

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

Инициализация необязательна в точке определения для объектов и говорит "вот начальное значение для этой вещи":

int bar = 0;     // variable
int T::baz = 42; // static member variable

Иногда это возможно в точке объявления:

struct T
{
   static int baz = 42;
};

& hellip; но это касается более сложных функций.

Ответ 3

Для C, по крайней мере, для C11 6.7.5:

Объявление определяет интерпретацию и атрибуты набора идентификаторы. Определение идентификатора является декларацией для этого идентификатор, который:

  • для объекта, заставляет хранилище быть зарезервированным для этого объекта;

  • для функции включает тело функции;

  • для константы перечисления, является (единственным) объявлением идентификатора;

  • для имени typedef, является первым (или единственным) объявлением идентификатора.

Per C11 6.7.9.8-10:

Инициализатор определяет начальное значение, хранящееся в объекте... if объект, который имеет автоматическое хранилище, не инициализируется явно, его значение неопределенно.

Итак, в целом, декларация вводит идентификатор и предоставляет информацию об этом. Для переменной определение - это объявление, которое выделяет память для этой переменной.

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

Итак, если вы определяете автоматическую переменную без указания начального значения для нее, например:

int myfunc(void) {
    int myvar;
    ...

Вы определяете его (и, следовательно, также объявляете его, поскольку определения являются декларациями), но не инициализируют его. Поэтому определение не равно объявлению плюс инициализация.

Ответ 4

"То есть означает, что определение равно объявлению плюс инициализация."

Не обязательно, ваше объявление может быть без инициализации любой переменной, например:

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 }