Ecco una rottura della differenza:
1. Precondizionismo:
* Definizione: Una condizione che deve essere vero * Prima* viene chiamata una funzione affinché la funzione funzioni correttamente e ne garantisca il comportamento. È la responsabilità * del chiamante * di garantire che le condizioni preliminari siano soddisfatte. Se viene violato un preliminare, il comportamento della funzione non è definito; Potrebbe schiantarsi, produrre risultati errati o comportarsi in modo imprevedibile.
* Scopo:
* Chiarire gli input e l'ambiente previsti: Precondizioni documenta cosa si aspetta una funzione. Questo rende la funzione più facile da capire e utilizzare.
* Prevenire errori e bug: Controllando i preliminari (utilizzando le asserzioni), è possibile rilevare e prevenire errori all'inizio del processo di sviluppo.
* Abilita l'ottimizzazione: Se una funzione sa che determinate condizioni saranno sempre vere, può eseguire ottimizzazioni che non sarebbero altrimenti sicure.
* Documentazione: Clear Documentation consente ad altri sviluppatori di utilizzare correttamente la funzione.
* Responsabilità: Il * chiamante * della funzione è responsabile di garantire che tutte le condizioni preliminari siano vere prima di chiamare la funzione.
* Esempio:
`` `c
#include
#include
// funzioni per calcolare il fattoriale di un numero
int fattoriale (int n) {
// precondizionamento:n deve essere non negativo
assert (n> =0);
if (n ==0) {
Ritorno 1;
} altro {
return n * fattoriale (n - 1);
}
}
int main () {
int risultato =fattoriale (5); // precondizionamento soddisfatto
printf ("fattoriale di 5:%d \ n", risultato);
// fattoriale (-1); // Precondizionamento violato! Ciò causerà un fallimento dell'asserzione.
restituzione 0;
}
`` `
In questo esempio, la funzione `fattoriale 'ha un preliminare secondo cui` n` deve essere non negativo. L'istruzione `Assert (n> =0)` controlla questa preconferenza. Se `n` è negativo, l'affermazione fallirà e il programma terminerà (in una build di debug).
2. Postcondition:
* Definizione: Una condizione che deve essere vero * Dopo* una funzione ha eseguito correttamente. Descrive lo stato del programma (variabili, strutture di dati, valore di restituzione) dopo che la funzione ha completato la sua attività. È la responsabilità * della funzione * di garantire che le postcondizioni siano soddisfatte, * supponendo * le condizioni preliminari sono state soddisfatte.
* Scopo:
* Garantire l'effetto della funzione: Postconditions documenta ciò che la funzione * promette * da fare.
* Verifica la correttezza: Controllando le postcondizioni (utilizzando le asserzioni), è possibile verificare che la funzione stia producendo i risultati previsti.
* Facilitare il debug: Se viene violata una postcondition, indica un bug all'interno della funzione stessa.
* Documentazione: Clear Documentation consente ad altri sviluppatori di comprendere il comportamento della funzione.
* Responsabilità: La * funzione stessa * è responsabile di garantire che tutte le partite siano vere prima di tornare.
* Esempio:
`` `c
#include
#include
// funzione per calcolare il quadrato di un numero
int quadra (int x) {
int risultato =x * x;
// Postcondition:il risultato deve essere non negativo (se x è un numero intero)
assert (risultato> =0); // Questo potrebbe non riuscire a causa dell'overflow intero se x è molto grande.
risultato di ritorno;
}
int main () {
int risultato =quadrato (5);
printf ("quadrato di 5:%d \ n", risultato);
int Large_number =100000; // potrebbe causare trabocco
risultato =Square (Large_number); // Postcondition può fallire a causa di Overflow.
printf ("quadrato di %d:%d \ n", grande_number, risultato);
restituzione 0;
}
`` `
In questo esempio, la funzione `Square 'ha una postconditazione secondo cui` risultato` non deve essere negativo (supponendo che `x` sia un numero intero). L'istruzione `Assert (risultato> =0)` controlla questa postconditura. Se il risultato è negativo (a causa dell'overflow intero, per esempio), l'affermazione fallirà.
Differenze chiave riassunte:
| Caratteristica | Precondizionismo | Postcondition |
| ---------------- | -------------------------------------------------- | ---------------------------------------------------- |
| Timing | Controllato * prima * La funzione esegue | Controllato * dopo * la funzione esegue |
| Responsabilità | Caller della funzione | Funzione stessa |
| scopo | Definire input e ambiente previsti | Definire il comportamento e l'effetto garantiti della funzione |
| Violazione | Indica un problema nel * codice chiamata * | Indica un problema * all'interno della funzione * |
| Garanzie | La funzione può funzionare correttamente | La funzione avrà raggiunto l'effetto previsto |
come implementare in c:
Poiché C non ha un supporto integrato per precondizioni e postcondizioni, l'approccio standard è usare:
1. `Assert ()` Macro (da `
2. `#ifdef Debug` Blocks :Puoi anche usare `#ifdef debug` per includere condizionalmente controlli precondizionari e postcondizioni che potrebbero comportare più di un semplice confronto.
3. Commenti :Anche se non usi le affermazioni, è fondamentale documentare precondizioni e postcondizioni nei commenti per rendere il tuo codice più comprensibile.
4. Framework di test: Prendi in considerazione l'utilizzo di framework di test che supportano i controlli pre/post-condizione per facilitare i test unitari.
Esempio con precondizioni combinate, postcondizioni e commenti:
`` `c
#include
#include
/**
* @brief calcola la potenza di un numero (base sollevata in esponente).
*
* @param base il numero di base (intero).
* @param esponente l'esponente (numero intero non negativo).
*
* @PRE Exponent> =0 (l'esponente deve essere non negativo).
* @pre Base! =0 || esponente! =0 (base ed esponente non entrambi 0 - evita un comportamento indefinito)
*
* @post restituisce la base aumentata al potere dell'esponente.
* @post Se l'esponente è 0, il risultato è 1 (ad eccezione di base =0, che è vietato).
*
* @return Il risultato della base aumentata al potere dell'esponente.
* Restituisce 1 se l'esponente è 0.
*/
int Power (int base, int esponente) {
// Precondizioni:
assert (esponente> =0);
assert (base! =0 || esponente! =0); // prevenire il comportamento non definito con 0^0
int risultato =1;
per (int i =0; i
}
// Postconditions:
if (esponente ==0) {
assert (risultato ==1); // Controlla il caso di base
}
risultato di ritorno;
}
int main () {
int risultato =potenza (2, 3); // 2^3 =8
printf ("2^3 =%d \ n", risultato);
risultato =potenza (5, 0); // 5^0 =1
printf ("5^0 =%d \ n", risultato);
// potenza (0,0); // Questo attiverà l'affermazione.
restituzione 0;
}
`` `
Vantaggi dell'utilizzo di precondizioni e postcondizioni:
* Qualità del codice migliorata: Ti costringono a pensare attentamente alle ipotesi e alle garanzie delle tue funzioni.
* Debug più facile: Le asserzioni aiutano a catturare gli errori in anticipo e individuare la fonte di problemi.
* Documentazione migliore: Documentano chiaramente il comportamento previsto delle tue funzioni.
* Aumento della manutenibilità: Rendono il tuo codice più facile da comprendere e modificare, il che riduce il rischio di introdurre bug.
* Verifica formale: In alcuni casi, precondizioni e postcondizioni possono essere utilizzati con strumenti di verifica formale per dimostrare la correttezza del codice.
Incorporando precondizioni e postcondizioni nel tuo codice C (anche se semplicemente usando commenti e asserzioni), puoi scrivere software più robusto, affidabile e mantenebile.
Informazioni correlate
Programmazione © www.354353.com