Разработка электронного учебника "Практическое решение задач в Delphi"
Знакомство с объектно-ориентированным языком программирования Borland Delphi. Главные составные части среды Delphi. Интерактивные обучающие программы - тьюторы. Построение пользовательского интерфейса, создание приложений, работающих с базами данных.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 16.05.2013 |
Размер файла | 1,4 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Имеются локальные переменные, которые объявлены в процедуре (функции) и действуют только в подпрограмме, и глобальные переменные, которые действуют во всей программе (включая подпрограммы).
Если подпрограмма должна изменить значение только одной переменной основной программы, то её следует оформить как функцию.
В остальных случаях подпрограмму нужно оформить как процедуру. При описании переменных подпрограмма имеет дело с параметрами.
Различают формальные и фактические параметры.
Параметры, определённые при описании процедуры (функции), называются формальными. Параметры, задаваемые при вызове процедуры (функции), называются фактическими.
Если в заголовке перед параметром стоит var, то этот параметр считается параметром-переменной, соответствующий ей фактический параметр может быть только именем переменной. Если же перед параметром var не стоит, то это - параметр-значение и его можно вызывать фактическим параметром, имеющим конкретное значение или выражение. Например,
procedure pr(a: integer; var s: real);
вызывается в разделе операторов
pr(5*6+2, s1);.
Структура процедуры
Процедура начинается заголовком, за которым следуют:
- раздел объявления констант;
- раздел объявления типов;
- раздел объявления переменных;
- раздел инструкций.
Объявление процедуры в общем виде выглядит следующим образом:
procedure Имя (СписокПараметров);
const // начало раздела объявления констант
type // начало раздела объявления типов
var // начало раздела объявления переменных
begin // начало раздела инструкций
end;
Заголовок процедуры состоит из слова Procedure, за которым следует имя процедуры. Если у процедуры есть параметры, то они указываются после имени процедуры в скобках. Завершается заголовок процедуры символом "точка с запятой".
Если в процедуре используются именованные константы, то они объявляются в разделе объявления констант, который начинается словом const.
За разделом констант следует раздел объявления типов, начинающийся словом type.
После раздела объявления типов идет раздел объявления переменных, в котором объявляются (перечисляются) все переменные, используемые в программе. Раздел объявления переменных начинается словом var.
За разделом объявления переменных расположен раздел инструкций. Раздел инструкций начинается словом begin и заканчивается словом end, за которым следует символ "точка с запятой". В разделе инструкций находятся исполняемые инструкции процедуры.
Ниже, в качестве примера, приведен фрагмент программы вычисления стоимости покупки - процедура summa.
procedure Summa;
var
cena: real; // цена
kol: integer; // количество
s : real; // сумма
mes: string[255]; // сообщение
begin
cena := StrToFloat (Form1.Edit1.Text);
kol := StrToInt(Form1.Edit2.Text);
s := cena * kol;
if s > 500 then
begin
s := s * 0.9;
mes := 'Предоставляется скидка 10%' + #13;
end;
mes := mes+ 'Стоимость покупки: '
+ FloatToStrF(s,ffFixed,4,2) +' руб.';
Form1.Label3.Caption := mes;
end;
3.2 Структура функции
Функция начинается с заголовка, за которым следуют разделы объявления констант, типов и переменных, а также раздел инструкций.
Объявление функции в общем виде выглядит следующим образом:
function Имя (СписокПараметров) : Тип;
const // начало раздела объявления констант
type // начало раздела объявления типов
var // начало раздела объявления переменных
begin // начало раздела инструкций
result := Значение; // связать с именем функции значение
end;
Заголовок функции начинается словом function, за которым следует имя функции. После имени функции в скобках приводится список параметров, за которым через двоеточие указывается тип значения, возвращаемого функцией (тип функции). Завершается заголовок функции символом "точка с запятой".
За заголовком функции следуют разделы объявления констант, типов и переменных.
В разделе инструкций помимо переменных, перечисленных в разделе описания переменных, можно использовать переменную result. По завершении выполнения инструкций функции значение этой переменной становится значением функции. Поэтому среди инструкций функции обязательно должна быть инструкция, присваивающая переменной result значение. Как правило, эта инструкция является последней исполняемой инструкцией функции.
3.3 Основные различия между функциями и процедурами
1. Функция, как правило, возвращает одно единственное значение, например Sin (x).
Процедура может возвращать сложные структуры, например массивы.
2. Заголовок функции (ее первая строка) завершается указанием типа возвращаемого значения (например, real, integer и т.д.). В заголовке процедуры такая информация не требуется.
3. В конце тела функции ей присваивается то значение, для вычисления которого она предназначена, например, Sum_Mas:=S;
4. Функция может быть операндом математического выражения. Процедура не может быть частью выражения.
3.4 Правила применения подпрограмм
Нельзя в заголовке подпрограммы описывать сложные структуры, необходимо ссылаться на описание типов этих структур в основной программе.например,
Procedure pr1(a: array [1..n] of integer); - нельзя!
Можно:
Procedure pr1(a: Mas_Type);,
где Mas_Type - имя типа, описанного в основной программе:
const n=100;
Type Mas_Type= array[1..n] jf integer;
2. Типы формальных и фактических параметров должны быть согласованными.
3. Подпрограммы с параметром-значением не возвращают этот параметр главной программе, параметр значение копируется в стек; им может быть переменная, константа или математическое выражение.
4. Процедуры с параметром-переменной возвращают этот параметр программе, в стек копируется только адрес параметра-переменной. Фактическими параметрами параметров переменных могут быть только переменные.
5. Подпрограммы с параметром-константой не могут изменить этот параметр в главной программе, в стек копируется только адрес параметра-константы, она может быть переменной, константой или математическим выражением.
6. Желательно, чтобы имена формальных и фактических параметров были различными. Глобальная переменная в подпрограмме становится локальной, если она объявлена в заголовке подпрограммы или в её разделе описания переменных.
7. В подпрограммах могут быть объявлены локальные метки, константы, переменные, процедуры и функции, но не может быть объявлена директива компилятора Uses.
3.5 Контрольные вопросы
1. В чем различия между процедурой и функцией?
2. Какие цели достигаются при использовании подпрограмм?
3. Опишите структуру процедуры.
4. С какого слова начинается объявление любой процедуры?
5. Каким символом завершается заголовок процедуры?
6. Что перечисляется в разделе объявление переменных?
7. Какими словами начинается и заканчивается раздел инструкций?
8. С какого слова начинается заголовок функции и что за ним следует?
9. Чем отличаются глобальные переменные от локальных?
10. Различают формальные и фактические параметры. Опишите.
11. Будет ли видима глобальная переменная внутри подпрограммы, если в этой программе имеется локальная переменная с таким же именем?
12. В каких случаях применимы параметры - константы?
13. Почему в функциях нежелательно использовать параметры - переменные?
3.6 Задния к лабораторной работе № 3
Вариант 1.
1. Треугольник задан координатами своих вершин. Составить прграмму для вычисления его площади.
2. Даны две дроби А/В и С/D (A,B,C,D-натуральные числа). Составить программу для вычитания из первой дроби второй. Результат должен быть несократимой дробью.
Вариант 2.
1. Заменить отрицательные элементы линейного массива их модулями, не пользуясь стандартной функцией вычисления модуля. Подсчитать количество произведенных замен.
2. Даны две дроби A/В и С/D (A,B,C,D-натуральные числа). Составить программу для сложения дробей. Результат должен быть несократимой дробью.
Вариант 3.
1. Сформировать массив X(N), N-й член которого определяется формулой X(N)=1/N!.
2. На плоскости заданы своими координатами n точек. Создать массив размером n(n-1), элементами которого являются расстояния от каждой из точек до n-1 других.
Вариант 4.
1. Даны числа X,Y,Z,T - длины сторон четырехугольника. Вычислить его площадь, если угол между сторонами длиной X и Y -прямой.
2. Составить программу для вычисления суммы факториалов всех чётных чисел от m до n.
Вариант 5.
1. Заменить данное натуральное число на число, которое получается из исходного записью его цифр в обратном порядке (например, дано число 156, нужно получить 651).
2. Дано простое число. Составить функцию, которая будет находить следующее за ним простое число.
Вариант 6.
1. Написать программу вычисления суммы p/q=1-1/2+1/3-…+((-1)^(n+1))/n для заданного числа n. Дробь p/q должна быть несократимой(p, q - натуральные).
2. Составить функцию для нахождения наименьшего нечётного натурального делителя k (k?1) любого заданного натурального числа n.
Вариант 7.
1. Напечатать все пары чисел-близнецов из отрезка [n,2n], где n - заданное натуральное число больше 2.
2. Дано натуральное число N. Составить программу для формирования массива, элементами которого являются цифры числа N.
Вариант 8.
1. Найти все пары дружественных чисел, которые не больше данного числа К.
2. Составить программу, определяющую, в каком из данных двух чисел больше цифр.
Написать программу вычисления суммы 1+1/2+1/3+…+1/n для зааданного числа n. Результат представить в виде несократимой дроби p/q (p, q - натуральные).
Вариант 9.
1. Составить программу для нахождения чисел из интервала [M,N], имеющих наибольшее количество делителей.
2. Найти все числа Армстронга от 1 до К написать программу, которая находит и выводит на печать все четырехзначные числа вида abcd, для которых выполняется: 1) a, b, c, d - разные цифры; 2) ab - cd = a+ b+ c+ d.
Вариант 10.
1. Даны числа X,Y,Z,T-длины сторон четырёхугольника. Вычислить его площадь, если угол между сторонами X и Y-прямой.
2. Составить программу для вычисления суммы факториалов, всех чисел, кратных 3, от А до В.
Вариант 11.
1. Дано простое число. Составить функцию, которая будет находить следующие К простых чисел. Сформировать массив X(N), N-ый член которого определяется формулой X(N)=1/N!
2. Заменить отрицательные элементы линейного массива их модулями, не пользуясь стандартной функцией вычисления модуля. Подсчитать количество произведённых замен.
Вариант 12.
1. Найти все натуральные числа, не превосходящие заданного n, которые делятся на каждую из своих цифр.
2. Найти все простые натуральные числа, не превосходящие n, двоичная запись которых представляет собой палиндром.
Вариант 13.
1. Составить подпрограмму, которая будет находить корни квадратного уравнения.
2. Написать программу вычисления суммы 1+1/2+1/3+…+1/n для заданного числа n. Результат представить в виде несократимой дроби p/q (p,q-натуральные).
Вариант 14.
1. Даны натуральные числа K и N. Составить программу формирования массива А, элементами которого являются числа, сумма цифр которых равна K и которые не больше N.
2. Найти все натуральные n-значные числа, цифры в которых образуют строго возрастающую последовательность (например, 1234, 5789).
Вариант 15.
1. Дано простое число. Составить функцию, которая будет находить следующие за ним последнее простое число..
2. Имеется часть катушки с автобусными билетами. Номер билета шестизначный. Составить программу, определяющее количество счастливых билетов на катушке, если меньший номер билета - N, больший - М(билет является счастливым, если сумма первых трех его цифр равнв сумме последних трех).
4. Лабораторная работа № 4. Строки
4.1 Понятие о строковой переменной
Строка - это последовательность символов. Каждый символ занимает 1 байт памяти (код ASCLL). Количество символов в строке называется ее длиной. Длина строки может находиться в диапазоне от 0 до 255. Строковые величины могут быть константами и переменными.
Строковая константа есть последовательность символов, заключенная в апострофы.
Например:
`Язык программирования ПАСКАЛЬ',
`IBM PC- computer',
'33-45-12'.
Строковая переменная описывается в разделе описания переменных следующим образом:
Var<идентификатор>:String [<максимальная длина строки>]
Например:
Var Name: String[20]
Строковая переменная занимает в памяти на 1 байт больше чем указанная в описании длина. Дело в том, что один (нулевой) байт содержит значение текущей длины строки. Если строковой переменной не присвоено никакого значения, то ее текущая длина равна нулю. По мере заполнения строки символами ее текущая длина возрастает, но она не должна превышать максимальной по описанию величины.
Символы внутри строки индексируются (нумеруются) от единицы. Каждый отдельный символ идентифицируется именем строки с индексом, заключенным в квадратные скобки.
Например:
Name[5], Name[i], slovo[k+l].
Тип String и стандартный тип char совместимы. Строки и символы могут употребляться в одних и тех же выражениях.
Строковые выражения строятся из строковых констант, переменных, функций и знаков операций. Над строковыми данными допустимы операции сцепления и операции отношения.
Операция сцепления (+) применяется для соединения нескольких строк в одну результирующую строку. Сцеплять можно как строковые константы, так и переменные.
Например:
`ЭВМ'+'IBM'+'PC'.
Длина результирующей строки не должна превышать 225.
Операции отношения =,<,>,<=,>=,<> производят сравнение двух строк, в результате чего получается логическая величина (true или false).
Операция отношения имеет более низкий приоритет, чем операция сцепления. Сравнение строк производится слева направо до первого несовпадающего символа, и больше считается та строка, в которой первый несовпадающий символ имеет больший номер в таблице символьной кодировки.
Если строки имеют различную длину, но в общей части символы совпадают, считается, что более короткая строка меньше, чем более длинная. Строки равны, если они полностью совпадают по длине и содержат одни и те же символы.
Функция Copy (S, Poz, N) выделяет из строки S подстроку длиной в N символов, начиная с позиции Poz. N и Poz - целочисленные выражения.
Функция Concat (S1,S2,…,SN) выполняет сцепление (конкатенацию) строк S1,…,SN в одну строку.
Функция Length (S) определяет текущую длину строки S. Результат- значение целого типа.
Функция Pos (S1,S2) обнаруживает первое появление в строке S2 подстроки S1. Результат - целое число, равное номеру позиции, где находится первый символ подстроки S1.
Если в строке S2 подстроки S1 не обнаружено, то результат равен 0.
Процедура Delete (S, Poz, N) выполняет удаление N символов из строки S, начиная с позиции Poz.
В результате выполнения процедуры уменьшается текущая длина строки в переменной S.
Процедура Insert (S1, S2, Poz) выполняет вставку строки S1 в строку S2, начиная с позиции Poz.
Процедуры преобразования типов данных
Str (процедура)
Преобразовывает число в строку.
Объявление:
Procedure Str(X [: Width [: Decimals ]]; Var S : String);
Замечания:
Преобразовывает числовое значение X в строковое представление этого числа, которое можно выводить операторами типа Write и OutText.
Val (процедура)
Преобразовывает строковое значение в его числовое представление.
Объявление:
Procedure Val (S; Var V; Var Code : Integer);
Где:
S - переменная со строковым типом. Должна представлять
последовательность символов, формирующих знаковое целое число.
V - переменная типа Real или Integer
Code - переменная типа Integer
4.1 Строковые типы в Delphi. Особенности реализации и использования
Какие строковые типы существуют в Delphi, и чем они отличаются друг от друга?
В Delphi 1.0 существовал лишь единственный строковый тип String, полностью эквивалентный одноименному типу в Turbo Pascal и Borland Pascal. Однако, этот тип имеет существенные ограничения. Для обхода этих ограничений, в Delphi 2, разработчики из Borland устроили небольшую революцию. Теперь, начиная с Delphi 2, имеются три фундаментальных строковых типа: ShortString, AnsiString, и WideString. Кроме того, тип String теперь стал логическим. Т.е., в зависимости от настройки соответствующего режима компилятора (режим больших строк), он приравнивается либо к типу ShortString (для совместимости со старыми программами), либо к типу AnsiString (по умолчанию). Управлять режимом, можно используя директиву компиляции {$LONGSTRINGS ON/OFF} (короткая форма {$H+/-}) или из окна настроек проекта - вкладка "Compiler" -> галочка "Huge strings". Если режим включен, то String приравнивается к AnsiString, иначе String приравнивается ShortString. Из этого правила есть исключение: если в определении типа String указан максимальный размер строки, например String[25], то, вне зависимости от режима компилятора, этот тип будет приравнен к ShortString соответствующего размера.
Поскольку по умолчанию, после установки Delphi, режим больших строк включен, большинство молодых программистов даже и не подозревают, что String может представлять что-то отличное от AnsiString. Поэтому, дальше в этом пункте, любое упоминание типа String без указания размера, подразумевает, что он равен типу AnsiString, если не будет явно указано иное. Т.е., считается, что настройка компилятора соответствует настройке по умолчанию.
Существуют различия между типами AnsiString и WideString. Эти типы имеют практически одинаковую реализацию, и отличаются лишь тем, что WideString используется для представления строк в кодировке UNICODE использующей 16-ти битное представление каждого символа (WideChar). Эта кодировка используется в тех случаях, когда необходима возможность одновременного присутствия в одной строке символов из двух и более языков (помимо английского). Например, строк содержащих одновременно символы английского, русского и европейских языков. За эту возможность приходится платить - размер памяти, занимаемый такими строками в два раза больше размера, занимаемого обычными строками. Использование WideString встречается не часто, поэтому, я буду в основном рассказывать о строках типа AnsiString. Но, поскольку они имеют одинаковую реализацию, почти все сказанное относительно AnsiString будет действительно и для WideString, естественно с учетом разницы в размере каждого символа.
Тоже самое касается и разницы между pChar и pWideChar.
Строковый тип AnsiString, обычно используется для представления строк в кодировке ANSI, или других (например, OEM) в которых для кодирования одного символа используется один байт (8 бит). Такой способ кодирования называется single-byte character set, или SBCS. Но, очень многие не знают о существовании еще одного способа кодирования многоязычных строк (помимо UNICODE) используемого в системах Windows и Linux. Этот способ называется multibyte character sets, или MBCS. При этом способе, некоторые символы представляются одним байтом, а некоторые, двумя и более. В отличие от UNICODE, строки, закодированные таким способом, требуют меньше памяти для своего хранения, но требуют более сложной обработки. Так вот, строковый тип AnsiString может использоваться для хранения таких строк.
Также существуют еще типы pChar (pWideChar) и array [...] of Char, они очень часто используются в сочетании со строковыми типами.
Таблица - Основные характеристики строковых типов
Тип |
Максимальный размер строки |
Размер переменной |
Объем памяти, требуемый для хранения строки |
|
String[n] где 0 <= n <= 255 |
n символов |
n+1 байт |
n+1 байт |
|
ShortString |
255 символов |
256 байт |
256 байт |
|
AnsiString |
~2^31 символов |
4 байта |
4 байта + (0 .. 2 Гбайт) |
|
WideString |
~2^30 символов |
4 байта |
4 байта + (0 .. 2 Гбайт) |
|
pChar |
не ограничено |
4 байта |
4 байта + размер строки +1 |
|
pWideChar |
не ограничено |
4 байта |
4 байта + (размер строки+1)*2 |
|
array [0..n] of Char |
n |
n+1 байт |
n+1 байт |
|
array [0..n] of WideChar |
n |
(n+1)*2 байт |
(n+1)*2 байт |
Теперь, остановимся подробнее на каждом из этих типов. Начнём с более простых.
array [0..n] of Char
Формально, этот тип не являются строковыми. Однако, в Delphi, он несколько отличаются от остальных типов массивов. А именно, если массив символов имеет нижнюю границу индекса равной 0, то Delphi считает такой тип совместимым по присваиванию со строковыми константами. Например, если переменная a будет описана как a :array[0..20] of Char, то оператор a := 'abc' будет допустим. Причём, значения элементов начиная с a[3] и до a[20] будут установлены в #0.
Есть ещё - оператор @ (получение указателя) для переменной такого типа возвращает значение типа pChar. Это очень удобно, поскольку переменные этого типа очень часто используются как буфер при работе с функциями Windows API. Например:
var
a :array[0..20] of Char;
...
GetModuleFileName(GetModuleFileName(HInstance,@a,SizeOf(a));
Здесь, функция GetModuleFileName возвращает результат в массив a.
pChar
Этот тип широко используется в языках C и C++. В Delphi, это не фундаментальный тип, а производный. Его определение выглядит так:
pChar = ^Char
Т.е. переменные этого типа являются указателем, поэтому и имеют размер 4 байта. Формально, значение pChar может указывать как на один символ, так и на строку символов. Однако, общепринято что значения pChar указывают на строки, завершающиеся символом с кодом 0 (#0). В DOSе, такие строки назывались ASCIIZ, но чаще можно встретить название null-terminated string. Наличие такого "концевика" позволяет легко определить реальный размер строки на которую указывает значение pChar.
Не смотря на то, что формально pChar это указатель на Char (^Char), как это часто бывает в Delphi, тип pChar имеет несколько особенностей по сравнению с другими указателями. Таких особенностей несколько.
Первая, заключается в том, что константы, и глобальные переменные этого типа могут быть проинициализированы строковой константой. Вот пример:
const pc :pChar ='abc';
var pv :pChar ='abc';
Эти строки, определяют константу pc и переменную pv типа pChar. При этом, и pc и pv указывают на разные области памяти, но содержащие одинаковые значения, состоящие из трех символов: 'a', 'b', 'c', и символа #0. Завершающий символ с кодом 0 компилятор добавил автоматически.
Вторая особенность в том, что к переменным типа pChar применимо обращение как к массиву символов. Например, если есть приведенные выше определения, тогда:
C := pv^; // C будет присвоен символ 'a'. Это обычное обращение
C := pv[0]; // необычно, но С станет равным 'a'
C := pv[1]; // С станет равным 'b'
C := pv[2]; // С станет равным 'c'
C := pv[3]; // С станет равным #0
C := pv[4]; // ОШИБКА!
Символ с индексом 3 отсутствует в строке, однако, там есть завершающий ее символ с кодом 0. Именно он будет результатом pv[3]. О pv[4] тоже стоит сказать особо. Дело в том, что компилятор не даст ошибки при компиляции, поскольку на этапе компиляции он, в общем случае, не известен реальный размер строки, на которую указывает переменная pv. Однако, на этапе выполнения программы, такое обращение может вызвать ошибку нарушения доступа к памяти (Access Violation). А может и не вызвать, но результатом будет неопределённое значение. Все зависит от "расклада" в памяти. Поэтому, при таком способе обращения необходимо быть внимательным, и выполнять все необходимые проверки, исключающие выход за размеры строки.
Третья и последняя особенность типа pChar в том, что к значениям этого типа применима так называемая адресная арифметика. Тем, кто программирует на C и C++ она хорошо знакома. Суть её в том, что значения pChar можно увеличивать, уменьшать, вычитать, и складывать. Для демонстрации использования этой особенности, приведем пример реализации функции подсчитывающей длину строки, указатель на которую передается в качестве параметра.
function StringLength (p :pChar) :Cardinal;
begin
Result := 0;
if p = nil then Exit;
while p^ <> #0 do begin
Inc(Result);
Inc(p); end;end;
Здесь важно обратить внимание на два нюанса.
Первый, это проверка переданного указателя на nil. Такая проверка необходима, поскольку очень часто, для обозначения пустой строки используется значение nil.
Второй, это оператор Inc(p) - он "продвигает" указатель на следующий символ. Можно было бы записать его и так: p := p + 1.
Что бы продемонстрировать вычитание указателей pChar, приведем еще один вариант реализации той же функции:
function StringLength (p :pChar) :Cardinal;
var pp :pChar;
begin
Result := 0;
pp := p;
if pp <> nil then
while pp^ <> #0 do
Inc(pp);
Result := (pp-p);
end;
Здесь, выражение pp-p дает "расстояние" между указателями, т.е. число символов между символом, на который указывает указатель p (начало строки) и символом, на который указывает указатель pp (завершающий строку #0).
ShortString, и String[n]
ShortString является частным случаем String[n], а если быть более точным, он полностью эквивалентен String[255].
Если посмотреть на таблицу, где приведены характеристики переменных этого типа, то мы увидим что их размер на один байт больше чем размер хранимой в них строки. Но в данном случае, это не для завершающего символа, как в pChar. Здесь в дополнительном байте хранится текущий размер строки. Кроме того, этот байт располагается не в конце строки, а наоборот, в ее начале. К примеру, если имеется следующее определение:
var s :String[4];
Оно означает, что для переменной s будет статически выделена область памяти размером 5 байт.
Теперь, выполнение оператора s := 'abc', приведёт к тому, что содержимое этих пяти байт станет следующим: байт 1 = 3, байт 2 = 'a', байт 3 = 'b', байт 4 = 'c', а значение байта 5 будет неопределённо - оно будет зависеть от "расклада" в памяти. Т.е., первый символ строки будет находиться во втором байте. Это неудобно, поэтому к символам строк ShortString принято индексироваться, начиная с 1. Следовательно:
s[1] = 'a' - первый символ строки
s[2] = 'b' - второй символ строки
s[3] = 'c' - третий символ строки
s[4] = все что угодно:).
А как же байт длины? Да все очень просто, к нему можно обратиться как s[0]. Только вот есть маленькая проблемка. Поскольку элементами строки являются символы, то и тип значения s[0] тоже будет символ. Т.е., если Вы хотите получить длину строки в виде целого числа, как это принято у нормальных людей, то надо выполнить соответствующее преобразование типа: Ord(s[0]) = 3 - размер строки.
Почему для типа String[n] существует ограничение 0<=n<=255. Это весь набор значений, которые могут быть представлены в одном байте. На всякий случай, отмечу, что размерность переменной (n) определяет размер выделяемой под эту переменную памяти, и он не зависит от размера строки, которая там хранится. Т.е., если, например переменная описана как String[30], то даже если присвоить ей значение 'abcd', то размер этой переменной все равно останется 31 байт. Это иногда бывает очень удобно, например, при записи (чтении) таких переменных в файл (из файла).
В качестве примера работы со структурой хранения такого типа, приведу пример все той же функции возвращающей длину строки:
Пример:
function StringLength (s :ShortString) :Cardinal;
begin
Result := Ord(s[0]);
end;
Как видите, это код существенно компактнее, и быстрее чем соответствующий код для pChar. Именно поэтому, он и применялся в языке Pascal.
Однако ясно, что ограничения переменных этого типа - максимальный размер строки 255 символов, и всегда максимальный размер занимаемой переменной памяти, вне зависимости от реально помещенной в нее строки, заставили разработчиков Delphi вести новые строковые типы. Вот к ним мы сейчас и перейдем.
AnsiString и WideString
Строки этого типа объединили в себе ряд качеств как строк ShortString и их байтом длины, так и строк завершающихся нулем (pChar). Последнее было необходимо, поскольку к моменту их появления, засилье C-ишников было уже так велико:), что большинство системных функций Windows API оперировало строками именно такого формата. А если серьезно, то такой формат строк хоть и более трудоемок в обработке, зато в принципе лишен ограниченности на максимальный размер строки. Ведь хранение размера строки всегда ограниченно какими-либо рамками: если хранить в байте, то ограничение 255 байт; если хранить в слове, то ограничение 65535 символов; и т.д. Однако, совсем отказываться от хранения текущей длинны строки в Borland не стали.
Еще одним из недостатков статически размещаемых строк ShortString было "расточительство". Т.е. определив переменную такого типа, мы заранее резервировали под нее 256 байт памяти, поэтому, если мы один раз, во всей программе, присвоили ей значение 'abcd', то 251 байт памяти мы просто "пустили на ветер". Казалось бы, а зачем так определили, написали бы String[4], и ничего не потеряли бы. Но, когда мы пишем программу, мы же чаще всего не знаем что мы будем "класть" в эту переменную. Вот и определяем с запасом. Решением этой проблемы стало использование динамически размещаемых строк.
Как они устроены?
Если вы обратили внимание, в таблице характеристик строковых типов, размер переменных AnsiString равен четырем байтам, как и у pChar. Это говорит нам о том, что переменные этого типа тоже являются указателями. Но, в отличие от pChar, в данном случае, это скрыто реализацией. Т.е. программист, работает с ними как с обычными строками: не надо выделять под них память, не надо заботиться о наличии завершающего нуля, не надо волноваться об изменении размеров строки и т.п. Всю эту работу берет на себя компилятор Delphi. Более того, он ещё и занимается оптимизациями. В частности, если например выполнить следующий код:
var s1, s2 :AnsiString;
...
s1 := 'abc';
s2 := s1;
то в памяти будет храниться лишь ОДИН экземпляр строки 'abc'!
Как же это происходит?
При выполнении первого оператора (присваивание s1), указатель, хранящийся в переменной s1 настраивается на область памяти в которой размещена строка 'abc'. При выполнении второго оператора, в s2 попадает тот же адрес! Т.е. в памяти при это присутствует лишь один экземпляр строки 'abc'. Да и зачем нам нужны дублирующие себя строки.
Не нужно программисту заботиться и об освобождении памяти занятой ненужными уже строками. Например есть такая процедура:
procedure ShowInteger;
var
s :AnsiString;
n :Integer;
begin
n := 123;
s := 'Значение переменной равно '+IntToStr(n);
ShowMessage(s);
end;
Здесь, при выполнении присваивания, Delphi создаст в памяти экземпляр строки 'Значение переменной равно 123', и присвоит адрес этой строки переменной s. Однако, при завершении процедуры, переменная s перестанет существовать - она же локальная. Значит, и экземпляр строки тоже уже не нужен - на него некому будет указывать. Вот поэтому, Delphi автоматически освободит память, выделенную под строку, как только, выполнение процедуры достигнет строки end. Более того, даже если во время выполнения процедуры возникнет исключительная ситуация, при которой "хвост" процедуры может и не выполниться, Delphi всё равно корректно освободит память для всех строк, распределенных в этой процедуре. Достигается это неявным использованием механизма подобного try - finally.
Казалось бы, всё замечательно. Но попробуем усложнить ситуацию.
var
gs :AnsiString; // глобальная переменная
procedure ShowInteger;
var
s :AnsiString;
n :Integer;
begin
n := 123;
s := 'Значение переменной равно '+IntToStr(n);
gs := s;
ShowMessage(s);
end;
Теперь, к моменту завершения процедуры, на экземпляр строки 'Значение переменной равно 123' уже ссылаются две переменные s и gs. И, несмотря на то, что область существования переменной s заканчивается, освобождать память, выделенную под строку на которую она указывает нельзя! Ведь позже, возможны обращения к переменной gs.
Для того, чтобы корректно обрабатывать такие ситуации, Delphi для каждой динамически распределенной строки ведет так называемый "счётчик ссылок". Т.е., как только он присваивает какой-либо из строковых (AnsiString) переменных ссылку на распределенную в памяти строку, то он увеличивает этот счетчик на единицу. Первоначально, при присваивании динамически распределённой строки, первой переменной (в примере s), значение этого счётчика устанавливается равным единице. В последствии, при прекращении жизни каждой строковой переменной, он уменьшает на 1 этот счетчик для той строки на которую она указывает. Если счётчик становится равным 0, то значит более нет строковых переменных, указывающих на данную строку. Значит, ее можно освобождать. Благодаря такому алгоритму, после присваивания в примере значения переменной gs, у строки 'Значение переменной равно 123' счетчик ссылок становится равным 2. Следовательно, при "умирании" переменной s, он декрементируется, и становится равным 1. Т.е. >0, поэтому то Delphi и не освобождает память, занятую строкой.
Еще, этот счётчик используется и для разрешения проблем, связанных со следующей ситуацией:
procedure ShowInteger;
var
s1 :AnsiString;
s2 : AnsiString;
n :Integer;
begin
n := 123;
s1 := 'abc'+IntToStr(n);
s2 := s1;
s2[1] := 'X';
end;
Здесь, как мы уже знаем, после выполнения оператора s2 := s1, обе переменные указывают на один и тот же экземпляр строки 'abc123'. Однако, что же произойдёт когда выполниться оператор s2[1] := 'X'? Казалось бы, в единственном имеющимся в нашем распоряжении экземпляре строки первая буква будет заменена на 'X'. И как следствие, обе строки станут равными 'Xbc123'. s1 то за что "страдает"? Но, к счастью это не так. Здесь на помощь Delphi вновь приходит счетчик ссылок. Delphi, при выполнении этого оператора понимает, что строка на которую указывает s2 будет изменена, а это может повлиять на других. Поэтому, перед изменением строки, проверяется ее счётчик ссылок. Обнаружив, что на нее ссылается более одной строковой переменной, делается следующее: создается копия этой строки со счётчиком ссылок равным 1, и адрес этой копии, присваивается s2; У исходного экземпляра строки, счетчик ссылок уменьшается на 1 - ведь s2 на неё теперь не ссылается. И лишь после этого, происходит изменение первой буквы, теперь уже собственного экземпляра строки. Т.е., по окончанию выполнения этого оператора, в памяти будут находиться две строки: 'abc123' и 'Xbc123'. Причем, s1 будет ссылаться на первую, а s2 на вторую.
При работе со строками определенными как константы, алгоритм работы несколько отличается.
Пример:
procedure ShowInteger;
var s :AnsiString;
begin
s := 'Вася';
ShowMessage(s);
end;
Казалось бы, при завершении работы процедуры, экземпляр строки 'Вася' должен быть уничтожен. Но в данном случае это не так. Ведь, при следующем входе в процедуру, для выполнения присваивания нужно будет вновь где-то взять строку 'Вася'. Для этого, ещё при компиляции, Delphi размещает экземпляр строки 'Вася' в области констант программы, где её даже невозможно изменить, по крайней мере, простыми методами. Но как же при завершении процедуры определить что строка 'Вася' - константная строка, и ее нельзя уничтожать? Все очень просто. Для константных строк, счётчик ссылок устанавливается равным -1. Это значение, "выключает" нормальный алгоритм работы со "счётчиком ссылок". Он не увеличивается при присваивании, и не уменьшается при уничтожении переменной. Однако, при попытке изменения переменной (помните s2[1]:='X'), значение счётчика равное -1 будет всегда считаться признаком того, что на строку ссылается более одной переменной (ведь он не равен 1). Поэтому, в такой ситуации всегда будет создаваться уникальный экземпляр строки, естественно, без декремента счётчика ссылок старой. Это защитит от изменений экземпляр строки-константы.
К сожалению, этот алгоритм срабатывает не всегда.
Где же Delphi хранит "счётчик ссылок"? Причем, для каждой строки свой! Естественно, вместе с самой строкой. Вот что представляет собой эта область памяти, хранящая экземпляр строки 'abc':
Байты с 1 по 4 |
Счётчик ссылок равный -1 |
|
Байты с 5 по 8 |
Длина строки равная 3 |
|
Байт 9 |
Символ 'a' |
|
Байт 10 |
Символ 'b' |
|
Байт 11 |
Символ 'c' |
|
Байт 12 |
Символ с кодом 0 (#0) |
Для удобства работы с такой структурой, когда строковой переменной присваивается ссылка на эту строку, в переменную заносится адрес не начала этой структуры, а адрес её девятого байта. Т.е. адрес начала реальной строки (прямо как pChar). Для того, что бы приблизиться к реальной жизни, перепишем приведённую структуру:
Смещение |
Размер |
Значение |
Назначение |
|
-8 |
4 |
-1 |
Счётчик ссылок |
|
-4 |
4 |
3 |
Длина строки |
|
0 |
1 |
'a' |
||
1 |
1 |
'b' |
||
2 |
1 |
'c' |
||
3 |
1 |
#0 |
С полем по смещению -8, нам уже должно быть все ясно. Это значение, хранящееся в двойном слове (4 байта), тот самый счетчик, который позволяет оптимизировать хранение одинаковых строк. Значение этого счетчика имеет тип Integer, т.е. может быть отрицательным. На самом деле, используется лишь одно отрицательное значение - "-1", и положительные значения. 0 не используется.
Теперь, обратим внимание на поле, лежащее по смещению -4. Это, четырёхбайтовое значение длинны строки (почти как в ShortString). Думаю, Вы заметили, что размер памяти выделенной под эту строку не имеет избыточности. Т.е. компилятор выделяет под строку минимально необходимое число байт памяти. Это конечно хорошо, но, при попытке "нарастить" строку: s1 := s1 + 'd', компилятору, точнее библиотеке времени исполнения (RTL) придется перераспределить память. Ведь теперь строке требуется больше памяти, аж на целый байт. Для перераспределения памяти нужно знать текущий размер строки. Вероятно, именно для того, что бы не приходилось каждый раз сканировать строку, определяя её размер, разработчики Delphi и включили поле длины, строки в эту структуру. Длина строки, хранится как значение Integer, отсюда и ограничение на максимальный размер таких строк - 2 Гбайт. Кстати, именно потому, что память под эти строки выделяется динамически, они и получили ещё одно свое название: динамические строки.
Ещё немного о нескольких особенностях переменных AnsiString. Важнейшей особенностью значений этого типа является возможность приведения их к типу Pointer. Это впрочем, естественно, ведь в "душе" они и есть указатели, как бы они этого не скрывали. Например, если описаны переменные: s :AnsiString и p :Pointer. То выполнение оператора p := Pointer(s) приведет к тому, что переменная p станет указывать на экземпляр строки. Однако, при этом, очень важно знать: счетчик ссылок этой строки не будет увеличен.
Поскольку, переменные этого типа реально являются указателями, то для них и реально такое значение как Nil - указатель в "никуда". Это значение в переменной типа AnsiString по смыслу приравнивается пустой строке. Более того, чтобы не тратить память и время на ведение счётчика ссылок, и поля размера строки всегда равного 0, при присваивании пустой строке переменной этого типа, реально, присваивается значение Nil. Это не очевидно, поскольку обычно не заметно, но как мы увидим позже, очень важная особенность.
Преобразование строк из одного типа в другой
Преобразование между "настоящими" строковыми типами String[n], ShortString, и AnsiString выполняются легко, и прозрачно. Никаких явных действий делать не надо, Delphi все сделает за Вас. Надо лишь понимать, что в маленькое большое не влезает. Например:
var
s3 :String[3];
s :AnsiString;
...
s := 'abcdef';
s3 := s;
В результате выполнения этого кода, в переменной s3 окажется строка 'abc', а не 'abcdef'. С преобразованием из pChar в String[n], ShortString, и AnsiString, тоже всё очень не плохо. Просто присваивайте, и все будет нормально.
Сложности начинаются тогда, когда мы начинаем преобразовывать "настоящие" строковые типы в pChar. Непосредственное присваивание переменным типа pChar значений строк не допускается компилятором. На оператор p := s где p имеет тип pChar, а s :AnsiString, компилятор выдаст сообщение: "Incompatible types: 'String' and 'PChar'" - несовместимые типы 'String' и 'PChar'. Чтобы избежать такой ошибки, надо применять явное приведение типа: p := pChar(s). Так рекомендуют разработчики Delphi. В общем, они правы. Но, если вспомнить, как хранятся динамические строки - с нулем в конце, как и pChar. А еще и то, что к AnsiString применимо преобразование в тип Pointer. Станет очевидным, что всего, возможно целых три способа преобразования строки в pChar:
var
s :AnsiString;
p1,p2,p3 :PChar;
...
p1 := pChar(s);
p2 := Pointer(s);
p3 := @(s[1]);
Все они, синтаксически правильны. И кажется, что все три указателя (p1, p2 и p3) будут в результате иметь одно и то же значение. Но это не так. Всё зависит от того, что находится в s. Если быть более точным, равно ли значение s пустой строке, или нет:
s <> ''
p1 = p2 <> p3
s = ''
p1 <> p2 = p3
Чтобы была понятна причина такого явления, опишем, как Delphi выполняет каждое из этих преобразований. Переменные AnsiString представляющие пустые строки, реально имеют значение Nil. Так вот:
pChar(s)
Для выполнения преобразования pChar(s), компилятор генерит вызов специальной внутренней функции @LstrToPChar. Эта функция проверяет - если строковая переменная имеет значение Nil, то вместо него, она возвращает указатель на реально размещенную в памяти пустую строку. Т.е. pChar(s) никогда не вернет указатель равный Nil.
Pointer(s)
Тут все просто, такое преобразование просто возвращает содержимое строковой переменной. Т.е. если она при пустой строке содержит Nil, то и результатом преобразования будет Nil. Если же строка не пуста, то результатом будет адрес экземпляра строки.
@(s[1])
Здесь, все совсем по-другому. Перед выполнением такого преобразования, компилятор вставляет код, обеспечивающий ситуацию, когда указатель, хранящийся в s, будет единственным указателем на экземпляр строки в памяти. В нашем примере, если строка не пуста, то будет создана копия исходной строки. Вот ее-то адрес и будет возвращен как результат такого преобразования. Но, если строка пуста, то результатом будет Nil, как и во втором случае.
Теперь, интересно отметить, что если в приведенном примере, преобразование p3 := @(s[1]) выполнить первым, то при не пустой строке в s, все указатели (p1, p2, и p3), будут равны. И содержать они будут адрес "персонального" экземпляра строки.
Вот, теперь, зная, как выполняются те или иные преобразования, Вы сможете всегда выбрать подходящий способ.
Приведем пример. В нем, преобразование, рекомендуемое разработчиками, приводит к "странному" поведению программы:
procedure X1;
var
s :AnsiString;
p :PChar;
begin
s := 'abcd';
p := PChar(s);
p^ := 'X'; // <-
ShowMessage(s);
end;
вызывает ошибку доступа к памяти при выполнении строки, помеченной <=. Почему - предлагаю Вам разобраться самостоятельно. После прочтения данной статьи Ваших знаний для этого достаточно. В тоже время, код:
procedure X1;
var
s :AnsiString;
p :PChar;
begin
s := 'abcd';
p := @(s[1]);
p^ := 'X';
ShowMessage(s);
end;
будет выполнен без ошибок, выведя строку 'Xabcd'. Также как и код:
procedure X1;
var
s :AnsiString;
p :PChar;
begin
s := 'abcd';
s[2] := 'b';
p := PChar(s);
p^ := 'X';
ShowMessage(s);
end;
Рассматривая преобразование AnsiString в pChar (получение адреса строки) нельзя не упомянуть ещё одну серьезную проблему - область действия для полученного таким путем указателя.
Delphi ведет учет всех ссылок на каждый экземпляр динамически распределенной строки. И на основании этого принимает решение об освобождении памяти занимаемой экземпляром строки. Но, это касается только ссылок хранящихся в переменных AnsiString. Ссылки, полученные преобразованием в pChar, не учитываются. Вот демонстрация того, как это может сказаться на поведении программы. Пусть есть следующая функция:
function IntToPChar (n :Integer) :pChar;
var s :AnsiString;
begin
s := IntToStr(n);
Result := PChar(s);
end;
Казалось бы, всё написано правильно. Однако если выполнить такой оператор:
ShowMessage(IntToPChar(100));
То, вместо ожидаемого окна со строкой '100', мы либо получим абракадабру, либо и того хуже - ошибку AV. А все почему? Да, просто, единственным учтённым указателем на экземпляр строки, полученный от IntToStr, будет s. Поэтому, когда его область действия прекращается по выходу из процедуры, экземпляр строки будет уничтожен. А не учтённый указатель, возвращаемый функцией IntToPChar, после этого станет указывать "куда бог пошлёт". Точнее, на то место в памяти, где недавно была строка. Если же переменная s будет объявлена на глобальном уровне, то будет нормально, но всё равно возможны ошибки. Например:
var s :AnsiString; // глобальная переменная
...
function IntToPChar (n :Integer) :pChar;
begin
s := IntToStr(n);
Result := PChar(s);
end;
...
var p100, p200 :pChar;
begin
p100 := IntToPChar(100);
p200 := IntToPChar(200);
...
После второго выполнения функции IntToPChar, указатель p100, опять будет указывать "куда бог пошлет", Почему, разберитесь сами:).
Длинные строки
Особенностью длинных строк является возможность присваивания константного литерала. В зависимости от того, является переменная локальной или нет, генерируется различный код.
Если происходит присваивание локальной переменной:
procedure E2;
var
S: string;
begin
S := 'String'; // refCnt = -1
end;
Переменная S получит счетчик равный -1 и будет ссылаться прямо на литерал. При присваивании другой локальной переменной или передаче в процедуру счетчик никогда не меняется. Естественно, ни о каком управлении памятью в данном случае речи не идет.
В остальных случаях (то есть когда строка помещается в глобальную переменную, поле, элемент массива и т.п.) Delphi создает обычную строку в динамической памяти, в которую копирует присваиваемую константу.
Любое изменение строки заменяется на вызов системных функций. Если счетчик строки в этот момент не равен 1, создается новая строка. Исключением из этого правила является доступ к содержимому строки по указателю (приведение к типу PChar). В этом случае уже ничего не контролируется.
4.3 Контрольные вопросы
1. Что появится на экране дисплея в результате работы следующего блока программы:
…
str_1:=' Привет друз ';
str_2:='ья';
writeln (str_1+str_2);
writeln (concate(str_1, str_2));
…
2. Какой может быть длина строки?
3. Какие операции можно производить над строками? Опишите их.
4. С помощью каких функций можно работать со строками?
5. Составте программу получения из слова "СТРОКА" слово "СЕТКА".
6. Какие строковые типы существуют в Delphi и чем они отличаются друг от друга?
7. К какому типу будет приравнен тип, если в определении типа String указан максимальный размер строки?
8. Чем отличаются типы AnsiString и WideString?
9. Сколько байт используется для кодирования одного символа в кодировке ANSI?
10. Каков максимальный размер строки типа ShortString?
11. Переменные какого типа являются указателем и имеют размер 4 байта?
12. В чем особенности типа pChar?
13. Перечислите недостатки строк ShortString.
14. Как устроены динамически размещенные строки?
15. Каковы особенности переменных AnsiString?
16. Назовите, в чем особенность длинных строк?
4.4 Задания к лабораторной работе № 4
Вариант 1.
1. Дана строка, заканчивающаяся точкой. Подсчитать, сколько слов в строке.
2. Дана строка. Указать те слова, которые содержат хотя бы одну букву с.
Вариант 2.
1. Дана строка, содержащая английский текст. Найти количество слов, начинающихся с буквы b.
2. Дана строка. Найти в ней те слова, которые начинаются и оканчиваются одной и той же буквой.
Вариант 3.
1. Дана строка. Подсчитать, сколько в ней букв r,k,t.
2. В строке заменить все двоеточия (:) точкой с запятой (;). Подсчитать количество замен.
Вариант 4.
1. Дана строка. Определить, сколько в ней символов *, ;, :.
2. В строке удалить символ "двоеточие" (:) и подсчитать количество замен
Вариант 5.
1. Дана строка, содержащая текст. Найти длину самого короткого слова и самого длинного слова.
2. В строке вставить вместо пробела запятую и пробел.
Вариант 6.
1. Дана строка символов, среди которых есть двоеточие (:). Определить, сколько символов ему предшествует.
2. Удалить часть символьной строки, заключенной в скобки (вместе со скобками)
Вариант 7.
1. Дана строка, содержащая текст, заканчивающийся точкой. Вывести на экран слова, содержащие три буквы.
2. Определить сколько раз в строке встречается заданное слово.
Вариант 8.
1. Дана строка. Преобразовать ее, удалив каждый символ * и повторив каждый символ, отличный от *.
2. В строке имеется точка с запятой (;). Подсчитать количество символов до точки с запятой и после нее.
знаки во второй половине символов.
Вариант 9.
1. Дана строка. Определить, сколько раз входит в нее группа букв abc.
2. Дана строка. Преобразовать ее, заменив точками все двоеточия, встречающиеся среди первой половины символов строки, и заменив точками все восклицательные.
Вариант 10.
1. Дана строка. Подсчитать количество букв k в последнем ее слове.
2. Строка содержит одно слово. Проверить будет ли она одинаково читаться справа налево и слева направо (т.е. является ли оно палиндромом.)
Вариант 11.
1. Дана строка. Подсчитать, сколько различных символов встречается в ней. Вывести их на экран.
2. В записке слова зашифрованы - каждое из них записано наоборот. Расшифровать сообщение.
Вариант 12.
1. Дана строка. Подсчитать самую длинную последовательность подряд идущих букв a.
2. Проверить, одинаковое ли число открывающихся и закрывающихся скобок в данной строке.
Вариант 13.
1. Дана строка. Указать те слова, которые содержат хотя бы одну букву k.
2. Дана строка. Заменить в ней все парные символы на одиночные (например, аа -> а, тт -> т).
Вариант 14.
1. Имеется строка, содержащая буквы латинского алфавита и цифры. Вывести на экран длину наибольшей последовательности цифр, идущих подряд.
2. Дана строка, содержащая текст, заканчивающийся точкой. Вывести на экран слова, содержащие хотя бы одну букву о.
Вариант 15.
1. Дан набор слов, разделенных точкой с запятой (;). Набор заканчивается двоеточием (:). Определить, сколько в нем слов, заканчивающихся буквой а.
2. Дана строка, заканчивающаяся точкой. Подсчитать, сколько запятых в строке.
5. Лабораторная работа № 5. Множества
Множество - структурированный тип данных, представляющий собой набор взаимосвязанных по какому-либо признаку или группе признаков обьектов, которые можно рассматривать как единое целое. Каждый обьект в множестве называется элементом множества. Все элементы множества должны принадлежать одному из скалярных типов, кроме вещественного. Этот тип называется базовым типом множества. Базовый тип задается диапозоном или перечислением. Область значений типа "множество" - набор всевозможных подмножеств, составленных из элементов базового типа. Если множество не имеет элементов, оно называется пустым и обозначается как [ ]. Количество элементов множества называется его мощностью.
...Подобные документы
Теоретические основы объектно-ориентированного языка программирования Delphi, изучение среды визуального проектирования приложений. Определение 40-го числа Фибоначчи, составление листинга и блок-схемы программы, тестирование ее на работоспособность.
курсовая работа [261,1 K], добавлен 25.03.2015Разработка головоломки на основе гравюры Альбрехта Дюрера "Магический квадрат". Главные составные части среды программирования Delphi, особенности ее стандартных компонентов и процесса сохранения программы. Компоненты и алгоритмы создаваемой программы.
курсовая работа [147,1 K], добавлен 05.02.2015Delphi как среда разработки программ, ориентированных на работу в Windows. Назначение и преимущество использования электронных учебников. Описание возможностей среды Delphi 5 для разработки электронного учебника. Варианты применения служб Internet.
дипломная работа [3,6 M], добавлен 13.07.2011Характеристика системы программирования. Главные составные части Delphi. Интерфейс программного приложения. Результаты работы программы. Руководство системного программиста и оператора. Язык программирования Delphi, среда компилятора Borland 7.0.
курсовая работа [1,6 M], добавлен 29.05.2013Borland Delphi 7 как универсальный инструмент разработки, применяемый во многих областях программирования, функции: добавление информации об абитуриентах в базу данных, формирование отчетов. Рассмотрение и характеристика основных компонентов Delphi.
контрольная работа [3,6 M], добавлен 18.10.2012Рассмотрение теории и технологии работы со средой программирования Delphi. Описание Описание интерфейса программы, структуры данных, генерации точек. Разработка задания по выявлению всех квадратов, которые могут быть образованы точками на плоскости.
реферат [21,0 K], добавлен 13.01.2015Основы программирования, работа в консольном режиме Delphi. Правила оформления комментариев. Типы данных, используемые в консольном режиме. Текстовый редактор Delphi Memo. Пример загрузки текстового файла. Примеры решения и оформления простейших задач.
отчет по практике [2,1 M], добавлен 11.03.2014Проектирование программного модуля в среде программирования Borland Delphi 7.0. Схемы алгоритмов решения задач по темам "Символьные переменные и строки", "Массивы", "Работа с файлами", "Создание анимации". Реализация программного модуля, код программы.
отчет по практике [961,6 K], добавлен 21.04.2012Особенности разработки приложений для операционной системы с помощью императивного, структурированного, объектно-ориентированного языка программирования Delphi. Формальное начало программы. Выделение конца программного блока. Листинг и описание программы.
курсовая работа [1,2 M], добавлен 04.08.2014Изучение общей структуры языка программирования Delphi: главные и дополнительные составные части среды программирования. Синтаксис и семантика языка программирования Delphi: алфавит языка, элементарные конструкции, переменные, константы и операторы.
курсовая работа [738,1 K], добавлен 17.05.2010Ознакомление с историей создания и особенностями объектно-ориентированного языка программирования Delphi. Разработка приложения, фиксирующего количество повторений какого-либо слова в тексте, введённом в поле MEMO. Описание интерфейса программы.
курсовая работа [880,1 K], добавлен 21.04.2015Программа поиска в базе данных в среде Borland Delphi 7.0 Enterprise. Условия и блок-схемы задач. Ввод массива. Текст программ в Delphi, в Паскаль. Текст программы поиска в базе данных. Кодирование материала. Изготовление реляционной базы данных.
практическая работа [27,6 K], добавлен 11.10.2008Особенности среды визуального проектирования Borland Delphi 7.0. Этапы разработки программы и составления блок-схемы алгоритмов. Способы вычисления кусочно-заданной функции одной переменной. Рассмотрение компонентов среды Delphi, ее предназначение.
контрольная работа [703,8 K], добавлен 24.09.2012Предмет объектно-ориентированного программирования и особенности его применения в средах Паскаль, Ада, С++ и Delphi. Интегрированная среда разработки Delphi: общее описание и назначение основных команд меню. Процедуры и функции программы Delphi.
курсовая работа [40,8 K], добавлен 15.07.2009Рассмотрение особенностей среды программирования Delphi, анализ клиент-серверной версии. Знакомство с библиотекой визуальных компонентов. Основные функции интеллектуального редактора. Характеристика требований к базам данных. Функции программы "Магистр".
дипломная работа [1,5 M], добавлен 10.03.2013Разработка информационной системы административного управления. Выбор языка и среды программирования. Структура взаимодействия информации. Требования к программно-аппаратному окружению. Создание программы в Delphi и связывание ее с базой данных.
курсовая работа [1010,9 K], добавлен 08.10.2015Создание электронного учебника "Энциклопедия Интернет" для ознакомления пользователя с его функциями. Подготовка к разработке программного продукта. Анализ предметной области. Выбор языка программирования. Работа в интегрированной среде Delphi 7.
курсовая работа [1,2 M], добавлен 09.03.2012Основные приемы работы в среде программирования Delphi. Особенности технологии создания простейших приложений. Работа с компонентами среды разработки приложений. Ввод, редактирование, выбор и вывод информации. Аспекты использования структуры ветвления.
методичка [619,9 K], добавлен 17.11.2011Внедрение информационных технологий в систему образования. Понятие, отличительные признаки, виды, структура и предназначение электронного учебника. Принципы его создания и основные этапы разработки в интегрированной среде программирования Delphi.
дипломная работа [2,3 M], добавлен 03.07.2015Объектно-ориентированные языки программирования. Среда разработки приложений Delphi и ее элементы. Разработка программного приложения. Описание работы системы "Абитуриент", являющейся хранилищем данных об абитуриентах, поступающих в учебное заведение.
курсовая работа [1,8 M], добавлен 09.11.2011