2017-02-14 18 views
0

APIを正しく使用する方法を理解するためのAPIを使用したサンプルコードを調べています。私は混乱したコードを見つけました。私の理解では、変数ハンドルがジェネリック ヌルとしてキャストタイプとなっている変数myStruct_var(を指し、 ヌル ジェネリックポインタであるということである 連続したC言語のポインタキャスト

typedef struct myStruct_id{ 
randomStruct1 var1; 
void *var2; 
unsigned char *var3; 
randomStruct2 var4; 
int var5; 
}myStruct_name; 

//Function Prototype 
void randomFunction(const randomStruct1 *in1, const randomStruct2 *in2, void *handle); 

//Global Variables 
//assuming data1-5 are of the correct types corresponding to randomStruct1, void, etc. 
myStruct_name myStruct_var = {data1, data2, data3, data4, data5}; 
void *handle = (void*)myStruct_var; 

void main(){ 
    myStruct_name *local_var = (myStruct_name *)handle; 
    //Other code here 
    local_var.var2 = randomFunction(&local_var.var1, &local_var.var4, &(local_var)); 
} 

:以下のコードの関連チャンクですポインタ)。 main関数では、変数local_varは変数myStruct_varを指しているポインターハンドルの値(myStruct_name型へのポインターとして型キャストされている)を指すstruct myStruct_nameへのポインターです。次に、関数randomFunctionは、var1だけのポインタ、var2のポインタ、変数local_varのポインタを入力として取ります。

私の混乱は、このです:入力ポインタは構造体と ヌル ジェネリックポインタを指すよう機能randomFunctionが必要です。 local_varがすでにポインタの場合、アドレス演算子(&)はなぜ必要ですか? local_varの値はすでにアドレスではありませんか?または、local_varが正しくないと何が起こっているのか、私の理解ですか?

また、randomFunctionへの最後の入力がカッコである理由はありますか?つまり、なぜ& local_varではなく&(local_var)ですか?かっこは何かしていますか?

お読みいただきありがとうございます。

EDIT:nullポインタを参照していないことを示す応答に感謝します。私はを参照しています。ここでは "データタイプ"は一般的です。

+0

ようこそスタックオーバーフロー。 [The Tour](http://stackoverflow.com/tour)を読み、[Help Center](http:// stackoverflow)の資料を参照してください。com/help/asking)ここで何をどのように聞くことができますか? –

+0

あなたは* nullポインタのコンセプトを読んでみたいと思います。*あなたの使い方は混乱しているようです。 – tofro

+1

_nullポインタ_定義点はどこにもありません。 'void *'と宣言するだけでは、ポインタをヌルポインタとして修飾しません。それで、どうしてタイプチェックをしないのですか?真実を必要とせずに 'void *'やキャストを使わないでください。 – Olaf

答えて

2

あなたの背景がJavaやその他の「安全な」言語で書かれている場合、ポインタは本当に頭を包むのが非常に難しいかもしれません。しかし、コアでは、メモリを扱っているだけです。

最初の質問 - なぜポインタのアドレスですか?

ここでは、再生できるサンプルコードを示します。 2つの方法で「浅い」スワップを実装しようとします。それだけで、スワップ2、アドレスにあった、1は何もしなかったスワップ

Before                             
Contents s1: 1 2 3 s2: 4 5 6                       
Contents p: 1 2 3 q: 4 5 6                        
Addresses: 0x60103c 0x601048 0x60103c 0x601048 0x7ffd29c58288 0x7ffd29c58280           
Swap 1                             
Contents s1: 1 2 3 s2: 4 5 6                       
Contents p: 1 2 3 q: 4 5 6                        
Addresses: 0x60103c 0x601048 0x60103c 0x601048 0x7ffd29c58288 0x7ffd29c58280           
Swap 2                             
Contents s1: 1 2 3 s2: 4 5 6                       
Contents p: 4 5 6 q: 1 2 3                        
Addresses: 0x60103c 0x601048 0x601048 0x60103c 0x7ffd29c58288 0x7ffd29c58280 

注:コンパイルと上記のコードを実行すると

#include <stdio.h> 

typedef struct {int x; int y; int z;} XYZ; 

XYZ s1 = {1, 2, 3}; 
XYZ s2 = {4, 5, 6}; 

void swap1(XYZ *a, XYZ *b); 
void swap2(XYZ **a, XYZ **b); 

int main() 
{ 
    XYZ *p = &s1; 
    XYZ *q = &s2; 

    printf("Before\n"); 
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z); 
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z); 
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q); 

    swap1(p, q); 

    printf("Swap 1\n"); 
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z); 
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z); 
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q); 

    swap2(&p, &q); 

    printf("Swap 2\n"); 
    printf("Contents s1: %d %d %d s2: %d %d %d\n", s1.x, s1.y, s1.z, s2.x, s2.y, s2.z); 
    printf("Contents p: %d %d %d q: %d %d %d\n", p->x, p->y, p->z, q->x, q->y, q->z); 
    printf("Addresses: %p %p %p %p %p %p\n", &s1, &s2, p, q, &p, &q); 

    return 0; 
} 

void swap1(XYZ *a, XYZ *b) 
{ 
    XYZ *t; 
    t = a; 
    a = b; 
    b = t; 
} 

void swap2(XYZ **a, XYZ **b) 
{ 
    XYZ *t; 
    t = *a; 
    *a = *b; 
    *b = t; 
} 

、あなたはこのような何かを得るでしょうスワップが起こったことが指摘されています。また、 s1s2は変更されていないことに注意してください。この関数を使用して、構造全体をコピーする必要のないソートを実装できます。

第2質問:なぜ&(local_var)&local_var

この違いは機能的に重要ではありません。以前の表現の残り物であったかもしれない、&ペースト、何でもカットしてください。たくさんの理由。

+0

ありがとう義民!ちょうど私の理解を家にハンマーをかける。 local_varはポインタであり、アドレス演算子(&)をlocal_varで使用すると、関連付けられたlocal_varのアドレスが関数randomFunctionに渡されますか?関数が何をしていても、 "ポインタのアドレス"データが渡されていますか? – MCHatora

+0

そうです、 'local_var'は構造体へのポインタで、'&local_var'は構造体へのポインタのアドレスです。 –