Садржај
1 Алгоритми
2 Како се програмира
3 Променљиве, подаци, типови
3.1 Реални бројеви
3.2 Целобројни типови
3.3 Конверзије и заокруживање
3.4 Знаковни подаци
3.5 Текстуални подаци (стрингови, ниске)
3.6 Логички подаци
4 Гранања
4.1 Наредба if
4.2 Остали облици if наредбе
4.3 Сложени услови
4.4 Неке типичне употребе if наредби
4.5 Угнежђено гранање
4.6 Наредба switch
4.7 Гранања - разни задаци
5 Петље
5.1 Врсте петљи
5.2 Наредбе break и continue
5.3 Основни алоритми са петљама
5.4 Цифре броја
5.5 Дељивост
5.6 Угнежђене петље
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). На сваки упит програм треба да одговори исписивањем података о свим књигама чијем аутору се упит садржи у имену и (након списка) укупним бројем страна тих књига.
Користићемо листу структура да запамтимо податке о књигама. За сваки упит ћемо проћи кроз цео низ књига и проверити да ли се упит садржи у имену аутора. Напомињемо да постоје и ефикаснији начини да се овај задатак реши (у смислу времена потребног за извршавање програма), али смо изабрали овај као једноставнији за разумевање и илустровање употребе структура.
using System;
using System.Collections.Generic;
class Program
{
struct Knjiga
{
public string autor;
public string naslov;
public string oblast;
public int brStrana;
};
public static void Main()
{
int brKnjiga = int.Parse(Console.ReadLine());
Knjiga k;
List<Knjiga> knjige = new List<Knjiga>();
for (int i = 0; i < brKnjiga; i++)
{
string[] tekst = Console.ReadLine().Split(',');
k.autor = tekst[0].Trim();
k.naslov = tekst[1].Trim();
k.oblast = tekst[2].Trim();
k.brStrana = int.Parse(tekst[3].Trim());
knjige.Add(k);
}
int brUpita = int.Parse(Console.ReadLine());
for (int i = 0; i < brUpita; i++)
{
string upit = Console.ReadLine();
int ukupnoStrana = 0;
foreach (Knjiga knjiga in knjige)
{
if (knjiga.autor.Contains(upit))
{
Console.WriteLine("{0}: {1}, {2} str.",
knjiga.oblast, knjiga.naslov, knjiga.brStrana);
ukupnoStrana += knjiga.brStrana;
}
}
Console.WriteLine("Ukupno {0} str.", ukupnoStrana);
}
}
}
(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
) поље коме може да се приступа и које служи да представи температуру нпр. у степенима Целзијуса, а само за преостале јединице да користимо својства. Решење у коме је свака јединица представљена својством је изабрано само због симетрије - у њему су све јединице равноправне.
using System;
class Program
{
struct Temperatura
{
private double t;
public double C // Celzijus (Celsius)
{
get { return t; }
set { t = value; }
}
public double F // Farenhajt (Fahrenheit)
{
get { return t * 1.8 + 32; }
set { t = (value - 32) * 5 / 9; }
}
public double K // Kelvin (Kelvin)
{
get { return t + 273.15; }
set { t = value - 273.15; }
}
public double R // Reomir (Réaumur)
{
get { return t * 0.8; }
set { t = value * 1.25; }
}
};
public static void Main()
{
Temperatura kljucanjeVode = new Temperatura(), paljenjePapira = new Temperatura();
kljucanjeVode.C = 100; // temperatura kljucanja vode
paljenjePapira.F = 451; // temperatura paljenja papira
Console.WriteLine("Voda kljuca na {0:F2}°C = {1:F2}°F = {2:F2}K",
kljucanjeVode.C, kljucanjeVode.F, kljucanjeVode.K);
Console.WriteLine("Papir se pali na {0:F2}°C = {1:F2}°F = {2:F2}K",
paljenjePapira.C, paljenjePapira.F, paljenjePapira.K);
Console.WriteLine("Razlika ovih temperatura je {0:F2}°C, ili {1:F2}°F, ili {2:F2}K",
paljenjePapira.C - kljucanjeVode.C,
paljenjePapira.F - kljucanjeVode.F,
paljenjePapira.K - kljucanjeVode.K);
}
}
(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
које може само да се чита, тако да је увек ажурно и не оптерећује структуру додатном меморијом (нема редунданце у подацима).
Остатак програма је једноставан и своди се на тражење максимума у серији података.
using System;
class Program
{
struct Posetilac
{
public string ime;
public int h1, m1, s1, h2, m2, s2;
public int TrajanjePosete
{
get { return 3600 * (h2 - h1) + 60 * (m2 - m1) + s2 - s1; }
}
}
static Posetilac UnosPosetioca()
{
string[] tekst = Console.ReadLine().Split();
Posetilac p = new Posetilac
{
ime = tekst[0],
h1 = int.Parse(tekst[1]),
m1 = int.Parse(tekst[2]),
s1 = int.Parse(tekst[3]),
h2 = int.Parse(tekst[4]),
m2 = int.Parse(tekst[5]),
s2 = int.Parse(tekst[6])
};
return p;
}
public static void Main()
{
int n = int.Parse(Console.ReadLine());
Posetilac maksimalni = UnosPosetioca();
for (int i = 1; i < n; i++)
{
Posetilac novi = UnosPosetioca();
if (maksimalni.TrajanjePosete < novi.TrajanjePosete)
maksimalni = novi;
}
Console.WriteLine("Najduze je ostao {0}, i to od {1}:{2}:{3} do {4}:{5}:{6}.",
maksimalni.ime,
maksimalni.h1, maksimalni.m1, maksimalni.s1,
maksimalni.h2, maksimalni.m2, maksimalni.s2);
}
}
(struct_posetilac)