【问题标题】:Question about how pointers work in C with a problem关于指针在 C 中如何工作的问题
【发布时间】:2021-12-05 13:59:00
【问题描述】:

我正在为 C 中的类解决一个问题,我从未排序的数组中返回最大值,并且该值的索引存储在指针 index_ptr 中。

这是我构建的代码:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int max = array[0], index;
    for (int i = 0; i < array_size-1; i++){
        if (array[i+1] > max){
            max = array[i];
            index = i;
        }
    }
    index_ptr = &index;
    printf("idx: %d\n", *index_ptr); //purely for testing
    return max;
}

我知道上面的工作是为了返回最高值,但在这种情况下运行它:

int main() {
    int arr[5] = {4, 7, 3, 9, 5};
    size_t arr_size = 5;
    int *idx;
    printf("biggest value in array arr => %d\n", get_biggest_index(arr, arr_size, idx));
    printf("idx of biggest value => %d", *idx);
    return 0;
}

输出是:

idx: 3
max value in array arr => 9
idx of max value => -98693133

有人可以具体解释一下为什么会在指针的值方面发生这种情况以及如何解决它吗?

我也很乐意听取有关其余代码的任何其他建议,因为我相信它会更好。

非常感谢您的帮助!

【问题讨论】:

标签: c pointers integer output


【解决方案1】:

变量indexget_biggest_index 函数内的本地。它的生命周期将在函数返回时结束,任何指向它的指针都将失效。

虽然这不是问题,因为index_ptr 也是一个局部变量,当函数返回时它的生命周期结束时,其值将丢失。

问题是你误解了在 C 中模拟传递引用的工作原理。你不应该传递一个指针,让它指向函数中的一个变量。相反,您应该在调用中使用指向运算符&amp; 来传递指向现有变量的指针。然后在函数中解引用指针来设置原始变量的值。

类似这样的:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int index;

    // ...

    *index_ptr = index;  // Set the *value*

    // ...
}

并将其称为:

int idx;  // Not a pointer
get_biggest_index(arr, arr_size, &idx);  // Pass pointer to the idx variable

【讨论】:

  • 非常感谢您的帮助,我现在明白我的问题所在了。完美运行:)
【解决方案2】:

您应该将index 的值而不是index 的地址分配给index_ptr。您应该在 8 行中将 index_ptr = &amp;index; 替换为 *index_ptr = index。把指针想象成一个桶。如果你在它前面加上*,你将访问存储桶的内容。

在您的特定情况下,您将存储桶发送到一个函数,并希望用最大数字的索引填充它。当您执行index_ptr = &amp;index; 时,您将用另一个存储桶替换原始存储桶并将原始存储桶留空。

正确的代码应该是:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int max = array[0], index;
    for (int i = 0; i < array_size-1; i++){
        if (array[i+1] > max){
            max = array[i];
            index = i;
        }
    }
    *index_ptr = index; // this is correct
    printf("idx: %d\n", *index_ptr); //purely for testing
    return max;
}

【讨论】:

  • 非常感谢您的帮助,我现在明白我的问题了 :)
【解决方案3】:

int *index_ptr 是函数的局部变量。它不会返回给调用者,因此index_ptr = &amp;index; 没有任何意义。此外,您不能将返回的指针指向局部变量的地址,因为当函数完成时,局部变量会超出范围。

一个更明智的功能是:

int* get_biggest_index (size_t size, int array[size]){
    int* result = NULL;
    int max = INT_MIN;
    for (int i = 0; i<size; i++){
        if (array[i] > max){
            max = array[i];
            result = &array[i];
        }
    }

    return result;
}

如果大小为零,这不会越界访问数组。出错时返回 NULL,否则返回最大项的指针。它指向传递的数组,因此它不引用局部变量。返回的指针按值复制给调用者。

【讨论】:

  • 谢谢你的解释,没想到越界的情况。
【解决方案4】:

对于索引,使用size_t 类型(不是int)。保持一致。

int get_biggest_index(int *array, size_t array_size, size_t *index_ptr){
    int max = array[0];
    *index_ptr = 0;
    for (size_t i = 1; i < array_size; i++){
        if (array[i] > array[*index_ptr]){
            *index_ptr = i;
        }
    }
    printf("idx: %zu\n", *index_ptr); //purely for testing
    return array[*index_ptr];
}

【讨论】:

  • 非常感谢您的意见,我同意您的观点,但论点及其类型是由教授定义的,所以我只需要使用它。
猜你喜欢
  • 2014-05-13
  • 1970-01-01
  • 2023-01-08
  • 2011-02-01
  • 2021-10-29
  • 1970-01-01
  • 2022-01-05
  • 2017-08-10
  • 1970-01-01
相关资源
最近更新 更多