Садржај
1 Алгоритми
Појам алгоритма
Запис алгоритма
Запис алгоритма - квиз
Разумевање алгоритама датих дијаграмом - квиз
Разумевање алгоритама датих псеудокодом - квиз
Програмирање слагањем блокова
2 Како се програмира
Изглед програма
О језичким правилима
Језичка правила - квиз
Интегрисано окружење за развој програма
Интегрисано окружење - квиз
Кориснички интерфејс програма
Кориснички интерфејс - квиз
3 Променљиве, подаци, типови
Променљиве, подаци, типови
3.1 Реални бројеви
Реални бројеви
Реални бројеви - квиз
Реални бројеви - задаци
3.2 Целобројни типови
Целобројни типови
Целобројни типови - квиз
Целобројни типови - задаци
3.3 Конверзије и заокруживање
Конверзије нумеричких типова и заокруживање
Конверзије и заокруживање - квиз
Конверзије и заокруживање - задаци
3.4 Знаковни подаци
Знаковни подаци
Знаковни подаци - квиз
3.5 Текстуални подаци (стрингови, ниске)
Текстуални подаци (стрингови, ниске)
Стрингови - квиз
3.6 Логички подаци
Логички подаци
Логички подаци - квиз
4 Гранања
Гранања
4.1 Наредба if
Наредба if
Наредба if - квиз
Наредба if - задаци
4.2 Остали облици if наредбе
Остали облици if наредбе
Остали облици if наредбе - задаци
4.3 Сложени услови
Сложени услови
Сложени услови - квиз
Сложени услови - задаци
4.4 Неке типичне употребе if наредби
Налажење минимума и максимума
Налажење минимума и максимума - задаци
Пребројавање, издвајање и претрага
Пребројавање и издвајање - задаци
4.5 Угнежђено гранање
Угнежђено гранање
Угнежђено гранање - квиз
Угнежђено гранање - задаци
4.6 Наредба switch
Наредба switch
Наредба switch - задаци
4.7 Гранања - разни задаци
Гранања - разни задаци
5 Петље
Петље
5.1 Врсте петљи
Врсте петљи
5.2 Наредбе break и continue
Наредбе break и continue
5.3 Основни алоритми са петљама
Основни алоритми са петљама
Агрегатне функције
Агрегатне функције - задаци
Пресликавања
Пресликавања - задаци
Пребројавање и издвајање
Пребројавање и издвајање - задаци
Претраживање
Претраживање - задаци
Сложене операције
Сложене операције - задаци
5.4 Цифре броја
Цифре броја
Цифре броја - задаци
5.5 Дељивост
Дељивост
Прости бројеви
Прости бројеви - задаци
Еуклидов алгоритам
Еуклидов алгоритам - задаци
5.6 Угнежђене петље
Угнежђене петље
Угнежђене петље - квиз
Угнежђене петље - ASCII графика
Угнежђене петље - ASCII графика - квиз
Угнежђене петље - ASCII графика - задаци
Угнежђене петље - сегменти
Угнежђене петље - сегменти - квиз
Угнежђене петље - сегменти - задаци
5.7 Петље - разни задаци
Петље
Петље - разни задаци
6 Статички методи
Статички методи
6.1 Писање статичких метода
Писање статичких метода
Писање статичких метода - квиз
6.2 Извршавање метода
Извршавање метода
Извршавање метода - квиз
6.3 Пренос аргумената по референци
Пренос аргумената по референци
Пренос аргумената по референци - квиз
6.4 Корист од метода
Корист од метода
Методи - задаци
7 Низови
Низови
7.1 Употреба низова
Употреба низова
Употреба низова - квиз
7.2 Низови - вежбање
Низови - вежбање
Низови - задаци
7.3 Низ као референцирани тип
Низ као референцирани тип
Низ као референцирани тип - квиз
7.4 Листе
Листе
Листе - квиз
Операције над листама
Операције над листама - квиз
Листе и ефикасност
Листе и ефикасност - квиз
7.5 Стринг и низ карактера
Стринг и низ карактера
Стринг и низ карактера - квиз
Трансформисање стрингова
Трансформисање стрингова - квиз
8 Матрице
Матрице
8.1 Употреба матрица
Употреба матрица
Употреба матрица - квиз
Матрице - задаци
9 Кориснички дефинисани типови
Кориснички дефинисани типови
9.1 Набројиви типови и структуре
Набројиви типови
Структуре
Набројиви типови и структуре - квиз
10 Фајлови
Фајлови
10.1 Управљање фајловима
Управљање фајловима
Управљање фајловима - квиз
10.2 Читање и упис података у текстуални фајл
Читање и упис података у текстуални фајл
Текстуални фајлови - квиз
Текстуални фајлови - вежбање
10.3 Аргументи командне линије програма
Аргументи командне линије програма
Аргументи командне линије програма - квиз

Структуре

Структуре су још један врло значајан тип који корисник сам дефинише. Оне представљају начин да од више података, који у датом контексту чине смисаону целину, направимо један „групни” податак. Груписањем података у структуру наглашавамо и на нивоу писања кода смисаону повезаност података и тиме програм чинимо јаснијим. Осим тога, поједностављујемо прослеђивање такве групе података као параметра методу, враћање групе података као резултата рада метода и додељивање групе података другој групи.

Поља структуре

Податке од којих се структура састоји зовемо поља структуре. Поља могу, али не морају да буду међусобно истог типа. Такође, поља могу да буду и сложеног типа, укључујући друге структуре, низове итд.

У свом најпростијем облику, структурни тип се дефинише писањем кључне речи struct, иза које следи име типа, а затим у витичастим заградама списак поља. На пример, структура Knjiga, која описује једну књигу, може да буде задата овако:

struct Knjiga {
    public string autor;
    public string naslov;
    public string oblast;
    public int brStrana;
};

Променљиве чији је тип нека структура такође зовемо структуре. Када је потребно да разликујемо тип и променљиву, користимо термине структурни тип и структурна променљива.

У програму се пољима структуре приступа помоћу имена структурне променљиве и тачке. На пример, након дате дефиниције структуре Knjiga, њена поља autor i brStrana би могла да се употребе овако:

Knjiga k;

// ...

if (k.autor.Contains(upit))
    Console.WriteLine(k.brStrana);

Напоменимо још да, за разлику од низова, листи, стрингова и матрица, структуре нису референцирани, него вредносни тип података. По томе су структуре сличније простим типовима као што су целобројни и реални типови. То значи да се приликом додељивања једне структурне променљиве другој врши копирање садржаја свих поља. На пример, извршавањем (иначе бесмисленог) кода

Knjiga k1, k2;

// ...

k2 = k1;
k1.brStrana += 1;
Console.WriteLine(k1.brStrana);
Console.WriteLine(k2.brStrana);

била би исписана два различита броја, чиме само потврђујемо да свака променљива задржава свој простор у меморији, тј. не долази до коришћења истог простора као што је то случај код референцираних типова података.

Пример - претрага књига

Написати програм који најпре учитава број n и податке о n књига, за сваку књигу у једном реду. Подаци о једној књизи су име аутора, наслов, област и број страна, раздвојени запетом. Редови са подацима о књигама могу да изгледају, на пример, овако:

3
J. J. Zmaj, Riznica pesama za decu, poezija za decu, 156
W. Shakespeare, Romeo i Julija, drama tragdija, 190
W. Shakespeare, Otelo, drama tragdija, 144

Након тога, програм треба да учита број m и m упита, сваки упит у посебном реду. Упит се састоји од имена или дела имена аутора (нпр. Zmaj). На сваки упит програм треба да одговори исписивањем података о свим књигама чијем аутору се упит садржи у имену и (након списка) укупним бројем страна тих књига.

Користићемо листу структура да запамтимо податке о књигама. За сваки упит ћемо проћи кроз цео низ књига и проверити да ли се упит садржи у имену аутора. Напомињемо да постоје и ефикаснији начини да се овај задатак реши (у смислу времена потребног за извршавање програма), али смо изабрали овај као једноставнији за разумевање и илустровање употребе структура.

46
 
1
using System;
2
using System.Collections.Generic;
3
4
class Program
5
{
6
    struct Knjiga
7
    {
8
        public string autor;
9
        public string naslov;
10
        public string oblast;
11
        public int brStrana;
12
    };
13
14
    public static void Main()
15
    {
16
        int brKnjiga = int.Parse(Console.ReadLine());
17
        Knjiga k;
18
        List<Knjiga> knjige = new List<Knjiga>();
19
        for (int i = 0; i < brKnjiga; i++)
20
        {
21
            string[] tekst = Console.ReadLine().Split(',');
22
            k.autor = tekst[0].Trim();
23
            k.naslov = tekst[1].Trim();
24
            k.oblast = tekst[2].Trim();
25
            k.brStrana = int.Parse(tekst[3].Trim());
26
            knjige.Add(k);
27
        }
28
        int brUpita = int.Parse(Console.ReadLine());
29
        for (int i = 0; i < brUpita; i++)
30
        {
31
            string upit = Console.ReadLine();
32
            int ukupnoStrana = 0;
33
            foreach (Knjiga knjiga in knjige)
34
            {
35
                if (knjiga.autor.Contains(upit))
36
                {
37
                    Console.WriteLine("{0}: {1}, {2} str.",
38
                        knjiga.oblast, knjiga.naslov, knjiga.brStrana);
39
                    ukupnoStrana += knjiga.brStrana;
40
                }
41
            }
42
            Console.WriteLine("Ukupno {0} str.", ukupnoStrana);
43
        }
44
    }
45
}
46

(struct_knjige)

Приметимо да приликом додавања књиге у листу (метод Add) долази до копирања садржаја у нови елемент листе, исто као и при додељивању вредности структури (ово и јесте додељивање вредности новој структури у листи).

Својства структуре

Поред поља са подацима, структуре могу да садрже и друге делове, као што су својства, индексери, методи, операторски методи и догађаји. Овде се нећемо упуштати у описивање свега набројаног, већ ћемо употребљавати само поља (о којима је већ било речи) и својства.

Својство је члан структуре који користи исту синтаксу као поље. То значи да својства структура у програмима користимо као да су то поља (гледајући кôд који само користи поља и својства структура, не можемо да видимо разлику између поља и својства). Међутим, за својства структуре се не одваја простор у меморији. Уместо тога, приликом очитавања и додељивања вредности својству, извршавају се наредбе које напишемо у такозваним приступницима (енгл. accessor) датом својству. Свако својство може да има приступник за очитавање вредности који се зове get, и приступник за постављање вредности који се зове set.

Један од ова два приступника може и да се изостави и тада се својство користи само за читање или само за упис вредности (у зависности од тога који приступник је изостављен). На пример, у дефиницији структуре Prozor датој испод (која описује положај прозора на екрану), поред четири поља постоје и два својства: poslednjiRed и poslednjaKolona.

struct Prozor
{
    public int prviRed;
    public int prvaKolona;
    public int visina;
    public int sirina;
    public int poslednjiRed { get { return prviRed + visina - 1; } }
    public int poslednjaKolona { get { return prvaKolona + sirina - 1; } }
};

Оба ова својства имају само приступник get, што значи да могу да се користе само за читање вредности. На пример, можемо да пишемо:

Prozor a = new Prozor { prviRed = 20, prvaKolona = 10, visina = 100, sirina = 200 };
Console.WriteLine(a.poslednjiRed);

али не и

a.poslednjiRed = 200;

јер својство poslednjiRed нема приступник set.

Када постоји веза између неких величина које описују структуру, као што је случај са структуром Prozor и величинама prviRed, visina и poslednjiRed, није добро за сваку од тих величина користити поље. Да смо у претходном примеру уместо својства додали поље poslednjiRed, било би компликовано обезбеђивати конзистентност вредности структурне променљиве (могло би се догодити да веза између ових величина грешком буде нарушена). Боље је да се поља користе само за подгрупу тих величина, у којој све величине могу да се мењају независно једна од друге. У нашем примеру независно се мењају prviRed и visina, а величина poslednjiRed се само израчунава и не мења се директно, већ искључиво имплицитно, као последица промене неке од величина које се мењају директно и независно.

Још једна (мање битна) предност својстава над додатним пољима је употреба мање меморије.

Иницијализација структура

У претходном примеру смо уједно видели и један начин иницијализације структурне променљиве када су познате почетне вредности свих поља:

Prozor a = new Prozor { prviRed = 20, prvaKolona = 10, visina = 100, sirina = 200 };

Могуће је иницијализовати структурну променљиву и када нису познате вредности свих поља, или чак ниједног поља:

Prozor b = new Prozor { prviRed = 50, prvaKolona = 60};
Prozor c = new Prozor();

Када користимо оператор new у коме не иницијализујемо сва поља структуре, поља која нису експлицитно иницијализована биће иницијализована имплицитно на подразумевану вредност за свој тип (нула за бројчане типове, празан стринг за стрингове, false за логички тип, null за референциране типове). Тако су иницијализације дате горе равноправне са

Prozor b = new Prozor { prviRed = 50, prvaKolona = 60, visina = 0, sirina = 0 };
Prozor c = new Prozor { prviRed = 0, prvaKolona = 0, visina = 0, sirina = 0 };

Уколико не иницијализујемо структурну променљиву помоћу оператора new, неопходно је да сваком пољу експлицитно доделимо вредност пре него што га употребимо. На пример, после

Prozor b;
b.prviRed = 3;

можемо да користимо b.prviRed, али не и b.visina.

Пример - температуре

У овом примеру је илустрована употреба својстава у структури. Структура представља температуру и може се задавати и очитавати у разним јединицама (Келвини, степени Целзијуса, Фаренхајта и Реомира). Међутим, све ове величине су међусобно зависне, тј. ако је позната једна (било која) могу да се израчунају све остале. Зато користимо само једно поље, које памти температуру у степенима Целзијуса, а и то поље је означено као приватно. То значи да корисници структуре не могу да приступају овом пољу. Температуре у свим јединицама су реализоване помоћу својстава.

Алтернативно решење је да имамо једно јавно (public) поље коме може да се приступа и које служи да представи температуру нпр. у степенима Целзијуса, а само за преостале јединице да користимо својства. Решење у коме је свака јединица представљена својством је изабрано само због симетрије - у њему су све јединице равноправне.

47
 
1
using System;
2
3
class Program
4
{
5
    struct Temperatura
6
    {
7
        private double t;
8
        public double C // Celzijus (Celsius)
9
        {
10
            get { return t; }
11
            set { t = value; }
12
        }
13
        public double F // Farenhajt (Fahrenheit)
14
        {
15
            get { return t * 1.8 + 32; }
16
            set { t = (value - 32) * 5 / 9; }
17
        }
18
        public double K // Kelvin (Kelvin)
19
        {
20
            get { return t + 273.15; }
21
            set { t = value - 273.15; }
22
        }
23
        public double R // Reomir (Réaumur)
24
        {
25
            get { return t * 0.8; }
26
            set { t = value * 1.25; }
27
        }
28
    };
29
30
    public static void Main()
31
    {
32
        Temperatura kljucanjeVode = new Temperatura(), paljenjePapira = new Temperatura();
33
        kljucanjeVode.C = 100; // temperatura kljucanja vode
34
        paljenjePapira.F = 451; // temperatura paljenja papira
35
        Console.WriteLine("Voda kljuca na {0:F2}°C = {1:F2}°F = {2:F2}K", 
36
            kljucanjeVode.C, kljucanjeVode.F, kljucanjeVode.K);
37
38
        Console.WriteLine("Papir se pali na {0:F2}°C = {1:F2}°F = {2:F2}K",
39
            paljenjePapira.C, paljenjePapira.F, paljenjePapira.K);
40
41
        Console.WriteLine("Razlika ovih temperatura je {0:F2}°C, ili {1:F2}°F, ili {2:F2}K",
42
            paljenjePapira.C - kljucanjeVode.C, 
43
            paljenjePapira.F - kljucanjeVode.F, 
44
            paljenjePapira.K - kljucanjeVode.K);
45
    }
46
}
47

(struct_temperatura)

Извршавањем програма добијамо следећи излаз:

Voda kljuca na 100.00°C = 212.00°F = 373.15K
Papir se pali na 232.78°C = 451.00°F = 505.93K
Razlika ovih temperatura je 132.78°C, ili 239.00°F, ili 132.78K

Пример - посетиоци

У једној згради за сваког посетиоца се бележи време почетка и завршетка посете у сатима, минутима и секундама.

Написати програм који учитава број n и податке о n посета и исписује податке о посетиоцу (име и времена доласка и одласка) који се најдуже задржао у посети.

Подаци о свакој посети су у једном реду, и то име посетиоца, сат, минут и секунд доласка и сат, минут и секунд одласка, раздвојени по једним размаком. На пример, ако је Марко био у згради од 9:15:27 до 9:59:38, ред са подацима би изгледао овако:

Marko 9 15 27 9 59 38

Унос података о једном посетиоцу смо издвојили у посебан метод UnosPosetioca, да бисмо једноставно (без понављања кода) могли да учитамо податке о првом посетиоцу пре петље, а о осталима у петљи. У овом методу можемо још једном да видимо како се иницијализује структурна променљива.

Структура Posetilac има и својство TrajanjePosete које може само да се чита, тако да је увек ажурно и не оптерећује структуру додатном меморијом (нема редунданце у подацима).

Остатак програма је једноставан и своди се на тражење максимума у серији података.

47
 
1
using System;
2
3
class Program
4
{
5
    struct Posetilac
6
    {
7
        public string ime;
8
        public int h1, m1, s1, h2, m2, s2;
9
        public int TrajanjePosete
10
        {
11
            get { return 3600 * (h2 - h1) + 60 * (m2 - m1) + s2 - s1; }
12
        }
13
    }
14
15
    static Posetilac UnosPosetioca()
16
    {
17
        string[] tekst = Console.ReadLine().Split();
18
        Posetilac p = new Posetilac
19
        {
20
            ime = tekst[0],
21
            h1 = int.Parse(tekst[1]),
22
            m1 = int.Parse(tekst[2]),
23
            s1 = int.Parse(tekst[3]),
24
            h2 = int.Parse(tekst[4]),
25
            m2 = int.Parse(tekst[5]),
26
            s2 = int.Parse(tekst[6])
27
        };
28
        return p;
29
    }
30
31
    public static void Main()
32
    {
33
        int n = int.Parse(Console.ReadLine());
34
        Posetilac maksimalni = UnosPosetioca();
35
        for (int i = 1; i < n; i++)
36
        {
37
            Posetilac novi = UnosPosetioca();
38
            if (maksimalni.TrajanjePosete < novi.TrajanjePosete)
39
                maksimalni = novi;
40
        }
41
        Console.WriteLine("Najduze je ostao {0}, i to od {1}:{2}:{3} do {4}:{5}:{6}.",
42
            maksimalni.ime,
43
            maksimalni.h1, maksimalni.m1, maksimalni.s1,
44
            maksimalni.h2, maksimalni.m2, maksimalni.s2);
45
    }
46
}
47

(struct_posetilac)

Претходна лекција
Следећа лекција
A- A+
Тема
Темa

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.