![]() ![]() ![]() | Datatyper |
Der er undertiden behov for at konvertere en værdi i én type til en værdi i en anden type. I nogle situationer er det programmøren, som ønsker dette. I så fald taler vi om en eksplicit typekonvertering, eller i teknisk jargon en cast. I andre tilfælde er det C compileren der føler trang til at foretage en typekonvertering. Disse omtales som implicitte typekonverteringer. I afsnit 19.1 ser vi først på de implicitte typerkonverteringer.
Som et andet emne i dette kapitel ser vi på brug af typedef til omnavngivning af eksisterende typer.
|
19.1. Implicit typekonvertering
Indhold Op Forrige Næste Slide Aggregerede slides Stikord Programindeks Opgaveindeks
Vi giver en ganske kortfattet oversigt over tre former for implicit typekonvertering herunder.
C foretager en række typekonverteringer 'bag ryggen på programmøren' |
|
Integral promotion benyttes bl.a. til at få beregninger på shorts og chars til at forgå inden for værdier i typen int.
Brug af widening er bekvem, når vi skriver udtryk der involverer værdier i to forskellige typer. Eksempelvis d + i, hvor d er en double og i er en int. Maskinen understøtter sandsynligvis ikke en addition af netop disse to typer, så derfor konverteres den mest snævre operand, her i, til typen af den mest brede operand. Altså konverteres værdien af i til en double, hvorefter der kan udføres en addition af to double værdier.
Narrowing udføres f.eks. når en double værdi assignes til en integer variable.
De tre forskellige former for typekonverteringer er illustreret i program 19.1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> int main(void) { short s = 12; char c = 'a'; double d = 123456.7; float f = 4322.1; int i; printf("c - s = %i is converted to int\n", c - s); /* The type of c - s is promoted to int */ printf("d + f = %f is converted to a double\n", d + f); /* f is converted to double before adding the numbers */ i = d; printf("In assigning d to i %f is demoted to the int %i\n", d, i); /* d is converted to an int - information is lost */ return 0; } | |||
|
19.2. Eksplicit typekonvertering
Indhold Op Forrige Næste Slide Aggregerede slides Stikord Programindeks Opgaveindeks
Som programmører har vi en gang imellem brug for at gennemtvinge en konvertering af en værdi fra en type til en anden. Ofte er konverteringen dog "spil for galleriet", i den forstand at vi blot garanterer over for kompileren at værdien kan opfattes som værende af en bestemt type. I disse situationer finder der ingen reel forandring sted som følge af en typekonvertering.
I C er det muligt for programmøren at konvertere værdien af et udtryk til en anden type ved brug af en såkaldt cast operator |
En typecast noteres ved at foranstille det udtryk, hvis værdi ønskes konverteret, i en typecase operator. En typecast operator er et typenavn i parentes.
At en typecast faktisk er en operator kan man overbevise sig om ved at studere niveau 14 i tabel 2.3.
| |||
|
I program 19.2 viser vi hvordan værdien af 'A'+10 kan konverteres til en long. Vi ser også hvordan værdien af long variablen y kan konverteres til en int. Bemærk at y konverteres før additionen, på grund af den indbyrdes placering af typecast og addition i tabel 2.3. Endelig ser vi hvordan værdien af udtrykket x=77, altså heltallet 77, kan konverteres til en double før assignmentet til z.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int main(void) { long y; float x; double z; y = (long) ('A' + 10); x = (float) ((int) y + 1); z = (double) (x = 77); printf("y: %li, x: %f, z: %f", y, x, z); return 0; } | |||
|
I det næste eksempel, program 19.3, ser vi hvordan funktionen next_day_of, som oprindelig blev vist i program 18.6, kan omskrives. I den omskrevne, og meget kortere udgave af next_day_of, benytter vi to casts. Den blå konvertering transformerer en enum days værdi til en int. Til dette heltal adderer vi 1 og vi uddrager resten ved division med 7. Tænk lige over hvorfor... Den røde konvertering bringer det resulterende heltal tilbage som en enum days værdi.
1 2 3 | enum days next_day_of(enum days d){ return (enum days) (((int) d + 1) % 7); } | |||
|
19.3. Navngivne typer med typedef
Indhold Op Forrige Næste Slide Aggregerede slides Stikord Programindeks Opgaveindeks
I nogle situationer kan vi have lyst til at give en eksisterende type et nyt navn. Dette gør sig specielt gældende for typer med ubekvemme betegnelser, så som enum days, enum grade_13, og enum simple_grade.
I C er det muligt at tildele en type et bestemt navn I tilfælde af komplicerede typer kan dette øge læsbarheden af et program |
Syntaksen for typedef er enkel. Blot skal man lige bemærke, at det nye typenavn angives til sidst.
| |||
|
Vi viser herunder hvordan program 18.6 og program 18.7 kan omskrives til program 19.4. Ændringerne er ikke revolutionerende, men læg alligevel mærke til de blå og røde steder i forhold til program 19.4.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <stdio.h> enum days {sunday, monday, tuesday, wednesday, thursday, friday, saturday}; typedef enum days days; days next_day_of(days d){ return ( days ) (((int) d + 1) % 7); } void prnt_day(days d){ switch (d) { case sunday: printf("Sunday"); break; case monday: printf("Monday"); break; case tuesday: printf("Tuesday"); break; case wednesday: printf("Wednesday"); break; case thursday: printf("Thursday"); break; case friday: printf("Friday"); break; case saturday: printf("Saturday"); break; } } int main(void){ days day1 = saturday, another_day; int i; printf("Day1 is %d\n", day1); printf("Day1 is also "); prnt_day(day1); printf("\n"); another_day = day1; for(i = 1; i <= 3; i++) another_day = next_day_of(another_day); printf("Three days after day1: "); prnt_day(another_day); printf("\n"); return 0; } | |||
|
Det kan måske forvirre lidt, at vi bruger days både som navnet på den nye type og som en del af navnet på den eksisterende type. Teknisk set er tag navnet days i enum days og det nye typenavn days i to forskellige navnerum. Derfor generer de ikke hinanden.