FOT mehjlparinn: S kvlina sem vlina

S kvlina sem vlina (kvaranataka og rksegir)

N kunnum vi ng C til a reikna, skja inntak og skila ttaki. etta dekkar allar "grunnagerirnar 7" nema ager nmer 5, bera saman tvr tlur og stkkva. r v verur n btt, v a er lti spunni forrit sem ekki geta teki kvaranir.

mynduu FOT-1313 tlvunni hfum vi agerina berasaman sem bar saman tvr tlur og stkk mismunandi stai forritinu eftir v hva kom t r samanburinum. Forrit me slkum samanburi og stkkum geta ori ansi lsileg eins og sst best af vlamlsforritinu sem fann strstu tluna af remur. Ef kmir a v forriti n ess a vita fyrirfram hva a geri tki ig eflaust langan tma a fatta a.

Sum eldri forritunarml, eins og BASIC, voru lk vlamlsforritum a essu leyti. Allar lnur BASIC forritum voru nmeraar og hgt var a stkkva kvena lnu me skipuninni GOTO nn, ar sem nn var nmeri lnunni. Af essari stu voru BASIC forrit oft lka lsileg og vlamlsforrit. Eitt vinslasta forriti egar hfundur essa heftis var a slta barnssknum BASIC forritun var t.d. etta:

   10 PRINT "Harri best"
   20 GOTO 10
Forrit me stkkskipunum fram og til baka eru stundum kllu spagettkdi af v a a er lka auvelt a rekja vinnuganginn eim og a lesa r spagettflkju. Til a bta r essu voru bin til n forritunarml sem kennd voru vi skipulega forritun (structured programming). Eitt eirra var t.d. Algol, en bi C og Pascal geta raki ttir snar til ess. essum mlum er goto skipunin fjarlg en eftirfarandi fyrirkomulag nota stainn: skipunin sem framkvma ef samanburarskilyri er uppfyllt er hf beint fyrir aftan samanburaragerina. Ef samanburarskilyri er ekki uppfyllt er stokki yfir skipunina, .e. hn er ekki framkvmd. Ef framkvma margar skipanir eftir samanbur er hgt a setja r allar inn eina blokk, sem stokki er yfir ef samanburarskilyri er ekki uppfyllt. ettta var engin smrisklausa, en etta skrist fljtlega me dmum.

Samanburaragerin C heitir v lsandi nafni if. egar skrifar C forrit sem tekur kvrun lkist forriti mun meira venjulegu ritmli heldur en vlamlsforrit. Skipun sem notar if er oft kllu ef-setning. Almennt form ef-setningar C er einhvernveginn svona:

   if (skilyri) skipun;
Ef skilyri er uppfyllt er skipun framkvmd, annars er skipun ekki framkvmd. Skilyri birtist t innan sviga (etta er bara ein af reglunum sem C setur). Skipunin getur veri hvaa C skipun sem er, t.d. a = b + 1 ea printf ("Elvis lifir!"). Hn getur meira a segja veri nnur if skipun.

Skilyri er einhver samanburur tlum, eins og alltaf. C hefur yfir a ra eftirfarandi samanburarvirkjum, sem flestir ttu a vera kunnuglegir:

   ==  Sama og
   !=  Ekki sama og
   >   Strra en
   >=  Strra en ea sama og
   <   Minna en
   <=  Minna en ea sama og
Skilyri ef-setningu er einfaldlega samanburarvirki me breytum og/ea fstum og segum sitthvorumegin vi virkjann. Hr er dmi um tv skilyri:

   (a == b)
   (c <= 42)
Taktu vel eftir v a samanburarvirkinn fyrir "sama og" eru tv jafnaarmerki r. Algeng byrjendamistk eru a rugla saman samanburarvirkjanum "sama og" (==) annarsvegar og gildisveitingarvirkjanum (=) hinsvegar. Reyndu a stimpla a strax inn hausinn a etta er alls ekki sami hluturinn!

Tkum dmi um C forrit me ef-setningu. Forriti spyr um tvr heiltlur. Ef tlurnar eru eins skrifar forriti "Tlurnar eru eins". Ef fyrri talan er strri en seinni talan skrifar forriti "Fyrri talan er strri en seinni talan". Annars skrifar forriti "Seinni talan er strri en fyrri talan."

   #include <stdio.h>

   /* Forrit sem spyr um tvr heiltlur og segir til um innbyris str eirra. */

   int main()
   {
      int a, b;

      printf("Slu inn heiltlu: ");
      scanf("%i", &a);
      printf("Slu inn ara heiltlu: ");
      scanf("%i", &b);

      if (a == b)
         printf("Tlurnar eru eins");
      if (a >  b)
         printf("Fyrri talan er strri en seinni talan");
      if (a <  b)
         printf("Seinni talan er strri en fyrri talan");

      return 0;
   }
Hr sru svart hvtu hvernig ef-setningar virka. Taktu eftir v a skipun sem er h ef-setningu (printf skipanirnar essu forriti) er sett nstu lnu fyrir nean if skipunina og er dregin inn um rj bil. munt brtt sj a etta gerir r auveldara a lesa C forrit, srstaklega egar um flknari ef-setningar er a ra, sem geta birst hver inni annarri. Vi gtum allt eins haft skipunina smu lnu ef vi vildum, a skiptir C andann ekki nokkru mli.

Verkefni 12: Bu til forrit sem spyr um eina tlu og prentar "Talan er jkv" ef talan er >= 0 en prentar "Talan er neikv" a rum kosti.

Ein mistk sem byrjendur gera stundum egar eir nota ef-setningar er a setja semkommu eftir skilyrinu, svona:

   if (dagur == 13);
      printf ("g vona a a s ekki fstudagur");
Httan vi essi mistk er a C andinn kvartar ekki. Ein stk semkomma telst vera fullgild skipun C, skipun sem gerir reyndar alls ekki neitt. etta er t.d. fullgild lna C forriti, tt trlegt megi virast:

   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
etta eru 42 skipanir sem gera ekki neitt! Ef-setningin undan segir v raun: ef breytan dagur inniheldur gildi 13, skaltu gera ekki neitt. San er printf skipunin framkvmd, burts fr ef-setningunni, .e. hvort sem breytan dagur er 13 ea ekki. Sumsagt: ekki hafa semkommu eftir skilyrinu, bara skipuninni.

Ef-setningarnar forritinu nu fyrir verkefni 12 litu sjlfsagt einhvernveginn svona t:

   if (a >= 0)
      printf ("Talan er jkv");
   if (a <  0)
      printf ("Talan er neikv");
arna sr sta kvein sun. Forriti yrfti ekki a nota tvo samanburi til a komast a rttri niurstu. Ef talan er ekki strri en ea jfn 0 er augljst a hn er minni en 0. Ef fyrra skilyrinu er ekki fullngt ttum vi a geta undi okkur beint a prenta "Talan er neikv". C forritunarmli var ekki hanna me sun huga og v er boi upp framlengingu if setningu me else klausu.

   if (skilyri) skipun1; else skipun2;
essi setning ir: ef skilyri er fullngt, framkvmdu skipun1, annars skaltu framkvma skipun2. Ef-setningarnar verkefni 12 gtu v liti svona t:
   if (a >= 0)
      printf ("Talan er jkv");
   else
      printf ("Talan er neikv");
Forriti verur bi hravirkara og skrara me essu mti. Athugau a a kemur semkomma eftir bum skipununum en hvorki eftir if ea else. Hgt er a hafa margar else klausur r. N er nll strangt til teki ekki jkv tala. Vi getum v endurbtt forriti svona:

   if (a == 0)
      printf ("Talan er nll");
   else if (a > 0)
      printf ("Talan er jkv");
   else
      printf ("Talan er neikv");
Ef breytan a er nll prentar forriti "Talan er nll", annars ef talan er strri en nll prentar forriti "Talan er jkv" annars prentar forriti "Talan er neikv" (eini mguleikinn sem er eftir). etta er enn eitt dmi um a tlvan geri alltaf upp milli tveggja mguleika en aldrei fleiri. Hn velur milli riggja mguleika me v a velja tvisvar milli tveggja mguleika.

Bum n til forrit sem spyr um tlu og reiknar svo kvaratrtina af henni. Ef talan er neikv kvartar forriti, annars reiknar a kvaratrtina og prentar hana t. Forriti notar keyrslusafnsfalli sqrt til a reikna rtina. Kjarninn r forritinu gti liti svona t:

   if (a <  0) printf ("Get ekki dregi kvaratrt af neikvri tlu!");
   if (a >= 0)
      b = sqrt (a);
   if (a >= 0)
      printf ("Kvaratrtin af %f er %f", a, b);
Fyrsta ef-setningin er sett upp hefbundinn htt, bara til a sna a a s hgt. Neri hluti forritsins er san pandi dmi um sun. Forriti notar tvr samskonar ef-setningar til a framkvma tvr skipanir. Mun hagkvmara vri a a nota eina ef-setningu sem stjrnai bum skipununum. a er ekki ng a gera svona:

   if (a >= 0)
      b = sqrt (a);
      printf ("Kvaratrtin af %f er %f", a, b);
C andinn horfir ekkert a hvernig vi stillum skipununum upp ea drgum inn. Fyrir andanum ltur lnan svona t:

   if ( a >= 0 ) b = sqrt ( a ) ; printf ( "Kvaratrtin af %f er %f" , a , b ) ;
Me rum orum, printf skipunin er h ef-setningunni og er alltaf framkvmd, lka egar a er minni en nll. Vi urfum a nota srstakan rithtt til a segja C andanum a hann eigi a nota margar skipanir (blokk) me ef-setningunni en ekki eina skipun. Vi viljum lta skipanirnar inni blokkinni virka eins og eina skipun me tilliti til ef setningarinnar. Vi skilgreinum blokk af skipunum me v a umlykja r slaufusvigum, { og }. Slaufusvigarnir lta skipanirnar sviganum virka eins og eina skipun me tilliti til ef-setninga, rtt eins og svigi strfri ltur allt sem sviganum er haga sr eins og ein tala me tilliti til reikniagera. ltur forriti svona t:

   if (a <  0)
      printf ("Get ekki dregi kvaratrt af neikvri tlu!");
   if (a >= 0) {
      b = sqrt (a);
      printf ("Kvaratrtin af %f er %f", a, b);
   }
N eru skipanirnar tvr aeins framkvmdar ef a er ekki neikv. Glggir lesendur hafa eftilvill tta sig v a seinni ef-setningunni er ofauki, hgt er a nota else klausu stainn, svona:

   if (a <  0)
      printf ("Get ekki dregi kvaratrt af neikvri tlu!");
   else {
      b = sqrt (a);
      printf ("Kvaratrtin af %f er %.3f", a, b);
   }
Verkefni 13: Skrifau C forrit sem les inn stulana annarsstigsjfnu og segir hvort jafnan hafi einhverjar rauntlulausnir.

Taktu eftir v a vi setjum .3 milli % og f printf skipuninni. etta segir printf a prenta rj aukastafi fyrir aftan kommu (sjlfgefi notar printf 6 aukastafi).

a er takmarka gagn v a vita einungis hvort jafna hafi rauntlulausnir. N skulum vi gera betur og ba til forrit sem finnur lausnirnar lka.

   #include <stdio.h>    /* Fyrir printf og scanf */
   #include <math.h>     /* Til a geta nota sqrt falli */

   int main ()
   {
      double a, b, c;   /* Stularnir  margliunni */
      double rot;       /* liurinn b^2 - 4ac */
      double u1, u2;    /* lausnirnar */

      printf ("Slu inn stuulinn vi x^2: ");
      scanf ("%f", &a);
      printf ("Slu inn stuulinn vi x: ");
      scanf ("%f", &b);
      printf ("Slu inn fastann: ");
      scanf ("%f", &c);

      rot = b*b - 4*a*c;

      if (rot < 0)
         printf ("Jafnan hefur enga rauntlulausn.");
      else {
         u1 = (-b + sqrt (rot)) / (2*a);
         u2 = (-b - sqrt (rot)) / (2*a);
         printf ("Lausnirnar eru %.4f og %.4f.", u1, u2);
      }
      return 0;
   }
Taktu eftir v a n hfum vi #include klausu fyrir math.h. Annars myndi andinn ekki kannast vi falli sqrt. Taktu lka eftir v hvernig mnus virkinn (-) er notaur me einni breytu egar u1 og u2 eru reiknaar t.

Mikilvg bending: a er varasamt a nota == me fleytitlubreytum! Eins og ur sagi er alltaf svoltil skekkja treikningum me fleytitlubreytum. Segjum a rot liurinn eigi a vera nll, t.d. ef b = 4, og a = c = 2. a er mun lklegra a eftir treikningana veri liurinn t.d. 0,000001 heldur en nkvmlega 0. Til a komast framhj essu verur forritarinn a kvea hversu nlgt nlli liurinn arf a vera til a teljast vera nll. sta ess a skrifa:

   if (rot == 0) ...
myndi hann t.d. skrifa

   if (fabs(rot) <  0.00001) ...
fabs er tlugildisfalli fyrir fleytitlur, .e. fabs(x) = |x| (tlugildisfalli fyrir heiltlur heitir abs). Svipu (en minni) htta er flgin notkun <= og >= virkjanna me fleytitlubreytum. Ef srlega mikillar nkvmni er krafist er hgt a nota long double breytur, sem taka 10 bti minni.

Verkefni 14: Endurbttu forriti annig a ef jafnan hefur aeins eina lausn prenti forriti t "Eina lausnin er x" (jafnan hefur bara eina lausn ef liurinn rot er nll).

Vi hfum hinga til a mestu snigengi char breytur (char er skammstfun character). a er tilvali a kynnast eim aeins nnar. char breyta getur innihaldi einn bkstaf. Raunar getur hn innihaldi mis merki lka, eins og punkta, kommur, upphrpunarmerki o.s.frv. char breyta er raun heiltlubreyta dulargerfi, v eins og vi vitum geymir tlvan bkstafi sem tlur. Vi getum nota char breytur nkvmlega eins og int breytur, sett tlur inn r og reikna me eim o.s.frv. Fyrir C andanum eru bkstafir og heiltlur nokkurnveginn sami hluturinn. a er lka elilegt, ar sem tlvan ltur annig mli lka. a hvaa tlur tkna hvaa bkstafi er kalla stafasett tlvu. Eitt tbreiddasta stafasetti er svokalla ASCII stafasett. Tlurnar hr eftir miast vi a sett.

Eftirfarandi er fullkomlega leyfilegt C:

   char k, j;

   k = 25;      /* dmi 1 */
   j = k + 15;  /* j verur 40, sem er stafurinn '(' */

   k = 'E';     /* dmi 2 */
   j = k + 3;   /* hva verur j?? */

   if (j > 'J') printf ("Skirilbabbbmmbei");   /* dmi 3 */
egar bkstafsfastar eru notair C forritum eru eir hafir einfldum gsalppum, til agreiningar fr strengfstum sem eru venjulegum tvfldum gsalppum. C andinn sr um a breyta bkstafnum rtta tlu.

dmi 2 er bkstafurinn E settur inn k og j san gefi gildi E+3. Hva er E+3? J, bkstfunum er rstafa tlum annig a bkstafurinn stra A fr tluna 65 ( ASCII stafasettinu), stra B tluna 66, stra C tluna 67 o.s.frv. Stra E hefur tluna 69. Breytan j fr v gildi 69+3 = 72, sem er einmitt bkstafurinn H (sem er 3 bkstfum aftar stafrfinu en E).

dmi 3 er breytan j san notu ef-setningu, ar sem hn er borin saman vi bkstafinn stra J. Ef breytan j er strri en bkstafurinn J prentar forriti "Skirilbabbbmmbei". N hefur breytan j gildi 72 en bkstafurinn J gildi 74. Skilyrinu er v ekki fullngt og ekkert prentast t. Taktu eftir v a ef-setningin segir raun: "ef bkstafurinn breytunni j er eftir J stafrfinu, prenta". a vri v hgarleikur fyrir okkur a ba til forrit sem raai bkstfum stafrfsr.

Vi skulum n ba til stutt forrit sem notar char breytur.

   char svar;

   printf ("Fli r Mozart? (j/n): ");
   scanf ("%c", &svar);  /* notum "%c" fyrir char breytur */

   if (svar == 'j')
      printf ("Ach so, sehr gut!");
   else if (svar == 'n')
      printf ("r eru undarleg(ur)!");
   else
      printf ("g tti eiginlega von  j ea n ...");
Forriti notar scanf eins og venjulega til a lesa inn svar notandans. ttir a geta tta ig v hvernig forriti vinnur. Bttu haus og hala a og keyru a til a prfa.

Hr lendum vi vandrum, vegna ess a stra J og litla j er alls ekki tkna me smu tlunni. J er bkstafur nmer 74 en j er bkstafur nmer 106. Ef notandinn slr inn J myndi forriti svara t htt "g tti eiginlega von j ea n ..." og vesalings notandinn myndi ruglast rminu. Vi gtum redda essu svona:

   if (svar == 'j')
      printf ("Ach so, sehr gut!");
   if (svar == 'J')
      printf ("Ach so, sehr gut!");
En etta er klassskt dmi um sun. Vi viljum geta nota eitt skilyri til a dekka bi tilfellin. Vi viljum skrifa "ef svar er j ea svar er J ...". etta er a sjlfsgu hgt C, nema hva sta ess a skrifa "ea" notum vi tv lrtt strik, ||. Betri tgfa af forritinu vri einhvernveginn svona:

   if (svar == 'j' || svar == 'J')
      printf ("Ach so, sehr gut!");
Kjarninn r Mozart forritinu yri svona:
   if (svar == 'j' || svar == 'J')
      printf ("Ach so, sehr gut!");
   else if (svar == 'n' || svar == 'N')
      printf ("r eru undarleg(ur)!");
   else
      printf ("g tti eiginlega von  j ea n ...");
Ef vi viljum nota og ef-setningu notum vi tv og-merki, && . Hr er dmi um notkun og ef-setningu:

   int a, b;
   scanf ("%c %c", &a, &b);   /* etta m! */
   if (a > 10 && b > 10)
      printf ("Bar tlurnar eru strri en 10");
Forriti prentar skilaboin aeins ef a er strri en 10 og b er strri en 10. Taktu eftir v hvernig scanf er nota. a getur nefnilega lesi inn margar breytur einu ef vi sendum v marga tknstrengi.

Til a hamra merkingu || og && kyrfilega inn hausinn r birtast birtast virkjarnir hr saman:

   ||	"ea"  rksegum
   && 	"og"  rksegum
Vi getum bi til eins flknar rksegir og okkur lystir me og og ea, samt sm hjlp fr svigunum ef rf krefur. Hr er dmi:

   char k, n;

   printf ("Ertu  kpunni? (j/n) ");
   scanf ("%c", &k);
   printf ("Ertu nmsmaur? (j/n) ");
   fflush (stdin);
   scanf ("%c", &n);

   if ((k == 'j' || k == 'J') &&  (n == 'j' || n == 'J'))
      printf ("V! blankur nmsmaur!");
etta dmi prentar skilaboin ef bi svrin eru j ea J. || og && hafa kvena forgangsr, rtt eins + og -. Til a vera viss um a C andinn tlki segina rtt er ruggast a nota bara fullt af svigum (a geri g ...)

Taktu eftir skipuninni sem kemur rtt undan seinna scanf-inu, fflush (stdin). Hn hefur mikilvgan tilgang. Hnnunin keyrslusafnsfllunum C miast miki til vi lestur og skrift textaskrr. Slkur lestur fer yfirleitt fram lnu fyrir lnu, ekki staf fyrir staf. v er a a jafnvel vi segjum scanf a vi viljum bara lesa inn einn staf les scanf inn heila lnu og ltur okkur san hafa fyrsta stafinn r eirri lnu. etta hentar okkur gtlega nema hva stafirnir eftir eim fyrsta eru eru settir bir og er skila nstu skipti sem kalla er scanf, stainn fyrir a sem notandinn er a sl inn (prfau bara a keyra forriti n ess a nota fflush). Til a losna vi etta kllum vi fflush rtt ur en vi kllum scanf aftur. fflush sr um a tma birina annig a nsti stafur sem vi fum veri sami stafur og notandinn slr inn. stdin er bara srstakt tkn fyrir inntak fr lyklaborinu. a er gtis regla a kalla alltaf fflush ur en lesi er fr lyklaborinu (ea rtt eftir, fyrir nstu scanf).

Hr nst er forritsbtur sem snir hvernig skipanablokkir geta birst hver inni annarri. Bturinn er hluti af forriti sem leggur spurningalista fyrir flk.

   char sv1, sv2, sv3, sv4;

   printf ("Hefur  velt r nktum/nakinni upp r dgg  Jnsmessuntt? ");
   scanf ("%c", &sv1);  fflush (stdin);
   if (sv1 == 'j' || sv1 == 'J') {
      printf ("Fkkstu eitthva kikk t r v? "); /* spurning 2 */
      scanf ("%c", &sv2);  fflush (stdin);
      if (sv2 == 'j' || sv2 == 'J') {
         printf ("Hefuru hugsa r a gera etta aftur? "); /*spurning 3 */
         scanf ("%c", &sv3);
      }
   } else {
      printf ("Hefur ig langa til a prfa a? ");  /* spurning 4 */
      scanf ("%c", &sv4);
   }
   /* spurning 5 ... */
Forriti er betra en spurningalisti pappr a v leytinu til a ekki arf a hafa leibeiningar eins og "Ef svarair 'j' li A, faru li B, annars skaltu fara li C". Forriti sr einfaldlega um a kvea hvaa spurning kemur nst eftir v hvernig notandinn svarar. Ef notandinn svarar fyrstu spurningunni jtandi er fari beint spurningu 2, annars er fari spurningu 4. Ef notandinn svarar spurningu 2 jtandi er fari spurningu 3, annars er fari spurningu 5. Ef r ykir erfitt a sj etta t r forritinu, reyndu a mynda r hve erfitt a vri ef forriti notai stkkskipanir eingngu!

Verkefni 15: Endurbttu forriti annig a a byrji a spyrja notandann hvort hann s karlkyns ea kvenkyns. Lttu san forriti nta sr essa vitneskju til a prenta t " ...nktum..." ea "...nakinni..." eftir v hvort vi, sta "... nktum/nakinni... ". Bttu haus og hala forriti, ddu a og prfau a.

Verkefni 16: (strembi) Bu til forrit sem les inn dagsetningu, .e. les inn dag, mnu og r. Lttu svo forriti athuga hvort dagsetningin s lgleg, .e. a mnuurinn s milli 1 og 12, a dagafjldinn s milli 1 og fjlda daga vikomandi mnui og a ri s ekki neikvtt. Ef ri er minna en 100 (t.d. 95) er 1900 lagt vi a. Reglurnar um hlaupr eru eftirfarandi: ef ri gengur upp fjra er hlaupr, nema aldamtari, er aeins hlaupr ef rtali gengur upp 400. ri 2000 verur til dmis hlaupr af v a 400 gengur upp 2000 en ri 1900 var ekki hlaupr. (bendingar: notau afgangsvirkjann % til a finna t hvort tala gangi upp ara. Ef a % b == 0 gengur b upp a. Notau eina breytu til a halda utan um hvort dagsetningin s lgleg. Lttu breytuna hafa gildi 1 upphafi. Strax og einhver athugun leiir ljs a dagsetningin er lgleg er breytunni gefi gildi 0 og frekari prufur eru ekki gerar. lokin athugar forriti breytuna og prentar t hvort dagsetning var lgleg).

Ef vilt lta forrit framkvma skipun ef skilyri er ekki uppfyllt getur sni skilyrinu vi me v a setja upphrpunarmerki fyrir framan a. Dmi:

   /* mtti skrifa: if (!(c == 'J' || c == 'N')) */
   if (!(c == 'J') &&  !(c == 'N'))
      printf ("Svari er hvorki J n N");
Stundum skiptir mli hvaa r seg er metin. Rksegir eru metnar fr vinstri til hgri. essu dmi:

   if (a == 1 &&  b == 2 &&  c == 3) ...
byrjar forriti a athuga a, san athugar a b og loks athugar a c. C framkvmir aldrei fleiri samanburi en arf. Ef a er ekki 1 dminu hr undan eyir forriti ekki tma a athuga hvort b s 2, a skiptir ekki mli v ekkert gildi b getur lti rksegina vera sanna.

Vi skulum n aeins rannsaka virkjana nnar. Vi kllum = virkja. Vi kllum +, -, * og / virkja lka. ar a auki kllum vi ==, !=, >, >=, < , <=, || og && virkja. Vi fyrstu sn virast essir virkjar samt ekki vera notair sama htt. A setja gildi breytu me = virkjanum er eitt og a bera saman tvr tlur me > = virkjanum er anna, ea hva?

Stareyndin er s a strangt til teki eru allir virkjarnir einskonar reikniagerir, lka virkjarnir fyrir samanbur. >= virkinn C er reikniager rtt eins og + virkinn! a + b skilar summu talnanna a og b. a >= b skilar hinsvegar 1 ef a er strri en b en 0 a rum kosti. Nll ir "satt" C, allar arar tlur a "satt".

   if (77) printf ("Jh!");
essi skipun mun alltaf prenta "Jh!" v talan sviganum er aldrei 0. 77 er annig s srstakt skilyri sem er alltaf satt. Tlvan vinnur me bkstafi sem tlur og auvita vinnur hn me sanngildi sem tlur lka. Fyrr heftinu sagi g a skipunin eftir if yri v aeins framkvmd a skilyri sviganum vri uppfyllt. etta var kvein einfldun eins og sr nna. Rttara er a segja a skipunin veri framkvmd og v aeins a talan sviganum s ekki 0. essu dmi:

   if (0) printf ("Bab!");
myndi forriti aldrei prenta neitt t, v 0 er skilgreiningin "satt" C.

a kemur oft fyrir a athuga urfi hvort breyta s nll ea ekki. Vi gtum t.d. skrifa:

   if (a != 0) printf ("Talan er ekki nll");
Einnig er hgt a skrifa essa lnu svona:

   if (a) printf ("Talan er ekki nll");
Af hverju? J, ef talan er ekki 0 er printf skipunin framkvmd, v allar arar tlur en 0 teljast vera "satt". Mundu a a "satt" s skilgreint sem 0 er "satt" ekki skilgreint sem 1. Satt getur veri 2, 3 o.s.frv, bara ekki 0.

   int c = (-2 >= 5);
Hvaa gildi fr c? J, >= virkinn er bara venjuleg reikniager sem skilar 1 ef talan vinstra megin vi virkjann er strri en ea jfn tlunni hgra megin en 0 annars. ar e -2 er minni en 5 skilar virkinn tlunni 0, sem er san sett inn breytuna c. Anna dmi:

   int c = (0 || 33);
Hvaa gildi fr c? J, || virkinn er bara venjuleg reikniager sem skilar 0 ef bar tlurnar kringum hann eru 0 en 1 annars. ar e nnur talan er ekki 0 skilar virkinn 1, sem fer inn c.

   int c = (0 &&  33);
Hvaa gildi fr c? J, && virkinn er bara venjuleg reikniager sem skilar 1 ef bar tlurnar kringum hann eru ekki 0 en 0 annars. c fr v gildi 0. Hr eru svo mistkin sem svo margir byrjendur gera:

   if (a = 1) ...
Kemuru auga mistkin? Hr tlai forritarinn vntanlega a athuga hvort breytan a vri 1 en hann notar vart = virkjann sta == virkjans. v er gildi 1 sett inn a og v gildi skila til ef-setningarinnar, sem verur alltaf snn! Varau ig essu! Ein lei til a minnka lkurnar essum mistkum er a skrifa alltaf fastann undan breytunni, svona:

   if (1 == a) ...
Ef r verur messunni og setur = sta == kvartar andinn yfir v srt a reyna a setja breytu inn fasta.

Hr eftir fer tafla sem skrir merkingu virkjanna:

   +	skilar summu gildanna sitthvorumegin vi virkjann.
   -	skilar gildinu vinstra megin virkjans a frdregnu gildinu hgra megin.
   *	skilar margfeldi gildanna sitthvorumegin  vi virkjann.
   /	skilar gildinu vinstra megin virkjans deildu me gildinu hgra megin.
   %	skilar afganginum egar gildinu vinstra megin virkjans er deilt me gildinu hgra megin.
   ==	skilar 1 ef gildin sitthvorumegin virkjans eru jfn en 0 annars.
   !=	skilar 0 ef gildin sitthvorumegin virkjans eru jfn en 1 annars.
   > 	skilar 1 ef gildi vinstra megin virkjans er strra en gildi hgra megin en 0 annars.
   >=	skilar 1 ef gildi vinstra megin er strra en ea jafnt gildinu hgra megin en 0 annars.
   < 	skilar 1 ef gildi vinstra megin virkjans er minna en gildi hgra megin en 0 annars.
   <=	skilar 1 ef gildi vinstra megin er minna en ea jafnt gildinu hgra megin en 0 annars.
   !	skilar 1 ef gildi fyrir aftan virkjann er 0 en 0 annars.
   ||	skilar 0 ef bi gildin sitthvorumegin vi virkjann eru 0 en 1 annars.
   && 	skilar 1 ef bi gildin sitthvorumegin vi virkjann eru ekki 0 en 0 annars.
   =	setur gildi breytunnar hgra megin inn  breytuna vinstra megin og skilar v gildi.
Taktu eftir v a allstaar er tala um gildi, ekki tlur ea breytur, v gildin geta veri fastar, breytur, gildi r falli ea heilu segirnar me fstum, fllum og breytum. Eins og sst tflunni er = virkinn einskonar reikniager lka sem skilar gildinu hgra megin vi virkjann. a a breytan vinstra megin fi gildi breytunnar hgra megin leiinni er bara eins og hver nnur hliarverkun! Hva gerist t.d. hr:

   int a, b, c;
   a = (b = (c = 123));
J, fyrst er c gefi gildi 123. = agerin skilar lka gildinu 123, annig a b fr gildi 123. A lokum fr a gildi 123 lka. tilviki = virkjans er hgt a sleppa svigunum og skrifa einfaldlega:

   a = b = c = 123;
= virkinn er einn af fum virkjum sem er metinn fr hgri til vinstri. essi mguleiki getur veri hentugur til a spara plss frumforritum, eins og sst hr a framan.

Verkefni 17: Hr eru nokkur laufltt dmi fyrir ig a spreyta ig , til a fullvissa ig um a hafir skili virkjana rtt. tt a segja hvaa gildi kemur t r segunum.

   1) 2 + 2
   2) (26 <  13) + 5
   3) (1 || 2 || 3)
   4) !(!(54))
   5) ((5 &&  7) || !13) - (16 >= 5)
   6) (!(10 % 3) * 5) || 0
Vi ljkum essari mikilvgu umfjllun um kvaranatku og rksegir me v a lra nokkra reiknivirkja sem koma rksegum ekki beinlnis vi en spara plss og ltta lund. a er mjg algengt forritum a einhverju gildi s btt vi breytu, t.d.:

   a = a + 1;
   b = b * 3;
Skum ess hve essar agerir eru algengar eru srstakir virkjar sem reikna t og gefa gildi um lei. Virkjarnir eru einskonar blanda af = virkjanum og reiknivirkjunum eins og sst tliti eirra. Virkjarnir eru:

   +=	leggur gildi hgra megin vi breytuna vinstra megin.
   -=	dregur gildi hgra megin fr breytunni vinstra megin
   *=	margfaldar breytuna vinstra megin me gildinu hgra megin.
   /=	deilir breytunni vinstra megin me breytunni hgra megin.
   %=	setur afganginn sem myndast egar vinstri er deilt me hgri  breytuna vinstra megin.
Allir virkjarnir skila tkomunni r treikningnum, nema hva. Forriti hr eftir er nkvmlega jafngilt forritinu hr rtt undan.

   a += 1;
   b *= 3;
Agerirnar a leggja einn vi breytu ea draga einn fr breytu eru svo algengar a r hafa srstaka virkja:

   ++	leggur einn vi breytuna (og skilar gildinu).
   --	dregur einn fr breytunni (og skilar gildinu).
Enn ein tgfan af forritinu vri v svona:

   a++;
   b *= 3;
loksins skiluru brandarann me nafngiftinni C++. C++ er eiginlega "C pls einn" ea "C einu skrefi lengra runarbrautinni". Nafni er lka rkrtt framhald nafninu C, v forveri C ku hafa heita B. Sagan segir a a hafi veri einkunnin sem nemandinn sem bj a til hafi fengi fyrir verkefni!

Vi kvenar astur arftu samt a gta n ++ og --. Hva gerist t.d. hr:

   a = 10;
   b = a++;
Hvort fr b gildi 10 ea 11? Fr b gildi a og san er a hkka ea er a hkka fyrst og san fr b nja gildi a? sumum tilfellum gti forritarinn vilja fyrri kostinn en rum tilfellum gti hann vilja ann seinni. Hann stjrnar v me v hvoru megin vi breytuna virkinn birtist. Ef hann birtist fyrir framan breytuna er breytan hkku/lkku ur en gildinu er skila. Ef hann birtist fyrir aftan er breytan hkku/lkku eftir a gildinu er skila. dminu hr a framan fr breytan a v gildi 10. Sem nnari skringu essu:

   a = 10;
   b = a++;      /* b fr gildi 10 */
   a = 10;
   c = ++a;      /* b fr gildi 11 */
Eins og sj m af umfjlluninni hr undan er hgt a nota margar brellur og skammstafanir C. a er hgt a misnota ennan sveigjanleika til a skrifa mjg lsileg forrit. Sumum finnst a meira a segja svaka tff (hfundur heftisins er v miur hallur undir slkan vafasaman tffaraskap). essi sveigjanleiki er meal annars a sem forriturum lka vel vi C og flinkir forritarar geta ntt sr hann en um lei skrifa snyrtileg og skr forrit.

Verkefni 18: Bu til forrit fyrir pstjnustuna sem reiknar t hve miki a rukka fyrir a senda bggul psti innanbjar. Gjaldskrin fer eftir rmmli bggulsins og yngd hans. Hn er mjg einfld og hefur aeins rj flokka.

Rmml (cm3)   <= 500    <= 2000   > 2000
ynd (grmm)   <= 50     <= 500    > 500
Ver (kr)      200       450       800
Rukka er eftir drari flokknum sem bggullinn lendir . a kostar t.d. 450 krnur a senda 40 gramma bggul sem er 600 cm3 a rmmli.

Verkefni 19: Endurbttu forriti annig a a geti teki me reikninginn hvert a senda bggulinn. a eru rr gjaldflokkar, fyrir sendingar innanbjar, t land ea til tlanda. A senda t land margfaldar veri um 1,7. A senda til tlanda margfaldar veri um 2,5 ( verur a nota fleytitlur fyrir lokaveri essu verkefni).

Verkefni 20: Bu til forrit sem jlfar notandann hugarreikningi. Til einfldunar notar forriti eingngu heiltlur. Fyrst forriti a spyrja hvort notandinn vilji leggja saman, draga fr ea margfalda. Svo br forriti til dmi og birtir skjnum. Ef notandinn slr inn rtt svar fr hann klapp baki en annars gltlega tilkynningu um villu sns vegar.

Til a lta tlvuna ba til slembitlu, .e. tilviljunarkennda tlu, notar keyrslusafnsfalli rand. Vi notum % virkjann til a f tlu bilinu 1-100. Til a f ekki alltaf smu tlurnar r rand byrjum vi a kalla falli srand fremst forritinu. Vi ltum srand hafa klukkuna tlvunni (sem vi fum r fallinu time) sem upphafspunkt fyrir slembitlurununa. Til a geta nota essi fll verur a hafa #include <stdlib.h> og #include <time.h> fremst frumforritinu. Hr er dmi um notkun fallana:

   #include <stdlib.h>
   #include <time.h>
   #include <stdio.h>
   int main () {
      int a;
      srand ((unsigned)time(0));
      a = (rand() % 100) + 1;
      printf ("Hr er tala  bilinu 1 til 100: %i", a);
      return 0;
   }
Auvita koma ekki alvru slembitlur t r fallinu. a kemur runa af tlum sem lta t fyrir a vera handahfskenndar. Ef kallar ngu oft slembifalli fru smu rununa aftur.


Efnisyfirlit, Nsti kafli