2012-02-16 17 views
1

アレイがグローバル変数として定義されているとします。 グローバル配列内の要素の位置を指すグローバル変数(C言語)

int array[] = {16, 25, 36, 49, 64}; 

これは共有ライブラリとしてコンパイルされる場合、コンパイラは、シンボル「アレイ」は、アレイのメモリ内の位置を指すとバイナリを生成します。

アレイ内にあるメモリの場所を表すグローバル変数を追加することは可能ですか?

int elem; 

elemが配列[2]と同じ場所をどのように表すことができますか? Cでも可能ですか?

EDIT:

は、それがポインタを介さずに行うことができますか?私はelem にすることに興味があり、魔法使い配列[2]のメモリ内の場所が存在します。 int* elem = &array[2]の場合、メモリはポインタ用に確保され、elemはそのポインタのシンボルになり、配列[2]のメモリアドレスがそこに格納されます。そのelemが配列[2]の位置のシンボルになりたいので、assert(elem == array[2])に常にを渡します。数学(≡)のアイデンティティのように。

誰でも知っているのは、私がプレーンCで、あるいはアセンブリでのみ可能なことです。

+1

:D __それだけでも可能ですか?__ – paislee

答えて

0

これは、ポインタを使用せずにプレーンCでは不可能です。

ただし、(これはポータブルと非常に、非常にハックではないことを注意してください)これを達成するために、いくつかのリンカの策略を使用することができます:-Wl,-Tyour_script.ldでコンパイルした後、デフォルトのリンカスクリプトはld -verboseから取得し、elem = (array) + 4 * 2;のようなものを含めて、それを編集します。 elemは現在(array[2]仮定sizeof(int) == 4ある)array + 8バイトと同じメモリアドレスを占めるべきである:

$ cat a.c 
#include <stdio.h> 

int foo[4] = {1,2,3,4}; 

int bar; 

int main() { 
    printf("%p %p\n", &foo[2], &bar); 
    return 0; 
} 
$ gcc -Wl,-Ta.ld a.c 
$ ./a.out 
0x6008e8 0x6008e8 
$ 
+0

これは私が探していた答えの一種です。私はそれのための代理人を取得するときに私はあなたに投票します。 :) – irpbc

+0

@iRasicまたはこの答えの横にあるチェックマークをクリックすると、質問の答えとしてマークすることができます(これは何らかの答えで行う必要があります) –

1
int array[] = {16, 25, 36, 49, 64}; 

int *elem = array + n; 
4

確かにこのような

// lib.c 

int array[] = { 1, 2, 3 }; 
int * const p = array + 2; 
// lib.h 

extern int array[]; 
extern int * const p; 
+1

+1定数ポインタ – Joe

0

はいすることができます

int array[] = {16, 25, 36, 49, 64}; 
int * elem = &array[2]; 

int main() 
{ 
    printf("array: %p elem: %p", array, elem); 
    return 0; 
} 
1

醜いプリプロセッサハックはあなただけアレイ状のElem2を使用することを可能にする[2]。ところで

ELEM2 = 42; 

int *p = &ELEM2; 

/* don't try this at home */ 

これは醜いですが、それは基本的にどのように標準入力、stdoutとstderrは、#defineで定義された次のとおりです。

int array[] = {16, 25, 36, 49, 64}; 
#define ELEM2 (array[2]) 

今のElem2も左辺値である:実際には、それ配列[2]であります(実際に私が見てきたすべての実装)ほとんどの実装で

UPDATE:

:それは醜いハックですが、それはこのようなエイリアシングの問題をキャッチするコンパイラを有効にし
array[2] = ELEM2++ * array[2]; /* no intervening sequence points here */ 
+0

この種のことは、通常、 'errno'も通常定義されている方法です - 左辺値のように動作するマクロ。これには何も問題ありません。リンカのトリック( 'array'は' ELEM2'を使ってコードに可視でなければならないことを除いて)と同様に動作し、移植可能です。 – caf

+0

実際、リンカのトリック(エイリアス)よりも頑丈です。 – wildplasser

+0

合意、良い点。 – caf

関連する問題