4

ポインターminとmaxがポインターである場所を変更しようとしていますが、「変更」が関数のスコープ外に留まっていないようです(関数の実行後)。関数を実行する前に、*minと*maxを「doublem=0」を指すように設定しました。私は一種のNOOBなので、アドバイスをいただければ幸いです。

int min_max(double * min , double * max , int size , double a[]){                                                                       
int i;                                                                                                                                

printf("\n%lg\t%lg\n", *min, *max);                                                                                                   

min = &a[0];                                                                                                                          
max = &a[0];                                                                                                                          

for (i = 1 ; i < size ; i++) {                                                                                                        
 if (a[i] > *max)                                                                                                                    
  max = &a[i];                                                                                                                      
 else if (a[i] < *min)                                                                                                               
  min = &a[i];                                                                                                                      
 }                                                                                                                                     
 printf("\n%lg\t%lg\n", *min, *max);                                                                                                   
 return 0;                                                                                                                             
}
4

3 に答える 3

10

ダブルへのポインタを送信すると、そのダブルの内容を変更できるようになります。ポインタを変更する場合は、ポインタをポインタ()に送信する必要がありますdouble**。これにより、ポインタの内容を変更できます。

int min_max(double ** min , double ** max , int size , double a[]){  
    int i;                                                                                                                                

    printf("\n%lg\t%lg\n", **min, **max);                                                                                                   

    *min = &a[0];                                                                                                                          
    *max = &a[0];                                                                                                                          

    for (i = 1 ; i < size ; i++) {                                                                                                        
        if (a[i] > **max)                                                                                                                    
            *max = &a[i];                                                                                                                      
        else if (a[i] < **min)                                                                                                               
            *min = &a[i];                                                                                                                      
    }                                                                                                                                     
    printf("\n%lg\t%lg\n", **min, **max);                                                                                                   
    return 0;                                                                                                                             
}

ここですべての間接参照が行われているので、2つのローカルポインターまたはインデックスだけを保持し、ループの最後に1回戻り値を設定することが理にかなっている場合があります。

[編集]

関数内のポインターを変更できないのはなぜですか?代わりに、最小値と最大値を保持するために配列(ポインターのようなもの)を送信すると、たとえば、minmax [0] = min、minmax [1] = maxのように、値が変更されます。

まあ、ある種ですが、実際の値ではなく、最小値と最大値である配列要素へのポインタを求めています。したがって、それを実現するために配列を渡したとしても、それはポインターの配列である必要があります(double *minmax[2])。さて、これは実際には2つの値(それぞれ要素0と1としてインデックスを付ける)double**を指すだけです。double*だからそれは同じことです。

さて、なぜポインタを変更できないのですか?あなたはできる!ただし、変更は関数の範囲内に限定されます。ポインタは値によって渡されるため、呼び出し元で値を元に戻すことはできません。double*混乱させる前に、値渡しと参照渡しを読む必要があるかもしれませんが、一般的な考え方は次のとおりです。

関数に送信するデータ型はすべて効果的にコピーされます。したがって、を渡す場合double、その値は呼び出し元から新しいメモリ位置(関数のパラメーター)にコピーされます。関数は、その値の元の場所への参照を持たなくなりました。

void my_func( double val ) {
    val = 42;  // Does not affect caller's value because it was copied
}

double value = 1;
my_func( value );
// value is still 1

を渡す場合も同じですdouble*double値のアドレスを関数に送信していますが、実際のアドレス(ポインター)は、double*提供された関数にコピーされる値です。

void my_func( double* val ) {
    *val = 42;  // Stuff 42 into the memory location pointed to by 'val'.
}

double value = 1;
my_func( value );
// value is now 42

しかし、呼び出し元は、最大値と最小値の配列内の実際のアドレスを望んでいるように見えます(これがポインターに慣れていないために間違いであった場合を除く)。その場合、ポインタの内容をコピーしているため、ポインタだけでは不十分です。ここでは、ポインタを保持しているメモリのアドレスを取得して、それを関数に渡す必要があります。そのアドレスがコピーされ、それを参照すると、そのメモリ位置にポインタを書き込むことができます。

void my_func( double** val ) {
    *val = *val + 1;  // Change the pointer pointed to by 'val'.
}

double values[4] = { 1, 2, 3, 42 };
double *value = &values[2];         // value points to '3'.
my_func( &value );
// value now points to 42

関数によって変更したい値へのポインターを提供するときはいつでも、それは参照渡しと呼ばれます。

于 2012-09-06T21:45:28.533 に答える
3

あなたの機能は

int min_max(double ** min , double ** max , int size , double a[]);

呼び出しステートメントは

int *min,*max;
min_max(&min,&max,...);
于 2012-09-06T21:47:13.507 に答える
2

ポインターが指している場所を変更して、関数の外部でそれらの変更を確認することはできません。ポインターを渡したので、ポイントされているものを変更できますが、ポインター自体は値によって渡されます。コピーを変更するだけです。

ポインタ自体を変更するには、ポインタをポインタに渡す必要があります。

int min_max(double**, double**, int, double);
于 2012-09-06T21:45:01.187 に答える