Массивтер

Массив – бұл элементтері бір типті болатын мәліметтер жиыны.

Массивтерді айнымалыларды секілді сипаттайды:

int a[100];

float c[10][20];

Біріншісі бүтін типті а[0],a[1], …,a[99] (индекстелу нөлден басталады) элементтерден тұратын бір өлшемді массив болып табылады. Екіншісі элементтері нақты тип болатын екі өлшемді массив болып табылады. Ол 10 жолдан, 20 бағаннан тұрады.

Массивті келесідей инициализациялауға болады:

int a[6]={10,20,30,40,50,60}; немесе int a[]={10,20,30,40,50,60};

float[2][3]={{10,20,30},{40,50,60}};

Мысал 1. 10 нақты саннан тұратын бірөлшемді S массиві берілген. Осы массивті кері ретпен шығару.

#include <stdio.h>

main()

{float s[10];

int i;

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

scanf(“%f”,&s[i]); /*массив элементтерін енгізу*/

for (i=9;i>=0;i--)

printf(“%f”,s[i]); /* массив элементтерін кері ретпен шығару*/

}

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

#include <stdio.h>

main()

{int i,j,max,in,jn,a[5][5];

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

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

scanf(“%d”, &a[i][j]); /*матрицаны енгізу*/

max=a[1][1];

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

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

if (a[i][j]>max)

{in=i; jn=j;}

printf(“%d %d”, in, jn);

}

Мысал 3. D(6,6) массивінің басты және кері диагональдің орындарын ауыстыру.

#include <stdio.h>

main()

{int i,j,a,d[6][6];

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

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

scanf(“%d”, &d[i][j]);

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

{a=d[i][i];

d[i][i]=d[i][6-i];

d[i][6-i]=a;

}

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

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

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

}

Матрица элементтерін жолдар бойынша шығаруда? операциясы пайдаланылады. Егер j=5, онда курсор келесі жолға түседі (“\n”), басқа жағдайда пробел шығарылады. Экранға символдық шама шығарылатындықтан %c спецификациясы пайдаланылады.

5.2 Көрсеткіштер және сілтемелер

Көрсеткіш – бұл кейбір мәліметтердің орналасу адресін сақтайтын айнымалы.

Көрсеткішті пайдалану:

1) Кез келген мәліметтердің орналасу жеріне нұсқау жасай алуға болады.

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

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

Келесі бағдарламаны қарастырайық:

main()

int a,*p;

p = &a;

a = 421;

printf("a орналасуы: %p\n",&a);

printf("a мәні: %d\n", a);

printf("p мәні: %p\n", p);

printf("адрестелінген мән р: %d\n",*p);

Осы бағдарламада екі айнымалы сипатталған а және р. Айнымалы а – бүтін типті, р – бүтін айнымалыға көрсеткіш, яғни айнымалының адресін сақтайды. Көрсеткішті сипаттағанда алдында (*) белгісін қояды. Келесі жолда а айнымалысының адресі р-ға меншіктеледі. Бұл жердегі (&) адрестік оператор айнымалының адресін алуға мүмкіндік береді. Содан соң 421 мәні а-ға меншіктеледі. Нәтижесінде экранға келесі жазу шығады:

а орналасуы: 166E

а мәні: 421

р мәні: 166E

адрестелінген мән р: 421

Сонымен &a – а айнымалысына сілтеме, р – көрсеткіш, *р – р көрсеткіші көрсететін адрестегі мән.

Сілтемелерге мысалдар:

1) int i=1;

int & r=i; r және і айнымалылары бір адреске сілтеме жасайды

int x=r; x=1

r=2; i=2

r++; i=3;

2) char c1=’a’;

char* p=&c1; р көрсеткіші с1 айнымалының адресіне сілтеме

char c2=*p; c2=’a’

Көрсеткіштердің келесі жазуын пайдалануға болады: ***р=143;

 
 


р *р **р ***р

Бұл жазу көрсеткішке көрсеткіш пайдаланғанын көрсетеді.

5.3 Бірөлшемді массивтер және көрсеткіштер

Индекстеу операциясымен жасалынатын массивтің кез келген элементіне қол жеткізуді көрсеткіш арқылы жасауға болады.

Мысалы, int a[10];

он элементтен тұратын a[0], a[1], …,a[9] массив болсын дейік және ра массивтің бірінші элементіне а[0] көрсеткіш болсын.

 
 

int *pa;

pa = &a[0]; немесе pa = a; деп жазуға болады

Онда ра+5 жазуы а[5] элементтің адресін көрсетеді, ал *(р+5) жазуы а[5] элементтің мәнін көрсетеді.

(a+i) = = &(a[i])

*(a+i) = = a[i]

Бұл жазбалар бір біріне тең. а массиві көрсеткіш ретінде сипатталмаса да *(a+i) жазу орынды болады.

Мысал 1: Массивті көрсеткіш көмегімен шығару

int arr[]={1,2,3,4,5,6,7,8,9,10};

for (int i=0;i<10; i++)

{

printf(“%d”, *(arr+i));

}

Көрсеткіш айнымалы болғандықтан pa=a немесе pa++ деп жазуға болады, бірақ а=ра; жазуы қате болады. ра++ операторы а массивінің келесі элементіне көшуді орындайды.

Ескерту *(a+2) мен *a+2 өрнектерінің айырмашылықтары бар:

*(а+2) –а массивінің үшінші элементі;

*а+2 – массивтің бірінші элементіне 2 санын қосу.

Мысал 2. Бірөлшемді массивті қарапайым тәсілмен және көрсеткіштерді пайдаланып шығару.

#include <stdio.h>

int a[6]={10,20,30,40,50,60};

main ()

{int i, *p;

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

printf(“%d”,a[i]); /*массивті қарапайым тәсілмен шығару*/

for (p=&a[0];p<=&a[5];p++)

printf(“%d”,*p); /*массивті көрсеткішті пайдаланып шығару*/

for (p=&a[0],i=0; i<6; i++)

printf(“%d”,p[i]); /*көрсеткішті пайдаланатын тағы бір тәсіл*/

}

Егер p=&a[i], онда р++ операциясынан кейін р –да a[i+1] элементінің адресі сақталынады.

Мысал 3. Көрсеткіш көмегімен массив элементтерінің арифметикалық ортасын табу.

#include <stdio.h>

int a[]={10,20,30,40,50,60}

main()

{int i,*p;

float s;

p=a;

for (s=0,i=0; i<6; i++)

s+=*(p+i); /*массив элементтерінің қосындысы*/

s=s/6; /*массивтің арифметикалық ортасы*/

printf(“%f”,s);

}

Мысал 4. Массив элементтерін кері ретпен шығару.

#include <stdio.h>

main()

{float s[10];

int *p,i;

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

scanf(“%f”,s[i]);

p=&s[9]; /*көрсеткіш массивтің соңғы элементінің адресін алады */

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

printf(“%f”,*(p-i)); /*элементтерді кері ретпен шығару*/

for (p=&a[9]; p>=&a[0]; p--) /*кері ретпен шығарудың тағы бір тәсілі*/

printf(“/n%d”,*p);

}

5.4 Екіөлшемді массивтер және көрсеткіштер

Мысалы, 3 бағаннан және 3 жолдан тұратын а массиві берілсін және р массивтің бірінші элементіне а[0] көрсеткіш болсын, онда

a[3][3]= {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

р р+3 р+6

р+3 көрсеткіші а[1][0] элементінің адресіне көшеді, р+6 көрсеткіші а[2][0] элементінің адресін көрсетеді.

Мысал 1. а матрицасы берілген. Экранға басты диагональ элементтерін, бірінші жол элементтерін және бірінші баған элементтерін көрсеткіштерді пайдаланып шығару.

#include <stdio.h>

main ()

{

int a[3][3]={{10,20,30},

{40,50,60},

{70,80,90}};

int *pa[3]={a[0],a[1],a[2]};

/*а массивінің жолдарына ра көрсеткішін сипаттау және бастапқы мәндерін меншіктеу: pa[0]=a[0]; pa[1]=a[1]; pa[2]=a[2]*/

int p=a[0]; / *а массивінің бірінші элементіне көрсеткішті сипаттау */

int i;

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

printf(“%d”,*(p+i)); /*бас диагональ элементтерін шығару*/

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

printf(“%d”,*p[i]); /*бірінші жолдың элементтерін шығару*/

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

printf(“%d”,pa[i]); /*бірінші бағанның элементтерін шығару*/

}

Басты диагональ элементтері a[0][0], a[1][1], a[2][2] болғандықтан, оған сәйкес р, р+4, р+8 көрсеткіштері пайдаланады. Сондықтан қадам 4-ке көбейеді i+=4.

a[3][3]= {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

р р+4 р+8


5.5 Динамикалық массив

Көрсеткіштер тақырыбында динамикалық үлестірілу туралы айта кеткен болатынбыз. Си тілі бағдарламаға қажетті көлем жадыны (байтта) сұратуға мүмкіндік береді. Осы әдісті динамикалық үлестіру деп атайды. Оның көмегімен жадының кез келген көлемін пайдалануға болады. Мысалы: массив өлшемділігі белгісіз. Ол енгізілетін санға байланысты болсын дейік. Динамикалық массивті пайдаланып массив өлшемділігін анықтау және массивті 1-ден енгізілетін санға дейін толтыру.

Бағдарлама 1: new функциясын пайдаланып

main()

{

int count;

scanf(“%d”, &count);

double *a=new double[count]; // динамикалық массивке жадыны дайындау

for (int i=0; i<count; i++)

{

a[i]=i+1;

printf(“%d”, a[i]);

}

delete [] a; // динамикалық массивке дайындалған жадыны тазалау.

}

Бағдарлама 2: calloc функциясын пайдаланып

#include <stdio.h>

#include <alloc.h>

main()

{

int i, n;

float *a;

scanf(“%d”, &n);

a=(float*)calloc(n,sizeof(float)); // динамикалық массивке жады беріледі

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

{

a[i]=i+1;

printf(“%d”, a[i]);

}

free(a); // динамикалық массивке берілген жадыны тазалау.

}

Бұл жердегі sizeof – тип өлшемін анықтау операциясы; new - жадыны үлестіру операциясы. Динамикалық жадының бөлігіне қол жеткізуге мүмкіндік береді. Операнд ретінде тип аты пайдаланылады. Бұл операция жадыда орналасқан объектінің адресін қайтарады; delete – new операциясымен бөлінген динамикалық жадыны тазалау операциясы.

Егер массив символдық тип болса, malloc функциясы пайдаланылады.

6 Құрылымдар және көрсеткіштер

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

Жазылуы:

struct тип {элемент типі 1 элемент аты 1;

элемент типі n элемент аты n; };

Мысалы:

struct date { int day;

int month;

int year;};

Жақшадан кейін осы типті айнымалылар сипатталуы мүмкін, мысалы:

struct date {…} a, b, c;

При этом выделяется соответствующая память.

Құрылымды құрылымда пайдалануға рұқсат берілген. Мысалы

struct okushy { char fam [15];

aty [15];

struct date tkun;

int synyp, zhasy;};

Жоғарыда анықталған date типінің үш элементі бар: күн, ай, жыл. Олардың мәндері бүтін (int). Okushy құрылымында: fam [15]; aty [15]; tkun, synyp, zhasy элементтері бар. fam [15]; aty [15]; –бұл 15 символдан тұратын массив. Tkun айнымалысы date (ішкі құрылыммен) сипатталған.

Құрылымдық типті айнымалыларды келесідей сипаттайды:

struct okushy okuslar [50];

okuslar массиві okushy типті 50 элементтерден тұрады.

Мысал 1:

#include < stdio.h >

struct comp { int zhad;

int ozu;

char model [20]; };

/* zhad, ozu, model элементтерінен тұратын comp типті құрылымды сипаттау */

struct comp DK= {80, 1024, “Pentium 4”}

/* comp типті DK айнымалысын сипаттау */

main ()

{

printf (“ Дербес компьютер % s\n\n “, DK.model);

printf (“қатты диск сиымдылығы - % d Гбайт \n”, DK.zhad);

printf (“жедел жады - % d Мбайт \n”, DK. ozu);

}

Мысал 2: құрылымда құрылымды пайдалану

# include < stdio.h >

struct date { int day;

int month;

int year; };

struct person { char fam [20];

char im [20];

char ot [20];

struct date f1;};

main ()

{

struct person ind1;

printf (“ Адамның фамилиясын, атын, әкесінің атын, туған күнін, \n айын және туған жылын енгіз \n”);

scanf (“ % S % S % S %d %d %d”, &ind1.fam, &ind1.im, &ind1.ot,

& ind1.f1.day, &ind1.f1.month, &ind1.f1.year);

printf (“ Фамилиясы, аты,әкесінің аты: % S % S % S \n”, ind1.fam, ind1.im, ind1.ot);

printf (“ туған жылы - % d \n”, ind1.f1.year);

printf (“ туған айы - % d \n”, ind1.f1.month);

printf (“ туған күні - % d \n”, ind1.f1.day);

}

Мысал 3: құрылымдар массиві

#include < stdio.h >

struct computer { int mem, sp;

char model [20];

} pibm [10];

main ()

{ int i, j, k, priz;

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

{

printf (“ ЭЕМ моделі - ”);

scanf (“%S”, &pibm [i].model);

printf (“жедел жады көлемі -”);

scanf (“%d”, &pibm[i].mem);

printf (“винчестер көлемі - ”);

scanf (“%d, &pibm[i].sp ”);

for (j=0; j<10, j++);

{

printf (“ дербес компьютер %s\n ”, pibm[j].model);

printf (“жедел жады көлемі - % d Гб \n ”, pibm[j].mem);

printf (“винчестер көлемі - % d Мб \n ”, pibm[j].sp);

}

Мысал 4: Құрылымға көрсеткішті пайдалану

main()

{

struct person

{

char fam[80];

char name[80];

char patronymic[80];

} man;

person *per=&man;

printf(“Фамилияны енгізіңіз”);

fgets(per->fam,80, stdin);

printf(“Атын енгізіңіз”);

fgets(per->name,80, stdin);

printf(“Әкесінің атын енгізіңіз”);

fgets(per->patronymic,80, stdin);

printf(“%s %s %s \n”, per->fam, per->name, per-> patronymic);

}

Нүкте – тура таңдаудың операциясы. Көрсеткішті пайдаланғанда нүктенің орнына -> белгісі пайдаланады. Ол жанама таңдауды білдіреді.

7 Функциялар және ішкі программалар


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: