2015-10-06 7 views
9

Ecco un esempio tratto da "Comprendere e utilizzare i puntatori C" di Richard Reese. La mia domanda dovrebbe essere "typedef int (* fptrOperation) ......" nella settima riga? Ho provato entrambi, ma hanno funzionato tutti bene. Ho cercato l'uso di typedef e pointer per funzionare online per due giorni, ma ancora non l'ho capito. Grazie per qualsiasi aiuto ~~typedef e puntatore per funzionare in C

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h>  


typedef int (fptrOperation)(const char*, const char*);// 


char* stringToLower(const char* string) { 
    char *tmp = (char*) malloc(strlen(string) + 1); 
    char *start = tmp; 
    while (*string != 0) { 
     *tmp++ = tolower(*string++); 
    } 
    *tmp = 0; 
    return start; 
}  

int compare(const char* s1, const char* s2) { 
    return strcmp(s1,s2); 
}  

int compareIgnoreCase(const char* s1, const char* s2) { 
    char* t1 = stringToLower(s1); 
    char* t2 = stringToLower(s2); 
    int result = strcmp(t1, t2); 
    free(t1); 
    free(t2); 
    return result; 
}  



void displayNames(char* names[], int size) { 
    for(int i=0; i<size; i++) { 
    printf("%s ",names[i]); 
    } 
    printf("\n"); 
}  

void sort(char *array[], int size, fptrOperation operation) { 
    int swap = 1; 
    while(swap) { 
     swap = 0; 
     for(int i=0; i<size-1; i++) { 
      if(operation(array[i],array[i+1]) > 0){ 
       swap = 1; 
       char *tmp = array[i]; 
       array[i] = array[i+1]; 
       array[i+1] = tmp; 
      } 
     } 
    } 
}  





int main(int argc, char const *argv[]) 
{ 
    char* names[] = {"Bob", "Ted", "Carol", "Alice", "alice"}; 
    sort(names,5,compareIgnoreCase); 
    displayNames(names,5);  

    return 0; 
}  
+2

https://stackoverflow.com/questions/17914057/is-an-asterisk-optional-in-a-function- puntatore –

+0

gcc con opzione -Wall non avvisa, suppongo che non ci siano restrizioni su come dichiarare un puntatore a funzione. Il compilatore fa la magia stessa, perché quando 'sort (names, 5, compareIgnoreCase);' è compilato non c'è altro modo in cui viene usato l'indirizzo di 'compareIgnoreCase'. – LPs

risposta

5

Non importa.

Questo perché per i parametri funzionali, tipi di funzione vengono automaticamente a puntatore a funzione (ISO/IEC 9899:2011, 6.7.6.3, § 8):

Una dichiarazione di un parametro come '' tipo ritorno funzione '' deve essere impostato su '' puntatore alla funzione che restituisce il tipo '', come in 6.3.2.1.

3

C99 6.3.2.1 lvalue, array e designatori funzione:

4 Una funzione designatore è un'espressione che ha tipo di funzione. Tranne quando si tratta dell'operando dell'operatore sizeof o dell'operatore unario & , una designazione di funzione con tipo '' tipo di risposta funzione '' viene convertita in un'espressione che ha il tipo '' puntatore alla funzione tipo restituito ''.

6.5.3.2 Indirizzo e indirezione operatori:

4 L'operatore unario * denota indirezione. Se l'operando punta a una funzione , il risultato è un designatore di funzione;

6.7.5.3 dichiaratori funzionali (compresi prototipi):

8 Una dichiarazione di un parametro come '' funzione tipo ritorno '' sono modificato per '' puntatore a funzione tipo ritorno '' , come in 6.3.2.1.

Così, il vostro esempio e anche la seguente è tutto valido:

#include <stdio.h> 

void foo(void) 
{ 
    puts("foo"); 
} 

int main(void) 
{ 
    foo(); 
    (&foo)(); 
    (*foo)(); 
    return 0; 
}