Una volta il mio istruttore mi ha detto che non dovrei definire una variabile all'interno di un ciclo , ma sinceramente non capisco perché.
Quali sono gli svantaggi di questo?
Qualcuno potrebbe spiegarmelo?
Una volta il mio istruttore mi ha detto che non dovrei definire una variabile all'interno di un ciclo , ma sinceramente non capisco perché.
Quali sono gli svantaggi di questo?
Qualcuno potrebbe spiegarmelo?
Non è un problema per definire una variabile all'interno di un ciclo. In effetti, è una buona pratica, dal momento che gli identificatori dovrebbero essere confinati al più piccolo ambito possibile.
Ciò che è male è assegnare una variabile all'interno di un ciclo, se puoi anche assegnarlo una volta prima il ciclo viene eseguito. A seconda della complessità del lato destro del compito, questo potrebbe diventare piuttosto costoso e potrebbe persino dominare il tempo di esecuzione del ciclo. Se scrivi un ciclo che utilizza lo stesso valore calcolato in tutte le iterazioni, dovresti sicuramente calcolarlo sopra il ciclo - che è più importante che minimizzare il suo ambito.
Per chiarire: finché compute()
restituisce sempre lo stesso valore, questo
int value = compute();
while (something) {
doSomething(value);
}
è più intelligente di questo:
while (something) {
int value = compute();
doSomething(value);
}
I tipi complessi hanno costruttori e distruttori non banali.
Questi verranno richiamati all'inizio e alla fine del corpo del ciclo (poiché è inizializzato e esce dall'ambito). Se l'inizializzazione è costosa, come se fosse necessario allocare memoria, dovrebbe essere evitata.
Tuttavia per tipi banali non c'è problema. L'allocazione e la deallocazione stessa stanno semplicemente aggiungendo e sottraendo un valore dal puntatore dello stack. (che verrà ottimizzato)
Bene, il suo consiglio è leggermente troppo semplice (è un eufemismo).
Segue tutto da una buona idea su chi cura e cattiva idea a impossibile .
Dovresti seguirlo ogni volta che riutilizzare costa meno che distruggere il vecchio e crearne uno nuovo.
#include <iostream>
#include <string>
int main() {
std::string s; // Don't needlessly free the buffer
while ((std::cin >> s))
std::cout << s;
}
Dovresti evitarlo come questione di stile quando non ha importanza per le prestazioni.
#include <stdio.h>
#include <stdlib.h>
int f(int, int);
int main() {
for (int i = 0; i < 100; ++i) {
int x = rand(); // Declared here so you don't need to hunt it down.
printf("%d => %d\n", x, f(x-1, x+i));
}
}
veramente dovrebbe essere evitato quando ha prestazioni peggiori o semantica sbagliata.
#include <iostream>
#include <string>
std::string generate(int);
int main() {
for(int i = 0; i < 100; ++i) {
std::string s = generate(i); // Using copy-ellision here
std::cout << s;
}
}
Tu non puoi seguirlo quando il tipo usato non consente né lo scambio, né l'assegnazione dello spostamento né l'assegnazione della copia.
#include <iostream>
#include <puzzle>
int main() {
for (int i = 0; i < 100; ++i) {
Puzzle x(i); // Puzzle is an immutable class. For whatever reasons.
std::cout << x;
}
}
Leggi altre domande sui tag programming-practices c++ performance initialization declarations