2015-10-06 33 views
9

Oto przykład z "Zrozumienia i korzystania z C Wskaźniki" Richard Reese. Moje pytanie brzmi: czy powinno być "typedef int (* fptrOperation) ......" w 7. linii? Próbowałem ich obu, ale wszystkie działały dobrze. Przeszukałem użycie typedef i wskaźnika, aby działały online przez dwa dni, ale wciąż nie rozumiałem tego. Dziękujemy za pomoc ~~typedef i wskaźnik do funkcji w 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- wskaźnik –

+0

gcc z opcją -Wall nie ostrzega, domyślam się, że nie ma żadnych ograniczeń, jak zadeklarować wskaźnik funkcji. Kompilator sam wykonuje magię, ponieważ gdy skompilowane jest 'sort (names, 5, compareIgnoreCase);' nie ma innego sposobu użycia adresu 'compareIgnoreCase'. – LPs

Odpowiedz

5

To nie ma znaczenia.

To dlatego parametrów funkcyjnych typy funkcji automatycznie przeliczeniu na wskaźnik do funkcji (ISO/IEC 9899:2011, 6.7.6.3, §8)

Zgłoszenie parametru w funkcji typu „” powrotu "" należy dostosować do wskaźnika "zwracającego wskaźnik funkcji", zgodnie z 6.3.2.1.

3

C99 6.3.2.1 lwartościami, tablice oraz określenia funkcji:

4 Funkcja oznaczenie to wyrażenie jest typu funkcji. Z wyjątkiem sytuacji, gdy jest operandem operatora sizeof lub unitarnego operatora & , oznaczenie funkcji z funkcją zwracającą typ typu " jest konwertowane na wyrażenie, które ma typ" wskaźnik do funkcji zwracający typ "".

6.5.3.2 adresowe i pośredni Operatorzy:

4 jednoargumentowych napędu * oznacza pośredni. Jeśli operand wskazuje na funkcję , wynikiem jest oznaczenie funkcji;

6.7.5.3 declarators funkcyjne (włącznie z prototypami):

8 Deklaracja parametru jako „” funkcja typ powrocie „” powinny być dostosowane do „” wskaźnik funkcjonować typ powrocie „” , jak w 6.3.2.1.

Tak Twój przykład i nawet po to wszystko ważne:

#include <stdio.h> 

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

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