Форум «Всё о Паскале» _ Задачи _ Массивы(с модулем)
Автор: Ursula 20.05.2006 7:08
Когда запускаю программу, максимальный и миним. элементы не находятся! я наверное формальные переменные не так написала!
Код
program obrabotkamassivov; uses WinCrt, My_ZS; var i, j, minimum, maximum, r, minX, maxX: integer;{индексы элеметов, где i-сттрока, j-столбец} k, m, n, w: integer; name: string; A: mas2r_i; {2мерный массив} x: mas1r_x;{сформированный 1мерный массив} f: boolean; procedure mas_x( n: integer; var x: mas1r_x); var s: word; begin writeln; writeln('массив, сформиpованный из сумм положительных элементов строк исходного массива'); n:=1; for i:=1 to m do begin S:=0; for j:=1 to k do begin if a[i,j]>0 then S:=S+a[i,j]; end; x[n]:=s; writeln(' x[',n,']=',s:3); n:=n+1; end; writeln; end; Procedure MxL(n:integer; x:mas1r_x); var max:integer; begin max:=x[1]; for i:=1 to n do begin if x[i]>max then max:=x[i]; writeln('максимальный элемент равен',max); end; end; Procedure MnL(n:integer; x:mas1r_x); var min:integer; begin min:=x[1]; for i:=1 to n do begin if x[i]<min then min:=x[i]; writeln('максимальный элемент равен',min); end; end; Procedure Zadanie; begin writeln(' И С Х О Д Н Ы Е Д А Н Н Ы Е'); Writeln('Прямоугольная целочисленная матрица С, состаящая из'); Writeln('М строк по К элементов'); Writeln(' З А Д А Н И Е'); Writeln('Сформировать массив Х из сумм положительных элементов'); Writeln('строк матрицы С; В массиве Х найти максимальный и минимальный элементы'); end; BEGIN zastavka(5,'Массивы'); ClrScr; Zadanie; writeln; writeln; vvod_mas2r(max,'A', m, k, A);{ввод 2мерного масссива} vivod_mas2r(m, k, 'A', a);readln; mas_x(n, x);readln; MxL(n,x); MnL(n,x); povtorka(f); end.
мой Модуль
Код
Unit My_ZS; interface Uses winCrt, windos; const max=50; type mas1r_x=array[1..max] of integer;{тип 1мерного массива целочисленного типа} mas1r_i=array[1..max] of string[50];{тип 1мерного массива целочисленного типа} mas2r_i=array[1..max,1..max] of integer;{тип 2мерного массива целочисленного типа} mas2r_r=array[1..max,1..max] of real; {тип 2мерного массива вещественного типа} var i, j: integer;{индексы элеметов, где i-сттрока, j-столбец} procedure vvod_mas2r(max: byte; name: string;var m, k: integer; var a: mas2r_i);{ввод 2мерного масссива} procedure vvod_mas1r(max: byte; name: string; var m: integer; var x: mas1r_x);{ввод 2мерного масссива} procedure vivod_mas2r(m,k: integer; name: string;a: mas2r_i); procedure vivod_1r(n:integer; name:string; x:mas1r_x); procedure In_Real(g:char; var x:real); procedure Out_real(g: char;var a: real); Procedure WaitDos (WaitTime :word); procedure In_integer(g: char; var a: integer); procedure wait; procedure In_real_comment(g: string; var a: real); procedure chetnost ( var a: integer); procedure In_integer_comment(g: string; var a: integer); procedure Out_real_comment(g: string; var a: real); procedure Out_integer_comment(g: string; var a: integer); procedure povtor(var f: boolean); procedure povtorka(var f: boolean); implementation procedure vvod_mas2r(max: byte;name: string; var m, k: integer; var a: mas2r_i); label L; var f: boolean; begin repeat writeln('введите количество строк массива ',name,'< ',max); readln(m); writeln('введите количество столбцов массива ',name,'< ',max); readln(k); f:=((m>=0)and(m<max))and((k>=0)and(k<max)); if not f then writeln('Вы ошиблись. Максимальное кол-во строк ',max, ' Максимальное кол-во столбцов ',max); until f; for i:=1 to m do begin for j:=1 to k do begin {$I-} L: write (name,'[', i:2,',',j:2,']='); read(a[i,j]); {$I+} if IOResult<>0 then begin writeln('вы ошиблись, повторите ввод'); goto L; end; end; writeln; end; end; procedure vvod_mas1r(max: byte;name: string; var m: integer; var x: mas1r_x); label L; var f: boolean; begin ClrScr; repeat writeln('введите количество строк массива ',name,'< ',max); readln(m); f:=((m>=0)and(m<max)); if not f then writeln('Вы ошиблись. Максимальное кол-во строк ',max); until f; for i:=1 to m do begin {$I-} L: write (name,'[', i:2,']='); read(x[i]); {$I+} if IOResult<>0 then begin writeln('вы ошиблись, повторите ввод'); goto L; end; end; writeln; end; procedure vivod_mas2r(m,k: integer; name: string;a: mas2r_i); begin for i:=1 to m do begin for j:=1 to k do begin write(' ',name,'[',i:2,',',j:2,']=', a[i,j]:3); end; writeln; end; readln; end; procedure vivod_1r(n:integer; name:string; x: mas1r_x); var i:integer; begin for i:=1 to n do write (' ',name,'[',i:2,']=',x[i]:3); writeln; end; {ввод переменной вщественного типа} PROCEDURE In_Real; Label 1; BEGIN 1: Write('Введите значение ',g,'='); {$I-} Readln(x) {$I+}; If Ioresult<>0 then BEGIN Writeln('Неверный ввод! повторите! '); Goto 1 END; end; procedure Out_real(g: char;var a: real); begin write(g,'= ', a:8:6); end; Procedure WaitDos; VAR House, Minute, Second, Sec100, Second_0:word; Begin GetTime(House, Minute, Second, Sec100); if WaitTime+Second >= 60 then Second_0:= WaitTime + Second-60 else Second_0:= Second + WaitTime; repeat GetTime(House, Minute, Second, Sec100); until Second = Second_0; END; {ввод целочисленной переменной} procedure In_integer(g: char; var a: integer); label 1; begin {$I-} 1: write ('введите значение ',g,' '); read (a); {$I+} if IOResult <>0 then begin writeln('Вы ошиблись повторите ввод');goto 1; end else end; procedure wait; begin write('Выход-ENTER'); readln; donewincrt; end; {ввод переменной вещественного типа с комментарием} procedure In_real_comment(g: string; var a: real); label 1; begin {$I-} 1: write (' ',g,' '); readln(a); {$I+} if IOResult <>0 then begin writeln('Вы ошиблись!!! повторите ввод!');goto 1; end else end; {процедура, определяющая перемиенную на четность} procedure chetnost ( var a: integer); var D: boolean; begin d:=odd(a); If d=true then writeln (a,' нечетное') else writeln(a,' четное'); writeln; readln; end; procedure In_integer_comment(g: string; var a:integer); label 1; begin {$I-} 1: write (' ',g,' '); readln(a); {$I+} if IOResult <>0 then begin writeln('Вы ошиблись, повторите ввод');goto 1; end else end; procedure Out_real_comment(g: string; var a: real);label 1; begin {$I-} writeln; 1: write(g,'= ', a:8:6); {$I+} if IOResult <>0 then begin writeln('Вы ошиблись, повторите ввод');goto 1; end; end; procedure Out_integer_comment(g: string; var a: integer); begin write(g,'= ', a); end; procedure povtor(var f: boolean); var x: char; begin REPEAT ClrEol; writeln('Хотите перейти к выбору работ? Y или N?'); readln(x); f:=(x='y')or(x='n'); if not f then begin writeln('Вы ошиблись. Повторите ввод'); end; UNTIL f; if (x='y') or (x='Y') then f:=true else begin F:=false; donewincrt; end; end; procedure povtorka(var f: boolean); var x: char; begin REPEAT ClrEol; writeln('Хотите повторить? Y или N?'); readln(x); f:=(x='y')or(x='n'); if not f then begin writeln('Вы ошиблись. Повторите ввод'); end; UNTIL f; if (x='y') or (x='Y') then f:=true else begin F:=false; donewincrt; end; end; end.
Автор: lapp 20.05.2006 7:15
Ursula, пожалуйста, используй теги. Отредактируй свое сообщение: Нажми кнопку "Изменить", выбери "Полное редактирование" Потом выдели весь текст программы (код) блоком и нажми кнопку P над окошком редактирования. И потом "Применить исправления" Ok?
Автор: Bokul 20.05.2006 11:20
Код
uses WinCrt, My_ZS;
Выложи свой модуль My_ZS ---------------------------------------------- Добавил потом
Извиняюсь, нашел его.
Автор: Bokul 20.05.2006 12:26
Наконец-то нашел ошибку, вернее ошибки Все дело в глобальных переменных... В процедурах нахождения максимального и минимального элементов ты объявляешь локальную переменную 'n', но другая переменная с таким же названием уже объявленная как глобальная... И за этого в процедурах, цикл идет не до того значения границ которое ты им передал, а до значения глобальной переменной... Для исправления этого, поменяй название локальных переменных в процедурах.
Совет на будущие: всегда аккуратно используй глобальные переменные, и вообще старайся обходится без них.
И еще одно:
Зачем выводить махимальное значения в цыкле?
Код
Procedure MnL(bb:integer; x:mas1r_x);{-----исправленно названия переменной-----} var min:integer; begin min:=x[1]; for i:=1 to bb do {-----исправленно названия переменной-----} begin if x[i]<min then min:=x[i]; writeln('максимальный элемент равен',min); {значения минимального выводится bb раз} end; end;
Так будет лутше:
Код
Procedure MnL(bb:integer; x:mas1r_x); {-----исправленно названия переменной-----} var min:integer; begin min:=x[1]; for i:=1 to bb do {-----исправленно названия переменной-----} begin if x[i]<min then min:=x[i]; end; writeln('максимальный элемент равен',min);{значения минимального выводится только один раз} end;
Автор: volvo 20.05.2006 13:19
Ursula, в следующий раз за дублирование буду закрывать обе темы. Ясно? Тебе задали вопрос тут: http://forum.pascal.net.ru/index.php?showtopic=10922
Зачем создала новую тему?
Автор: volvo 20.05.2006 14:35
Цитата(Bokul @ 20.05.2006 8:26)
Все дело в глобальных переменных... В процедурах нахождения максимального и минимального элементов ты объявляешь локальную переменную 'n', но другая переменная с таким же названием уже объявленная как глобальная... И за этого в процедурах, цикл идет не до того значения границ которое ты им передал, а до значения глобальной переменной...
Ничего подобного... Корень зла не в этом
Если бы компилятор обрабатывал глобальные/локальные переменные так, как ты говоришь - отладка программ стала бы адом для программиста. Но есть одно НО: Локальные переменные имеют преимущество над глобальными... То есть, если в программе есть глобальная переменная, а в процедуре еще и локальная с тем же именем, то процедура (по умолчанию, если ты не скажешь ей делать иначе) будет работать именно с локальной.
Теперь о корне зла. Он в том, что в процедуры MnL и MxL передается неправильное значение параметра N (чувствуешь разницу? Не локальной переменной, а параметра). А почему? Потому, что правильное значение N было сформировано в процедуре mas_x (и оно-таки было правильным, проверено)... Вот только изменения не передались в основную программу...
procedure mas_x(n: integer; var x: mas1r_x);
Почему X описан с Var, а N без него? Описываем N как var-параметр (передаем его по ссылке, а не по значению), и будет тебе счастье
Кстати, еще кое-что:
procedure mas_x( var n: integer; var x: mas1r_x); var s: word; begin writeln; writeln('массив, сформиpованный из сумм положительных', ' элементов строк исходного массива'); n := 0; { <--- Внимательно смотри на значение } for i:=1 to m do begin S:=0; for j:=1 to k do begin if a[i,j]>0 then S:=S+a[i,j]; end; n := n + 1; { <--- Сначала увеличиваем индекс, потом заносим элемент !!! } x[n]:=s; writeln(' x[',n,']=',s:3); end; writeln; end;
Спросишь, а какая разница? Простая. Если оставить все, как было, то N вернет значение на 1 больше, чем в массиве X есть элементов, и в результате MnLвсегда будет выдавать 0, ибо будет рассматривать один лишний элемент, равный нулю... При захождении максимума это роли не играет, а вот минимум - проблема...