2015-05-16 29 views
5

Campione intestazione C.sintassi struttura C

typedef LPVOID UKWD_USB_DEVICE; 

typedef struct _UKWD_USB_DEVICE_INFO { 
    DWORD dwCount; 
    unsigned char Bus; 
    unsigned char Address; 
    unsigned long SessionId; 
    USB_DEVICE_DESCRIPTOR Descriptor; 
} UKWD_USB_DEVICE_INFO, *PUKWD_USB_DEVICE_INFO, * LPUKWD_USB_DEVICE_INFO; 

mia comprensione

struct definisce una struttura (la parte compresa tra {}). Il tipo di struttura è _UKWD_USB_DEVICE_INFO. Dopo la chiusura }UKWD_USB_DEVICE_INFO è an alias to this structure.

Domanda

Qual è lo scopo delle dichiarazioni dopo. * PUKD_USB_DEVICE_INFO e *LPUKWD_USB_DEVICE_INFO. Do these pointer aliases significa qualcosa di diverso se si sta toccando la variabile e l'altro ha uno spazio tra * e caratteri?

+0

non è possibile "dichiarare una definizione" =) – Mints97

+0

Grazie a tutti per il vostro aiuto. La tua direzione è stata molto istruttiva. – Ccorock

risposta

5

C typedef dichiarazioni intese per analogia con dichiarazioni variabili.

int a, *b; 

dichiara i valori a di tipo int e b di tipo int*.

typedef int A, *B; 

dichiara il tipo A equivalente int e il tipo B equivalente a int*. Quindi, pensa a cosa sarebbe il tipo di variabile se questa fosse una dichiarazione di variabile.

Quindi sì, PUKWD_USB_DEVICE_INFO diventa equivalente a struct _UKWD_USB_DEVICE_INFO*.

EDIT

Inoltre, lo spazio non ha importanza. C è un linguaggio di spazi vuoti. Gli alias aggiuntivi non sono necessari, sono solo lì per adattarsi alle convenzioni di vari progetti e API che amano chiamare i tipi di puntatore con nomi che includono P o altre sottostringhe. A volte questi progetti finiscono con più convenzioni nel tempo, quindi ci sono più alias. Possono anche essere necessari per ragioni di compatibilità quando le API vengono aggiornate o tra piattaforme diverse.

+0

"C è un linguaggio di spazi vuoti"? C'è una parola mancante? – Leushenko

+0

No, è intenzionale. Almeno negli anni '90, era comune (per me) vedere affermazioni come "C è un linguaggio di spazi bianchi" o "C++ è un linguaggio di spazi vuoti", seguito da una spiegazione che lo spazio bianco nel codice sorgente non è significativo. Emory è sbagliato o questo non è un uso moderno. – antron

1

Sì, è un alias puntatore, è quindi possibile utilizzare PUKWD_USB_DEVICE_INFO come UKWD_USB_DEVICE_INFO *. La maggior parte le strutture di Windows fanno questo:

enter image description here

che L nel terzo alias sta per lungo (puntatore), e se non mi sbaglio, non ha alcun significato in 32/64 bit di codice - è probabile un rimanenze da materiale a 16 bit, come nel caso della definizione .

+0

Perché dovresti usare più di un alias? È questo per consentire dimensioni variabili della struttura? – Ccorock

+0

@Ccorock Vedere la risposta aggiornata. – szczurcio

+1

typedef'ing a struct è una pratica di programmazione molto scarsa. Ingombra il codice, porta a equivoci, rende il codice più difficile da comprendere per gli umani e ingombra lo spazio dei nomi del compilatore. Purtroppo, Microsoft non ha ancora deciso che vogliono che il loro codice sia semplice e diretto. Il risultato è la confusione vista oggi in cose come le loro librerie e convenzioni di denominazione. – user3629249

1

Sono questi alias puntatori?

Sì.

Significa qualcosa se si sta toccando la variabile e l'altro ha uno spazio tra * e caratteri?

No. In C, gli spazi tra token non hanno significato per il compilatore. Semplicemente cambiano la leggibilità per le persone che guardano il codice.

Ho visto pochissimi esempi di codice in linea utilizzare più di un nome dopo la chiusura delle parentesi graffe. Qualche idea su questo?

genere, e in questo caso in particolare, è fatto per consentire i nomi dei simboli che possono rappresentano tipi diversi, ma anche non può.

Si vede che sulla propria architettura, un "puntatore" P e un "puntatore lungo" LP "capita di essere dello stesso tipo.

Su un'architettura a 16 bit, si guarderebbe un'intestazione diversa e quei tipi sarebbero diversi.

1

Questo stile di definizione è comune sulla piattaforma Windows. Nei giorni del 16 bit architetture segmentate, ciascuna definizione typedef struttura aveva anche 2 typedefs puntatore per near e far (alias lunghi puntatori):

typedef LPVOID UKWD_USB_DEVICE; 

typedef struct _UKWD_USB_DEVICE_INFO { 
    DWORD dwCount; 
    unsigned char Bus; 
    unsigned char Address; 
    unsigned long SessionId; 
    USB_DEVICE_DESCRIPTOR Descriptor; 
} UKWD_USB_DEVICE_INFO, NEAR * PUKWD_USB_DEVICE_INFO, FAR * LPUKWD_USB_DEVICE_INFO; 

NEAR puntatori erano 16 bit di larghezza e FAR puntatori erano 32 bit di larghezza. La maggior parte delle API di Windows utilizzava i puntatori FAR e i loro prototipi utilizzavano il typedef del puntatore. Per inciso, LPVOID è stata definita in questo modo:

typedef void FAR *LPVOID; 

32 bit di Windows è uscito nel 1995 e ha reso questo obsoleta. NEAR e FAR le parole chiave sono state mantenute per un po ', definite come vuote, per ragioni di compatibilità.

La compatibilità con Windows a 16 bit è diventata a lungo inutile, ma l'utilizzo permane anche quando i typedef sono ancora in uso, ma le parole chiave FAR esono state rimosse.

Lo spazio tra * e PUKWD_USB_DEVICE_INFO viene ignorato, ma sono d'accordo con te è piuttosto confuso metterne uno lì.