2015-10-06 7 views
9

ここでは、Richard Reeseの「Cのポインタの理解と使用」の例を示します。 私の質問は7行目で "typedef int(* fptrOperation)......"であるべきですか? 私は両方を試しましたが、すべてうまく働いていました。 typedefの使い方とポインタを2日間オンラインで検索しましたが、まだそれを把握していませんでした。それは問題ではありません任意の助け~~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

C99 6.3.2.1左辺値、アレイ、及び関数指定子:

4関数指定子は、関数型を持つ式です。 sizeof演算子のオペランドまたは単項演算子である場合を除き、関数戻り型 ' 'を持つ式に変換されます。

6.5.3.2アドレスと間接演算子:

4単項*演算子は、間接を示しています。オペランドが ファンクションを指す場合、結果はファンクション指定子です。 (試作品を含む)

6.7.5.3関数宣言子:

8パラメータの宣言 '関数復帰型「としては、」 「」タイプを返す関数へのポインタ「」に調整しなければなりません6.3.2.1のように。

だから、あなたの例としても、次はすべて有効です。

#include <stdio.h> 

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

int main(void) 
{ 
    foo(); 
    (&foo)(); 
    (*foo)(); 
    return 0; 
} 
関連する問題