diff --git a/README.md b/README.md index 006b746..eda1b07 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,33 @@ -## Navodila za uporabo +## Navodila za uporabo template sistema -`tmplt.tex` je file ki si ga skopirate in dodate notr svojo vsebino. `style.py` -je file, ki mu date C++ kodo na standardn input in sproducira sumljiv in -neberljiv Latex na standardnem izhodu. Ta latex lahko potem pastate v svoj -`.tex` file na primernem mestu. To je mal neprakticno in tko naprej. -Improvementi temu processu so se work in progress. +Nova poglavja dodajaj v podmapo `chapters/`. Datoteka naj izgleda tako: + +```latex +%#template templates/template.text + +%#block title +Naslov poglavja +%#endblock + +%#block content +Tu piši vse kar želiš napisati. Uporabljaj \LaTeX{} kodo, +kakor običajno. Na voljo imaš vse, kar je bilo na voljo v starih +templatih. + +Če želiš vključiti del kode, napiši: +%#insert python3 style.py < chapters/ime-poglavja/datoteka.cpp +kjer je to dejansko obstoječa datoteka. + +% Na splošno lahko kot argument v %#insert podaš katerokoli shell +% komando. Glej, da jo bo lahko pognal kdorkoli, ki bi želel prevesti program. + +Ne pozabiti +%#endblock +``` + +Da prevedeš, poženi `./lp.py chapters/ime-datoteke.tex`. +Končna PDF datoteka bo v `./ime-datoteke.p.pdf`. ### dependencies -Za `style.py` zaganjat boste rabl python knjiznico `pygments`. + +`pip3 install pygments` diff --git a/arithm.tex b/arithm.tex deleted file mode 100644 index d0bee89..0000000 --- a/arithm.tex +++ /dev/null @@ -1,422 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 9in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\title{Računske operacije} -\date{} - -\begin{document} -\maketitle - -\section{Seštevanje, odštevanje, množenje} -Računalniki lahko s spremenljivkami počnejo veliko stvari. Najpreprostejše so operacije na številih, kot so seštevanje, odštevanje in množenje. Račune zapisujemo tako kot v šoli, z \emph{operatorji}. -\begin{itemize} - \item \verb-+- za seštevanje - \item \verb+-+ za odštevanje - \item \verb+*+ za množenje -\end{itemize} - -Rezultat lahko izračunamo kar znotraj funkcije \verb+printf+: - - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{5}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{7}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{+}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - - -\begin{inout} - -\tcblower -12 -\end{inout} - - -\end{examples} - -\pagebreak -Rezultat lahko tudi shranimo v novo spremenljivko: -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{vsota}\PY{p}{,}\PY{+w}{ }\PY{n}{razlika}\PY{p}{,}\PY{+w}{ }\PY{n}{produkt}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{vsota}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{a}\PY{o}{+}\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{razlika}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{a}\PY{o}{\PYZhy{}}\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{a}\PY{o}{*}\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{vsota}\PY{p}{,}\PY{+w}{ }\PY{n}{razlika}\PY{p}{,}\PY{+w}{ }\PY{n}{produkt}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -3 7 -\tcblower -12\\ --4\\ -21 -\end{inout} - -\end{examples} - -\begin{errors} -Spremenljivko \emph{inicializiramo} tako, da notri nekaj shranimo, bodisi kot \verb+a=5+, bodisi s tem, da vanjo nekaj napišemo s funkcijo \verb+scanf+. -Če je ne inicializiramo, pozneje pa jo poskusimo uporabiti za izpisovanje, računanje ali kaj drugega, lahko dobimo zelo čudne rezultate, naš program se lahko celo sesuje. -\end{errors} - -%CHECK -V zgornjem programu tudi vidimo, da lahko z enim klicem funkcije \verb+scanf+ preberemo več spremenljivk. - -\subsection*{Negativna števila} -Na meteorološki postaji Kredarica so leta 2014 izmerili povprečno januarsko temperaturo približno -5 °C, povprečno avgustovsko pa približno 6 °C. -Med tema meritvama je 11 °C razlike. \\ -Pozimi lahko izmerimo temperature manjše od 0. Takšnim številom, kot je -5, rečemo \emph{negativna števila}. Lahko jih uporabimo tudi drugje, ne samo pri merjenju temperature. \\ -S pozitivnimi števili lahko štejemo od 0 do neskončno (1, 2, 3, ...), z negativnimi pa do - neskončno. (-1, -2, -3, ...). Tako kot pozitivna števila jih lahko seštevamo in odštevamo: - -\begin{examples} -5 - 11 = -6 \\ --6 + 11 = 5 \\ -5 -(-6) = 11 \\ --2 - 1 = -3 \\ --2 - (-1) = -1 --2 + (-1) = -3 \\\\ -\emph{Pravila:}\\ --(-6) = +6\\ -+(-1) = -1 \\ --(-(-(-1))) = -(-(+1)) = -(-1) = 1 -\end{examples} - -Lahko jih tudi množimo: - -\begin{examples} -2 * (-5) = -10 \\ -(-5) * (-5) = 25 \\ - -\emph{Pravila:} -Če množimo dve pozitivni števili, je produkt pozitiven. \\ -Če množimo eno pozitivno in eno negativno število, je produkt negativen. \\ -Če množimo dve negativni števili, je produkt spet negativen. \\ -O negativnih številih lahko razmišljamo kot: -3 = (-1) * 3 -\end{examples} - -Računalniki z negativnimi števili računajo enako kot s pozitivnimi: - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Vsota: \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{Razlika: \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{Produkt: \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{+w}{ }\PY{o}{+}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{+w}{ }\PY{o}{\PYZhy{}}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{+w}{ }\PY{o}{*}\PY{+w}{ }\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - - -\begin{inout} -3 7 -\tcblower -Vsota: 10 \\ -Razlika: -4 \\ -Produkt: 21 -\end{inout} - -\end{examples} - -\pagebreak -\section{Deljenje} -Števila lahko tudi delimo. Za deljenje uporabljamo znak \verb+/+. -Za razumevanje poglavja si bomo pomagali s formulo $a = k*b + o$, ki ponazarja deljenje z ostankom. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{/}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - - -\begin{inout} -16 8 -\tcblower -2 -\end{inout} - -\end{examples} - -\begin{errors} -Deljenje v jezikih C in C++ je celoštevilsko. Deljenje z ostankom lahko zapišemo po formuli: $a = k*b + o$. - -16/8: 16 = 2*8 + 0 \\ -Ostanek je 0, ker je 16 deljivo z 8. \\\\ - -16/5: 15 = 3*5 + 1 \\ -1 je ostanek. \\\\ - -Celoštevilsko deljenje pomeni, da nam program vnre samo $k$. Primer vhoda in izhoda za zgornji program, kjer števili nista deljivi: - -\begin{inout} -16 3 -\tcblower -5 -\end{inout} - -Tudi, če bi bil rezultat deljenja 7.9, tega program ne zaokroži na 8, temveč nam vrne 7. \\ -Če manjše število delimo z večjim, zato vedno dobimo 0. - -\end{errors} - -\pagebreak -Operator \verb+/+ nam torej iz pri deljenju \verb+a/b+ vrne \verb+k+. Lahko pa dobimo tudi ostanek \verb+o+. Do njega pridemo z operatorjem \verb+%+ (\emph{modulo}). - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d = \PYZpc{}d*\PYZpc{}d + \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{/}\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{\PYZpc{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Količnik: \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{Ostanek: \PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{/}\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{\PYZpc{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -25 7 -\tcblower -25 = 3*7 + 4 \\ -Količnik: 3 \\ -Ostanek: 4 -\end{inout} - -\end{examples} - -\begin{errors} -Deljenje z 0 v matematiki ni definirano in prav tako ne v programiranju. Če neko število delimo z 0, se nam bo program sesul. Prav tako, če poskušamo izračunati ostanek pri deljenju z 0. \\ -Ta napaka se pogosto zgodi v programih, kjer delimo z več števili, zato moramo biti na to pozorni. -\end{errors} - -\end{document} diff --git a/basic-conditionals.tex b/basic-conditionals.tex deleted file mode 100644 index 363270b..0000000 --- a/basic-conditionals.tex +++ /dev/null @@ -1,438 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 9in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\title{Pogojni stavki} -\date{} - -\begin{document} -\maketitle - -Pogosto želimo, da računalnik izvaja drugačno kodo glede na vrednost ene ali -večih spremenljivk, npr. da nam pokaže drugačno vsebino, če smo napisali -pravilno ali napačno geslo, da računalo sešteva, če smo pritisnili gumb za -seštevanje, oz. odšteva, če smo pritisnili gumb za odštevanje, ipd. Z drugimi -besedami, želimo upravljati potek programa (torej izbrati, katera koda naj -se izvede) glede na vrednosti spremenljivk. Angleško takemu upravljanju -pravimo \emph{control flow}, najpogosteje pa ga izvajamo s t.i. \emph{pogojnimi} -ali \emph{if stavki}. Osnovna struktura je sledeča: - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{k}{if} \PY{p}{(}\PY{n}{pogoj}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, ce pogoj velja} -\PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, ce pogoj ne velja} -\PY{p}{\PYZcb{}} -\end{Verbatim} -\end{examples} - -\emph{Pogoj} je nov pojem. Označuje neke vrste račun, katerega rezultat ni -število, vendar \emph{logična vrednost}. Tu sta možni vrednosti le dve: -pravilno (angl.~\verb+true+) in napačno (angl.~\verb+false+). Če bo rezultat -računa, navedenega v običajnih oklepajih v zgornjem \verb+if+ stavku, -\verb+true+, -se bo izvedla koda znotraj prvih zavitih oklepajev, če pa je rezultat računa -\verb+false+, pa se bo izvedla koda v drugih zavitih oklepajih (tistih za besedo -\verb+else+). Drugega dela, t.j. \verb+else+ in oklepaji za njim, ni treba -pisati, če ga ne želimo. - -Kako pa zapišemo pogoj? Za to uporabimo posebne logične operatorje. Pri delu s -številkami so nam na voljo naslednji: -\begin{itemize} - \item \verb+==+: primerja dve številski vrednosti. - Rezultat je \verb+true+, če sta vrednosti enaki. - \item \verb+!=+: primerja dve številski vrednosti. - Rezultat je \verb+true+, če sta vrednosti različni. - \item \verb+<+: primerja dve številski vrednosti. - Rezultat je \verb+true+, če je vrednost na levi manjša od vrednosti na desni. - \item \verb+>+: deluje podobno kot \verb+<+, le da v drugo smer; - rezultat je \verb+true+, če je vrednost na desni manjša od vrednosti na levi. - \item \verb+<=+: primerja dve številski vrednosti. - Rezultat je \verb+true+, če sta vrednosti enaki, ali če je vrednost - na levi manjša od vrednosti na desni. - \item \verb+>=+ deluje podobno kot \verb+<=+, le da v drugo smer. -\end{itemize} - -\begin{examples} - -Poglejmo si primer uporabe pogojnega stavka. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{k+kt}{int} \PY{n}{a}\PY{p}{,} \PY{n}{b}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} - - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{=}\PY{o}{=} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Stevili sta enaki.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{!}\PY{o}{=} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Stevili sta razlicni.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZlt{}} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Prvo stevilo je manjse od drugega.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZgt{}} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Prvo stevilo je vecje od drugega.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZlt{}}\PY{o}{=} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Prvo stevilo je manjse ali enako drugemu.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZgt{}}\PY{o}{=} \PY{n}{b}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Prvo stevilo je vecje ali enako drugemu.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -12 12 -\tcblower -Stevili sta enaki.\\ -Prvo stevilo je manjse ali enako drugemu.\\ -Prvo stevilo je vecje ali enako drugemu. -\end{inout} - -\begin{inout} -3 7 -\tcblower -Stevili sta razlicni.\\ -Prvo stevilo je manjse od drugega.\\ -Prvo stevilo je majnse ali enako drugemu. -\end{inout} - -\end{examples} - - -\begin{errors} - Pri primerjavi moramo uporabiti dva enačaja (\verb+==+). Če uporabimo samo - en enačaj, kot v matematiki (torej \verb+=+), se bo program sicer zagnal, - vendar ne bo deloval pravilno. - Enojnega enačaja nikoli ne uporabljamo v pogoju \verb+if+ stavka. -\end{errors} - -\begin{errors} - % Pri predelavi v učbenik: pogovor, če je smiselno že tu omenjati strcmp - Taka primerjava deluje samo na številih. Če želimo primerjati dve besedili, - za to potrebujemo posebno funkcijo \verb+strcmp+, ki jo bomo - podrobneje spoznali, ko bomo govorili o besedilu. -\end{errors} - -\begin{examples} - -Primer uporabe stavka \verb+else+. Program bo uporabnika vprašal za PIN, -in mu napisal, če je bil PIN pravilen oziroma napačen. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// Vprasaj uporabnika za PIN, in preveri, ce je pravilen} - \PY{k+kt}{int} \PY{n}{pin}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{pin}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{pin} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{42}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{PIN je pravilen!}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{PIN je napacen!}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -42 -\tcblower -PIN je pravilen! -\end{inout} - -\begin{inout} -7 -\tcblower -PIN je napacen! -\end{inout} - -\end{examples} - -\begin{examples} -\verb+if+ stavke lahko tudi gnezdimo; torej vstavimo enega v drugega. -Spodnji program od uporabnika sprejme naročilo v restavraciji, kjer ponujajo -dve vrsti hrane; juhe in sendviče. Na voljo sta dve vrsti juhe, in dve vrsti -sendvičev. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// Uporabnik naj napise 1, ce zeli juho, in 2, ce zeli sendvic.} - \PY{k+kt}{int} \PY{n}{zelja}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{zelja}\PY{p}{)}\PY{p}{;} - - \PY{k}{if} \PY{p}{(}\PY{n}{zelja} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{1}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// Uporabnik naj napise 1, ce zeli govejo juho,} - \PY{c+c1}{// in 2, ce zeli paradiznikovo.} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{n}{zelja}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{zelja} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{1}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Ena goveja juha. Dober tek!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Ena paradiznikova juha. Dober tek!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{c+c1}{// Uporabnik naj napise 1, ce zeli sendvic s sunko,} - \PY{c+c1}{// in 2, ce zeli vegeterjanski sendvic.} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{zelja}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{zelja} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{1}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{En sendvic s sunko. Dober tek!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{En vegeterjanski sendvic. Dober tek!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -2\\ -1 -\tcblower -En sendvic s sunko. Dober tek! -\end{inout} -\end{examples} - - -\begin{errors} - -Pozorni bodimo tudi na postavitev kode. Običajno kodo znotraj zavitih oklepajev -\verb+if+ stavka pišemo tako, da je poravnana štiri presledke bolj desno od -kode zunaj \verb+if+ stavka. V nekaterih programskih jezikih je taka poravnava -obvezna, v C/C++ pa ne, vendar nezamaknjena koda že v zelo majhnih programih -postane popolnoma nepregledna. Branje in popravljanje kode je veliko lažje, če -del kode znotraj zavitih oklepajev zamaknemo za štiri presledke. Za to lahko -uporabimo tudi tipko Tab, ki se na tipkovnici nahaja levo od tipke Q. - -\vspace{0.3cm} -Tako \textbf{nikoli} ne pišemo: - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} -\PY{k}{if} \PY{p}{(}\PY{l+m+mi}{3} \PY{o}{\PYZgt{}} \PY{l+m+mi}{2}\PY{p}{)} \PY{p}{\PYZob{}} -\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Velja}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} -\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Ne velja}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{p}{\PYZcb{}} -\PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\end{errors} - -\end{document} diff --git a/chapters/arithm/arithm.tex b/chapters/arithm/arithm.tex new file mode 100644 index 0000000..b58fa47 --- /dev/null +++ b/chapters/arithm/arithm.tex @@ -0,0 +1,164 @@ +%#template templates/template.tex + +%#block title +Računske operacije +%#endblock + +%#block content +\section{Seštevanje, odštevanje, množenje} +Računalniki lahko s spremenljivkami počnejo veliko stvari. Najpreprostejše so operacije na številih, kot so seštevanje, odštevanje in množenje. Račune zapisujemo tako kot v šoli, z \emph{operatorji}. +\begin{itemize} + \item \verb-+- za seštevanje + \item \verb+-+ za odštevanje + \item \verb+*+ za množenje +\end{itemize} + +Rezultat lahko izračunamo kar znotraj funkcije \verb+printf+: + + +\begin{examples} + +%#insert python3 style.py < chapters/arithm/sestevanje.cpp + +\begin{inout} + +\tcblower +12 +\end{inout} + + +\end{examples} + +\pagebreak +Rezultat lahko tudi shranimo v novo spremenljivko: +\begin{examples} + +%#insert python3 style.py < chapters/arithm/nova-spremenljivka.cpp + +\begin{inout} +3 7 +\tcblower +12\\ +-4\\ +21 +\end{inout} + +\end{examples} + +\begin{errors} +Spremenljivko \emph{inicializiramo} tako, da notri nekaj shranimo, bodisi kot \verb+a=5+, bodisi s tem, da vanjo nekaj napišemo s funkcijo \verb+scanf+. +Če je ne inicializiramo, pozneje pa jo poskusimo uporabiti za izpisovanje, računanje ali kaj drugega, lahko dobimo zelo čudne rezultate, naš program se lahko celo sesuje. +\end{errors} + +%CHECK +V zgornjem programu tudi vidimo, da lahko z enim klicem funkcije \verb+scanf+ preberemo več spremenljivk. + +\subsection*{Negativna števila} +Na meteorološki postaji Kredarica so leta 2014 izmerili povprečno januarsko temperaturo približno -5 °C, povprečno avgustovsko pa približno 6 °C. +Med tema meritvama je 11 °C razlike. \\ +Pozimi lahko izmerimo temperature manjše od 0. Takšnim številom, kot je -5, rečemo \emph{negativna števila}. Lahko jih uporabimo tudi drugje, ne samo pri merjenju temperature. \\ +S pozitivnimi števili lahko štejemo od 0 do neskončno (1, 2, 3, ...), z negativnimi pa do - neskončno. (-1, -2, -3, ...). Tako kot pozitivna števila jih lahko seštevamo in odštevamo: + +\begin{examples} +5 - 11 = -6 \\ +-6 + 11 = 5 \\ +5 -(-6) = 11 \\ +-2 - 1 = -3 \\ +-2 - (-1) = -1 +-2 + (-1) = -3 \\\\ +\emph{Pravila:}\\ +-(-6) = +6\\ ++(-1) = -1 \\ +-(-(-(-1))) = -(-(+1)) = -(-1) = 1 +\end{examples} + +Lahko jih tudi množimo: + +\begin{examples} +2 * (-5) = -10 \\ +(-5) * (-5) = 25 \\ + +\emph{Pravila:} +Če množimo dve pozitivni števili, je produkt pozitiven. \\ +Če množimo eno pozitivno in eno negativno število, je produkt negativen. \\ +Če množimo dve negativni števili, je produkt spet negativen. \\ +O negativnih številih lahko razmišljamo kot: -3 = (-1) * 3 +\end{examples} + +Računalniki z negativnimi števili računajo enako kot s pozitivnimi: + +\begin{examples} + +%#insert python3 style.py < chapters/arithm/negativna-stevila.cpp + +\begin{inout} +3 7 +\tcblower +Vsota: 10 \\ +Razlika: -4 \\ +Produkt: 21 +\end{inout} + +\end{examples} + +\pagebreak +\section{Deljenje} +Števila lahko tudi delimo. Za deljenje uporabljamo znak \verb+/+. +Za razumevanje poglavja si bomo pomagali s formulo $a = k*b + o$, ki ponazarja deljenje z ostankom. + +\begin{examples} + +%#insert python3 style.py < chapters/arithm/deljenje.cpp + +\begin{inout} +16 8 +\tcblower +2 +\end{inout} + +\end{examples} + +\begin{errors} +Deljenje v jezikih C in C++ je celoštevilsko. Deljenje z ostankom lahko zapišemo po formuli: $a = k*b + o$. + +16/8: 16 = 2*8 + 0 \\ +Ostanek je 0, ker je 16 deljivo z 8. \\\\ + +16/5: 15 = 3*5 + 1 \\ +1 je ostanek. \\\\ + +Celoštevilsko deljenje pomeni, da nam program vnre samo $k$. Primer vhoda in izhoda za zgornji program, kjer števili nista deljivi: + +\begin{inout} +16 3 +\tcblower +5 +\end{inout} + +Tudi, če bi bil rezultat deljenja 7.9, tega program ne zaokroži na 8, temveč nam vrne 7. \\ +Če manjše število delimo z večjim, zato vedno dobimo 0. + +\end{errors} + +\pagebreak +Operator \verb+/+ nam torej iz pri deljenju \verb+a/b+ vrne \verb+k+. Lahko pa dobimo tudi ostanek \verb+o+. Do njega pridemo z operatorjem \verb+%+ (\emph{modulo}). + +\begin{examples} + +%#insert python3 style.py < chapters/arithm/modulo.cpp + +\begin{inout} +25 7 +\tcblower +25 = 3*7 + 4 \\ +Količnik: 3 \\ +Ostanek: 4 +\end{inout} + +\end{examples} + +\begin{errors} +Deljenje z 0 v matematiki ni definirano in prav tako ne v programiranju. Če neko število delimo z 0, se nam bo program sesul. Prav tako, če poskušamo izračunati ostanek pri deljenju z 0. \\ +Ta napaka se pogosto zgodi v programih, kjer delimo z več števili, zato moramo biti na to pozorni. +\end{errors} +%#endblock diff --git a/chapters/arithm/deljenje.cpp b/chapters/arithm/deljenje.cpp new file mode 100644 index 0000000..b00ba05 --- /dev/null +++ b/chapters/arithm/deljenje.cpp @@ -0,0 +1,8 @@ +#include + +int main(){ + int a, b; + scanf("%d%d", &a, &b); + printf("%d\n", a/b); + return 0; +} diff --git a/chapters/arithm/modulo.cpp b/chapters/arithm/modulo.cpp new file mode 100644 index 0000000..4e1cc0e --- /dev/null +++ b/chapters/arithm/modulo.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + int a, b; + scanf("%d%d", &a, &b); + printf("%d = %d*%d + %d\n", a, a/b, b, a%b); + printf("Količnik: %d\nOstanek: %d\n", a/b, a%b); + return 0; +} diff --git a/chapters/arithm/negativna-stevila.cpp b/chapters/arithm/negativna-stevila.cpp new file mode 100644 index 0000000..ee4aee9 --- /dev/null +++ b/chapters/arithm/negativna-stevila.cpp @@ -0,0 +1,8 @@ +#include + +int main(){ + int a, b; + scanf("%d%d", &a, &b); + printf("Vsota: %d\nRazlika: %d\nProdukt: %d\n", a + b, a - b, a * b); + return 0; +} diff --git a/chapters/arithm/nova-spremenljivka.cpp b/chapters/arithm/nova-spremenljivka.cpp new file mode 100644 index 0000000..7799d23 --- /dev/null +++ b/chapters/arithm/nova-spremenljivka.cpp @@ -0,0 +1,11 @@ +#include + +int main(){ + int a, b, vsota, razlika, produkt; + scanf("%d%d", &a, &b); + vsota = a+b; + razlika = a-b; + produkt = a*b; + printf("%d\n%d\n%d\n", vsota, razlika, produkt); + return 0; +} diff --git a/chapters/arithm/sestevanje.cpp b/chapters/arithm/sestevanje.cpp new file mode 100644 index 0000000..00ee630 --- /dev/null +++ b/chapters/arithm/sestevanje.cpp @@ -0,0 +1,7 @@ +#include + +int main(){ + int a = 5, b = 7; + printf("%d\n", a+b); + return 0; +} diff --git a/chapters/asimptoticna-notacija/asimptoticna-notacija.tex b/chapters/asimptoticna-notacija/asimptoticna-notacija.tex new file mode 100644 index 0000000..2919080 --- /dev/null +++ b/chapters/asimptoticna-notacija/asimptoticna-notacija.tex @@ -0,0 +1,155 @@ +%#template templates/template.tex + +%#block title +Efektivnost programov in asimptotična notacija +%#endblock + +%#block content +\section{Merjenje efektivnosti programa} + +Pogosto obstaja več možnosti, kako se lahko lotimo reševanja danega problema. +Če želimo najti najmanjši element v seznamu, lahko pregledamo celoten seznam in +si beležimo najmanjšega, ki smo ga našli do sedaj, lahko pa celoten seznam +uredimo po vrsti in nato izberemo prvi element, na primer. +Pričakujemo lahko, da se bodo različni algoritmi za reševanje istega problema +razlikovali tudi po tem, kako hitro problem rešijo. +Kako pa v računalništvu izmerimo hitrost? Če delamo samo na enem računalniku, +lahko izmerimo, konkretno koliko časa je program potreboval, da je zaključil +z delovanjem. Na ta način lahko na primerih demonstriramo, da je nek algoritem +boljši od drugega; ko pa želimo naše rezultate deliti in primerjati z drugimi, +pa se ne moramo zanašati, da bodo imeli enako močen računalnik kot mi, in da +bodo njihovi testni primeri primerljivo zahtevni z našimi. Dejansko so težave +pri tem še hujše; na hitrost delovanja našega programa ne vpliva samo strojna +oprema računalnika (torej, kakšen procesor ima, koliko ima spomina itd.), temveč +tudi ostali programi, ki jih imamo hkrati odprte. +Če se želimo pogovarjati o hitrosti algoritmov, potrebujemo bolj abstraktno +orodje. Na pomoč pride asimptotična zahtevnost. + +Da določimo hitrost našega programa, moramo prvo določiti, katere spremenljivke +vplivajo na čas delovanja, ter kako je čas od njih odvisen. +Rezultat take analize zapišemo kot izraz v oklepaje, pred katere zapišemo +veliko črko O: \(O(\ldots)\) +Poglejmo si primer. + +%#insert python3 style.py < chapters/asimptoticna-notacija/poisci-najmanjsega.cpp + +Funkcija \verb+poisci_najmanjsega+ sprejme število \(n\), ki pove dolžino seznama +\verb+arr+. Po seznamu se nato enkrat sprehodi, in si ob tem beleži indeks +najmanjšega elementa, ki ga je do sedaj našla. + +Razmislimo, katere vse različne operacije program opravi. +\begin{itemize} + \item + Večkrat med programom nastavimo neki spremenljivki novo vrednost. + \item + V vsaki iteraciji zanke prištejemo 1 spremenljivki \verb+i+. + \item + Poleg tega v vsaki iteraciji zanke tudi primerjamo \verb+i+ z \verb+n+, + \item + dvakrat dostopamo do nekega elementa v seznamu, + \item + ter ju primerjamo. + \item + Na koncu še enkrat dostopamo do elementa v seznamu, ter ga vrnemo. +\end{itemize} + +Vse naštete operacije same po sebi \emph{trajajo} \(O(1)\) časa. To pomeni, da +se vedno izvajajo enako hitro, neodvisno od parametrov, ki jim podamo. Rečemo +tudi, da porabijo \emph{konstantno mnogo} časa. + +Kolikokrat pa izvedemo te operacije? Analizirajmo najslabši primer za naš +program; če je seznam \verb+arr+ padajoče urejen. Tedaj bomo v vsaki iteraciji +zanke enkrat primerjali \verb+i < n+, dvakrat dostopali do elementov seznama, +enkrat primerjali \verb+arr[min_idx] > arr[i]+, enkrat nastavili \verb+min_idx+, +ter enkrat povečali \verb+i+. Zunaj zanke bomo nastavili \verb+min_idx+ ter +\verb+i+ na začetni vrednosti, ter še enkrat dostopali do elementa v seznamu. +Zanka se vedno izvaja za natanko \verb+n+ iteracij; vedno vsak element pregledamo +enkrat. Torej je celotna časovna zahtevnost našega programa \(O(3 + 6n)\). +Ker pa za velike \(n\) del zunaj zanke hitro postane nepomemben, ga ignoriramo. +Poleg tega ignoriramo tudi faktor pred členom \(n\) -- ker tako in tako ne moramo +vedeti, kako hitre so operacije v zanki v primerjavi druga z drugo, te konstante +ne moramo natančno določiti. Končna časovna zahtevnost našega programa je torej +\(O(n)\). + +To je tudi najboljši možni algoritem za iskanje najmanjšega elementa v seznamu. +Če bi nek algoritem namreč deloval v hitrejšem času kot \(O(n)\), bi moral +nekatera mesta v seznamu izpustiti; če tedaj algoritmu podamo seznam, ki ima +najmanjši element ravno na takem mestu, ga algoritem ne bo našel, in bo podal +napačen odgovor. + +Pomembna opazka je, da hitrost našega algoritma ni odvisna od velikosti števil +v seznamu, temveč le od velikosti seznama. Naslednji program prav tako poišče +najmanjše število v seznamu, vendar je konkretno počasnejši od zgornjega: + +%#insert python3 style.py < chapters/asimptoticna-notacija/poisci-najmanjsega-slabsi.cpp + +V tem programu imamo dve zanki; ena se sprehaja po vseh možnih vrednosti števil +v seznamu, druga pa preverja, če je ta element dejansko v seznamu. Vsakič, ko se +zunanja zanka izvede enkrat, se notranja izvede \verb+n+-krat (v najslabšem +primeru), zunanja zanka pa se izvede \verb|m+1|-krat. Torej je zahtevnost +\(O((m+1) \cdot n)\), oziroma \(O(mn + n)\). Člen \(n\) v vsoti pa je v vseh +primerih manjši od člena \(mn\) ali njemu enako velik, zato ga izpustimo. +Končna časovna zahtevnost drugega algoritma je torej \(O(mn)\). + +\verb+int+ lahko hrani števila, velika do približno dve milijardi -- najslabšem +primeru je \(m\) torej približno \(2 \cdot 10^9\). Če prvi algoritem na nekem +računalniku potrebuje eno sekundo, da se konča, bi drugi algoritem v najslabšem +primeru na istem računalniku potreboval več kot šestdeset let. + +\begin{examples} + + Naslednji program za vsako število v seznamu \verb+arr+ poišče število števil desno od njega, ki so večja. + + %#insert python3 style.py < chapters/asimptoticna-notacija/stevilo-vecjih.cpp + + Notranja zanka se v prvi iteraciji izvede \((n-1)\)-krat, v drugi iteraciji + \((n-2)\)-krat, v tretji \((n-3)\)-krat, itd. V zadnji iteraciji se sploh ne + izvede. Skupaj se koda znotraj druge zanke torej izvede + \((n-1) + (n-2) + \ldots + 1 + 0 = \frac{n(n-1)}{2}\)-krat. Spet ignoriramo + konstanto \(\frac{1}{2}\) ter člen samo z \(n\), in pridemo do zahtevnosti + \(O(n^2)\). + +\end{examples} + +\begin{examples} + + Naslednji program preveri, če je število \(n\) praštevilo. + + % Zahvala Roku Lavriču za popravek v kodi + %#insert python3 style.py < chapters/asimptoticna-notacija/prastevilo.cpp + + Program ima eno zanko, ki se sprehaja toliko časa, da kvadrat spremenljivke + \(i\) postane večji kot \(n\), oz.~dokler je \(i \le \sqrt{n}\). Zanka se torej + izvede v \(O(\sqrt{n})\). + +\end{examples} + +\pagebreak +\section{Klasifikacija} + +Računalnik lahko v eni sekundi opravi približno \(10^7\) operacij. Da določimo, +kako dober algoritem potrebujemo za rešitev neke naloge, lahko preverimo +omejitve vhodnih podatkov. Spodnja tabela prikazuje nekaj pogostih časovnih +zahtevnosti, ter pripadajoče največje omejitve. Z uporabo te tabele lahko +vnaprej določimo, kakšno največjo časovno zahtevnost mora imeti naš program, +da reši določeno nalogo. + +\begin{table}[h!] + \centering + \begin{tabular}{|c|c|c|} + \hline + Zahtevnost & Omejitev za \(n\) & Ime zahtevnosti \\ + \hline + \(O(1)\) & brez & \emph{konstantna} \\ + \(O(\log n)\) & zelo visoka & \emph{logaritemska} \\ + \(O(\sqrt{n})\) & \(10^{14}\) & \emph{korenska} \\ + \(O(n)\) & \(10^7\) & \emph{linearna} \\ + \(O(n \log n)\) & \(10^6\) & \\ + \(O(n^2)\) & \(10^4\) & \emph{kvadratna} \\ + \(O(n^3)\) & \(300\) & \emph{kubična} \\ + \(O(2^n)\) & \(20\) & \emph{eksponentna} \\ + \hline + \end{tabular} +\end{table} + +%#endblock \ No newline at end of file diff --git a/chapters/asimptoticna-notacija/poisci-najmanjsega-slabsi.cpp b/chapters/asimptoticna-notacija/poisci-najmanjsega-slabsi.cpp new file mode 100644 index 0000000..a7c74ff --- /dev/null +++ b/chapters/asimptoticna-notacija/poisci-najmanjsega-slabsi.cpp @@ -0,0 +1,18 @@ +int arr[100002]; +int poisci_najmanjsega_slabsi(int n, int m) { + // Poišči najmanjše število v seznamu, dolgemu n, + // kjer je največje število veliko največ m + for (int zelja = 0; zelja <= m; zelja++) { + // zelja nam pove, kateri element si v tej iteraciji želimo + // najti. Pogledati moramo še, da ta element dejansko je v seznamu; + // ko pa najdemo enega, bo to najmanjši (ker zelja v vsaki iteraciji + // narasca) + bool je_v_seznamu = false; + for (int i = 0; i < n; i++) { + if (arr[i] == zelja) + je_v_seznamu = true; + } + if (je_v_seznamu) + return zelja; + } +} diff --git a/chapters/asimptoticna-notacija/poisci-najmanjsega.cpp b/chapters/asimptoticna-notacija/poisci-najmanjsega.cpp new file mode 100644 index 0000000..88cfbca --- /dev/null +++ b/chapters/asimptoticna-notacija/poisci-najmanjsega.cpp @@ -0,0 +1,12 @@ +int arr[100002]; + +int poisci_najmanjsega(int n) { + // Poišči najmanjše število v seznamu, dolgemu n + int min_idx = 0; + for (int i = 0; i < n; i++) { + if (arr[min_idx] > arr[i]) { + min_idx = i; + } + } + return arr[min_idx]; +} diff --git a/chapters/asimptoticna-notacija/prastevilo.cpp b/chapters/asimptoticna-notacija/prastevilo.cpp new file mode 100644 index 0000000..fa6a9c6 --- /dev/null +++ b/chapters/asimptoticna-notacija/prastevilo.cpp @@ -0,0 +1,10 @@ +bool preklicano = false; +for (int i = 2; i * i < n; i++) { + if (n % i == 0) { + printf("%d ni prastevilo\n", n); + preklicano = true; + break; + } +} +if (!preklicano) + printf("%d je prastevilo\n", n); diff --git a/chapters/asimptoticna-notacija/stevilo-vecjih.cpp b/chapters/asimptoticna-notacija/stevilo-vecjih.cpp new file mode 100644 index 0000000..ca06bcc --- /dev/null +++ b/chapters/asimptoticna-notacija/stevilo-vecjih.cpp @@ -0,0 +1,9 @@ +for (int i = 0; i < n; i++) { + int stevilo = 0; + for (int j = i+1; j < n; j++) { + if (arr[j] > arr[i]) { + stevilo++; + } + } + printf("%d\n", stevilo); +} diff --git a/chapters/basic_conditionals/basic_conditionals.tex b/chapters/basic_conditionals/basic_conditionals.tex new file mode 100644 index 0000000..ff9574c --- /dev/null +++ b/chapters/basic_conditionals/basic_conditionals.tex @@ -0,0 +1,145 @@ +%#template templates/template.tex + +%#block title +Pogojni stavki +%#endblock + +%#block content + +Pogosto želimo, da računalnik izvaja drugačno kodo glede na vrednost ene ali +večih spremenljivk, npr. da nam pokaže drugačno vsebino, če smo napisali +pravilno ali napačno geslo, da računalo sešteva, če smo pritisnili gumb za +seštevanje, oz. odšteva, če smo pritisnili gumb za odštevanje, ipd. Z drugimi +besedami, želimo upravljati potek programa (torej izbrati, katera koda naj +se izvede) glede na vrednosti spremenljivk. Angleško takemu upravljanju +pravimo \emph{control flow}, najpogosteje pa ga izvajamo s t.i. \emph{pogojnimi} +ali \emph{if stavki}. Osnovna struktura je sledeča: + +\begin{examples} + +%#insert python3 style.py < chapters/basic_conditionals/sintaksa.cpp + +\end{examples} + +\emph{Pogoj} je nov pojem. Označuje neke vrste račun, katerega rezultat ni +število, vendar \emph{logična vrednost}. Tu sta možni vrednosti le dve: +pravilno (angl.~\verb+true+) in napačno (angl.~\verb+false+). Če bo rezultat +računa, navedenega v običajnih oklepajih v zgornjem \verb+if+ stavku, +\verb+true+, +se bo izvedla koda znotraj prvih zavitih oklepajev, če pa je rezultat računa +\verb+false+, pa se bo izvedla koda v drugih zavitih oklepajih (tistih za besedo +\verb+else+). Drugega dela, t.j. \verb+else+ in oklepaji za njim, ni treba +pisati, če ga ne želimo. + +Kako pa zapišemo pogoj? Za to uporabimo posebne logične operatorje. Pri delu s +številkami so nam na voljo naslednji: +\begin{itemize} + \item \verb+==+: primerja dve številski vrednosti. + Rezultat je \verb+true+, če sta vrednosti enaki. + \item \verb+!=+: primerja dve številski vrednosti. + Rezultat je \verb+true+, če sta vrednosti različni. + \item \verb+<+: primerja dve številski vrednosti. + Rezultat je \verb+true+, če je vrednost na levi manjša od vrednosti na desni. + \item \verb+>+: deluje podobno kot \verb+<+, le da v drugo smer; + rezultat je \verb+true+, če je vrednost na desni manjša od vrednosti na levi. + \item \verb+<=+: primerja dve številski vrednosti. + Rezultat je \verb+true+, če sta vrednosti enaki, ali če je vrednost + na levi manjša od vrednosti na desni. + \item \verb+>=+ deluje podobno kot \verb+<=+, le da v drugo smer. +\end{itemize} + +\begin{examples} + +Poglejmo si primer uporabe pogojnega stavka. + +%#insert python3 style.py < chapters/basic_conditionals/stevila.cpp + +\begin{inout} +12 12 +\tcblower +Stevili sta enaki.\\ +Prvo stevilo je manjse ali enako drugemu.\\ +Prvo stevilo je vecje ali enako drugemu. +\end{inout} + +\begin{inout} +3 7 +\tcblower +Stevili sta razlicni.\\ +Prvo stevilo je manjse od drugega.\\ +Prvo stevilo je majnse ali enako drugemu. +\end{inout} + +\end{examples} + + +\begin{errors} + Pri primerjavi moramo uporabiti dva enačaja (\verb+==+). Če uporabimo samo + en enačaj, kot v matematiki (torej \verb+=+), se bo program sicer zagnal, + vendar ne bo deloval pravilno. + Enojnega enačaja nikoli ne uporabljamo v pogoju \verb+if+ stavka. +\end{errors} + +\begin{errors} + % Pri predelavi v učbenik: pogovor, če je smiselno že tu omenjati strcmp + Taka primerjava deluje samo na številih. Če želimo primerjati dve besedili, + za to potrebujemo posebno funkcijo \verb+strcmp+, ki jo bomo + podrobneje spoznali, ko bomo govorili o besedilu. +\end{errors} + +\begin{examples} + +Primer uporabe stavka \verb+else+. Program bo uporabnika vprašal za PIN, +in mu napisal, če je bil PIN pravilen oziroma napačen. + +%#insert python3 style.py < chapters/basic_conditionals/pin.cpp + +\begin{inout} +42 +\tcblower +PIN je pravilen! +\end{inout} + +\begin{inout} +7 +\tcblower +PIN je napacen! +\end{inout} + +\end{examples} + +\begin{examples} +\verb+if+ stavke lahko tudi gnezdimo; torej vstavimo enega v drugega. +Spodnji program od uporabnika sprejme naročilo v restavraciji, kjer ponujajo +dve vrsti hrane; juhe in sendviče. Na voljo sta dve vrsti juhe, in dve vrsti +sendvičev. + +%#insert python3 style.py < chapters/basic_conditionals/nesting.cpp + +\begin{inout} +2\\ +1 +\tcblower +En sendvic s sunko. Dober tek! +\end{inout} +\end{examples} + + +\begin{errors} + +Pozorni bodimo tudi na postavitev kode. Običajno kodo znotraj zavitih oklepajev +\verb+if+ stavka pišemo tako, da je poravnana štiri presledke bolj desno od +kode zunaj \verb+if+ stavka. V nekaterih programskih jezikih je taka poravnava +obvezna, v C/C++ pa ne, vendar nezamaknjena koda že v zelo majhnih programih +postane popolnoma nepregledna. Branje in popravljanje kode je veliko lažje, če +del kode znotraj zavitih oklepajev zamaknemo za štiri presledke. Za to lahko +uporabimo tudi tipko Tab, ki se na tipkovnici nahaja levo od tipke Q. + +\vspace{0.3cm} +Tako \textbf{nikoli} ne pišemo: + +%#insert python3 style.py < chapters/basic_conditionals/unindented.cpp + +\end{errors} + +%#endblock diff --git a/chapters/basic_conditionals/nesting.cpp b/chapters/basic_conditionals/nesting.cpp new file mode 100644 index 0000000..fc954ff --- /dev/null +++ b/chapters/basic_conditionals/nesting.cpp @@ -0,0 +1,26 @@ +#include +int main() { + // Uporabnik naj napise 1, ce zeli juho, in 2, ce zeli sendvic. + int zelja; + scanf("%d", &zelja); + if (zelja == 1) { + // Uporabnik naj napise 1, ce zeli govejo juho, + // in 2, ce zeli paradiznikovo. + scanf("%d", zelja); + if (zelja == 1) { + printf("Ena goveja juha. Dober tek!\n"); + } else { + printf("Ena paradiznikova juha. Dober tek!\n"); + } + } else { + // Uporabnik naj napise 1, ce zeli sendvic s sunko, + // in 2, ce zeli vegeterjanski sendvic. + scanf("%d", &zelja); + if (zelja == 1) { + printf("En sendvic s sunko. Dober tek!\n"); + } else { + printf("En vegeterjanski sendvic. Dober tek!\n"); + } + } + return 0; +} diff --git a/chapters/basic_conditionals/pin.cpp b/chapters/basic_conditionals/pin.cpp new file mode 100644 index 0000000..3960960 --- /dev/null +++ b/chapters/basic_conditionals/pin.cpp @@ -0,0 +1,13 @@ +#include + +int main() { + // Vprasaj uporabnika za PIN, in preveri, ce je pravilen + int pin; + scanf("%d", &pin); + if (pin == 42) { + printf("PIN je pravilen!"); + } else { + printf("PIN je napacen!"); + } + return 0; +} diff --git a/chapters/basic_conditionals/sintaksa.cpp b/chapters/basic_conditionals/sintaksa.cpp new file mode 100644 index 0000000..8cf263a --- /dev/null +++ b/chapters/basic_conditionals/sintaksa.cpp @@ -0,0 +1,5 @@ +if (pogoj) { + // koda, ki se izvede, ce pogoj velja +} else { + // koda, ki se izvede, ce pogoj ne velja +} diff --git a/chapters/basic_conditionals/stevila.cpp b/chapters/basic_conditionals/stevila.cpp new file mode 100644 index 0000000..0e4d7cd --- /dev/null +++ b/chapters/basic_conditionals/stevila.cpp @@ -0,0 +1,25 @@ +#include + +int main() { + int a, b; + scanf("%d%d", &a, &b); + if (a == b) { + printf("Stevili sta enaki.\n"); + } + if (a != b) { + printf("Stevili sta razlicni.\n"); + } + if (a < b) { + printf("Prvo stevilo je manjse od drugega.\n"); + } + if (a > b) { + printf("Prvo stevilo je vecje od drugega.\n"); + } + if (a <= b) { + printf("Prvo stevilo je manjse ali enako drugemu.\n"); + } + if (a >= b) { + printf("Prvo stevilo je vecje ali enako drugemu.\n"); + } + return 0; +} diff --git a/chapters/basic_conditionals/unindented.cpp b/chapters/basic_conditionals/unindented.cpp new file mode 100644 index 0000000..8e23e27 --- /dev/null +++ b/chapters/basic_conditionals/unindented.cpp @@ -0,0 +1,9 @@ +#include +int main() { +if (3 > 2) { +printf("Velja\n"); +} else { +printf("Ne velja\n"); +} +return 0; +} diff --git a/chapters/for-loop/branje-stevil.cpp b/chapters/for-loop/branje-stevil.cpp new file mode 100644 index 0000000..6000907 --- /dev/null +++ b/chapters/for-loop/branje-stevil.cpp @@ -0,0 +1,14 @@ +#include + +int main() { + int n; + scanf("%d", &n); + int vsota = 0; + for (int i=0; i < n; i++) { + int sestevanec; + scanf("%d", &sestevanec); + vsota += sestevanec; + } + printf("%d\n", vsota); + return 0; +} diff --git a/chapters/for-loop/branje-z-while.cpp b/chapters/for-loop/branje-z-while.cpp new file mode 100644 index 0000000..5cc6ad3 --- /dev/null +++ b/chapters/for-loop/branje-z-while.cpp @@ -0,0 +1,11 @@ +#include + +int main() { + int produkt = 1; + int clen; + while (scanf("%d", &clen) == 1) { + produkt = produkt * clen; + } + printf("%d\n", produkt); + return 0; +} diff --git a/chapters/for-loop/for-loop.tex b/chapters/for-loop/for-loop.tex new file mode 100644 index 0000000..794ca02 --- /dev/null +++ b/chapters/for-loop/for-loop.tex @@ -0,0 +1,221 @@ +%#template templates/template.tex + +%#block title +For zanka +%#endblock + +%#block content + +\section{Kako napišemo zanko?} + +V programiranju pogosto želimo nek del kode ponoviti, zato imamo \emph{zanke}. +Zanka, ki jo bomo najpogosteje uporabljali je \emph{for} zanka, +ki deluje na princip \textbf{začetka}, \textbf{pogoja} in \textbf{koraka}. +\begin{examples} +\verb+Najbolj osnoven program, ki uporablja for zanko.+ + +%#insert python3 style.py < chapters/for-loop/sintaksa.cpp + +\begin{inout} + nekaj \\ + nekaj \\ + nekaj +\end{inout} + +\end{examples} + +Poglejmo si, kako ta program deluje. Podpičja v vrstici \\ +\texttt{for~({\textcolor{red}{int~stevec=0}};~\textcolor{blue}{stevec~<~3};~\textcolor{purple}{stevec++})~\{} \\ +razdelijo okrogle oklepaje na tri dele; \textcolor{red}{začetek}, +\textcolor{blue}{pogoj} in \textcolor{purple}{korak}. +Začetek se bo izvedel, ko se ta zanka začne. Vsakič preden se izvede koda +v notranjosti zanke se preveri pogoj, če drži, +se bo še enkrat izvedla koda v zanki, sicer se bo pa zanka končala. +Korak je podoben začetku, le da se izvede na koncu vsake ponovitve zanke. + +Tu začetek naredi novo številko $stevec$ in jo nastavi na $0$. +Pogoj preveri, če je $stevec$ manjši od $3$. Korak \texttt{stevec++} je pa +okrajšava za \texttt{stevec = stevec + 1}, torej poveča $stevec$ za $1$. + +\begin{itemize} + \item Program se začne in pride do for zanke, + najprej se izvede začetek \texttt{int~stevec=0}. + \item Zdaj se je začela zanka, preveri se pogoj \texttt{stevec~<~3}. + Ker je $stevec$ za zdaj še $0$, je pogoj izpolnjen. Izvede se vsebina zanke, + torej program izpiše \emph{nekaj}. Zdaj smo prišli do konca zanke, + izvede se korak, $stevec$ se poveča na $1$, program pa skoči nazaj na + začetek zanke. + \item Ker smo na začetku zanke se preveri pogoj, \texttt{stevec~<~3}, + ker je $stevec$ zdaj $1$ je pogoj še vedno izpolnjen, zato se izvede + vsebina zanke. Ko program še enkrat izpiše \emph{nekaj} izvede korak, + $stevec$ poveča na $2$ in skoči nazaj na začetek. + \item Spet smo na začetku, zato se preveri pogoj, $stevec$ je zdaj $2$, + kar je manjše od $3$, zato se \emph{nekaj} spet izpiše. Program poveča + $stevec$ na $3$ in skoči nazaj na začetek. + \item Ker smo spet na začetku se bo še enkrat preveril pogoj, + a zdaj je $stevec$ enak $3$ in $3$ ni manjše od $3$, + zato se for zanka konča. Ker je naslednji ukaz \texttt{return 0;} se bo + program tam končal. +\end{itemize} + +Vidimo, da bo res izpisal \emph{nekaj} trikrat. Vredno je omeniti, +da je naš števec zavzel vrednosti 0, 1, 2, kar se mogoče zdi čudno, glede na +to, da bi ponavadi šteli do tri kot 1, 2, 3, a je \emph{štetje od nič} zelo +pogosto v programiranju, zato smo se odločili, da vas že od začetka poskušamo +navaditi nanj. + +\section{Razni primeri uporabe for zanke} + +\subsection{Spreminjanje dolžine for zanke} +Zanka, ki smo jo napisali zgoraj, se bo vedno ponovila trikrat, +kaj pa če hočemo da se zanka ponovi glede na neko število na vhodu? +Seveda je tudi to mogoče in sicer tako, da vstavimo našo spremenljivko v pogoj +for zanke. Poglejmo si primer: + +\begin{examples} +\verb+Program, ki dobi število in nariše puščico te dolžine.+ + +\verb+Še en trik tu je, da printf-ja v for zanki ne končamo z \n, kar doseže+ + +\verb+to, da so v izhodu pomišljaji eden zraven drugega v isti vrstici in ne+ + +\verb+vsak v svoji vrstici.+ + +%#insert python3 style.py < chapters/for-loop/puscica.cpp + +\begin{inout} + 4 + \tcblower + -{}-{}-{}-> +\end{inout} + +\end{examples} + +\subsection{Branje števil v for zanki} + +Ena od moči računalnikov je zelo hitra obdelava velike količine podatkov, +računalnik bo zlahka seštel 1000 števil, medtem ko bi bilo to početi na roko +precej zamudno. Poglejmo si, kako bi napisali program, ki bi nekaj izračunal z +več števili. + +\begin{examples} +\verb+Najprej preberemo eno število, recimo mu n.+ + +\verb+Po njemu moramo prebrati še n števili in jih sešteti.+ + +%#insert python3 style.py < chapters/for-loop/branje-stevil.cpp + +\begin{inout} + 4 \\ + 12 \\ + 13 \\ + 8 \\ + 1 + \tcblower + 34 +\end{inout} + +\end{examples} + +V zgornjem primeru se je zgodilo precej novih stvari, poglejmo si vse po vrsti. + +Najprej preberemo n iz navodil. Naredimo novo spremenljivko z imenom $vsota$, v njo +bomo sešteli vsa dana števila. + +Opazimo, da je v for zanki namesto $stevec$ zdaj uporabljen $i$, tradicionalno +se namreč v for zankah uporablja $i$. +V notranjosti zanke so zdaj trije ukazi. Najprej naredimo novo +spremenljivko, ki jo poimenujemo $sestevanec$ in preberemo naslednje +število iz vhoda. Nato pa z okrajšavo \texttt{vsota~+=~sestevanec;} prištejemo +spremenljivki $vsota$ spremenljivko $sestevanec$. Na daljše bi to lahko napisali +\texttt{vsota~=~vsota~+~sestevanec}. + +\subsection{While zanka in branje neznano mnogo števil} + +Naučili smo se, kako se prebere nekaj števil, ko nam je podano koliko števil +moramo prebrati. Kaj pa če tega ne vemo, če hočemo pač prebrati vsa števila, +ki so na vhodu? Zato lahko uporabimo \emph{while} zanko, ki deluje tako kot +for zanka, le da ima samo pogoj. + +\begin{examples} +\verb+Preperimo vsa števila in jih zmnožimo.+ + +%#insert python3 style.py < chapters/for-loop/branje-z-while.cpp + +\begin{inout} + 2 \\ + 3 \\ + 4 \\ + 5 + \tcblower + 120 +\end{inout} + +\end{examples} + +Kot že povedano, zgoraj napisani stavek while bi enako napisali kot +\texttt{for~(~;~scanf("\%d")~==~1~;~)}, torej for zanka, ki ima samo pogoj. +Mogoče se zdi čudno, da ukaz scanf \emph{primerjamo} s številko, a bomo kasneje +v letu, ko se bomo učili o funkcijah razumeli, kaj to pomeni. Za zdaj pa +bomo rekli le, da to, da je scanf \emph{enak} ena pomeni, da je uspešno prebral +in shranil eno številko. Če bi zgornji program prebral v človeških besedah, bi +bilo: +\begin{itemize} + \item Nastavi $produkt$ na 1 + \item Naredi novo spremenljivko $clen$ + \item Preberi eno število in ga shrani v $clen$, dokler tega ne moreš + narediti več. + \item Nastavi $produkt$ na $produkt * clen$ + \item Ko končaš s množenjem vseh členov, izpiši rezultat. +\end{itemize} + +\begin{errors} +\verb+Tu na začetku nastavimo produkt na 0, kar pa je napaka, saj je 0 krat+ + +\verb+karkoli še vedno 0. Naš program bo veno izpisal 0 ne glede na vhod.+ + +%#insert python3 style.py < chapters/for-loop/napaka.cpp + +\end{errors} + +\subsection{For zanka z drugačnim korakom in začetkom} + +Do zdaj so vse naše for zanke izgledale nekako tako +\texttt{for~(int~i=0;~i~<~10;~i++)}, torej so začele na nič in se nekajkrat +ponovile. Ampak zapis for zanke, ki ga imamo v c++ lahko naredi veliko več. +Poglejmo kot primer zanko, ki izpiše vsa soda števila med $1$ in $100$. + +Pozorno poglejmo števila, ki jih moramo izpisati. Ker $1$ ni sodo, bo prvo +izpisano število $2$. Število $3$ prav tako ni sodo, tako da bomo izpisali $4$, +po tem pa $6$, $8$, $10$ in tako dalje. Vidimo, da vsak korak povečamo izpisano +število za $2$, napišimo torej program. + +\begin{examples} +\verb+Izpišemo vsa soda števila med 1 in 100.+ + +%#insert python3 style.py < chapters/for-loop/soda-stevila.cpp + +\begin{inout} + 2 \\ + 4 \\ + 6 \\ + 8 \\ + 10 \\ + 12 \\ + $\vdots$ \\ + 96 \\ + 98 \\ + 100 +\end{inout} + +\end{examples} + +Ker se želena števila začnejo z dva, bomo v začetni del for zanke vpisali +\texttt{int i=2}. Ker hočemo izpisati števila med $1$ in $100$ in ne med $1$ in +$99$ bomo v pogojnem delu uporabili znak manjše ali enako \texttt{i<=100} +(pogoj \texttt{i<100} ne bi veljal za število $100$). Ker želimo povečati naše +število za $2$ vsak korak, smo v polje za korak napisali \texttt{i += 2}. +Edina stvar, ki jo naredimo v notranjosti napisane zanke pa je, da izpišemo +trenutno vrednost spremenljivke $i$. + +%#endblock diff --git a/chapters/for-loop/napaka.cpp b/chapters/for-loop/napaka.cpp new file mode 100644 index 0000000..e9ae21b --- /dev/null +++ b/chapters/for-loop/napaka.cpp @@ -0,0 +1,11 @@ +#include + +int main() { + int produkt = 0; + int clen; + while (scanf("%d", &clen) == 1) { + produkt = produkt * clen; + } + printf("%d\n", produkt); + return 0; +} diff --git a/chapters/for-loop/puscica.cpp b/chapters/for-loop/puscica.cpp new file mode 100644 index 0000000..3c866b3 --- /dev/null +++ b/chapters/for-loop/puscica.cpp @@ -0,0 +1,11 @@ +#include + +int main() { + int dolzina; + scanf("%d", &dolzina); + for (int stevec=0; stevec < dolzina; stevec++) { + printf("-"); + } + printf(">\n"); + return 0; +} diff --git a/chapters/for-loop/sintaksa.cpp b/chapters/for-loop/sintaksa.cpp new file mode 100644 index 0000000..0ab57a8 --- /dev/null +++ b/chapters/for-loop/sintaksa.cpp @@ -0,0 +1,10 @@ +#include + +int main() { + // začetek pogoj korak + for (int stevec=0; stevec < 3; stevec++) { + // koda, ki se izvedce vsako zanko + printf("nekaj\n"); + } + return 0; +} diff --git a/chapters/for-loop/soda-stevila.cpp b/chapters/for-loop/soda-stevila.cpp new file mode 100644 index 0000000..2353614 --- /dev/null +++ b/chapters/for-loop/soda-stevila.cpp @@ -0,0 +1,8 @@ +#include + +int main() { + for (int i=2; i<=100; i += 2) { + printf("%d\n", i); + } + return 0; +} diff --git a/chapters/inout/branje.cpp b/chapters/inout/branje.cpp new file mode 100644 index 0000000..8c46919 --- /dev/null +++ b/chapters/inout/branje.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + char ime[50]; + printf("Kako ti je ime?\n"); + scanf("%s", ime); + printf("Zivjo, %s!\n", ime); + return 0; +} diff --git a/chapters/inout/branje_stevil.cpp b/chapters/inout/branje_stevil.cpp new file mode 100644 index 0000000..33bf8da --- /dev/null +++ b/chapters/inout/branje_stevil.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + int razred; + printf("Kateri razred si?\n"); + scanf("%d", &razred); + printf("%d. razred je najboljši.\n", razred); + return 0; +} diff --git a/chapters/inout/helloworld.cpp b/chapters/inout/helloworld.cpp new file mode 100644 index 0000000..0596ef3 --- /dev/null +++ b/chapters/inout/helloworld.cpp @@ -0,0 +1,6 @@ +#include + +int main(){ + printf("Hello World!\n"); + return 0; +} diff --git a/chapters/inout/inout.tex b/chapters/inout/inout.tex new file mode 100644 index 0000000..61737d9 --- /dev/null +++ b/chapters/inout/inout.tex @@ -0,0 +1,122 @@ +%#template templates/template.tex + +%#block title +Branje in pisanje +%#endblock + +%#block content +\section{Vhod in izhod} +Programi za svoje delovanje potrebujejo način za komunikacijo z +uporabnikom. Kompleksnejši programi v ta namen uporabljajo ekran, miško +in tipkovnico. Pri tekmovalnem programiranju pa najpogosteje uporabljamo najpreprostejši način za komunikacijo: pisanje in branje s \emph{standardnega vhoda in izhoda}. Običajno to pomeni, da se nam ob zagonu programa odpre okno, kamor lahko pišemo programu in kamor program izpisuje stvari.\\ +Ko želimo, da naš program kaj izpiše, uporabimo \emph{funkcijo} \verb+printf+. +\begin{examples} + +%#insert python3 style.py < chapters/inout/helloworld.cpp + +\begin{inout} +\tcblower +Hello World! +\end{inout} + +\end{examples} + +\verb+printf+ - funkcija, ki ji v dvojnih narekovajih damo besedilo ali števila, ki jih želimo izpisati\\ +\verb+\n+ - znak za novo vrstico +\\\\ +Stvari, ki jih mora vsebovati (skoraj) vsak program: +\begin{itemize} + \item \verb+stdio.h+ - \emph{knjižnica} (datoteka), ki vsebuje funkcije, ki jih bomo uporabljali v programu (kot npr. \verb+printf+ in \verb+scanf+) + \item \verb+#include<>+ - ukaz, s katerim našemu programu povemo, katere knjižnice potrebuje + \item \verb+int main(){}+ - telo našega programa - večino kode v programu napišemo med zavite oklepaje + \item \verb+return 0+ - zadnja vrstica v programu, ki sporoča računalniku, da se je pravilno zaključil +\end{itemize} + +\noindent V program lahko dodamo \emph{komentarje}. To je takšno besedilo, ki je napisano v kodi, a vsebinsko ne vpliva na program. +\begin{itemize} + \item \verb+//+ - s tem zakomentiramo vse od poševnic do konca vrstice + \item \verb+/* */+ - s tem lahko zakomentiramo več vrstic ali del znotraj vrstice +\end{itemize} + +\begin{examples} + +%#insert python3 style.py < chapters/inout/komentarji.cpp + +\begin{inout} +\tcblower +Zivjo svet! +\end{inout} + +\end{examples} + +\begin{errors} +Zadnji znak, ki ga program izpiše, mora biti \verb+\n+. +\end{errors} + +\begin{errors} +Večina vrstic v programu se konča s podpičjem (\verb+;+) (skoraj vse razen tistih, ki se končajo z oklepaji ali zavitimi zaklepaji). Brez tega program ne bo delal. +\end{errors} + +\pagebreak +\section{Branje} +Program za branje stvari, ki mu jih sporočamo, uporablja funkcijo \verb+scanf+. + +\begin{examples} + +%#insert python3 style.py < chapters/inout/branje.cpp + +\begin{inout} +{\color{blue} \bf output:} Kako ti je ime?\\ +{\color{blue} \bf input:} Tinka \\ +{\color{blue} \bf output:} Zivjo, Tinka! +\end{inout} + +\end{examples} + + +Če želimo, da program lahko kaj počne s podatki, ki jih je prebral, moramo najprej to shraniti na neko mesto v spominu. Temu mestu rečemo \emph{spremenljivka}, saj lahko s programom spreminjamo, kaj je tam shranjeno. Spremenljivke v svojem programu poimenujemo, v našem primeru ji rečemo \verb+ime+. Vsaki spremenljivki moramo določiti \emph{podatkovni tip}, saj lahko beremo in pišemo več različnih vrst podatkov, npr. besede ali števila. \\\\ +\verb+char+ - s tem povemo, da je naša spremenljivka besedilo oz. \emph{niz} \\\\ +\verb+[...]+ - številka v oglatih oklepajih za besedo pove največjo dolžino niza, ki ga lahko program prebere. + +\begin{errors} %CHECK +Ko določamo največjo dolžino niza, vedno vzamemo večjo številko, kot jo bomo potrebovali. O tem bomo več govorili v kasnejših poglavjih. +\end{errors} + + +Funkciji \verb+scanf+ podamo dva ali več \emph{parametrov}: +\begin{itemize} + \item kaj naj prebere, torej kakšne tipe spremenljivk. To podamo s \emph{formatnikom} (v našem primeru \verb+%s+, ki pomeni niz (\emph{string}). \verb+%s+ prebere vse znake do prvega presledka ali nove vrstice) + \item ostali parametri povejo, kam naj funkcija shrani stvari, ki jih je prebrala (torej v spremenljivke, ki smo jih naredili prej) +\end{itemize} + + +%CHECK +Do zdaj smo funkciji \verb+printf+ podali samo točno določeno besedilo, ki smo ga želeli izpisati. Izpisujemo pa lahko tudi spremenljivke, kot smo to naredili v tem zadnjem primeru. Znotraj besedila dodamo formatnike na mesta, kjer želimo, da so spremenljivke, potem pa izven narekovajev naštejemo imena spremenljivk, ki jih želimo izpisati (tako kot pri funkciji \verb+scanf+). + +\pagebreak +\section{Branje števil} +%CHECK +Poleg nizov lahko programi delajo tudi s števili. Števila beremo in izpisujemo z istima funkcijama kot nize, vendar moramo uporabiti drug formatnik. + +\begin{examples} + +%#insert python3 style.py < chapters/inout/branje_stevil.cpp + +\begin{inout} +{\color{blue} \bf output:} Kateri razred si?\\ +{\color{blue} \bf input :} 7\\ +{\color{blue} \bf output:} 7. razred je najboljši. +\end{inout} + +\end{examples} + +%CHECK +\verb+&+ - znak, ki ga moramo dati pred ime spremenljivke vedno, kadar beremo števila. +\verb+int+ - podatkovni tip število \\ +Pri številih za imenom spremenljivke ne povemo, kako velika so lahko. \\\\ +Za branje in pisanje števil uporabimo formatnik \verb+%d+. + +\begin{errors} +Ko beremo števila, moramo pred ime spremenljivke dati znak \verb+&+, česar pri branju nizov ne delamo. Prav tako tega ne delamo pri izpisovanju števil. +\end{errors} +%#endblock diff --git a/chapters/inout/komentarji.cpp b/chapters/inout/komentarji.cpp new file mode 100644 index 0000000..872a187 --- /dev/null +++ b/chapters/inout/komentarji.cpp @@ -0,0 +1,11 @@ +#include +int main(){ //komentar do konca vrstice + printf /*komentar znotraj vrstice*/("Zivjo svet!\n"); + /* + komentar + čez + več + vrstic + */ + return 0; +} diff --git a/chapters/inout_advanced/datoteke.cpp b/chapters/inout_advanced/datoteke.cpp new file mode 100644 index 0000000..f6fdda7 --- /dev/null +++ b/chapters/inout_advanced/datoteke.cpp @@ -0,0 +1,14 @@ +#include + +int main(){ + int a; + FILE *fr, *fw; + fr = fopen("in.txt", "r"); + fw = fopen("out.txt", "w"); + while(fscanf(fr, "%d", &a) != EOF){ + fprintf(fw, "%d\n", a*a); + } //iz datoteke fr preberemo vsa števila in v fw izpišemo njihove kvadrate + fclose(fr); + fclose(fw); + return 0; +} diff --git a/chapters/inout_advanced/do_konca_vhoda.cpp b/chapters/inout_advanced/do_konca_vhoda.cpp new file mode 100644 index 0000000..d02c53e --- /dev/null +++ b/chapters/inout_advanced/do_konca_vhoda.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + int a; + while(scanf("%d", &a) != EOF){ + printf("%d\n", a*a); //izpisujemo kvadrate prebranega števila + } + return 0; +} diff --git a/chapters/inout_advanced/do_konca_vrstice.cpp b/chapters/inout_advanced/do_konca_vrstice.cpp new file mode 100644 index 0000000..b4254d5 --- /dev/null +++ b/chapters/inout_advanced/do_konca_vrstice.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + char a[50]; + scanf("%[^\n]", a); //ali scanf("%[^\n]%*c") in brez getchar() + getchar(); + printf("%s\n", a); + return 0; +} diff --git a/chapters/inout_advanced/formatnik_s.cpp b/chapters/inout_advanced/formatnik_s.cpp new file mode 100644 index 0000000..9beef5f --- /dev/null +++ b/chapters/inout_advanced/formatnik_s.cpp @@ -0,0 +1,9 @@ +#include + +int main(){ + char a[50], b[50]; + scanf("%s", a); + scanf("%s", b); + printf("%s %s\n", a, b); + return 0; +} diff --git a/chapters/inout_advanced/inout_advanced.tex b/chapters/inout_advanced/inout_advanced.tex new file mode 100644 index 0000000..3d237c0 --- /dev/null +++ b/chapters/inout_advanced/inout_advanced.tex @@ -0,0 +1,212 @@ +%#template templates/template.tex + +%#block title +Branje in pisanje 2 +%#endblock + +%#block content +\section{Scanf} + +Funkcija \verb+scanf+ lahko bere različne vrste podatkov: +\begin{itemize} + \item \verb+%s+ - beseda (vsi znaki razen praznih znakov (glej spodaj)) (\verb+char+) + \item \verb+%c+ - en (poljuben) znak (\verb+char+) + \item \verb+%d+ - število med $-2^{31}$ in $2^{31}-1$ (\verb+int+) + \item \verb+%lld+ - število med $-2^{63}$ in $2^{63}-1$ (\verb+long long+) + \item ... +\end{itemize} + +\noindent Prazni znaki (whitespace) so znaki, ki jih ne vidimo: +\begin{itemize} + \item \verb+\n+ nova vrstica + \item \verb+\t+ zamik + \item " " presledek +\end{itemize} + +S formatnikom \verb+%s+ funkcija \verb+scanf+ bere do prvega takšnega znaka. Prebere tudi vse take znake, ki sledijo, a jih ne shrani. Naslednjič, ko jo pokličemo, bere od prvega nepraznega znaka naprej. + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/formatnik_s.cpp + +\begin{inout} +Hello \\ \\ World! +\tcblower +Hello World! +\end{inout} + + +\end{examples} + +\pagebreak +\section{Branje do konca vrstice} + +Lahko določimo, da se \verb+scanf+ ne bo ustavil pri prvem praznem znaku, temveč šele pri koncu vrstice (ali kje drugje). + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/do_konca_vrstice.cpp + +\begin{inout} +Beremo do konca vrstice. +\tcblower +Beremo do konca vrstice. +\end{inout} + +\end{examples} + +\verb+[...]+ - med oklepaje pišemo navodila, kakšne znake lahko bere +\begin{itemize} + \item \verb+[a-z]+ - beri male črke angleške abecede + \item \verb+[a-zA-Z0-9]+ - beri male in velike črke in številke +\end{itemize} + +\verb+[^...]+ - beri vse do znakov, ki sledijo strešici +\begin{itemize} + \item \verb+[^\n]+ - beri vse do \verb+\n+ +\end{itemize} + +%CHECK +\begin{errors} +Za razliko od \verb+%s+ funkcija \verb+scanf+ s \verb+[^\n]+ prebere vse do \verb+\n+, tega pa ne prebere in se ustavi pred njim. Ko funkcijo pokličemo naslednjič, začne tam, kjer je nazadnje ostala, kar je v tem primeru točno pred znakom \verb+\n+. Če jo torej ponovno pokličemo s parametrom \verb+[^\n]+, se ne bo nikamor premaknila, saj je pred njo znak za novo vrstico. \\ +\end{errors} + +%CHECK +\verb+%c+ - prebere en znak (\verb+char+), ki je lahko karkoli - črka, številka, prazen znak... \\ +\verb+%*c+ - prebere en znak, a ga ne shrani \\ +Funkcija \verb+getchar+ dela podobno, vzame en znak in ga ne shrani. \\ + +Za razliko od tega s formatnikom \verb+%s+ preberemo vse prazne znake med dvema +nepraznima nizoma in jih ne shranimo. Tudi, če bodo prazni znaki pred besedo, +jih bo program ignoriral in poiskal prvi neprazen znak. + +\pagebreak +\section{Branje do konca vhoda} + +Če vemo točno, koliko besed/številk/vrstic bomo imeli na vhodu, jih lahko preberemo s for zanko. Kako preberemo neznano količino podatkov na vhodu, tako da preberemo vse? \\ +Če napišemo \verb+while(true)+ ali \verb+while(1)+, bomo sicer prebrali vse, a se program ne bo nikoli ustavil. +Namesto tega lahko napišemo: + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/do_konca_vhoda.cpp + +\begin{inout} +1 2 3 4 5 +\tcblower +1\\4\\9\\16\\25 +\end{inout} +\end{examples} + +\vskip 0.15in +%CHECK +\noindent Funkcija \verb+scanf+ vrne število formatnikov, ki jih je uspešno +prebrala (če ji kot parameter podamo samo \verb+%d+, bo vrnila $1$, če je +uspešno prebrala število, sicer pa 0). \verb+EOF+ (End of File) vrne, če na +vhodu ni ničesar več za prebrati. Tedaj se bo zanka ustavila. Če programu +vhodne podatke podajamo iz datoteke, se to zgodi avtomatsko ob koncu datoteke, +če pa mu podatke podajamo na roko, konec vhoda sporočimo s +\verb-Ctrl+D (Linux in MacOS)- ali \verb-Ctrl+Z- (Windows). + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/stevilo_prebranih.cpp + +\begin{inout} + 5 8 100 + \tcblower + 3 +\end{inout} +\begin{inout} + 5 8 miha + \tcblower + 2 +\end{inout} + + +\end{examples} + +\pagebreak +\section{Branje in pisanje v in iz niza} + +\verb+scanf+ uporabljamo za branje s standardnega vhoda, \verb+printf+ pa za pisanje na standardni izhod. +Namesto tega lahko beremo in pišemo tudi drugače, npr. v in iz nizov. +Za to uporabljamo funkciji \verb+sscanf+ in \verb+sprintf+, ki delata podobno kot \verb+scanf+ in \verb+printf+. + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/sprintf.cpp + +\begin{inout} + +\tcblower +a 157 Slovenska +\end{inout} + +\end{examples} + +\begin{errors} +Medtem ko \verb+%s+ praznih znakov ne shrani, jih \verb+%c+ obravnava tako kot +vse ostale. Če pogeldamo prejšnji primer vidimo, da je v funkciji +\verb+scanf+ pred \verb+%c+ presledek. Ker so med posameznimi podatki, ki +jih želimo prebrati, presledki, bi \verb+%c+ pobral presledek, ne pa črke, +ki mu sledi. Če med posamezne formatnike postavimo presledek, ta načeloma +pobere prazne znake do naslednjega drugačnega znaka, vendar to v splošnem +ni dobra praksa. +\end{errors} + +\noindent Funkciji \verb+sscanf+ podamo tri parametre (ali več): +\begin{enumerate} + \item ime niza, iz katerega naj bere + \item tip podatka, ki naj ga prebere (niz, število...) + \item kam naj ta podatek zapiše (ime spremenljivke) +\end{enumerate} + +\noindent Funkciji \verb+sprintf+ prav tako podamo tri parametre (ali več): +\begin{enumerate} + \item ime niza, kamor naj piše + \item tip podatka, ki naj ga zapiše + \item kaj naj zapiše (ime spremenljivke ali podatek sam) +\end{enumerate} + +\pagebreak +\section{Branje in pisanje v in iz datoteke} + +Podobno kot v niz lahko pišemo in beremo tudi v in iz datotek s funkcijama \verb+fscanf+ in \verb+fprintf+. + +\begin{examples} + +%#insert python3 style.py < chapters/inout_advanced/datoteke.cpp + +\begin{inout} +{\color{blue} \bf in.txt:} \\ +1 2 3 4 5 6 7 +\tcblower +{\color{blue} \bf out.txt:} \\ +1\\ +4\\ +9\\ +16\\ +25\\ +36\\ +49 +\end{inout} + +(Ta program ne bere s standardega vhoda in ne piše ne standardni izhod.) +\end{examples} + +\verb+FILE+ - tip podatka +\verb+fopen+ - funkcija, s katero odpremo datoteko, podamo ji ime datoteke, ki +jo želimo odpreti in način \verb+"r"+ (\emph{read} - za branje) ali \verb+"w"+ +(\emph{write} - za pisanje).\\ Datoteke, ki jih odpiramo za branje, morajo že +prej obstajati, sicer se bo program sesul. \\ + +Za datoteke, v katere pišemo, ni nujno, da že obstajajo. Če še ne obstajajo, bo +program ustvaril novo datoteko s tem imenom. Če že obstajajo, program ne bo +pisal na konec te datoteke, temveč bo pobrisal vso prejšnjo vsebino. +Če želimo obstoječi datoteki dodajati vsebino, moramo uporabiti način +\verb+"a"+ (\emph{append} - pripenjanje). + +\verb+fclose+ - funkcija, ki zapre odprto datoteko, podamo ji ime datoteke + +%#endblock diff --git a/chapters/inout_advanced/sprintf.cpp b/chapters/inout_advanced/sprintf.cpp new file mode 100644 index 0000000..6b6eb22 --- /dev/null +++ b/chapters/inout_advanced/sprintf.cpp @@ -0,0 +1,11 @@ +#include + +int main(){ + int n; + char a[10], b; + char text[]="Slovenska 157 a"; + sscanf(text, "%s%d %c", a, &n, &b); + sprintf(text, "%c %d %s", b, n, a); + printf("%s\n", text); + return 0; +} diff --git a/chapters/inout_advanced/stevilo_prebranih.cpp b/chapters/inout_advanced/stevilo_prebranih.cpp new file mode 100644 index 0000000..278d059 --- /dev/null +++ b/chapters/inout_advanced/stevilo_prebranih.cpp @@ -0,0 +1,8 @@ +#include + +int main() { + int a, b, c; + int r = scanf("%d%d%d", &a, &b, &c); + printf("%d\n", r); + return 0; +} diff --git a/chapters/more-conditionals/med-steviloma.cpp b/chapters/more-conditionals/med-steviloma.cpp new file mode 100644 index 0000000..2081ba9 --- /dev/null +++ b/chapters/more-conditionals/med-steviloma.cpp @@ -0,0 +1,10 @@ +#include + +int main() { + int n; + scanf("%d", &n); + if (3 < n && n < 9) { + printf("n je med 3 in 9.\n"); + } + return 0; +} diff --git a/chapters/more-conditionals/more-conditionals.tex b/chapters/more-conditionals/more-conditionals.tex new file mode 100644 index 0000000..e4544a6 --- /dev/null +++ b/chapters/more-conditionals/more-conditionals.tex @@ -0,0 +1,164 @@ +%#template templates/template.tex + +%#block title +Pogojni stavki: 2. del +%#endblock + +%#block content + +\section{Nizanje pogojev} + +Pogosto se srečamo s problemi, kjer je za rešitev potrebno upoštevati več kot +en pogoj. V takih primerih želimo združiti več pogojnih stavkov tako, da se +nek del kode izvede, če velja prvi pogoj, drugi del kode pa, če prvi pogoj +ne velja, velja pa drugi pogoj. Z gnezdenjem stavkov lahko to v kodo vključimo +na naslednji način: + +%#insert python3 style.py < chapters/more-conditionals/nizanje-narobe.cpp + +V takem primeru nam je na voljo bližnjica \verb+else if+. Zgornja koda deluje +popolnoma enako kot spodnja: + +%#insert python3 style.py < chapters/more-conditionals/nizanje-pravilno.cpp + +Prednost te bližnjice je, da je naša koda krajša in bolj razumljiva. +Stavke \verb+else if+ lahko tudi verižimo; enemu \verb+if+ stavku lahko sledi +poljubno mnogo stavkov \verb+else if+. Pri tem bo računalnik pogoje preverjal po +vrsti. Pri prvem veljavnem pogoju se bo ustavil in izvedel kodo v pripadajočih +zavitih oklepajih, za čimer ne bo več preverjal pogojev, temveč bo izvajanje +nadaljeval za zaključkom vseh nanizanih stavkov. + +Kakor nam v osnovnem \verb+if+ stavku ni bilo treba pisati dela z \verb+else+, +če ga nismo potrebovali, nam ga tudi pri uporabi \verb+else if+ ni treba. + +\pagebreak +\begin{examples} +Naslednji program prebere število in pove, če je večje, manjše ali enako 0. + +%#insert python3 style.py < chapters/more-conditionals/vecje-manjse-enako.cpp + +\begin{inout} +3 +\tcblower +Stevilo je vecje od 0. +\end{inout} + +\end{examples} + +\begin{examples} +Pogoji se preverjajo po vrsti; izvede se samo koda pri prvem veljavnem pogoju, +ne glede na to, koliko pogojev za njim je tudi veljavnih. + +%#insert python3 style.py < chapters/more-conditionals/nizanje-elseif.cpp + +Program izpiše le eno stvar - \verb+a je 7.+, kljub temu, da velja tudi +\verb+a > 1+. + +\end{examples} + +\section{Logični vezniki} + +Osnovni operatorji za primerjavo pogosto niso dovolj, da izrazimo željen pogoj. +Če na primer želimo pogledati, ali je neko število med dvema drugima, tega ne +moramo narediti samo z eno primerjavo. + +Pogoje združujemo s t.i. \emph{logičnimi vezniki}, ki jim včasih pravimo tudi +\emph{logični operatorji}. Poznamo tri osnovne veznike: +\begin{itemize} + \item \verb+and+ oz.~\verb+&&+ združi dva pogoja tako, da združeni pogoj velja + samo v primeru, da veljata oba hkrati. + \item \verb+or+ oz.~\verb+||+ združi dva pogoja tako, da združeni pogoj velja + v primeru, da velja katerikoli od dveh, ali da veljata oba + \item \verb+not+ oz.~\verb+!+ sprejme samo en pogoj. Nov pogoj velja samo + takrat, ko originalni pogoj ne velja. +\end{itemize} + +Logična veznika \verb+&&+ (\emph{in}) ter \verb+||+ (\emph{ali}) lahko +predstavimo z resničnostno tabelo. + +\begin{table}[h!] + \centering + \caption{Resničnostna tabela za in} + \vspace{0.1cm} + \begin{tabular}{c|c|c} + Leva vrednost & Desna vrednost & Vrednost veznika \\ + \hline + resnica & resnica & resnica \\ + resnica & neresnica & neresnica \\ + neresnica & resnica & neresnica \\ + neresnica & neresnica & neresnica + \end{tabular} +\end{table} + +\begin{table}[h!] + \centering + \caption{Resničnostna tabela za ali} + \vspace{0.1cm} + \begin{tabular}{c|c|c} + Leva vrednost & Desna vrednost & Vrednost veznika \\ + \hline + resnica & resnica & resnica \\ + resnica & neresnica & resnica \\ + neresnica & resnica & resnica \\ + neresnica & neresnica & neresnica + \end{tabular} +\end{table} + +\begin{examples} + +Če želimo preveriti, ali je dano število med dvema drugima, uporabimo +logični veznik \verb+&&+. + +%#insert python3 style.py < chapters/more-conditionals/med-steviloma.cpp + +\begin{inout} +5 +\tcblower +n je med 3 in 9. +\end{inout} + +\end{examples} + +\begin{errors} + V matematiki pogosto napišemo dvojno primerjavo: \verb+a < b < c+. + Če nekaj podobnega napišemo v C++ program, se bo le-ta sicer zagnal, vendar + ne bo deloval pravilno. Kaj pričakujemo, da se zgodi, če v tako primerjavo + zapišemo \verb+3 < 2 < 1+? Kaj pa se dejansko zgodi? +\end{errors} + +Pri kombiniranju pogojev bodimo previdni glede pravil prednosti. Zanikanje +(veznik \verb+not+ oz.~\verb+!+) ima namreč prednost pred primerjalnimi +vezniki (\verb+<+, \verb+==+, \ldots), ter drugima ločnima veznikoma. +Če v takem primeru uporabljamo zanikanje, moramo zanikan izraz postaviti +v oklepaje. + +\begin{examples} + Zanikanje se lahko v večini primerov zapiše tudi na krajši način. + + \begin{tabular}{|c|c|c|} + \hline + Izraz & Ekvivalenten izraz & Komentar \\ + \hline + \verb+!(a == b)+ & \verb+a != b+ & \\ + \verb+!(a < b)+ & \verb+a >= b + & Če sta \verb+a+ in \verb+b+ enaka, bo prvi izraz veljaven. \\ + \verb+!(a <= b)+ & \verb+a > b+ & \\ + \hline + \end{tabular} +\end{examples} + +\begin{examples} +Napišimo program, ki preveri, ali je uporabnik vpisal prestopno leto. +Leto je prestopno, če je deljivo s 4; razen, če je hkrati deljivo s 100. Izjema so leta, deljiva +s 400, ki so prestopna kljub temu, da so deljiva s 100. + +Kako te pogoje zapišemo v program? Opazimo, da so leta, deljiva s 400, +prestopna ne glede na druga pogoja. Če leto ni deljivo s 400, potem mora biti +deljivo s 4 in ne sme biti deljivo s 100. Povedano krajše; leto mora biti +deljivo s 400, ali pa s 4 in ne hkrati s 100. Tak pogoj lahko zapišemo z +logičnimi vezniki. + +%#insert python3 style.py < chapters/more-conditionals/prestopno-leto.cpp + +\end{examples} + +%#endblock diff --git a/chapters/more-conditionals/nizanje-elseif.cpp b/chapters/more-conditionals/nizanje-elseif.cpp new file mode 100644 index 0000000..566388c --- /dev/null +++ b/chapters/more-conditionals/nizanje-elseif.cpp @@ -0,0 +1,17 @@ +#include + +int main() { + int a = 7; + if (a < 3) { + printf("a je manjsi od 3.\n"); + } else if (a == 7) { + printf("a je 7.\n"); + } else if (a == 4) { + printf("a je 4.\n"); + } else if (a > 1) { + printf("a je vecji od 1.\n"); + } else { + printf("Nic od nastetega ne velja.\n"); + } + return 0; +} diff --git a/chapters/more-conditionals/nizanje-narobe.cpp b/chapters/more-conditionals/nizanje-narobe.cpp new file mode 100644 index 0000000..ca6ed18 --- /dev/null +++ b/chapters/more-conditionals/nizanje-narobe.cpp @@ -0,0 +1,10 @@ +if (prvi pogoj) { + // koda, ki se izvede, če velja prvi pogoj +} else { + if (drugi pogoj) { + // koda, ki se izvede, če prvi pogoj ne velja, + // velja pa drugi pogoj + } else { + // koda, ki se izvede, če ne veljata ne prvi ne drugi pogoj + } +} diff --git a/chapters/more-conditionals/nizanje-pravilno.cpp b/chapters/more-conditionals/nizanje-pravilno.cpp new file mode 100644 index 0000000..ca6ed18 --- /dev/null +++ b/chapters/more-conditionals/nizanje-pravilno.cpp @@ -0,0 +1,10 @@ +if (prvi pogoj) { + // koda, ki se izvede, če velja prvi pogoj +} else { + if (drugi pogoj) { + // koda, ki se izvede, če prvi pogoj ne velja, + // velja pa drugi pogoj + } else { + // koda, ki se izvede, če ne veljata ne prvi ne drugi pogoj + } +} diff --git a/chapters/more-conditionals/prestopno-leto.cpp b/chapters/more-conditionals/prestopno-leto.cpp new file mode 100644 index 0000000..cfdd10c --- /dev/null +++ b/chapters/more-conditionals/prestopno-leto.cpp @@ -0,0 +1,12 @@ +#include + +int main() { + int leto; + scanf("%d", &leto); + if (leto % 400 == 0 || (leto % 4 == 0 && !(leto % 100 == 0))) { + printf("Leto je prestopno.\n"); + } else { + printf("Leto ni prestopno.\n"); + } + return 0; +} diff --git a/chapters/more-conditionals/vecje-manjse-enako.cpp b/chapters/more-conditionals/vecje-manjse-enako.cpp new file mode 100644 index 0000000..5f62a09 --- /dev/null +++ b/chapters/more-conditionals/vecje-manjse-enako.cpp @@ -0,0 +1,14 @@ +#include + +int main() { + int stevilo; + scanf("%d", &stevilo); + if (stevilo < 0) { + printf("Stevilo je manjse od nic.\n"); + } else if (stevilo == 0) { + printf("Stevilo je enako 0.\n"); + } else if (stevilo > 0) { + printf("Stevilo je vecje od 0.\n"); + } + return 0; +} diff --git a/chapters/stringi/ali-si-filip.cpp b/chapters/stringi/ali-si-filip.cpp new file mode 100644 index 0000000..2dc40df --- /dev/null +++ b/chapters/stringi/ali-si-filip.cpp @@ -0,0 +1,7 @@ +char niz[101]; +scanf("%s", niz); +if (strcmp(niz, "Filip") == 0) { + printf("Ime ti je Filip\n"); +} else { + printf("Ni ti ime Filip\n"); +} diff --git a/chapters/stringi/auto/stringi.el b/chapters/stringi/auto/stringi.el new file mode 100644 index 0000000..1513dee --- /dev/null +++ b/chapters/stringi/auto/stringi.el @@ -0,0 +1,7 @@ +(TeX-add-style-hook + "stringi" + (lambda () + (LaTeX-add-labels + "tab:ascii")) + :latex) + diff --git a/chapters/stringi/basic-char-syntax.cpp b/chapters/stringi/basic-char-syntax.cpp new file mode 100644 index 0000000..faa28a5 --- /dev/null +++ b/chapters/stringi/basic-char-syntax.cpp @@ -0,0 +1 @@ +char crka = 'A'; diff --git a/chapters/stringi/basic-string-syntax.cpp b/chapters/stringi/basic-string-syntax.cpp new file mode 100644 index 0000000..3b776e1 --- /dev/null +++ b/chapters/stringi/basic-string-syntax.cpp @@ -0,0 +1 @@ +char niz_besedila[300]; diff --git a/chapters/stringi/copy-vs-reference.cpp b/chapters/stringi/copy-vs-reference.cpp new file mode 100644 index 0000000..9c4463c --- /dev/null +++ b/chapters/stringi/copy-vs-reference.cpp @@ -0,0 +1,4 @@ +niz[3] = 'x'; // spremeni niz + +char znak = niz[3]; +znak = 'y'; // znak je sedaj 'y', niz pa je nespremenjen diff --git a/chapters/stringi/dolzina-niza-bolje.cpp b/chapters/stringi/dolzina-niza-bolje.cpp new file mode 100644 index 0000000..b9096a2 --- /dev/null +++ b/chapters/stringi/dolzina-niza-bolje.cpp @@ -0,0 +1,9 @@ +#include +#include // strlen + +int main() { + char niz[201]; + scanf("%s", niz); + printf("Dolzina niza: %d\n", strlen(niz)); + return 0; +} diff --git a/chapters/stringi/dolzina-niza.cpp b/chapters/stringi/dolzina-niza.cpp new file mode 100644 index 0000000..bcb3150 --- /dev/null +++ b/chapters/stringi/dolzina-niza.cpp @@ -0,0 +1,18 @@ +#include + +int main() { + char niz[301]; + // uporabnik lahko napise niz dolžine najvec 300 + scanf("%s", niz); + + // da poiščemo dolžino, bomo dejansko poiskali indeks + // znaka NULL; s tem bomo dobili točno število znakov pred njim + int i = 0; // trenutni indeks v nizu + while (niz[i] != 0) { // ASCII koda znaka NULL je 0 + i++; + } + // na kocnu je i ravno indeks znaka NULL, in s tem enak + // dolzini niza + printf("Niz je dolg %d znakov\n", i); + return 0; +} diff --git a/chapters/stringi/indeksiranje.cpp b/chapters/stringi/indeksiranje.cpp new file mode 100644 index 0000000..40f34e4 --- /dev/null +++ b/chapters/stringi/indeksiranje.cpp @@ -0,0 +1,5 @@ +char niz[201] = "Primicovi Julji"; +printf("Znak na prvem mestu: %c\n", niz[0]); // P +niz[8] = 'a'; +niz[14] = 'a'; +printf("%s\n", niz); // izpiše "Primicova Julja" diff --git a/chapters/stringi/is-capital-letter.cpp b/chapters/stringi/is-capital-letter.cpp new file mode 100644 index 0000000..05b23be --- /dev/null +++ b/chapters/stringi/is-capital-letter.cpp @@ -0,0 +1,14 @@ +#include + +int main() { + char crka; + scanf("%c", &crka); + if (crka >= 'A' && crka <= 'Z') { + printf("To je velika crka\n"); + } else if (crka >= 'a' && crka <= 'z') { + printf("To je majhna crka\n"); + } else { + printf("To sploh ni crka!\n"); + } + return 0; +} diff --git a/chapters/stringi/odstevanje-nic.cpp b/chapters/stringi/odstevanje-nic.cpp new file mode 100644 index 0000000..83c1587 --- /dev/null +++ b/chapters/stringi/odstevanje-nic.cpp @@ -0,0 +1,5 @@ +char znak = '7'; // števka 7, napisana kot znak +int stevilka = znak - '0'; // če odštejemo nič, nič ne spremenimo + +// NAROBE! +int to_pride_55 = znak - 0; diff --git a/chapters/stringi/pozdravljen.cpp b/chapters/stringi/pozdravljen.cpp new file mode 100644 index 0000000..650cc0b --- /dev/null +++ b/chapters/stringi/pozdravljen.cpp @@ -0,0 +1,8 @@ +#include + +int main() { + char uporabnikovo_ime[300]; + scanf("%s", uporabnikovo_ime); // NE napišemo & + printf("Zivjo %s!\n", uporabnikovo_ime); + return 0; +} diff --git a/chapters/stringi/scanf-printf-char.cpp b/chapters/stringi/scanf-printf-char.cpp new file mode 100644 index 0000000..cad1bdc --- /dev/null +++ b/chapters/stringi/scanf-printf-char.cpp @@ -0,0 +1,3 @@ +char crka; +scanf("%c", &crka); +printf("Tvoja crka: %c\n", crka); diff --git a/chapters/stringi/string-v-stevilo.cpp b/chapters/stringi/string-v-stevilo.cpp new file mode 100644 index 0000000..3485766 --- /dev/null +++ b/chapters/stringi/string-v-stevilo.cpp @@ -0,0 +1,18 @@ +#include +#include + +int main() { + char niz[11]; // niz, ki bo hranil številko + // premisli, zakaj je dolžina 11 že dovolj + scanf("%s", niz); + int dolzina = strlen(niz); + int stevilo = 0; // začnemo z 0 + for (int i = 0; i < dolzina; i++) { + stevilo *= 10; + stevilo += (niz[i] - '0'); + // niz[i] je znak, ki ga moramo pretvoriti v številko, da lahko + // računamo z njim + } + printf("Stevilka je %d\n", stevilo); + return 0; +} diff --git a/chapters/stringi/stringi.tex b/chapters/stringi/stringi.tex new file mode 100644 index 0000000..46b1fd6 --- /dev/null +++ b/chapters/stringi/stringi.tex @@ -0,0 +1,322 @@ +%#template templates/template.tex + +%#block title +Nizi in besedilo +%#endblock + +%#block content + +\section{Uvod} + +Poleg dela s številkami od računalnika pogosto želimo, da nekaj naredi z nizi +besedila. +Primeri takšnih programov so npr.~urejevalniki besedila, ki jih uporabljamo tako +za pisanje ``enostavnega'' besedila (koda), kot tudi za razna obogatena +besedila. +Pravzaprav pa skoraj vsak računalniški program dela z besedilom; kadarkoli +želimo uporabniku prikazati neke informacije, jih moramo namreč izpisati na +zaslon. +Ko smo delali s številkami, smo problem izpisovanja prepustili računalniku, ker +je kodo za branje in izpisovanje številk k sreči napisal že nekdo drug. +Za pisanje splošnih programov pa tovrstno znanje ne bo dovolj; zato si poglejmo +osnove dela z besedili. + +Pri slovenščini se naučimo, da je besedilo sestavljeno iz več odstavkov, +odstavek iz več povedi, poved iz več stavkov, stavek iz več besed, besede pa iz +več črk. +Pri tem se moramo zavedati, da stavke ločimo z ločili (vejice, pike, klicaji, +itd.), besede ločimo s presledki, posamične odstavke pa ločimo z zamikanjem prve +povedi v desno. +Za predstavitev v računalniku je tak model preveč zakompliciran, zato vzamemo +bolj enostavnega. +Besedila bomo predstavili z \textit{nizi} (angl.~\textit{string}), ki bodo +zaporedja več \textit{znakov} (angl.~\textit{character}). +Vse, kar bi si kadarkoli zaželeli izpisati, bomo proglasili za znak. +Tako si bomo vse črke predstavljali kot znak, kjer bomo ločili tudi velikimi in +malimi črkami (saj vendar izgledajo drugače, če jih napišemo), prav tako bomo za +znake proglasili tudi ločila, oklepaje in matematične operacije +(\verb|+, -, *, /|). +Poleg tega bomo za znak proglasili tudi števke od 0 do 9, ker tudi njih +izpišemo. + +Nenazadnje bomo ustvarili še nekaj posebnih znakov, ki jih morda nebi +pričakovali. +Od teh bomo zdaj spoznali tri: znak za presledek, znak za novo vrstico in znak +za konec besedila. +Znak za presledek bomo uporabili, kjerkoli želimo imeti prostor med dvema +besedama (torej presledek). +Za razliko od slovenščine tudi presledke obravnavamo, kot da bi bili pravzaprav +neke posebne črke. +Znak za novo vrstico bomo uporabili tam, kjer želimo, da izpis našega programa +skoči vrstico nižje; brez tega znaka nam bo program vse izpisal v eni zelo dolgi +vrstici besedila. +Ta znak označimo s posebno kodo \verb+\n+ (ker se v angleščini ta znak imenuje +\textit{newline}), opazimo pa, da smo ga pravzaprav že srečali čisto na začetku. +Uporabili bomo tudi znak za konec besedila, ki ga označimo z \verb+\0+, +pogosto pa mu rečemo tudi \textit{NULL}. +Več o temu znaku bomo povedali kasneje. + +\section{Predstavitev znakov} + +Preden si pogledamo nize, moramo razumeti, kako delamo z znaki. +V C++-u imamo za to poseben tip \verb+char+, ki nam hrani en znak. +Če želimo spremenljivki tipa \verb+char+ nastaviti vrednost, moramo želeni znak +dati v enojne narekovaje; +%#insert python3 style.py < chapters/stringi/basic-char-syntax.cpp +Ta koda nam ustvari spremenljivko tipa \verb+char+, ki hrani vrednost +\verb+'A'+, torej znak za veliko črko A. +Tako kot števila lahko tudi znake pišemo in beremo; pri tem uporabimo +\verb+printf+, znotraj njega pa poseben formatnik \verb+%c+, narejen za znake. +%#insert python3 style.py < chapters/stringi/scanf-printf-char.cpp + +\begin{table}[h!] + \centering + \begin{tabular}[h!]{|c|c|} + \hline + Znak & ASCII koda \\ + \hline + NULL (\verb+\0+) & 0 \\ + Nova vrstica (\verb+\n+) & 10 \\ + Presledek (\verb+' '+) & 32 \\ + \hline + \verb+0+ & 48 \\ + \verb+1+ & 49 \\ + \verb+2+ & 50 \\ + \vdots & \vdots \\ + \verb+9+ & 57 \\ + \hline + \verb+A+ & 65 \\ + \verb+B+ & 66 \\ + \verb+C+ & 67 \\ + \vdots & \vdots \\ + \verb+Z+ & 90 \\ + \hline + \verb+a+ & 97 \\ + \verb+b+ & 98 \\ + \verb+c+ & 99 \\ + \vdots & \vdots \\ + \verb+z+ & 122 \\ + \hline + \end{tabular} + \caption{Del ASCII tabele} + \label{tab:ascii} +\end{table} + +Ker so računalniki narejeni za delo s številkami, moramo tudi znake +predstaviti kot številke. +To dosežemo s t.i.~\textit{kodnimi tabelami}, ki vsakemu znaku priredijo eno +številko. +Najpreprostejša kodna tabela je ASCII, ki lahko zakodira vse črke angleške +abecede ter vse ostale zgoraj naštete znake, ne zmore pa zakodirati šumnikov. +Le-teh se pri programiranju izogibamo, kar se le da. +ASCII kode nekaterih pogostih znakov so prikazane v tabeli~\ref{tab:ascii}. +Opazimo lahko, da so števke in črke v tabeli zaporedno; števka \verb+0+ ima kodo +48, števka \verb+1+ 49, \ldots, črka \verb+A+ ima kodo 65, \verb+B+ ima kodo 66, +itd. +Opazimo tudi, da so velike črke od malih ločene, in da imajo male črke večje +kode. + +Ta dejstva lahko uporabimo v programih tako, da črke preprosto obravnavamo, kot +da bi bile številke. +Črki \verb+'a'+ lahko npr.~prištejemo neko številko, in tako dobimo črko, ki je +toliko znakov naprej v abecedi; \verb|'a' + 7| je na primer enako \verb|'h'|. +Poleg tega lahko znake med sabo primerjamo, kar bomo videli v prvem primeru. + +\begin{errors} + ASCII koda je bila narejena v Ameriki specifično za angleško uporabo. + Ker ne vsebuje šumnikov, le-teh ne moramo predstaviti v naših programih. + Za delo s šumniki potrebujemo drugačne kodne tabele, ki jih tukaj ne bomo + obravnavali. +\end{errors} + +\begin{examples} + Če poznamo kodne tabele, lahko na relativno enostaven način preverimo, če je + neka črka velika ali majhna: + %#insert python3 style.py < chapters/stringi/is-capital-letter.cpp + \begin{inout} + p + \tcblower + To je velika crka + \end{inout} + Koda sprva prebere eno črko iz vhoda, nato pa preveri, če je vpisana črka med + \verb+A+ in \verb+Z+; če ni, potem preverimo še, če je črka med \verb+a+ in + \verb+z+. +\end{examples} + +Če dobro pogledamo v tabelo, vidimo, da koda 0 ne pripada števki \verb+0+, pač +pa znaku za konec besedila. +To se morda na prvi pogled zdi nepričakovano, ampak ima svoj smisel; če je +števka del besedila, o njej ne razmišljamo kot o številki, temveč pač o nekem +znaku, ki ima v drugem kontekstu drugačen pomen. +Če želimo to števko pretvoriti v številko, s katero lahko brez skrbi računamo, +lahko uporabimo trik, kjer ``odštejemo nič:'' +%#insert python3 style.py < chapters/stringi/odstevanje-nic.cpp +Pri tem triku moramo biti previdni, da odštejemo pravilno ničlo; če odštejemo +številko \verb+0+, se ne bo nič spremenilo; tako kot pri matematiki namreč +odštevanje ničle številke ne spremeni. +Če pa odštejemo \emph{znak} \verb+'0'+ (v enojnih narekovajih), pa dejansko +odštevamo številko 48, t.j.~ASCII kodo znaka \verb+'0'+. +Praktično uporabo tega trika bomo pokazali v naslednjem delu. + +\section{Predstavitev nizov} + +Niz predstavimo kot zaporedje znakov. +Ker o zaporedjih (oziroma natančneje o seznamih) nismo še ničesar povedali, +moramo uvesti novo sintakso: +%#insert python3 style.py < chapters/stringi/basic-string-syntax.cpp +Ta ukaz pove računalniku, naj ustvari spremenljivko z imenom +\verb+niz_besedila+, ki hrani \emph{največ} 300 znakov. +V tej spremenljivki bomo hranili naše zaporedje besedila. +Če želimo nize brati ali pisati, uporabimo funkciji, ki ju že poznamo, ter +formatnik \verb+%s+, tu pa je ena posebnost; za branje nizov \underline{ne} +napišemo znaka \verb+&+. +Če želimo neko spremenljivko nastaviti na niz, ki ga ne bomo prebrali, jo lahko +nastavimo na običajen način z enačajem, ter z dvojnimi narekovaji. +Tak način podajanja nizov smo že srečali; namreč vedno, ko uporabimo funkciji +\verb+scanf+ ali \verb+printf+. + +\begin{examples} + Da se navadimo nove sintakse, si poglejmo preprost primer. + Spodnji program prebere uporabnikovo ime in ga pozdravi. + %#insert python3 style.py < chapters/stringi/pozdravljen.cpp +\end{examples} + +Ko ustvarimo niz, računalniku povemo, kolikšna je njegova najdaljša možna +dolžina. +Nič pa nam ne preprečuje, da v to spremenljivko shranimo krajši niz. +Kako pa potem računalnik ve, kje se naš niz dejansko konča? +Pričakujemo namreč, da bomo za zapis kratkega niza uporabili nekaj mest za znake +na začetku, potem pa se bo niz nekje končal; kaj je na neuporabljenih mestih +zaporedja, nas ne zanima. +Ravno iz tega razloga so nizi zgrajeni tako, da imajo na koncu dodaten znak za +konec besedila; znak NULL, ki smo ga omenili na začetku. +Ta znak pove računalniku, da se besedilo tu konča in da naj naprej ne gleda. +Če vrednost niza nastavimo z enačajem ali niz preberemo s \verb+scanf+, bo +računalnik sam poskrbel, da bo ta znak napisan na pravo mesto; če pa z nizi +delamo kaj bolj zapletenega, moramo za ta znak skrbeti sami. +Zaradi tega znaka je dejansko število vidnih znakov, ki jih lahko shranimo v +niz, za eno manjše od predpisane največje dolžine. +Da se tovrstnim problemom izognemo, bomo od sedaj naprej vedno napisali nekaj +večjo število za dolžino niza; če pričakujemo, da uporabnik vpiše največ 200 +znakov, bomo za velikost niza dejansko napisali 201 (ali celo malo več). + +Preden pridemo do primerov, moramo spoznati še indeksiranje. +Vsako mesto za znak v nizu ima svoj zaporedni \textit{indeks}, s katerim +lahko enolično dostopamo do tistega mesta. +Indeksi so zaporedna števila, ki se začnejo z 0; prvi znak v nizu ima indeks 0, +drugi znak ima indeks 1, tretji ima indeks 2, itd. +Indeksiranje od 0 se morda sprva zdi nesmiselno, vendar je za tem zelo dober +razlog, ki ga bomo spoznali pri obravnavi kazalcev (nadaljevalna skupina). +Poglejmo si na primeru, kako deluje indeksiranje. + +\vspace{0.5cm} + +\begin{tabular}[h!]{|c|cccccccccccccccc|} + Znak & P & r & i & m & i & c & o & v & i & \verb+' '+ & J & u & l & j & i & NULL \\ + \hline + Indeks & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13 & 14 & 15 \\ +\end{tabular} + +\vspace{0.5cm} + +V zgornji tabeli je razpisan niz \verb+"Primicovi Julji"+, pod vsakim znakom pa +je napisan indeks, s katerim lahko dostopamo do tega mesta v nizu. +Da zares dostopamo do teh znakov, uporabimo oglate oklepaje; +%#insert python3 style.py < chapters/stringi/indeksiranje.cpp +Ko zapišemo \verb+niz[indeks]+, dobimo znak, ki ga lahko uporabljamo kot +katerokoli drugo spremenljivko. +Pri tem pazimo samo na to, da lahko niz spremenimo le, če ga spremenimo +``direktno''; če znak prvo shranimo v neko drugo spremenljivko, in potem +spremenimo to spremenljivko, se niz \underline{ne} bo spremenil. +%#insert python3 style.py < chapters/stringi/copy-vs-reference.cpp + +\begin{examples} + Za prvi primer si poglejmo, kako bi lahko izračunali dolžino niza. + %#insert python3 style.py < chapters/stringi/dolzina-niza.cpp + Ta koda ni težka, vendar jo je pogosto neprijetno pisati, zato imamo boljšo + alternativo; če na začetek programa dodamo \verb+#include +, lahko + uporabljamo funkcijo \verb+strlen+, ki nam ravno tako izračuna dolžino niza: + %#insert python3 style.py < chapters/stringi/dolzina-niza-bolje.cpp + Funkcijo \verb+strlen+ uporabljamo v skoraj vsakem programu z nizi, zato je + dobro, da se je čim prej navadimo. + Poleg tega \verb+strlen+ dolžino dejansko izračuna hitreje kakor zgornja koda. +\end{examples} + +\begin{examples} + V naslednjem primeru bomo napisali kodo, ki pretvori besedilo v velike črke. + Za to uporabimo eno od lastnosti ASCII tabele, ki smo jo omenili prej; namreč, + da so črke napisane zaporedno, da so velike črke pred malimi. + %#insert python3 style.py < chapters/stringi/upcase.cpp +\end{examples} + +\begin{examples} + Za ta primer si poglejmo, kako bi pretvorili številko, zapisano z nizom, v + številko, zapisano s številko. + Prej omenjen trik z odštevanjem nič ne bo deloval, ker lahko z njim + pretvarjamo le znake; lahko pa številko pretvorimo znak po znak. + Pri tem pretvarjanju uporabljamo lastnosti desetiškega zapisa števil; namreč, + da zaporedna mesta v zapisu predstavljajo vrednosti, ki se razlikujejo za + faktor 10. + Ko pretvorimo prvi del besedila, in želimo dopisati še eno števko, moramo že + zapisani del ``premakniti'' eno mesto v levo, ter premaknjenemu številu + prišteti novo števko. + Premikanje dosežemo z množenjem z 10. + %#insert python3 style.py < chapters/stringi/string-v-stevilo.cpp +\end{examples} + +\section{Standardne funkcije} + +Izkaže se, da pri delu z nizi pogosto pišemo zelo podobne kose programa, kakor +se je zgodilo pri primeru z izračunom dolžine. +Namesto da večkrat napišemo skoraj enako kodo, so v knjižnici \verb+string.h+ +dostopne razne funkcije, ki nam pogosto olajšajo delo. + +\subsection{Primerjava nizov} + +Za primerjavo dveh nizov \underline{ne} uporabljamo dvojnega enačaja +(\verb+==+), temveč funkcijo \verb+strcmp+. +Funkcijo uporabimo tako, da ji v okrogle oklepaje napišemo dva niza; +\verb+strcmp(niz1, niz2)+. +Če sta niza enaka, funkcija vrne rezultat \verb+0+, sicer pa vrne drugačen +rezultat. +Spodnja koda preveri, če je uporabniku ime Filip: +%#insert python3 style.py < chapters/stringi/ali-si-filip.cpp + +Funkcija nam pravzaprav poda več informacij. +Z njo lahko pogledamo, kakšna je \textit{leksikografska ureditev} dveh nizov; +preprosto povedano, kateri od nizov bi se, če bi bila oba niza besedi, pojavil +prej v slovarju (leksikonu). +Če bi se prvi niz pojavil prej, funkcija vrne negativno število. +Če bi se drugi niz pojavil prej, pa funkcija vrne pozitivno število. + +\subsection{Kopiranje nizov} + +Če želimo eno spremenljivko prekopirati v drugo, lahko napišemo \verb+b = a+. +Na žalost pa to ne deluje za nize; namesto \verb+niz2 = niz1+ moramo napisati +\verb+strcpy(niz2, niz1)+. +Funkcija \verb+strcpy+ prekopira drugi niz v prvega; na koncu bosta oba niza +imela enako vsebino. + +Če želimo nekemu nizu na konec dodati nek drug niz, lahko za to uporabimo +funkcijo \verb+strcat+ (\textit{string concatenate}). +Ta funkcija prav tako sprejme dva niza; ko jo pokličemo, drug niz kopira na +konec prvega. + +\subsection{Operacije na prvih $n$ znakih} + +Včasih želimo kopirati ali primerjati le del niza. +Za to imamo na voljo malce drugačne verzije zgoraj naštetih funkcij; če v imenih +teh funkcij za \verb+str+ dodamo še \verb+n+ (torej \verb+strncmp+, +\verb+strncpy+, \ldots), in funkciji kot zadnji argument podamo številko $n$, bo +funkcija svoje delo opravila le na prvih $n$ znakih; +\verb+strncmp(niz1, niz2, 3)+ bo primerjal le prve tri znake, +\verb+strncpy(niz2, niz1, 7)+ bo kopiral le prvih sedem znakov, ipd. + +\section{Napredno branje nizov} + +Pogosto se v nalogah pojavi, da moramo prebrati niz do konca vrstice, ali pa da +sploh ne vemo, koliko vrstic vhoda bo do programa prišlo. +Spopadanje s tovrstnimi problemi je opisano v zapiskih za nadaljevalno skupino +iz tretje ure (Branje in pisanje 2). + +%#endblock diff --git a/chapters/stringi/upcase.cpp b/chapters/stringi/upcase.cpp new file mode 100644 index 0000000..589876a --- /dev/null +++ b/chapters/stringi/upcase.cpp @@ -0,0 +1,22 @@ +#include +#include + +int main() { + char niz[201]; + scanf("%s", niz); + + // Zamik med velikimi in majhnimi črkami je enak ne glede na to, katera + // črka je to. V zanki bomo vsaki majhni črki odšteli zamik, s čimer jo + // pretvorimo v veliko + int zamik = 'a' - 'A'; + int dolzina = strlen(niz); + for (int i = 0; i < dolzina; i++) { + // če je črka majhna, jo moramo povečati + // to moramo nujno preveriti, saj drugih znakov ne smemo spremeniti! + if ('a' <= niz[i] && niz[i] <= 'z') { + niz[i] = niz[i] - zamik; + } + } + printf("%s\n", niz); + return 0; +} diff --git a/chapters/urejanje/algorithm.cpp b/chapters/urejanje/algorithm.cpp new file mode 100644 index 0000000..2be8a3d --- /dev/null +++ b/chapters/urejanje/algorithm.cpp @@ -0,0 +1,2 @@ +#include +using namespace std; diff --git a/chapters/urejanje/compare.cpp b/chapters/urejanje/compare.cpp new file mode 100644 index 0000000..8c1c96b --- /dev/null +++ b/chapters/urejanje/compare.cpp @@ -0,0 +1,3 @@ +bool compare(int a, int b) { + return a < b; +} diff --git a/chapters/urejanje/kombinirani.cpp b/chapters/urejanje/kombinirani.cpp new file mode 100644 index 0000000..afb2b40 --- /dev/null +++ b/chapters/urejanje/kombinirani.cpp @@ -0,0 +1,30 @@ +#include +#include +using namespace std; + +int tocke[100003]; +char imena[100003][30]; +int idxs[100003]; + +int compare(int i, int j) { + return tocke[i] > tocke[j]; +} + +int main() { + int n; + scanf("%d", &n); + for (int i = 0; i < n; i++) { + scanf("%s%d", imena[i], &tocke[i]); + } + // pripravimo tabelo indeksov + for (int i = 0; i < n; i++) + idxs[i] = i; + + sort(idxs, idxs+n, compare); + + for (int i = 0; i < n; i++) { + int idx = idxs[i]; + printf("%s\n", imena[idx]); + } + return 0; +} diff --git a/chapters/urejanje/nasprotno.cpp b/chapters/urejanje/nasprotno.cpp new file mode 100644 index 0000000..b633d30 --- /dev/null +++ b/chapters/urejanje/nasprotno.cpp @@ -0,0 +1,22 @@ +#include +#include +using namespace std; + +int arr[1000003]; + +int compare_padajoce(int a, int b) { + return a > b; +} + +int main() { + int n; + scanf("%d", &n); + for (int i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + sort(arr, arr+n, compare_padajoce); + for (int i = 0; i < n; i++) { + printf("%d\n", arr[i]); + } + return 0; +} diff --git a/chapters/urejanje/uporaba.cpp b/chapters/urejanje/uporaba.cpp new file mode 100644 index 0000000..b3605bb --- /dev/null +++ b/chapters/urejanje/uporaba.cpp @@ -0,0 +1,18 @@ +#include +#include +using namespace std; + +int arr[1000003]; + +int main() { + int n; + scanf("%d", &n); + for (int i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + sort(arr, arr+n); + for (int i = 0; i < n; i++) { + printf("%d\n", arr[i]); + } + return 0; +} diff --git a/chapters/urejanje/urejanje.tex b/chapters/urejanje/urejanje.tex new file mode 100644 index 0000000..83dad89 --- /dev/null +++ b/chapters/urejanje/urejanje.tex @@ -0,0 +1,105 @@ +%#template templates/template.tex + +%#block title +Urejanje +%#endblock + +%#block content + +\section{Osnovno o urejanju} + +V programih pogosto želimo nek seznam števil urediti po vrsti. +V ta namen lahko napišemo svojo funkcijo, ki implementira enega od znanih +algoritmov za urejanje; npr.~\textit{bubble sort}, \textit{insertion sort}, +\textit{quick sort}, ipd. Ker pa so učinkovite implementacije pogosto komplicirane +in se pri pisanju hitro zmotimo, je bolje, da uporabimo funkcije, ravno v ta +namen vključene v standardno knjižnjico. Za to bomo potrebovali na začetek +programa dodati še dve vrstici: + +%#insert python3 style.py < chapters/urejanje/algorithm.cpp + +Ukaz \verb+#include+ že poznamo, opazimo pa, da tokrat za spremembo nima končnice +\verb+.h+. To je zato, ker funkcije, ki smo jih uporabljali do sedaj, izvirajo +iz jezika C, tokrat pa potrebujemo funkcijo, napisano posebaj za C++. To razloži +tudi drugo vrstico; vse funkcije v standardni knjižnjici v C++ so vključene +v imenski prostor \verb+std+. Če jih želimo klicati, moramo pred ime funkcije +vedno napisati \verb+std::+, ali pa na začetek programa vključiti vrstico +\verb+using namespace std+. + +Sedaj lahko uporabimo funkcijo \verb+sort+, ki sprejme dva argumenta; +začetek in konec predela spomina, ki ga želimo urediti. Poglejmo si enostavni +primer. + +%#insert python3 style.py < chapters/urejanje/uporaba.cpp + + +Program prebere število \(n\), za njim pa še \(n\) števil, jih uredi naraščajoče, +in jih izpiše. Funkcijo \verb+sort+ smo poklicali tako, da smo kot prvi argument +podali seznam \verb+arr+, kot drugi argument pa konec predela seznama, ki ga +želimo urediti; to zapišemo kot \verb|arr+n|. Točen pomen tega izraza bomo +spoznali v prihodnje, za sedaj pa bomo kot drugi argument vedno podali seznam +plus njegovo dolžino. + +Optimalna časovna zahtevnost algoritma za urejanje je \(O(n \log n)\). To v praksi +pomeni, da bo urejanje delovalo dovolj hitro za \(n \le 10^6\). Če imamo več +podatkov kot toliko, bo urejaje trajalo predolgo in naša rešitev ne bo sprejeta. + +\section{Primerjalna funkcija} + +Če želimo urediti seznam padajoče namesto naraščajoče, lahko seznam prvo uredimo +naraščajoče, in ga nato obrnemo. Ker s tem dobimo veliko dodatnega dela, je +bolje, da funkciji \verb+sort+ podamo lastno primerjalno funkcijo. Le-ta mora +sprejeti dva argumenta ter vrniti \verb+bool+, in sicer; če mora biti prvi +argument v urejenem seznamu levo od drugega, mora funkcija vrniti \verb+true+, +sicer pa \verb+false+. + +Če ne podamo tretjega argumenta, se \verb+sort+ obnaša tako, kot da bi podali +naslednjo funkcijo: + +%#insert python3 style.py < chapters/urejanje/compare.cpp + +Če želimo urediti seznam padajoče, moramo le podati nasprotno funkcijo: + +%#insert python3 style.py < chapters/urejanje/nasprotno.cpp + +\subsection{Urejanje sestavljenih podatkov} + +Recimo, da imamo v nalogi dana imena tekmovalcev ter točke, ki so jih ti +tekmovalci dosegli na tekmovanju, naš cilj pa je, da izpišemo imena tekmovalcev +po vrsti glede na doseženo število točk. Če bomo prebrali točke in imena v +različna seznama, ter uredili seznam točk, bo seznam imen ostal nespremenjen in +ne bomo več vedeli, katero ime pripada katerim točkam. + +Kako uredimo oba seznama hkrati? Bolj enostavna možnost je uporaba \verb+struct+, +ki pa ga še ne poznamo. Namesto tega si lahko pripravimo seznam indeksov, ki +na začetku na \verb+i+-tem mestu hrani številko \verb+i+. Če sestavimo funkcijo +\verb+compare+ tako, da sprejme dva indeksa, ter ju uredi glede na vrednosti +v tabeli s točkami na pripadajočih indeksih. Urejamo pa ne tabele s točkami, +temveč novo tabelo indeksov. +Na ta način se tabeli s točkami in z imeni ne bosta spreminjali, +in bodo točke pripadale imenu na istem indeksu. + +\begin{examples} + +Primer implementacije opisane rešitve: + +%#insert python3 style.py < chapters/urejanje/kombinirani.cpp + +\begin{inout} + 5 \\ + France 37 \\ + Gregor 34 \\ + Julija 38 \\ + Matija 29 \\ + Urska 8 \\ + \tcblower + Julija + France + Gregor + Matija + Urska +\end{inout} + +\end{examples} + +%#endblock \ No newline at end of file diff --git a/for-loop.tex b/for-loop.tex deleted file mode 100644 index 25d96a0..0000000 --- a/for-loop.tex +++ /dev/null @@ -1,525 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 9in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\title{For zanka} -\date{} - -\begin{document} -\maketitle - -\section{Kako napišemo zanko?} - -V programiranju pogosto želimo nek del kode ponoviti, zato imamo \emph{zanke}. -Zanka, ki jo bomo najpogosteje uporabljali je \emph{for} zanka, -ki deluje na princip \textbf{začetka}, \textbf{pogoja} in \textbf{koraka}. -\begin{examples} -\verb+Najbolj osnoven program, ki uporablja for zanko.+ - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - -\PY{+w}{ }\PY{c+c1}{// začetek pogoj korak} -\PY{+w}{ }\PY{k}{for}\PY{+w}{ }\PY{p}{(}\PY{k+kt}{int}\PY{+w}{ }\PY{n}{stevec}\PY{o}{=}\PY{l+m+mi}{0}\PY{p}{;}\PY{+w}{ }\PY{n}{stevec}\PY{+w}{ }\PY{o}{\PYZlt{}}\PY{+w}{ }\PY{l+m+mi}{3}\PY{p}{;}\PY{+w}{ }\PY{n}{stevec}\PY{o}{+}\PY{o}{+}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{c+c1}{// koda, ki se izvedce vsako zanko} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{nekaj}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{p}{\PYZcb{}} - -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - nekaj \\ - nekaj \\ - nekaj -\end{inout} - -\end{examples} - -Poglejmo si, kako ta program deluje. Podpičja v vrstici \\ -\texttt{for~({\textcolor{red}{int~stevec=0}};~\textcolor{blue}{stevec~<~3};~\textcolor{purple}{stevec++})~\{} \\ -razdelijo okrogle oklepaje na tri dele; \textcolor{red}{začetek}, -\textcolor{blue}{pogoj} in \textcolor{purple}{korak}. -Začetek se bo izvedel, ko se ta zanka začne. Vsakič preden se izvede koda -v notranjosti zanke se preveri pogoj, če drži, -se bo še enkrat izvedla koda v zanki, sicer se bo pa zanka končala. -Korak je podoben začetku, le da se izvede na koncu vsake ponovitve zanke. - -Tu začetek naredi novo številko $stevec$ in jo nastavi na $0$. -Pogoj preveri, če je $stevec$ manjši od $3$. Korak \texttt{stevec++} je pa -okrajšava za \texttt{stevec = stevec + 1}, torej poveča $stevec$ za $1$. - -\begin{itemize} - \item Program se začne in pride do for zanke, - najprej se izvede začetek \texttt{int~stevec=0}. - \item Zdaj se je začela zanka, preveri se pogoj \texttt{stevec~<~3}. - Ker je $stevec$ za zdaj še $0$, je pogoj izpolnjen. Izvede se vsebina zanke, - torej program izpiše \emph{nekaj}. Zdaj smo prišli do konca zanke, - izvede se korak, $stevec$ se poveča na $1$, program pa skoči nazaj na - začetek zanke. - \item Ker smo na začetku zanke se preveri pogoj, \texttt{stevec~<~3}, - ker je $stevec$ zdaj $1$ je pogoj še vedno izpolnjen, zato se izvede - vsebina zanke. Ko program še enkrat izpiše \emph{nekaj} izvede korak, - $stevec$ poveča na $2$ in skoči nazaj na začetek. - \item Spet smo na začetku, zato se preveri pogoj, $stevec$ je zdaj $2$, - kar je manjše od $3$, zato se \emph{nekaj} spet izpiše. Program poveča - $stevec$ na $3$ in skoči nazaj na začetek. - \item Ker smo spet na začetku se bo še enkrat preveril pogoj, - a zdaj je $stevec$ enak $3$ in $3$ ni manjše od $3$, - zato se for zanka konča. Ker je naslednji ukaz \texttt{return 0;} se bo - program tam končal. -\end{itemize} - -Vidimo, da bo res izpisal \emph{nekaj} trikrat. Vredno je omeniti, -da je naš števec zavzel vrednosti 0, 1, 2, kar se mogoče zdi čudno, glede na -to, da bi ponavadi šteli do tri kot 1, 2, 3, a je \emph{štetje od nič} zelo -pogosto v programiranju, zato smo se odločili, da vas že od začetka poskušamo -navaditi nanj. - -\section{Razni primeri uporabe for zanke} - -\subsection{Spreminjanje dolžine for zanke} -Zanka, ki smo jo napisali zgoraj, se bo vedno ponovila trikrat, -kaj pa če hočemo da se zanka ponovi glede na neko število na vhodu? -Seveda je tudi to mogoče in sicer tako, da vstavimo našo spremenljivko v pogoj -for zanke. Poglejmo si primer: - -\begin{examples} -\verb+Program, ki dobi število in nariše puščico te dolžine.+ - -\verb+Še en trik tu je, da printf-ja v for zanki ne končamo z \n, kar doseže+ - -\verb+to, da so v izhodu pomišljaji eden zraven drugega v isti vrstici in ne+ - -\verb+vsak v svoji vrstici.+ - -\begin{Verbatim}[commandchars=\\\{\}] - \PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - - \PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{dolzina}\PY{p}{;} - \PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{dolzina}\PY{p}{)}\PY{p}{;} - - \PY{+w}{ }\PY{k}{for}\PY{+w}{ }\PY{p}{(}\PY{k+kt}{int}\PY{+w}{ }\PY{n}{stevec}\PY{o}{=}\PY{l+m+mi}{0}\PY{p}{;}\PY{+w}{ }\PY{n}{stevec}\PY{+w}{ }\PY{o}{\PYZlt{}}\PY{+w}{ }\PY{n}{dolzina}\PY{p}{;}\PY{+w}{ }\PY{n}{stevec}\PY{o}{+}\PY{o}{+}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZhy{}}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{+w}{ }\PY{p}{\PYZcb{}} - - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZgt{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - - \PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - \PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - 4 - \tcblower - -{}-{}-{}-> -\end{inout} - -\end{examples} - -\subsection{Branje števil v for zanki} - -Ena od moči računalnikov je zelo hitra obdelava velike količine podatkov, -računalnik bo zlahka seštel 1000 števil, medtem ko bi bilo to početi na roko -precej zamudno. Poglejmo si, kako bi napisali program, ki bi nekaj izračunal z -več števili. - -\begin{examples} -\verb+Najprej preberemo eno število, recimo mu n.+ - -\verb+Po njemu moramo prebrati še n števili in jih sešteti.+ - -\begin{Verbatim}[commandchars=\\\{\}] - \PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - - \PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{n}\PY{p}{;} - \PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{n}\PY{p}{)}\PY{p}{;} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{vsota}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - - \PY{+w}{ }\PY{k}{for}\PY{+w}{ }\PY{p}{(}\PY{k+kt}{int}\PY{+w}{ }\PY{n}{i}\PY{o}{=}\PY{l+m+mi}{0}\PY{p}{;}\PY{+w}{ }\PY{n}{i}\PY{+w}{ }\PY{o}{\PYZlt{}}\PY{+w}{ }\PY{n}{n}\PY{p}{;}\PY{+w}{ }\PY{n}{i}\PY{o}{+}\PY{o}{+}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{sestevanec}\PY{p}{;} - \PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{sestevanec}\PY{p}{)}\PY{p}{;} - \PY{+w}{ }\PY{n}{vsota}\PY{+w}{ }\PY{o}{+}\PY{o}{=}\PY{+w}{ }\PY{n}{sestevanec}\PY{p}{;} - \PY{+w}{ }\PY{p}{\PYZcb{}} - - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{vsota}\PY{p}{)}\PY{p}{;} - - \PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - \PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - 4 \\ - 12 \\ - 13 \\ - 8 \\ - 1 - \tcblower - 34 -\end{inout} - -\end{examples} - -V zgornjem primeru se je zgodilo precej novih stvari, poglejmo si vse po vrsti. - -Najprej preberemo n iz navodil. Naredimo novo spremenljivko z imenom $vsota$, v njo -bomo sešteli vsa dana števila. - -Opazimo, da je v for zanki namesto $stevec$ zdaj uporabljen $i$, tradicionalno -se namreč v for zankah uporablja $i$. -V notranjosti zanke so zdaj trije ukazi. Najprej naredimo novo -spremenljivko, ki jo poimenujemo $sestevanec$ in preberemo naslednje -število iz vhoda. Nato pa z okrajšavo \texttt{vsota~+=~sestevanec;} prištejemo -spremenljivki $vsota$ spremenljivko $sestevanec$. Na daljše bi to lahko napisali -\texttt{vsota~=~vsota~+~sestevanec}. - -\subsection{While zanka in branje neznano mnogo števil} - -Naučili smo se, kako se prebere nekaj števil, ko nam je podano koliko števil -moramo prebrati. Kaj pa če tega ne vemo, če hočemo pač prebrati vsa števila, -ki so na vhodu? Zato lahko uporabimo \emph{while} zanko, ki deluje tako kot -for zanka, le da ima samo pogoj. - -\begin{examples} -\verb+Preperimo vsa števila in jih zmnožimo.+ - -\begin{Verbatim}[commandchars=\\\{\}] - \PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - - \PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{1}\PY{p}{;} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{clen}\PY{p}{;} - - \PY{+w}{ }\PY{k}{while}\PY{+w}{ }\PY{p}{(}\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{clen}\PY{p}{)}\PY{+w}{ }\PY{o}{=}\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{1}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - \PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{*}\PY{+w}{ }\PY{n}{clen}\PY{p}{;} - \PY{+w}{ }\PY{p}{\PYZcb{}} - - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{produkt}\PY{p}{)}\PY{p}{;} - - \PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - \PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - 2 \\ - 3 \\ - 4 \\ - 5 - \tcblower - 120 -\end{inout} - -\end{examples} - -Kot že povedano, zgoraj napisani stavek while bi enako napisali kot -\texttt{for~(~;~scanf("\%d")~==~1~;~)}, torej for zanka, ki ima samo pogoj. -Mogoče se zdi čudno, da ukaz scanf \emph{primerjamo} s številko, a bomo kasneje -v letu, ko se bomo učili o funkcijah razumeli, kaj to pomeni. Za zdaj pa -bomo rekli le, da to, da je scanf \emph{enak} ena pomeni, da je uspešno prebral -in shranil eno številko. Če bi zgornji program prebral v človeških besedah, bi -bilo: -\begin{itemize} - \item Nastavi $produkt$ na 1 - \item Naredi novo spremenljivko $clen$ - \item Preberi eno število in ga shrani v $clen$, dokler tega ne moreš - narediti več. - \item Nastavi $produkt$ na $produkt * clen$ - \item Ko končaš s množenjem vseh členov, izpiši rezultat. -\end{itemize} - -\begin{errors} -\verb+Tu na začetku nastavimo produkt na 0, kar pa je napaka, saj je 0 krat+ - -\verb+karkoli še vedno 0. Naš program bo veno izpisal 0 ne glede na vhod.+ - -\begin{Verbatim}[commandchars=\\\{\}] - \PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - - \PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - - \PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{clen}\PY{p}{;} - - \PY{+w}{ }\PY{k}{while}\PY{+w}{ }\PY{p}{(}\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{clen}\PY{p}{)}\PY{+w}{ }\PY{o}{=}\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{1}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - \PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{produkt}\PY{+w}{ }\PY{o}{*}\PY{+w}{ }\PY{n}{clen}\PY{p}{;} - \PY{+w}{ }\PY{p}{\PYZcb{}} - - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{produkt}\PY{p}{)}\PY{p}{;} - \PY{+w}{ } - \PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - \PY{p}{\PYZcb{}} -\end{Verbatim} - -\end{errors} - -\subsection{For zanka z drugačnim korakom in začetkom} - -Do zdaj so vse naše for zanke izgledale nekako tako -\texttt{for~(int~i=0;~i~<~10;~i++)}, torej so začele na nič in se nekajkrat -ponovile. Ampak zapis for zanke, ki ga imamo v c++ lahko naredi veliko več. -Poglejmo kot primer zanko, ki izpiše vsa soda števila med $1$ in $100$. - -Pozorno poglejmo števila, ki jih moramo izpisati. Ker $1$ ni sodo, bo prvo -izpisano število $2$. Število $3$ prav tako ni sodo, tako da bomo izpisali $4$, -po tem pa $6$, $8$, $10$ in tako dalje. Vidimo, da vsak korak povečamo izpisano -število za $2$, napišimo torej program. - -\begin{examples} -\verb+Izpišemo vsa soda števila med 1 in 100.+ - -\begin{Verbatim}[commandchars=\\\{\}] - \PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{+w}{ }\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - - \PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - - \PY{+w}{ }\PY{k}{for}\PY{+w}{ }\PY{p}{(}\PY{k+kt}{int}\PY{+w}{ }\PY{n}{i}\PY{o}{=}\PY{l+m+mi}{2}\PY{p}{;}\PY{+w}{ }\PY{n}{i}\PY{o}{\PYZlt{}}\PY{o}{=}\PY{l+m+mi}{100}\PY{p}{;}\PY{+w}{ }\PY{n}{i}\PY{+w}{ }\PY{o}{+}\PY{o}{=}\PY{+w}{ }\PY{l+m+mi}{2}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} - \PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{i}\PY{p}{)}\PY{p}{;} - \PY{+w}{ }\PY{p}{\PYZcb{}} - - \PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} - \PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - 2 \\ - 4 \\ - 6 \\ - 8 \\ - 10 \\ - 12 \\ - $\vdots$ \\ - 96 \\ - 98 \\ - 100 -\end{inout} - -\end{examples} - -Ker se želena števila začnejo z dva, bomo v začetni del for zanke vpisali -\texttt{int i=2}. Ker hočemo izpisati števila med $1$ in $100$ in ne med $1$ in -$99$ bomo v pogojnem delu uporabili znak manjše ali enako \texttt{i<=100} -(pogoj \texttt{i<100} ne bi veljal za število $100$). Ker želimo povečati naše -število za $2$ vsak korak, smo v polje za korak napisali \texttt{i += 2}. -Edina stvar, ki jo naredimo v notranjosti napisane zanke pa je, da izpišemo -trenutno vrednost spremenljivke $i$. - - -\end{document} diff --git a/inout.tex b/inout.tex deleted file mode 100644 index 0b9742e..0000000 --- a/inout.tex +++ /dev/null @@ -1,370 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 9in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\title{Branje in pisanje} -\date{} - -\begin{document} -\maketitle - -\section{Vhod in izhod} -Programi za svoje delovanje potrebujejo način za komunikacijo z -uporabnikom. Kompleksnejši programi v ta namen uporabljajo ekran, miško -in tipkovnico. Pri tekmovalnem programiranju pa najpogosteje uporabljamo najpreprostejši način za komunikacijo: pisanje in branje s \emph{standardnega vhoda in izhoda}. Običajno to pomeni, da se nam ob zagonu programa odpre okno, kamor lahko pišemo programu in kamor program izpisuje stvari.\\ -Ko želimo, da naš program kaj izpiše, uporabimo \emph{funkcijo} \verb+printf+. -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Hello World!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -\tcblower -Hello World! -\end{inout} - - -\end{examples} - -\verb+printf+ - funkcija, ki ji v dvojnih narekovajih damo besedilo ali števila, ki jih želimo izpisati\\ -\verb+\n+ - znak za novo vrstico -\\\\ -Stvari, ki jih mora vsebovati (skoraj) vsak program: -\begin{itemize} - \item \verb+stdio.h+ - \emph{knjižnica} (datoteka), ki vsebuje funkcije, ki jih bomo uporabljali v programu (kot npr. \verb+printf+ in \verb+scanf+) - \item \verb+#include<>+ - ukaz, s katerim našemu programu povemo, katere knjižnice potrebuje - \item \verb+int main(){}+ - telo našega programa - večino kode v programu napišemo med zavite oklepaje - \item \verb+return 0+ - zadnja vrstica v programu, ki sporoča računalniku, da se je pravilno zaključil -\end{itemize} - -\noindent V program lahko dodamo \emph{komentarje}. To je takšno besedilo, ki je napisano v kodi, a vsebinsko ne vpliva na program. -\begin{itemize} - \item \verb+//+ - s tem zakomentiramo vse od poševnic do konca vrstice - \item \verb+/* */+ - s tem lahko zakomentiramo več vrstic ali del znotraj vrstice -\end{itemize} - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}}\PY{c+c1}{ //komentar do konca vrstice} -\PY{+w}{ }\PY{n}{printf}\PY{+w}{ }\PY{c+cm}{/*komentar znotraj vrstice*/}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Zivjo svet!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{c+cm}{/*} -\PY{c+cm}{ komentar} -\PY{c+cm}{ čez} -\PY{c+cm}{ več} -\PY{c+cm}{ vrstic} -\PY{c+cm}{ */} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;}\PY{+w}{ } -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -\tcblower -Zivjo svet! -\end{inout} - -\end{examples} - -\begin{errors} -Zadnji znak, ki ga program izpiše, mora biti \verb+\n+. -\end{errors} - -\begin{errors} -Večina vrstic v programu se konča s podpičjem (\verb+;+) (skoraj vse razen tistih, ki se končajo z oklepaji ali zavitimi zaklepaji). Brez tega program ne bo delal. -\end{errors} - -\pagebreak -\section{Branje} -Program za branje stvari, ki mu jih sporočamo, uporablja funkcijo \verb+scanf+. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{char}\PY{+w}{ }\PY{n}{ime}\PY{p}{[}\PY{l+m+mi}{50}\PY{p}{]}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Kako ti je ime?}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{ime}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Zivjo, \PYZpc{}s!}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{ime}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -{\color{blue} \bf output:} Kako ti je ime?\\ -{\color{blue} \bf input:} Tinka \\ -{\color{blue} \bf output:} Zivjo, Tinka! -\end{inout} - -\end{examples} - - -Če želimo, da program lahko kaj počne s podatki, ki jih je prebral, moramo najprej to shraniti na neko mesto v spominu. Temu mestu rečemo \emph{spremenljivka}, saj lahko s programom spreminjamo, kaj je tam shranjeno. Spremenljivke v svojem programu poimenujemo, v našem primeru ji rečemo \verb+ime+. Vsaki spremenljivki moramo določiti \emph{podatkovni tip}, saj lahko beremo in pišemo več različnih vrst podatkov, npr. besede ali števila. \\\\ -\verb+char+ - s tem povemo, da je naša spremenljivka besedilo oz. \emph{niz} \\\\ -\verb+[...]+ - številka v oglatih oklepajih za besedo pove največjo dolžino niza, ki ga lahko program prebere. - -\begin{errors} %CHECK -Ko določamo največjo dolžino niza, vedno vzamemo večjo številko, kot jo bomo potrebovali. O tem bomo več govorili v kasnejših poglavjih. -\end{errors} - - -Funkciji \verb+scanf+ podamo dva ali več \emph{parametrov}: -\begin{itemize} - \item kaj naj prebere, torej kakšne tipe spremenljivk. To podamo s \emph{formatnikom} (v našem primeru \verb+%s+, ki pomeni niz (\emph{string}). \verb+%s+ prebere vse znake do prvega presledka ali nove vrstice) - \item ostali parametri povejo, kam naj funkcija shrani stvari, ki jih je prebrala (torej v spremenljivke, ki smo jih naredili prej) -\end{itemize} - - -%CHECK -Do zdaj smo funkciji \verb+printf+ podali samo točno določeno besedilo, ki smo ga želeli izpisati. Izpisujemo pa lahko tudi spremenljivke, kot smo to naredili v tem zadnjem primeru. Znotraj besedila dodamo formatnike na mesta, kjer želimo, da so spremenljivke, potem pa izven narekovajev naštejemo imena spremenljivk, ki jih želimo izpisati (tako kot pri funkciji \verb+scanf+). - -\pagebreak -\section{Branje števil} -%CHECK -Poleg nizov lahko programi delajo tudi s števili. Števila beremo in izpisujemo z istima funkcijama kot nize, vendar moramo uporabiti drug formatnik. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{razred}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Kateri razred si?}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{razred}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d. razred je najboljši.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{razred}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -{\color{blue} \bf output:} Kateri razred si?\\ -{\color{blue} \bf input :} 7\\ -{\color{blue} \bf output:} 7. razred je najboljši. -\end{inout} - -\end{examples} - -%CHECK -\verb+&+ - znak, ki ga moramo dati pred ime spremenljivke vedno, kadar beremo števila. -\verb+int+ - podatkovni tip število \\ -Pri številih za imenom spremenljivke ne povemo, kako velika so lahko. \\\\ -Za branje in pisanje števil uporabimo formatnik \verb+%d+. - -\begin{errors} -Ko beremo števila, moramo pred ime spremenljivke dati znak \verb+&+, česar pri branju nizov ne delamo. Prav tako tega ne delamo pri izpisovanju števil. -\end{errors} - -\end{document} diff --git a/inout_advanced.tex b/inout_advanced.tex deleted file mode 100644 index 10d0162..0000000 --- a/inout_advanced.tex +++ /dev/null @@ -1,482 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 10in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\title{Branje in pisanje 2} -\date{} - -\begin{document} -\maketitle - -\section{Scanf} - -Funkcija \verb+scanf+ lahko bere različne vrste podatkov: -\begin{itemize} - \item \verb+%s+ - beseda (vsi znaki razen praznih znakov (glej spodaj)) (\verb+char+) - \item \verb+%c+ - en (poljuben) znak (\verb+char+) - \item \verb+%d+ - število med $-2^{31}$ in $2^{31}-1$ (\verb+int+) - \item \verb+%lld+ - število med $-2^{63}$ in $2^{63}-1$ (\verb+long long+) - \item ... -\end{itemize} - -\noindent Prazni znaki (whitespace) so znaki, ki jih ne vidimo: -\begin{itemize} - \item \verb+\n+ nova vrstica - \item \verb+\t+ zamik - \item " " presledek -\end{itemize} - -S formatnikom \verb+%s+ funkcija \verb+scanf+ bere do prvega takšnega znaka. Prebere tudi vse take znake, ki sledijo, a jih ne shrani. Naslednjič, ko jo pokličemo, bere od prvega nepraznega znaka naprej. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{char}\PY{+w}{ }\PY{n}{a}\PY{p}{[}\PY{l+m+mi}{50}\PY{p}{]}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{[}\PY{l+m+mi}{50}\PY{p}{]}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s \PYZpc{}s}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -Hello \\ \\ World! -\tcblower -Hello World! -\end{inout} - - -\end{examples} - -\pagebreak -\section{Branje do konca vrstice} - -Lahko določimo, da se \verb+scanf+ ne bo ustavil pri prvem praznem znaku, temveč šele pri koncu vrstice (ali kje drugje). - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{char}\PY{+w}{ }\PY{n}{a}\PY{p}{[}\PY{l+m+mi}{50}\PY{p}{]}\PY{p}{;} -\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}[\PYZca{}}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{]}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{)}\PY{p}{;}\PY{+w}{ }\PY{c+c1}{//ali scanf(\PYZdq{}\PYZpc{}[\PYZca{}\PYZbs{}n]\PYZpc{}*c\PYZdq{}) in brez getchar()} -\PY{+w}{ }\PY{n}{getchar}\PY{p}{(}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -Beremo do konca vrstice. -\tcblower -Beremo do konca vrstice. -\end{inout} - -\end{examples} - -\verb+[...]+ - med oklepaje pišemo navodila, kakšne znake lahko bere -\begin{itemize} - \item \verb+[a-z]+ - beri male črke angleške abecede - \item \verb+[a-zA-Z0-9]+ - beri male in velike črke in številke -\end{itemize} - -\verb+[^...]+ - beri vse do znakov, ki sledijo strešici -\begin{itemize} - \item \verb+[^\n]+ - beri vse do \verb+\n+ -\end{itemize} - -%CHECK -\begin{errors} -Za razliko od \verb+%s+ funkcija \verb+scanf+ s \verb+[^\n]+ prebere vse do \verb+\n+, tega pa ne prebere in se ustavi pred njim. Ko funkcijo pokličemo naslednjič, začne tam, kjer je nazadnje ostala, kar je v tem primeru točno pred znakom \verb+\n+. Če jo torej ponovno pokličemo s parametrom \verb+[^\n]+, se ne bo nikamor premaknila, saj je pred njo znak za novo vrstico. \\ -\end{errors} - -%CHECK -\verb+%c+ - prebere en znak (\verb+char+), ki je lahko karkoli - črka, številka, prazen znak... \\ -\verb+%*c+ - prebere en znak, a ga ne shrani \\ -Funkcija \verb+getchar+ dela podobno, vzame en znak in ga ne shrani. \\ - -Za razliko od tega s formatnikom \verb+%s+ preberemo vse prazne znake med dvema -nepraznima nizoma in jih ne shranimo. Tudi, če bodo prazni znaki pred besedo, -jih bo program ignoriral in poiskal prvi neprazen znak. - -\pagebreak -\section{Branje do konca vhoda} - -Če vemo točno, koliko besed/številk/vrstic bomo imeli na vhodu, jih lahko preberemo s for zanko. Kako preberemo neznano količino podatkov na vhodu, tako da preberemo vse? \\ -Če napišemo \verb+while(true)+ ali \verb+while(1)+, bomo sicer prebrali vse, a se program ne bo nikoli ustavil. -Namesto tega lahko napišemo: - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{;} -\PY{+w}{ }\PY{k}{while}\PY{p}{(}\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{)}\PY{+w}{ }\PY{o}{!}\PY{o}{=}\PY{+w}{ }\PY{n}{EOF}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{*}\PY{n}{a}\PY{p}{)}\PY{p}{;}\PY{+w}{ }\PY{c+c1}{//izpisujemo kvadrate prebranega števila} -\PY{+w}{ }\PY{p}{\PYZcb{}} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -1 2 3 4 5 -\tcblower -1\\4\\9\\16\\25 -\end{inout} -\end{examples} - -\vskip 0.15in -%CHECK -\noindent Funkcija \verb+scanf+ vrne število formatnikov, ki jih je uspešno -prebrala (če ji kot parameter podamo samo \verb+%d+, bo vrnila $1$, če je -uspešno prebrala število, sicer pa 0). \verb+EOF+ (End of File) vrne, če na -vhodu ni ničesar več za prebrati. Tedaj se bo zanka ustavila. Če programu -vhodne podatke podajamo iz datoteke, se to zgodi avtomatsko ob koncu datoteke, -če pa mu podatke podajamo na roko, konec vhoda sporočimo s -\verb-Ctrl+D (Linux in MacOS)- ali \verb-Ctrl+Z- (Windows). - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{+w}{ }\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{c}\PY{p}{;} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{r}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d\PYZpc{}d\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{c}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{r}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}}\PY{p}{;} -\end{Verbatim} - -\begin{inout} - 5 8 100 - \tcblower - 3 -\end{inout} -\begin{inout} - 5 8 miha - \tcblower - 2 -\end{inout} - - -\end{examples} - -\pagebreak -\section{Branje in pisanje v in iz niza} - -\verb+scanf+ uporabljamo za branje s standardnega vhoda, \verb+printf+ pa za pisanje na standardni izhod. -Namesto tega lahko beremo in pišemo tudi drugače, npr. v in iz nizov. -Za to uporabljamo funkciji \verb+sscanf+ in \verb+sprintf+, ki delata podobno kot \verb+scanf+ in \verb+printf+. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{n}\PY{p}{;} -\PY{+w}{ }\PY{k+kt}{char}\PY{+w}{ }\PY{n}{a}\PY{p}{[}\PY{l+m+mi}{10}\PY{p}{]}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{;} -\PY{+w}{ }\PY{k+kt}{char}\PY{+w}{ }\PY{n}{text}\PY{p}{[}\PY{p}{]}\PY{o}{=}\PY{l+s}{\PYZdq{}}\PY{l+s}{Slovenska 157 a}\PY{l+s}{\PYZdq{}}\PY{p}{;} -\PY{+w}{ }\PY{n}{sscanf}\PY{p}{(}\PY{n}{text}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s\PYZpc{}d \PYZpc{}c}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{n}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{b}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{sprintf}\PY{p}{(}\PY{n}{text}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}c \PYZpc{}d \PYZpc{}s}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{b}\PY{p}{,}\PY{+w}{ }\PY{n}{n}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}s}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{text}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} - -\tcblower -a 157 Slovenska -\end{inout} - -\end{examples} - -\begin{errors} -Medtem ko \verb+%s+ praznih znakov ne shrani, jih \verb+%c+ obravnava tako kot -vse ostale. Če pogeldamo prejšnji primer vidimo, da je v funkciji -\verb+scanf+ pred \verb+%c+ presledek. Ker so med posameznimi podatki, ki -jih želimo prebrati, presledki, bi \verb+%c+ pobral presledek, ne pa črke, -ki mu sledi. Če med posamezne formatnike postavimo presledek, ta načeloma -pobere prazne znake do naslednjega drugačnega znaka, vendar to v splošnem -ni dobra praksa. -\end{errors} - -\noindent Funkciji \verb+sscanf+ podamo tri parametre (ali več): -\begin{enumerate} - \item ime niza, iz katerega naj bere - \item tip podatka, ki naj ga prebere (niz, število...) - \item kam naj ta podatek zapiše (ime spremenljivke) -\end{enumerate} - -\noindent Funkciji \verb+sprintf+ prav tako podamo tri parametre (ali več): -\begin{enumerate} - \item ime niza, kamor naj piše - \item tip podatka, ki naj ga zapiše - \item kaj naj zapiše (ime spremenljivke ali podatek sam) -\end{enumerate} - -\pagebreak -\section{Branje in pisanje v in iz datoteke} - -Podobno kot v niz lahko pišemo in beremo tudi v in iz datotek s funkcijama \verb+fscanf+ in \verb+fprintf+. - -\begin{examples} -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include}\PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int}\PY{+w}{ }\PY{n+nf}{main}\PY{p}{(}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{k+kt}{int}\PY{+w}{ }\PY{n}{a}\PY{p}{;} -\PY{+w}{ }\PY{k+kt}{FILE}\PY{+w}{ }\PY{o}{*}\PY{n}{fr}\PY{p}{,}\PY{+w}{ }\PY{o}{*}\PY{n}{fw}\PY{p}{;} -\PY{+w}{ }\PY{n}{fr}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{fopen}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{in.txt}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{r}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{fw}\PY{+w}{ }\PY{o}{=}\PY{+w}{ }\PY{n}{fopen}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{out.txt}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{w}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{while}\PY{p}{(}\PY{n}{fscanf}\PY{p}{(}\PY{n}{fr}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{o}{\PYZam{}}\PY{n}{a}\PY{p}{)}\PY{+w}{ }\PY{o}{!}\PY{o}{=}\PY{+w}{ }\PY{n}{EOF}\PY{p}{)}\PY{p}{\PYZob{}} -\PY{+w}{ }\PY{n}{fprintf}\PY{p}{(}\PY{n}{fw}\PY{p}{,}\PY{+w}{ }\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{,}\PY{+w}{ }\PY{n}{a}\PY{o}{*}\PY{n}{a}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{p}{\PYZcb{}}\PY{+w}{ }\PY{c+c1}{//iz datoteke fr preberemo vsa števila in v fw izpišemo njihove kvadrate} -\PY{+w}{ }\PY{n}{fclose}\PY{p}{(}\PY{n}{fr}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{n}{fclose}\PY{p}{(}\PY{n}{fw}\PY{p}{)}\PY{p}{;} -\PY{+w}{ }\PY{k}{return}\PY{+w}{ }\PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -{\color{blue} \bf in.txt:} \\ -1 2 3 4 5 6 7 -\tcblower -{\color{blue} \bf out.txt:} \\ -1\\ -4\\ -9\\ -16\\ -25\\ -36\\ -49 -\end{inout} - -(Ta program ne bere s standardega vhoda in ne piše ne standardni izhod.) -\end{examples} - -\verb+FILE+ - tip podatka -\verb+fopen+ - funkcija, s katero odpremo datoteko, podamo ji ime datoteke, ki -jo želimo odpreti in način \verb+"r"+ (\emph{read} - za branje) ali \verb+"w"+ -(\emph{write} - za pisanje).\\ Datoteke, ki jih odpiramo za branje, morajo že -prej obstajati, sicer se bo program sesul. \\ - -Za datoteke, v katere pišemo, ni nujno, da že obstajajo. Če še ne obstajajo, bo -program ustvaril novo datoteko s tem imenom. Če že obstajajo, program ne bo -pisal na konec te datoteke, temveč bo pobrisal vso prejšnjo vsebino. -Če želimo obstoječi datoteki dodajati vsebino, moramo uporabiti način -\verb+"a"+ (\emph{append} - pripenjanje). - -\verb+fclose+ - funkcija, ki zapre odprto datoteko, podamo ji ime datoteke - -\end{document} diff --git a/lp.py b/lp.py new file mode 100755 index 0000000..0290464 --- /dev/null +++ b/lp.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +# LaTeX Preprocessor +# Process a LaTeX source file with the following custom tags: + +# %#template path/to/template.tex -- Process this file as a subtemplate. +# This must be the first line of the file. + +# %#block blockname -- Begin block definition. Subtemplates can override +# their template's blocks with this directive. + +# %#endblock -- End block definition. Blocks cannot be nested. + +# %#insert shell_command -- This line is replaced with the output +# of shell_command + + +import argparse +import os +import subprocess + + +def find_first_symbol(s): + """Find first symbol in string s. This is the first word, unless it's + dobule-quoted, in which case it's everything until the end of the quote.""" + if s[0] == '"': + try: + idx = s.index('"', 1) + return s[1:idx] + except ValueError: + print(f"Could not find endquote for quoted text {s[:20]}...") + quit(1) + + else: + return s.split()[0] + + +def find_blocks(filecontent): + """Find %#block and %#endblock directives in content. + Return a dictionary of their names and contents.""" + + blockname = None + content = "" + blocks = {} + for ln in filecontent.split("\n"): + stripped = ln.strip() + if stripped.startswith("%#block "): + l = len("%#block ") + blockname = find_first_symbol(stripped[l:]) + + elif stripped.startswith("%#endblock"): + if blockname is None: + print("%#endblock without %#block.") + quit(1) + + blocks[blockname] = content + blockname = None + content = "" + + elif blockname is not None: + content += ln + "\n" + + return blocks + + +def replace_blocks(content, blocks): + """Replace blocks in content with data from blocks. Return new content.""" + + out_content = "" + suppress = False + + for ln in content.split("\n"): + stripped = ln.strip() + if stripped.startswith("%#block "): + l = len("%#block ") + blockname = find_first_symbol(stripped[l:]) + if blockname in blocks: + suppress = True + out_content += ln + "\n" + out_content += blocks[blockname] + else: + out_content += ln + "\n" + elif stripped.startswith("%#endblock") and suppress: + out_content += ln + "\n" + suppress = False + elif not suppress: + out_content += ln + "\n" + + return out_content + + +def replace_inserts(content): + """Replace %#insert directives with their corresponding values.""" + out_content = "" + for ln in content.split("\n"): + stripped = ln.strip() + if stripped.startswith("%#insert "): + l = len("%#insert ") + out_content += \ + subprocess.check_output(stripped[l:], shell=True).decode() + "\n" + else: + out_content += ln + "\n" + return out_content + + +def process_file(filename): + """Process filename, return string of content to be compiled.""" + with open(filename) as f: + content = f.read() + + # if this file depends on a template, process that first + if content.startswith("%#template "): + l = len("%#template ") + template_name = find_first_symbol(content[l:]) + template_content = process_file(template_name) + + # replace blocks in template with blocks in subtemplate (filename) + # ignore everything else in the subtemplate + subtemplate_blocks = find_blocks(content) + + content = replace_blocks(template_content, subtemplate_blocks) + + return replace_inserts(content) + + +def process_and_compile(filename, inhibit_clean=False): + content = process_file(filename) + + new_filename = filename.replace(".tex", ".p.tex") + if new_filename == filename: + # don't override the old file + new_filename = new_filename + ".p" + + with open(new_filename, "w") as f: + f.write(content) + + os.system(f"pdflatex {new_filename}") + + # clean up after ourselves + if not inhibit_clean: + os.remove(new_filename) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(prog="lp.py") + parser.add_argument("filename", help="The file to be processed.") + parser.add_argument( + "--inhibit-clean", + help="Inhibit cleaning of intermediary file", + action="store_const", + const=True, + default=False + ) + args = parser.parse_args() + + process_and_compile(args.filename, args.inhibit_clean) diff --git a/more-conditionals.tex b/more-conditionals.tex deleted file mode 100644 index b54bb67..0000000 --- a/more-conditionals.tex +++ /dev/null @@ -1,452 +0,0 @@ -\documentclass{article} -\usepackage{fancyvrb} -\usepackage{color} -\usepackage[utf8]{inputenc} -\usepackage[a4paper, total={6.2in, 9in}]{geometry} -\usepackage[many]{tcolorbox} -\usepackage[T1]{fontenc} -\usepackage[slovene]{babel} - -\usetikzlibrary{calc} - -\setlength\parindent{0pt} - -\makeatletter -\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% - \let\PY@ul=\relax \let\PY@tc=\relax% - \let\PY@bc=\relax \let\PY@ff=\relax} -\def\PY@tok#1{\csname PY@tok@#1\endcsname} -\def\PY@toks#1+{\ifx\relax#1\empty\else% - \PY@tok{#1}\expandafter\PY@toks\fi} -\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% - \PY@it{\PY@bf{\PY@ff{#1}}}}}}} -\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} - -\@namedef{PY@tok@c}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cp}{\def\PY@tc##1{\textcolor[rgb]{0.19,0.51,0.25}{##1}}} -\@namedef{PY@tok@k}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@o}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@p}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@n}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@s}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@m}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@kc}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kd}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kn}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kp}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kr}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@kt}{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.67}{##1}}} -\@namedef{PY@tok@na}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nb}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@bp}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@no}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nd}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ni}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@ne}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nf}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@fm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@py}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nl}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nn}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nx}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nt}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@nv}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vc}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vg}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vi}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@vm}{\def\PY@tc##1{\textcolor[rgb]{0.05,0.05,0.05}{##1}}} -\@namedef{PY@tok@sa}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sb}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sc}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@dl}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sd}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s2}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@se}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sh}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@si}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sx}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@sr}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@s1}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@ss}{\def\PY@tc##1{\textcolor[rgb]{0.16,0.16,1.00}{##1}}} -\@namedef{PY@tok@mb}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mf}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mh}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mi}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@il}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@mo}{\def\PY@tc##1{\textcolor[rgb]{0.94,0.03,0.94}{##1}}} -\@namedef{PY@tok@ow}{\def\PY@tc##1{\textcolor[rgb]{1.00,0.02,0.02}{##1}}} -\@namedef{PY@tok@ch}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cm}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cpf}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@c1}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} -\@namedef{PY@tok@cs}{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.88}{##1}}} - -\def\PYZbs{\char`\\} -\def\PYZus{\char`\_} -\def\PYZob{\char`\{} -\def\PYZcb{\char`\}} -\def\PYZca{\char`\^} -\def\PYZam{\char`\&} -\def\PYZlt{\char`\<} -\def\PYZgt{\char`\>} -\def\PYZsh{\char`\#} -\def\PYZpc{\char`\%} -\def\PYZdl{\char`\$} -\def\PYZhy{\char`\-} -\def\PYZsq{\char`\'} -\def\PYZdq{\char`\"} -\def\PYZti{\char`\~} -% for compatibility with earlier versions -\def\PYZat{@} -\def\PYZlb{[} -\def\PYZrb{]} -\makeatother - -\definecolor{myblue}{RGB}{0,163,243} -\definecolor{myred}{RGB}{243, 10, 25} -\definecolor{mygreen}{RGB}{50, 205, 50} - -\newcommand{\fon}[1]{\fontfamily{#1}\selectfont} - - -\tcbset{examplestyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myblue, - colback=myblue!20, - attach boxed title to top left, - boxed title style={ - colback=myblue, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\tcbset{inoutstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=mygreen, - colback=mygreen!20, - attach boxed title to top left, - boxed title style={ - colback=mygreen, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily, - fontupper=\ttfamily, - fontlower=\ttfamily, - } -} - -\tcbset{errorstyle/.style={ - enhanced, - outer arc=4pt, - arc=4pt, - colframe=myred, - colback=myred!20, - attach boxed title to top left, - boxed title style={ - colback=myred, - outer arc=4pt, - arc=4pt, - top=3pt, - bottom=3pt, - }, - fonttitle=\sffamily - } -} - -\newtcolorbox[auto counter,number within=section]{examples}[1][]{ - examplestyle, - colback=white, - title=Primer, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} -\newtcolorbox[auto counter]{errors}[1][]{ - errorstyle, - colback=white, - title=Pogoste napake, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\newtcolorbox[auto counter]{inout}[1][]{ - inoutstyle, - colback=white, - title=Primer vhoda in izhoda, - overlay unbroken and first={ - \path - let - \p1=(title.north east), - \p2=(frame.north east) - in - node[anchor=west,font=\sffamily,color=myblue,text width=\x2-\x1] - at (title.east) {#1}; - } -} - -\title{Pogojni stavki: 2. del} -\date{} - -\begin{document} - -\maketitle - -\section{Nizanje pogojev} - -Pogosto se srečamo s problemi, kjer je za rešitev potrebno upoštevati več kot -en pogoj. V takih primerih želimo združiti več pogojnih stavkov tako, da se -nek del kode izvede, če velja prvi pogoj, drugi del kode pa, če prvi pogoj -ne velja, velja pa drugi pogoj. Z gnezdenjem stavkov lahko to v kodo vključimo -na naslednji način: - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{k}{if} \PY{p}{(}\PY{n}{prvi} \PY{n}{pogoj}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če velja prvi pogoj} -\PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{k}{if} \PY{p}{(}\PY{n}{drugi} \PY{n}{pogoj}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če prvi pogoj ne velja,} - \PY{c+c1}{// velja pa drugi pogoj} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če ne veljata ne prvi ne drugi pogoj} - \PY{p}{\PYZcb{}} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -V takem primeru nam je na voljo bližnjica \verb+else if+. Zgornja koda deluje -popolnoma enako kot spodnja: - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{k}{if} \PY{p}{(}\PY{n}{prvi} \PY{n}{pogoj}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če velja prvi pogoj} -\PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{drugi} \PY{n}{pogoj}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če prvi pogoj ne velja,} - \PY{c+c1}{// velja pa drugi pogoj} -\PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{c+c1}{// koda, ki se izvede, če ne veljata ne prvi ne drugi pogoj} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -Prednost te bližnjice je, da je naša koda krajša in bolj razumljiva. -Stavke \verb+else if+ lahko tudi verižimo; enemu \verb+if+ stavku lahko sledi -poljubno mnogo stavkov \verb+else if+. Pri tem bo računalnik pogoje preverjal po -vrsti. Pri prvem veljavnem pogoju se bo ustavil in izvedel kodo v pripadajočih -zavitih oklepajih, za čimer ne bo več preverjal pogojev, temveč bo izvajanje -nadaljeval za zaključkom vseh nanizanih stavkov. - -Kakor nam v osnovnem \verb+if+ stavku ni bilo treba pisati dela z \verb+else+, -če ga nismo potrebovali, nam ga tudi pri uporabi \verb+else if+ ni treba. - -\pagebreak -\begin{examples} -Naslednji program prebere število in pove, če je večje, manjše ali enako 0. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{k+kt}{int} \PY{n}{stevilo}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{stevilo}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{stevilo} \PY{o}{\PYZlt{}} \PY{l+m+mi}{0}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Stevilo je manjse od nic.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{stevilo} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{0}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Stevilo je enako 0.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{stevilo} \PY{o}{\PYZgt{}} \PY{l+m+mi}{0}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Stevilo je vecje od 0.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -3 -\tcblower -Stevilo je vecje od 0. -\end{inout} - -\end{examples} - -\begin{examples} -Pogoji se preverjajo po vrsti; izvede se samo koda pri prvem veljavnem pogoju, -ne glede na to, koliko pogojev za njim je tudi veljavnih. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{k+kt}{int} \PY{n}{a} \PY{o}{=} \PY{l+m+mi}{7}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZlt{}} \PY{l+m+mi}{3}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{a je manjsi od 3.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{7}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{a je 7.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{4}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{a je 4.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{k}{if} \PY{p}{(}\PY{n}{a} \PY{o}{\PYZgt{}} \PY{l+m+mi}{1}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{a je vecji od 1.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Nic od nastetega ne velja.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -Program izpiše le eno stvar - \verb+a je 7.+, kljub temu, da velja tudi -\verb+a > 1+. - -\end{examples} - -\section{Logični vezniki} - -Osnovni operatorji za primerjavo pogosto niso dovolj, da izrazimo željen pogoj. -Če na primer želimo pogledati, ali je neko število med dvema drugima, tega ne -moramo narediti samo z eno primerjavo. - -Pogoje združujemo s t.i. \emph{logičnimi vezniki}, ki jim včasih pravimo tudi -\emph{logični operatorji}. Poznamo tri osnovne veznike: -\begin{itemize} - \item \verb+and+ oz.~\verb+&&+ združi dva pogoja tako, da združeni pogoj velja - samo v primeru, da veljata oba hkrati. - \item \verb+or+ oz.~\verb+||+ združi dva pogoja tako, da združeni pogoj velja - v primeru, da velja katerikoli od dveh, ali da veljata oba - \item \verb+not+ oz.~\verb+!+ sprejme samo en pogoj. Nov pogoj velja samo - takrat, ko originalni pogoj ne velja. -\end{itemize} - -Logična veznika \verb+&&+ (\emph{in}) ter \verb+||+ (\emph{ali}) lahko -predstavimo z resničnostno tabelo. - -\begin{table}[h!] - \centering - \caption{Resničnostna tabela za in} - \vspace{0.1cm} - \begin{tabular}{c|c|c} - Leva vrednost & Desna vrednost & Vrednost veznika \\ - \hline - resnica & resnica & resnica \\ - resnica & neresnica & neresnica \\ - neresnica & resnica & neresnica \\ - neresnica & neresnica & neresnica - \end{tabular} -\end{table} - -\begin{table}[h!] - \centering - \caption{Resničnostna tabela za ali} - \vspace{0.1cm} - \begin{tabular}{c|c|c} - Leva vrednost & Desna vrednost & Vrednost veznika \\ - \hline - resnica & resnica & resnica \\ - resnica & neresnica & resnica \\ - neresnica & resnica & resnica \\ - neresnica & neresnica & neresnica - \end{tabular} -\end{table} - -\begin{examples} - -Če želimo preveriti, ali je dano število med dvema drugima, uporabimo -logični veznik \verb+&&+. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{k+kt}{int} \PY{n}{n}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{n}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{l+m+mi}{3} \PY{o}{\PYZlt{}} \PY{n}{n} \PY{o}{\PYZam{}}\PY{o}{\PYZam{}} \PY{n}{n} \PY{o}{\PYZlt{}} \PY{l+m+mi}{9}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{n je med 3 in 9.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\begin{inout} -5 -\tcblower -n je med 3 in 9. -\end{inout} - -\end{examples} - -\begin{errors} - V matematiki pogosto napišemo dvojno primerjavo: \verb+a < b < c+. - Če nekaj podobnega napišemo v C++ program, se bo le-ta sicer zagnal, vendar - ne bo deloval pravilno. Kaj pričakujemo, da se zgodi, če v tako primerjavo - zapišemo \verb+3 < 2 < 1+? Kaj pa se dejansko zgodi? -\end{errors} - -Pri kombiniranju pogojev bodimo previdni glede pravil prednosti. Zanikanje -(veznik \verb+not+ oz.~\verb+!+) ima namreč prednost pred primerjalnimi -vezniki (\verb+<+, \verb+==+, \ldots), ter drugima ločnima veznikoma. -Če v takem primeru uporabljamo zanikanje, moramo zanikan izraz postaviti -v oklepaje. - -\begin{examples} - Zanikanje se lahko v večini primerov zapiše tudi na krajši način. - - \begin{tabular}{|c|c|c|} - \hline - Izraz & Ekvivalenten izraz & Komentar \\ - \hline - \verb+!(a == b)+ & \verb+a != b+ & \\ - \verb+!(a < b)+ & \verb+a >= b + & Če sta \verb+a+ in \verb+b+ enaka, bo prvi izraz veljaven. \\ - \verb+!(a <= b)+ & \verb+a > b+ & \\ - \hline - \end{tabular} -\end{examples} - -\begin{examples} -Napišimo program, ki preveri, ali je uporabnik vpisal prestopno leto. -Leto je prestopno, če je deljivo s 4; razen, če je hkrati deljivo s 100. Izjema so leta, deljiva -s 400, ki so prestopna kljub temu, da so deljiva s 100. - -Kako te pogoje zapišemo v program? Opazimo, da so leta, deljiva s 400, -prestopna ne glede na druga pogoja. Če leto ni deljivo s 400, potem mora biti -deljivo s 4 in ne sme biti deljivo s 100. Povedano krajše; leto mora biti -deljivo s 400, ali pa s 4 in ne hkrati s 100. Tak pogoj lahko zapišemo z -logičnimi vezniki. - -\begin{Verbatim}[commandchars=\\\{\}] -\PY{c+cp}{\PYZsh{}}\PY{c+cp}{include} \PY{c+cpf}{\PYZlt{}stdio.h\PYZgt{}} - -\PY{k+kt}{int} \PY{n+nf}{main}\PY{p}{(}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{k+kt}{int} \PY{n}{leto}\PY{p}{;} - \PY{n}{scanf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{\PYZpc{}d}\PY{l+s}{\PYZdq{}}\PY{p}{,} \PY{o}{\PYZam{}}\PY{n}{leto}\PY{p}{)}\PY{p}{;} - \PY{k}{if} \PY{p}{(}\PY{n}{leto} \PY{o}{\PYZpc{}} \PY{l+m+mi}{400} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{0} \PY{o}{|}\PY{o}{|} \PY{p}{(}\PY{n}{leto} \PY{o}{\PYZpc{}} \PY{l+m+mi}{4} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{0} \PY{o}{\PYZam{}}\PY{o}{\PYZam{}} \PY{o}{!}\PY{p}{(}\PY{n}{leto} \PY{o}{\PYZpc{}} \PY{l+m+mi}{100} \PY{o}{=}\PY{o}{=} \PY{l+m+mi}{0}\PY{p}{)}\PY{p}{)}\PY{p}{)} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Leto je prestopno.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} \PY{k}{else} \PY{p}{\PYZob{}} - \PY{n}{printf}\PY{p}{(}\PY{l+s}{\PYZdq{}}\PY{l+s}{Leto ni prestopno.}\PY{l+s+se}{\PYZbs{}n}\PY{l+s}{\PYZdq{}}\PY{p}{)}\PY{p}{;} - \PY{p}{\PYZcb{}} - \PY{k}{return} \PY{l+m+mi}{0}\PY{p}{;} -\PY{p}{\PYZcb{}} -\end{Verbatim} - -\end{examples} - -\end{document} diff --git a/tmplt.tex b/templates/template.tex similarity index 98% rename from tmplt.tex rename to templates/template.tex index 2488b90..e06b020 100644 --- a/tmplt.tex +++ b/templates/template.tex @@ -7,6 +7,9 @@ \usepackage[T1]{fontenc} \usepackage[slovene]{babel} +%#block packages +%#endblock + \usetikzlibrary{calc} \setlength\parindent{0pt} @@ -209,12 +212,18 @@ at (title.east) {#1}; } } -\title{Naslov/tema ure} + +\title{ +%#block title +%#endblock +} \date{} \begin{document} \maketitle +%#block content + \section{Poglavje, če ima ta tema poglavja} Nek tekst o temi poglavja in recimo \emph{novi pojmi}. @@ -235,4 +244,6 @@ \section{Poglavje, če ima ta tema poglavja} Pogoste napake/opozorila pri tej temi. \end{errors} +%#endblock + \end{document}