Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.05.2020, 20:15   #1
elizabethezova
Новичок
Джуниор
 
Регистрация: 19.05.2020
Сообщений: 2
По умолчанию Поменять местами последний элемент массива с максимальным четным

Здравствуйте, тут вот такое задание нужно написать консольное приложение для того чтобы поменять местами максимальный четный элемент массива с последим.
Должно быть 4 процедуры (желательно с разными способами передачи параметров):
- ввод массива
- вывод массива
- поиск максимального четного
- обмен местами

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

Начинала делать, и при вводе размера массива происходит зацикливание и зависание.
Как это можно исправить, спасибо.
Код:
.586                           
.model   flat,    stdcall     
 
option   casemap  :  none                   
 
 
 
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\msvcrt.inc
 
 
 
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\msvcrt.lib                     
 
.STACK
 
.DATA       
ConsoleTitle    db  "  Работа ",0   ;  заголовок окна консоли
Name_Title              db  30 dup(0) 
ComSizeMas      db  " ВВедите размер массива ",13,10
Len_ComSize equ $- ComSizeMas  ; разница между адресами переменных - розмер          предыдушего  поля    ComSizeMas
ComElemMas      db  " Введите элементы массива ",13,10
Len_ComElem equ $- ComElemMas
ComMasBefore    db  " Массив до обробки  ",13,10
Len_MasBefore   equ $- ComMasBefore
ComMasAfter     db  " Массив  после обробки ",13,10
Len_MasAfter        equ $- ComMasAfter
format_size_buf db  "%d",0
format_print_buf  db    " %5d ",0  
print_buf_b     db  "Buf [  ",0
print_buf_e     db  "]=",0
print_13_10       db    13,10,0
print_13       db    13,0
 
 
.DATA?
Buf     dd  100 dup(?)   ;  максимальний обсяг масиву
Size_buf    dd  ?   ;  фактичний розмір масиву
h_input dd  ?   ;   дескриптор пристрою вводу
h_output    dd  ?   ;   дескриптор пристрою виводу
nWrite      dd  ?   ; змінна для функції WriteConsole
number_element  dd  ?     ;  поточний номер елементу вводу
element_buf dd  ?   ;   змінна для вводу елементу масиву
.CODE
main   proc
 
 call   AllocConsole     ;   створення власної консолі
 
;   перетворення символів в формат Oem  для виводу заголовку
 
invoke   CharToOemA, addr ConsoleTitle, addr Name_Title  
 
invoke      SetConsoleTitle,   addr Name_Title       ;  вивід заголовку
invoke  GetStdHandle,   STD_INPUT_HANDLE 
mov h_input, eax        ; отримали дескриптор пристрою вводу
invoke  GetStdHandle,   STD_OUTPUT_HANDLE         
mov h_output, eax                 ;  отримали дескриптор пристрою виводу
 
 
 invoke SetConsoleOutputCP,1251         ;  підтримка кирилиці
  invoke SetConsoleCP,1251  
 
call input_mas      ;  Ввід початкових даних
call work_mas       ;   Обробка масиву
call print_rezult   ;   Вивід результатів 
 
 invoke Sleep,10000  ;  Затримка зображення на екрані   
 
call FreeConsole
invoke ExitProcess, 0   ;  Завершення програми
 
main endp 
;--------------------------------------------------------------------------------------------------- 
 
input_mas   proc
 
;      ввод размера массива
 
invoke  WriteConsole, h_output, ADDR ComSizeMas, Len_ComSize, ADDR nWrite, 0 
 
invoke      crt_scanf,  ADDR format_size_buf, ADDR Size_buf     ; форматный ввод 
 
;   !!!!   сделать проверку        1<= Size_buf<=100  в случае ошибки – повторить ввод
 
mov number_element, 0       
m_input_buf:
 
invoke WriteConsole, h_output, ADDR print_buf_b, 7, ADDR nWrite, 0     ; вывод  buf [
 
invoke      crt_printf, ADDR format_size_buf , number_element   ;  вывод  № элемента
 
    invoke WriteConsole, h_output, ADDR print_buf_e, 2, ADDR nWrite, 0   ; вывод  ]= 
 
 invoke      crt_scanf, ADDR format_size_buf, ADDR  element_buf   ; ввод элементов
or eax,eax
    jnz m_1     ;  нет ошибки
 
;  ошибка ввода  - очистка буфера ввода
 
  m_2: invoke crt_getchar
      cmp eax,10    ;  доки не enter
      jne m_2
    invoke      crt_printf,   ADDR print_13
      jmp m_input_buf
m_1:
    mov eax,   element_buf         
    mov esi,   number_element     
    shl esi,2            
    mov Buf [esi],  eax         
    inc number_element     
    mov  edx,   number_element
    cmp edx,   Size_buf             
    jnz  m_input_buf      ;    цикл без   LOOP 
 
    ret
input_mas   endp
;-----------------------------------------------------------------------------------------------------
 
work_mas  proc       
 
   ret  
work_mas  endp   
;-----------------------------------------------------------------------------------------------------
 
print_rezult  proc      ;  Вывод результатов
 
 invoke WriteConsole, h_output, ADDR ComMasBefore, Len_MasBefore, ADDR nWrite, 0 
 
    mov number_element,0               
m1:   mov ecx,5     ;      вывод по 5 элементов в строку
m2:    push ecx
 
    mov eax,number_element              
    shl eax,2             
    mov esi,eax        
 
    invoke      crt_printf,   ADDR format_print_buf   ,  Buf[esi]       
    pop ecx
    inc number_element 
     mov  edx, number_element
    cmp edx, Size_buf               
    jz m_ret            ;       все элементы выведены
        dec ecx
     jnz m2
     invoke      crt_printf,   ADDR print_13_10 ;  переход на новую строчку
     jmp m1
m_ret:  ret 
print_rezult    endp
;-------------------------------------------------------------------------------------------------------
      end main
elizabethezova вне форума Ответить с цитированием
Старый 19.05.2020, 22:50   #2
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

elizabethezova, не могу понять причин, но ваша программа при компиляции, как консольного приложения /SUBSYSTEM:CONSOLE вполне нормально работает.
А при компиляции как /SUBSYSTEM:WINDOWS - возникает эта ошибка.

Вижу, что вы формируете консольное окно, потом освобождаете от неё память.
То, что выводится средствами WinAPI (WriteConsole) присутствует в окне, а вывод средствами msvcrt (crt_printf) в окне отсутствует.

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

Не сможете - забудьте о msvcrt и работайте WinAPI и библиотеками masm32 - их достаточно.
Это тоже вариант решения.
FPaul вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Си]: В каждом столбце двумерного массива поменять местами первый отрицательный элемент и последний нулевой. Помогите найти ошибку Yulia24* Помощь студентам 2 20.11.2016 01:21
Программа в Паскале: Дан одномерный массив С размерностью N. Переставить местами первый и последний элемент массива, если... hars1 Паскаль, Turbo Pascal, PascalABC.NET 7 19.03.2014 17:30
Третий положительный элемент поменять местами с максимальным PicniX Помощь студентам 0 27.12.2012 13:24
Поменять местами минимальный и максимальный элемент массива Лераа Паскаль, Turbo Pascal, PascalABC.NET 3 19.12.2012 00:32
Максимальный элемент массива поменять местами с четвертым. Katie Помощь студентам 2 13.01.2010 05:59