Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1, 2, 3, 4, 5, 6  След.
 Re: Сравнение двух стилей программирования
Аватара пользователя
Господа, давайте не будем переходить к теме противоборства сильной и слабой типизаций. то всё же отдельная тема, в которой сломано немало копий.

Munin в сообщении #658130 писал(а):
Вы так думаете?

Да. А вы нет?

Munin в сообщении #658130 писал(а):
Нет, они просто имеют чётко прописанное поведение.

AddElement() тоже.
И это какая-то игра словами получается. "Имеют чётко прописанное поведение" - " полагаются на здравомыслие и адекватность программиста.".
Какая разница?
Можно подумать, чётко прописанное поведение мешает программисту написать код так, что программа порушится.

Joker_vD в сообщении #658495 писал(а):
Я могу раскопать статью о неявных приведениях типов в C (кажется), в которой показывается, как вроде бы безобидные арифметические выражения могут иметь результатом ответ, резко отличающийся от задуманного программистом.

Можно мне, пожалуйста? (:

_Ivana, всё же Ваш случай - опять-таки не совсем стандартный.
Как Вы же и заметили ранее, оптимизация процесс - сложный, и надо учитывать массу параметров.
И довольно спорно, насколько можно Ваш опыт можно просто экстраполировать на общий случай.
Хотя да, помнить о том, что приоритеты могут быть разными, нужно.

 Re: Сравнение двух стилей программирования
venco в сообщении #658504 писал(а):
делают совсем не так - пишут ровно один байт в 4-байтовый блок в стеке.

Но со стороны это выглядит как если бы в стек положили 4-байтовое слово. На нем ведь нигде не написано, что остальные три байта — мусор.

venco в сообщении #658504 писал(а):
Ну так они и при преобразовании int в byte то же самое швыряют.

Т.е. вы хотите сказать, что
Код:
int x = 265;
byte t = (byte)x;

кинет исключение? Или я чего-то не так понял?

Я уж не знаю, о чем идет речь.

-- Сб дек 15, 2012 03:39:59 --

shau-kote в сообщении #658574 писал(а):
Господа, давайте не будем переходить к теме противоборства сильной и слабой типизаций.

Да не бывает сильной/слабой типизации. Бывает статическая — когда типы выводятся на этапе компиляции и динамическая — когда они выводятся во время выполнения. Плюс неявные преобразования, встроенные в язык. Так что AddElement(TooWideUntegralArgument) будет вести себя вполне определенным образом: в Си/Дельфи аргумент обрежется до нужного размера, в C#/Java этот вызов просто не скомпилируется.

 Re: Сравнение двух стилей программирования
Joker_vD в сообщении #658577 писал(а):
Т.е. вы хотите сказать, что
Код:
int x = 265;
byte t = (byte)x;

кинет исключение?
Да, и при тех же условиях, что и переполнение при сложении - в checked коде.

 Re: Сравнение двух стилей программирования
Аватара пользователя
shau-kote в сообщении #658574 писал(а):
AddElement() тоже.

Ну что ж, давайте проверим. Опишите мне поведение вашего AddElement() из первого сообщения.

 Re: Сравнение двух стилей программирования
ewert в сообщении #658475 писал(а):
В том же Паскале есть механизм приведения типов (или уж не помню, как он называется). Запросто можно написать то-нибудь типа byte(c):=i или там char(b):='&', или наоборот, и это весьма эффективно. Если, конечно, хоть изредка приходить в сознание.

Эффективно, но действительно потенциально опасно. Вот, например, такая программа:
Используется синтаксис Delphi
program test;
var
  a, b, c: byte;
  n: longint;

begin
  writeln(37*41*61);
  a:=37;
  b:=41;
  c:=61;
  n:= a*b*c;
  writeln(n);
end.

выведет на экран два разных числа. Это, кстати, пример из жизни: автор этого кода долго ломал голову над вопросом, почему так получается.

 Re: Сравнение двух стилей программирования
Аватара пользователя
Joker_vD в сообщении #658577 писал(а):
Да не бывает сильной/слабой типизации. Бывает статическая — когда типы выводятся на этапе компиляции и динамическая — когда они выводятся во время выполнения.

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

Munin в сообщении #658666 писал(а):
Ну что ж, давайте проверим. Опишите мне поведение вашего AddElement() из первого сообщения.

Процедура AddElement() добавляет в список-очередь новый элемент и помещает в него данные.
Соответственно, довольно очевидно, что она должна получать на вход собственно "данные" (число в данном случае) и указатель на конец списка.

-- 15.12.2012, 16:44 --

Pphantom в сообщении #658709 писал(а):
автор этого кода долго ломал голову над вопросом, почему так получается.

А действительно, кстати, почему?
При вычислении промежуточного результата a*b он помещается в ячейку того же типа(byte)?

 Re: Сравнение двух стилей программирования
shau-kote в сообщении #658734 писал(а):
А действительно, кстати, почему?
При вычислении промежуточного результата a*b он помещается в ячейку того же типа(byte)?

Нет, все немного хитрее. Компилятор предполагает, что результаты операций с данными некоторого типа могут выходить за его пределы, поэтому всегда при вычислениях расширяет тип до следующего уровня. В итоге при перемножении a*b*c результату приписывается тип integer (но на 32-битной системе результат в него не помещается, и в переменную n помещается уже результат "обрезки"). В случае же перемножения без переменных константы автоматически принимают тип integer (а не byte), результату приписывается тип longint и все работает правильно.

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

 Re: Сравнение двух стилей программирования
Аватара пользователя
Pphantom в сообщении #658738 писал(а):
Нет, все немного хитрее. Компилятор предполагает, что результаты операций с данными некоторого типа могут выходить за его пределы, поэтому всегда при вычислениях расширяет тип до следующего уровня. В итоге при перемножении a*b*c результату приписывается тип integer (но на 32-битной системе результат в него не помещается, и в переменную n помещается уже результат "обрезки"). В случае же перемножения без переменных константы автоматически принимают тип integer (а не byte), результату приписывается тип longint и все работает правильно.

Мда. Действительно, хитро.

Я так понимаю, простейший способ это обойти - написать longint(a)*b*c?

 Re: Сравнение двух стилей программирования
shau-kote в сообщении #658747 писал(а):
Я так понимаю, простейший способ это обойти - написать longint(a)*b*c?

Да. Но при этом вся польза от неявного преобразования типов испаряется.

 Re: Сравнение двух стилей программирования
Аватара пользователя
Pphantom в сообщении #658753 писал(а):
Да. Но при этом вся польза от неявного преобразования типов испаряется.

Ну почему же.
Неявное преобразование типов хорошо тем, что оно позволяет не преобразовывать явно типы в большинстве случаев, когда компилятор может "угадать", что от него тут хочет программист.
Но это не даёт полного избавления от необходимости иногда, _иногда_ давать явные указания по преобразованию типов.

 Re: Сравнение двух стилей программирования
Аватара пользователя
Можно так сделать:
n:=a;
n:=n*b*c;
А умножение байтов не учитывает тот факт, что произведение имеет размер равный сумме размеров операндов, следовательно нужно отслеживать переполнение.
Т.е. n:=n*b*c*d уже может не влезть в лонгинт (31 бит).

 Re: Сравнение двух стилей программирования
Munin в сообщении #657767 писал(а):
А в procedure add никто не хочет last^.next на nil проверить? А то в чём смысл структурировать программу, если получающиеся куски всё равно полагаются друг на друга...
А вот задача: Написать функцию, проверяющая является ли односвязанный список зацикленным. (или заканчивает на nil). Входные параметры: указатель к стартовому элементу. Структура известна.

 Re: Сравнение двух стилей программирования
Аватара пользователя
Почему бы не так сделать?
Код:
...
{ Создание нового узла списка }
procedure make ( var lst : lst_ptr );
begin
   new ( lst );
   readln ( lst^.data ); { Ввод строки }
   lst^.next := top;
   top := lst;
end;
...
begin
   top := nil;   { Указатель на вершину списка }
   lst := nil;   { Указатель на элемент списка }
   repeat
      make ( lst );
   until lst^.data = '0';
...

 Re: Сравнение двух стилей программирования
Аватара пользователя
Shadow, вот, что смог придумать за двадцать минут.
Знаю, что неструктурные операторы не есть хорошо, но тем не менее.
Использовал типы, объявленные EtCetera во втором посте треда.

код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
function checkLooped(sameElement: PElement): boolean;
var q: PElement;
begin
 
  if sameElement=nil then
    begin
      Result:=FASLE;
      Exit;
    end;
 
  q:=sameElement;

  repeat
    q:=q^.nextElement;
  until (q=nil) or (q=sameElement);
 
  Result:=(q=sameElement);

end;
 


-- 15.12.2012, 23:46 --

Chifu в сообщении #658876 писал(а):
Почему бы не так сделать?

А чем Ваш вариант лучше тех, что были в этом треде ранее?
Тем, что обращается из подпрограммы к глобальным переменным?

 Re: Сравнение двух стилей программирования
shau-kote к сожелению, список может быть зациклен не на стартовый елемент. Например 1->2->3->2->3->2->3->...

 [ Сообщений: 82 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group