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

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

52

Решение

декларация

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

void xyz();

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

class klass;
struct ztruct;

и последнее, но не менее важное: объявить объект:

int x;

В стандарте C ++ это описано в п. 3.1 / 1 как:

Декларация (пункт 7) может вводить одно или несколько имен в единицу перевода или переименовывать имена, введенные в предыдущих декларациях.

Определение

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

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

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

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

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

Инициализация относится к «присваиванию» значения во время построения. Для универсального объекта типа T, это часто в форме:

T x = i;

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

T x(i);

или даже:

T x {i};

с C ++ 11.

Заключение

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

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

int x;

Это определение без инициализации. Ниже приведено определение с инициализацией:

int x = 0;

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

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

69

Другие решения

Декларация гласит: «Эта вещь где-то существует»:

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;
};

… но это становится все более сложным.

28

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

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

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

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

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

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

Согласно C11 6.7.9.8-10:

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

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

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

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

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

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

4

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

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

 void helloWorld(); //declaration or Prototype.

void helloWorld()
{
std::cout << "Hello World\n";
}
1
По вопросам рекламы [email protected]