Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Описание и инициализация массива в программе



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

  1. Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми. К примеру:
; массив из 5 элементов.Размер каждого элемента 4 байта: mas dd 1, 2, 3, 4, 5
  1. Используя оператор повторения dup. К примеру:
; массив из 5 нулевых элементов.; Размер каждого элемента 2 байта: mas dw 5 dup (0)

 

Такой способ определения используется для резервирования памяти с целью размещения и инициализации элементов массива.

  1. Используя директивы label и rept. Пара этих директив может облегчить описание больших массивов в памяти и повысить наглядность такого описания. Директива rept относится к макросредствам языка ассемблера и вызывает повторение указанное число раз строк, заключенных между директивой и строкой endm. К примеру, определим массив байт в области памяти, обозначенной идентификатором mas_b. В данном случае директива label определяет символическое имя mas_b, аналогично тому, как это делают директивы резервирования и инициализации памяти. Достоинство директивы label в том, что она не резервирует память, а лишь определяет характеристики объекта. В данном случае объект — это ячейка памяти. Используя несколько директив label, записанных одна за другой, можно присвоить одной и той же области памяти разные имена и разный тип, что и сделано в следующем фрагменте:
...n=0...mas_b label bytemas_w label wordrept 4 dw 0f1f0hendm

В результате в памяти будет создана последовательность из четырех слов f1f0. Эту последовательность можно трактовать как массив байт или слов в зависимости от того, какое имя области мы будем использовать в программе — mas_b или mas_w.

  1. Использование цикла для инициализации значениями области памяти, которую можно будет впоследствии трактовать как массив.
  2. Посмотрим на примере листинга 2, каким образом это делается.
Листинг 2 Инициализация массива в цикле; prg_12_1.asmMASMMODEL smallSTACK 256.datames db 0ah, 0dh, 'Массив- ', '$'mas db 10 dup (? ); исходный массивi db 0.codemain: mov ax, @data mov ds, ax xor ax, ax; обнуление ax mov cx, 10; значение счетчика цикла в cx mov si, 0; индекс начального элемента в cxgo: ; цикл инициализации mov bh, i; i в bh mov mas[si], bh; запись в массив i inc i; инкремент i inc si; продвижение к следующему элементу массива loop go; повторить цикл; вывод на экран получившегося массива mov cx, 10 mov si, 0 mov ah, 09h lea dx, mes int 21hshow: mov ah, 02h; функция вывода значения из al на экран mov dl, mas[si] add dl, 30h; преобразование числа в символ int 21h inc si loop showexit: mov ax, 4c00h; стандартный выход int 21hend main; конец программы

Доступ к элементам массива

При работе с массивами необходимо четко представлять себе, что все элементы массива располагаются в памяти компьютера последовательно.

Само по себе такое расположение ничего не говорит о назначении и порядке использования этих элементов. И только лишь программист с помощью составленного им алгоритма обработки определяет, как нужно трактовать эту последовательность байт, составляющих массив. Так, одну и ту же область памяти можно трактовать как одномерный массив, и одновременно те же самые данные могут трактоваться как двухмерный массив. Все зависит только от алгоритма обработки этих данных в конкретной программе. Сами по себе данные не несут никакой информации о своем “смысловом”, или логическом, типе. Помните об этом принципиальном моменте.

Эти же соображения можно распространить и на индексы элементов массива . Ассемблер не подозревает об их существовании и ему абсолютно все равно, каковы их численные смысловые значения.

Для того чтобы локализовать определенный элемент массива, к его имени нужно добавить индекс. Так как мы моделируем массив, то должны позаботиться и о моделировании индекса. В языке ассемблера индексы массивов — это обычные адреса, но с ними работают особым образом. Другими словами, когда при программировании на ассемблере мы говорим об индексе, то скорее подразумеваем под этим не номер элемента в массиве, а некоторый адрес.

Давайте еще раз обратимся к описанию массива. К примеру, в программе статически определена последовательность данных:

mas dw 0, 1, 2, 3, 4, 5

Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой dw, то есть она равна 2 байта. Чтобы получить доступ к третьему элементу, нужно к адресу массива прибавить 6. Нумерация элементов массива в ассемблере начинается с нуля.

То есть в нашем случае речь, фактически, идет о 4 -м элементе массива — 3, но об этом знает только программист; микропроцессору в данном случае все равно — ему нужен только адрес.

В общем случае для получения адреса элемента в массиве необходимо начальный (базовый) адрес массива сложить с произведением индекса (номер элемента минус единица) этого элемента на размер элемента массива:

база + (индекс*размер элемента)

Архитектура микропроцессора предоставляет достаточно удобные программно-аппаратные средства для работы с массивами. К ним относятся базовые и индексные регистры, позволяющие реализовать несколько режимов адресации данных. Используя данные режимы адресации, можно организовать эффективную работу с массивами в памяти. Вспомним эти режимы:

  • индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется из двух компонентов:
    • постоянного (базового) — указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;
    • переменного (индексного) — указанием имени индексного регистра.
    • К примеру:
mas dw 0, 1, 2, 3, 4, 5... mov si, 4; поместить 3-й элемент массива mas в регистр ax: mov ax, mas[si]
  • базовая индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется максимум из трех компонентов:
    • постоянного (необязательный компонент), в качестве которой может выступать прямой адрес массива в виде имени идентификатора, обозначающего начало массива, или непосредственное значение;
    • переменного (базового) — указанием имени базового регистра;
    • переменного (индексного) — указанием имени индексного регистра.

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

Напомним, что в качестве базового регистра может использоваться любой из восьми регистров общего назначения. В качестве индексного регистра также можно использовать любой регистр общего назначения, за исключением esp/sp.

Микропроцессор позволяет масштабировать индекс. Это означает, что если указать после имени индексного регистра знак умножения “*” с последующей цифрой 2, 4 или 8, то содержимое индексного регистра будет умножаться на 2, 4 или 8, то есть масштабироваться.

Применение масштабирования облегчает работу с массивами, которые имеют размер элементов, равный 2, 4 или 8 байт, так как микропроцессор сам производит коррекцию индекса для получения адреса очередного элемента массива. Нам нужно лишь загрузить в индексный регистр значение требуемого индекса (считая от 0). Кстати сказать, возможность масштабирования появилась в микропроцессорах Intel, начиная с модели i486. По этой причине в рассматриваемом здесь примере программы стоит директива.486. Ее назначение, как и ранее использовавшейся директивы.386, в том, чтобы указать ассемблеру при формировании машинных команд на необходимость учета и использования дополнительных возможностей системы команд новых моделей микропроцессоров.

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

Листинг 3. Просмотр массива слов с использованиеммасштабирования; prg_12_2.asmMASMMODEL smallSTACK 256.data; начало сегмента данных; тексты сообщений: mes1 db 'не равен 0! $', 0ah, 0dhmes2 db 'равен 0! $', 0ah, 0dhmes3 db 0ah, 0dh, 'Элемент $'mas dw 2, 7, 0, 0, 1, 9, 3, 6, 0, 8; исходный массив.code.486; это обязательноmain: mov ax, @data mov ds, ax; связка ds с сегментом данных xor ax, ax; обнуление axprepare: mov cx, 10; значение счетчика цикла в cx mov esi, 0; индекс в esicompare: mov dx, mas[esi*2]; первый элемент массива в dx cmp dx, 0; сравнение dx c 0 je equal; переход, если равноnot_equal: ; не равно mov ah, 09h; вывод сообщения на экран lea dx, mes3 int 21h mov ah, 02h; вывод номера элемента массива на экран mov dx, si add dl, 30h int 21h mov ah, 09h lea dx, mes1 int 21h inc esi; на следующий элемент dec cx; условие для выхода из цикла jcxz exit; cx=0? Если да — на выход jmp compare; нет — повторить циклequal: ; равно 0 mov ah, 09h; вывод сообщения mes3 на экран lea dx, mes3 int 21h mov ah, 02h mov dx, si add dl, 30h int 21h mov ah, 09h; вывод сообщения mes2 на экран lea dx, mes2 int 21h inc esi; на следующий элемент dec cx; все элементы обработаны? jcxz exit jmp compareexit: mov ax, 4c00h; стандартный выход int 21hend main; конец программы

Еще несколько слов о соглашениях:

  • Если для описания адреса используется только один регистр, то речь идет о базовой адресации и этот регистр рассматривается как базовый:
; переслать байт из области данных, адрескоторой находится в регистре ebx: mov al, [ebx]
  • Если для задания адреса в команде используется прямая адресация (в виде идентификатора) в сочетании с одним регистром, то речь идет об индексной адресации. Регистр считается индексным, и поэтому можно использовать масштабирование для получения адреса нужного элемента массива:
add eax, mas[ebx*4]; сложить содержимое eax с двойным словом в памяти; по адресу mas + (ebx)*4
  • Если для описания адреса используются два регистра, то речь идет о базово-индексной адресации. Левый регистр рассматривается как базовый, а правый — как индексный. В общем случае это не принципиально, но если мы используем масштабирование с одним из регистров, то он всегда является индексным. Но лучше придерживаться определенных соглашений.
  • Помните, что применение регистров ebp/bp и esp/sp по умолчанию подразумевает, что сегментная составляющая адреса находится в регистре ss.

Заметим, что базово-индексную адресацию не возбраняется сочетать с прямой адресацией или указанием непосредственного значения. Адрес тогда будет формироваться как сумма всех компонентов.

К примеру:

mov ax, mas[ebx][ecx*2]; адрес операнда равен [mas+(ebx)+(ecx)*2]... sub dx, [ebx+8][ecx*4]; адрес операнда равен [(ebx)+8+(ecx)*4]

Но имейте в виду, что масштабирование эффективно лишь тогда, когда размерность элементов массива равна 2, 4 или 8 байт. Если же размерность элементов другая, то организовывать обращение к элементам массива нужно обычным способом, как описано ранее.

Рассмотрим пример работы с массивом из пяти трехбайтовых элементов (листинг 4). Младший байт в каждом из этих элементов представляет собой некий счетчик, а старшие два байта — что-то еще, для нас не имеющее никакого значения. Необходимо последовательно обработать элементы данного массива, увеличив значения счетчиков на единицу.

Листинг 4. Обработка массива элементов с нечетной длиной; prg_11_3.asmMASMMODEL small; модель памятиSTACK 256; размер стека.data; начало сегмента данныхN=5; количество элементов массиваmas db 5 dup (3 dup (0)).code; сегмент кодаmain: ; точка входа в программу mov ax, @data mov ds, ax xor ax, ax; обнуление ax mov si, 0; 0 в si mov cx, N; N в cxgo: mov dl, mas[si]; первый байт поля в dl inc dl; увеличение dl на 1 (по условию) mov mas[si], dl; заслать обратно в массив add si, 3; сдвиг на следующий элемент массива loop go; повтор цикла mov si, 0; подготовка к выводу на экран mov cx, Nshow: ; вывод на экран содержимого; первых байт полей mov dl, mas[si] add dl, 30h mov ah, 02h int 21h loop showexit: mov ax, 4c00h; стандартный выход int 21hend main; конец программы

9. Лекция 7. Двухмерные массивы. Типовые операции с массивами (1 пара)

С представлением одномерных массивов в программе на ассемблере и организацией их обработки все достаточно просто. А как быть если программа должна обрабатывать двухмерный массив? Все проблемы возникают по-прежнему из-за того, что специальных средств для описания такого типа данных в ассемблере нет. Двухмерный массив нужно моделировать. На описании самих данных это почти никак не отражается — память под массив выделяется с помощью директив резервирования и инициализации памяти.

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

При этом вы вольны в выборе того, как понимать расположение элементов двухмерного массива в памяти: по строкам или по столбцам.

Если последовательность однотипных элементов в памяти трактуется как двухмерный массив, расположенный по строкам, то адрес элемента (i, j) вычисляется по формуле

(база + количество_элементов_в_строке * размер_элемента * i+j)

Здесь i = 0...n–1 указывает номер строки, а j = 0...m–1 указывает номер столбца.

Например, пусть имеется массив чисел (размером в 1 байт) mas(i, j) с размерностью 4 на 4

(i= 0...3, j = 0...3):

23 04 05 67 05 06 07 99 67 08 09 23 87 09 00 08

В памяти элементы этого массива будут расположены в следующей последовательности:

23 04 05 67 05 06 07 99 67 08 09 23 87 09 00 08

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

mas(2, 3) = 23, то проведя нехитрый подсчет, убедимся в правильности наших рассуждений:

Эффективный адрес mas(2, 3) = mas + 4 * 1 * 2 + 3 = mas + 11

Посмотрите на представление массива в памяти и убедитесь, что по этому смещению действительно находится нужный элемент массива.

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

  • сочетание прямого адреса, как базового компонента адреса, и двух индексных регистров для хранения индексов:
mov ax, mas[ebx][esi]
  • сочетание двух индексных регистров, один из которых является и базовым и индексным одновременно, а другой — только индексным:
mov ax, [ebx][esi]

В программе это будет выглядеть примерно так:

; Фрагмент программы выборки элемента; массива mas(2, 3) и его обнуления.datamas db23, 4, 5, 67, 5, 6, 7, 99, 67, 8, 9, 23, 87, 9, 0, 8i=2j=3.code... mov si, 4*1*i mov di, j mov al, mas[si][di]; в al элемент mas(2, 3)...

В качестве законченного примера рассмотрим программу поиска элемента в двухмерном массиве чисел (листинг 5). Элементы массива заданы статически.

Листинг 5. Поиск элемента в двухмерном массиве; prg_11_4.asmMASMMODEL smallSTACK 256.data; матрица размером 2x5 — если ее не инициализировать,; то для наглядности она может быть описана так:; array dw 2 DUP (5 DUP (? )); но мы ее инициализируем: array dw 1, 2, 3, 4, 5, 6, 7, 3, 9, 0; логически это будет выглядеть так:; array= {1 2}; {3 4}; {5 6}; {7 3}; {9 0} elem dw 3; элемент для поискаfailed db 0ah, 0dh, 'Нет такого элемента в массиве! ', '$'success db 0ah, 0dh, 'Такой элемент в массиве присутствует ', '$'foundtime db? ; количество найденных элементовfnd db ' раз(а)', 0ah, 0dh, '$'.codemain: mov ax, @data mov ds, ax xor ax, ax mov si, 0; si=столбцы в матрице mov bx, 0; bx=строки в матрице mov cx, 5; число для внешнего цикла (по строкам)external: ; внешний цикл по строкам mov ax, array[bx][si]; в ax первый элемент матрицы push cx; сохранение в стеке счётчика внешнего цикла mov cx, 2; число для внутреннего цикла (по столбцам) mov si, 0iternal: ; внутренний цикл по строкам inc si; передвижение на следующий элемент в строке; сравниваем содержимое текущего элемента в ax с искомым элементом: cmp ax, elem; если текущий совпал с искомым, то переход на here для обработки,; иначе цикл продолжения поиска je here; иначе — цикл по строке cx=2 раз loop iternalhere: jcxz move_next; просмотрели строку? inc foundtime; иначе увеличиваем счётчик совпавшихmove_next: ; продвижение в матрице pop cx; восстанавливаем CX из стека (5) add bx, 1; передвигаемся на следующую строку loop external; цикл (внешний) cmp foundtime, 0h; сравнение числа совпавших с 0 ja eql; если больше 0, то переходnot_equal: ; нет элементов, совпавших с искомым mov ah, 09h; вывод сообщения на экран mov dx, offset failed int 21h jmp exit; на выходeql: ; есть элементы, совпавшие с искомым mov ah, 09h; вывод сообщений на экран mov dx, offset success int 21h mov ah, 02h mov dl, foundtime add dl, 30h int 21h mov ah, 09h mov dx, offset fnd int 21hexit: ; выход mov ax, 4c00h; стандартное завершение программы int 21hend main; конец программы

При анализе работы программы не забывайте, что в языке ассемблера принято элементы массива нумеровать с 0. При поиске определенного элемента массив просматривается от начала и до конца.

Приведенная программа сохраняет в поле foundtime количество вхождений искомого элемента в массив. В качестве индексных регистров используются si и bx.

Типовые операции с массивами

Для демонстрации основных приемов работы с массивами лучше всего подходят программы поиска или сортировки.

Рассмотрим одну такую программу, выполняющую сортировку массива по возрастанию (листинг 6).

Листинг 6. Сортировка массива< 1> ; prg_12_5.asm< 2> MASM< 3> MODEL small< 4> STACK 256< 5> .data< 6> mes1 db 0ah, 0dh, 'Исходный массив — $', 0ah, 0dh< 7> ; некоторые сообщения< 8> mes2 db 0ah, 0dh, 'Отсортированный массив — $', 0ah, 0dh< 9> n equ 9; количество элементов в массиве, считая с 0< 10> mas dw 2, 7, 4, 0, 1, 9, 3, 6, 5, 8; исходный массив< 11> tmp dw 0; переменные для работы с массивом< 12> i dw 0< 13> j dw 0< 14> .code< 15> main: < 16> mov ax, @data< 17> mov ds, ax< 18> xor ax, ax< 19> ; вывод на экран исходного массива< 20> mov ah, 09h< 21> lea dx, mes1< 22> int 21h; вывод сообщения mes1< 23> mov cx, 10< 24> mov si, 0< 25> show_primary: ; вывод значения элементов< 26> ; исходного массива на экран< 27> mov dx, mas[si]< 28> add dl, 30h< 29> mov ah, 02h< 30> int 21h< 31> add si, 2< 32> loop show_primary< 33> < 34> ; строки 40-85 программы эквивалентны следующему коду на языке С: < 35> ; for (i=0; i< 9; i++)< 36> ; for (j=9; j> i; j--)< 37> ; if (mas[i]> mas[j])< 38> ; {tmp=mas[i]; < 39> ; mas[i]=mas[j]; < 40> ; mas[j]=tmp; }< 41> mov i, 0; инициализация i< 42> ; внутренний цикл по j< 43> internal: < 44> mov j, 9; инициализация j< 45> jmp cycl_j; переход на тело цикла< 46> exchange: < 47> mov bx, i; bx=i< 48> shl bx, 1< 49> mov ax, mas[bx]; ax=mas[i]< 50> mov bx, j; bx=j< 51> shl bx, 1< 52> cmp ax, mas[bx]; mas[i]? mas[j] — сравнение элементов< 53> jle lesser; если mas[i] меньше, то обмен не нужен и; переход на продвижение далее по массиву< 54> ; иначе tmp=mas[i], mas[i]=mas[j], mas[j]=tmp: < 55> ; tmp=mas[i]< 56> mov bx, i; bx=i< 57> shl bx, 1; умножаем на 2, так как элементы — слова< 58> mov tmp, ax; tmp=mas[i]< 59> < 60> ; mas[i]=mas[j]< 61> mov bx, j; bx=j< 62> shl bx, 1; умножаем на 2, так как элементы — слова< 63> mov ax, mas[bx]; ax=mas[j]< 64> mov bx, i; bx=i< 65> shl bx, 1; умножаем на 2, так как элементы — слова< 66> mov mas[bx], ax; mas[i]=mas[j]< 67> < 68> ; mas[j]=tmp< 69> mov bx, j; bx=j< 70> shl bx, 1; умножаем на 2, так как элементы — слова< 71> mov ax, tmp; ax=tmp< 72> mov mas[bx], ax; mas[j]=tmp< 73> lesser: ; продвижение далее по массиву во внутреннем цикле< 74> dec j; j--< 75>; тело цикла по j< 76> cycl_j: < 77> mov ax, j; ax=j< 78> cmp ax, i; сравнить j? i< 79> jg exchange; если j> i, то переход на обмен< 80> ; иначе на внешний цикл по i< 81> inc i; i++< 82> cmp i, n; сравнить i? n — прошли до конца массива< 83> jl internal; если i< 85> ; вывод отсортированного массива< 86> mov ah, 09h< 87> lea dx, mes2< 88> int 21h< 89> prepare: < 90> mov cx, 10< 91> mov si, 0< 92> show: ; вывод значения элемента на экран< 93> mov dx, mas[si]< 94> add dl, 30h< 95> mov ah, 02h< 96> int 21h< 97> add si, 2< 98> loop show< 99> exit: < 100> mov ax, 4c00h; стандартный выход< 101> int 21h< 102> end main; конец программы

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

10. Лекция 8. Структуры (1 пара)

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

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

К примеру, ранее мы рассмотрели листинг 4, в котором работа производилась с массивом трехбайтовых элементов. Каждый элемент, в свою очередь, представлял собой два элемента разных типов: однобайтовое поле счетчика и двухбайтовое поле, которое могло нести еще какую-то нужную для хранения и обработки информацию. Если читатель знаком с одним из языков высокого уровня, то он знает, что такой объект обычно описывается с помощью специального типа данных — структуры.

С целью повысить удобство использования языка ассемблера в него также был введен такой тип данных.

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

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

  1. Задать шаблон структуры.
  2. По смыслу это означает определение нового типа данных, который впоследствии можно использовать для определения переменных этого типа.
  3. Определить экземпляр структуры.
  4. Этот этап подразумевает инициализацию конкретной переменной заранее определенной (с помощью шаблона) структурой.
  5. Организовать обращение к элементам структуры.

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

Описать структуру в программе означает лишь указать ее схему или шаблон; память при этом не выделяется.

Этот шаблон можно рассматривать лишь как информацию для транслятора о расположении полей и их значении по умолчанию.

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

Описать структуру в программе можно только один раз, а определить — любое количество раз.

Описание шаблона структуры

Описание шаблона структуры имеет следующий синтаксис:

имя_структуры STRUC < описание полей> имя_структуры ENDS

Здесь < описание полей> представляет собой последовательность директив описания данных db, dw, dd, dq и dt.

Их операнды определяют размер полей и, при необходимости, начальные значения. Этими значениями будут, возможно, инициализироваться соответствующие поля при определении структуры.

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

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

Рассмотрим работу со структурами на примере моделирования базы данных о сотрудниках некоторого отдела.

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

Определим структуру записи этой базы данных следующим шаблоном:


Поделиться:



Популярное:

  1. I. ОПИСАНИЕ ИСПЫТАТЕЛЬНОЙ УСТАНОВКИ. ПОРЯДОК ПЕРЕКЛЮЧЕНИЙ. МЕРЫ БЕЗОПАСНОСТИ.
  2. Библиографическое описание нормативного правового акта
  3. Библиографическое описание статьи из сборника
  4. Блок 1. Понятие о морфологии. Имена. Имя существительное: определение, грамматические признаки, правописание
  5. Выбор и описание способов прокладки электрических сетей внешнего и внутризаводского электроснабжения
  6. Глава 2. Описание экспериментального стенда «Газогидраты»
  7. Дополнения и изменения в рабочей программе
  8. Дополнения и изменения в рабочей программе,
  9. Дополнения и изменения к рабочей программе
  10. Ежедневный комплекс упражнений в программе «Сатори»
  11. Ж. КРАТКОЕ ОПИСАНИЕ ОРГАЗМИЧЕСКОГО ВЫТЯГИВАНИЯ
  12. Из предложений 11–12 выпишите образованные приставочно-суффиксальным способом наречия, в которых правописание суффикса зависит от приставки.


Последнее изменение этой страницы: 2016-05-28; Просмотров: 733; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.051 с.)
Главная | Случайная страница | Обратная связь