Getch();
Clrscr();
Char z;
Void main()
Getch();
Putchar(z);
Clrscr();
Char z;
Void main()
Getch();
Clrscr();
Main ()
Getch();
Clrscr();
Int m,k;
Int amin;
Main ()
Getch();
Clrscr();
Main ()
Getch();
S=0;
Clrscr();
Int i,j,r,s;
Main ()
Getch();
Clrscr();
Int i,j;
Main()
Getch();
Clrscr();
Float c;
Int i,j,s;
Main ()
Clrscr();
Main ()
Getch();
Clrscr();
Int i,j;
Main ()
Getch();
Line();
Clrscr();
Int i,j,jmin,min;
Main ()
Void line()
Getch();
L= abs(L1 - L2);
Line();
Line();
Clrscr();
Int L1,L2,L;
Int i,j;
Main ()
Void line()
Getch();
Line();
P2 = 1;
P1 = 1;
Line();
Line();
Clrscr();
Float p1, p2, z;
Int i,j;
Main ()
Void line()
Getch();
Clrscr();
Main()
Getch();
N = i;
Clrscr();
Int n,k,i;
Main()
Getch();
Clrscr();
Main()
S=f1(b,10);
Clrscr();
Main()
Return (sum);
F1(b,10);
Getch();
S=f1(b,10);
Clrscr();
Main()
Return (sum);
Main()
Clrscr();
Main()
......
Main()
Getch();
Clrscr();
Main ()
Int temp;
Int sum;
Getch();
I++;
Do
Clrscr();
Textbackground(WHITE);
Textcolor(MAGENTA);
Int i;
Main ()
Getch();
Clrscr();
Textbackground(YELLOW);
Textcolor(BLUE);
Main()
Getch();
Clrscr();
Textbackground(GREEN);
Textcolor(RED);
Main ()
Int n;
Main()
J--;
J=i-1;
Int i,j,x;
Int i,min,n_min,j;
Int i,nom;
Int k;
Int k,i,t,r;
Getch();
Int n;
Void main()
Getch();
Int n;
Void main()
Getch();
Int n;
Void main()
Int index;
Main ()
Else
Do
Clrscr();
Textbackground(WHITE);
Textcolor(RED);
Char symbol;
Main ()
Getch();
S+=a;
Do
Clrscr();
Float a,s;
Int i;
Main ()
Getch();
Do
Clrscr();
Int a, max;
Main ()
N-оператор;
Оператор;
Оператор;
Do
Getch();
X=x0;
Float x,y,x0,xk,dx;
Main ()
Getch();
K++;
Clrscr();
Int s,k;
Main ()
Оператор;
Мұнда шарт ретінде шартты өрнек немесе кез келген типтегі өрнек пайдаланылуы мүмкін. Оператор қарапайым немесе құрама болуы мүмкін. Ол құрама оператор болса, онда операторлар жиыны жүйелі жақшаға алынып жазылады. While операторы орындалғанда, алдымен жақша ішіндегі өрнек есептеліп тексеріледі. Егер өрнек мәні ақиқат болса немесе жалпы жағдайда 0-ге тең болмаса, онда оператор атқарылады. Содан соң жақшадағы өрнек тағы да есептеледі. Егер өрнек мәні жалған болса (немесе жалпы жағдайда 0-ге тең болса), онда while цикл операторы өз жұмысын аяқтайды.
Мұнда шарт-өрнек құрамына кіретін айнымалы цикл ішінде өзгеріп отырады.
5-мысал.
/* 1-ден 100-ге дейінгі бүтін
сандар қосындысы */
#include <stdio.h>
#include <conio.h>
{
s=0; k=1;
while (k<=100)
{ s+=k;
}
printf("s= %d",s);
printf("\nАяқтау үшін
Enter басыңыз\n");
}
6-мысал. y=-2.4x2 +5x-3
функциясы мәндерін оның аргументі х0-ден хk-ға дейін қадамы dx болып өзгерген кездерде анықтау керек. Мұнда цикл алдында параметрге алғашқы мән меншіктеледі де, параметр цикл ішінде берілген қадамға өзгеріп отырады (4.6-сурет). Жалпы функция кез келген түрде беріле алады. Ол параметр мәніне байланысты тармақталып кететін функция да болуы мүмкін.
/* х тұрақты қадаммен х0-ден хk-ға дейін өзгергенде, функция мәндері кестесін алу, х0, хk, dx (қадам) пернелерден енгізіледі */
#include <stdio.h>
#include <math.h>
#include <conio.h>
{
clrscr();/* экранды тазалау */
printf("х-тің бастапқы,соңғы мәндері: ");
scanf("%f%f",&x0,&xk);
printf("х-тің өзгеру қадамы dх-ті енгізіңіз: ");
scanf("%f",&dx);
printf("----------------------\n");
printf(" x | y\n");
printf("----------------------\n");
while (x<=xk)
{
y=-2.4*x*x+5*x-3*sqrt(fabs(x));
printf("%6.2f | %6.2f\n",x,y);
x=x+dx;
}
printf("----------------------\n");
}
4.3. Do ... while цикл операторы
Шарты соңынан тексерілетін do … whileциклінің орындалу схемасы суретте көрсетілген. Осыған сәйкес оператордың жалпы жазылу түрі:
{
… … …
}
while (өрнек);
Цикл тұлғасы ретінде қарапайым немесе құрама оператор қолданылуы мүмкін. Жақшадағы өрнек цикл тұлғасынан кейін тексеріледі. Сондықтанdo while цикл тұлғасы ең болмағанда бір рет орындалады. Цикл тұлғасынан кейін жазылған өрнек ақиқат болса (немесе жалған жағдайда ол 0-ге тең болмаса), цикл тұлғасы қайтадан орындалады. Ал өрнек жалған болса (немесе 0-ге тең болса), цикл аяқталады. Енді мысалдар келтірейік.
7-мысал.
// Енгізілген сандардың үлкенін (максимумын) табу
#include <stdio.h>
#include <conio.h>
{
printf("\n Сандар максимумын табу \n");
printf("Аяқтау үшін 0 енгізіңіз \n");
max = -32000;
// алдын ала максимумды ең кіші бүтінге теңейміз
{
printf("Сан енгізіңіз : ");
scanf("%i",&a);
if (a > max) max = a;
}
while (a!=0);
printf("Сандардың максимумы: %i",m);
}
8-мысал. Келесі программада шексіз сандар қосындысын
алдын ала берілгін дәлдікпен e=10-5 анықтау керек, яғни келесі қосылатын қатар мүшесі осы e санынан кіші болғанда, қосынды табу аяқталады.
#include <stdio.h>
#include <conio.h>
#define epsilon 1e-5
{
s=0; i=1;
{a=1.0/i/i;
i++;}
while (a>epsilon);
printf("s=%7.4f",s);
}
9-мысал. Төмендегі программада енгізілген бүтін санның тақ немесе жұп екендігі анықталады.
/* Санның жұп екендігін анықтау */
#include <stdio.h>
#include <conio.h>
{
int k; /* енгізілетін сан */
printf("\n* Санның жұп/тақ екендігін анықтау *\n");
{printf("\nБір бүтін сан енгізіңіз : ");
scanf("%i",&k);
printf("Бұл %i саны -",k);
if (k % 2 == 0)
printf("жұп сан.");
printf("тақ сан.");
printf("\nТағы да енгісесіз бе? Иә-'Y',Жоқ-'N':");
scanf("%s",&symbol);
}
while ((symbol=='Y')||(symbol=='y'));
}
Бақылау сұрақтары
1. Параметрлі циклдің орындалу схемасы мен жазылуы.
2. Параметрлі цикл бір де бір рет орындалмауы мүмкін бе?
3. for операторының параметрі қандай типтерде бола алады?
4. for операторы параметрінің алғашқы мәні оның соңғы мәнінен кіші бола ма?
5. Параметрлі цикл операторының неше рет қайталанатынын алдын ала білуге бола ма, болса – ол қалай анықталады?
6. for цикл операторындағы жақша ішіндегі бір немесе бірнеше өрнектерді жазбауға бола ма?
7. for цикл операторы нүктелі үтірмен аяқтала ала ма?
8. for цикл операторында қай кезде құрама операторлар қолданылады?
9. for цикл операторы қай кезде шексіз циклге айналады?
10. for цикл операторында бірнеше құрама өрнектерді үтір арқылы қалай жазуға болады?
11. Шарты алдын ала тексерілетін цикл операторының орындалу схемасы мен оның жазылуы.
12. while цикл операторының ішкі тұлғасы бір де бір рет орындалмауы мүмкін бе?
13. while цикл операторының шарты қатынас таңбаларысыз жазыла ма?
14. while цикл операторы қай кезде шексіз циклге айналады?
15. while цикл операторының тұлғасындаоның шартына әсер ететін өрнектер жазыла ма?
16. Шарты соңынан тексерілетін do … whileциклінің орындалу схемасы мен жазылуы.
17. do …while цикл операторының ішкі тұлғасы бір де бір рет орындалмауы мүмкін бе?
18. do …while цикл операторының шартында қатынас таңбасы болмаса, оның ақиқат немесе жалған екенін қалай анықтауға болады?
19. do …while цикл операторының ішкі тұлғасында шартсыз көшу операторын қолдануға бола ма?
20. do …while цикл операторы қай кезде шексіз орындалады?
Дәріс№7
5. СИ ТІЛІНДЕ МАССИВТЕРДІ ПАЙДАЛАНУ
Жиым немесе массив – бір типтегі элементтердің реттелген жиыны. Олар бір атаумен – идентификатормен аталады да, индексті айнымалы ұғымына сәйкес келеді. Мысалы, мынадай тізбек
0 1 1 2 3 5 8 13 21
Фибоначчи тізбегінің 9 элементін құрайды (алғашқы екі санды таңдап алып, келесі санды алдыңғы екеуін қосу жолымен алады). Ал мынау өзіне және бірге ғана бөлінетін жай сандар тізбегінің алғашқы 7 элементі:
1 3 5 7 11 13 17
Осындай бір текті тізбектерді жиым түрінде Си тілінде сипаттап, оған бастапқы мән беріп инициалдау үшін былай жазамыз:
int fib[8]={0, 1, 1, 2, 3, 5, 8, 13, 21};немесе
int fib[]={0, 1, 1, 2, 3, 5, 8, 13, 21}; деп көрсетеміз. мұндағы fib– жиым аты, оның элементтерінің типі int, ал ені, яғни ұзындығы – 9, жиым элементтерінің индекстері 0-ден бастап нөмірленеді, сол себепті 9 элемент 8 индекспен көрсетіледі. Мәндері толық көрсетілсе, индексті жазбаса да болады. Ал былай болса,
int fib[8]={0, 1, 2, 3}; қалған элементтері 0 болып саналады.
n=10; k=2; fib[n-k]={0, 1, 2, 3}; десе де болады.
Жоғарыдағы тізбектің 7-ші элементін бір бүтін айнымалыға меншіктеу үшін былай жазамыз.
int а = fib[6]; // а = 8
Жиымды сипаттау кезінде оның ені нақты санмен көрсетіледі, мыс., a[20], a[n] деп жазу үшін алдын ала
#define n 20жолы көрсетіледі немесе
const n=20;болып жазылады.
Жиым элементтерін енгізу немесе оларды түрлендіру үшін цикл операторлары қолданылады. Төменде 10 элементі бар жиымды 0-ден 9-ға дейінгі сандармен толтырып, сонан кейін оларды кері бағытта экранға шығару мысалы көрсетілген:
{
int ia[10];
for (index = 0; index <10; index ++)
ia[index] = index ;
for (index = 9; index >=0; index --)
printf(“ %i”, ia[index]);
Си тілінде жиымды жиымға бірден теңестіруге болмайды, мыс., а0, а1, а2, ... , а9 және с0, с1, с2, ... , с9 жиымдары үшін а = c деп жазуға рұқсат етілмейді. Олардың элементтерін цикл ішінде бір-біріне біртіндеп теңестіру керек.
Мысалы, мынадай цикл жазылуы тиіс:
int a[9], c[9];
for (int i=0; i<9; ++i)
a[i]=c[i];
Си тілінде кездейсоқ сандарды пайдалану
Си тілінде кездейсоқ сандар беретін функциялар бар.
int rand() – 0..RAND_MAX=32767 аралығынан кез келген кездейсоқ бүтін сан береді.
Ал int random(n)0..n аралығынан кез келген кездейсоқ бүтін сан береді.
Бұл функцияларды пайдалану <stdlib.h> файлы арқылы орындалады.
Мысалы:
//a[n] жиымына кездейсоқ сандар енгізу
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
{
int a[100];
printf("\nEnter the size of array:", n);
scanf("%i",&n);
for(int I=0;I<n;I++)
{a[I]=rand()%100-50;
printf(" %i ", a[I]);}
}
Жиымды өңдеу есептерінің түрлері (кластары)
Жиымды өңдеу есептері көбінесе бірыңғайланған төрт түрге бөлінеді.
1) Есептердің 1-түріне жиым элементтерінің барлығын немесе көрсетілгендерін бірдей бір тәсілмен өңдеу есептері жатады.
2) Есептердің 2-түріне (класына) жиым элементтерінің орналасу реттілігін өзгерту тәсілдері жатады.
3) Есептердің 3-класына бірнеше жиымдарды қатар өңдеу немесе бір жиымның ішкі элементтерін бірнеше топқа бөліп жеке-жеке өңдеу тәсілдері жатады. Жиымдар бір тәсілмен – синхронды өңделеді немесе әр түрлі тәсілмен – асинхронды түрде өңделеді.
4) Есептердің 4-класына жиымның берілген санға тең бірінші элементін табу, яғни іздеу есептері жатады.
1-түрдегі есептер
1 есеп. Жиымның ең үлкен элементін анықтау керек.
// максимум табу
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
{
int a[100];
printf("\nEnter the size of array:", n);
scanf("%i",&n);
for(int I=0;I<n;I++)
{ a[I]=rand()%100-50;
printf(" %i ", a[I]);
}
int max=a[0];
for(I=1;I<n;I++)
if (a[I]>max) max=a[I];
printf("\nMax= %i", max);
}
2 есеп. Жиымның жұп индексті элементтері қосындысын анықтау.
/* 0, 2, 4... индексті элементтер қосындысын табу */
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
{
int a[100];
printf("\nEnter the size of array:", n);
scanf("%i",&n);
for(int I=0;I<n;I++)
{a[I]=rand()%100-50;
printf(" %i ", a[I]);
}
int Sum=0;
for(I=0;I<n;I+=2)
Sum+=a[I];
printf("\nSum= %i ", Sum);
}
Соңғы циклді басқаша да құрастыруға болады:
//Екінші тәсіл
for(I=0;I<n;I++)
if(I%2==0) Sum+=a[I];
printf("\nSum= %i ", Sum);
2-түрдегі есептер
Жиым ішіндегі екі элементтің бір-бірімен орнын ауыстыру үшін қосымша тағы бір айнымалы керек болады. Мысалы, a[I] және a[J] элементтерінің орнын ауыстыру үшін қосымша R айнымалысы керек:
R=a[I]; a[I]=a[J]; a[J]:=R;
3-есеп. Жиым элементтерін кері бағытта орналастыру.
for(int i=0, j=n-1; i<j; i++, j--)
{int r=a[i];
a[i]=a[j];
a[j]=r;}
4-есеп. Жиымның қатар тұрған екі элементін: 1 және 2, 3 және 4, 5 және 6, т.с.с. элементтерін бір-бірімен орын ауыстыру
for(int i=0;i<n-1;i+=2)
{int r=a[i];
a[i]=a[i+1];
a[i+1]=r;}
5 есеп. Жиым элементтерін k орынға солға (оңға) ығыстыру, яғни жылжыту.
printf(“k = “);
skanf(“%d”,&k);
for(t=0;t<k;t++)
{
r=a[0];
for(int i=0; i<n-1; i++)
a[i]=a[i+1];
a[n-1]=r;
}
3-класс есептері
Жиымдарды синхронды түрде өңдеуде жиымдар элементін қарастыру кезінде индекстер бірдей қадамға өзгереді. Мысалы, бүтін сандардан құралған n элементтерден тұратын 2 жиым берілген делік. Жаңа c жиымы мынадай формула арқылы алынады: c[I]=a[I]+b[I].
for (int I=0; I<n; I++) c[I]=a[I]+b[I];
Жиымдарды асинхрондық өңдеу кезінде әр жиым индексі өз реттілігімен өзгеріп отырады.
6-есеп. Бүтін сандардан құралған жиымдағы теріс элементтердің барлығын оның бас жағына орналастыру керек.
int b[10]; //қосымша массив
int i,j=0;
for(i=0;i<n;i++)
if(a[i]<0){b[j]=a[i];j++;}
// а-дан b-ға теріс элементтерді көшіріп жазу
for(i=0;i<n;i++)
if(a[i]>=0){b[j]=a[i];j++;}
// а-дан b-ға оң элементтерді көшіріп жазу
for(i=0;i<n;i++) printf (“ %d ”, b[I]);
7 есеп. Жиымның барлық жұп элементтерін жою керек.
int b[10];
int i,j=0;
for(i=0;i<n;i++)
if(a[i]%2!=0){b[j]=a[i];j++;}
for(i=0;i<j;i++) printf (“ %d ”, b[I]);
printf ("\n");
4-класс есептері
Іздеу есептерінде берілген шартқа сәйкес келетін элементті іздеп табу керек. Ол үшін жиым элементтерін біртіндеп тізбектей қарастырып отырып шартты тексеріп шығу қажет. Осылай ету барысында циклден шығудың екі жолы бар:
- керекті элемент табылғаннан кейін;
- жиым элементтері тегіс қаралып шықты, керекті элемент табылмады.
8- есеп. Берілген k санына тең жиымның алғашқы элементін табу.
printf("\nK=");
scanf(“%i”,&k);
int ok=0;//элемент табылғаны/табылмағаны белгісі
for(i=0;i<n;i++)
if(a[i]==k){ok=1;nom=i;break;}
if(ok==1) printf("\nnom=",nom);
else printf("\nk-ға тең элемент жоқ!");
Бақылау сұрақтары
1. Жиым дегенімз не?
2. Жиымдарға бастапқы мәндер қалай тағайындалады?
3. Жиымды сипаттау тәсілдері.
4. Жиым элементтерін енгізу және экранға шығару жолдары.
5. Кездейсоқ сандарды қалай шығаруға болады?
6. Жиымға кездейсоқ сандарды меншіктеу қалай орындалады?
7. Жиымды өңдеу есептерінің түрлері (кластары).
8. Жиымның ең үлкен (ең кіші) элементін анықтау.
9. Жиым элементтері қосындысын табу.
10. Жиым ішіндегі екі элементтің бір-бірімен орнын алмастыру.
11. Жиым элементтерін кері бағытта орналастыру.
12. Жиымның көрсетілген элементтерін өңдеу тәсілдері.
Дәріс№8
Жиымды сұрыптау (сорттау, реттеу)
Сұрыптау – берілген объектілер жиынын (сандарды) ұсынылған реттілікпен қайта теріп орналастыру процесі.
Жиымдарды сұрыптау жылдамдығы әр түрлі болады. Қарапайым сұрыптау тәсілдері n*n рет салыстыруды керек етеді, мұндағы n – жиым элементтері саны; ал жылдам сұрыптау тәсілі n*ln(n) рет салыстыруды қажет етеді. Қарапайым тәсілдер түсінуге жеңіл, өйткені алгоритмі түсінікті. Күрделі тәсілдер аз әрекеттер санын керек еткенмен, операциялары күрделірек болады, сондықтан элементтер саны аз жиымдарға қарапайым тәсілдерді қолданған дұрыс.
Қарапайым тәсілдер 3 топқа бөлінеді:
- жай таңдау жолымен сұрыптау;
- жай енгізу тәсілімен сұрыптау;
- жай алмастыру тәсілімен сұрыптау.
Жай таңдау жолымен сұрыптау
Жиымның ең кіші элементі анықталады да, ол бірінші элементпен орын ауыстырады. Қалған элементтермен де осы тәсіл қайталанады.
for(i=0;i<n-1;i++)
{
min=a[i];n_min=i; // минимумды іздеу
for(j=i+1;j<n;j++)
if(a[j]<min)
{ min=a[j];n_min=j; }
a[n_min]=a[i]; //алмастыру
a[i]=min;}
Жай енгізу (кірістіру) тәсілімен сұрыптау
Жиым элементтері екіге – бастапқы тізбекке және дайын тізбекке бөлінеді. Әрбір адымда I=2 нөмірінен бастап, бастапқы берілген тізбектен I-ші элемент алынады да, ол дайын тізбектің керекті жеріне орналастырылады. Мұнан кейін I-ге 1 қосылады да, сол әрекеттер қайталанады.
|
|
|
|
|
|
дайын тізбек
| бастапқы тізбек
|
Керекті орынды іздеу кезінде оң жақтағы келесі элементпен орын ауыстыру қарастырылады, яғни таңдалып алынған элемент сұрыпталғандардың J:=I-1 нөмірінен басталатын кезекті элементімен салыстырылады. Егер таңдалып алынған элемент a[I]-ден артық болса, онда ол сұрыпталғандар ішіне қосылады, әйтпесе a[J] бір орынға ығысады да, таңдалған элемент сұрыпталғандар ішіндегі келесі элементпен салыстырылады. Керекті орынды іздеу әрекеті екі жағдайда:
- егер a[J]>a[I] болатын элемент табылса;
- дайын тізбектің сол жақ шетіне жеткен кезде аяқталады.
Мысалы:
for(i=1;i<n;i++)
{ x=a[i];//ауысатын элементті есте сақтау
while(x<a[j]&&j>=0) //керекті орынды іздеу
{
a[j+1]=a[j]$ //оңға жылжыту
}
a[j+1]=x;//элементті кірістіріп қою
}
Жай алмастыру арқылы сұрыптау
Мұнда ең соңғыдан бастап, екі элемент салыстырылады да, қажет болса, орындары алмастырылады. Осындай әрекет нәтижесінде ең кіші элемент жиымның ең сол жақ шетіне ығысады. Қалған жиым элементтері үшін де осы процесс қайталанады.
|
|
|
| 94
|
|
|
|
|
|
|
|
for(int i=1;i<n;i++)
for(int j=n-1;j>=i;j--)
if(a[j]<a[j-1])
{int r=a[j];a[j]=a[j-1];a[j-1]=r;}
9-есеп. Бүтін оң және теріс сандардан тұратын a[n] жиымының жұп нөмірлі элементтерінің қосындысын табу керек, мұнда n саны енгізіледі, ал жиым элементтерінің мәндері кездейсоқ бүтін сандардан тұрады.
rand() функциясы 0...32767 аралығындағы бүтін сан береді. Оны пайдалану үшін stdlib.h директивасын, яғни тақырып файлын қолдану қажет. Жиым элементтері екі разрядты оң және теріс сандардан тұруы үшін алынған кездейсоқ сан 100-ге бөлініп, қалдығынан 50 алып тасталынған.
/*жиымның жұп элементтерi қосындысы*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
{
int a[50];
printf("\nЖиымда неше элемент бар? ");
scanf("%d",&n);
printf("Жиым элементтерi:\n");
for(int i=0;i<n;i++)
{
a[i]=rand()%100-50;
/*жиымға 0 - 50 аралығындағы кездейсоқ сандарды меншiктеу */
printf("%d, ",a[i]);
//сандарды экранда бейнелеу
}
int sum=0;
for(i=0;i<n;i+=2)
sum+=a[i];
//0, 2, 4... индекстi элементтердi қосу
printf("\nЖиымның жұп элементтерi қосындысы: %d",sum);
getch(); // нәтижелiк экранды жапқызбай, көруге мүмкiндiк беру
}
10-есеп. Бүтін сандардан құралған А(10) бір өлшемді жиымы берілген. Сол жиым элементтерінің арифметикалық ортасын табу керек.
/* А[10] жиымынын арифметикалық
ортасын табу */
#include <conio.h>
#include <stdio.h>
#define n 10
{int i=0,s=0;
int a[n];
//экран символдары кызыл тустi
//экран фоны жасыл түстi
printf ("Жиым элементтерiн
- 10 сан енгiзiңiз:\n");
while (i<n)
{
printf("a[%i]=",i);
scanf("%i",&a[i]);
s=s+a[i];
i=i+1;
}
printf("Жиым арифметикалық ортасы : %5.2f",(float)s/n);
printf("\nАяқтау yшiн Enter басыңыз");
}
11-есеп. Бүтін сандардан тұратын А10 жиымы берілген. Сол жиымның ең үлкен элементін – максимумын және оның индексін анықтау керек.
/* Жиым максимумын табу */
#include <conio.h>
#include <stdio.h>
#define n 10
{ int i,t,a[n]={6,5,9,8,7,4,1,2,3,0},max;
printf("a[10] элементтерi : ");
for (i=0; i<n; i++)
printf(" %d ",a[i]);
max=a[0]; t=0; // max - максимум, t - оның индекci
for (i=1; i<n; i++)
if (a[i] > max)
{max = a[i]; t=i;}
printf("\nmax = %d, индексi = %d\n", max, t);
}
12-есеп. Нақты сандардан тұратын А[15] жиымы берілген. Жиымның оң элeменттерінің геометриялық ортасын анықтау керек.
Геометриялық орта мынадай өрнекпен анықталады:
/* Нақты сандардан тұратын A[15] жиымының оң
элементтерiнiң геометриялық ортасын табу керек */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#define n 15
{
float a[n];
randomize(); // кездейсоқ сандарды өзгертіп отыру функциясы
printf("\nЖиым элементтері:\n");
for(i=0;i<n;i++)
{a[i] = (float)(rand() % 100 - 50)/10;
printf(" %5.1f",a[i]);}
// көбейтінді мен оң элементтердің санын табу
i=0; // бастапқы индекс = 0
float p=1; // оң элементтер көбейтіндісі
int k=0; // оң элементтер саны
{ if (a[i]>0) { k++; p*=a[i];}
}
while (i<n);
printf("\nоң элементтер саны : %d\n",k);
p=pow(p,1.0/k);
printf("геометриялық орта = %f",p);
}
Адрестік операциялар
Адрестік операциялар үшін Си тілінде екі арнайы оператор қолданылады.
& – адресті анықтау үшін қолданылатын операция;
* – адрес арқылы қатынас жасау үшін қолданылатын операция.
& операциясы берілген айнымалының адресін қайтарады. Мысалы, программа мәтінінде sum айнымалысы былай сипатталған болсын:
онда &sum жазуы осы айнымалының компьютер жадындағы орналасқан ұясының адресі болып табылады.
Нұсқауыштар. Нұсқауыш мәліметтердің адресін сақтайтын айнымалы болып табылады. Жалпы алғанда, нұсқауыш адрестің символдық кескінделуі болып саналады. Қарастырылатын мысалда &sum – sum атты айнымалыға сілтейтін нұсқауыш болып табылады. Нақты адрес ретінде белгілі бір сан тұрады, ал &sumнұсқауыш типті константа болып табылады.
Си тілінде нұсқауыш типті айнымалылар да бар. Нұсқауыш типті айнымалылар мәні болып белгілі бір шаманың адресі саналады.
Мысалы, нұсқауыш типті айнымалы ptr идентификаторы арқылы белгіленген болсын, онда төмендегі оператор sum айнымалысының адресін ptrаттынұсқауыш типті айнымалыға меншіктейді. ptrаттынұсқауыш типті айнымалы басқа да объектіге сілтеуі мүмкін. Мысалы:
int *ptr;
ptr=∑ ptr=&max;
* операциясы – адрес арқылы қатынас жасау үшін пайдаланылатын операция. Мысалы, ptrнұсқауыш типті айнымалысында max айнымалысына нұсқайтын сілтеме сақталған болсын. Осы айнымалының мәнін білу үшін * адресі бойынша қатынас жасау операциясын қолдануға болады. ptrнұсқауышы мәнін анықтау үшін келесі операцияны орындау қажет: res=*ptr;
Нұсқауышты сипаттау. Нұсқауыш типті айнымалыны сипаттағанда берілген нұсқауыш қандай типті айнымалыға сілтейтінін көрсету қажет. Өйткені әр түрлі типті айнымалыға ЭЕМ жадында ұялардың әр түрлі саны бөлініп беріледі.
int *iptr;
char *сptr;
float *fptr;
Функциялар арасында байланыс жасау үшін нұсқауыштарды пайдалану
13 мысал. Бұл программада айнымалының мәндерін ауыстыру үшін нұсқауыштар пайдаланылған:
#include <stdio.h>
#include <conio.h>
void change (int *u, int *v)
{
temp = *u; *u = *v; *v = temp; }
{ int x=5, y=10;
printf ("x=%d y=%d\n",x,y);
change (&x,&y);
printf ("x=%d y=%d\n",x,y);
}
Нәтижесі:
x=5 y=10
x=10 y=5
Жиымдар және жиымдарға қолданылатын нұсқауыштар
Жиымдарды сипаттағанда, элементтер типі және жалпы жағдайда компьютер жадының қажетті класы көрсетіледі. Қарапайым айнымалыларда қарастырылатын қасиеттер жиымдарды де сипаттау кезінде қолданылуы мүмкін. Мысалы:
int b[30];
{ float a[30];
static char c[20];
extern b[];
}
Жиымдарды инициалдауды қарастырайық. Жиым сипатталуында тек сыртқы немесе статистикалық жиымдар ғана инициалдануы мүмкін. Мысалы, 8 топтағы студенттер саны stud[8] жиымы ретінде көрсетілген:
#include <conio.h>
#include <stdio.h>
int stud[8]={15,16,14,18,15,20,17,19};
{ int i;
extern int stud[];
for (i=0; i<8; i++)
printf("N %i тобында %i студент\n",
i+1,stud[i]);
}
Жиымның нұсқауыштарын қарастырайық. Мысалы:
int *а;
Жиым аты нұсқауышты қолданған жағдайда, жиымның 0-ші элементін анықтайды, яғни а жиымы сипатталған болса, программа мәтініндегі a идентификаторы 0-ші элементті көрсетеді деп саналады:
a == &a[0];
бұл теңдеудің екі бөлігі де – a да және &a[0]де жиымның 0-ші элементінің адресін анықтайды. Осы екі белгілеу де нұсқауыш типті константа болып табылады. Сондықтан оларды мән ретінде нұсқауыш типті айнымалыға меншіктеуге болады немесе қажет болса, нұсқауыш типті айнымалының мәнін өзгертуге болады.
14 мысал. Нұсқауыштың мәніне санды қосуға болатынын көрсететін программа қарастырайық.
{ int a[4], *pti, i;
float b[4], *ptf;
pti=a;
ptf=b;
for (i=0; i<4; i++)
printf("нұсқауыштар +% d: %8u %10u\n",i,pti+i,
ptf+i);
}
Мұның нәтижесі:
нұсқауыштар + 0: 65518 65498
нұсқауыштар + 1: 65520 65502
нұсқауыштар + 2: 65522 65506
нұсқауыштар + 3: 65524 65510
Келесі мысалды қарастырайық.
(a+2)==&a[2];
*(a+2)==a[2];
Бұлар нұсқауыштар мен жиымның арасындағы байланысты анықтайды, яғни жиымның жеке элементін анықтау үшін немесе оның мәнін пайдалану үшін нұсқауышты қолдануға болады.
Нұсқауыштарды пайдаланып жиымдармен жұмыс істеу
Жиымдарды функция арқылы қарастырып, содан кейін осы функцияны нұсқауыштарды пайдаланып жазып шығу керек болсын.
15 мысал. Функция арқылы жиым қосындысын табу.
// функция арқылы жиым қосындысын табу
#include <conio.h>
#include <stdio.h>
int f1(int a[], int t)
{
int i,sum=0;
for (i=0; i<t; i++)
sum+=a[i];
}
{ int i,s,b[10]={5,6,14,12,30,5,9,7,15,5};
printf("s=%d",s);
}
Негізгі программада f1 функциясын шақыру үшін нақты параметрлерді жазып, функция келесі түрде шақырылып отыр:
16 мысал. Нұсқауышты функцияда (f1) пайдалану программасын жазайық.
// функцияда нұсқауыш арқылы жиым қосындысын табу
#include <conio.h>
#include <stdio.h>
int f1(int *pa, int t)
{
int i,sum=0;
for (i=0; i<t; i++)
sum+=*(pa+i);
}
{ int i,s,b[10]={5,6,14,12,30,5,9,7,15,5};
printf("s=%d",s);
getch();}
программада осы f1 функциясын шақыру үшін, нақты параметрлер бұрынғыдай жазыла береді: f1(b,10);
Нұсқауыштарға қолданылатын операциялар
Си тілінде нұсқауыш типті айнымалыларға бес негізгі оператор қолдануға болады:
1. меншіктеу операциясы. Нұсқауышқа адресті меншіктеуге болады. Жиымның атын қолданып немесе адресті анықтайтын & операторын пайдаланып, әдетте адресті меншіктеуге болады;
2. мәнді анықтау. Берілген адрес бойынша кейбір ұяшықта сақталатын мәнді анықтау үшін * операциясы қоланылады;
3. нұсқауыштың адресін анықтау. Кез келген айнымалылар сияқты нұсқауыш типті айнымалылар мәні немесе адресі болуы мүмкін. & операциясы арқылы нұсқауыштың адресін анықтауға болады;
4. нұсқауыштарды арттыру. Бұл амал әдеттегі + операциясы көмегімен немесе арттыру операциясы арқылы орындалуы мүмкін. Нұсқауышты арттырып, жиымның келесі элементіне өтуге болады (қажет болса, нұсқауыш мәнін кемітуге де болады);
5. нұсқауыштардың айырмасы. Бір жиымның элементіне сілтейтін нұсқауыштың айырмасын табуға болады. Жиым элементінің арасындағы ара қашықтығын анықтау үшін нұсқауыштың айырмасын есептеуге болады.
17 мысал.
/* Жиымның максимумын тауып, одан кейінгі элементтерін кемуі бойынша реттеп орналастыру */
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define n 10
{ int i,j,t,c;
int a[n]={6,5,9,8,7,4,1,2,3,0};
int *pa,max;
printf("a[10] элементтерi : ");
for (i=0; i<n; i++)
printf(" %d ",a[i]);
pa=a; max=*pa; t=0; // максимумды және оның
// индексін табу
for (i=1; i<n; i++)
if((*(pa+i)) > (max))
{max = *(pa+i); t=i;
}
printf("\nmax = %d оның индексі = %d\n", max, t);
for (i=t; i<n-1; i++) // элементтерді кемуі бойынша
for (j=i+1; j<n; j++) // реттеу
if(*(pa+i) < *(pa+j))
{ c=*(pa+i); // жиымның 2 элементін алмастыру
*(pa+i)=*(pa+j);
*(pa+j)=c;
}
printf("\nнәтиже : ");
for (i=0; i<n; i++)
printf("%d ", *(pa+i));
}
18-есеп.
Берілген жиым элементтерін – х10 сол жиымда өсу реті бойынша орналастыру керек.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
{
int xmin,x[10];
printf("\nБерілген жиым элементтері:");
for (k=0; k<10; k++)
{x[k] = rand() % 100;
/* 32767-ге дейінгі кездейсоқ сандар */
printf(" %i",x[k]);}
for (k=0; k<9; k++)
{ xmin=x[k];n=k;
for (i=k+1; k<10; k++)
if (x[i] < xmin)
{
xmin=x[i];
}
x[n]=x[k]; x[k]=xmin;
}
printf("\nРеттелген жиым
элементтері:");
for (k=0; k<10; k++)
printf(" %i",x[k]);
}
Бақылау сұрақтары
13. Жиымды сұрыптау (сорттау, реттеу) жолдары.
Дәріс№7
6. ЕКІ ӨЛШЕМДІ ЖИЫМДАР
Екі өлшемді жиымды – матрицаны пайдалану үшін тік жақшалар ішінде олардың екі өлшемінің де енін көрсету керек. Мысалы:
int a[4][3];
алғашқы сан жолдар санын, ал екінші сан бағаналар санын көрсетеді, а жиымы 12 элементтен тұрады. Оларға бастапқы мәнді былай береміз:
int a[4][3]={ {0,1,2},
{3,4,5},
{6,7,8},
{9,10,11}
};
ішкі жүйелі жақшаларды қоймаса да болады:
int a[4][3]={0,1,2,3,4,5,6,7,8,9,10,11};
Келесі түрде сипаттау жолдардың тек бірінші элементтерін ғана анықтайды, қалған элементтер 0-ге тең болып саналады:
int a[4][3]={ {0},{3},{6},{9} };
Егер ішкі жүйелі жақшалар алынып тасталса, онда мағынасы өзгереді.
int a[4][3]={ 0,3,6,9 };
мұнда бірінші жолдың 3 элементі мен екінші жолдың бірінші элементі анықталады да, қалғандары 0 болып саналады.
Екі өлшемді жиымды инициалдау қабаттасқан циклдер арқылы орындалады.
1-мысал.
/* a[3][4] жиымы элементтерін rand() арқылы енгізу және экранға шығару */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
{
const int row=3, col=4;
int a[row][col];
for (int i=0; i<row; i++)
for (int j=0; j<col; j++)
a[i][j]=rand()%100-50;
printf("\nа[3][4] жиым элементтерi мәндерi:");
for (i=0; i<row; i++)
for (j=0; j<col; j++)
printf(" %i",a[i][j]);
}
Матрицаларды өңдейтін негізгі алгоритмдер ретінде бір өлшемді жиымдарды өңдеу кезінде қолданылған алгоритмдер саналады. Жалпы матрицаларды өңдейтін барлық алгоритмдерді екі топқа бөліп қарастыруға болады, олар:
1. матрицаның барлық элементтерін өңдейтін алгоритмдер.
2. матрицаның әр жолы немесе әр бағанасы элементтерін жеке-жеке өңдейтін алгоритмдер.
Матрицаның барлық элементтерін өңдейтін алгоритмдер
2-мысал. Нақты сандардан тұратын a4,6 матрицасы берілген. Мынадай өрнекті есептеу керек, мұндағы P1 и P2 – сәйкесінше алынған матрицаның оң және теріс элементтерінің көбейтіндісі.
/* a[4][6] матрицасы берiлген. z=p1/|p2| есептеу керек, p1 и p2 – матрицаның
оң және терiс элементтерiнiң көбейтiндiсi */
#include <math.h>
#include <conio.h>
#include <stdio.h>
{printf("------------------------------\n");
return;}
{
static int a[4][6]={
{5,-11,4,-2,5,6},
{3,3,-12,-5,7,8},
{2,3,-3,14,-9,-3},
{-9,3,-6,14,9,-3}
};
printf("Берiлген матрица :\n");
for (i=0; i<4; i++)
{for (j=0; j<6; j ++)
printf(" %3i ", a[i][j]);
printf("\n");}
/* Матрицаны өңдеу */
for (i=0; i<4; i++)
for (j=0; j<6; j ++)
{if (a[i][j]>0) p1 = p1*a[i][j];
if (a[i][j]<0) p2 = p2*a[i][j];
}
z = p1/abs(p2);
printf(" z = %f\n",z);
}
3-мысал.Бүтін сандардан тұратын квадрат b5,5 матрицасы берілген. Оның бас диагоналының сол жағында және оң жағында орналасқан нөлге тең элементтері санын анықтап, солардың айырмасының модулін табу керек.
Мынадай белгілеулер енгізейік:
L1 – бас диагональдың сол жағында (төменінде) орналасқан элементтер саны;
L2 – бас диагональдың оң жағында (жоғарысында) орналасқан элементтер саны;
L= |L1-L2| – солардың айырмасы модулі.
#include <math.h>
#include <conio.h>
#include <stdio.h>
{printf("-------------------------\n");
return;}
{
static int b[5][5]={
{5,0,0,0,0},
{0,3,12,0,0},
{0,33,13,14,0},
{0,23,0,14,0},
{35,0,13,14,9},
};
printf("Берiлген матрица :\n");
for (i=0; i<5; i++)
{for (j=0; j<5; j ++)
printf(" %3i ", b[i][j]);
printf("\n");}
L1 = L2 = 0;
for (i=0; i<5; i++)
for (j=0; j<5; j ++)
if (b[i][j]==0)
{if (i>j) L1 = L1+1;
if (i<j) L2 = L2 +1;
}
printf(" L = %i ",L);
}
Екінші типтегі есептер алгоритмдері
4-мысал. Бүтін сандардан тұратын a3,6 матрицасы жолдарының алғашқы элементін осы жолдың минимальды элементімен алмастыру керек. Нәтижелік a3,6 матрицасы элементтерін экранға шығару қажет.
/* a[3][6] матрицасы жолдарының алғашкы элементiн осы жолдың минимальды элементiмен алмастыру керек. Натижелiк Х матрицасы элементтерiн экранға шығару кажет.*/
#include <math.h>
#include <conio.h>
#include <stdio.h>
{printf("------------------------------\n");
return;}
{
static int a[3][6]={
{5,-11,4,-2,5,6},
{2,3,-3,14,-9,-3},
{-9,3,-6,-14,9,-3}
};
printf("Берiлген матрица :\n");line();
for (i=0; i<3; i++)
{for (j=0; j<6; j ++)
printf(" %3i ", a[i][j]);
printf("\n");
}
for (i=0; i<3; i++)
{ min=+1E6;
for (j=0; j<6; j ++)
if (a[i][j]<min)
{min=a[i][j];
jmin=j;
}
a[i][jmin]=a[i][0];
a[i][0]=min;
}
printf("Өңделген матрица :\n");line();
for (i=0; i<3; i++)
{for (j=0; j<6; j ++)
printf(" %3i ", a[i][j]);
printf("\n");
} line();
}
5-мысал. Бүтін сандардан тұратын a3,4 матрицасының әрбір бағаналарының арифметикалық орташа мәнін анықтап, оларды бір өлшемді s4 жиымы ретінде бейнелеу керек.
/* a[3][4] матрицасының әрбiр бағаналарының арифметикалық орташа мәнiн анықтап,оларды бiр өлшемдi s[4] жиымы ретiнде бейнелеу керек. */
//ә