2017-05-08 21 views
2

私はこれが重複していることを知っています。私はすでに検索しましたが、私が抱えている問題は何も解決していません。 私の混乱を取り除くために、私は元のタイプキャストを単純化しようとしました。うまくいけば、それは私が混乱し場所です関数ポインタ関数ポインタの型キャスト

FuncPtr = (int (*)(void*, void*))strcmp 

を型キャストのstrcmp宣言

Int (*funcPtr)(void*,void*); 

関数へのポインタを宣言

int strcmp (char *, char *); 

未定義の動作ではありません。私はTypecasting私たちが作成した関数のポインタを理解しています。したがって、タイプキャストFuncPtrは、たとえば、機能のタイプを変更するだけです。funcPtrが指すことができます。私はまた、関数の名前は、自身への関数ポインタがそう

int (*)(void*, void*))strcmp 

のstrcmpが今無効にするために2つのポインタを取る関数を指すことができ、のstrcmpを型キャストし、上から私の理解を使用していることを読んだことがあります私は関数名が別の関数へのポインタになることはできないと思います。私はあなたがdoesnのためにどのような関数ポインタのstrcmpポイントを変更すると、次の型キャスト

FuncPtr = (int (*)(void*, void*))strcmp 

でFuncPtrstrcmpののアドレスを割り当てることができますどのように見ることができない上にあるので私の理解の

引数を変更して戻り値の型をstrcmpに変更しないでください。

私はちょうど混乱しているいくつかの知識を本当に感謝します。

+3

あなたができるというだけで、良いアイデアだとは限りません。もし私が望むなら私の車を私の車に乗せることができます.... – ThingyWotsit

+1

関数ポインタはどの関数も指し示すことができますが、ポインティングされた型が関数と正確に一致しない限りポインタを介して関数を呼び出すことはできません –

+0

を指しています。「関数名は別の関数へのポインタにはなりません」と思いますか?ここでも何を意味していますか? 'FuncPtr'とは何ですか? C言語では大文字と小文字が区別されることに注意してください。 – Lundin

答えて

4

関数があり、関数ポインタがあります。 strcmpは、プロジェクトにリンクされている関数です。式の中で識別子strcmpが使用されると、その関数への関数ポインタが得られます。しかし、strcmpはポインタではなく関数であるため、 "strcmpが指す場所"を変更することはできません。

Cでは、さまざまな関数ポインタタイプ間の変換が可能です。ただし、互換性のない型の関数ポインタを使用して関数を呼び出そうとすると、未定義の動作が呼び出されます。

int (*funcPtr)(void*,void*); 

は、次の形式を持っているstrcmp、と互換性がありません:

int strcmp(const char *s1, const char *s2); 

意味:実際にその関数ポインタを通じて機能strcmpを呼び出すために

funcPtr = (int(*)(void*, void*))strcmp; // this is ok but not very meaningful 
funcPtr(); // this is NOT ok, invokes undefined behavior 

、あなたが希望正しいタイプ、つまり int (*)(const char*, const char*)にキャストする必要があります。

+0

"関数名(ラベル)はそれ自身へのポインタに変換されます。" http://denniskubes.com/2013/03/22/basics-of-function-pointers-in-c/最後の章でこれについて説明しています – Simple

+0

私はまだキャスト(int(*)(void * 、void *)strcmpにするか?引数の型をvoidに戻してint型に戻す – Simple

+0

@Simple 'int x = 0; char * ptr =&x;'と同じ理由でstrcmpに何もしません'x 'には何も書かれていません。ポインターは指定された項目のアドレスを保持します。異なるタイプのポインターを変数に指定するだけで、変数自体のタイプは変更されません。 – Lundin