Чому потрібно декларувати тип даних під час декларування змінних?


41

У більшості мов кодування (якщо не у всіх) потрібно оголосити змінні. Наприклад, в C #, якщо його числове поле, тоді

int PhoneNumber

Якщо я використовую звичайну англійську мову, мені не потрібно заявляти, PhoneNumberяк intнею користуватися. Наприклад, якщо я попрошу свого друга Сема дати мені його номер телефону, я кажу:

"Сем дай мені номер телефону"

Я б не сказав

"Char (20) Сем, дай мені цілий телефонNumber"

Чому нам взагалі потрібно вказувати тип даних?


83
Це тому, що в англійській мові є неявне введення тексту - тому ваш PhoneNumber неявно вводиться як PhoneNumber - люди також мають динамічне розподілення пам'яті ...;)
HorusKol

28
Ви і Сем знаєте, що номер телефону складається з цифр, і ви здивуєтеся, знайшовши в ньому лист. Про комп’ютери немає і не потрібно їх говорити.
Thorbjørn Ravn Andersen

16
І коли я чую цифри на кшталт 1-800-JIMBO у фільмах, мені здається: як це число ? Оо
муру

103
Не слід оголошувати phoneNumber як int. У більшості мов програмування це видалить провідні нулі.
Aron_dc

25
@HorusKol: люди мають не лише динамічне розподілення пам’яті, але й сильно неконсервативний збирач сміття…
Продовження

Відповіді:


79

У більшості мов кодування (якщо не у всіх) потрібно оголосити змінні.

[…]

Чому нам взагалі потрібно вказувати тип даних?

Це два незалежні питання:

  • Чому нам потрібно оголошувати змінні?
  • Чому нам потрібно декларувати типи?

Між іншим, відповідь на обидва: ми цього не робимо.

Існує безліч статично набраних мов програмування, де не потрібно оголошувати типи. Компілятор може виводити типи з навколишнього контексту та використання.

Наприклад, у Scala можна сказати

val age: Int = 23

або ви могли просто сказати

val age = 23

Два цілком еквівалентні: компілятор буде робити висновок про тип, який буде Intвиражений ініціалізацією 23.

Так само і в C♯ ви можете сказати будь-яке з них, і вони означають абсолютно те саме:

int age = 23;
var age = 23;

Ця функція називається виведенням типу , і багато мов, крім Scala і C♯, мають її: Haskell, Kotlin, Ceylon, ML, F♯, C ++, ви її називаєте. Навіть у Java є обмежені форми виводу типу.

У динамічно набраних мовах програмування змінні навіть не мають типів. Типи існують лише динамічно під час виконання, а не статично. Тільки значення та вирази мають типи, і лише під час виконання змінні не мають типів.

Напр. В ECMAScript:

const age = 23;
let age = 23;

І нарешті, для багатьох мов вам взагалі не потрібно декларувати змінні. наприклад в Ruby:

age = 23

Насправді, цей останній приклад дійсний у ряді мов програмування. Наприклад, точно такий же рядок коду також буде працювати в Python.

Тому,

  • Навіть у статично введених мовах, де змінні мають типи, не обов’язково їх оголошувати,
  • у динамічно набраних мовах змінні не мають типів, тому очевидно, ви навіть не можете їх оголосити,
  • багатьма мовами вам навіть не потрібно декларувати змінні

2
Плюс один для пояснення як виводу типу, так і динамічного набору тексту (пізнє
в'язування

36
Це чудова інформація про помилки, що стоять за запитанням, але все ще залишає це питання без відповіді. Питання, правильніше, полягає в тому, чому нам потрібно вказувати тип даних при оголошенні змінних мовами, які цього вимагають? Чому їх розробили так? На це питання є хороші відповіді, і, розробляючи альтернативи, розширюється кругозір ОП, і це дуже добре, що мені не здається повним.
KRyan

7
@KRyan: якщо ви хочете знати, чому певний мовний дизайнер зробив певний вибір мовного дизайну, вам доведеться запитати цього дизайнера мови, я боюся. Я не можу вам сказати, чому дизайнери C of вирішили проти виводу типу, а також не можу сказати, чому вони згодом передумали. Мовна конструкція дуже впевнена і часто зводиться до смаку. Якщо, OTOH, ви хочете дізнатися про конкретні компроміси, відповідь в основному буде повторним друком типів і мов програмування професора Пірса, що є занадто широким для обміну стеками.
Йорг W Міттаг

2
JörgWMittag: як уже говорив @KRyan, відповідь "вам не потрібно" не дуже цікава (це тривіально очевидно - багато мов дозволяють опускати декларації типу в деяких випадках). Питання "чому ви хочете оголосити типи" набагато цікавіше і краще відображає дух оригінального запитання (ваша відповідь нагадує мені жарт: "де ми?" - "ви в повітряній кулі" ! " ). Вам не потрібно знати, що думав дизайнер певної мови в той час, щоб надати кілька вагомих причин на користь оголошення типу.
jfs

1
@Zaibis: auto i = 1 // i is inferred to type int, vector<int> vec; auto itr = vec.iterator(); // itr is inferred to type vector<int>::iteratorі так далі. Якщо ви хочете дізнатися, як саме це працює, можете переглянути його у специфікації.
Йорг W Міттаг

53

Коли ви використовуєте природну мову для посилання на інформацію, вона не дуже точна, і, зокрема, не повідомляє іншим про ваші наміри. Подібні проблеми виникають при спробі занять математикою природничою мовою: вона просто недостатньо точна.

Програмування є складним; помилки все надто просто. Типи є частиною системи перевірок, призначених для запобігання незаконним станам програми шляхом виявлення умов помилок. Різні мови використовують різні типи: деякі мови активно використовують типи для виявлення помилок під час компіляції. Практично всі мови мають певне поняття несумісних типів як помилку виконання. Зазвичай помилка типу вказує на помилку в програмі. Коли ми дозволяємо програмам продовжуватись, незважаючи на помилки, ми, швидше за все, отримуємо дуже погані відповіді. Ми вважаємо за краще зупинити програму, а не отримувати погані чи неправильні відповіді.

По-іншому, типи висловлюють обмеження щодо поведінки програми. Обмеження, коли їх застосовує якийсь механізм, дає гарантії. Такі гарантії обмежують кількість міркувань, необхідних для роздумів про програму, тим самим спрощуючи завдання читання та підтримки програми для програмістів. Без типів та їх впливу на інструменти (тобто компілятор), які виявляють помилки типу, навантаження на програмування значно вище, а значить, і дорожче.

Це правда, що (багато) люди легко розрізняють європейський, американський та міжнародний номер телефону. Однак комп’ютер насправді не «думає», а за назвою набере номер США в Європі або навпаки. Наприклад, типи - це хороший спосіб розрізнити ці випадки, не вчити комп’ютер "думати". У деяких мовах ми можемо отримати помилку часу компіляції для спроби змішати європейський номер телефону в американській телефонній системі. Ця помилка говорить про те, що нам потрібно змінити нашу програму (можливо, перетворивши номер телефону на міжнародну послідовність набору або, замість цього, використовуючи номер телефону в Європі), перш ніж ми навіть спробуємо запустити програму.

Крім того, оскільки комп'ютер не думає, назва поля чи змінної (наприклад phonenumber) нічого не означає для комп'ютера. Для комп'ютера назва поля / змінної просто "blah123". Подумайте, якою була б ваша програма, якби всі змінні були "blahxxx". Yikes. Ну, це те, що бачить комп'ютер. Надання типу дає комп’ютеру змову ввести значення змінної, яку він просто не може зробити з одного імені.

Далі, як говорить @Robert, у багатьох сучасних мовах нам не доведеться вказувати типи так само, як це було раніше, оскільки такі мови, як C #, виконують "умовивід типу", що є набором правил для визначення належного типу для змінної в контексті. C # надає лише висновок про тип на локальних змінних, але не на формальних параметрах або полях класу чи екземпляра.


4
ЗНАЙТЕ сумну частину: Неможливо зробити висновок про тип загальнодоступного члена (публічне поле, підпис публічного методу), оскільки ви не можете передбачити, коли і як він буде використовуватися. Також примітки про тип - це документація.
Серхіо Туленцев

Я думаю, вам слід виділити / жирним цей рядок: Types are part of a system of checks that ...оскільки він безпосередньо відповідає на ОП Why do we have to specify data type at all?..
txtechhelp

Примітка: ви відповідаєте, передбачає, що мова, яка використовується для визначення типів, якось краще уникати помилок, ніж ваша звичайна мова програмування. Очевидно, це не так, наприклад, розгляньте мову шаблонів C ++, яка є повною Тьюрінгом (і тому дозволяє висловити багато перевірок помилок), але вона майже нечитабельна в порівнянні з багатьма іншими мовами повного тюрінга, такими як Haskell, Python та навіть інші частини C ++ сама. Запитайте себе, чому ви не використовуєте ту саму мову програмування, щоб висловити перевірки помилок, як і решта вашої програми (є хороші відповіді в деяких, але не у всіх випадках).
jfs

@SergioTulentsev Це неправда - у F # ви можете мати публічні методи, не чітко вказуючи їх типи. Компілятор виводить типи з використання всередині методу. Наприклад, є дійсними визначення загальнодоступних методів: static member add x y = x + y, member x.Append s = x.Text + s. У першому випадку xі yбуде зроблено висновок intпро те, що додається. У другому випадку вони будуть будь-якими достовірними залежно від типу x.Text- якщо це а string, то sбуде stringтакож а. Я згоден, що примітки про тип - це документація.
Roujo

"Неявні локальні типи, явні типи інтерфейсів" - це те, як багато людей програмують навіть на таких мовах, як Haskell, які дозволяють опускати (майже) всі типи, зберігаючи компілятор, випливаючи строгі типи. Є багато людей, які не вважають це сумно, коли мова застосовує цю практику (як це робить C #).
Бен

29

Окрім інших відповідей, слід включити ще одне. Пам'ятайте, що комп'ютери - це просто біти. Скажіть, я даю вам байти:

26 3A 00 FF

Що це означає ? Він зберігається таким чином на комп’ютері, але без будь-якої інтерпретації, це просто біти . Це може бути 4 символи ascii. Це може бути ціле число. Це може бути кілька байтів у масиві. Це може бути частиною об'єкта. Це може бути вказівником на те, куди це котяче відео буферизується. Практично всі мови програмування, починаючи з монтажу на нові, потребують чогось, щоб знати, як інтерпретувати біти, щоб зробити їх значущими обчисленнями.

А оскільки комп’ютер не може знати значення цих бітів, вам потрібно сказати це - явно за допомогою анотацій типу, або неявно через механізми виводу типу, згадані в інших відповідях.


10
Досить правда, але для того, щоб по-справжньому заблукати розум, зрозумійте, що комп'ютер ніколи не здатний зрозуміти, що означають ці біти - навіть коли ви розповідаєте про це більше анотацій типу. Ваші пояснення просто перетворюються на ще більше шістнадцяткових чисел, щоб "уточнити" перші шістнадцяткові числа. Значення всього створюється людьми для того, щоб поставити намір в електроніку і змусити їх робити те, що ми маємо намір. А тепер скажіть "дякую" інженеру. :)
Wildcard

1
Я багато років програвав на мейнфреймах. З PL / 1 ця відповідь має багато сенсу. Досить регулярно ми використовували б базування даних на основі покажчика, встановленого на адресу іншої змінної іншого типу даних для доступу до байтів по-іншому. Наприклад, PL / 1 не підтримує двобайтове числове поле з байтом на 1 байт, але ми базуємо змінну на 1 символ за адресою, щоб ми могли зберігати 6-байтовий масив, що зберігає 6 однобайтових бінарних полів (у цьому випадку дозволяє нам зберегти 6 байт на адресу - що було важливо, коли зберігання було дорогим).
Кікстарт

1
Комп'ютер здатний зрозуміти безліч можливостей, але навіть розумним компіляторам потрібен контекст, щоб зрозуміти. Це не те саме число 0 або "0". Або Рядок "31 грудня" буде замовлений до "1 травня", який розглядається як рядок, але не буде розглядатися як дата. Або візьміть 5/2. Це 2 як вхід, але 2,5 як подвійний. Також тип - це запобіжний захід від небажаних перетворень. Нуль, NaN, округлення або переповнення також можуть стати проблемою. Сильні та статично набрані мови мають деякі переваги. Наприклад, компілятор допомагає виявити проблеми під час рефакторингу.
Борджаб

1
@Borjab Ви мали на увазі "Це 2 як ціле число "?
Річард Еверетт

1
@RichardEverett Безумовно, це був лапсус. Дякую, але пізно відредагувати.
Борджаб

23

Відповідь на те, чому комп’ютерам потрібна ця інформація, стосується представлення даних .

Назва "типу даних" - це посилання на правила, які допомагають комп'ютеру зберігати та витягувати інформацію з її неочищеного стану 0 та 1 у пам'яті комп'ютера.

Наприклад, ваш звичайний 8-бітний символ ASCII буде зберігатися в пам'яті комп'ютера (або оперативної пам'яті, або диска) як 01000001(верхній регістр символу "A", ASCII код 65) або 00001000(знак відсотка), або будь-які комбінації 0 і 1 в цих 8 біт.

Для іншого прикладу, деякі 8-бітні цілі числа можуть бути збережені як 00000101(число 5) або 00001000(число 8)

Зауважте, як двійкове представлення символів 8 та символів% може бути однаковим, але вони означають різні речі, оскільки їхні типи різні.

Навіть у мовах, які визначають тип даних, вони можуть не мати правила, що "типи всіх змінних повинні бути оголошені програмістом", у них є правила типу "якщо ваша серія символів укладена в лапки, це рядок" і ще багато правил для кожного типу даних.

Тому навіть їм потрібні типи даних, щоб зрозуміти, що означає значення 0 і 1, тому вони можуть, наприклад, виконувати функцію конкатенації рядків, якщо ви спробуєте "додати" два символи або зробити ціле додавання, якщо ви намагаєтеся додати два цілих числа .

У вашій історії теж скажімо, що ви не просили Сема про номер телефону, але Сем дає вам аркуш паперу, на якому написано "1123581321". Ви не можете бути впевнені, чи Сем просто фанат перших восьми номерів Фібоначчі чи це номер телефону. Для здогадки вам доведеться враховувати наявний контекст і підказки, як-от, можливо, ви запитували Сема номер телефону день тому, або в примітці написано "Зателефонуй мені", або якщо порахувати цифри і знайти він відповідає шаблонам більшості номерів телефонів. Тільки тоді ви дізнаєтесь, що це номер телефону, на який ви можете телефонувати, а не деякі цифри, які ви забивали б у калькулятор.

Зверніть увагу, як ці підказки, які привели вас до здогаду, що номер був телефонним номером, схожі на те, як підказки ведуть мову комп'ютера, яка не вимагає декларації для виведення типу значення.


3
Це найближча відповідь. Це все стосується пам'яті. Ви оголошуєте тип, щоб компілятор знав, скільки пам'яті для програми потрібно запитувати під час виконання. Знання, як слід інтерпретувати біти, є другорядним.
Грег Бургхардт

@GregBurghardt правда. Для розуміння вже наявних бітів, а також для виведення бітів на перше місце після перетворення заданих даних у бінарні відповідно до типу даних.
Peeyush Kushwaha

10

У деяких мовах не потрібно вказувати тип даних.

Мови, які підтримують умови вибору, зазвичай можуть визначити тип даних із вашого використання. Наприклад,

var name = "Ali"

внутрішньо набирається як рядок, оскільки значення оточене лапками.

Деякі мови не вимагають, щоб ви також декларували змінну; змінна створюється при її першому використанні. Однак вважається найкращою практикою спеціально оголошувати свої змінні з ряду важливих причин; в основному тому, що робити це краще виражає ваші наміри.


5
var name = "Ali"Стиль насправді загальний для сучасних статичний типізованих мов. У статично типових мовах тип фіксується при створенні, але він все ще може бути визначений ініціалізатором. Визначення динамічно набраної мови полягає в тому, що типи приєднуються до значень, а не до змінних. Призначення значення змінній тому встановлює і тип змінних.
MSalters

@MSalters: я змінив формулювання.
Роберт Харві

5
Іронія тут полягає в тому, що це стосується C # з цим точним синтаксисом.
Дерек Елкінс

1
@MSalters Призначення значення змінній тому встановлює тип змінних. Або що змінна не має притаманного типу, і інтерпретатор намагатиметься застосувати будь-яку операцію до значення змінної. Чи є якісь динамічно набрані мови, де такий код, як наведений нижче (Javascript), заборонено, var x = 5; x = "";оскільки перше твердження спричиняє xпов'язаність типу "Номер" x? Сортування конфліктів із динамічним набором тексту . А якщо ні, то який ефект має тип, пов'язаний зі змінною, поза асоціацією типу зі значенням?
Зев Шпіц

1
@ZevSpitz: Перший тип системи не динамічно набирається, але зовсім не набирається. Ваш приклад Javascript не набирається динамічно, саме тому, що тип Числа не може змінюватися. У динамічно набраній мові x = "";змінює тип x на рядок, навіть якщо раніше це було число.
MSalters

9

Тому що саме це визначає мовна конструкція. Тож, щоб відповісти на ваше запитання, нам потрібно розглянути наміри, що стоять за явним набором тексту на таких мовах, як C # і C ++. (Ну, C # робить це тому, що C ++ робить це тому, що C робить це, тому нам потрібно подивитися на шлях намірів тоді).

По-перше, явна та статична типізація забезпечує суворість у кодуванні - визначення змінної як цілого числа означає, що компілятор та програмне забезпечення повинні дивуватися та створювати помилку, коли ви присвоюєте символу чи рядку змінної. Динамічне введення тексту може спричинити головний біль для необережних (просто подивіться на підхід PHP або javascripts до правдивості таких речей, як масиви та порожні рядки).

Ви можете мати статику з неявним введенням тексту - ініціалізація змінної як рядка означає, що змінна повинна бути колись лише рядком, але я відчуваю, що це може спричинити проблеми для людей, які читають код (я схильний припускати динамічне введення тексту, коли є неявна введення тексту ).

Крім того, на деяких мовах можна написати щось на зразок цього псевдокода, щоб ініціалізувати клас із рядкового введення:

PhoneNumber phoneNumber = "(61) 8 8000 8123";

По-друге, явне введення тексту також йде разом із розподілом пам'яті. У int завжди стільки байтів. У телефонному номері стільки байтів. Компілятор може призначити відповідний розмір блоку пам'яті, який потім може бути використаний пізніше, не бачачи, скільки місця знадобиться при призначенні значення.

PhoneNumber phoneNumber;
...
phoneNumber = "some value from somewhere";

Нарешті, це видаляє плутанину ... це 123 ціле число чи непідписане ціле число? Їм потрібна однакова кількість байтів, але максимальне значення, що зберігається у змінних будь-якого типу, сильно відрізняється ...

Це не так сказати, що явне краще, ніж неявне, але мовна конструкція покладається на такі варіанти вибору, і C # працюватиме по-різному з неявним набором тексту. PHP та javascript працюватимуть по-різному з явним набором тексту.


5

Тому що Сем розумніший за компілятори. Наприклад, коли ви говорите, дайте мені номер телефону, ви не вказуєте, чи хочете ви вказати префікс країни або код міста, чи є це робочим номером, де потрібні лише останні 4 цифри. Крім того, якщо ви запитаєте номер місцевої спільної піци, ви зможете розібратися з відповіддю "pizza4u".

Сем, вияснює це з контексту. Хоча компілятор також може це зрозуміти з контексту, Сем буде краще в ньому (і здатний перервати процес, щоб просити роз'яснення).

Існує два основні підходи до типів і змінних: або змінна має тип, і в цьому випадку дії, які заборонені типом, заборонені та перешкоджають компіляції, або значення має тип та дії, які заборонено тип ловиться під час виконання.

Кожен підхід має свої переваги та недоліки. Взагалі автори-компілятори намагаються мінімізувати недоліки та максимально використати переваги. Ось чому, наприклад, C # дозволяє var phoneNumber = GetPhoneNumber();і буде виводити тип phoneNumber з підпису GetPhoneNumber. Це означає, що ви повинні оголосити тип для методу, але не змінну, яка отримує результат. З іншого боку, існують проекти різного типу натяку / виконання проектів для JavaScript. Все є компромісом.


3

Це питання способу зберігання даних. Ваша взаємодія з Семом зробила б краще порівняння, якби ви запитували, щоб ваш міг записати це, але мав на папері лише вісім символів.

"Сем, дай мені номер."

"5555555555"

"О, ні, я не з паперу. Якби я заздалегідь знав, скільки даних я прошу, я міг би підготуватися краще!"

Тож натомість більшість мов змушують вас оголошувати тип, тому він буде знати і готуватися до часу:

"Сем, як довго телефонний номер?"

"Десять символів."

"Гаразд, тоді дозвольте мені взяти більший аркуш паперу. Тепер дайте мені номер."

"5555555555"

"Зрозумів! Дякую Сем!"

Він стає ще більш суєтним, коли дивишся на фактичні основні способи зберігання даних. Якщо ви схожі на мене, у вас є зошит з різними нотатками, цифри, які просто скреслили, немає контексту чи маркування ні для чого, і ви не маєте поняття, що це означає через три дні. Це також є проблемою для комп’ютерів багато разів. Багато мов мають типи "int" (int, long, short, byte) та "float" (float, double). Чому це потрібно?

Ну спочатку давайте подивимось, як ціле число зберігається і взагалі представлено в комп'ютері. Ви, мабуть, знаєте, що на базовому рівні це все бінарне (1 та 0). Двійкова - це насправді система числення, яка працює точно так само, як наша система десяткових чисел. У десятковій формі ви рахуєте від 0 до 9 (з нескінченними маючи на увазі провідні нулі, які ви не пишете), потім перевертаєтесь назад на 0 і збільшуєте наступну цифру, щоб у вас було 10. Повторюєте, поки не перекинетеся з 19 на 20, повторюйте, поки не перекинетеся з 99 на 100 тощо.

Бінарне не відрізняється, за винятком того, що замість 0 до 9 ви рахуєте від 0 до 1. 0, 1, 10, 11, 100, 101, 110, 111, 1000. Отже, коли ви набираєте 9, в пам'яті, записаній у двійковій як 1001. Це фактичне число. Його можна додавати, віднімати, множувати тощо в точно такому вигляді. 10 + 1 = 11. 10 + 10 = 100 (переверніть на 1 до 0 і перенесіть 1). 11 х 10 = 110 (і рівнозначно 11 + 11 = 110).

Тепер у власній пам’яті (реєстри включені) є список, масив, як би ви не хотіли його назвати, бітів (потенціал 1 або 0 ') прямо поруч один з одним, тому він зберігає ці біти логічно організованими для створення число більше 1. Проблема полягає в тому, що ви робите з десятковими знаками? Ви не можете просто вставити частину обладнання між двома бітами в реєстр, і це буде коштувати занадто дорого, щоб додати "десяткових біт" між кожною парою біт. То що робити?

Ви кодуєте це. Як правило, архітектура процесора або програмного забезпечення визначає, як це робиться, але один поширений спосіб - зберігати знак (+ або -, як правило, 1 - мінус) у першому біті реєстру, мантісі (номер зміщений однак багато разів потрібно позбутися десяткової) для наступного числа X біт і показника (кількість разів, коли вам довелося його змістити) на залишок. Це схоже на наукові позначення.

Введення тексту дозволяє компілятору знати, на що він дивиться. Уявіть, що ви зберегли значення 1,3 в регістрі 1. Ми просто створимо тут власну схему кодування, 1 біт для знака, 4 для мантіси, 3 для експонента (1 біт для знака, 2 для величини). Це додатне число, тому знак позитивний (0). Нашій мантісі було б 13 (1101), а наш показник - -1 (101 (1 за негативним, 01 = 1)). Таким чином, ми зберігаємо 01101101 в регістрі 1. Тепер ми не вводили цю змінну, тому, коли час виконання буде перейти до її використання, він говорить "звичайно, це ціле число, чому б і ні", тому коли він друкує значення, яке ми бачимо 109 (64 + 32 + 8 + 4 + 1), що, очевидно, не правильно.

Однак не кожна мова вимагає чітко вводити текст. C # має ключове слово "var", яке викликає інтерпретацію типу змінної під час компіляції, а інші мови, як-от Javascript, повністю динамічно набираються, до того, що ви можете зберігати ціле число у змінній, а потім присвоювати його булевому, а потім присвоїти його знову рядку, і мова відстежує все це.

Але набагато простіше на компіляторі, інтерпретаторі чи під час виконання - і це часто призводить до більш швидкої програми, оскільки їй не доведеться витрачати цінні ресурси на сортування всього, щоб запитати вас, програміста, який саме тип дані, які ви їх надаєте.


2

Є мови програмування, де вам не потрібно оголошувати типи даних для своїх змінних. Існують навіть мови програмування, де вам не потрібно декларувати змінні заздалегідь; ви можете просто скористатися ними, негайно.

Проблема з недекларуванням імен змінних полягає в тому, що якщо ви випадково неправильно написали ім’я змінної, ви випадково створили нову, абсолютно не пов'язану змінну. Тож, запускаючи свою програму, ви не можете зрозуміти, чому чорт, що ця змінна, яку ви встановили, раптом не має нічого в ній ... Доки після багатьох годин налагодження ви не зрозумієте, що ви неправильно ввели прокляте ім'я! GRRR !!

Тому вони зробили це так, що вам доведеться оголосити імена змінних, які ви будете використовувати раніше. А тепер, коли ви ввели ім’я неправильно, ви отримуєте помилку під час компіляції, яка одразу підкаже вам , де саме помилка, перш ніж ваша програма навіть запуститься. Хіба це не так простіше?

Те саме стосується типів даних. Існують мови програмування, де вам не потрібно декларувати, якими мають бути речі. Якщо у вас є customerзмінна, яка насправді є лише ім'ям замовника, а не всім об'єктом клієнта, намагаючись отримати адресу клієнта із звичайної звичайної рядки ... не вийде. Вся суть статичного набору тексту полягає в тому, що програма не збирається; вона голосно скаржиться, вказуючи на точне місце, де проблема. Це набагато швидше, ніж запускати свій код і намагатися з’ясувати, чому, чорт забирає, це не працює.

Все це - функції, щоб повідомити компілятору, що ви мали намір зробити, щоб він міг перевірити, що ви насправді зробили, і переконатися, що це має сенс. Це дає можливість компілятору автоматично знаходити для вас помилки, що є великою угодою.

(Далеко в далекому минулому вам не потрібно було декларувати підпрограми . Ви б просто вказали GOSUBпевний номер рядка. Якщо ви хочете передати інформацію між підпрограмами, ви встановите конкретні глобальні змінні, зателефонуйте у свою підпрограму та огляньте інші коли повертається підпрограма. Але це лякає просто забути ініціалізувати один із параметрів. Тому майже всі сучасні мови програмування вимагають оголосити, які саме параметри приймає підпрограма, щоб ми могли перевірити, чи ви їх усі вказали. )


1
У C ++ ви можете поставити "auto x = 1", і він знає, що це int. auto y = 1,2; auto z = 'Z'; тощо
QuentinUK

@QuentinUK У C # можна поставити var x=1подібні результати. Але це нічого; в Haskell ви можете написати всю свою програму без підписів типів, але вона все статично набрана, і ви все одно отримаєте помилки, якщо помилитесь (хоча не зовсім мейнстрім.)
MathematicalOrchid

@QuentinUK Але якщо ви пишете, for (auto i=0; i<SomeStdVector.size(); ++i)ваш лінійка поскаржиться, оскільки він вивів підписаний тип, і ви продовжуєте порівнювати його з неподписаним типом. Ви повинні написати auto i=0ul(явно повторно поставивши інформацію про тип, тому слід просто написати size_t i=0в першу чергу).
dmckee

1

Якщо я використовую звичайну англійську мову, мені не потрібно оголошувати PhoneNumber як int, щоб використовувати його. Наприклад, якщо я попрошу свого друга Сема дати мені його номер телефону, я кажу:

"Сем дай мені номер телефону"

Я б не сказав>

"Char (20) Сем, дай мені цілий телефонNumber"

Чому нам взагалі потрібно вказувати тип даних?

Перейдіть до MathOverflow або Теоретичної інформатики та прочитайте на деякий час, щоб зрозуміти, як люди спілкувались між собою алоритмами, коли хочуть переконатися, що немає можливості непорозуміння. Або читайте стандарт для якоїсь зрілої мови програмування.

Ви побачите, що визначення того, які типи значень допускаються до терміна, є частиною дійсно точної комунікаційної практики, навіть від людини до людини.

Що ви помітили, що щоденна взаємодія є досить регулярною, а людина є досить толерантною до помилок, тому непорозуміння щодо телефонних номерів взагалі уникається спільними знаннями учасників.

Але ви коли-небудь намагалися зняти номер телефону комусь в іншій країні? Чи сказали вони вам явно, скільки разів натискати нуль, щоб дістатися до міжнародної адреси? Вони сказали вам свій код країни? Ви визнали це таким? Скільки цифр ви очікували? Скільки ви отримали? Чи знали ви, як згрупувати цифри? Або навіть якщо групування має значення?

Раптом проблема стає набагато складніше, і ви, ймовірно, взяли набагато більше уваги, щоб чітко перевірити, чи отримана кількість була зрозуміла так, як це відправник відзначив.


0

Ще одна причина декларування типів - ефективність. Хоча ціле число може бути збережене в 1 байті, або 2 байтах, або 4, програма, що використовує дуже велику кількість змінних, може використовувати в 4 рази більше необхідної пам'яті, залежно від того, що робиться. Тільки програміст знає, чи менший простір для зберігання є життєздатним, тому він може сказати це, оголосивши тип.

Крім того, динамічно набрані об'єкти дозволяють отримати безліч можливих типів, на льоту. Це може загрожувати деякими накладними "під капотом", сповільнюючи програму порівняно з дотриманням одного типу весь час.


0

Ряд мов раннього програмування (особливо Fortran) не вимагав від вас декларування змінних перед використанням.

Це призвело до низки проблем. Одне очевидно одне - компілятор більше не може сприймати прості друкарські помилки майже так само надійно. Якщо у вас є код, який повинен модифікувати існуючу змінну, але має помилку друку, у вас все ще є ідеально законний код, який щойно створив (і призначив значення) новій змінній:

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

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

Навіть на даний момент з багатьма мовами, що динамічно набираються, ви все одно можете легко отримати ту саму основну проблему. У деяких є можливість попередити вас, якщо ви присвоюєте змінну, але ніколи не читайте її (що евристично сприймає досить багато подібних проблем), а інші не мають таких речей.


0

Коли ви оголошуєте будь-яку змінну, деякий простір виділяється в пам'яті ,, але машина (комп'ютер у цьому випадку) вже не знає, скільки місця потрібно виділити для цієї змінної.

Приклад: - ви створюєте програму, яка просить користувача ввести будь-яке число, у цьому випадку вам потрібно вказати тип даних для зберігання цього числа, інакше машина не може сама по собі оцінити, що він повинен виділити 2 байти або 2 гігабайти , якщо він намагається робити розподіл самостійно, то це може призвести до неефективного використання пам'яті. З іншого боку, якщо ви вказали тип даних у вашій програмі, то після компіляції машина виділить належний простір відповідно до потреби.


це, здається, не пропонує нічого суттєвого щодо питань, викладених та пояснених у попередніх 11 відповідях
gnat

1
Гнат, ти повинен ще раз детально прочитати всі відповіді і побачити, що я намагався відповісти на це питання набагато простішим способом, який можна легко зрозуміти.
Atul170294

Я щойно переглянув три останні відповіді, які були опубліковані приблизно за годину до цього, і всі три, здається, роблять те саме, і за кожним моїм прочитанням пояснюю це простіше, ніж тут
gnat

Хоча я не відповідав за нагороду за ваш голос, але я думаю, ви повинні ознайомитися з одним, - вам слід спростувати відповідь, оскільки вона може дати марну або неправильну інформацію, і якщо вона містить щось образливе. Усі відповіді, які мають найкориснішу та найвідповідальнішу інформацію, отримають більшу кількість оновлень, що достатньо для розмежування відповіді, хорошої та найкращої відповіді. Ваша дитяча активність, яка не має жодних вагомих причин, буде відштовхувати інших людей, які також хочуть поділитися своєю думкою, яку вони вважають корисною іншим
Atul170294

1
Ваша відповідь, швидше за все, була оскаржена, оскільки вона невірна. Статистичне введення тексту не потрібно, щоб допомогти в управлінні пам'яттю. Є багато мов, які дозволяють динамічно вводити текст, і ці мови / середовища здатні вирішувати проблеми, які ви згадуєте щодо управління пам'яттю.
Джей Елстон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.