Typedef

De la Viquipèdia, l'enciclopèdia lliure.
Saltar a la navegació Saltar a la cerca

typedef és una paraula claudels llenguatges deprogramació C i C ++ . L’objectiu del typedef és assignar noms alternatius als tipus de dades existents, generalment aquells la declaració estàndard dels quals és massa feixuga, potser confusa, o fer que el codi sigui més fàcilment reutilitzable entre una implementació i una altra.

Segons les convencions C (biblioteca estàndard), els tipus declarats amb typedef acaben amb la cadena "_t" (per exemple, size_t , time_t ).

Exemples d'ús

Per indicar què representa una variable

Es pot utilitzar un typedef per indicar com una variable representa alguna cosa, com ara una unitat de mesura:

 int velocitat_actual ;
int high_score ;
...

void congratulate ( int your_score ) {
    if (el vostre_punt > puntuació_alt )
...

Ara tingueu en compte:

 typedef int km_per_hour ;
punts int typedef ;

km_per_hour current_speed;
punts high_score ;
...

void felicita ( apunta la vostra puntuació ) {
    if (el vostre_punt > puntuació_alt )
...

Les dues seccions de codi implementen la mateixa operació. No obstant això, l'ús del typedef en el segon exemple deixa més clar que, tot i que les dues variables estan representades pel mateix tipus de dades ( int ), la informació que contenen és lògicament incompatible. La declaració a congratulate() de your_score indica al programador que current_speed (o qualsevol altra variable no declarada com a points ) no s’ha de passar com a argument. Això no hauria estat tan visible si tots dos es declaressin com a enters. Tingueu en compte que la indicació només és útil per als programadors; El compilador C / C ++ tracta ambdues variables en el seu conjunt i no informarà de cap inconsistència si passa current_speed com a argument a la funció congratulate() .

Simplifiqueu una afirmació

Es pot utilitzar un typedef per simplificar la declaració d'un tipus de dades compost ( struct , union ) o d'un punter .

 struct var {
    int data1 ;
    int data2 ;
    char data3 ;
};

A sobre es va definir el tipus de dades struct var . Per declarar una variable d'aquest tipus, en C, cal l'ús de la paraula clau struct (això no s'aplica a C ++):

 struct var a ;

Es pot utilitzar un typedef per eliminar la necessitat de repetir la paraula struct . Per exemple amb:

 typedef struct newtype var;

ara podem crear una variable d'aquest tipus amb:

 nou tipus a ;

Tingueu en compte que la definició de l'estructura i typedef es poden combinar en una sola sentència:

 typedef struct var {
    int data1 ;
    int data2 ;
    char data3 ;
} newtype ;

A C ++ , a diferència de C, les paraules clau struct , class i enum són opcionals en declaracions de variables separades de les definicions.

 struct var x ; // Això està permès
var y ; // Això també està permès

Per tant, var pot utilitzar-se sempre que newtype es pot utilitzar. Tanmateix, el contrari no és cert. Per exemple, el mètode constructor de var no es pot anomenar newtype .

Utilitzeu typedef amb punteres

Els Typedefs també poden simplificar les declaracions per als tipus de punter. Penseu en això:

 struct Node {
    dades int ;
    struct Node * nextptr ;
};

A C, és possible declarar diverses variables del mateix tipus en una sola sentència, fins i tot barrejant punteres i no punteres. Sigui com sigui, haureu de posar un asterisc davant de cada variable per convertir-lo en un punter.

 struct Node * startptr , * endptr , * curptr , * prevptr , errptr , * refptr ;

Un programador probablement assumiria que errptr era realment de tipus Node * , però per a un error errptr és de tipus Node . Això provocarà un error de sintaxi.

En definir un typedef per a Node * , esteu segur que totes les variables seran de tipus punter.

 typedef struct Node * NodePtr ;
...
NodePtr startptr , endptr , curptr , prevptr , errptr , refptr ;

Utilitzeu el typeped cast typedef

Es crea un typedef mitjançant la sintaxi de declaració de tipus, però es pot utilitzar com si es creés mitjançant la sintaxi de tipus cast . Per exemple, a cada línia de codi després de la primera línia de:

 typedef int ( * funcptr ) ( doble ); // punter per funcionar amb doble argument i retornar tipus int
funcptr x = ( funcptr ) NULL ; // C o C ++
funcptr y = funcptr ( NULL ); // C o C ++
funcptr z = static_cast < funcptr > ( NULL ); // només C ++

funcptr s'utilitza al costat esquerre per declarar una variable i al costat dret de l'assignació per convertir un valor. Per tant, els programadors que poden utilitzar typedefs no volen entendre com convertir la sintaxi declarativa en sintaxi de transmissió.

Tingueu en compte que sense typedefs, generalment no és possible utilitzar sintaxi declarativa i de repartiment indistintament. Per exemple:

 int ( * x ) ( doble ) = ( int ( * ) ( doble )) NUL ; // Això és permès
int ( * ) ( doble ) y = ( int ( * ) ( doble )) NUL ; // El costat esquerre de la tasca no és apte
int ( * z ) ( doble ) = ( int ( * NULL ) ( doble )); // La part dreta de la tasca no és apta

Preocupacions sobre l’ús

Alguns s’oposen a l’ús intensiu de typedefs. El motiu principal és el fet que els typedefs amaguen el tipus de dades real de la variable. Per exemple, Greg Kroah-Hartman , un experimentat hacker i desenvolupador del nucli Linux , desaconsella el seu ús per a qualsevol cosa menys una declaració de prototip de funció. Argumenta que aquesta pràctica no només oculta el codi innecessàriament, sinó que també pot causar confusió al programador que accidentalment fa un mal ús de grans estructures de dades pensant que són elementals. [1]

Altres argumenten que l'ús de typedefs facilita la revisió del codi. El K&R afirma que hi ha dues raons per utilitzar typedefs. En primer lloc, fan que el codi sigui més portàtil. En lloc d’haver de canviar un tipus de dades cada vegada que apareix a tota la font, només es canvia un typedef. En segon lloc, els typedefs poden fer més fàcil d’entendre una declaració complexa.

Ús en C ++

A C ++, els noms de tipus poden ser molt complicats i typedef proporciona un mecanisme per assignar un nom simple al tipus.

 valors std :: vector <std :: pair <std :: string, int >> ;
for ( std :: vector < std :: pair < std :: string , int >> :: const_iterator i = valors . begin (); i ! = valors . end (); ++ i )
{
   std :: pair < std :: string , int > const & t = * i ;
   // fer quelcom
}

I

 typedef std :: pair < std :: string , int > value_t ;
typedef std :: vector < value_t > values_t ;

valors_t valors ;
for ( values_t :: const_iterator i = values . begin (); i ! = values . end (); ++ i )
{
   valor_t const & t = * i ;
   // fer quelcom
}

Utilitzeu-lo amb plantilles en C ++

No hi ha cap manera directa de tenir un typedef en una plantilla C ++. Per exemple, per fer value_t<T> representar std::pair<std::string, T> per a qualsevol class T no es pot utilitzar:

 plantilla < classe T >
typedef std :: pair < std :: string , T > valor_t < T > ; // No funciona

Tanmateix, si voleu acceptar value_t<T>::foo , o alguna cosa similar, en lloc de value_t<T> , podeu obtenir el resultat desitjat amb un typedef dins d’una classe o estructura continguda en una plantilla:

 plantilla < classe T >
valor struct_t
{
    typedef std :: pair < std :: string , T > foo ; // Fa que value_t <T> :: foo representi std :: pair <std :: string, T>
};

Des de C ++ 11 és possible utilitzar una declaració d’àlies mitjançant la paraula clau using per obtenir el resultat desitjat:

 plantilla < typename T >
utilitzant TaggedValue = std :: pair < std :: string , T > ; // legal des de C ++ 11

void foo (TaggedValue <int> foo);

Altres llengües

En una varietat de llenguatges de programació funcional , com ara ' Haskell , Miranda , OCaml , etc., és possible definir els anomenats sinònims tipus, sinònims tipus, que corresponen al typedef a C. Un exemple escrit a Haskell:

 escriviu PairOfInts = (Int, Int)

Aquest exemple defineix un sinònim de tipus anomenat "PairOfInts" que té el mateix significat que un parell d'enters.

C # inclou una característica similar a C typedef, però l’inconvenient és que s’ha de declarar per a cada fitxer per separat. [2]

 utilitzant newType = global :: System.Runtime.Interop.Marshal;
utilitzant otherType = Enums.MyEnumType;

Nota

  1. Kroah-Hartman, Greg, Proper Linux Kernel Coding Style , a linuxjournal.com , 01/01/2002 . Recuperat el 23-09-2007 .
  2. ^ [1] Article de MSDN sobre typedef a C #

Articles relacionats