Процитирую Википедию :
Два широко используемых языка, поддерживающих многие виды неявного преобразования, - это C и C ++, и иногда утверждается, что это языки со слабой типизацией. Однако другие утверждают, что эти языки налагают достаточно ограничений на то, как могут быть смешаны операнды разных типов, что эти два языка следует рассматривать как строго типизированные языки.
Есть ли более точный ответ?
c
strong-typing
weakly-typed
Сидиус
источник
источник
Ответы:
Термины «строго типизированный» и «слабо типизированный» не имеют общепринятого технического значения. Термины, которые имеют четко определенное значение:
Динамически типизированный означает, что типы присоединяются к значениям во время выполнения, и попытка смешивания значений разных типов может вызвать «ошибку типа времени выполнения». Например, если в схеме вы попытаетесь добавить единицу к true, написав,
(+ 1 #t)
это вызовет ошибку. Вы столкнетесь с ошибкой, только если попытаетесь выполнить ошибочный код.Статически типизированный означает, что типы проверяются во время компиляции, а программа, не имеющая статического типа, отклоняется компилятором. Например, если в ML вы попытаетесь добавить единицу к true путем записи
1 + true
, программа будет отклонена с (возможно, загадочным) сообщением об ошибке. Вы всегда получаете сообщение об ошибке, даже если код может никогда не быть выполнен.Разные люди предпочитают разные системы отчасти в зависимости от того, насколько они ценят гибкость и насколько они беспокоятся об ошибках времени выполнения.
Иногда «строго типизированный» используется в широком смысле для обозначения «статически типизированный», а «слабо типизированный» неправильно используется для обозначения «динамически типизированный». Термин «строго типизированный» лучше использовать в том случае, если «нельзя обойти или подорвать систему типов», тогда как «слабо типизированный» означает «в системе типов есть лазейки». И наоборот, большинство языков со статическими системами типов имеют лазейки, в то время как многие языки с системами динамических типов не имеют лазеек.
Ни один из этих терминов никак не связан с количеством неявных преобразований, доступных в языке.
Если вы хотите говорить именно о языках программирования, лучше избегать терминов «строго типизированный» и «слабо типизированный». Я бы сказал, что C - это язык со статической типизацией, но в нем много лазеек. Одна лазейка заключается в том, что вы можете свободно преобразовывать любой тип указателя к любому другому типу указателя. Вы также можете создать лазейку между любыми двумя типами по вашему выбору, объявив объединение C, состоящее из двух членов, по одному для каждого из рассматриваемых типов.
Я написал больше о статической и динамической типизации в статье, почему-интерпретируемые-языки-в основном-утиные-пока-скомпилированы-имеют-строгую-типизацию .
источник
whereas "weakly typed" means "there are loopholes in the type system
Трудно разделить каждый язык на «слабо» или «строго» типизированный - это скорее континуум. Но по сравнению с другими языками C довольно сильно типизирован. Каждый объект имеет тип во время компиляции, и компилятор сообщит вам (громко), если вы делаете что-то с объектом, что его тип не позволяет вам сделать. Например, вы не можете вызывать функции с неправильными типами параметров, получать доступ к несуществующим членам структуры / объединения и т. Д.
Но есть несколько слабых мест. Одна из основных слабостей - это приведение типов: они по сути говорят, что вы собираетесь возиться с типами объектов, и компилятор должен молчать (когда это возможно).
void*
еще одна слабость - это общий указатель на неизвестный тип, и когда вы их используете, вы должны быть особенно осторожны, чтобы поступать правильно. Компилятор не может статически проверить большинство случаев использованияvoid*
.void*
также может быть преобразован в указатель на любой тип без приведения (только в C, а не в C ++), что является еще одним недостатком.источник
В литературе об этом не говорится. Я думаю, что строгая типизация - это не да / нет, есть разные степени строгой типизации.
В языке программирования есть спецификация того, как он выполняет программы. Иногда непонятно, как выполнять определенные программы. Например, программы, которые пытаются вычесть строку из числа. Или программы, которые делят на ноль. Есть несколько способов справиться с этими состояниями. В некоторых языках есть правила работы с этими ошибками (например, они вызывают исключение). В других языках просто нет правил для таких ситуаций. Эти языки обычно имеют системы типов для предотвращения компиляции программ, которые приводят к неопределенному поведению. И также существуют языки, которые имеют неопределенное поведение и не имеют системы типов, чтобы предотвратить эти ошибки во время компиляции (если вы напишете программу, которая выполняет неопределенное поведение, она может запустить ракеты).
Так:
Языки, которые определяют, что происходит во время выполнения в каждом случае (например, добавление числа в строку), называются динамически типизированными. Языки, которые предотвращают выполнение программ с ошибками во время компиляции, имеют статическую типизацию. Языки, которые не определяют, что происходит, а также не имеют системы типов для предотвращения ошибок, называются слабо типизированными.
Так является ли Java статически типизированной? Да, потому что его система типов не позволяет вычитать строку из числа. Нет, потому что это позволяет делить на ноль. Вы можете предотвратить деление на ноль во время компиляции с помощью системы типов. Например, создав числовой тип, который не может быть нулем (например, NonZeroInt), и разрешить деление только на числа, которые имеют этот тип.
Итак, C строго типизирован или слабо типизирован? C строго типизирован, потому что система типов запрещает некоторые ошибки типов. Но он слабо типизирован в других случаях, когда неясно, что происходит (и система типов вас не защищает).
источник
int
получает значение от пользователя, аргументов командной строки или файла, компилятор ничего не может сделать, чтобы помешать этому быть нулем!C считается слабо типизированным, потому что вы можете преобразовать любой тип в любой другой с помощью приведения без ошибки компилятора. Вы можете узнать больше о проблеме здесь .
источник
C более строго типизирован, чем Javascript, и менее строго типизирован, чем Ada.
Я бы сказал, что это больше относится к строго типизированной стороне континуума. но кто-то другой может не согласиться (даже если он ошибается).
Как это для окончательного?
источник
C считается статически типизированным (вы не можете изменять переменную с int на float). Как только переменная объявлена, она так и застревает.
Но он считается слабо типизированным, потому что типы можно перевернуть.
Что такое 0? '\ 0', ЛОЖЬ, 0,0 и т. Д.
на многих языках нельзя использовать IF (переменная), потому что условия будут принимать только логические значения из логических выражений. Они более строго типизированы. То же самое относится к переходу между символами и целыми числами.
в основном c имеет два основных простых типа данных, целые числа и числа с плавающей запятой (хотя и с различной точностью). Все остальное логические значения, перечисления (не простые, но подходящие) и т.д. реализованы как одни из них. Даже символы в основном целые.
Сравните с другими языками, где есть строковые типы, типы перечислений, которые могут быть присвоены только определенным значениям, логические типы, где могут использоваться только выражения, которые генерируют логические значения или истина / ложь.
Но вы можете возразить, что по сравнению с Perl C сильно типизирован. Так что это один из тех известных аргументов (vi vs emacs, linux vs windows и т. Д.). C # типизирован сильнее, чем C. В принципе, можно спорить в любом случае. И ваши ответы, вероятно, пойдут в обе стороны :) Также некоторые учебники / веб-страницы скажут, что C слабо типизирован, а некоторые скажут, что C строго типизирован. Если вы зайдете в Википедию, в записи C написано «частично слабая типизация». Я бы сказал, что по сравнению с Python C слабо типизирован. Итак, Python / C #, C, Perl на континууме.
источник
Здесь много хороших ответов. Я хочу поднять важный момент из Real World Haskell :
(вырезать)
Итак, посмотрите ответы на C и C ++, но помните, что «сильный» и «слабый» не соответствуют «хорошему» и «плохому».
источник
По словам Денниса Ричи ( создателя C ) и Брайана Кернигана, C не является строго типизированным языком. Следующие строки взяты из книги Язык программирования C, страница 3, параграф 5.
источник
На мой взгляд, C / C ++ строго типизированы. Типы хаков, которые позволяют преобразовывать типы (void *), существуют из-за близости C к машине. Другими словами, вы можете вызывать команды ассемблера из Паскаля и манипулировать указателями, а Паскаль по-прежнему считается строго типизированным языком. Вы можете вызывать исполняемые файлы ассемблера и C из Java через JNI, но это не делает Java слабо типизированным.
В C просто «встроен» ассемблер с необработанными указателями и тому подобным.
источник
Термин строго типизированный не имеет согласованного определения. Поэтому, если вы не определите, что вы имеете в виду под «строго типизированным», на ваш вопрос невозможно ответить.
По моему опыту, термины «строго типизированный» и «слабо типизированный» используются исключительно троллями, потому что их отсутствие определений позволяет троллям переопределять их в середине аргумента, чтобы удовлетворить их повестку дня. Эти термины бесполезны, если не считать начала боевых действий.
Вы также можете взглянуть на Каковы ключевые аспекты строго типизированного языка? здесь, в StackOverflow.
источник
Существует континуум с множеством параллельных направлений между «слабо типизированным» и «строго типизированным», двумя терминами, которые даже не имеют четкого определения.
C является статически типизированным, поскольку компилятор знает, какой объявлен тип каждой локальной переменной и элемента структуры.
Языки с динамической типизацией по-прежнему могут быть строго типизированными, если каждый объект имеет определенный тип, но компилятор не может узнать этот тип.
источник
В чем причина вашего запроса? Причина, по которой я спрашиваю, заключается в том, что это небольшая разница, и ваше конкретное использование «строго типизированного» может потребовать более или менее разъяснений. Я бы определенно сказал, что Java и другие языки имеют более жесткие ограничения на диалог неявных типов.
источник
Трудно дать конкретный ответ, когда нет конкретного определения термина «строго типизированный». Я бы сказал, что C строго типизирован в том смысле, что каждая переменная и каждое выражение имеет тип, но слабо типизирован, так как он позволяет вам изменять типы с помощью приведения типов и переинтерпретировать представление одного типа как другого.
источник
Я бы сказал, что C настолько строго типизирован, как того требует ваш компилятор / платформа. Например, если вы строите на строгой платформе, разыменование перфорированного указателя типа может сломаться:
void m_free(void **p) { if (*p != NULL) { free(*p); *p = NULL; } } .... char *str = strdup("foo"); m_free((void **) &foo);
Теперь, если вы скажете компилятору пропустить строгий псевдоним, это не проблема, но не очень переносимая. В этом смысле расширение границ языка возможно, но, вероятно, не лучшая идея. Это выходит за рамки типичного приведения типов, т. Е. Приведения типов к int до тех пор, пока они не выполняются, и действительно показывает одну из возможных ловушек void.
Итак, я бы сказал, что C в основном строго типизирован, но его различные компиляторы предполагают, что программист лучше всех знает и допускает некоторую гибкость. Это действительно зависит от компилятора, некоторые не заметят эту потенциальную ошибку. Так что в этом смысле выбранный компилятор действительно играет роль при ответе на вопрос. То, что является правильным, часто отличается от того, что ваш компилятор позволяет вам избежать.
источник
c слабо типизирован, b нетипизирован.
источник
Не строго типизированный.
Подумайте, что следующий прототип функции сообщает вам о типах данных аргументов:
void func (int n, char ch, ...);
Ничего. Поэтому я предлагаю здесь не применять строгую типизацию.
источник
Я бы сказал, что это строго типы, поскольку каждое выражение имеет тип, который не является функцией его значения; ei это может быть известно до времени выполнения.
OTOH Я не уверен, что это правильное описание строго типизированного. Единственное более сильное утверждение, которое я вижу для языка, - это уверенность в том, что вы не можете ниспровергнуть систему типов во время выполнения, переинтерпретируя приведение типов, объединения, вызовы на другие языки, указатели, язык ассемблера и т. Д. Подобные языки существуют, но настолько искалечены, что, кажется, не представляют особого интереса для программистов, за исключением высокоуровневых и академических кругов. Как заметил кто-то, чтобы действительно сделать это правильно, вам нужно иметь такие типы, как
nonZeroInt
и еще много чего. Фу.источник