C - 将指针传递给函数

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

2
你应该拥有指向指针的指针,即传递指针的地址。 - Basile Starynkevitch
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])。现在,那实际上只是指向两个double *值(分别作为元素0和1进行索引)的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* 中的值。请注意保留 HTML 标签。
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

无论何时你提供一个指向值的指针,你希望这个值被函数改变,这被称为按引用传递。

为什么我不能在函数中更改指针呢?如果我发送一个类似指针的数组来保留最小值和最大值,比如minmax[0]=min,minmax[1]=max,那么值就会改变,对吧? - csta

3
您的函数应该是:
int min_max(double ** min , double ** max , int size , double a[]);

调用语句应该是

int *min,*max;
min_max(&min,&max,...);

2

您不能更改指针所指的位置并在函数外部看到这些更改。由于您传递了指针,因此可以更改指向的内容,但指针本身是按值传递的:您只能更改副本。

要更改指针本身,您需要传递指向指针的指针:

int min_max(double**, double**, int, double);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接