2014 dxdy logo

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

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




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

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

Да. А вы нет?

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

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

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

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

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

 
 
 
 Re: Сравнение двух стилей программирования
Сообщение15.12.2012, 02:35 
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: Сравнение двух стилей программирования
Сообщение15.12.2012, 08:18 
Joker_vD в сообщении #658577 писал(а):
Т.е. вы хотите сказать, что
Код:
int x = 265;
byte t = (byte)x;

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

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

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

 
 
 
 Re: Сравнение двух стилей программирования
Сообщение15.12.2012, 14:25 
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: Сравнение двух стилей программирования
Сообщение15.12.2012, 15:42 
Аватара пользователя
Joker_vD в сообщении #658577 писал(а):
Да не бывает сильной/слабой типизации. Бывает статическая — когда типы выводятся на этапе компиляции и динамическая — когда они выводятся во время выполнения.

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

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

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

-- 15.12.2012, 16:44 --

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 
 
 
 Re: Сравнение двух стилей программирования
Сообщение15.12.2012, 22:31 
Аватара пользователя
Почему бы не так сделать?
Код:
...
{ Создание нового узла списка }
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: Сравнение двух стилей программирования
Сообщение15.12.2012, 22:42 
Аватара пользователя
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: Сравнение двух стилей программирования
Сообщение15.12.2012, 22:47 
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