Почему язык программирования позволяет присвоение от целого числа до короткого целого?

program TypeCategory;
{$R+}
var
    sInt : shortint;
    iInt : integer;
begin
    readln(iInt);
    sInt := iInt;
    writeln(sInt);
end.

Рассматривание вышеупомянутого примера, язык Паскаля действительно позволяет присвоение от integer кому: shortint, или даже longint кому: shortint без explict преобразования типа. Таким образом, Паскаль действительно позволяют присвоение в категории типа (вот целые типы).

Паскаль известен strongly typed, но почему это позволяет это отчасти weakly typed вещь? Я думаю, что этот вид синтаксиса поощрил бы непоследовательный код.

Что такое профессионалы для этого вида синтаксиса? Есть ли какие-либо другие языки, которые применили этот вид синтаксиса, кроме известного C и C++?

спасибо.

Править:
Я только протестировал turbo pascal и free pascal with fpc/objfpc/tp/delphi model.Also, gcc/g++ и msvc приведите к тому же результату. Таким образом, присвоение от int(который является размером 4 байтов на моем компьютере) к short int(размер 2), не инициирует ошибок компиляции, в то время как Вы могли установить надлежащие опции заставить компиляторы генерировать possible lose of data предупреждения.

5
задан Jichao 23 January 2010 в 13:34
поделиться

4 ответа

Часть 1. Об определениях

Прежде всего, какой язык и реализация вы используете называется «паскаль»? Если вы говорите о ISO Pascal , то он мертв много лет назад. Если вы говорите о каком-либо другом языке или реализации, пожалуйста, предоставьте дополнительную информацию.

Во-вторых (как уже упоминал Теун Д.) нет определения термина строгая типизация . Взгляните на статью в Википедии о строгой типизации .

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

Предположим, что мы следуем определению из статьи Луки Карделли «Типовое программирование», описанной ниже на странице Википедии:

В статье Луки Карделли «Типовое программирование» строгая типизация описывается просто как отсутствие неконтролируемых ошибок типов во время выполнения. В других текстах отсутствие неконтролируемых ошибок времени выполнения называется безопасностью или безопасностью типов; В ранних работах Тони Хора это называется безопасностью собственности.

В любом случае описанное поведение нельзя классифицировать как дисциплину статической (или безопасной) печати. Мне лично очень не нравится этот хммм ... Ну это не фича, это ошибка. =)

Часть 2. Ответ

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

Существуют ли другие языки, в которых применяется такой синтаксис, кроме знаменитых C и C ++?

Я думаю, что почти каждый статически типизированный язык с множеством типов целых чисел имеет такое поведение. Было неплохо иметь эти SHORTINT и все такое в ранние годы для экономии памяти. Но теперь, когда почти каждый компьютер имеет около 1 ГБ и больше ОЗУ ... Предположим, у нас есть 1 миллион 4-байтовых INTEGER вместо 2-байтовых SHORTINT. Это всего лишь около 4 МБ ОЗУ вместо 2 МБ. Я думаю, что это разумная цена за отсутствие всего этого странного поведения, которое вы описали.

Взгляните на Оберон-07 Вирта ( Отчет о языке, PDF ). Есть только один целочисленный тип - 32-битный INTEGER.

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

Итак, вы можете увидеть тенденцию - разнообразие типов целых чисел - это выживание 70-х. =)

Какие плюсы у такого синтаксиса?

Плюсы (вероятно) в уменьшении многословности. Эти статически типизированные языки уже настолько многословны, что, если мы решим добавить явное преобразование целочисленных типов, как это сделал Вирт в Обероне-2 (взгляните на функции SHORT () и LONG ()), они станут еще более подробными. В качестве компромисса можно разрешить неявное преобразование. Также во многих языках фактический размер переменных целочисленных типов не фиксирован и отличается от одной реализации к другой. Единственная доступная информация - это размер (shortint) <= size (int). В случае равенства явное преобразование выглядит довольно странно.

Часть 3. Дифирамб к Оберону-2 =)

Между прочим, не стоит слишком опасаться Паскаля. Он мертв, но в Оберон-2 Никлаус Вирт исправил свою ошибку.

В главе 6 Language Report вы можете найти информацию о типах. Для нашего обсуждения важно следующее:

Типы с 3 по 5 являются целочисленными типами, типы 6 и 7 являются действительными типами, и вместе они называются числовыми типами.Они образуют иерархию; больший тип включает (значения) меньшего типа: LONGREAL> = REAL> = LONGINT> = INTEGER> = SHORTINT

В главе 9 мы можем прочитать о присваивания:

Выражение должно быть совместимым по присваиванию с переменной

Наконец, в Приложении A:

Совместимость с присваиванием

Выражение e типа Te совместимо с присваиванием переменной v введите Tv, если выполнено одно из следующих условий:

Te и Tv одного типа;

Te и Tv являются числовыми типами и Tv включает Te ;

...

Итак, мы здесь. Вы не можете присвоить выражение INTEGER переменной SHORTINT. Если вам интересно, вы также можете взглянуть на Component Pascal , второстепенный вариант и усовершенствование Oberon-2. BlackBox Component Builder - это IDE для Windows.


В ответ на комментарий Джастина Смита.

Я удивлен, что он сказал, что больший тип включает (значения) меньшего типа: LONGREAL> = REAL> = LONGINT> = INTEGER> = SHORTINT, учитывая, что есть LONGINTS, которые не могут быть выражены как «REAL».

Я немного запутался в вашем утверждении

есть ДОЛГОСЫ, которые не могут быть выражены как "РЕАЛЬНЫЕ"

На самом деле на моей машине IDE, упомянутой выше, имеет

MAX (LONGINT) = 9223372036854775807

MAX (REAL) = 1,797693134862316E + 308

Таким образом, вы можете представить каждую LONGINT как REAL число. Но представление может быть неточным. Я думаю, вы на самом деле говорили об этом, но мы говорим здесь о различных преобразованиях целочисленных типов. А преобразование между REAL и INTEGER - это отдельная история. История плохого и запутанного нейминга. НАСТОЯЩИЕ числа на самом деле не являются действительными числами с математической точки зрения. Это какое-то приблизительное представление. Можно использовать аппроксимацию рациональных чисел (сохраняя числитель и знаменатель как целые числа), но обычно используется приближение с плавающей запятой. Стандарт IEEE для арифметики с плавающей запятой (также известный как IEEE 754) является наиболее широко используемым стандартом для вычислений с плавающей запятой.

Каждый должен знать, что НАСТОЯЩИЕ числа не являются действительными, а являются числами, описанными в стандарте IEEE 754. И каждый должен прочитать «Что должен знать каждый компьютерный ученый об арифметике с плавающей запятой» , чтобы прояснить некоторые моменты.

Но это уже другая история ... =)

8
ответ дан 13 December 2019 в 22:08
поделиться

Забудьте о создании событий, таких как нажатия клавиш. Хотя можно (различными непортящимися способами) создавать события и направлять их в систему обработки событий, это вызовет только соответствующие функции обработчика событий; он не заставляет браузер выполнять действия по умолчанию для создаваемого пользователем действия, например нажатие клавиши или щелчка мыши.

В любом случае, поведение, о котором вы говорите с сбросом на побег, является IE причудой: ни в одном другом браузере Escape не имеет никакого эффекта, и даже в IE это ненадежно. В частности, в обычной форме один Побег пресс теряет изменения с момента последнего фокуса, а два Побега пресса в строке сбрасывают всю форму до начальных значений. Однако если форма имеет в себе < input type = «reset» > , одно нажатие Escape сбрасывает форму и фокусирует кнопку сброса. Это еще больше облегчает случайную потерю всего введенного и является еще одной хорошей причиной не включать кнопку сброса в формы.

Таким образом, если требуется восстановить исходные значения, можно вызвать form.reset () . Если требуется сбросить только одно поле, можно задать значение input.value = input.defureValue (или input.checked = input.defureChecked для флажков/радиоприемников и аналогично defureSelected для параметров).

Если, однако, вы хотите, чтобы значение, которое присутствовало во время последней фокусировки поля, так как IE ведет себя, когда нет кнопки сброса, вам придется сделать некоторые переменные запоминания, например:

var undonevalue= $('#undoable').val();
$('#undoable').focus(function() {
    undonevalue= $('#undoable').val();
});
$('#undoer').click(function() {
    $('#undoable').val(undonevalue);
});
-121--4746504-

Согласовано, это глупое правило. Невозможно развернуть обновление исправления ошибок для сборки с сильным именем, когда вы следуете за ним. В противном случае существует несколько причин не делать их одинаковыми, если фактически необходимо изменить [AssemblyVersion]. Возможно, вы не должны использовать этот инструмент, когда исправляете ошибки. Иронично.

-121--3147274-

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

Вы имеете в виду, что, по-видимому, Паскаль не проверяет переполнение. В например. C #, можно задать поведение проверки из кода ( http://msdn.microsoft.com/en-us/library/khy08726 (VS.71) .aspx ), но часто это не делается из соображений производительности. Я предполагаю, что это касается и Паскаля.

0
ответ дан 13 December 2019 в 22:08
поделиться

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

2
ответ дан 13 December 2019 в 22:08
поделиться

Если бы язык никогда не допускал присваивания от int к short int, то невозможно было бы написать этот код

var
sInt : shortint;
iInt : integer;

if (iInt < 100 && iInt > -100)
{
   sInt := iInt; // this would not compile
}

или этот

var
sInt : shortint;
iInt : integer;

sInt := (iInt & 0xFFFF); // this would not compile

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

var
sInt1 : shortint;
sInt2 : shortint;
iInt : integer;

/* I want to multiply sInt2 by sInt1 and then divide by 100 */
iInt = sInt2;
sInt2 := (iInt * sInt1) / 100; // this would not compile

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

0
ответ дан 13 December 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: