3. Lektion
Denne lektion handler grundlæggende om Forgreninger
Emnerne behandles i lærebogen på siderne 100 til 133
Jeg starter med et program, vi har set på tidligere, det var det program, der talte op hvor mange tegn og bogstaver, der var i en sætning. Nu indføjer jeg en funktion, der også kan optælle, hvor mange ord der er i sætningen.
For at optælle antallet af ord, skal vi finde ud af hvor mange mellemrum, der er i teksten. Hver gang der optræder et mellemrum, skal der laves en forgrening, hvor der tilføjes en optælling af mellemrummene (= et afsluttet ord). Ved det direkte gennemløb optælles kun tegn incl. mellemrummene.
Vis et eksempel på en overskrift til et program.
Eksempel 1
#include <stdio.h> // Til printf()
#include <conio.h> // Til getche()
void main(void)
{
int bogstavtal = 0;
int ordtal = 1;
char ch;
printf("\nIndtast en sætning:\n"); // Indtast en tekst
while ( (ch=getche()) != '\r' ) // Snup et tegn af gangen indtil RETURN
{
bogstavtal++; // Tæl op antal gange løkken gennemløbes
if ( ch == ' ' )
ordtal++;
}
printf
("\nTeksten indholdt %d tegn og bogstaver", bogstavtal);
printf("\nTeksten indeholdt %d ord", ordtal);
} // Slut på programmet
Ovenstående er et program med en enkelt forgrening. I næste eksempel får forgreningen tilføjet et alternativ, idet der anvendes else i konstruktionen.
Koderne i nedenstående eksempel virker kun i compilere, som arbejder i et DOS-vindue. Brug f.eks. programmet fra øvelse 2 fra 2. lektion til at finde en passende værdi til at erstatte med i den C-compiler du anvender. Værdien skal være en, som sætter en fuldt udfyldt firkant som et tegn.
Følgende program tegner et skakbræt på skærmen. Koden kan tolkes således: (x + y) % 2 giver restværdien efter heltalsdivision med 2. Dvs. at (x + y) %2 hver anden gang i en bestemt linie giver værdien 1, altså != 0. I den næste linie vil (x + y) % 2 give 1 forskudt 1 felt i forhold til felterne i den foregående linie osv.
Eksempel 2
void main(void)
{
int x, y;
char a;
printf("\n");
for ( y = 1; y < 24; y++)
{
for ( x = 1; x < 24; x++)
if ( (x+y)%2 == 0 )
printf("\xdb\xdb");
// Bemærk disse koder virker kun med Cpp 5.02
else
printf(" ");
printf("\n");
} // Slut på ydre tælleløkke
a = getch();
}
Det er også muligt at indlejre forgreninger i forgreninger. I eksempel 3 indlejres en if - sætning i en if - sætning. Denne gang går opgaven ud på at sætter felter af som to diagonaler, der skal krydse hinanden ned over skærmen. Da der kun skal sættes 2 tegn af i hver linie, skal vi bruge en if - sætning til hvert af tegnene. Det ene tegn skal sættes hver gang x == y, det andet skal sættes når x == (24 - y), idet jeg har sat en tælle-løkke til at gentage 23 gange, og y til at starte med værdien 1.
Eksempel 3
void main(void)
{
int x, y;
char a;
printf("\n");
for ( y = 1; y < 24; y++)
{
for ( x = 1; x < 24; x++)
if (x == y)
printf("\xdb");
else
if ( x == (24 - y))
printf("\xdb");
else
printf("\xb0");
printf("\n");
}
a = getch();
}
Lads os prøve at se på Kryds-programmet en gang til, der må kunne spares noget kode.
Der findes en række logiske operatorer, vi kan tage fat i. Det er:
|| = or (eller)
&& = and (og)
! = = not ( ikke eller forskellig fra)
Der begyndes med kommandoen til en ny linie fra eksempel 3
printf("\n");
for ( y = 1; y < 24; y++)
{
for ( x = 1; x < 24; x++)// Ændringen ligger i næste linie
if (x == y || x == 24-y )
printf("\xdb");
else
printf("\xb0");
printf("\n");
}
a = getch();
Det gjorde koden lidt fiksere og en compilering vil vise at programmet er blevet lidt mindre.
Næste udfordring går på at bruge multiple choice
Hvordan det virker kan vises ved at lave en lille regnemaskine. Vi skal her have et valg for hver regneart, som maskinen skal kunne behandle.
Eksempel 4
void main(void)
{
float num1 = 1.0, num2 = 1.0;
char op;
while ( !(num1 == 0.0 && num2 == 0.0) )
{
printf("\n\nIndtast et tal, et regnetegn og et tal \n");
scanf("%f %c %f", &num1, &op, &num2);
if (op == '+') //
Her lægges tal sammen
printf(" = %f", num1 + num2);
else if (op == '-') //
Her trækkes tal fra hinanden
printf(" = %f", num1 - num2);
else if (op == '*')
// Her ganges
printf(" = %f", num1 * num2);
else if (op == '/') // Her
divideres
printf(" = %f", num1 / num2);
else
printf("Du har indtastet en ulovlig operator");
// Tal pænt til brugeren, hvis der laves fejl!
} // Slut på "Så længe som"
} // Slut på programmet
Konstruktionen af regnemaskinen kan ændres, idet der findes en kommando, som er kortere at anvende end alle if - konstruktionerne indlejret i hinanden. Kommandoen svarer til CASE . . OF i Pascal. I C hedder den switch. Hvert valg i switch skal derpå markeres med det reserverede ord case.
Eksempel 5
void main(void)
{
float num1 = 1.0, num2 = 1.0;
char op;
while ( !(num1 == 0.0 && num2 == 0.0) )
{
printf("\n\nIndtast et tal, et regnetegn og et tal \n");
scanf("%f %c %f", &num1, &op, &num2);
switch (op)
{
case '+' : printf(" = %f", num1 + num2);
break;
case '-' : printf(" = %f", num1 + num2);
break;
case '*' : // Tilføj f.eks. case 'x' :
printf(" = %f", num1 * num2);
break;
case '/' : // Tilføj f.eks. case '\' :
printf(" = %f", num1 / num2);
break;
default :
printf("Du har indtastet en ulovlig operator");
} // Slut på switch
} // Slut på while
} // Slut på programmet
Bemærk, at efter CASE kommer der et : (kolon) og der er ingen { (Tuborg-klamme) om de sætninger, der følger efter CASE. Til gengæld er der en BREAK-kommando for at få programmet til at forlade SWITCH efter at et alternativ er udført.
Ud over de ovenfor nævnte operatorer findes der i C også en såkaldt Conditional operator.
I modsætning til de fleste andre operatorer tager denne operator tre argumenter:
Condition ? udtryk1 : udtryk2;
f.eks. max = ( num1 > num2 ) ? num1 : num2;
resultatet af denne operation er det samme som traditionelt at skrive:
if (num1 > num2)
max = num1;
else
max = num2;
Vi kan med denne kommando elegant lave en funktion, der altid giver den numeriske værdi af et tal:
Abs = (num < 0) ? -num : num;
Når I nu har lært at lave forgreninger skal I til at tænke lidt mere over konstruktion af et program. Udviklingen at et program består af 3 trin. Vi kan kalde det mini-SPU.
Øvelse 1
Prøv at ændre programmet fra eksempel 2, således at der
tilføjes bogstaverne A, B, C . . . . osv. vandret over skatbrættet og vandret under
dette. Desuden tilføjes tal lodret på begge sider af brættet.
Eksempler og løsningerne kan hentes her.
Eksempel 1
Eksempel 2
Eksempel 3
Eksempel 4
Eksempel 5
Øvelse 1
Øvelse 2a
Øvelse 2b