2015-10-06 3 views
9

Вот пример из «Понимание и использование указателей C» Ричарда Риз. Вопрос в том, должен ли он быть «typedef int (* fptrOperation) ......» в 7-й строке? Я пробовал их обоих, но все они хорошо работали. Я искал использование typedef и указатель для работы в Интернете в течение двух дней, но все же не понял его. Спасибо за любую помощь ~~typedef и указатель на функцию в 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- указатель –

+0

gcc с опцией -Wall не предупреждает, я думаю, что нет никаких ограничений на то, как объявить указатель на функцию. Компилятор сам делает магию, потому что когда 'sort (names, 5, compareIgnoreCase);' компилируется, нет другого способа, которым будет пользоваться адрес 'compareIgnoreCase'. – LPs

ответ

5

Это не имеет значения.

Это происходит потому, что для параметров функции, типы функций автоматически преобразуются в указатель на функцию (ISO/IEC 9899:2011, 6.7.6.3, §8):

Объявление параметра как «» функции возвращающегося типа '' должен быть скорректирован на «указатель на возвращаемый тип функции», как в 6.3.2.1.

3

С99 6.3.2.1 Lvalues, массивы и функции десигнаторами:

4 Функция Обозначение это выражение, которое имеет тип функции. За исключением случаев, когда это операнд оператора sizeof или оператора унарного оператора , обозначение функции с типом '' function return type '' преобразуется в выражение, которое имеет указатель типа '' для функции возвращающий тип ''.

6.5.3.2 Адрес и операторы: косвенного предоставления

4 Унарный оператор * обозначает косвенность. Если операнд указывает на функцию , результатом будет обозначение функции;

6.7.5.3 Функция declarators (в том числе прототипы):

8 Декларация параметра как «» функция типа возвращения «» должен быть устанавливают «» указатель на функцию, возвращающую тип «» , как в пункте 6.3.2.1.

Итак, ваш пример и даже все нижеследующее является действительным:

#include <stdio.h> 

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

int main(void) 
{ 
    foo(); 
    (&foo)(); 
    (*foo)(); 
    return 0; 
} 
Смежные вопросы