Программа денесі(операторлар тізбегі)


Көлемді массивтермен жұмыс істеу



бет88/163
Дата07.02.2022
өлшемі4,26 Mb.
#94523
түріПрограмма
1   ...   84   85   86   87   88   89   90   91   ...   163
Байланысты:
cda6b05d-8cb5-11e3-bf6e-f6d299da70eeУММ ПР1

Көлемді массивтермен жұмыс істеу
Алдыңғы тақырыпта айтылғандай LongInt типті 15 мың элементтен тұратын массивті өңдей аламыз, ал 20 мың элементтен тұратын массивті өңдей алмаймыз. Себебі құрылымданған типтер үшін максималды өлшем 65520 байт, ал динамикалық жадының (немесе үйменің) көлемі шамамен 300000 байт. Неге көлемді массивтерді өңдеу үшін осы жады пайдаланылмайды? Дегенмен динамикалық жадыны пайдаланғанда да құрылымданған типтер үшін максималды өлшемге шектеу қойылады (65520 байт). Сондықтан қосымша динамикалық жады бөле отырып (NEW процедурасы арқылы), жай ғана айнымалылырды сипаттау бөлімінде массивті жариялай салу мүмкін емес. Бірақ 65520 байт бөгетті жеңу үшін жады бөліктеріне (немесе блоктарына) типтендірілмеген нұсқауыштар болып табылатын 9 элементтен тұратын массив құруға болады. Мұнда осындай блоктардың әрбіреуі LongInt типті 8000 элементке арналған. (Басқаша айтқанда біз 72 мың элементтен тұратын массивпен жұмыс істеуге тырысамыз – бұл жуық шамамен динамикалық жадының мүмкіндіктеріне сәйкес келеді). Неліктен біздің көлмеді массивімізбің блоктары (8000 элементтен) сақталатын жады бөліктеріне сілтемелер үшін типтендірілмеген нұсқауыштар қолданылады. Себебі типтендірілмеген нұсқауыш нұсқайтын динамикалық айнымалыға жады резервтеу үшін GetMem процедурасы қолданылады. Ал бұл процедураның типтендірілген нұсқауыштар үшін қолданылатын New процедурасынан ерекшелігі резервтелетін жадының көлемін көрсететін параметрге ие. Басқаша айтқанда бұл тәсіл 8000 элементтен тұратын блоктың бірінші элементіне нұсқауышты анықтауға және бір мезгілде блоктың қалған 7999 элементі үшін жады резервтеуге мүмкіндік береді.
Келесі мысалда осындай программа көрсетілген:
Program array2;
Const number=8000; {бір блоктағы элементтер саны}
Type
ab=array[0..8] of longint;
pab=^ab;
Var
Ch:array[0..8] of pointer;
Total, i:longint;
Begin
Total:=number*9; {9 блоктағы элементтерсаны}
Writeln(‘Бос жады=’, MemAvail, ‘; ең үлкен бөлік=’, MaxAvail);
For i:=0 to 8 do
GetMem(ch[i], number*SizeOf(longint)); {жады резервтеу}
For i:=0 to total-1 do
Pab(ch[i div number])^[i mod number]:=i; {реттік номерді меншіктеу}
For i:=0 to total-1 do
If (i mod 1000=0) or (i=total) then
Write(i:10, pab(ch[i div number])^[i mod number]:6);
Writeln;
Writeln(‘Бос жады=’, MemAvail, ‘; ең үлкен бөлік=’, MaxAvail);
Readln;
End.
Мұнда Number тұрақтысы блоктағы элементтердің санын береді. Ch айнымалысы (Ch:array[0..8] of pointer) әр блоктағы бірінші элементтерге нұсқайтын типтендірілмеген нұсқауыштар массивін сипаттайды. Total айнымалысы барлық блоктардағы элементтердің жалпы санын (Total:=Number*9) көрсетеді.
Динамикалық жадыны бөлгенге дейін және бөлгеннен кейін экранға үйменің жалпы бос кеңістігінің және оның ең үлкен үзіліссіз бөлігінің мәні (сәйкесінше MemAvail және MaxAvail функциялары) шығарылады. Сонымен қатар біз өңдейтін массивке динамикалық жады бөлінген:
For i:=0 to 8 do GetMem(ch[i], number*SizeOf(longint))
i айнымалысының мәні жады бөлінетін кезекті блоктың номеріне сәйкес келеді. GetMem процедурасының (типтендірілмеген нұсқауыш үшін динамикалық жады фрагментін резервтейтін) екі параметрі бар. Оның бірінішісі (ch[i]) – блоктың бірінші элементіне арналған динамикалық жады облысына нұсқайтын типтендірілмеген нұсқауыш. Процедураның екінші элементі (number*SizeOf(longint)) динамикалық айнымалының байт бойынша өлшемін анықтайды. Біздің жағдайымызда Number – бұл блоктағы элементтер саны (8000). SizeOf функциясы көрсетілген объектінің ішкі көрсетілімінің ұзындығын береді (LongInt типі үшін – 4 байт). Енді қанша байт жады резервтелетін есептеуге болады – 9 блокты 8000 блок элементіне көбейтіп, содан кейін әрбір элементті 4 байтқа көбейтеміз. Нәтижесі 288 мың байт. MemAvail функциясының программа басында және соңында беретін мәндерінің арасында тура осындай айырмашылық болуы керек.
Ары қарай программа кейбір (цикл параметрінің мәндерін) мәндерді көлемді массивтің әр элементіне бөлінген жады адрестері бойынша орналастырады.
For i:=0 to total-1 do
рab(ch[i div number])^[i mod number]:=i
Бұл оператордың екінші жартысы мұқият зер салуды талап етеді. Бірінші жартысы түсінікті - for i:=0 to total-1 do параметрлі цикл операторы біз жасаған динамикалық жадыдағы тоғыз блокта қамтылған әрбір элементке қатынас жасайды. Бірақ қатынасты қалай жасайды? Оны түсіну үшін төмендегі 3-суретке назар аударайық.

3-суретте көрсетілген программа жолында i mod number өрнегі – блоктағы әр элемент номері. Ch – бұл блоктардың бірінші элементтеріне 9 нұсқауыштан тұратын массив, сондықтан ch[i div number] өрнегі 9 блоктың бірінші элементтеріне қатынасты көрсетеді.


Бірақ әрбір блоктың әр элементіне қалай қатынас жасауға болады? Ол үшін ch массиві (типтендірілмеген нұсқауыштар массиві) Pab типіне келтіріледі (рab(ch[i div number])). Pab – бұл LongInt элементтерінің массивіне нұсқауыш екенін білеміз. Содан кейін бұл нұсқауыштың атауы өзгертіледі (яғни, массивтің өзіне қатынасқа түрлендіріледі) және массив идентификаторын көрсететін (рab(ch[i div number])^) өрнекке ([i mod number]) индексі қосылады. Осылайша, рab(ch[i div number])^[i mod number]:=I өрнегі LongInt типті 72000 (8000*9) элементтен тұратын массивтің әрбір элементіне қатынас жасайды.
Содан кейін экранға массивтің әрбір мыңыншы, сол сияқты соңғы элементтері шығарылды.
For i:=1 to total do
If (I mod 1000=0) or (i:=total-1) then
Write(i:10, pab(ch[I div number])^[I mod number]:6);
Әрине, әрбір элементтің мәні цикл параметрінің і мәнімен бірге шығарылады (бақылау үшін) – бұл мәндер бірдей болуы керек.
Ең соңында, экранға үйменің жалпы бос кеңістігінің және оның ең үлкен үзіліссіз бөлігінің мәні (сәйкесінше MemAvail және MaxAvail функциялары) шығарылады. Мұндай салыстырулар динамикалық жадының ұсынатын мүмкіндіктерін демонстрациялайды. Осы программаның нәтижесі экранда қалай көрінетіні 4-суретте келтірілген. Статикалық жадыны қолданып LongInt типті 15000 элементті массивті ғана өңдеуге болса, динамикалық жадыны қолдана отырып, осындай 72000 элементті қамтитын массивті өңдей алдық. Осы программа динамикалық жадыны бөлдік (GetMem процедурасы арқылы), бірақ соңынан босатқан жоқпыз.

Мәселе мынада: жадыны боосату – мақсат емес. Жадыны тек басқа айнымалыларға қолдану қажет болған кезде ғана босату керек. Біздің жағдайымызда динамикалық жадыны босату қажет мезетте программа өз жұмысын аяқтайды. Ал программаны қайта жүктегенде динамикалық жады бастапқы көлемге қайта ие болады.






Достарыңызбен бөлісу:
1   ...   84   85   86   87   88   89   90   91   ...   163




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет