Прочитавши запитання , я знаю різницю між декларацією та визначенням. То чи це означає, що визначення дорівнює декларації плюс ініціалізація?
Прочитавши запитання , я знаю різницю між декларацією та визначенням. То чи це означає, що визначення дорівнює декларації плюс ініціалізація?
Відповіді:
Декларація, як правило, стосується введення нової назви в програму. Наприклад, ви можете оголосити нову функцію, описавши її "підпис":
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), декларація псевдоніма (7.1.3), декларація використання (7.3. 3), static_assert-декларація (п. 7), атрибут-декларація (п. 7), порожня декларація (п. 7) або директива з використання (7.3.4).
Ініціалізація відноситься до "присвоєння" вартості під час побудови. Для загального об’єкта типу T
він часто має вигляд:
T x = i;
але в C ++ це може бути:
T x(i);
або навіть:
T x {i};
з C ++ 11.
То чи це означає, що визначення дорівнює декларації плюс ініціалізація?
Це залежить. Про те, про що ви говорите. Якщо ви говорите про об'єкт, наприклад:
int x;
Це визначення без ініціалізації. Натомість наведено визначення з ініціалізацією:
int x = 0;
У певному контексті немає сенсу говорити про "ініціалізацію", "визначення" та "декларацію". Наприклад, якщо ви говорите про функцію, ініціалізація не означає багато чого.
Отже, відповідь негативна : визначення не означає автоматично оголошення та ініціалізацію.
int x;
це визначення, а також декларація.
So does it mean definition equals declaration plus initialization
.
Декларація говорить "ця річ десь існує":
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;
};
... але це потрапляння в більш складні функції.
Для С, принаймні, для С11 6.7.5:
Декларація визначає інтерпретацію та атрибути набору ідентифікаторів. Визначення ідентифікатора є декларацією для цього ідентифікатора , що:
для об’єкта викликає зарезервоване сховище для цього об’єкта;
для функції включає тіло функції;
для константи перерахування - це (єдине) оголошення ідентифікатора;
для імені typedef - це перша (або єдина) декларація ідентифікатора.
За C11 6.7.9.8-10:
Ініціалізатор визначає початкове значення, що зберігається в об'єкті ... якщо об'єкт, що має автоматичне зберігання, не ініціалізується явно, його значення невизначене.
Отже, загалом, декларація вводить ідентифікатор та надає інформацію про нього. Для змінної визначення - це оголошення, яке виділяє пам’ять для цієї змінної.
Ініціалізація - це специфікація початкового значення, яке слід зберегти в об’єкті, що не обов’язково збігається з тим, коли ви явно призначили перший раз йому значення. Змінна має значення, коли ви його визначаєте, незалежно від того, явно ви надаєте йому значення. Якщо ви явно не надаєте їй значення, а змінна має автоматичне зберігання, вона матиме початкове значення, але це значення буде невизначеним. Якщо у нього є статичне сховище, воно буде неявно ініціалізоване залежно від типу (наприклад, типи покажчиків ініціалізуються до нульових покажчиків, арифметичні типи ініціалізуються до нуля тощо).
Отже, якщо ви визначите автоматичну змінну, не вказавши для неї початкове значення, наприклад:
int myfunc(void) {
int myvar;
...
Ви визначаєте його (і, отже, також декларуєте, оскільки визначення є деклараціями), але не ініціалізуєте. Отже, визначення не дорівнює декларації плюс ініціалізації.