Форум программистов, компьютерный форум, киберфорум
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
Другие темы раздела
Pascal Установить в Debian что-нибудь похожее интерфейсом IDE на Turbo Pascal https://www.cyberforum.ru/ pascal/ thread1260862.html
Подскажите, что и как можно установить в Debian что-нибудь похожее интерфейсом IDE на Turbo Pascal. Спасибо. Добавлено через 3 минуты Да, ещё желательно, чтоб была совместимость с синтаксисом...
Pascal В массиве удалить все элементы кратные заданному числу
Задать три массива: один случайными целыми числами, второй вещественными положительными числами, третий - целыми числами в диапазоне значений от h до f. В первом массиве удалить все элементы кратные...
Вывести K-e степени чисел из заданного набора Pascal
Вариант4. Даны целые числа K, N и набор из N вещественных чисел: A1, A2, …,AN. Вывести K-e степени чисел из данного набора: (A1)^K, (A2)^K, …, (AN)^K. ^cтепень
Pascal Вычислить значение y в зависимости от х функции очень нуждаюсь в помощи.. нужно вычислить значение y в зависимости от х функции... https://www.cyberforum.ru/ pascal/ thread1260635.html
Pascal Задать массив вещественными числами от а до в, в количестве n и найти сумму всех цифр чисел кратных трем https://www.cyberforum.ru/ pascal/ thread1260321.html
Задать массив вещественными числами от а до в , в количестве n и найти сумму всех цифр чисел кратных трем
Задать массив целыми числами в диапазоне [0.100] и удалить все элементы , у которых последняя цифра 8 Pascal
Задать массив целыми числами в диапазоне и удалить все элементы , у которых последняя цифра 8
Pascal Если в строке, размещенной в динамической памяти, нет символа +, то оставить текст без изменения
Если в строке,размещенной в динамической памяти,нет символа +,то оставить текст без изменения, иначе каждую из цифр, предшествующую первому вхождению символа + заменить символом -.помогите сделать на...
Pascal Найти в последовательности самую длинную подпоследовательность, состоящую только из положительных чисел Найти в заданной последовательности самую длинную подпоследовательность, состоящую только из положительных чисел. используя текстовые файлы https://www.cyberforum.ru/ pascal/ thread1260267.html
Pascal Написать программу, в которой задается число, а компьютер его угадывает https://www.cyberforum.ru/ pascal/ thread1259883.html
помогите пожалуйста, написать программу, в которой я задаю число, а компьютер угадывает это число. количество попыток ограничено ?
Pascal Дан текст содержащий сведения об успеваемости учащихся. Определить средний балл каждого ученика Задача:Дан текст содержащий сведения об успеваемости учащихся, разделенное запятой.Каждое сведение содержит фамилию, имя ученика и оценки по 4 предметам, и заканчивается ".". Определить средний... https://www.cyberforum.ru/ pascal/ thread1259643.html
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
30869 / 20190 / 7875
Регистрация: 22.10.2011
Сообщений: 35,050
Записей в блоге: 6
0

Как не надо писать программы

22.09.2014, 21:10. Просмотров 17383. Ответов 4
Метки (Все метки)


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

Итак:

Когда вы пишете графическую программу, вы не должны ...

... рассчитывать на то, что размер экрана постоянен, и равен 640 пикселей по горизонтали на 480 по вертикали. Простейший код - заставка: приветствие пользователя. В центре экрана должна появиться надпись 'Hello'. Что делают новички?
Pascal
1
2
{ инициализация графики }
OutTextXY(320, 240, 'Hello');
Так делать не надо. Потому что это сейчас программа запускается в режиме VgaHi (640x480). Позже вам может понадобиться несколько видеостраниц, а в этом режиме их нет. Придется инициализировать или VgaMed (640x350), или VgaLo (640x200). В случае VGALo вы вообще не увидите "заставки", просто потому что она будет вне экрана.
Написав код правильно:
Pascal
1
2
{ инициализация графики }
OutTextXY(GetMaxX div 2, GetMaxY div 2, 'Hello');
, вы избегаете таких проблем, это будет корректно работать в любом режиме, хоть 320*200, хоть 640*480 (и даже в более высоких разрешениях).

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

Этот пункт является по сути продолжением предыдущего пункта. Итак, была поставлена задача вывести несколько строк, и обвести их прямоугольником (что-то подобное всплывающему меню в Windows-приложениях). Вот так эта задача была решена:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uses graph;
var gd, gm, i: integer;
const
  s: array[1 .. 5] of string = (
    'one', 'two', 'three', 'four', 'five'
  );
begin
  initgraph(gd, gm, '');
  for i := 1 to 5 do
  begin
    outtextxy(10, 10 + 15 * (i - 1), s[ i ]);
  end;
  rectangle(5, 5, 60, 10+15*5);
  readln;
  closegraph;
end.
При запуске программы получается достаточно приемлемый результат. И тогда программист берет и выносит этот код в отдельную процедуру, справедливо полагая, что это поможет ему выводить разные "менюшки" в разных местах экрана:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
uses graph;
var
  gd, gm, i: integer;
  i: integer;
 
procedure Print(px, py: integer;
                const s: array of string; n: integer);
var i: integer;
begin
  for i := 1 to n do
  begin
    outtextxy(px, py + 15 * (i - 1), s[i - 1]);
  end;
  rectangle(px - 5, py - 5, px + 50, py+15*n);
end;
 
const
  s: array[1 .. 5] of string = (
    'one', 'two', 'three', 'four', 'five'
  );
begin
  initgraph(gd, gm, '');
  print(10, 10, s, 5);
 
  readln;
  closegraph;
end.
Этот код работает абсолютно так же, как и предыдущий:

Как не надо писать программы


после чего программист, считая, что здесь прокола не будет, использует эту процедуру в своей программе "по полной". И в какой-то момент сталкивается с проблемой:

Как не надо писать программы


Шрифт был изменен с дефолтного на SmallFont, отображение уже не такое, как прежде, и придется искать неправильную константу и исправлять ее (скорее всего - методом подбора). А этого опять же можно было избежать, сразу ориентируясь на работу с разными шрифтами:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure Print(px, py: integer;
                const s: array of string; n: integer);
var i, curr_x, curr_y, max_x: integer;
begin
  max_x := 0; curr_y := 0;
  for i := 1 to n do
  begin
    curr_x := textwidth(s[i - 1]);
    if curr_x > max_x then max_x := curr_x;
 
    outtextxy(px, py + curr_y, s[i - 1]);
    inc(curr_y, textheight(s[i - 1]) + 5);
  end;
  rectangle(px - 5, py - 5, px + max_x + 5, py + curr_y);
end;
Никаких "магических чисел", ширина и высота текста вычисляются библиотечными функциями. Такая процедура будет работать с любыми выбранными шрифтами, и картинка будет одинаково правильной:
(smallfont, 4)

Как не надо писать программы



(gothicfont, 5)

Как не надо писать программы


... использовать числовые значения вместо именованных констант.
В общем-то, этого правила стоило бы придерживаться не только при программировании графики, но и вообще при любом программировании, особенно начинающему программисту. Однако, как показывают вопросы, задаваемые на форумах, этого правила новички как раз и не придерживаются. А зря. Мне, например, гораздо сложнее понять, что такое:
Pascal
1
2
3
4
5
SetFillStyle(1, 12);
fillEllipse(i, j, r, r);
delay(1000);
SetFillStyle(1, 0);
fillEllipse(i, j, r, r);
или
Pascal
1
2
3
4
SetTextJustify(1,2);
OutTextXY(ygmin-5, xgmin-10, 'fi');
SetTextJustify(2,1);
OutTextXY(ygmax+170, xgmax-160, 't');
, чем разобраться вот в таких кодах:
Pascal
1
2
3
4
5
SetFillStyle(SolidFill, LightRed);
fillEllipse(i, j, r, r);
delay(1000);
SetFillStyle(SolidFill, Black);
fillEllipse(i, j, r, r);
и
Pascal
1
2
3
4
SetTextJustify(CenterText, TopText);
OutTextXY(ygmin-5, xgmin-10, 'fi');
SetTextJustify(RightText, CenterText);
OutTextXY(ygmax+170, xgmax-160, 't');
Ведь компилятор все равно подставит те же самые значения (выигрыша от того, что задаются числа не будет никакого), но программисту будет гораздо проще понять код, и, следовательно, сопровождать и модифицировать его.

Ну, и еще одно замечание. Не перемешивайте логику и интерфейс. Я уже устал говорить об этом, но, похоже, меня не слышат. Если вы делаете графическое меню, то функция отображения должна только отображать его, ни в коем случае не выполняя действия, "подключенные" к этому пункту меню. Потому, что если вам потом захочется сделать другое меню (или текстовое, или тоже графическое, но, скажем, трехмерное), то при разделенных логике/интерфейсе достаточно будет написать новую функцию, отображающую менюшки, а все остальное останется без изменения. В большинстве же проектов, которые пишут студенты начальных курсов ВУЗов, проще переписать всю программу заново, чем чуть-чуть изменить ее внешний вид (потому что все переплетено настолько вычурно, что только потяни за одну ниточку, все запутается окончательно).

Вернуться к обсуждению:
Как не надо писать программы
11
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.09.2014, 21:10
Готовые ответы и решения:

Как писать программы?
Подскажите как чайнику написать прогу

Подскажите, пожалуйста, как писать данные программы, чтобы я понял принцип
Приветствую, форумчане! Подскажите пожалуйста, как писать данные программы, чтобы я понял принцип и...

Как писать программы с неравенствами?
как вообще писать программы с неравенствами ??? решите эту ((a*x)/(x+b))>0 с чего начать:(

Литература: как писать программы в паскале
Пожалуйста,напишите список литературы где очень доходчиво написанно как писать программы в паскале

4
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.