Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [C] Esercizi K&R

  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    3

    [C] Esercizi K&R

    Salve a tutti (mi sono appena registrato )

    Sono alle prime armi con il C, e sto leggendo il K&R che immagino la maggior parte di voi conosca.
    Sto provando a svolgere gli esercizi proposti dal testo pero', dal momento che non vi sono le soluzioni, non ho modo di verificare se quanto scrivo sia una buona soluzione.
    Vorrei quindi chiedervi, se possibile, se potete dare uno sguardo al codice che segue (esercizio 1.13 del testo); il programma funziona, vi chiedo di darmi consigli/correzioni/giudizi, se potevo trovare soluzioni piu' sintetiche, se vi sono errori di concetto, se il codice e' troppo ermetico o troppo prolisso e, in generale, tutto quello che notate.

    Grazie

    codice:
    /* Si scriva un programma che visualizzi un istogramma
       della lunghezza delle parole contenute nel testo in
       ingresso. E' facile disegnare un istogramma che si
       sviluppa in orizzontale, mentre richiede maggior
       abilita' tracciarlo in verticale */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_LENGTH 10
    
    int main()
    {
    
      int i, k;
      int contatore[MAX_LENGTH];
      char *buffer = (char *)malloc(MAX_LENGTH*sizeof(char));;
      char c;
    
      for (i=0; i < MAX_LENGTH; i++) {
        contatore[i] = 0;
      }
    
      printf("\nInserire del testo con parole di lunghezza massima 10.\n");
      printf("Per terminare l'inserimento scrivere fine.\n\n");
    
      i=0;
      while (strcmp(buffer, "fine")) {
        c = getchar();
        if (c != ' ' && c != '\t' && c != '\n') {
          buffer[i] = c;
          i++;
        } else {
          buffer[i] = '\0';
          if (strcmp(buffer, "fine")) {
            contatore[strlen(buffer)-1]++;
          }
          i=0;
        }
      }
      free(buffer);
    
      printf("\nIstogramma orizzontale della lunghezza delle parole inserite:\n\n");
    
      for (i=0; i < MAX_LENGTH; i++) {
        printf("Parole di lunghezza %d:\t", i+1);
        if (contatore[i]) {
          for (k=0; k < contatore[i]; k++) {
            printf("*");
          }
        }
          printf("\n");
      }
      
      return 0;
    
    }

  2. #2
    codice:
      char *buffer = (char *)malloc(MAX_LENGTH*sizeof(char));
    Se l'allocazione dinamica non è strettamente necessaria evitala. In questo caso basta un
    codice:
    char buffer[MAX_LENGTH];
    .
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    potresti modificare questa

    codice:
      printf("\nInserire del testo con parole di lunghezza massima 10.\n");
    nella seguente

    codice:
      printf("\nInserire del testo con parole di lunghezza massima %d.\n", MAX_LENGTH);
    cosi' se cambi il valore di MAX_LENGTH (mantenendolo un intero) non devi toccare la stringa.

    RFC Project - http://rfc.altervista.org
    Clessidra MUD - http://www.clessidra.it - telnet: mud.clessidra.it:4000

  4. #4

    Re: [C] Esercizi K&R

    Originariamente inviato da ale_d il programma funziona, vi chiedo di darmi consigli/correzioni/giudizi
    Il programma NON funziona: come minimo se la malloc dovesse fallire, il tuo programma produrrebbe un comportamenento indefinito (che nel caso fortunato sarebbe un crash del programma).
    Controlla SEMPRE gli eventuali errori restituiti dalle funzioni che utilizzi.

    ;-)

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    3
    (solo per chiarire) La mia affermazione "il programma funziona" non era un presupposto di saccenza, era per far capire che chiedevo aiuto non per il completamento di cio' che dovevo ottenere con il programma, ma una sua eventuale sistemazione/miglioramento o correzione degli errori

    Ringrazio per chi ha risposto e mi appresto a seguire i consigli e sistemare.

    Originariamente inviato da MacApp

    se la malloc dovesse fallire, il tuo programma produrrebbe un comportamenento indefinito (che nel caso fortunato sarebbe un crash del programma).
    Controlla SEMPRE gli eventuali errori restituiti dalle funzioni che utilizzi.
    Non ci avevo proprio minimamente pensato.
    Dunque, la malloc (a buon fine) mi ritorna un puntatore alla memoria che viene allocata, quindi se fallisce presumo mi ritorni un puntatore nullo. _Se_ non ho detto castronerie, potrei controllare l'eventuale errore cosi', che dite?

    codice:
    char *buffer = (char *)malloc(MAX_LENGTH*sizeof(char));
    if (buffer == NULL) {
      printf("Errore nell'allocazione di memoria.\n");
      exit(EXIT_FAILURE);
    }
    Originariamente inviato da MItaly
    Se l'allocazione dinamica non è strettamente necessaria evitala. In questo caso basta un char buffer[MAX_LENGTH];
    La prendo per buona. Mi date pero' una piccola spiegazione? Se ne capisco le motivazioni imparo qualcosa.

    Ora, richiamando le due questioni viste ora (possibilita' di fallimento di una malloc ed uso di una "allocazione diretta" (passatemi il termine) al posto di una dinamica (ove non strettamente necessario il contrario), mi viene da chiedermi: e' possibile che fallisca anche un'allocazione del tipo:

    codice:
    char buffer[MAX_LENGTH];
    Siate clementi, i miei dubbi sono portati dal newbie che c'e' in me

  6. #6
    Originariamente inviato da ale_d
    La prendo per buona. Mi date pero' una piccola spiegazione? Se ne capisco le motivazioni imparo qualcosa.
    Perché l'allocazione nello heap è più lenta, perché poi ti devi ricordare della free, perché usando gli array statici le dimensioni sono note a compile-time.
    Ora, richiamando le due questioni viste ora (possibilita' di fallimento di una malloc ed uso di una "allocazione diretta" (passatemi il termine) al posto di una dinamica (ove non strettamente necessario il contrario), mi viene da chiedermi: e' possibile che fallisca anche un'allocazione del tipo:

    codice:
    char buffer[MAX_LENGTH];
    Può fallire se viene esaurito lo spazio nello stack, nel qual caso il programma termina con un errore. Tuttavia è piuttosto improbabile che questo accada; in ogni caso l'heap andrebbe sempre usato per buffer molto grandi, dal momento che lo stack è molto più limitato in capacità.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Originariamente inviato da MItaly
    Perché l'allocazione nello heap è più lenta, perché poi ti devi ricordare della free, perché usando gli array statici le dimensioni sono note a compile-time.

    Può fallire se viene esaurito lo spazio nello stack, nel qual caso il programma termina con un errore. Tuttavia è piuttosto improbabile che questo accada; in ogni caso l'heap andrebbe sempre usato per buffer molto grandi, dal momento che lo stack è molto più limitato in capacità.
    Oltre al fatto che l'allocazione dinamica non ha senso, se si conosce a priori il numero di byte da allocare.

  8. #8
    Be', potrebbe aver senso se si dovesse allocare una gran quantità di memoria (per il motivo detto prima).
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    3
    Grazie per le risposte, ora mi e' chiara la questione


    Per quanto riguarda invece la gestione di un eventuale fallimento di allocazione dinamica e' corretto fare cosi' ?

    codice:
    char *buffer = (char *)malloc(MAX_LENGTH*sizeof(char));
    if (buffer == NULL) {
      printf("Errore nell'allocazione di memoria.\n");
      exit(EXIT_FAILURE);
    }

  10. #10
    Spesso per semplificare mi faccio una macro che mi fa tutto il lavoro ;=)
    codice:
    #define tok2str(tok) #tok
    #define mem_alloc(pointer, size, type) \
    do { \
       \
       (pointer) = (type*)malloc(size * sizeof(type)); \
       \
       if ((pointer) == NULL) { \
          \
          fprintf(stderr, "malloc failed at %s:%s\n%s returned NULL\n", __FILE__, __LINE__, tok2str(pointer)); \
          exit(EXIT_FAILURE); \
          \
       } \
     \
    }while(0);
    da usare così:

    codice:
    int main(void) {
    
       char *buffer = NULL;
       
       mem_alloc(buffer, MAX_LENGTH, char);
    
       /* ... Your own code ... */
    
       free(buffer);
    
       return 0;
    
    }


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.