2016-08-23 11 views
-1

次のコードではエラーが発生し続けます。 3行目を変更するには?なぜそれが起こっているのですか?どうしましたか?パラメータ付きマクロ

#include <stdio.h> 
#include "stdlib.h" 
#define ARRAY_IDX(type, array, i) ((type *)(array+i)) // you can only modify this line! 

int main(int argc, const char * argv[]) { 
    void *ptr = malloc(10*sizeof(int)); 
#ifdef ARRAY_IDX 
    for (int i = 0; i < 10; i++) { 
     ARRAY_IDX(int, ptr, i) = i * 2; 
    } 

    for (int i = 0; i < 10; i++) { 
     printf("%d ", ARRAY_IDX(int, ptr, i)); 
    } 
    free(ptr); 
#else 
    printf("Implement ARRAY_IDX first"); 
#endif 
} 
+5

"エラー" - >どのエラー? (http://ideone.com/gTOLSe) –

+2

標準のCコンパイラでは、マクロがしようとするように 'void *'をインデックスすることはできません。 GCCはデフォルトでそれを許可していますが、GCCはデフォルトで標準のCコンパイラではありません。マクロに間接演算子もありません。 –

答えて

-2

voidポインターにintを追加することは何も問題ありません。長年にわたって、コンパイラ設計者はこれが標準的な動作であると想定し、そのように実装されました。これは、匿名の構造体や共用体のように、コンパイラがほぼ20年間持っていたもので、C11で最近追加されただけのものです。実際には、すべてのコンパイラは、特別なコンパイラフラグを使わなくても、警告やエラーなしでコンパイルできます。

あなたが指摘したように、ポインタに値を割り当てているという問題があります。あなたはキャストの後に逆参照する必要があります。

ARRAY_IDX(int, ptr, i) = i * 2; 

printf("%d ", ARRAY_IDX(int, ptr, i)); 

をみる

#define ARRAY_IDX(type, array, i) ((type *)array)[i] 
+2

まだ完全に定義されていません。あなたはまだ標準Cではない 'void *'を索引付けしています。あなたは十分な括弧を持っていません。 –

+0

@JonathanLeffler彼は空白を索引付けしていないので、intポインタにキャストして索引付けしています。 – DeftlyHacked

+2

間違っている!あなたはコード内の 'ptr'(' 'ptr'')を' 'ptr''に追加して' '(配列+ i)' 'を(' 'パラメータ名とマクロの引数として渡される値)マクロの 'array'引数として渡されます)は' void * 'です。これは許可されていません。 –

4

はそのように、発現

ARRAY_IDX(int, whatever, whatever) 

は、タイプint(及び左辺値の表現に展開すべきであることを示しています我々 それに割り当てることができます)。

need to change (cast) it to a pointer that allows indexingあなたが最初void *でオフに開始し、そしてあなたが(エイリアシングの違反になりませんその個々のバイト、)インデックスにその配列の要素をしたいので、あなたはそれがint *最初に行う必要があります。

(int *)(ptr) 

ここで、整数(配列、うまくいけば)へのポインタがあります。インクリメント:

(int *)(ptr) + (idx) 

最後に、左辺値intが必要です。それを取得するためのポインタを間接参照:プリプロセッサマクロにそれを変換する

(*((int *)(ptr) + (idx))) 

はなんとかなるべきものであるので、私はあなたにそれを任せます。


あなたにそのコードを提供している人は、誰でも信頼する必要がある教師ではありません。これは正しいCについてはあまり教えてくれません。プリプロセッサについて教えてくれるかもしれません。しかし、そのようなコードを書かないでください。ただしないでください。可能であれば、正しいタイプを使用してください。 mallocの失敗を確認してください。

関連する問題