Qual è il riferimento futuro in C?
-
11-07-2019 - |
Domanda
Qual è il riferimento diretto in C rispetto ai puntatori?
Posso avere un esempio?
Soluzione
Vedi questa pagina su riferimenti in avanti . Non vedo come il riferimento futuro sarebbe diverso con i puntatori e con altri tipi di PoD.
Nota che puoi inoltrare i tipi di dichiarazione e dichiarare le variabili che sono puntatori a quel tipo:
struct MyStruct;
struct MyStruct *ptr;
struct MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
// Or:
typedef struct MyStruct MyStruct;
MyStruct *ptr;
MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
Penso che questo sia ciò che stai chiedendo quando hai a che fare con puntatori e dichiarazione in avanti.
Altri suggerimenti
Penso che "riferimento in avanti" rispetto ai puntatori significa qualcosa del genere:
struct MyStruct *ptr; // this is a forward reference.
struct MyStruct
{
struct MyStruct *next; // another forward reference - this is much more useful
// some data members
};
Il puntatore viene dichiarato prima che venga definita la struttura a cui punta.
Il compilatore può cavarsela perché il puntatore memorizza un indirizzo e non è necessario sapere cosa c'è a quell'indirizzo per riservare la memoria per il puntatore.
Il riferimento diretto è quando si dichiara un tipo ma non lo si definisce.
Ti permette di usare il tipo tramite puntatore (o riferimento per C ++) ma non puoi dichiarare una variabile.
Questo è un modo per dire al compilatore che esiste qualcosa
Supponi di avere una struttura Plop definita in Plop.h :
struct Plop
{
int n;
float f;
};
Ora vuoi aggiungere alcune funzioni di utilità che funzionano con quella struttura. Crei un altro file PlopUtils.h (diciamo che non puoi cambiare Plop.h):
struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time
void doSomething(Plop* plop);
void doNothing(Plop* plop);
Ora quando si implementa quella funzione, sarà necessaria la definizione della struttura, quindi è necessario includere il file Plop.h nel PlopUtils.cpp :
#include "PlopUtils.h"
#include "Plop.h" // now we need to include the header in order to work with the type
void doSomething(Plop* plop)
{
plop->n ...
}
void doNothing(Plop* plop);
{
plop->f ...
}
Penso che il compilatore C originariamente avesse un passaggio in cui faceva insieme la costruzione della tabella dei simboli e l'analisi semantica. Quindi ad esempio:
....
... foo(a,b) + 1 ... // assumes foo returns int
....
double foo(double x, double y){ ... } // violates earlier assumption
per evitarlo, dici:
double foo(double x, double y); // this is the forward declaration
....
... foo(a,b) + 1 ... // correct assumptions made
....
double foo(double x, double y){ ... } // this is the real declaration
Pascal aveva lo stesso concetto.
Aggiunta a risposte precedenti. La situazione tipica in cui il riferimento diretto è obbligatorio è quando una struttura foo contiene un puntatore a una barra struct e una barra contiene un puntatore a foo (una dipendenza circolare tra le dichiarazioni). L'unico modo per esprimere questa situazione in C è usare una dichiarazione anticipata, cioè:
struct foo;
struct bar
{
struct foo *f;
};
struct foo
{
struct bar *b;
};
I riferimenti in avanti consentono al compilatore C di fare meno passaggi e riduce significativamente i tempi di compilazione. Probabilmente è stato importante circa 20 anni fa quando i computer erano molto più lenti e i computer meno efficienti.