Pamoka 6

Masyvai

~35 min · 3 žingsniai · 6 / 6 pamokų
Ką pastatysi
Daug reikšmių viename kintamajame

Iki šiol kintamasis laikė vieną reikšmę. Masyvas laiko daug to paties tipo reikšmių po vienu vardu:

int pazymiai[5] = {8, 6, 9, 7, 10};

Tai sukuria 5 sveikų skaičių talpyklą. Kiekvienas elementas turi indeksą, prasidedantį nuo 0:

printf("%d\n", pazymiai[0]);  // 8  (pirmas elementas)
printf("%d\n", pazymiai[4]);  // 10 (penktas elementas)

Dėmesio. Indeksai eina nuo 0 iki dydis - 1. Masyve iš 5 elementų teisingi indeksai yra 0..4. pazymiai[5] peržengia ribą — tai klaida, kurios C nesustabdo, todėl saugokis pats.


Masyvas ir ciklas — tobula pora

Masyvai ir for ciklai sukurti vienas kitam. Indeksą paima ciklo skaitiklis:

int pazymiai[5] = {8, 6, 9, 7, 10};
for (int i = 0; i < 5; i++) {
    printf("Pazymys %d: %d\n", i + 1, pazymiai[i]);
}

Pavyzdys: suma ir vidurkis

#include <stdio.h>

int main(void) {
    int pazymiai[5] = {8, 6, 9, 7, 10};
    int suma = 0;

    for (int i = 0; i < 5; i++) {
        suma = suma + pazymiai[i];
    }

    double vidurkis = (double)suma / 5;
    printf("Suma: %d\n", suma);
    printf("Vidurkis: %.2f\n", vidurkis);
    return 0;
}

(double)suma konvertuoja sumą į trupmeninį skaičių, kad dalyba nenukirstų trupmenos (prisimink 2 pamokos spąstus).


Pavyzdys: didžiausia reikšmė

int didziausias(int masyvas[], int dydis) {
    int max = masyvas[0];
    for (int i = 1; i < dydis; i++) {
        if (masyvas[i] > max) {
            max = masyvas[i];
        }
    }
    return max;
}

int main(void) {
    int pazymiai[5] = {8, 6, 9, 7, 10};
    printf("Geriausias: %d\n", didziausias(pazymiai, 5));  // 10
    return 0;
}

Štai kur viskas susijungia: masyvas laiko duomenis, ciklas juos pereina, pasirinkimas (if) randa didžiausią, o funkcija viską supakuoja į daugkartinį bloką.


Baigiamoji užduotis

Pabandyk pats parašyti programą, kuri:

  1. Turi masyvą iš 6 temperatūrų.
  2. Funkcija apskaičiuoja vidurkį.
  3. Funkcija suskaičiuoja, kiek dienų buvo virš vidurkio.
  4. main viską išspausdina.

Naudosi visus keturis dalykus: eilės tvarką, pasirinkimą, kartojimą ir funkcijas. Tai ir yra struktūrinis programavimas.


Trikčių sprendimas

Keistos reikšmės arba programa lūžta — galbūt peržengei masyvo ribą (indeksas per didelis).

Vidurkis išeina sveikas — pamiršai (double) konvertavimą.

Ciklas praleidžia paskutinį elementą — sąlyga turi būti i < dydis, ne i < dydis - 1.


Projektas CLion

Baigiamajame projekte papildysim mathutil dviem masyvų funkcijomis (vidurkis, didziausias) ir panaudosim jas main.c. CMakeLists.txt keisti nereikiamathutil.c jau įtrauktas iš praeitos pamokos.

Žingsniai žemiau rodo pilną kiekvieno failo turinį po pakeitimo.


Apibendrinimas

Išmokai saugoti daug reikšmių masyve, pereiti jį ciklu ir apdoroti funkcijomis. Tai paskutinis kurso elementas.

Dabar turi visą struktūrinio programuotojo įrankių rinkinį: kintamuosius, sąlygas, ciklus, funkcijas ir masyvus. Su jais gali spręsti tikras problemas — ir esi pasiruošęs kitiems kursams, kur šie pagrindai virsta didelėmis programomis.

mathutil.h modify

Papildyk mathutil.h — vidurkis ir didžiausias

#ifndef MATHUTIL_H
#define MATHUTIL_H

// Grazina dvieju skaiciu suma.
int suma(int a, int b);

// Grazina 1, jei n yra pirminis, kitaip 0.
int ar_pirminis(int n);

// Grazina masyvo elementu vidurki.
double vidurkis(const int masyvas[], int dydis);

// Grazina didziausia masyvo elementa.
int didziausias(const int masyvas[], int dydis);

#endif

Papildyk mathutil.h dviem naujais prototipais — vidurkis ir didziausias. Pridėk juos prieš #endif.

Ką šis kodas daro:

  • double vidurkis(const int masyvas[], int dydis); — priima masyvą ir jo dydį, grąžina vidurkį.
  • int didziausias(const int masyvas[], int dydis); — grąžina didžiausią elementą.

Svarbu: masyvas funkcijai perduodamas kartu su dydis — C masyvas „nežino" savo ilgio, todėl visada perduodam jį atskirai. const reiškia, kad funkcija masyvo nekeis.

mathutil.c modify

Papildyk mathutil.c — naujų funkcijų kodas

#include "mathutil.h"

int suma(int a, int b) {
    return a + b;
}

int ar_pirminis(int n) {
    if (n < 2) {
        return 0;
    }
    for (int i = 2; i < n; i++) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

double vidurkis(const int masyvas[], int dydis) {
    int s = 0;
    for (int i = 0; i < dydis; i++) {
        s = s + masyvas[i];
    }
    return (double)s / dydis;
}

int didziausias(const int masyvas[], int dydis) {
    int max = masyvas[0];
    for (int i = 1; i < dydis; i++) {
        if (masyvas[i] > max) {
            max = masyvas[i];
        }
    }
    return max;
}

Papildyk mathutil.c dviejų naujų funkcijų apibrėžimais (po esamomis).

Ką šis kodas daro:

  • vidurkis — ciklu sudeda visus elementus, tada dalija iš dydis. (double)s užtikrina trupmeninę dalybą.
  • didziausias — pradeda nuo pirmo elemento ir ciklu ieško didesnio.

Svarbu: didziausias ciklą pradeda nuo i = 1, nes max jau lygus masyvas[0].

main.c modify

Pakeisk main.c — baigiamasis masyvų projektas

#include <stdio.h>
#include "mathutil.h"

int main(void) {
    int pazymiai[5] = {8, 6, 9, 7, 10};
    int dydis = 5;

    printf("Pazymiai: ");
    for (int i = 0; i < dydis; i++) {
        printf("%d ", pazymiai[i]);
    }
    printf("\n");

    printf("Vidurkis: %.2f\n", vidurkis(pazymiai, dydis));
    printf("Geriausias: %d\n", didziausias(pazymiai, dydis));
    return 0;
}

Pakeisk visą main.c baigiamuoju kodu: masyvas pažymių, kurį apdorosim mūsų funkcijomis.

Ką šis kodas daro:

  • int pazymiai[5] = {8, 6, 9, 7, 10}; — masyvas iš penkių sveikų skaičių.
  • Ciklas išspausdina visus elementus.
  • vidurkis(pazymiai, dydis) ir didziausias(pazymiai, dydis) — perduoda masyvą ir dydį funkcijoms.

Svarbu: čia susijungia visi blokai — masyvas (duomenys), ciklas (perėjimas), funkcijos (apdorojimas). Tai ir yra struktūrinis programavimas.