Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C++] Puntatori ad array

    codice:
    char ultimaLettera(stringa s)
    {
         while(*s++);
         return *(s);
    }
    stringa è un array di caratteri, la s che gli passo è un nome, quello che vorrei fare è ritornare l'ultima lettera del nome, ma naturalmente non funziona, cosa c'è di sbagliato?

    EDIT:

    codice:
    char ultimaLettera(stringa s)
    {
         return *(s+(strlen(s)-1));
    }
    così mi ritorna l'ultima lettera, il problema è che ho una serie di nomi... c'è un modo senza usare lo strlen?

  2. #2
    codice:
    char ultimaLettera(stringa s)
    {
         while(*s++);
         return s[-2];
    }
    ... a te capire perché funziona.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    non riesco a capire quando finisce di incrementare il puntatore :S
    scusa non finisce di incrementare il puntatore quando trova '\0'?

  4. #4
    Supponiamo di chiamare ultimaLettera sulla stringa "parola".
    codice:
    s --+
        V
      +---+---+---+---+---+---+----+ · · · 
      | p | a | r | o | l | a | \0 |   ·
      +---+---+---+---+---+---+----+ · · ·
    finché s punta ad una lettera valida non succede nulla di che.
    Ora esaminiamo il caso in cui s sia arrivato al \0:
    codice:
    s ---------------------------+
                                 V
      +---+---+---+---+---+---+----+ · · · · ·
      | p | a | r | o | l | a | \0 |   ·   ·
      +---+---+---+---+---+---+----+ · · · · ·
    qui viene valutata l'espressione
    codice:
    *s++
    che restituisce 0 (facendo terminare il while) ma incrementa s; per cui, all'uscita del while la situazione è la seguente:
    codice:
    s -------------------------------+
                                     V
      +---+---+---+---+---+---+----+ · · · · ·
      | p | a | r | o | l | a | \0 |   ·   ·
      +---+---+---+---+---+---+----+ · · · · ·
    ovvero, s punta alla "posizione fantasma" immediatamente dopo il carattere di fine stringa†.

    A questo punto, per tornare all'ultimo carattere "vero" bisogna tornare indietro di due posizioni
    codice:
    s -------------------------------+
                                     |
    s-2 --------------------+        |
                            V        V
      +---+---+---+---+---+---+----+ · · · · ·
      | p | a | r | o | l | a | \0 |   ·   ·
      +---+---+---+---+---+---+----+ · · · · ·
    da cui:
    codice:
    return s[-2];
    (per chiarezza: s[-2] è uguale per definizione a *(s-2))

    Nota comunque che questo codice non considera il caso speciale di una stringa vuota (ovvero, contenente solo il terminatore); in tal caso, si restituirebbe un puntatore non valido; per ovviare a questo problema, si può aggiungere un caso speciale all'inizio:
    codice:
    char ultimaLettera(stringa s)
    {
        if(!*s)
            return 0;
        while(*s++);
        return s[-2];
    }
    -----

    † nota che questo è ammesso dallo standard - si garantisce che l'aritmetica dei puntatori funzioni correttamente fino ad un elemento dopo l'ultimo, in modo da poter esprimere i range come intervalli semiaperti [inizio, fine).
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    !*s cosa vuol dire?

    Grazie infinite, chiarissimo!

  6. #6
    Originariamente inviato da djanthony93
    !*s cosa vuol dire?
    *s dereferenzia s, ottenendone il primo carattere; ! è l'operatore di not booleano - quanto segue viene convertito in un bool (0=>false; tutto il resto=>true) e negato.
    Quindi, if(!*s) è come dire if(s[0]==0).
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Ok capito, ma nel while se avessimo fatto semplicemente "s++"?

  8. #8
    Originariamente inviato da djanthony93
    Ok capito, ma nel while se avessimo fatto semplicemente "s++"?
    Eh?
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da djanthony93
    Ok capito, ma nel while se avessimo fatto semplicemente "s++"?
    Questo

    while(*s++);

    con il carattere * controlla il contenuto della locazione puntata dal puntatore, mentre così

    while(s++);

    controlli il valore del puntatore e non dei caratteri della stringa ...

    Capito la differenza?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Sì, sto facendo un po' di confusione, alla fine sia "*s" che "s" non sono due puntatori? La differenza è che uno punta al contenuto e l'altro all'allocazione in memoria? Cioè l'indirizzo?

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 © 2025 vBulletin Solutions, Inc. All rights reserved.