Является ли C строго типизированным?

Чтобы процитировать Wikipedia:

Два часто используемых языка, которые поддерживают многие виды неявных преобразование - это C и С++, и это иногда утверждали, что это слабо типизированные языки. Однако, другие утверждают, что эти языки достаточно ограничить операнды разных типов могут быть смешанный, что эти два следует рассматривать как сильно типизированные языки.

Есть ли более окончательный ответ?

Ответ 1

"Сильно типизированные" и "слабо типизированные" - это термины, которые не имеют широко согласованного технического смысла. Термины, которые имеют четко определенный смысл,

  • Динамически типизированный означает, что типы привязаны к значениям во время выполнения, а попытка смешивания значений разных типов может вызвать "ошибку типа времени выполнения". Например, если в Scheme вы пытаетесь добавить одно к true, написав (+ 1 #t), это приведет к ошибке. Вы сталкиваетесь с ошибкой только в том случае, если пытаетесь выполнить код нарушения.

  • Статически типизированный означает, что типы проверяются во время компиляции, а программа, которая не имеет статического типа, отвергается компилятором. Например, если в ML вы пытаетесь добавить одно к true, написав 1 + true, программа будет отклонена с (возможно, загадочным) сообщением об ошибке. Вы всегда получаете ошибку, даже если код никогда не будет выполнен.

Различные люди предпочитают разные системы, в частности, от того, насколько они ценят гибкость и насколько они беспокоятся о ошибках во время выполнения.

Иногда "строго типизированный" используется слабо для обозначения "статически типизированного", а "слабо типизированный" используется неправильно, чтобы означать "динамически типизированный". Лучше использовать термин "строго типизированный" в том, что "вы не можете обойти или подорвать систему типов", тогда как "слабо типизированный" означает "в системе типов есть лазейки". Извращенно большинство языков с системами статического типа имеют лазейки, а многие языки с системами динамического типа не имеют лазеек.

Ни одно из этих условий никак не связано с количеством неявных преобразований, доступных на языке.

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

Я написал больше о статической и динамической типизации на why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing.

Ответ 2

Трудно классифицировать каждый язык на "слабо" или "сильно" набирать - это скорее континуум. Но, по сравнению с другими языками, C довольно строго типизирован. Каждый объект имеет тип времени компиляции, и компилятор даст вам знать (громко), если вы что-то делаете с объектом, который его тип не позволяет делать. Например, вы не можете вызывать функции с неправильными типами параметров, получать доступ к элементам struct/union, которых нет, и т.д.

Но есть несколько недостатков. Одной из основных недостатков являются приведения типов - они, по сути, говорят, что вы собираетесь обманывать типы объектов, а компилятор должен быть тихим (когда это возможно). void* - еще одна слабость - это общий указатель на неизвестный тип, и когда вы их используете, вы должны быть осторожны, чтобы поступать правильно. Компилятор не может статически проверять большинство использования void*. void* также может быть преобразован в указатель на любой тип без трансляции (только в C, а не на С++), что является еще одним недостатком.

Ответ 3

В литературе это не ясно. Я думаю, что строго типизировано не да/нет, есть разные степени сильной типизации.

Язык программирования имеет спецификацию того, как он выполняет программы. Иногда не ясно, как выполнять определенные программы. Например, программы, которые пытаются вычесть строку из числа. Или программы, которые делятся на ноль. Существует несколько способов решения этих условий. На некоторых языках есть правила для устранения этих ошибок (например, они генерируют исключение). На других языках просто нет правил для решения этих ситуаций. Эти языки обычно имеют системы типов, чтобы предотвратить компиляцию программ, которые приводят к неуказанному поведению. Кроме того, существуют языки, которые имеют неопределенное поведение и не имеют системы типов для предотвращения этих ошибок во время компиляции (если вы пишете программу, которая сталкивается с неуказанным поведением, она может запускать ракеты).

Итак:

Языки, которые определяют, что происходит во время выполнения в каждом случае (например, добавление числа в строку), называются динамически типизированными. Языки, которые предотвращают выполнение программ с ошибками во время компиляции, статически типизируются. Языки, которые не определяют, что происходит, а также не имеют системы типов для предотвращения ошибок, называются слабо типизированными.

Итак, Java статически типизирована? Да, потому что его система типа запрещает вычитать строку из числа. Нет, потому что он позволяет вам делить на ноль. Вы можете предотвратить деление на ноль во время компиляции с помощью системы типов. Например, создав тип номера, который не может быть нулем (например, NonZeroInt), и только разрешить деление на номера, имеющие этот тип.

Итак, C сильно типизирован или слабо типизирован? C строго типизирован, потому что система типов запрещает некоторые ошибки типа. Но он слабо набирается в других случаях, когда undefined что происходит (и система типов не защищает вас).

Ответ 4

C считается слабо типизированным, потому что вы можете преобразовать любой тип в любой другой тип с помощью cast, без ошибки компилятора. Вы можете подробнее узнать о проблеме здесь.

Ответ 5

C более строго типизирован, чем Javascript и менее строго типизирован, чем Ada.

Я бы сказал, что он больше попадает в строго типизированную сторону континуума. но кто-то другой может не согласиться (даже если они ошибаются).

Как это для окончательного?

Ответ 6

C считается статически типизированным (вы не можете изменить переменную от int до float). Как только переменная объявлена, она застревает таким образом.

Но он считается слабо типизированным, потому что типы могут быть перевернуты.

Что такое 0? '\ 0', FALSE, 0.0 и т.д.

на многих языках вы не можете сказать IF (переменная), потому что условия будут принимать только булевы значения из булевых выражений. Они более строго типизированы. То же самое относится к перемещению между символами и целыми числами.

в основном c имеет два основных простых типа данных: целые числа и числа с плавающей запятой (хотя и различные префиксы). Все остальное логическое, перечисление (не просто, но подходит) и т.д. Реализованы как один из них. Даже символы - это целые числа.

Сравнение с другими языками, где существуют типы строк, перечисляемые типы, которые могут быть назначены только определенным значениям, логические типы, в которых могут использоваться только выражения, которые генерируют логические значения или true/false.

Но вы можете утверждать, что по сравнению с Perl C строго типизирован. Таким образом, это один из тех известных аргументов (vi vs emacs, linux vs windows и т.д.). С# сильнее набирается, чем C. В принципе, вы можете спорить в любом случае. И ваши ответы, вероятно, будут идти в обоих направлениях:) Также некоторые учебники/веб-страницы скажут, что C слабо типизирован, а некоторые скажут, что C строго типизирован. Если вы перейдете к википедии, в записи C будет сказано "частично слабая типизация". Я бы сказал, что по сравнению с Python C слабо типизирован. Итак, Python/С#, C, Perl на континууме.

Ответ 7

Здесь много хороших ответов. Я хочу вынести важный момент из Real World Haskell:

Полезно знать, что многие языковые сообщества имеют свои собственные определения "сильный тип". Тем не менее, мы будем говорить кратко и в широком смысле о понятии силы в системах типов.

(надрез)

Фейерверки вокруг систем типа имеют свои корни на обычном английском языке, где люди присоединяют понятия ценности к словам "слабый" и "сильный": мы обычно думаем о силе лучше, чем о слабости. Многие программисты говорят на простом английском языке, нежели на академическом жаргоне, и нередко академики действительно бросают кирпичей в любую систему типов, которая не устраивает их воображение. Результатом часто является популярное интернет-времяпрепровождение, пламенная война.

Итак, посмотрите ответы на C и С++, но помните, что "сильный" и "слабый" не соответствуют "хорошим" и "плохим".

Ответ 8

По-моему, C/С++ строго типизированы. Тип хаков, которые позволяют преобразовывать типы (void *), существует из-за близости C к машине. Другими словами, вы можете вызвать команды ассемблера из Pascal и манипулировать указателями, а Pascal по-прежнему считается строго типизированным языком. Вы можете вызвать ассемблер и исполняемые файлы C из Java через JNI, но это не делает Java слабо типизированным.

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

Ответ 9

Термин строго типизированный не имеет согласованного определения. Поэтому, если вы не определяете, что вы подразумеваете под "строго типизированным", на ваш вопрос невозможно ответить.

По моему опыту, термины "строго типизированные" и "слабо типизированные" используются исключительно троллями, потому что их отсутствие определений позволяет троллям переопределять их в середине аргумента в соответствии с их повесткой дня. Помимо начальных фламинго, эти условия в значительной степени бесполезны.

Вы также можете взглянуть на Каковы ключевые аспекты строго типизированного языка? здесь, в StackOverflow.

Ответ 10

Существует континуум с несколькими параллельными направлениями между "слабо типизированными" и "сильно типизированными", два слагаемых, которые даже не определены четко.

C статически типизирован, поскольку компилятор знает, что объявленный тип каждой локальной переменной и член структуры.

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

Ответ 11

c слабо набрано, b не имеет значения.

Ответ 12

По словам Денниса Ричи (создателя C) и Брайана Кернигана, C не является строго типизированным языком. Следующие строки взяты из книги Язык программирования C стр. 3, пункт 5

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

Ответ 13

В чем причина вашего запроса? Причина, по которой я спрашиваю, заключается в том, что это своего рода незначительная разница, и ваше конкретное использование "строго типизированных" может потребовать более или менее разъяснений. Я бы определенно сказал, что Java и другие языки имеют более жесткие ограничения на неявный тип общения.

Ответ 14

Трудно дать конкретный ответ, если нет конкретного определения "строго типизированного". Я бы сказал, что C строго типизирован в том, что каждая переменная и каждое выражение имеют тип, но слабо набраны тем, что позволяют изменять типы с помощью приведения и переинтерпретировать представление одного типа как другого.

Ответ 15

Я бы сказал, что C так же строго типизирован, как диктуется ваш компилятор/платформа. Например, если вы строите на строгой платформе, разыменование типа плавающего указателя, скорее всего, сломается:

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

....
char *str = strdup("foo");
m_free((void **) &foo);

Теперь, если вы сказали компилятору пропустить строгий псевдоним, это будет не проблема, но не очень портативная. Таким образом, в этом смысле возможно продвижение границ языка, но, вероятно, не лучшая идея. Это выходит за рамки типичного литья, т.е. Литье int как можно дольше и действительно показывает одну из возможных ловушек пустоты.

Итак, я бы сказал, что C в основном строго типизирован, но его различные компиляторы предполагают, что программист знает лучше всего и допускает некоторую гибкость. Это действительно зависит от компилятора, некоторые из них не поймут этот потенциал. Поэтому в этом смысле, компилятор выбора действительно играет определенную роль при ответе на вопрос. То, что правильно, часто отличается от того, что ваш компилятор позволит вам уйти.

Ответ 16

Не сильно типизирован.

Рассмотрим, что прототип следующей функции сообщает вам о типах данных аргументов:

void func (int n, char ch, ...);

Ничего. Поэтому я предлагаю, чтобы сильная типизация здесь не применялась.

Ответ 17

Я бы сказал, что это сильно типы, поскольку каждое выражение имеет тип, который не является функцией его значения; E.I. он может быть известен до выполнения.

OTOH Я не уверен, что это правильное описание строго типизированного. Единственная сильная претензия, которую я могу видеть в объяснении для языка, - это уверенность в том, что вы не можете подорвать систему типов во время выполнения с помощью типов реинтерпретов, союзов, вызовов на другие языки, указателей, языка ассемблера и т.д. Языки, подобные этому существуют, но настолько искалечены, что они, похоже, не представляют большого интереса для программистов за пределами высокой уверенности и академических кругов. Как отметил кто-то, чтобы действительно сделать это право, вам нужно будет иметь такие типы, как nonZeroInt и еще что-то. Тьфу.