Бұл мысал оператор-1 мен оператор-2-нің орнында күрделі конструкциялар болуын бейнелейді. if-тің кірістірілген операторларын пайдалануға болады. if операторы if конструкциясына немесе if-тің басқа операторларының else конструкциясына енгізілуі мүмкін. Программаның жеңіл оқылуы үшін фигуралық жақшаларды пайдалану if-тің кірістірілген операторларындағы операторлар мен конструкцияларды топтастыру ұсынылады. Егер де фигуралық жақшалар жоқ болса, онда компилятор әрбір else кілттік сөзін неғұрлым жақын else-сі жоқ if-пен байланыстырады. Мысалдар:
Бұл программаның орындалу нәтижесінде r 2-ге тең болады.
else ...
switch операторы әр түрлі варианттар жиынынан алынған таңдауды ұйымдастыру үшін арналған. Оператордың форматы келесі түрде:
switch кілттік сөзінен кейінгі дөңгелек жақшаға алынған өрнек мәні бүтін Си тілінде мүмкін болатын кез келген өрнек бола алады.
Бұл өрнектің мәні бірнеше варианттан таңдау үшін кілттік (ключевой) болып табылады. switch операторының денесі кезекті тұрақты өрнегі бар case кілттік сөзімен белгіленген бірнеше операторлардан тұрады. Бүтін тұрақты өрнекті пайдалану қарастырылған операторға тән маңызды жетіспеушілік болып табылады.
Тұрақты өрнек трансляция мезетінде есептелетіндіктен онда айнымалылар немесе функцияның шақырулары болмайды. Әдетте тұрақты өрнек ретінде бүтін немесе символдық тұрақтылар пайдаланылады.
switch операторындағы барлық тұрақты өрнектер өте сирек болуы керек. case кілттік сөзімен белгіленген операторлардан басқа default кілттік сөзімен белгіленген жалғыз бір фрагмент болуы мүмкін. Сонымен қатар switch операторында операторлар тізбегін фигуралық жақшаға алу міндетті емес.
switch операторында сонымен қатар жариялануы case-тің бірінші кілттік сөзінің алдында болатын өзінің локальды айнымалыларын пайдалануға болады, бірақ жариялануда инициализация пайдаланылмау керек.
switch операторының орындалуы case2 деп белгіленген оператордан басталады. Осылайша i айнымалысы алтыға тең мәнді қабылдайды, әрі қарай case0 кілттік сөзімен белгіленген оператор орындалады, ал содан кейін case4, i айнымалысы үш мәнін, ал содан кейін екі мәнін қабылдайды. default кілттік сөзімен белгіленген оператор айнымалының мәнін өзгертпейді.
break операторын пайдалану қажетті мезетте switch операторының денесіндегі орындалатын оператрлар тізбегін switch операторынан кейінгі операторға беру арқылы үзуге (прервать) мүмкіндік береді.
break операторы оны біріктіретін switch, do, for, while операторларының ең ішкі орындалуының тоқтатылуын қамтамасыз етеді. break орындалғаннан кейін басқару келесі операторға беріледі.
for операторы – бұл циклды ұйымдастырудың ортақ әдісі. Оның форматы келесідей:
өрнек1 әдетте циклды басқаратын айнымалылардың бастапқы мәндерін бекіту үшін пайдаланылады. өрнек2 – бұл шартты анықтайтын өрнек. Бұл шарт кезінде цикл денесі орындалады. өрнек3 цикл денесінің әрбір орындалуынан кейін циклды басқаратын айнымалылардың өзгеруін анықтайды.
1.өрнек1 есептеледі.
2.өрнек2 есептеледі.
3. Егер өрнек2-нің мәндері нөлден айрықша (ақиқат) болса цикл денесі орындалады, өрнек3 есептеледі және 2-ші пунктке көшу орындалады, егер өрнек2 нөлге тең (жалған) болса, онда басқару for операторынан кейінгі операторға беріледі.
Шарттың тексерілуі циклдың басында орындалады. Бұл егер орындалу шарты жалған болса, цикл денесі бір де бір рет орындалмайтынын білдіреді.
Бұл мысалда 1-ден 9-ға дейінгі сандар квадраты есептеледі. for операторының пайдаланылуының кейбір варианттары циклды басқаратын бірнеше айнымалыларды пайдалану мүмкіндігінің есебінен оның икемділігі артады. Мысал:
Бұл символдар жолын кері тәртіпте жазатын мысалда циклды басқару үшін top және bot екі айнымалысы пайдаланылады. Мұнда өрнек1 мен өрнек3-тің орнына үтір арқылы жазылған және тізбек түрінде орындалатын бірнеше өрнектер пайдаланылады.
for операторын пайдаланудың басқа варианты болып шексіз цикл саналады. Мұндай циклды ұйымдастыру үшін бос шартты өрнекті пайдалануға болады, ал циклдан шығу үшін әдетте осылайша шартты және break операторын пайдаланады.
Си тілінің синтаксисіне сәйкес нөл бос бола алады, сонымен бірге for операторының денесі де бос болуы мүмкін. Оператордың мұндай формасы іздеуді ұйымдастыру ‡шін пайдаланыла алады. Мысал:
Берілген мысалда циклдің i айнымалысы мәні оннан үлкен болатын t массивінің бірінші элементінің нөмірінің мәнін қабылдайды.
Циклдың while операторы шарты алдын ала берілген цикл деп аталады және оның формасы келесідей:
өрнек ретінде Си тілінің кез келген өрнегін, ал оператордың денесі ретінде кез келген оператор (бос немесе құрама) пайдалануға болады. while операторының орындалу схемасы келесідей:
1. өрнек есептеледі.
2. Егер өрнек жалғанболса, онда while операторы аяқталады және рет
бойынша келесі оператор орындалады.
3. Процесс 1-пункттан бастап қайталанады.
for операторының орындалуы кезіндегі сияқты while операторында да шартты тексеру орындалады. Сондықтан while операторын оператор денесін әрқашан орындамаған жағдайларда пайдаланған ыңғайлы. for және while операторларының ішінде сәйкес типтердің анықтамасы жариялалантын локальды айнымалыларды пайдалануға болады.
do while циклының операторы бос цикло ператоры деп аталады және цикл денесі ең болмағанда бір рет орындау қажет болған жағдайларда пайдаланылады. Оператордың форматы келесі түрде болады:
1. Цикл денесі орындалады (ол құрама операторболуы мүмкін).
2. өрнек орындалады.
3. Егер өрнек жалған болса, онда do while операторының орындалуы аяқталады да келесі кезекті оператор орындалады. Егер өрнек ақиқат болса, онда оператордың орындалуы 1-пункттан бастап жалғасады. Шарт жалған болғанға дейін циклдың орындалуын тоқтату үшін break операторын пайдалануға болады. while және do while операторлары кірістіріліген болуы мүмкін. Мысал:
...
continue операторы break операторы сияқты тек цикл операторларының ішінде пайдаланылады, бірақ одан айырмашылығы программаның орындалуы тоқтатылған оператордан кейінгі оператордан емес, тоқтатылған оператордың басынан жалғасады. Оператордың форматы келесідей:
1-ден а-ға дейінгі сандардың қосындысы тақ болған кезде continue операторы басқаруды жұп қосындылардың өңделу (обработка) операторларын орындамай for циклының кезекті итерациясына береді. continue операторы break операторы сияқты оның көлемді циклдарының ішкісін үзеді.
return операторы
return операторы берілген функцияның орындалуын аяқтайды және басқаруды шақырылатын функцияға, яғни шақырудан кейінгі нүктеге қайтарады. main функциясы басқаруды операциялық жүйеге береді. Оператор форматы: return [өрнек];
өрнек мәні, егер ол берілсе шақырылатын функцияның мәні ретінде қайтарылады. Егер өрнек жоқ болса, онда қайтарылатын мән анықталмайды. өрнек дөңгелек жақшаларға алынуы мүмкін,бірақ жақшалардың болуы міндетті емес.
Егер қандай да бір функцияда return операторы жоқ болса, онда басқарудың шақырылатын функцияға берілісі шақырылатын функцияның соңғы операторы орындалмағаннан кейін жүреді. Мұнда қайтарылатын мәнанықталмаған. Егер функцияның қайтарылатын мәні болмаса, онда оны void типімен жариялау керек. Осылайша return операторның пайланылуы не функциядан дереу шығу үшін, не қайтарылатын мәннің берілісі үшін қажет. Мысал:
sum функциясының екі int типті формальды a және b параметрлері бар және функция атының алдында тұрған сипаттаушы (описатель) жазатын int типті мәнді қайтарады. return операторымен қайтарылатын мән ақиқат параметрлердің қосындысына тең. Мысал:
void prov (int a, double b)
goto шартсыз көшу операторын Ситілінде программалау практикасында пайдалану аса міндетті емес, себебі ол программаның түсінілуін және олардың модификациялану мүмкіндігін қиындатады.
түріндегі оператормен жазылады. Программаның мысалы:
Индекстелген айнымалылардың келесі индексі алдыңғыға қарағанда “жылдамырақ” алмасады, яғни ЭЕМ-нің жадысында c[3][2] массив элементтері келесі тәртіпте орналасады:
Мысал (бүтін санды бірөлшемді массивтің минималды элементінің нөмірін анықтау функциясы):
Си тілінің ерекшеліктері: компиляторға өңделетін массивтің өлшемі талап етілмейді. Функция мәтінінде массив басының адресін көрсету жеткілікті.
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 тұрақты өрнекке тең мән меншіктеледі, егер осы идентификатордың өзінің тұрақты өрнегі болмаса. Саналу элементтерін пайдалану келесі ережелерге бағынуы керек:
Айнымалыда қайталанатын мәндер болуы мүмкін.
Саналу тізіміндегі идентификаторлар кәдімгі айнымалылар аттарын және саналудың басқа тізімдерінен алынған идентификаторларды қосқандағы сол көріну облысындағы барлық басқа идентификаторлардан өзгеше болуы керек.
Саналу типінің аттары осы көріну облысындағы саналу құрылымдардан (структуралардан) және қоспалар типтерінің аттарынан өзгеше болуы керек.
Мән саналу тізімінің соңғы элементінен кейін болуы мүмкін.
Мысал:
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;
Биттік өрістердің құрылымында таңбалы компоненттер де болуы мүмкін. Мұндай компоненттер автоматты сөздердің сәйкес шекараларына орналасады, сонымен қатар сөздердің кейбір биттері пайдаланылмай қалуы мүмкін.
Биттер өрісіне сілтеме жалпы құрылым компоненттері орындалған сияқты тура солай орындалады. Ал биттік өрістің өзі максималды мәні өрістің ұзындығымен анықталатын бүтін сан ретінде қарастырылады.
Құрылымы өзгеретін айнымалылар
Программаның кейбір объектілері өте жиі кейбір бөлшектерімен ғана өзгешеленетін бір ғана класқа жатады. Мысалға геометриялық фигуралардың көрінісін қарастырамыз. Фигуралар туралы жалпы ақпарат аудан, периметр сияқты элементтер туралы болуы мүмкін. Дегенмен, сәйкес геометриялық өлшемдер туралы ақпарат олардың формасына байланысты әр түрлі болуы мүмкін.
Геометриялық фигуралар туралы ақпарат құрылым мен біріктіруді қиыстырып пайдалану негізінде көрсетілетін мысалды қарастырамыз.
struct figure {
double area, perimetr; /* жалпы компоненттер */
int type; /* компонент белгісі */
union /* компоненттердің саналуы */
{ double radius; /* шеңбер */
double a[2]; /* тікбұрыш*/
double b[3];/* үшбұрыш*/
} geom_fig;
} fig1, fig2;
Жалпы жағдайда figure типті әрбір объект үш компоненттен тұратын болады: area, perimetr, type. type компоненті белсенді компоненттің белгісі (метка) деп аталады, өйткені ол geom_fig біріктіру компоненттерінің қайсысы берілген мезгілде белсенді екенін көрсету үшін пайдаланылады. Мұндай құрылым айнымалы құрылым деп аталады, өйткені оның компоненттері белсенді компоненттің белгісінің мәніне байланысты өзгеріп отырады (мәні type). int типті type компонентінің орнына саналынатын типті пайдаланған жөн. Мысалы, мынандай
enum figure_chess {CIRCLE,
BOX,
TRIANGLE };
CIRCLE, BOX, TRIANGLE тұрақтылары сәйкесінше 0, 1, 2—ге тең мәндерді қабылдайды. type айнымалысы саналынатын тип ретінде жариялана алады:
enum figure_chess type;
Бұл жағдайда Си компиляторы программиске потенциалды қате меншіктеулер жөнінде ескерту жасайды. Мысалға,
figure.type=40;
Жалпы жағдайда құрылым айнымалысы үш бөліктен тұратын болады: ортақ компоненттер жиынтығы, белсенді компоненттің белгілері және компоненттері өзгеріп отыратын бөліктер. Құрылым айнымалысының жалпы формасы келесі түрде болады:
struct {ортақ компиляторлар;
белсенді компилятордың белгісі;
union {1-компилятордың жазылуы;
2-компилятордың жазылуы;
…
…
n-компилятордың жазылуы;
} біріктіру идентификаторы
} құрылым идентификаторы;
Аты helth_record болатын құрылым айнымалысы анықтауға мысал
struct {/* жалпы ақпарат */
char name [25]; /* аты */
int age; /* жасы */
char sex; /* жынысы */
/* белсенді компилятор белгісі */
/* (отбасы жағдайы)*/
enum merital_status ins;
/* айнымалы бөлік */
union {/* бойдақ */
/* компиляторлар жоқ */
struct {/* некелескен */
char marripge_date [8];
char spouse name [25];
int no_children;
} marriage_info;
/* айрылысқан */
char date_divorced [8];
}marital_info;
}health_record;
enum marital_status {SINGLE, /* бойдақ */
MARRIGO, /* үйленген */
DIVOREED /* айрылысқан */
};
Құрылым компьютерлеріне сілтемелер көмегімен қарауға болады:
helth_record.name,
helth_record.ins,
helth_record.marriage_info.marriage_date.
Дәріс №8
Тақырыбы: Объектілер мен типтерді анықтау.
Мақсаты: С++ тілінде жарияланған айнымалының типі, тип спецификаторы, идентификатор, модификаторы бар идентификатор комбинациясы, ұғымдарын енгізу.
Жоғарыда айтылғандай, Си тілінде жазылған программаларда пайдаланылатын барлық айнымалылар жариялануы тиіс. Жарияланатын айнымалының типі типтің спецификаторы ретінде қай кілттік сөз пайдаланылатынына және түсіндіруші қарапайым идентификатор немесе модификаторы бар идентификатор комбинациясы, массив (квадрат жақшалар) немесе функциялар ма, соған байланысты.
Қарапайым айнымалыны, құрылымдарды қоспаларды немесе біріктірулерді, сонымен қатар саналуларды жариялау кезінде түсіндіруші – бұл қарапайым идентификатор. Көрсеткішті, массивті немесе функцияларды жариялау үшін идентификатор мына үлгіде өзгереді: сол жағында жұлдызша, оң жағында квадрат немесе дөңгелек жақшалар.
Си тілінің маңызды ерекшелігі мынада: жариялау кезінде әр түрлі күрделі типтер түсіндірушілер жиынын құруға мүмкіндік беретін модификаторды бір мезгілде бірнеше рет пайдалануға болады.
Дегенмен, модификаторлардың кейбір комбинациялары мүмкін емес екенін есте ұстау керек:
функциялар массив элементтері бола алмайды,
функциялар массивтерді немесе функцияларды қайтара аламайды.
Күрделі түсіндірушілерді инициализациялау кезінде квадраттық және дөңгелек жақшалар (идентификатордың оң жағындағы) жұлдызшаларға қарағанда басымырақ (идентификатордың сол жағынан). Квадраттық немесе дөңгелек жақшалардың басымдығы бірдей және солдан оңға қарай ашылады. Тип спецификаторы түсіндіруші толығымен талданып болған кезде соңғы қадамда қарастырылады. Дөңгелек жақшаларды талдау тәртібін қажеттіге ауыстыру үшін пайдалануға болады.
Күрделі түсіндірмелерді талдау үшін “іштен сыртқа” (изнутри наружу) деп естілетін және төрт қадамнан тұратын қарапайым ереже ұсынылады.
Идентификаторын бастау керек және квадраттық немесе дөңгелек жақшалар бар ма сол үшін оңға қарау керек.
Егер олар бар болса, онда түсіндірушінің осы бөлігін талдап және содан кейін жұлдызшаны іздеу үшін солға қарау керек.
Егер кез келген кезеңде оң жақтан жабатын дөңгелек жақша кездессе, онда басында барлық осы ережелерді дөңгелек жақшалардың ішінде қолдану қажет, содан кейін барып талдауды жалғастыру керек.
Тип спецификаторын талдау керек.
Мысалдар:
int * ( * comp[10]) ( );
6 5 3 1 2 4
Берілген мысалда comp (1) айнымалысы функцияны (4) көрсететін он (2) көрсеткіштен тұратын массив ретінде және бүтін мәндерге (6) қайтаратын көрсеткіштер жарияланған.
char * ( * ( * var ) ( ) ) [10];
7 6 4 2 1 3 5
var (1) айнымалысы char типті мәндерге көрсеткіш (6) болатын он элементтен тұратын массивке (5) көрсеткішті қайтаратын функцияға көрсеткіш ретінде жарияланады.
Әр түрлі типті айнымалыларды жариялаудан басқа типтерді жариялау мүмкіндігі бар. Мұны екі тәсілмен істеуге болады.
Бірінші тәсіл – құрылымдарды, біріктірулерді немесе саналуларды жариялау кезінде тег атын көрсету керек, ал содан кейін осы атты осы тегке сілтеме ретінде айнымалылар мен функцияларды жариялау кезінде пайдалану.
Екінші тәсіл – типті жариялау үшін typedef кілттік сөзін пайдалану.
typedef кілттік сөзімен жариялаған кезде жазылатын (баяндалатын) объектінің орнында тұрған идентификатор талдауға кіретін мәліметтер типінің аты болып табылатын және әрі қарай бұл тип айнымалыларды жариялау үшін пайдаланылуы мүмкін.
Кез келген тип көрсеткіш, функциялар немесе массивтер типтерін қосқандағы typedef кілттік сөзін пайдаланып жариялана алады. Көрсеткіш, құрылымдар, біріктірулер типтері үшін typedef кілттік сөзі бар ат осы типтер анықталғанға дейін жариялануы керек, бірақ жариялаушының көріну аралығында .
Мысалдар:
typedef double (* MATH) ();
/* MATH – double типті мәнді қайтаратын функцияға
көрсеткіш болатын типтің жаңа аты*/
MATH cos;
/* cos double типті мәнді қайтаратын функцияға көрсеткіш */
/* Эквивалентті жариялау жүргізуге болады */
double (*cos) ( );
typedef char FIO[40]
/* FIO – 40 символдан тұратын массив */
FIO person;
/* person айнымалысы 40 символдан тұратын массив */
/* Бұл жариялауға эквивалентті */
char person[40];
Айнымалылар мен типтерді жариялау кезінде мұнда тип (MATH FIO) атттары пайдаланылды. Бұдан басқа тип аттары тағы да үш жағдайда пайдаланыла алады: формалды параметрлер тізімінде, функцияларды жариялау кезінде, типтерді келтіру операцияларында және sizeof (типтің келтіру операциясы) операциясында.
Негізгі типтер, саналу, құрылым және қоспа типтері үшін тип аттары болып осы типтер үшін тип спецификаторы табылады. Массив және функция көрсеткішінің типтері үшін тип аттары келесі түрде абстрактылы түсіндірушілер көмегімен беріледі:
тип спецификаторы абстарктылы түсіндіруші;
Абстрактылы түсіндіруші – бұл бір немесе бірнеше көрсеткіш, массив модификаторларынан тұратын идентификаторсыз түсіндіруші. Көрсеткіш модификаторы (*) әрқашан түсіндірушідегі идентификатордың алдында беріледі, ал массив [ ]және функциялар ( ) модификаторлары – содан кейін. Осылайша абстрактылы түсіндірушіні дұрыс талдау үшін талдауды жобаланған идентификатордан бастау керек.
Абстрактылы түсіндірушілер күрделі болуы мүмкін. Күрделі абстрактылы түсіндірушілердегі жақшалар жариялауда күрделі түсіндірушілерді талдау кезінде жасаған сияқты талдау тәртібін береді.
Мәліметтердің инициализациялануы.
Айнымалыны жариялау кезінде оған бастаушыны (инициатор) түсіндірушіге қоса отырып бастапқы мәнді меншіктеуге болады. Бастаушы “=” таңбасынан басталады және келесі формаларға ие.
Формат 1:=бастаушы;
Формат 2:= {бастаушылар тізімі};
Формат1 негізгі типтер мен көрсеткіш айнымалыларын инициализациялау кезінде пайдаланылады, ал формат2 – құрама объектілердің инициализациясы кезінде.
Мысалдар:
char tol=’N’;
tol айнымалысы ‘N’символымен инициализацияланады.
const long megabute=(1024*1024);
Модификацияланбайтын megabute айнымалысы тұрақты өрнекпен инициализацияланады, осыдан кейін ол өзгере алмайды.
static int b[2][2]={1,2,3,4};
Бүтін шамалардың екі өлшемді b массиві инициализациланады, массив элементтеріне тізімнен мәндер меншіктеледі. Осы инициализация келесі түрде орындалуы мүмкін:
static int b[2][2]={{1,2},{3,4}};
Массивті инициализациялау кезінде бір немесе бірнеше өлшемдіктерді (размерность) алып тастауға болады
static int b[3[ ]={{1,2},{3,4}};
Егер инициализация кезінде жол үшін аз мән көрсетілсе, онда қалған элементтер нөлге инициализацияланады, яғни жазылу кезінде
static int b[2][2]={{1,2},{3}};
Бірінші жолдың элементтері 1 және 2 деген мәндерді, ал екінші жолдың элементтері 3 және 0 мәндерін алады.
Құрама объектілерді инициализациялау кезінде жақшаның және инициализаторлар тізімінің пайдаланылуын қатаң қадағалау керек. Мысалдар:
struct complex {double real;
double imag; } comp [2][3]=
{{{1,1}, {2,3}, {4,5}},
{{6,7}, {8,9}, {10,11}}};
Берілген мысалда comp екі жолдан және үш бағаннан тұратын құрылымдар массиві инициализацияланады, мұндағы әрбір құрылым real және imag екі элементінен тұрады.
struct complex 2 [2][3]=
{{1,1}, {2,3}, {4,5}, {6,7}, {8,9}, {10,11}};
Бұл мысалда компилятор қарастырылатын фигуралық жақшаларды келесі түрде талдайды:
бірінші сол жақ фигуралық жақша – comp2 массиві үшін құрама бастаушының басы.
екінші сол жақ фигуралық жақша - comp2[0] массивінің бірінші жолының инициализациялануының басы. 1,1 мәндері бірінші құрылымның екі элементіне меншіктеледі;
бірінші оң жақ жақша (1-ден кейін) бастаушылар тізімі массив жолы үшін аяқталғанын компиляторға нұсқайды және comp[0] жолындағы қалған құрылымдардың элементтері автоматты түрде нөлмен инициализациаланады;
алдыңғыға ұқсас {2,3} тізімі comp[1] жолында бірінші құрылымды инициализациялайды, ал массивтің қалған құрылымдары нөлге айналады;
{4,5} инициализаторлардың келесі тізіміне компилятор мүмкін қателер туралы хабарлайды, өйткені copm2 массивінде үшінші жол жоқ.
Біріктіруді инициализациялау кезінде біріктірудің оның типіне сәйкес бірінші элементінің мәні беріледі.
Мысал:
union tab {unsigned char name[10];
int tab1;
} pers={‘С’, ‘А’, ‘Л’, ‘Е’, ‘М’};
pers.name айнымалысы инициализацияланады және бұл массив болғандықтан оның инициализациялануы үшін фигуралық жақшаға алынған мәндермен, ал қалғандары нөлмен инициализацияланады.
Символдар массивінің инициализациялануын жолдық литералды пайдалану жолымен орындауға болады.
char stroka[]=”привет “;
Жеті элементтен тұратын символдар массиві инициализацияланады, оның соңғы элементі (жетінші) барлық жолдық литералдар аяқталатын ‘\0’ символы болады.
Егер массив өлшемі берілсе, ал жолдық ле\итерал массив өлшеміне қарағанда ұзынырақ болса, онда артық символдар алынып тасталады.
Келесі жариялау stroka айнымалысын жеті элементтен тұратын массив ретінде инициализациялайды.
char stroka[5]=”привет”;
stroka айнымалысына литералдың алғашқы бес элементі түседі, ал ‘T’ және ‘\0’ символдары алынып тасталады.
Егер жол массив өлшеміне қарағанда қысқа болса, онда массивтің қалған элементтері нөлмен толтырылады.
tab типті айнымалының инициализациялануы келесі түрде бола алатынын ескерейік:
union tab pers1=”Айман “;
және осылайша символдық массивке символдар түседі:
‘А’, ‘Й’, ‘М’, ‘А’, ‘Н’, ‘\0’,
ал қалған элементтер нөлмен инициализацияланады.
Дәріс №9
Тақырыбы: С++ тіліндегі файлдар.
Мақсаты: С++ тілінде файлдардан енгізу, файлдарға шығару, файлдарға жазбаларды толықтыруды ұйымдастыру ұғымдарын енгізу.
Файл – сыртқы жинақтауыштарда орналасып, өңдеу процессінде және сілтеме кезінде тұтас болып қарастырылатын мәліметтер жиынтығы.
Жұмыс істемес бұрын оған қол жеткізу үшін файлды ашу керек, яғни файл туралы информация дан тұратын мәліметтер облысын жасап, инициализациялау керек.
Си алгоритмдік тілінде оны fopen функциясы атқарады. Ол жинақтауыштағы физикалық файлды программадағы логикалық атымен байланыстырады. Логикалық аты – бұл файлға, яғни файл туралы ақпарат орналасқан жады облысына көрсеткіш. Файлдарға көрсеткіштерді жариялау керек. Мұндай көрсеткіштің форматы келесідей:
FILE * файлға көрсеткіш;
Мысал:
FILE *f;
f=fopen(“B:\BC.CPP”, “w”);
“w” символы ашылатын файлға қол жеткізу құқығын анықтайды. Осы мысалда В: дискісіндегі BC.CPP файлы тек қана оқу ашылады.
Си тілінде ашылатын файлдарға қол жеткізу режимдерін орнататын келесі кодтар қолданылады:
Символ
|
Сипатталуы
|
R
|
Файл тек оқу үшін ашылады, егер дискіде файл болмаса қателік туады.
|
W
|
Файл тек жазуға ашылады. Егер осы атаумен берілген файл болмаса, жасалады. Егер осы атаумен файл бар болса ашылмас бұрын ол файлдағы ақпарат өшіріледі.
|
A
|
Файл соңына ақпарат толықтырылуға ашылады.
|
r+
|
Файл ондағы мәліметтерді редакртрлеуге ашылады. Файлды жазуға да, оқуға да болады.
|
w+
|
r+ режиміндегідей.
|
a+
|
А режиміндегідей, тек жазбаны файлдың кез-келген орнына жазуға болады. Файлды оқуға да болады.
|
T
|
Файл текстік режимде ашылады. r, w,a,r+,w+,a+ өрістері көрсетіледі.
|
B
|
Файд екілік режимде ашылады. . r, w,a,r+,w+,a+ өрістері көрсетіледі.
|
Үнсіз келісім бойынша файл текстік режимде ашылады. Си тілінде файлды жабу үшін fclose функциясы пайдаланылады. Олдыңғы мысалдарғы файл fclose(f) функциясымен жабылады. Бірнеше файлды жабу үшін Си тілінде төмендегідей жарияланған функция пайдаланылады:
Void fcloseall(Void);
Мәліметтерді файлдарға жазу/файлдардан оқу әрекеттерін үш топқа бөлуге болады:
Символ бойынша енгізу/шығару операциялары.
Жол бойынша енгізу/шығару операциялары.
Блок бойынша енгізу/шығару операциялары.
Төменде көрсетілген үш топ бойынша қолданылатын негізгі функциялар көрсетілген.
Символ бойынша енгізу/шығару
Символ бойынша енгізу/шығару операцияларында файлға бір символды жіберу немесе файлдан бір символды алу операциялары орындалады.
Функция
|
Функция әрекеті
|
int fgets(FILE*fp)
|
Ашық тұрған файлдан бір символды оқу немесе қайтару.
|
int fgetchov(void)
|
stdin файлынан символды оқиды және қайтарады.
|
Int ungetc(int ch, FILE *fp)
|
сh символын файлға қайтарады. Келесі файлдан оқу операциясы символды қайта қайтарады.
|
Int fputs(int ch, FILE *fp)
|
Файлға сh символының кодын жазады.
|
Жол бойынша енгізу/шығару
Функция
|
Функция әрекеті
|
int gets(char *S)
|
stdin файлынан символды оқиды және нуль-терминатормен ауыстырылатын ‘\n’ символын кездестіргенше S жолына жазады.
|
int fgets(char *S int m, FILE *fp)
|
fp сипатталған файлдан символды алады және ‘\n’ символын кездестіргенше немесе m байт оқылғанша S жолына жазады.
|
int fputs(char *S, FILE *fp)
|
Файлға көшірілмейтін және‘\n’ символын ауыстырылмайтын нуль-терминатор кездестірмейінше S жолынан файлға жазады.
|
int puts(char *S)
|
Файлға көшірілмейтін және‘\n’ символын ауыстырылмайтын нуль-терминатор кездестірмейінше S жолынан stdout байттарын файлға жазады.
|
Блок бойынша енгізу/шығару
Блок бойынша енгізу/шығару операцияларында жұмыс бүтін блоктарға жүргізіледі.
Функция
|
Функция әрекеті
|
int fread (void *ptv, int size, int n, FILE *fp)
|
ptv көрсеткіші көрсететін жады облысына әрбір fp файлынан size байттан n блок оқиды.
|
int fwrite(void * ptv, int size, int n, FILE *fp)
|
ptv көрсеткіші көрсететін жады облысынан әрбір fp файлына size байттан n блок жазады.
|
Дәріс №10
Достарыңызбен бөлісу: