2014-01-17 3 views
3

Я всегда кладу звездочку, как это при создании указателей:Размещение [] и *

//directly adjacent to the type 
int* p = new int(); 

Так что я не запутать заявление с dererefence. Но потом я узнал об этом:

//p is a pointer, q is an int 
int* p, q; 

Что вводит в заблуждение меня, поэтому я начал поставить звездочку рядом с переменной, а не тип. Однако это заставило меня задуматься. Почему они спроектировали его таким образом? Вероятно, ужасно думать об этом так, но я всегда думал о указателе как о части этого типа. Например, его не указатель на int, его указатель int. Я знаю, что на самом деле это не так, но в моей голове всегда все исходило. И что на самом деле заставило меня задуматься, почему в скобки идут:

//after the variable 
int p[1]; 

tldr; Почему звездочка идут перед переменной, но скобки позади

+1

Вам интересны мотивы дизайнеров языка? – bitmask

+0

Да, это то, что мне интересно о – BWG

+2

Кстати, вы демонстрируете, почему декларации переменных штабелирования на одном из утверждений - плохая идея – pm100

ответ

4

int* стиль в C был разработан сравнительно поздно, и я не могу рекомендовать его.

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

В C я бы придерживался старого соглашения о применении операций адресации к имени переменной. Среди прочего, что на самом деле является выразительным; декларация непосредственно отражает операции, необходимые для получения типа. То есть, если декларация int *foo[10], то выражение *foo[3] будет иметь тип int.

Чтобы ответить на ваш tl; dr ... Скобки, следующие после переменной, были установлены на других языках задолго до C, и не было никаких причин для ее изменения. Звездочка, идущая раньше ... Я думаю, что это решение «переворачивать монету», и ответ «по той же причине, что унарный * был использован, чтобы вообще означать« значение, на которое указывает ... », им нужна операция, они схватили что-то, что не противоречило тем, что использовались другими персонажами, и как только они приняли это решение, они не смогли изменить его, не создавая новый несовместимый язык.

Это то, что это потому, что это то, , неудовлетворительный, поскольку этот ответ может быть.

(Лично я всегда задавался вопросом, почему они не использовали @, и задаются вопросом, связано ли это с близким религиозным аргументом в отношении того, является ли @ наиболее правильным означает «при» или «при условии, каждый ".)

+0

Интересно. Некоторое время я использовал (очень простой) язык, в котором синтаксис для доступа к памяти был «{address}», и я влюбился в этот стиль, потому что это имело для меня такой смысл. Теперь весь этот материал с «incriment the pointer по размеру элемента, который он указывает», действительно меня раздражает, потому что он запутывает то, что на самом деле происходит. Думаю, вам нужно найти правильный баланс между низким и высоким уровнем. – BWG

+2

Да, это балансирующий акт. Сопряженность синтаксиса C позволяет действительно по-настоящему умным идиомам, но также допускает некоторое по-настоящему нечеткое/плохое кодирование. Существует причина, по которой C был одним из языков, обычно используемых в соревнованиях с запутанными кодами. Это острый нож; обращайтесь с осторожностью, но вы привыкнете к этому. – keshlam

+0

Конечно, C не мог использовать синтаксис '{address}', поскольку фигурные скобки уже использовались для операторов блоков. ASCII имеет только так много символов пунктуации, и C, возможно, начинает заканчиваться ... – keshlam

0

я подозреваю, что [] было выбрано потому, что это общая математическая нотация для индексации

почему * х был выбран для обозначения «что х точек на уровне» не является очевидным. Но установка * после «х», очевидно, не будет выполняться при условии, что * означает умножение.

COBOL будет лучше :-)

move what x points to to y 
+0

- это фактический синтаксис кобола? pretty dang verbose – BWG

+0

Cobol _is_ verbose. Он был разработан для того, чтобы быть языком программирования, на котором не программисты могли бы чувствовать себя комфортно. C был разработан для удобства и выразительности, но не для удобочитаемости ... поэтому особенно важно, чтобы программисты C были осторожны в форматировании и документировании своего кода. – keshlam

+0

@BWG нет, это шутка. Но, как говорит кешлам, кобол очень многословный. Это было объявлено как «конец программирования, деловые люди могут просто написать свои требования на простом английском языке», ха-ха. Типичный оператор cobol - «умножить itemprice на numberordered, давая ordertotal» – pm100

5

Синтаксис C для объявлений использует модель

Таким образом, если x является int, мы начинаем с x, а потом говорят, что это int «Покажите нам, как вы бы использовать что-то и сказать нам, какой тип, что есть.»: int x;.

Если x является указателем на int, то мы будем использовать *x получить int, поэтому мы говорим int *x;.

Если x это функция, которая возвращает int, то мы будем использовать его в качестве x() получить int, поэтому мы говорим, что это int: int x();.

Одной из причин использования этой модели является то, что она в основном использует грамматику, которую вы уже создали для выражений: тело декларации анализируется так же, как выражения, а затем вы просто придерживаетесь типа. Если вы не используете одну и ту же модель, вам нужно придумать больше грамматики для объявления типов.

Эта модель делает заявления, такие как int *x, y; совершенно ясно: Оба *x и y имеют тип int.

+0

ОЧЕНЬ интересно. Мне жаль, что я не могу принять несколько ответов, все очень рассказывают. Этот дизайн имеет большой смысл, хотя я бы предпочел это другим способом. В конце концов, как часто приходится объявлять разные типы хранилищ (я думаю, что они называются) одного типа в одной строке? – BWG

+0

Не все, что необычно, на самом деле. Для сложного многослойного типа и для более простых подтипов, извлекаемых из него, может использоваться одна строка объявления. Конечно, Best Practice на самом деле использует typedefs для создания чего-либо действительно сложного поэтапно, что дает вам промежуточные typedefs в качестве бесплатного бонуса. – keshlam

+0

Кстати, хорошо иллюстрирую это отношение, Эрик. Я упомянул об этом попутно, но вы вызвали его и поняли. – keshlam

0

См. How do you read C declarations? для получения дополнительной информации.

Эта статья ссылки на утилиты Cdecl (человек страницы в http://gd.tuwien.ac.at/linuxcommand.org/man_pages/cdecl1.html, вам нужно поиск фактической полезности), которые я использовал, чтобы использовать, чтобы понять более сложные декларации.

Смежные вопросы