4

我正在尝试更改指针 min 和 max 指向的位置,但似乎“更改”并未超出函数的范围(在函数运行后)。在运行函数之前,我将 *min 和 *max 设置为指向“double m = 0”。我是一个菜鸟,所以任何建议都将不胜感激。

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;                                                                                                                             
}

由于此处进行了所有取消引用,因此保留两个本地指针甚至仅保留索引并在循环结束时设置一次返回值可能是有意义的。

[编辑]

为什么我不能更改函数中的指针?如果我改为发送一个数组(类似指针的东西)来保留最小值和最大值,比如 minmax[0]=min 和 minmax[1]=max,这些值会改变,不是吗?

好吧,有点,但是您要求的是指向最小值和最大值的数组元素的指针,而不是实际值。因此,即使您传递了一个数组来实现这一点,它也必须是一个指针数组(double *minmax[2])。现在,这实际上只是 adouble**指向两个double*值(您分别索引为元素 0 和 1)。所以这是一样的。

现在,为什么不能更改指针?你可以!但是您的更改仅限于您的功能范围内。您不能在调用者处将值更改回,因为double*指针是按值传递的。在我让您感到困惑之前,您可能需要先阅读一下按值传递和按引用传递,但总体思路是这样的:

您发送给函数的任何数据类型都会被有效地复制。因此,如果您传递 a 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 回答