Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'Datatyper
19.  Typekonvertering og typedef

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 typekonvertering19.3 Navngivne typer med typedef
19.2 Eksplicit typekonvertering
 

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"

    • Udtryk af heltalstype hvori der indgår short eller char værdier konverteres til en værdi i typen int.

    • Eksempel: Hvis x og y er af typen short er værdien af x + y int.

  • "Usual arithmetic conversions" - widening

    • Konvertering af en mindre præcis værdi til en tilsvarende mere præcis værdi således at begge operander får samme type

    • Der mistes ikke information og præcision

  • Narrowing - demotion

    • Konvertering af mere præcis værdi til en mindre præcis værdi

    • Der mistes information

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;
}
Program 19.1    Eksempler på implicitte typekonverteringer.

 

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.


(typeName) expression
Syntaks 19.1    Syntaktisk definition af casting - eksplicit typekonvertering i C

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;
}
Program 19.2    Et program med eksempler på casts.

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);
}
Program 19.3    Funktionen next_day_of omskrevet med brug af casts.

 

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.


typedef oldType newType
Syntaks 19.2    Syntaktisk definition af casting - eksplicit typekonvertering i C

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;
}
Program 19.4    En omskrivning af ugedags programmet som benytter typedef.

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.

Genereret: Onsdag 7. Juli 2010, 15:11:30
Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'