«Программалау» ПӘнінің ОҚУ-Әдістемелік кешені



бет3/16
Дата21.12.2019
өлшемі1,23 Mb.
#53890
1   2   3   4   5   6   7   8   9   ...   16
Байланысты:
cf272a53-91fd-11e3-8e6b-f6d299da70eeУММ Пр2-2 ШАКАРИМА

Массив және көрсеткіштер


Егер алдыңғы программаны орындасақ, онда келесі түрдегі нәтижені аламыз:

Айнымалылар адресі: 183А 183С 183Е

Айнымалылар мәні: 123 456 2001

Массив атын сілтеме (указатель) ретінде пайдалануға болады. Көрсеткішті индекстеуге болады. Осы кезде келесі әділ:

(u+i)=&(mas[i])

(u+i)=mas[i]

Программада массив аты ретінде u-ды пайдалануға болады.

Бір типті берілгендер жинағымен жұмыс істеу үшін сілтемелер мен массивтерді қолданудың айырмашылығы неде? Программаға массивтің жазылуын енгізе отырып программист автоматты түрде жадыда белгілі бір облыс қалдырады. Егер де массивтердің жазылуының орнына сілтеме қолданылса, онда программистен қосымша жадыны бөлуге мысалы, malloc функциясымен немесе сілтемеге алдын ала бөлінген жады адресін меншіктеуге дәл көрсету талап етіледі.


Массивтер және жолдар


Символдар жолын символдар массив түсінігін пайдаланып немесе сілтемені енгізіп сипаттауға болады. char типті берілгендердің массиві ретінде жолды жариялап, біз оған жады бөлеміз. Жол басының адресін анықтау үшін char типті берілгендерге сілтемені пайдаланып, біз malloc() немесе calloc()-ты пайдаланбайынша жадының бөлінуін талап етпейміз, не сілтемеге алдын ала бар жолдың бастапқы адресін меншіктейміз.
Көпөлшемді массивтер

Көпөлшемді массивтер келесі форматқа сәйкес сипатталады:

тип массив_ аты [1_өлшем][2_өлшем]...[N_өлшем];

Мысал (3x4 өлшемді А матрицасының 4x2 өлшемді В матрицасына көбейтілуі):


# include

main()


{

int a[3] [4]= { {5, 2, -4, 3},

{4, 9, 0, 6},

{7, -1, 8, 3}

};

int b[4] [2]= { {1, -2},



{-3, 4},

{5, -6},


{-7, 8}

};

int c[3] [2], i, j, k;



for (i=0; i<4;i++)

for (j=0; j<2; j++)

{

c[i][j]=0;



for (k=0; k<4;k++)

c[i][j]+=a[i][k]*b[k][j];

};

for (i=0; i<3; i++)



for (j=0; j<2; j++)

printf(“c[%d][%d]=%d\n”, c[i][j]);

}

Индекстелген айнымалылардың келесі индексі алдыңғыға қарағанда “жылдамырақ” алмасады, яғни ЭЕМ-нің жадысында c[3][2] массив элементтері келесі тәртіпте орналасады:



c [0][0] c [0][1] c [1][0] c[1][1] c[2][0] c [2][1]


Массив және функциялар


Массивтің ақиқат (фактически) параметрлері ретінде ішкі программаға (функцияға) беру үшін оның басының адресін көрсету жеткілікті.

Мысал (бүтін санды бірөлшемді массивтің минималды элементінің нөмірін анықтау функциясы):


int min_index (int sp[], int ras)

{

int i, mindx, m;



mindx=0;

m=sp[mindx];

for (i=1; i

if (sp[i]

{

m=sp[i];


mindx=i;

};

return (mindx);



}

Си тілінің ерекшеліктері: компиляторға өңделетін массивтің өлшемі талап етілмейді. Функция мәтінінде массив басының адресін көрсету жеткілікті.

Мысал (min_indx функциясын қарататын программа):

# include

main()

{

# define dlina 150



int k, list[dlina];

for (k=0; k

list [k]=rand ();

k=min_indx (list, dlina);

printf(“list[%3d] = %6d \n”, k, list [k] );

}

Бір өлшемді массивті кездейсоқ бүтін сандармен инициализациялау үшін мына түрдегі функцияны пайдалануға болады



void init (int mas [ ], int ras)

{

int k;



for (k=0; k

mas [k]=rand ( );

}

Егер программаның бір жерінде мына init ( spisok, dlina) түрдегі функцияға көңіл аударсақ (обращение), онда dlina өлшемді мән бір өлшемді spisok массивінің элементтері мән ретінде кездейсоқ шамаларды қабылдайды.



Айталық, Table [7][8] екі өлшемді массив болсын. Егер init функциясын пайдаланып программаға init (Table, 7*8) командасын енгізсек, онда Table екі өлшемді массиві 7*8=56 элементтен тұратын бір өлшемді массив ретінде қабылданады. Бұлэлементтерге кездейсоқ сандар тапсырысшының (датчик) мәндері меншіктеледі.

Функцияларға көп өлшемді массивтерді беруге болады.

Мысал:

void minit (int matrix[ ] [KO], int str)



{

int i, j;

for (i=0; j

for (j=0; j=KO; j++)

matrix[i][j]= rand [ ];

}

Қарастырылған функцияда екі өлшемді массив бағандарының саны белгіленген және KO глобальды айнымалысымен анықталады. Егер KO=8 болса, онда бұл функцияның көмегімен Table массивін minit(Table, 7) командасын беру арқылы өңдеуге болады.



Егер матрица бағандарының сандарын белгілеуден бас тартсақ, яғни KO идентификаторын формальды параметр ретінде пайдалансақ, онда функцияның тақырыбы мына түрде болуы керек:
void minit (int matrix [ ][ ], int stro, int KO ).

Көрсеткіштер (указатели)

Көрсеткіш – бұл идентификаторларды орналастыру үшін үлестірілетін (идентификатор ретінде айнымалының, массивтің, құрылымның, жолдық әріптердің аттары бола алады) жады адресі. Осы жағдайда, егер айнымалы көрсеткіш ретінде жарияланса, онда онда кез келген скалярлы шамасын табуға болатын жады адресі бар. Көрсеткіш типті айнымалыны жариялау кезінде адресі айнымалыда және кезекті (предшествующий) жұлдызшасы (немесе жұлдызшалар тобы) бар көрсеткіш атында болатын мәліметтер объектісінің типін анықтау қажет. Көрсеткіштің жариялану форматы:

тип спецификаторы [модификатор]*түсіндіруші

Тип спецификаторы объектінің типін және кез келген негізгі типін, құрылым, қоспа типін (бұл туралы төменде айтылатын болады) береді. Тип спецификаторының орнына void кілттік сөзін бере отырып, өзгеше түрде көрсеткіш сілтенетін тип спецификациясын кешіктіруге болады. void типіне көрсеткіш ретінде жарияланатын айнымалы кез келген типті объектіге сілтеу үшін пайдаланыла алады. Бірақ та, көрсеткішке немесе өздері көрсететін объектілерге арифметикалық және логикалық операцияларды орындай алу үшін әрбір операцияның орындалуы кезінде объектінің типін дәл анықтау үшін қажет. Типтің бұлай анықталуы типке келтіру операциясының көмегімен орындалуы мүмкін.

Көрсеткішті жариялау кезінде модификатор ретінде const, near, far, huge кілттік сөздері қолданыла алады. const кілттік сөзі көрсеткіш программада өзгермейтінін көрсетеді. Көрсеткіш ретінде жарияланған айнымалының өлшемі компьютердің архитектурасына және пайдаланылатын жады моделіне (ол үшін программа құрастырылады) байланысты. Мәліметтердің әр түрлі типінің көрсеткіштерінің бірдей ұзындықта болуы міндет емес.

Көрсеткіш өлшемін модификациялау үшін const, near, far, huge кілттік сөздерін пайдалануға болады. Мысалдар:

unsigned int *a; /* а айнымалысы типіне (таңбасыз бүтін сандар)

көрсеткіш ретінде көрсетіледі */

double *x; /* x айнымалысы екі еселенген дәлдікпен қалқыма

нүктесі бар мәліметтер типін көрстетеді */

char *fuffer; /* char типті айнымалыны көрсететін көрсеткіш

fuffer атымен жарияланады*/

double nomer;

void *addres;

addres=&nomer;

(double *) addres++;

/* addres айнымалысы кез келген типті объекті үшін көрсеткіш ретінде жарияланған. Сондықтан оған кез келген объектінің адресін меншіктеуге болады (& - адресті есептеу операциясы). Бірақ та, жоғарыда көрсетілгендей өзі көрсететін мәліметтер типі дәл анықталмайынша көрсеткішке бір де бір арифметикалық операция орындалмайды. Мұны addres-ті double типінің көрсеткішіне, ал содан кейін адрестің көбеюіне түрлендіру үшін (double *) типіне келтіру операциясын пайдалана отырып жасауға болады. */

const *dr;

/* dr айнымалысы тұрақты өрнекке көрсеткіш ретінде жарияланған, яғни көрсеткіш мәні программаның орындалу процесінде өзгере алады, ал ол көрсететін шама өзгере алмайды. */

unsigned char *const w=&obj.

/* w айнымалысы char unsigned типті мәліметтерге тұрақты көрсеткіш ретінде жарияланған. Бұл программаның барлық аралығында w жадының тек бір облысына ғана көрсететінін білдіреді. Осы облыстың мазмұны өзгере алады. */

Саналынатын типті айнымалылар


Қандай да бір мәндер тізімінен алынған мәнді қабылдайтын айнымалы саналынатын типті айнымалы деп аталады.

Саналудың жариялануы enum кілттік сөзінен басталады және оның көрсетілуінің екі форматы бар.

Формат 1.enum [саналу тегінің аты]{санлау тізімі}түсіндіруші[,

түсіндіруші …];

Формат 2.enum саналу тегінің аты түсіндіруші [, түсіндіруші …]

Саналудың жариялануы саналатын айнымалының типін береді және саналу тізімі деп аталатын аталған тұрақтылардың тізімін анықтайды. Тізімнің әр атын+ың мәні болып қандай да бір бүтін сан саналады.

Саналатын типті айнымалы тізімнің аталған тұрақтыларының бірінің мәндерін қабылдай алады. Тізімнің аталған (именованные) тұрақтыларының типі int болады. Осылайша саналынатын айнымалыға сәйкес келетін жады бұл int типті мәнді орналастыру үшін қажет.

enum типті айнымалы индексті өрнектерде пайдаланыла алады және операндалар ретінде арифметикалық операцияларда және қатынас операцияларында пайдаланыла алады.

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

Саналу тізімі мына түрдегі бір немесе бірнеше құрылысқа (конструкцияға) ие:

идентификатор [=тұрақты өрнек]

Әрбір идентификатор саналу элементі деп аталатын enum тізіміндегі барлық идентификаторлар өте сирек болуы тиіс. Тұрақты өрнек жоқ болған жағдайда бірінші идентификаторға 0 мәні сәйкес келеді, ал келесі идентификаторға – 1 мәні және т.с.с. Саналу тұрақтысының аты оның мәніне эквивалентті.

Тұрақты өрнекпен байланысқан идентификатор осы тұрақты өрнек беретін мәнді қабылдайды. Тұрақты өрнек int типті болуы керек және ол оң да, теріс те болуы мүмкін. Тізімде келесі идентификаторға плюс 1 тұрақты өрнекке тең мән меншіктеледі, егер осы идентификатордың өзінің тұрақты өрнегі болмаса. Саналу элементтерін пайдалану келесі ережелерге бағынуы керек:


  1. Айнымалыда қайталанатын мәндер болуы мүмкін.

  2. Саналу тізіміндегі идентификаторлар кәдімгі айнымалылар аттарын және саналудың басқа тізімдерінен алынған идентификаторларды қосқандағы сол көріну облысындағы барлық басқа идентификаторлардан өзгеше болуы керек.

  3. Саналу типінің аттары осы көріну облысындағы саналу құрылымдардан (структуралардан) және қоспалар типтерінің аттарынан өзгеше болуы керек.

  4. Мән саналу тізімінің соңғы элементінен кейін болуы мүмкін.

Мысал:

enum week {SUB=0, /* 0 */

VOS=0, /* 0 */

POND, /* 1 */

VTOR, /* 2 */

SRED, /* 3 */

HETV, /* 4 */

PJAT /* 5 */

} rab_ned;

Берілген мысалда сәйкес мәндер жиыны бар week саналымды тегі және week типті rab_ned айнымалысы жарияланған.

2-ші форматта саналу тегінің аты қандай да бір басқа жерде анықталатын саналу типіне сілтеу үшін пайдаланылады. Саналу тегінің аты ағымдағы көріну облысының жарияланған және саналу тізімі жариялау кезінде көрсетілмеген.

Мысал:


enum week rab1

Саналу мәліметтер типінің көрсеткішін жариялау кезінде және typedef деп жарияланатын саналу типтері үшін саналу тегінің атын берілген саналу тегі анықталмай тұрып пайдалнуға болады. Дегенмен, саналуды анықтау typedef жариялау типінің пайдаланылатын көрсеткішінің кез келген әрекетінің алдында болуы керек. Түсіндірушілердің келесі тізімінсіз жариялау тегті немесе саналу шаблонын түсіндіреді.


Массивтер


Массивтер – бұл бірдей типті (double, float, int және т.с.с.) элементтер тобы. Массивтің жариялануынан компилятор массивтің элементтерінің типі туралы және олардың саны туралы ақпарат алуы керек.Массивтің жариялануының екі форматы бар:

Түсіндіруші типтегі спецификатор [тұрақты өрнек];

Түсіндіруші типтегі спецификатор []

Түсіндіруші – бұл массив идентификаторы.

Тип спецификаторы жарияланатын массив элементерінің типін береді. Массив элементтері ретінде функциялар және void типті элементтер бола алмайды.

Квадрат жақшадағы тұрақты өрнек массив элементтерінің санын береді. Массивті жариялау кезіндегі тұрақты өрнек келесі жағдайларда түсіріле алады:



  • жариялау кезінде массив инициализацияланады,

  • массив функцияның формальды параметр ретінде жарияланған,

  • массив басқа файлда дәл анықталған массивке сілтеме ретінде жарияланған.

Си тілінде тек бір өлшемді массивтер анықталған, бірақ массив элементі массив болуы да мүмкін, сондықтан көп өлшемді массивтерді анықтауға болады. Олар массив идентификаторынан кейінгі тұрақты өрнектер тізімінен қалыптасады, сонымен қатар әрбір тұрақты өрнек өздерінің квадрат жақшаларына алынады.

Әрбір квадрат жақша ішіндегі тұрақты өрнек массивтің берілген өлшемі бойынша элементтер санын анықтайды, сондықтан екі өлшемді массивті жариялау екі тұрақты өрнектен тұрады, ал үш өлшемді массивті – үш және т.с.с. Си тілінде массивтің бірінші элементі 0-ге тең индекс болады.

Мысалдар:

int a[2][3]; /* a[0][0] a[0][1] a[0][2] матрица түрінде көрсетілген

a[1][0] a[1][1] a[1][2] */

double b[10]; /* double типті он элементтен тұратын вектор */

int w[3][3]={{2, 3, 4}, {3, 4, 8}, {1, 0, 9}};

Соңғы мысалда w[3][3] массиві жарияланған. Фигуралық жақшаларға алынған тізімдер массивінің жолдарына сәйкес келеді, жақшалар жоқ болған жағдайда инициализация дұрыс орындалмайды.

Си тілінде басқа жоғары деңгейдегі тілдердегі (PL1 және т.с.с.) сияқты массив қималарын пайдалануға болады, дегенмен қималарды пайдалануға бірқатар шектеулер қойылады. Қима квадрат жақшалардың бір немесе бірнеше жұптарын алып тастау салдарынан қалыптасады. Квадрат жақшалар жұптарын тек оңнан солға қарай және қатаң жүйелі түрде алып тастауға болады. Массив қималары Си тілінің қолданушылар жасайтын функцияларда есептеу процесін ұйымдастыру кезінде пайдаланылады.

Мысалдар:

int s[2][3];

Егер қандай да бір функцияға қараған кезде s[0] деп жазсақ, онда s массивінің нөлдік жолы беріле бастайды.

int b[2 ][3][4];

b массивіне қарап, мысалы, b[1][2] деп жазуға болады және төрт элементтен тұратын вектор беріле бастайды, ал b[1] өлшемі үш те төрт болатын екі өлшемді массивті береді. Вектор беріледі деп түсініп b[2][4] деп жазуға болмайды, өйткені массив қималарын пайдалануға қойылған шектеулерге сәйкес келмейді.

Символдық массивті жариялауға мысал.

char str[]=”символдық массивті жариялау “;

Символдық литералда бір элементке көп табылатынын есеп ке алу керек, өйткені элементтердің соңғысы ‘\0’ басқарушы тізбек болып табылады.
Дәріс №7

Тақырыбы: Құрылымдар.

Мақсаты: Құрылым типін жариялау, құрылым тегтері, біріктірулер, биттер өрісі ұғымдарын енгізу.
Құрылымдар (Структуралар)

Құрылымдар – бұл функцияларды қоспағандағы кез келген типтің элементтері кіретін құрама объект. Біртекті объекті болып табылатын массивтен айырмашылығы құрылымдар біртекті емес бола алады. Құрылым типі мына түрдегі жазумен анықталады:

struct {анықтамалар тізімі}

Құрылымда міндетті түрде ең болмағанда бір компонент көрсетілуі тиіс. Құрылымды анықтау келесі түрде болады:

мәліметтер типі түсіндіруші;

Мұндағы мәліметтер типі түсіндірушіде анықталатын объектілер үшін құрылым типін көрсетеді. Қарапайым формада түсіндірушілер идентификаторлар немесе массивтер түрінде болады.

Мысал:

struct {double x,y;} s1,s2,sm[9];



struct {int year;

char moth,day; } date1;date2;

s1,s2 айнымалылары құрылымдар ретінде анықталады, олардың әрқайсысы x және y екі компонентінен тұрады. sm айнымалысы тоғыз құрылымнан тұратын массив ретінде анықталады. date1, date2 айнымалыларының әрқайсысы year, moth,day, >p> үш компоненттен тұрады. Атауды құрылым типімен ассоциациялаудың басқа тәсілі де бар, ол құрылым тегін пайдалануға негізделген. Құрылым тегі саналымды тип тегіне ұқсас. Құрылым тегі келесі үлгіде анықталады:

struct тег {түсіндірме тізімі (список описаний);};

мұндағы тег идентификатор болып табылады.

Төменде көрсетілген мысалда student идентификаторы құрылым тегі ретінде жазылады:

struct student {char name[25];

int id, age;

char prp; };

Құрылым тегі берілген түрдің құрылымының кезекті жариялануы үшін мына формада пайдаланылады:

struct тег идентификаторлар тізімі;

Мысал: student st1, st2;

Құрылымның тегтерін пайдалану рекурсивті құрылымдарды жазу үшін қажет. Төменде құрылымның рекурсивті тегтерін пайдалну қарастырылады.

struct node {int data;

struct node *next; } st1_node;

Құрылым тегі node шынында рекурсивті, себебі ол өзінің жеке жазылуында пайдаланылады, яғни next көрсеткішінің құрылуында. Құрылымдар рекурсивті бола алмайды, яғни node құрылымында node құрылымы болатын компонент болмауы керек, бірақ кез келген құрылымда келтірілген мысалда жасалғандай өз типіне көрсеткіш болатын компонент бола алады.

Құрылым компоненттеріне құрылым атын көрсету арқылы және келесі нүкте арқылы компоненттің атын белгіленген көрсету арқылы жол ашылады. Мысалға:

st1.name=”Мұхаметжанова “;

st2.id=st1.id;

st1_node.data=st1.age



Біріктіру (қоспаларды)

Біріктіру құрылымға ұқсас, бірақ әрбір уақыт мезгілінде тек біріктіру элементтерінің біреуі пайдаланыла алады (немесе басқа сөзбен айтқанда жауапты болу). Біріктіру типі келесі түрде беріле алады:

union {1 элементтің жазылуы;

n элементтің жазылуы; };



Біріктірудің басты ерекшелігі жарияланған әрбір элемент үшін жадының бір облысы бөлінгендігі, яғни олар қайта жабылады (перекрываются). Дегенмен, жадының осы облысына элементтердің кез келгенін пайдалану мүмкіндігі бар, бұл мақсат үшін элемент алынған нәтиже мағынасыз болмайтындай етіп таңдалуы керек.

Біріктіру элементтеріне құрылымдар жүзеге асырылатын тәсілдер арқылы мүмкіндік бар. Біріктіру тегі құрылым тегі сияқты құрылады.

Біріктіру келесі мақсаттар үшін қолданылады:


  • жадының пайдаланылатын объектісінің инициализациясы, егер әрбір уақыт мезгілінде көп объектілердің ішіндегі тек біреуі белсенді болса;

  • бір типті объектінің негізгі көрінісінің интерпретациясы, егер осы объектіге басқа тип меншіктелсе.

Біріктіру типті айнымалыға сәйкес келетін жады біріктірудің ең ұзын элементін орналастыру үшін қажет шамамен анықталады. Ұзындығы қысқа элемент пайдаланылса, онда біріктіру типті айнымалыларда пайдаланылмаған жады болады. Біріктірудің барлық элементтері жадының бір адрестен бастап бір ғана облысында сақталады.

Мысал:


union { char fio[30];

char address[80];

int vozrast;

int telefon; } inform;

union { int ax;

char al[2]; } ua;

union типті infor объектісін пайдалану кезінде тек мән алған элементті ғана өңдеуге болады, яғни inform.fio элементіне мән меншіктелгеннен кейін басқа элементтерге мән берудің мағынасы жоқ. ua біріктіруі ua.ax екі байтты санның кіші ua.al[0]-ге және үлкен ua.al[1] байттарына жеке жол ашуға мүмкіндік береді.

Биттер өрісі

Құрылымның элементі жадының жеке биттеріне жолды ашатын биттік өріс болуы мүмкін. Құрылымнан тыс биттік өрістерді жариялауға болмайды. Сонымен қатар биттік өрістердің массивін ұйымдастыруға және өрістерге адресті анықтау операциясын қолдануға болмайды. Жалпы жағдайда биттік өрісі бар құрылым типі келесі түрде беріледі:

struct {unsigned идентификатор1: 1-өрістің ұзындығы;

unsigned идентификатор2: 2-өрістің ұзындығы; }

өрістің ұзындығы бүтін өрнекпен немесе тұрақтымен беріледі. Бұл тұрақты сәйкес өріске бөлінген биттер санын анықтайды. Нөлдік ұзындықтың өрісі келесі сөздің шекараға теңестірілуін білдіреді.

Мысал:

struct {unsigned a1: 1;

unsigned a2: 2;

unsigned a3: 5;

unsigned a4: 2; }prim;

Биттік өрістердің құрылымында таңбалы компоненттер де болуы мүмкін. Мұндай компоненттер автоматты сөздердің сәйкес шекараларына орналасады, сонымен қатар сөздердің кейбір биттері пайдаланылмай қалуы мүмкін.

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



Достарыңызбен бөлісу:
1   2   3   4   5   6   7   8   9   ...   16




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

    Басты бет