2015-10-14 21 views
5

以下はコードスニペットです。私はline no. 17 typecastingが有効で、適切であるかどうかを知りたいですか?私は配列へのポインタへのポインタのキャスト

void intermediate(twoInts b) { 
    print(&b); 
} 

に定義intermediateを変更する場合

#include <stdio.h> 

typedef int twoInts[2]; 

void print(twoInts *twoIntsPtr); 
void intermediate (twoInts twoIntsAppearsByValue); 

int main() { 
    twoInts a; 
    a[0] = 0; 
    a[1] = 1; 
    print(&a); 
    intermediate(a); 
    return 0; 
} 
void intermediate(twoInts b) { 
    print((int(*)[])b); // <<< line no. 17 <<< 
} 

void print(twoInts *c){ 
    printf("%d\n%d\n", (*c)[0], (*c)[1]); 
} 

また、コンパイル時私は警告の下に取得していますし、O/pは適切ではありません。私の理解あたりとして

1.c:17:11: warning: passing argument 1 of print from incompatible pointer type 
    print(&b); 
     ^
1.c:5:6: note: expected int (*)[2] but argument is of type int ** 
void print(twoInts *twoIntsPtr); 

、配列は目的球引数にpointer to intに減衰されます。正確な理由は何ですか?

+3

'void print(twoInts * twoIntsPtr);'は と同じです。void print(int(* twoIntsPtr)[2]); 'つまり、配列を非表示にしないでください。 typedefの背後にあるポインタ。 – this

+2

問題の最も適切な解決策は、実際にはtypedefの背後に配列を隠すことはないということです。次に、プログラムを忘却することを難読化する必要なしに、単純な 'int *'ポインタを使うことができます。 – Lundin

+0

私は 'print((twoInts *)&b);'と言います。 – alk

答えて

3

aは配列です。したがって、intermediate()に渡すと、最初の要素へのポインタに変換されます(別名「配列の崩壊」)。

ので、中b

void intermediate(twoInts b) { 
    print(&b); 
} 

は、あなたが期待するように見えるかもしれないとしてint*、ないint[2]を入力しています。したがって、&bは、print()機能によって期待されるint (*)[2]ではなく、int**のタイプです。 したがって、タイプは一致しません。

あなたがintermediate()を変更する場合:

void intermediate(twoInts *b) { 
    print(b); 
} 

あなたは&bのアドレスを渡す必要がありません、それはとして期待され、種類が正しく一致します。

関連する問題