我很难使用按引用传递

I'm having a hard time using pass by reference

我不知道为什么当我尝试进行引用传递时,我的代码中总是出现错误,以便使用递归查找整数的最大数目。

我的代码在按值传递时可以工作,但在按引用传递时我没能正确执行。


我的主要:

#include <stdio.h>
#include <math.h>

void largest_digit(int* digit);

int main() {
   int num;

   printf("\nPlease enter a number ");
   scanf("%d", &num);

   largest_digit(&num);
   printf("The largest digit = %d\n", num);

   return 0;
}

我的函数:

void largest_digit(int* digit) {
   int hold, hold1;

    if(*digit == 0 || *digit < 0) {
        *digit = 0;
        *digit;
        return;
    }

    // If-statement with Recursion.
    if(*digit > 0){
        hold = *digit % 10;
        hold1 = largest_digit(*digit/10);

        if(hold > hold1) {
            hold = *digit;
            *digit;
            return;
        } else {
            hold1 = *digit;
            *digit;
            return;
        }
    }
}

你说你是通过引用传递它,但你只是想在这里通过值传递它

hold1 = largest_digit(*digit/10);

用*digit/10创建一个新的int并将地址传递给largest_digit

int hold1Temp = *digit/10;
hold1 = largest_digit(&hold1Temp);

编辑:你的函数应该是这样的:

void largest_digit (int* digit)
{
  if (*digit <= 0) return; // if there's no more digit to compare, stop
  int currentDigit = *digit % 10; // if you receive 982, it gets the 2
  int nextDigit = *digit/10; // if you receive 982, it turns into 98
  largest_digit(&nextDigit); // does the same thing again
  *digit = currentDigit > nextDigit ? currentDigit : nextDigit; // chooses the biggest digit
}

你的麻烦在于,除了 *digit 为负的情况外,你从未真正设置 *digit。每次执行此操作时:

*digit;

上面只是取消引用指针并查找值,但实际上并没有更改它。您需要在每个 return 路线上做的是实际 设置 值:

*digit = ...something...;

如果不在任何地方设置此值,main() 函数中 num 的值实际上永远不会改变。

此外,您将 largest_digit 视为具有 return 值,但它没有:

hold1 = largest_digit(*digit/10); // <- assigning the return value does not make sense

首先有几件事:

  1. 指针上使用的一元间接运算符(*)的意思是“看看它指向什么”。因此,单独使用 *digit; 语句没有任何用处。你可以很好地将它从你的代码中删除(我看到你多次使用它),也许你打算做一个任务?语句*digit = X;是赋值,修改指针指向的数据。

  2. C中不存在“按引用传递”,只能按值传递。该值虽然可以是指向另一个值的指针,这就是您“模拟”通过引用传递某些内容的方式。

  3. 声明为 void f(...) 的函数没有 return 任何值。因此,将这样一个函数的“return值”赋给一个变量是没有意义的。


现在,考虑以上:

您的调用 largest_digit(*digit/10) 不是传递指针,而是取消引用指针 digit,将值除以 10,然后将其作为参数传递。正如您已经想到的那样,这是错误的。要在您的情况下正确地通过引用传递,您需要修改 digit 指向的原始值,或者创建一个新值并传递其地址。

无论如何,为这种递归函数传递一个指针(而不是直接传递值)没有多大意义,只是一个复杂的转折,除了让你的生活更艰难之外,没有多大作用。使用普通值作为参数。

int largest_digit(int num) {
    if (num < 0)
        return largest_digit(-num);

    if (num == 0)
        return 0;

    int cur = num % 10;
    int next = largest_digit(num / 10);

    if (cur > next)
        return cur;

    return next;
}

int main(void) {
    printf("%d\n", largest_digit(1923)); // 9
    printf("%d\n", largest_digit(4478)); // 8
    printf("%d\n", largest_digit(-123)); // 3
}

注意:为简单起见,如果数字为负数,上述函数还通过调用 largest_digit(-num) 来处理负数,因此它仅支持负数 INT_MIN+1(即没有正确处理INT_MIN)。

前面有人说过,largest_digit函数是void的,调用时不能赋值给变量。您可以做的是在调用之前修改 *digit,然后将 *digit 的值分配给您想要的值,在本例中为 hold1.

另一件事是你需要在返回之前将值保存到*digit中,例如,而不是做hold = *digit,你应该做*digit = hold.

以下是建议的修改:

void largest_digit(int* digit) {
   int hold, hold1;

    if(*digit == 0 || *digit < 0) {
        *digit = 0;
        return;
    }

    // If-statement with Recursion.
    if(*digit > 0){
        hold = (*digit) % 10;
        (*digit) /= 10;
        largest_digit(digit);
        hold1 = *digit;

        if(hold > hold1) {
            *digit = hold;
            return;
        } else {
            *digit = hold1;
            return;
        }
    }
}

有了这条主线,

int main() {

   int a=123, b=652, c=3274;
   largest_digit(&a);
   largest_digit(&b);
   largest_digit(&c);
   printf("%d\n",a);
   printf("%d\n",b);
   printf("%d\n",c);

   return 0;
}

输出是

3
6
7