Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [C]Problema con strutture

    codice:
     
    #ifndef PAK_H
    #define PAK_H
    
    #include "include.h"
    
    typedef char bool;
    
    typedef struct
    {
        char content[PAK_N]; /* the content of pak */
        bool flag[FLAG_N]; /* the pak flag */
        char sign[10]; /* the verification signature */
    
    } Pak; 
    
    
    void setSign(Pak * ptr, const char sign[10])
    {
        #ifdef DEBUG
            assert(ptr != NULL);
        #endif  
        if((strlen(sign) > 10) || (strlen(sign) < 10))return;
        strcpy(ptr->sign, sign);   
    }
    
    bool cntSign(Pak * ptr)
    {
        #ifdef DEBUG
            assert(ptr != NULL);
        #endif  
    }
    
    
    void setContent(Pak * ptr, char content[PAK_N])
    {
        #ifdef DEBUG
            assert(ptr != NULL);
        #endif  
        int i;
        for(i = 0; i<PAK_N; i++)
        {
            ptr->content[i] = content[i];
        }  
    }
    
    int send(Pak * ptr, int mode)
    {
        #ifdef DEBUG
            assert(ptr != NULL);
        #endif  
        if(strlen(ptr->content) < PAK_N)
            return -1;
        setContent(ptr, ptr->content);
        ptr->flag[0] = TRUE; /* the dimension OK flag */
        switch(mode)
        {
            case SERVER:
                    ptr->flag[1] = SERVER; /* the pak type flag */
                    break;
            case CLIENT:
                    ptr->flag[1] = CLIENT;
                    break;  
            case REQUEST:
                    ptr->flag[1] = REQUEST;
                    break; 
            default:
                    ptr->flag[1] = ERROR;
                    break;                               
        } 
        if((ptr->flag[0] == TRUE) && (ptr->flag[1] != ERROR))
        {   
            setSign((Pak *) ptr->sign, CHECK);
        }else{
            return -1;
        }
        /*
            send to serial port
        */
        return 0;
            
    }
    
    void rec(Pak * ptr, char buf[PAK_N])
    {
        /*
            receive to serial port
        */   
        #ifdef DEBUG
            assert(ptr != NULL);
        #endif  
        strcpy(buf, ptr->content);
    }
    /*
     * Log Format:
     * # DATE #
     * # FLAG #
     * # CONTENT #
     */
    void log(char * msg)
    {
        FILE * log = fopen("app.log", "a+");
        #ifdef DEBUG
            assert(log!= NULL);
        #endif  
        fprintf(log, "#%s#\n", msg);
        fclose(log);
    }
    
    void controlChecksum(char * ck, bool * control)
    { 
        if(strcmp(ck, CHECK) == 0)
        {   
            control =  (bool *) 0;
        }else{   
            control =  (bool *) 1;
        }    
    }
    
    #endif
    Se provo ad usare la funz send() mi restituisce -123343


    Help me
    La stupidità umana e l'universo sono infinite.
    Della seconda non sono certo(Einstein)

    Gnu/Linux User

  2. #2
    non lo so, la funzione send non restituisce mai quella cifra, quel numero viene fuori da qualche altra cosa.

    Piuttosto sull uso della programmazione per contratto e sull'uso delle asserzioni: evita di usare un'asserzione su una variabile il cui valore non dipende dall'avere fatto errori di programmazione. (mi riferisco all'assert che fai sull'apertura del file in caso di fallimento, andrebbe gestito come eccezione non come asserzione)

    Domanda: A cosa servono le asserzioni?

    Risposta: A scrivere codice corretto e leggibile. Si può scrivere codice corretto anche facendo in modo che sia il chiamante che la funzione eseguano i controlli sulla correttezza dei parametri. Però è svantaggioso. Se siamo sicuri che il chiamante fa già i controlli è inutile che anche la funzione li faccia. Allora è meglio stabilire chi deve fare i controlli usando le asserzioni.

    Domanda: Come facciamo ad essere sicuri che il chiamante effettui questi controlli usando le asserzioni?

    Risposta: Se il chiamante non farà i controlli, durante l'esecuzione del programma in modalità di debug scatteranno le asserzioni, (che terminano il programma e danno un messaggio di errore) quindi il programmatore avrà modo di rendersi conto di dover correggere il programma.

    La cosa importante delle asserzioni è che sono utili prima ancora di avere scritto l'implementazione, già a livello di specifica. Poi terminata la fase di debug le asserzioni vengono rimosse, eliminando tutte le ridondanze nei controlli e rendendo il programma più veloce e compatto.

    Due parole su diritti e doveri: per essere più specifici, qualunque metodo ha delle condizioni che devono essere verificate PRIMA dell'esecuzione (i parametri sono corretti? l'ambiente è corretto?) e DOPO l'esecuzione (il risultato è corretto?, l'ambiente è corretto?).

    Ad esempio una PREREQUISITO (diritto) della funzione log(x) sarà esplicitato da assert(x>0), ciò significa che la responsabilità di verificare che il parametro in input sia corretto spetta al chiamante.

    Un POSTREQUISITO (dovere della funzione) è verificare che in effetti il valore ritornato sia il logaritmo di x. Ad esempio assert(exp(risultato) == x), sarà inserito dal progettista in fase di specifica, in modo che il programmatore della funzione log abbia la possibilità di verificare che la sua funzione in effetti dia il risultato voluto.

    LA COSA FONDAMENTALE DA CAPIRE è che questo tipo di POSTREQUISITO dipende solo e soltanto dalla buona implementazione della funzione log, in questo caso si usa un asserzione. Quando un postrequisito non può essere raggiunto per motivi indipendenti dalla buona implementazione della funzione si usa invece sollevare un ECCEZIONE. Se ad esempio non riesco a scrivere su un log perchè il file non si apre, questa è un eccezione, non va usata un asserzione, tra l'altro questo tipo di evento non va gestita solo in fase di DEBUG... Inoltre la gestione delle eccezioni và di norma delegata al modulo software più specifico possibile (intendo dire che deve essere gestita dal modulo più possibile vicino all'utente, eg. GUI), quindi o la funzione che scrive il log genera un eccezione C++ o restituisce un valore che comunichi al chiamante l'eccezione.

    Magari in futuro potrei farci una pillola, spiegando un po' più in dettaglio ciò che penso... e parlando anche degli INVARIANTI, ovvero le condizioni che riguardano l'ambiente.

  3. #3
    codice:
    /*
     * Log Format:
     * # DATE #
     * # FLAG #
     * # CONTENT #
     */
    void log(char * msg)
    {
        FILE * log = fopen("app.log", "a+");
        if(log!= NULL)
          return;
        fprintf(log, "#%s#\n", msg);
        fclose(log);
    }
    Una cosa simile?
    La stupidità umana e l'universo sono infinite.
    Della seconda non sono certo(Einstein)

    Gnu/Linux User

  4. #4
    dipende da quanta importanza dai al fatto di scrivere sul log.

    Se non è così importante puoi anche fare un

    codice:
    if(log==NULL)
       return;
    se invece ritieni che il chiamante debba essere informato (secondo me sarebbe meglio) che l'operazione è fallita, in C++ puoi fare

    throw(string("impossibile aprire log file"));

    oppure trasformi la funz in boleana e fai

    return FALSE;

    a questo punto spetterà al chiamante decidere cosa fare, siccome il chiamante è più vicino all'utente di quanto non lo sia la funzione log avrà maggiori cognizioni di causa per decidere cosa fare, ignorare l'errore o mandare un messaggio sullo schermo ad esempio...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.