Mi sono imbattuto in qualche codice C che utilizza gli operatori di riferimento/dereferenziazione (o qualsiasi altra cosa si sceglie chiamarli), *
e &
, allo stesso tempo, come &*foo
e *&bar
. Ne sono perplesso. C'è qualche ragione per farlo?C'è un motivo per usare * & or & * nel codice C?
risposta
Sì, possono essere utilizzati in modo significativo: un caso di utilizzo valido è nelle definizioni macro per verificare che l'argomento macro corrisponda ai requisiti.
&*foo
verifica che foo
sia un tipo di puntatore (eventualmente dopo una conversione implicita da un array o un tipo di funzione).
*&foo
verifica che foo
sia un'espressione lvalue.
Ad esempio, certamente un esempio così semplice che potrebbe essere un po 'di abuso macro:
void f(int *);
#define F(x) (f(&*(x)))
void g(int *);
#if A
#define G(x) (g(x), (x)=0)
#elif B
#define G(x) (g(*&(x)))
#endif
void h(int *p, int i) {
f(p); // okay
F(p); // still okay, does the same thing as f(p)
f(i); // typically just a compiler warning
F(i); // pretty much always a compiler error
g(p); // okay
G(p); // okay
g(p+0); // okay
G(p+0); // error if A because of the modification
// should be an error if B even without modification
}
Potresti fornire esempi più concreti? Aiuterà a capire meglio la tua risposta. Grazie. –
@StanislavPankevich Qualcosa di simile? :) – hvd
Molto utile, grazie. Potresti anche aggiungere un esempio per '* & foo verifica che foo sia un'espressione lvalue.? –
L'unico motivo significativo per farlo è quello di smettere di trattare l'espressione come un lvalue.
Citando C11
, capitolo §6.5.3.2
Il unario
&
operatore cede l'indirizzo del suo operando. Se l'operando ha tipo '' tipo '', , il risultato è di tipo "" per puntare a "". Se l'operando è il risultato di un operatore univoco , né l'operatore né l'operatore&
vengono valutati e il risultato è come se entrambi fossero omessi, eccetto che i vincoli sugli operatori continuano a essere applicati e il risultato non è un lvalue .
Quando vorresti farlo? Non ho mai detto a me stesso, "Mi auguro che questo non fosse un valore". – yellowantphil
@yellowantphil Questo dipende, ma in caso di controlli di uguaglianza, può aiutare a rilevare problemi '=' vs '=='. –
@SouravGhosh Non ho mai visto persone scrivere '& * p1 == & * p2' per capirlo. Hai? – hvd
&*ptr
contiene un suggerimento per il compilatore cheptr != NULL
(altrimenti*ptr
significherebbe comportamento indefinito).*&
può essere semplicemente il risultato di un cambiamento di manutenzione in cui è stata eliminata una variabile puntatore ausiliario:struct { int i; double } x; void foo() { int* ip = &x.i; ... *ip = 1; ... }
semplicemente sostituendo nel codice precedente
ip
con&x.i
risultati in codice che può dar vita ad una tale domanda su StackOverflow:struct { int i; double } x; void foo() { ... *&x.i = 1; // <--- ... }
Analogamente
&*
può essere introdotto da un cambiamento refactoring che ha sostituito lvalue con un puntatore.Prima di refactoring:
int main() { struct sockaddr_in serv_addr; ... bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); ... }
Dopo l'estrazione del codice di configurazione del server in una funzione a sé stante:
void setup_server(struct sockaddr_in* serv_addr) { ... bind(sockfd, (struct sockaddr *) &*serv_addr, sizeof(*serv_addr)); ... } int main() { struct sockaddr_in serv_addr; ... setup_server(&serv_addr); ... }
- 1. C'è un motivo per usare enum per definire una singola costante nel codice C++?
- 2. C'è mai un motivo per usare ":: template"?
- 3. Qualche motivo per usare byte/short ecc. In C#?
- 4. C++: C'è qualche motivo per usare uint64_t invece di size_t
- 5. C'è un motivo per usare std :: int_fast32_t o std :: int_fast16_t di C++ 11 su int in codice multipiattaforma?
- 6. C'è un motivo per non usare AssertionHelper con NUnit?
- 7. come usare opencv in Android Studio nel codice C++ nativo
- 8. C'è un motivo per usare const_cast su una stringa letterale in questo codice?
- 9. Rifattore codice C++ per usare un linguaggio di scripting?
- 10. come usare "AND", "OR" per RewriteCond su Apache?
- 11. quando usare @objc nel codice swift?
- 12. Come usare OR logico in SPIRQL regex()?
- 13. Come usare lzma2 nel codice Python?
- 14. estratto 7zip nel codice C#
- 15. Condizione OR nel selettore CSS
- 16. Qualsiasi motivo per usare! 0 invece di vero?
- 17. Motivo per passare un puntatore tramite riferimento in C++?
- 18. C'è un modo per incorporare Fitnesse nel codice C++?
- 19. C'è qualche motivo per usare se (1 ||! Foo())?
- 20. come usare #ifdef con una condizione OR?
- 21. Posso fare NON usare OR e AND?
- 22. nel collegamento di un riferimento a object-or-dummy
- 23. Qualche motivo per assegnare -0?
- 24. Posso usare istruzioni OR in switch Java?
- 25. Come usare XPath per trovare l'antenato più vicino in un antenato-or-self nodelist
- 26. Motivo di progettazione per l'oggetto dinamico C#
- 27. Android Wear: c'è qualche motivo per usare un oggetto Time piuttosto che un oggetto Calendar?
- 28. C'è qualche motivo per usare il threading.Lock over multiprocessing.Lock?
- 29. Motivo decorativo in C++
- 30. Posso usare in qualche modo il codice C# o la libreria C# nel progetto java android?
ci mostri un caso ad esempio (_non esempio _codice)? –
Viene utilizzato in assegnazioni di variabili semplici. –