2016-10-29 10 views
4

によって私はまた、このポインタはに渡さインデックスが指すポインタ

char *ptr; 
ptr = A[5] 

そのアレイの一つの要素を指すポインタを有する

char A[100][100] 

として2次元char配列が宣言しましたそのポインタのインデックス(この場合は5)を知る必要がある別の関数

void func(void *ptr) { 
int index = ??? 
} 

どのようにすればいいですか?これも可能ですか?

+0

なぜ単にインデックスを渡さないだけです: 'void func(void * ptr、size_t i);'? – alk

答えて

3

Afuncにある場合は可能です(Aは配列上のポインタではなく、2重にインデックスされた1D配列です)、それが可能です。

#include <stdio.h> 

char A[100][100]; 

void func(void *ptr) { 
    char *ptrc = (char*)ptr; 
    printf("index %d\n",int((ptrc-A[0])/sizeof(A[0]))); 
} 

int main() 
{ 
    char *ptr = A[5]; 
    func(ptr); 
} 

結果:もちろん

index 5 

あなたはfuncに関係のないポインタを渡す場合は、未定義の結果を持っています。

注:入力されたvoid *ポインタをchar *にキャストする必要があります。そうしないと、コンパイラは互換性のない型のdiffポインタを許可しません。

編集:私は、両方のインデックスを計算するためにchqrlieによって挑戦されたように、私はそれを試み、それが(無関係なポインタで呼び出される関数を防止するためにも追加の安全性)を働いた:

#include <stdio.h> 
#include <assert.h> 

char A[100][100]; 

void func(void *ptr) 
{ 
    char *ptrc = (char*)ptr; 
    ptrdiff_t diff = (ptrc-A[0]); 
    assert(0 <= diff); 
    assert(diff < sizeof(A)); 
    printf("index %d %d\n",(int)(diff/sizeof(A[0])),(int)(diff % sizeof(A[0]))); 
} 

int main() 
{ 
    char *ptr = &(A[5][34]); 
    func(ptr); 
} 

結果:

index 5 34 
+0

ちょっと興味がありますが、なぜあなたはchar * ptrc =(char *)ptr;の最初のキャストをしますか?あなたはそのprintステートメントでptrを使うことはできませんか? – Bob

+0

ポインタが同じ型である必要があります。そうしないと、コンパイラはポインタをdiffしません。 –

+0

ポインタは2D配列内を指し示すことができ、両方のインデックスを計算することはきれいに見える。 – chqrlie

2

あなたは配列の先頭からptrのオフセットおよび座標を導き出す計算することができます。

#include <stdio.h> 
#include <stdlib.h> 

char A[100][100]; 

void func(void *ptr) { 
    if (ptr == NULL) { 
     printf("ptr = NULL\n"); 
     return; 
    } 
    ptrdiff_t pos = (char *)ptr - A[0]; 
    if (pos < 0 || pos > (ptrdiff_t)sizeof(A)) { 
     printf("ptr points outside A: ptr=%p, A=%p..%p\n", 
       ptr, (void*)A, (void*)&A[100][100]); 
    } else { 
     printf("ptr = &A[%d][%d]\n", 
       (int)((size_t)pos/sizeof(A[0])), // row number 
       (int)((size_t)pos % sizeof(A[0]))) // column number 
    } 
} 

int main(void) { 
    char *ptr = &A[5][3]; 
    func(ptr); 
    return 0; 
} 
+0

この 'size_t pos'には' ptrdiff_t'があります。 – alk

+0

@alk:正しいですが、 'ptr'が' A'の内部またはその上端にある有効なポインタである場合、 'pos'はコンストラクションによって正です。この場合、変換は正常です。 'ptr'が' NULL'または 'A'の外側を指している場合、その差を計算することはとにかく意味がありません。 – chqrlie

関連する問題