Чому C використовує зірочку для покажчиків? [зачинено]


21

Я тільки зараз дізнаюся про С.

Мені дивно, що творці обрали зірочку ( *) як символ для покажчиків, а не символ, який насправді виглядає як вказівник ( ->).

Зважаючи на те, наскільки заплутаними можуть бути покажчики перенаправлення та функціонування, чи є історична чи навіть практична причина використання зірочки?


10
Зауважте, ->що використовується мовою С як оператор скидання - при доступі до полів у структурі:, struct_pointer->fieldщо скорочено (*struct_pointer).field.
амон

@amon: Це стосується лише дереференції structs, що мені здавалося дивним. Це символ вказівника, правда? Чому б не ( <-) для перенаправлення? Я справді єдиний, хто думає так?
Noob Saibot

1
Враховуючи два чудових відповіді в цьому запитанні, в тому числі один з відповіддю безпосередньо від дизайнера мови, важко реально виправдати близьке як "на основі думки". Тому я був висунутий на повторне відкриття.
Жуль

Стиль IMHO Pascal краще. ^використовується і може вважатися поворотною стрілкою і читати як "вказати на", таке ж значення, ->але коротше. ^integerозначає "покажчик на ціле число" для оголошення типу і var^означає "пам'ять varвказує на" для перенаправлення. Положення символу є більш логічним, ніж C, коли читається зліва направо, яке завжди ставиться після типу та перед назвою змінної. Паскаль також використовує @для отримання адреси, що краще &, оскільки @varце "адреса, за якою знаходиться var"
phuclv

Відповіді:


59

Чому C використовує зірочку для покажчиків?

Просто - тому що Б зробив.

Оскільки пам'ять є лінійним масивом, можна інтерпретувати значення в комірці як індекс цього масиву, а BCPL постачає оператор для цієї мети. Мовою оригіналу було написано rv, і пізніше !, тоді як B використовує одинарний *. Таким чином, якщо pкомірка, що містить індекс (або адресу), або покажчик на) іншої комірки, *pпосилається на вміст комірки, що вказує на точку, або як значення в виразі, або як ціль призначення.

Із розвитку мови С

Це воно. На даний момент питання настільки ж нецікаве, як "чому python 3 використовує .для виклику методу? Чому ні ->?" Ну ... тому що Python 2 використовує .для виклику методу.

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


Отже, чому B не використовував !для дефренансування вказівника, як це робив його попередник BCPL?

Що ж, BCPL був трохи розмовним. Замість &&або ||BCPL використовується logandі logor. Це було тому, що більшість клавіатур не мають або клавіш, а не однакові були фактично словом NEQV(див . Посібник з BCPL ).

Здається, B частково надихнувся на посилення синтаксису, а не на довгі слова для всіх цих логічних операторів, що програмісти робили досить часто. І таким чином !для дереференції стало *таким, що !може бути використане для логічного заперечення. Зауважте, є різниця між одинарним *оператором і двійковим *оператором (множення).


Ну, а як щодо інших варіантів, як ->?

->Було прийнято для синтаксичного цукру навколо поля derefrences struct_pointer->fieldякий(*struct_pointer).field

Інші варіанти, як-от, <-можуть створити неоднозначні розбирання. Наприклад:

 foo <- bar

Чи слід це читати як:

(foo) <- (bar)

або

(foo) < (-bar)

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

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

int main(int argc, char->-> argv, char->-> envp)

Це також стає важко читати.

Можливо, можливі й інші символи ( @не використовувався, поки ціль C не призначила його ). Хоча знову ж таки, це іде до основи «C використовує, *тому що B». Чому B не використовував @? Ну, B використовував не всіх персонажів. Не було bppпрограми (порівняти cpp ), а інші символи були доступні в B (такі, #які пізніше використовували cpp).

Якщо я можу загрожувати здогадкою, чому - це через те, де клавіші. З посібника на B :

Щоб полегшити маніпулювання адресами, коли це здається доцільним, B надає два оператори унарної адреси *та &. &є адресовим оператором, так &xце адреса x, якщо припустити, що він є. *є оператором опосередкування; *xозначає "використовувати вміст x як адресу".

Зауважте, що &це shift-7 і *є shift-8. Їх близькість один до одного, можливо, була натяком програмісту на те, що вони роблять ... але це лише здогадки. Варто було б запитати Кена Томпсона про те, чому був зроблений такий вибір.


Отже, там у вас є. C саме так, бо Б був. Це так, тому що він хотів змінитись із того, яким був BCPL.


2
... дивовижно! Це чудова відповідь, @MichaelT! Ви показали мені і історичні, і практичні причини, і навіть речі, які я не зовсім зрозумів, але міг розглянути. Дякую. +1
Noob Saibot

@NoobSaibot Вибір символу полягає не стільки в угоді, скільки в тому, що оператор - це надбавка, а не оператор після відправки. Для цього потрібно багато зайвих парен (хоча синтаксичний цукор допомагає), що може призвести до нерозумних, але неприємних помилок навіть для досвідченого програміста на C ++.
Trixie Wolf

1
Ви також можете згадати, що C знайшов застосування майже для кожного пунктуаційного символу Ассії. Запасних було не так багато. Я думаю, @була б інша можливість.
david.pfx

1
@ David.pfx я розширив , що - хоча це було не C , що зробив цей вибір ... це був Б. А, ну, я зробив припущення щодо того , чому (клавіатура близькості &і *). B також не використовував, #тож було ще кілька запасних частин тоді ... є також $.

1
@ david.pfx Підручник з B, який я знайшов, написав BW Kernighan. На жаль, Денніса Річі більше не вдається запитати (він помер у жовтні 11 року), в той час як Керніган, очевидно, все ще є професором кафедри CS в Прінстоні. Кен Томпсон (інший творець B) працює в Google ... Можливо, також були проблеми з клавіатурами (позначені триграфами для C для того, що ми б вважали загальними клавішами), припускаючи, що не всі вони були доступні ( Я не впевнений, чи було "@".

55

Я запитав студент , якщо &і *були вибрані тому , що вони були поруч один з одним на клавіатурі (що - то я ніколи раніше не помічав). Багато googling привів мене до B та BCPL документації, і ця тема. Однак я взагалі не міг багато чого знайти. Здавалося, *в Б було багато причин , але я нічого не міг знайти &.

Тож, висловивши пропозицію @ MichaelT, я попросив Кена Томпсона:

Від: Кен Томпсон <ken@google.com>

поблизу на клавіатурі: ні.
c скопійовано з b так & і * там само.
b отримав * з попередніх мов - деякі збори,
bcpl, і я думаю, що pl / 1.
я думаю, що я використав & тому, що ім'я (амперсанд)
звучить як "адреса". b був розроблений для запуску із
телетайпом моделі 33 телетайпу. (5-бітний код бод-о),
тому використання символів було обмеженим.


19
+1, щоб зв’язатися з Кеном Томпсоном та повідомити тут.
stakx
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.