2016-10-26 7 views
2

私のコードは配列をvoidポインタに渡す必要があります(構造体にはvoid *があり、変更できません)。以下の2つのバージョンのコードは同じ出力を生成しますが、後者のコードでは2つの警告があります。私の質問は、2つの方法のどちらが優先されるかです。警告を削除するために型キャストする方法はありますか?voidポインタの使用の違いを説明してください

このバージョンでは、期待通りの警告を持っており、出力を生成しません:

#include <stdio.h> 

void test(void *var_arr, char var_1); 

typedef struct { 
    char chip; 
    void *buffer; 
}test_struct; 

int main() 
{ 
    int test_array[3] = {3,7,5}; 
    char var_1 = 0x20; 

    printf("Hello, World!\n"); 

    test(&test_array, var_1); 
    return 0; 
} 

void test(void *var_arr, char var_1) 
{ 
    int i; 

    test_struct var_ts; 

    var_ts.chip = var_1; 
    var_ts.buffer = var_arr; 

    for (i=0; i<3; ++i) 
     printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i)); 

} 

こんにちは、世界を!

データ値は、次のとおり3

データ値は、次のとおり7つの

データ値である:5


以下このバージョンでは、2回の警告を有するが、コンパイルし、生成します期待される出力:

警告: source_file.c:関数 'main'で: source_file.c:17:10:警告:互換性のないポインタ型から 'test'の引数1を渡します。 test(& test_array、var_1); ^ source_file.c:3:6:注: 'int 'が必須ですが、引数の型が 'int()[3]' です。void test(int * var_arr、char var_1);代わりに、最初の要素へのポインタの配列へのポインタを渡す:

#include <stdio.h> 

void test(int *var_arr, char var_1); 

typedef struct { 
    char chip; 
    void *buffer; 
}test_struct; 

int main() 
{ 
    int test_array[3] = {3,7,5}; 
    char var_1 = 0x20; 

    printf("Hello, World!\n"); 

    test(&test_array, var_1); 
    return 0; 
} 

void test(int *var_arr, char var_1) 
{ 
    int i; 

    test_struct var_ts; 

    var_ts.chip = var_1; 
    var_ts.buffer = (void *)var_arr; 

    for (i=0; i<3; ++i) 
     printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i)); 

} 
+2

test()の呼び出しでアンパサンドを削除します。 –

+3

注: 'void *'からのポインタをキャストする必要はありません。異なるレベルの間接指定が誤って使用された場合、問題を隠すことができます。 –

答えて

1

は低いバージョンは、問題が最初のものだったかを表示します。

タイプint(*)[3]持つ配列へのポインタを渡す:タイプint*を有する第一の要素へのポインタを渡す

test(&test_array, var_1); 

を:

test(test_array, var_1); 

コードが動作する起こります2つのポインタが同じアドレスを指しているため、配列へのポインタは動作するように見えますが、コードは未定義です。

int[3]という型の配列test_arrayが関数に渡されるときにint*となるため、ポインタを最初の要素に渡すのは正しいです。

+0

"配列へのポインタ..." - 文字列があいまいです。ポインタは 'int(*)[3]'型であり、配列ではありません。 – Olaf

+0

ポインタ型 'int(*)3'を記述する最良の方法は何ですか?それはintへの3つのポインタの配列ですか? – kcinicx

+0

@kcinicx 'int(*)3 '型は有効な型ではありません。 'int(*)[3]'型は、3つのint *の配列へのポインタです。 – 2501

0

コンパイラがコードの静的解析を行い、バグの原因を特定したため、警告が表示されます。

voidポインターを使用すると、どのタイプが使用されているかわからないため、コンパイラーはこの静的解析を実行できません。

データ型がわかっている場合、私はいつもvoidポインタの代わりにこの型をポインタとして使用することをお勧めします。私はポインタが何かを指すことができることが許容されるときにのみ、voidポインタを使用します。結局のところ、これはあなたが従う個人的な好みとコードガイドラインに関するものです。

関連する問題