2011-10-12 45 views
3

ここをクリックしてください。シンプルなコードの断片を混乱させてポインタを学習/理解しようとしています。なぜこのCのポインタコードは機能しませんか?

#include <stdio.h> 

void swap(int *px, int *py) 
{ 
    int tmp; 
    tmp = *px; 
    *px = *py; 
    *py = tmp; 
} 

main() 
{ 
    int *a, *b; 
    *a = 1; 
    *b = 2; 
    swap(&a,&b); 
    printf("%d %d\n", *a, *b); 
} 

なぜ無効ですか?このコードは、逆参照演算子*をメインから削除すると動作します。

概念的には、これはうまくいくようです。私は、それぞれint 1int 2を指すポインターとしてabを初期化します。私はswap()に自分のアドレスを送って、それは彼らが指しているものに切り替えるべきです。

+0

http://publications.gbdirect.co.uk/c_book/chapter5/pointers.html – etuardu

+4

すべての警告を使用してコンパイルする場合(常にそうであるはずですが)、型変換の警告が必要です。なぜなら、 &aは 'int **'です。 –

答えて

11

いくつかの問題があります。まず、ポインタabが有効なメモリを指していない。したがって、整数値の代入は未定義です(クラッシュする可能性があります)。第2に、スワップ(aとbが有効なメモリを指していると仮定)がアドレスを含んではいけません(現在、ポインタ変数のアドレスを送信しています)。

次の変更は、それが仕事になるだろう:

int a, b; 
a = 1; 
b = 2; 
swap(&a,&b); 
printf("%d %d\n", a, b); 
+0

"ポインタaとbは有効なメモリを指していません"。なぜ彼らはint 1とint 2が格納されているメモリのいくつかの場所を指していないのですか? – babonk

+1

整数リテラル(1や2など)はメモリに格納されません。彼らには住所がありません。 –

+0

@babonk: '* a = 1'はメモリのビットを取り、そのメモリのビットに値 '1'を設定します。したがって、上記のプログラムで '1'がメモリを占有したとしても、あなたはそのメモリ位置を' a'に割り当てることを要求していません。そして、定数1はメモリを使いません。&1'は、定数1のアドレスを得ることは無効か、または未定義です。 –

0

あなたのメソッドのシグネチャが間違っています。あなたはintへの2つのポインタを要求しますが、intへのポインタへの2つのポインタを渡します。

6

swap()機能はOKですが、メインの内側に、あなたはポインタのアドレスを取っているので、あなたがint*パラメータにint**引数を渡しています。 main()にコードを置き換え、それを修正する

int *a, *b; 
swap(&a,&b); 

int a = 1, b = 2; 
swap(&a,&b); 
printf("%d %d\n", a, b); 
+0

明確にするために、私は誤って変数へのポインタの代わりにポインタへのポインタを送信していましたか? – babonk

+1

@babonk:正確に。 1つの間接レベルが多すぎます。 –

4

ポインタは、データを指します。ポインタ自体は記憶域用のメモリを備えておらず、既存のメモリを指しているだけです。したがって、int *a;を宣言すると、使用可能な値を持たないガベージ・ポインタがあるだけです。逆参照しないでください。

ポインタを使用する唯一の賢明な方法は、それらにアドレスの何か(またはいくつかの割り当て関数の結果)を割り当てることです:

int i; 
int *a = &i; // now a points to i 

したがって、あなたのスワップ機能を使用するための正しい方法を渡すことですそれは、整数のアドレスは:

int i = 10; 
int j = -2; 

swap(&i, &j); 
2

abは、彼らが未定義の動作を誘導するデリファレンス、初期化されていないポインタです。あなたがしたい:

int main() { 
    int a, b; 
    a = 1; 
    b = 2; 
    swap(&a,&b); 
    printf("%d %d\n", a, b); 
    return 0; 
} 
0

「私はスワップ()にアドレスを送って、彼らが指しているものを切り替えるべきだ」と言うとき。メインのポインタ変数内のアドレス値を変更しようとしていますが、それらが指しているメモリのビットを切り替えるのですか?その場合、あなたはリダイレクトの別のステップが必要になります。

#include <stdio.h> 

void swap(int **px, int **py) { 
    int *tmp; 
    tmp = *px; 
    *px = *py; 
    *py = tmp; 
} 

int main (void) { 
    int x, y; /* storage to point to */ 
    int *a, *b; 

    a = &x; 
    b = &y; 

    *a = 1; 
    *b = 2; 

    printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y); 
    swap(&a, &b); 
    printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y); 
} 

$ ./a.out 
(*a, *b, x, y) == (1, 2, 1, 2) 
(*a, *b, x, y) == (2, 1, 1, 2) 

x & y値が変更されていないが、axに指していたし、今bためyおよびその逆を指します。

関連する問題