2015-10-06 40 views
9

Burada Richard Reese tarafından 'C Pointers'ı Anlama ve Kullanma' dan bir örnek verilmiştir. Sorum şu: 7. satırda "typedef int (* fptrOperation) ......" olmalı? İkisini de denedim ama hepsi iyi çalıştı. Ben iki gün boyunca çevrimiçi işlev görmek için typedef ve işaretçi kullanımını aradım ama yine de bunu anlayamadım. Farketmez herhangi bir yardım ~~typedef ve işaretçiyi işlev göstermek iç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- İşaretçi –

+0

gcc ile -Wall seçeneği uyarmıyor, sanırım bir işlev işaretçisinin nasıl bildirileceğine dair bir kısıtlama yoktur. Derleyici, sihri kendisi yapar, çünkü 'sort (names, 5, compareIgnoreCase)', 'compareIgnoreCase' adresinin kullanılmasının başka bir yolu bulunmadığı için derlenmiştir. – LPs

cevap

5

için teşekkürler. işlev parametreleri, fonksiyon türleri otomatik olarak işaretçi işleve çevrilir için

Bu

( ISO/IEC 9899:2011, 6.7.6.3 §8,) 'dir:

'' fonksiyonu geri türü olarak bir parametrenin bir beyan 6.3.2.1'de olduğu gibi, '' geri dönen tip işlevine '' işaretlenecektir.

3

C99 6.3.2.1 SolDeğerler, diziler ve işlev tanımlayıcılar:

4 bir fonksiyon dezignatör fonksiyonu türüne sahip bir ifadesidir. tip olan bir ifade dönüştürülür sizeof operatörünün işlenen ya da tekli & operatör, tip bir işlev dezignatör ‘'fonksiyonu geri türü’ olduğunda hariç ‘’ işaretçi dönen tip işlev'.

6.5.3.2 Adresi ve indirection operatörleri:

4 tekli * operatörü indirection gösterir. İşlenen, bir işlevine işaret ediyorsa, sonuç bir işlevlendiricidir; (Prototip dahil)

6.7.5.3 Fonksiyon declarators:

8 'tür geri çalışması için işaretçi' için ayarlanmalıdır 'fonksiyon tipi dönen' gibi bir parametrenin bir beyan , 6.3.2.1'de olduğu gibi.

Yani, örnek ve hatta aşağıdaki tüm geçerlidir:

#include <stdio.h> 

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

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