Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Лабораторные работы по курсу «Основы языка Assembler»
3 Работа с массивами и стеком на языке ассемблера
3.1 Общие сведения о массивах
Как структура представления, массив является упорядоченным множеством элементов определенного типа. Упорядоченность массива определяется набором целых чисел, называемых индексами, которые связываются с каждым элементом массива и однозначно конкретизируют его расположение среди других элементом массива. Локализация конкретного элемента массива - ключевая задача при разработке любых алгоритмов, работающих с массивами.
Наиболее просто представляются одномерные массивы. Соответствующая им структура хранения это вектор. Она однозначна и есть не что иное, как просто последовательное расположение элементов в памяти. Чтобы локализовать нужный элемент одномерного массива, достаточно знать его индекс. Так как ассемблер не имеет средств для работы с массивом как структурой данных, то для доступа к элементу массива необходимо вычислить его адрес.
Представление двумерных массивов немного сложнее. Здесь мы имеем случай, когда структуры хранения и представления различны. О структуре представления говорить излишне это матрица. Структура хранения остается прежней вектор. Но теперь его нельзя без специальных оговорок интерпретировать однозначно. Все зависит от того, как решил разработчик программы «вытянуть» массив по строкам или по столбцам. Наиболее естествен порядок расположения элементов массива по строкам. При этом наиболее быстро изменяется последний элемент индекса.
3.2 Вывод массива
Пример вывода массива:
;процедура вывода без знакового двухзначного элемента массива
out_elem proc far; AX входной параметр, т.е. элемент массива
pusha ;помещаем основные регистры в стек
div ten ; после деления первая цифра в AL, а вторая в AH
mov dx,ax; сохраним первую и вторую цифры
mov ah,0Eh
mov bh,00h ; обнулим регистр
mov al,dl ; первую цифру отправляем в AL
add al,'0' ; получаем ASCII символ цифры
int 10h; вывод цифры на экран, вызовом соответствующего прерывания
mov al,dh
add al,'0'
int 10h; вывод второй цифры
popa
ret
out_ elem endp
…
;вызов процедуры в цикле для вывода всех значений массива
xor si,si ;обнуляем счетчик
mov cx,n ; n размерность массива
out_massiv:
xor ax,ax
mov AL,Z[si]; Z исходный массив
call out_elem ;
inc si
loop massiv
…
3.3 Способы сортировки массивов.
Метод пузырька
Процедура bubble_sort
; сортирует массив слов методом пузырьковой сортировки
; ввод: DS:DI = адрес массива
; DX = размер массива (в словах)
bubble_sort proc near
pusha
cld
cmp dx,1
jbe sort_exit ; выйти, если сортировать нечего
dec dx
sb_loop1:
mov cx,dx ; установить длину цикла
xor bx,bx ; BX будет флагом обмена
mov si,di ; SI будет указателем на
; текущий элемент
sn_loop2:
lodsw ; прочитать следующее слово
cmp ax,word ptr [si]
jbe no_swap ; если элементы не
; в порядке,
xchg ax,word ptr [si] ; поменять их местами
mov word ptr [si-2],ax
inc bx ; и установить флаг в 1,
no_swap:
loop on_loop2
cmp bx,0 ; если сортировка не закончилась,
jne sn_loop1 ; перейти к следующему элементу
sort_exit:
popa
ret
bubble_sort endp
Пузырьковая сортировка осуществляется так медленно потому, что сравнения выполняются лишь между соседними элементами. Чтобы получить более быстрый метод сортировки перестановкой, следует выполнять сравнение и перестановку элементов, отстоящих далеко друг от друга. На этой идее основан алгоритм, который называется «быстрая сортировка». Он работает следующим образом: делается предположение, что первый элемент является средним по отношению к остальным. На основе такого предположения все элементы разбиваются на две группы - больше и меньше предполагаемого среднего. Затем обе группы отдельно сортируются таким же методом. В худшем случае быстрая сортировка массива из N элементов требует N2 операций, но в среднем случае - только 2n*log2n сравнений и еще меньшее число перестановок.
Метод быстрой сортировки:
; Процедура quick_sort
; сортирует массив слов методом быстрой сортировки
; ввод: DS:BX = адрес массива
; DX = число элементов массива
quicksort proc near
cmp dx,1 ; Если число элементов 1 или 0,
jle qsort_done ; то сортировка уже закончилась
xor di,di ; индекс для просмотра сверху (DI = 0)
mov si,dx ; индекс для просмотра снизу (SI = DX)
dec si ; SI = DX-1, так как элементы нумеруются с нуля,
shl si,1 ; и умножить на 2, так как это массив слов
mov ax,word ptr [bx] ; AX = элемент X1, объявленный средним
step_2: ; просмотр массива снизу, пока не встретится
; элемент, меньший или равный Х1
cmp word ptr [bx][si],ax ; сравнить XDI и Х1
jle step_3 ; если XSI больше,
sub si,2 ; перейти к следующему снизу элементу
jmp short step_2 ; и продолжить просмотр
step_3: ; просмотр массива сверху, пока не встретится
; элемент меньше Х1 или оба просмотра не придут
; в одну точку
cmp si,di ; если просмотры встретились,
je step_5 ; перейти к шагу 5,
add di,2 ; иначе: перейти
; к следующему сверху элементу,
cmp word ptr [bx][di],ax ; если он меньше Х1,
jl step_3 ; продолжить шаг 3
steр_4:
; DI указывает на элемент, который не должен быть
; в верхней части, SI указывает на элемент,
; который не должен быть в нижней. Поменять их местами
mov cx,word ptr [bx][di] ; CX = XDI
xchg cx,word ptr [bx][si] ; CX = XSI, XSI = XDI
mov word ptr [bx][di],cx ; XDI = CX
jmp short step_2
step_5: ; Просмотры встретились. Все элементы в нижней
; группе больше X1, все элементы в верхней группе
; и текущий - меньше или равны Х1 Осталось
; поменять местами Х1 и текущий элемент:
xchg ах,word ptr [bx][di] ; АХ = XDI, XDI = X1
mov word ptr [bx],ax ; X1 = AX
; теперь можно отсортировать каждую из полученных групп
push dx
push di
push bx
mov dx,di ; длина массива X1...XDI-1
shr dx,1 ; в DX
call quick_sort ; сортировка
pop bx
pop di
pop dx
add bx,di ; начало массива XDI+1...XN
add bx,2 ; в BX
shr di,1 ; длина массива XDI+1...XN
inc di
sub dx,di ; в DX
call quicksort ; сортировка
qsort_done: ret
quicksort endp
Кроме того, что быстрая сортировка - самый известный пример алгоритма, использующего рекурсию, то есть вызывающего самого себя. Это еще и самая быстрая из сортировок «на месте», то есть сортировка, использующая только ту память, в которой хранятся элементы сортируемого массива. Можно доказать, что сортировку нельзя выполнить быстрее, чем за n*log2n операций, ни в худшем, ни в среднем случаях; и быстрая сортировка достаточно хорошо приближается к этому пределу в среднем случае. Сортировки, достигающие теоретического предела, тоже существуют это сортировки турнирным выбором и сортировки вставлением в сбалансированные деревья, но для их работы требуется резервирование дополнительной памяти Так что, например, работа со сбалансированными деревьями будет происходить медленно из-за дополнительных затрат на поддержку сложных структур данных в памяти.
Примеры обработки массивов:
;1) Переменной Max присвоить значение максимального элемента одномерного массива.
.model small ; задание модели памяти
.stack 200h ; задание сегмента стека размером 512 байт
.data ; начало сегмента данных
; выделение 10 байт под массив из 5 элементов (по 2 байта
; каждый) с начальной инициализацией
A dw 5 dup (5,2,8,3,1)
Max dw ? ; выделение 2 байт под переменную
MaxStr dw ? ; значение Max в символьном виде
db $ ; символ конца строки
.code ; начало сегмента кода
Begin:
mov ax, @Data ; настройка регистра сегмента данных
mov ds, ax
mov ax, A
mov Max, ax
; в регистр si заносится смещение элемента массива относительно
; базового адреса массива(т.к. один элемент массива занимает
; 2 байта, то для второго элемента смещение равно 2 байтам,
; для третьего элемента - 4 байтам и т.д.)
mov si, 2
; команда цикла loop работает с регистром сх, в который
; заносится необходимое количество итераций
mov cx, 4
for_cycle: mov ax, A[si] ; команде дано символическое имя - метка for_cycle
cmp ax, Max
jle do_else
mov Max, ax
do_else: add si, 2
loop for_cycle
;вывод значения переменной Max на экран (для примера считаем
;Max числом, состоящим из одного знака)
add ax, 48 ; получаем код символа значения Max
mov MaxStr, ax
mov dx, offset MaxStr
mov ax, 09h
int 21h
mov ax, 4C00h ; корректное завершение программы
int 21h
end Begin
;2) Задан массив A[N] из элементов типа Byte (целое 8-разрядное без знака).
; Составить программу нахождения максимального и минимального элемента.
; Разместить индексы минимального и максимального элемента в отдельных ячейках
; памяти. Подсчитать среднее арифметическое минимума и максимума.
; Индекс максимального элемента разместим в ячейке IndMax, а индекс ;минимального элемента разместим в ячейке IndMin.
;Среднее арифметическое минимума и
; максимума разместим в ячейке Mean.
.model small
.386
.stack 100h
.data
N dw 10 ; Размерность массива.
A db 3, 120, 2, 6, 11, 5, 4, 34, 15, 10
IndMax dw ? ; Номер максимального элемента в A.
IndMin dw ? ; Номер минимального элемента в A.
Mean db ? ; Среднее арифметическое минимума и максимума.
.code
;процедура очистки экрана
cls_all proc;
pusha
mov ax,0003h;устанавливаем графический режим 03h (80х25)
int 10h; вызываем соответствующее прерывание
popa
ret
cls_all endp
Start:
mov ax, @data
mov ds, ax
mov si, 0 ; Инициализируем счётчик цикла.
mov ch, -128 ; Инициализируем максимальное значение массива.
mov cl, 127 ; Инициализируем минимальное значение массива.
M1: mov al, A[si]
cmp al, ch ; Поиск максимума.
jle M2
mov ch, al ; Текущий элемент больше максимума.
mov IndMax, si ; Запоминаем его номер.
inc IndMax ; Корректировка номера, т.к. si=i-1.
M2: cmp al, cl ; Поиск минимума.
jge M3
mov cl, al ; Текущий элемент меньше минимума.
mov IndMin, si ; Запоминаем его номер.
inc IndMin ; Корректировка номера, т.к. si=i-1.
M3: inc si ; Команды завершения тела цикла.
cmp si, N
jb M1
; Ищем среднее арифметическое минимума(CL) и максимума(CH).
mov al, cl ; AL = Min
add al, ch ; AL = Min+Max
shr al, 1 ; AL = AL / 2 среднее арифметическое.
mov Mean, al ; Записываем результат.
mov ax, 4c00h
int 21h
end Start
3.4 Работа со стеком в ассемблере
3.4.1 Команды работы со стеком
В процессорах Intel команду BSWAP можно использовать и для обращения порядка байт в 16-битных регистрах, но в некоторых совместимых процессорах других фирм этот вариант BSWAP не реализован.
Команда: |
PUSH источник |
Назначение: |
Поместить данные в стек |
Процессор: |
8086 |
Команда помещает содержимое источника в стек. В качестве параметра «источник» может быть регистр, сегментный регистр, непосредственный операнд или переменная. Фактически эта команда копирует содержимое источника в память по адресу SS:[ESP] и уменьшает ESP на размер источника в байтах (2 или 4). Команда PUSH практически всегда используется в паре с POP (считать данные из стека). Так, например, чтобы скопировать содержимое одного сегментного регистра в другой (что нельзя выполнить одной командой MOV), можно использовать такую последовательность команд:
push cs
pop ds ; теперь DS указывает на тот же сегмент, что и CS
Другое частое применение команд PUSH/POP временное хранение переменных, например:
push ax ; сохраняет текущее значение АХ
... ; здесь располагаются какие-нибудь команды,
; которые используют АХ, например CMPXCHG
pop ax ; восстанавливает старое значение АХ
Начиная с 80286, команда PUSH ESP (или SP) помещает в стек значение ESP до того, как эта же команда его уменьшит, в то время как на 8086 SP помещался в стек уже уменьшенным на два.
Команда: |
POP приемник |
Назначение: |
Считать данные из стека |
Процессор: |
8086 |
Команда помещает в приемник слово или двойное слово, находящееся в вершине стека, увеличивая ESP на 2 или 4 соответственно. POP выполняет действие, полностью обратное PUSH. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS (чтобы загрузить CS из стека, надо воспользоваться командой RET), или переменная. Если в роли приемника выступает операнд, использующий ESP для косвенной адресации, команда POP вычисляет адрес операнда уже после того, как она увеличивает ESP.
Команда: |
PUSHA |
Назначение: |
Поместить в стек все регистры общего назначения |
Процессор: |
80186 |
PUSHA помещает в стек регистры в следующем порядке: АХ, СХ, DX, ВХ, SP, ВР, SI и DI. PUSHAD помещает в стек ЕАХ, ЕСХ, EDX, ЕВХ, ESP, EBP, ESI и EDI. (В случае SP и ESP используется значение, которое находилось в этом регистре до начала работы команды.) В паре с командами POPA/POPAD, считывающими эти же регистры из стека в обратном порядке, это позволяет писать подпрограммы (обычно обработчики прерываний), которые не должны изменять значения регистров по окончании своей работы. В начале такой подпрограммы вызывают команду PUSHA, а в конце РОРА.
На самом деле PUSHA и PUSHAD одна и та же команда с кодом 60h. Ее поведение определяется тем, выполняется ли она в 16- или в 32-битном режиме. Если программист использует команду PUSHAD в 16-битном сегменте или PUSHA в 32-битном, ассемблер просто записывает перед ней префикс изменения размерности операнда (66h).
Это же будет распространяться на некоторые другие пары команд: РОРА/POPAD, POPF/POPFD, PUSHF/PUSHFD, JCXZ/JECXZ, CMPSW/CMPSD, INSW/INSD, LODSW/LODSD, MOVSW/MOVSD, OUTSW/OUTSD, SCASW/SCASD и STOSW/STOSD.
Команда: |
POPA |
Назначение: |
Загрузить из стека все регистры общего назначения |
Процессор: |
80186 |
3.4.2 Передача параметров в стеке
Параметры помещаются в стек сразу перед вызовом процедуры. Именно этот метод используют языки высокого уровня, такие как С и Pascal. Для чтения параметров из стека обычно используют не команду POP, а регистр ВР, в который помещают адрес вершины стека после входа в процедуру:
push parameter1 ; поместить параметр в стек
push parameter2
call procedure
add sp,4 ; освободить стек от параметров
[...]
procedure proc near
push bp
mov bp,sp
(команды, которые могут использовать стек)
mov ax,[bp+4] ; считать параметр 2.
; Его адрес в сегменте стека ВР + 4, потому что при выполнении
; команды CALL в стек поместили адрес возврата - 2 байта для процедуры
; типа NEAR (или 4 - для FAR), а потом еще и ВР - 2 байта
mov bx,[bp+6] ; считать параметр 1
(остальные команды)
рор bp
ret
procedure endp
Параметры в стеке, адрес возврата и старое значение ВР вместе называются активационной записью функции.
Для удобства ссылок на параметры, переданные в стеке, внутри функции иногда используют директивы EQU, чтобы не писать каждый раз точное смещение параметра от начала активационной записи (то есть от ВР), например так:
push X
push Y
push Z
call xyzzy
[...]
xyzzy proc near
xyzzy_z equ [bp+8]
xyzzy_y equ [bp+6]
xyzzy_x equ [bp+4]
push bp
mov bp,sp
(команды, которые могут использовать стек)
mov ax,xyzzy_x ;считать параметр X
(остальные команды)
pop bp
ret 6
xyzzy endp
При внимательном анализе этого метода передачи параметров возникает сразу два вопроса: кто должен удалять параметры из стека, процедура или вызывающая ее программа, и в каком порядке помещать параметры в стек. В обоих случаях оказывается, что оба варианта имеют свои «за» и «против», так, например, если стек освобождает процедура (командой RET число_байтов), то код программы получается меньшим, а если за освобождение стека от параметров отвечает вызывающая функция, как в нашем примере, то становится возможным вызвать несколько функций с одними и теми же параметрами просто последовательными командами CALL. Первый способ, более строгий, используется при реализации процедур в языке Pascal, а второй, дающий больше возможностей для оптимизации, - в языке С. Разумеется, если передача параметров через стек применяется и для возврата результатов работы процедуры, из стека не надо удалять все параметры, но популярные языки высокого уровня не пользуются этим методом. Кроме того, в языке С параметры помещают в стек в обратном порядке (справа налево), так что становятся возможными функции с изменяемым числом параметров (как, например, printf - первый параметр, считываемый из [ВР+4], определяет число остальных параметров). Но подробнее о тонкостях передачи параметров в стеке рассказано далее, а здесь приведен обзор методов.
4.4.3 Передача параметров в потоке кода
В этом необычном методе передаваемые процедуре данные размещаются прямо в коде программы, сразу после команды CALL (как реализована процедура print в одной из стандартных библиотек процедур для ассемблера UCRLIB):
call print
db "This ASCIZ-line will be printed",0
(следующая команда)
Чтобы прочитать параметр, процедура должна использовать его адрес, который автоматически передается в стеке как адрес возврата из процедуры. Разумеется, функция должна будет изменить адрес возврата на первый байт после конца переданных параметров перед выполнением команды RET. Например, процедуру print можно реализовать следующим образом:
print proc near
push bp
mov bp,sp
push ax
push si
mov si,[bp+2] ; прочитать адрес
; возврата/начала данных
cld ; установить флаг направления
; для команды lodsb
print_readchar:
lodsb ; прочитать байт из строки,
test al,al ; если это 0 (конец строки),
jz print_done ; вывод строки закончен
int 29h ; вывести символ в AL на экран
jmp short print_readchar
print_done:
mov [bp+2],si ; поместить новый адрес возврата в стек
pop si
pop ax
pop bp
ret
print endp
Передача параметров в потоке кода, так же, как и передача параметров в стеке в обратном порядке (справа налево), позволяет передавать различное число параметров. Но этот метод - единственный, позволяющий передать по значению параметр различной длины, что и продемонстрировал этот пример. Доступ к параметрам, переданным в потоке кода, несколько медленнее, чем к параметрам, переданным в регистрах, глобальных переменных или стеке, и примерно совпадает со следующим методом.
4.5 Задания
Дан двумерный массив. Размер массива и его элементы вводятся пользователем с клавиатуры. Результат работы программы выводится на экран. Необходимы алгоритмы обработки массива оформить виде процедур, такие как ввод элементов массива, вывод массива на экран, поиск минимального элемента, поиск максимального элемента и т.п.
Варианты:
Вариант 1
Из исходного массива двузначных десятичных чисел со знаком получить два новых, поместив в первый из них значения элементов, превосходящих среднее значение массива, а во второй номера этих элементов (среднее = ).
Вариант 2
Из двух исходных массивов двузначных десятичных чисел без знака X и Y cформировать массив Z, поместив в него все элементы исходных, превышающие общее среднее = .
Вариант 3
Из исходного массива двузначных десятичных чисел со знаком получить два новых, поместив в первый из них номера максимальных, а во 2-ой номера минимальных элементов исходного. (Предполагается, что MIN и MAX могут быть не единственными).
Вариант 4
Найдите в массиве двузначных десятичных чисел без знака X все элементы и их номера и поместите эти значения в два новых массива Y - элементов и Z - индексов.
Вариант 5
Из исходного массива X двузначных десятичных чисел со знаком сформировать массив Y- отклонений от среднего
() и массив Z- номеров элементов исходного массива, превышающих среднее.
Вариант 6
Выявить все номера элементов массива двузначных десятичных чисел без знака X, превышающих (max+min)/2. В результате сформировать 2 массива: Y- масив номеров и Z- массив значений, для которых выполняется заданное условие.
Вариант 7
Из исходного массива двузначных десятичных чисел со знаком X получить новый массив Y ().
Подсчитайте среднее = .
Вариант 8
Из исходного массива двузначных десятичных чисел без знака получить два новых, поместив в них значения и номера элементов, для которых выполняется условие
Вариант 9
Из исходного массива двузначных десятичных чисел со знаком X получить два новых Y и Z, таких что:
Вариант 10
Получить из исходного массива X двузначных десятичных чисел без знака два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие .
Вариант 11
Получить из исходного массива X двузначных десятичных чисел без знака два новых Y, Z, помеcтив в них номера элементов и их значения, для которых выполняется условие .
Вариант 12
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них элементы и номера, для которых выполняется условие .
Вариант 13
Из исходного массива X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в Y элементы, значения которых меньше (Xmax+Xmin)/ 2, а в Z - номера этих элементов.
Вариант 14
Из исходного массива X двузначных десятичных чисел со знаком получить два новых Y, Z, поместив в первый из них нечетные значения элементов массива, а во второй их номера.
Вариант 15
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них номера элементов превышающих заданное число А, а во второй - элементы, значения которых меньше среднего в массиве (среднее = ).
Вариант 16
Получить из исходного массива X двузначных десятичных чисел без знака два новых Y, Z, поместив в них элементы и номера, для которых выполняется условие x i <= xi-1 + xi+1.
Вариант 17
Из исходного массива двузначных десятичных чисел без знака X получить два новых Y и Z, таких что:
Вариант 18
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi <= xmax xmin.
Вариант 19
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них номера элементов и их значения, для которых выполняется условие: xi < (xi-1 +xi +xi+1)/3.
Вариант 20
Получить из исходного массива X двузначных десятичных чисел без знака два новых Y, Z, поместив в них элементы и номера, для которых выполняется условие: xi <= xmax +xmin.
Вариант 21
Из исходного массива X двузначных десятичных чисел со знаком получить два новых Y, Z, поместив в Y элементы, значения которых меньше (xmax-xmin)/ 4, а в Z - номера этих элементов.
Вариант 22
Из исходного массива X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них четные значения элементов массива, а во второй их номера.
Вариант 23
Из исходного X двузначных десятичных чисел со знаком получить два новых Y, Z,, поместив в первый из них номера элементов не превышающих заданное число А, а во второй - элементы, значения которых больше среднего в массиве (среднее = ).
Вариант 24
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них элементы и номера, для которых выполняется условие x i = xi-1 + xi+1.
Вариант 25
Из исходного массива двузначных десятичных чисел без знака получить два новых, поместив в первый из них значения элементов, не превосходящих среднее значение массива, а во второй номера этих элементов (среднее = ).
Вариант 26
Из двух исходных массивов двузначных десятичных чисел со знаком X и Y cформировать массив Z, поместив в него все элементы исходных, не превышающие общее среднее = .
Вариант 27
Из исходного массива двузначных десятичных чисел со знаком X сформировать массив Z, поместив в него только те элементы, которые не превышают разность максимального и минимального элементов массива.
Вариант 28
Из исходного массива двузначных десятичных чисел со знаком X сформировать массив Z, в котором нечетные элементы исходного массива Х заменены на сумму номеров минимального и максимального элементов.
Вариант 29
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi <= последнего отрицательного элемента.
Вариант 30
Получить из исходного массива X двузначных десятичных чисел со знаком два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi >= последнего нечетного элемента.
Вариант 31
Получить из исходного массива X двузначных десятичных чисел без знака, два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi <= максимального среди четных элементов.
Вариант 32
Получить из исходного массива X двузначных десятичных чисел без знака, два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi >= минимального среди нечетных элементов.
Вариант 33
Получить из исходного массива X двузначных десятичных чисел без знака, два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi > минимального среди кратных 3 элементов.
Вариант 34
Получить из исходного массива X двузначных десятичных чисел со знаком, два новых Y, Z, поместив в них элементы и номера элементов массива X, для которых выполняется условие: xi < максимального среди кратных 3 элементов.
Вариант 35
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них номера элементов превышающих введенного с клавиатуры числа А, а во второй - элементы, значения которых больше разности максимального элемента и числа A.
Вариант 36
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них номера элементов меньше количества нулевых элементов, а во второй - элементы, значения которых больше количества не нулевых элементов.
Вариант 37
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них номера элементов меньше разности последнего четного и первого нечетного элементов, а во второй их значения.
Вариант 38
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них значения элементов больше половины суммы последнего четного и минимального элементов, а во второй их номера.
Вариант 39
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них значения элементов меньше суммы первого четного, последнего нечетного, минимального и максимального элементов, деленных на четыре, а во второй их номера.
Вариант 40
Из исходного X двузначных десятичных чисел без знака получить два новых Y, Z, поместив в первый из них значения элементов больше разности минимального плюс максимального элементов и количества нулевых элементов, деленных на четыре, а во второй их номера.
Список литературы:
PAGE \* MERGEFORMAT 21