Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    45

    puntatori a funzioni in c

    ciao a tutti sto studiando i puntatori a funzione è mi sono trovata davati un sesercizio che deve ordinare un array in ordine crescente o descrescente a seconda della scelta dell'utente. nella dichiarazione delle funzioni:
    codice:
    void bubble( int work[], const int size, int (*compare)( int a, int b ) );
    int ascending( int a, int b );
    int descending( int a, int b );
     void swap( int *element1Ptr, int *element2ptr );
    nella funzione bubble non ho capito perchè cè scritto int (*compare)( int a, int b )..

    un'altra cosa:a e b sarebbero gli elementi dell'array e nella funzione swap vengono passati i puntatori dei elementi perchè si vuole cambiare l'array originale giusto?
    grazie in anticipo!
    eg

  2. #2
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    ciao

    ciao
    int (*compare)( int a, int b ) è un puntatore a funzione dato come parametro
    quindi allinterno della funzione bubble () ci sara una istruzione simile a questa
    compare(a,b);
    o a questa ,
    (*compare)( a, b );
    che richiama la funzione passata alla funzione

    esempio
    bubble( work, 34 , ascending);
    il puntatore riceve la funzione ascendig che poi sara richiamata nel corpo della stessa
    con nome (*puntatore_afunzione)(argomenti);

    un'altra cosa:a e b sarebbero gli elementi dell'array e nella funzione swap vengono passati i puntatori dei elementi perchè si vuole cambiare l'array originale giusto?

    presumo di si ! ma dai soli prototipi bisogna essere veggenti , per capire cosa faccia il
    programma
    Tecnologia

  3. #3
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Swap è una funzione per scambiare elementi, se la scrivi correttamente ciò non influenza l' esito dell' ordinamento.
    Ma la compare è quella che fa la differenza, perchè se confronti a e b devi scegliere che risultato far ritornare alla compare, e puoi scegliere se ritornare a-b oppure b-a, il che cambia tutto ed è la chiave per avere un ordinamento crescent eo decrescente.
    Questa è la funzione qsort di stdlib.h :
    http://www.cplusplus.com/reference/c...cstdlib/qsort/
    Ritornare a-b (sono puntatori dunque *a-*b) causa un ordinamento crescente, ritornare *b-*a cause un ordinamento decrescente.
    L' istruzione sarà quasi sicuramente analoga a questa:
    codice:
    if(compare(v[i],v[i-1])<0)
        swap(&v[i],&v[i-1]);
    Il che rende la funzione molto flessibile perchè si può scegliere un qualsiais criterio di ordinamento (nel caos di qsort, si possono ordinare interi, ma anche stringhe o strutture di qualsiasi tipo, basta scrivere bene la swap e la compare).
    La swap ha come argomenti puntatori perchè gli argomenti delle funzioni vengono sempre copiate come variabili locali alla funzione, per cui scambiare quegli elementi nella swao (se non sono puntatori) sarebbe sterile: vengono solo cambiate quelle variabili locali e quelle originali rimangono invariate.
    Sapendo queste cose, prova a scrivere la swap,la descending e ascending e prova a risolvere l' esercizio (posta il codice).

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    45
    grazie per le risposte lo swap l'ho capito, la funzione bubble un pò di meno,il codice corrispondente alla funzione è :
    codice:
    void bubble( int work[], const int size, int (*compare)( int a, int b ) )
    {
       int pass; /* pass counter */
       int count; /* comparison counter */
    
       /* loop to control passes */
       for ( pass = 1; pass < size; pass++ ) {
    
          /* loop to control number of comparisons per pass */
          for ( count = 0; count < size - 1; count++ ) {
    
             /* if adjacent elements are out of order, swap them */
             if ( (*compare)( work[ count ], work[ count + 1 ] ) ) {
                swap( &work[ count ], &work[ count + 1 ] );
             }
          }
       }
    }
    ho capito che int (*compare)( int a, int b ) è la "dichiarazione" del puntatore a funzione che riceve i due parametri a,b. Non mi è tanto chiaro la condizione(If)
    eg

  5. #5
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Allora no, la compare la devi implementare in maniera diversa, non è come quella che chiede qsort di stdlib.h;
    L' istruzione:
    codice:
    /* if adjacent elements are out of order, swap them */
             if ( (*compare)( work[ count ], work[ count + 1 ] ) ) {
                swap( &work[ count ], &work[ count + 1 ] );
    Dice che se la compare ritorna un valore non-zero, gli elementi vengono scambiati.
    Per cui la compare deve ritornare un booleano, se vuoi ordinare gli elementi in ordine crescente deve essere:
    codice:
    int ascending(int a,int b)
    {
        return (a>b);
    }
    Così se work[count] è maggiore di work[count+1] la compare ritorna 1 e gli elementi vengono scambiati.

    PS: Ma che corso stai frequentando?

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2012
    Messaggi
    45
    ok ho capito, visto che compare è un puntatore a funzione la condizione viene impostata in quel modo.
    grazie..


    PS. IETI (ingegneria elettronica e tecnologie dell'informazione)
    eg

  7. #7
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    ciao

    roby89
    ti sei dilungato ma a mio avviso , hai confuso sole le idee
    puntatore a funzione come ti ho detto .

    bisogna creare una semplicissima funzione scabia
    due funzioni compare dai nomi dati nei prototipi
    una che restituisce -1 se a < b
    l'altra che restituisce -1 se a>b
    e passarli alla funzione in seguito o di ordinamento crescente o di ordinamento decrescente

    io sono un principiante autodidatta
    l'unica cosa che mi è servita di quello che ha detto roby
    è

    if(compare(v[i],v[i-1])<0)
    swap(&v[i],&v[i-1]);


    posto come lo ho risolto io , ma solo per dimostrare che ha una risoluzione più
    semplice della descrizione


    codice:
    #include <stdio.h>
    #include <stdlib.h>
    void bubble( int work[], const int size, int (*compare)( int a, int b ) );
    int ascending( int a, int b );
    int descending( int a, int b );
     void swap( int *a, int *b );
    
    int main(int argc, char *argv[])
    {
      int *array;
      int i,j;
      printf("Quanti elementi vuoi inserire nell'array ?  \n");
      scanf("%d",&i);
      array=(int*)malloc(sizeof(int)*i);
      for(j=0;j<i;j++)
      {
          printf("inserisci l'elemento %d  -->",j+1);
          scanf("%d",&array[j]);
          
          
          }
          
      printf("Come vuoi ordinare l'array ? \n1 ordine decrescente  \n2 ordine crescente\n");
      scanf("%d",&j);
      if(j==1)
       bubble( array , i, descending );
      else if(j==2)  
      bubble( array , i, ascending ); 
      //stampa vettore
      for(j=0;j<i;j++)
          printf("%d\n",array[j]);
      
      
      system("PAUSE");	
      return 0;
    }
    
    
    int descending(int a, int b)
    {
          if(a>b)
               return -1;
         else 
          return 1 ;
    
    }
    
    int ascending(int a ,int b)
    {
    
       if(a<b)
               return -1; 
         else 
              return 1 ;
     
      
        
    }
    
    
    void swap( int *a, int *b )
    {
        int temp;
        temp=*a;
        *a=*b;
        *b=temp;
        
        
        
        }
    void bubble( int v[], const int size, int (*compare)( int a, int b ) )
    {
        int i;
        for(i=1;i< size;i++)
        {
        if((*compare)(v[i],v[i-1])<0)
        swap(&v[i],&v[i-1]);
        
       }    
        
        
        }
    Tecnologia

  8. #8
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219

    Re: ciao

    Originariamente inviato da torn24

    codice:
    void bubble( int v[], const int size, int (*compare)( int a, int b ) )
    {
        int i;
        for(i=1;i< size;i++)
        {
        if((*compare)(v[i],v[i-1])<0)
        swap(&v[i],&v[i-1]);
        
       }
    Non è un bubblesort questo, se ci guardi bene ha come unico effetto di "trascinare" il massimo nell' ultima posizione dell' array.Devi usare due cicli for annidati.

  9. #9
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    ciao

    hai ragione ramy89
    non lo avevo notato , per combinazione con la sequenza di numeri che gli davo
    me le ordinava "anche se sara stato un caso".
    ho aggiunto un for come nell' esempio postato da egla .


    io questi algoritmi di ordinamento , non li ho mai imparati a memoria e quando mi servono
    cerco online.
    a dire il vero ho imparato a memoria pochissimi algoritmi
    Tecnologia

  10. #10
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219

    Re: ciao

    Originariamente inviato da torn24
    io questi algoritmi di ordinamento , non li ho mai imparati a memoria e quando mi servono
    cerco online.
    a dire il vero ho imparato a memoria pochissimi algoritmi
    Fai bene, è sempre meglio provare le cose di mano propria.
    Ma faresti ancora meglio senza cercare l' algoritmo su internet, provando a scrivere te lo pseudocodice.

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.