6

Sorry, another C pointer question.. I have a function func() that sorts an array, then get the largest and smallest integers. I'm trying to put them inside pointer variables in main() but the values are only correct inside the func() function. I don't understand why :(

#include <stdio.h>

void func(int arr[], int *s, int *l, int n){
    int i = 1;
    for(; i < n; i++){
        int temp = arr[i];
        int n = i;
        while( n > 0 && arr[n-1] > temp){
            arr[n] = arr[n-1];
            n--;
        }
        arr[n] = temp;
    }
    l = &arr[n-1];
    s = &arr[0];\
    printf("%d %d\n",*l,*s);
}

int main(void){
    int arr[] = {1,2,9,3,58,21,4};
    int *s, *l;
    int size = 7;
    func(arr,s,l,size);
    printf("%d %d\n",*l,*s);
} 
4

3 回答 3

10

当您将指针作为参数传递给 C 中的函数时,会生成指针的副本。因此,更改指针的值在该函数之外没有任何影响。但是,更改指针引用的内存中的值将在任何地方生效,如您所愿。在您的情况下,您需要这样做:

void func(int arr[], int *s, int *l, int n){
    // sorting code..
    // l = &arr[n-1]; WRONG - these change the value of the pointer,
    //s = &arr[0];\   without changing the value of the memory they reference

    *l = arr[n-1]; // CORRECT - changes the value at the referenced memory
    *s = arr[0];
    printf("%d %d\n",*l,*s);
}

当然,您使用指针的main方式也不正确;它们未初始化,可能会导致分段错误。由于似乎没有理由在那里使用实际int*变量而不是普通int变量,我们可以采用另一种方法“通过引用”传递它们:

int main(void){
    int arr[] = {1,2,9,3,58,21,4};
    // int *s, *l; WRONG - we don't need pointers, we need to pass regular ints
    int s, l;
    int size = 7;
    // Get the address of our variables with the address-of (&) operator
    // This effectively creates int* variables out of our int variables
    func(arr, &s, &l,size);
    printf("%d %d\n",*l,*s);
} 

请注意,此处的“通过引用”一词在该短语的真正意义上是不正确的,因为您仍会收到与变量关联的地址的副本。大多数语言通过消除这种区别并只允许您访问变量及其值来提供真正的按引用功能,而复制在程序员的视线之外。您可以将其视为“通过相对于ls内部的引用main”,因为它们的值可能会因调用的函数而改变。

于 2012-11-14T15:47:48.310 回答
5

You need to pass the address of the pointer variables if you want to change what they are pointing at, otherwise a copy of the pointer variable is being changed inside the function (and is why it is correct within the function):

void func(int arr[], int** s, int** l, int n){
    /* snip */

    *l = &arr[n-1];
    *s = &arr[0];
}

func(arr, &s, &l, size);

This would leave s and l pointing to elements of the array arr. If you just wanted the values of integers then the alternative would be to define int variables in main() and pass their addresses to func() and copy the relevent values from the array:

void func(int arr[], int* s, int* l, int n){
    /* snip */

    *l = arr[n-1];
    *s = arr[0];
}

int s, l;
func(arr, &s, &l, size);

See this question from the C FAQ.

于 2012-11-14T15:46:18.423 回答
1

您的指针未初始化。你有两个解决方案:

  • 在函数中使用整数main(最终,虽然没用,但在同一个函数中使指针指向它们);
  • 为指针动态分配内存。

最简单的代码:

#include <stdio.h>

int main(void)
{
    int arr[] = {1, 2, 9, 3, 58, 21, 4};
    int s, l;
    int size = 7;
    func(arr, &s, &l, size);
    printf("%d %d\n", l, s);
} 

在当前代码中,您不需要 makels指向数组的大小写。所以,正如Dan F所说,你可以只做整数的赋值。

void func(int arr[], int *s, int *l, int n)
{
    int i = 1;
    for(; i < n; i++){
        int temp = arr[i];
        int n = i;
        while( n > 0 && arr[n-1] > temp){
            arr[n] = arr[n-1];
            n--;
        }
        arr[n] = temp;
    }
    *l = arr[n-1];
    *s = arr[0];
    printf("%d %d\n", *l, *s);
}
于 2012-11-14T15:43:31.440 回答