C语言 更改 c 指针值的正确方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13382065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:25:27  来源:igfitidea点击:

correct way to change values of c pointers

carrayspointers

提问by crispyfriedchicken

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 :(

抱歉,另一个 C 指针问题.. 我有一个函数 func() 对数组进行排序,然后获取最大和最小整数。我试图将它们放在 main() 中的指针变量中,但这些值仅在 func() 函数中是正确的。我不明白为什么:(

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

回答by Chris Hayes

When you pass a pointer as an argument to a function in C, a copyof the pointer is made. Thus, changing the value of the pointer has no effect outside of that function. However, changing the value at the memory referenced bythe pointer will take effect everywhere, as you want. In your case, you would need to do this:

当您将指针作为参数传递给 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);
}

Of course, the way you're using the pointers in mainis also incorrect; they're uninitialized and likely to cause a segmentation fault. Since there appears to be no reason to use actual int*variables over ordinary intvariables there, we can take another approach to passing them "by reference":

当然,你使用指针的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);
} 

Note that the term "by reference" here is not correct in the true sense of the phrase, since you are still receiving a copyof the address associated with the variable. Most languages provide a true by-reference faculty by removing this distinction and only allowing you access to the variable and its value, with the copying somewhat out of sight of the programmer. You can think of this as being "by reference with respect to land sinside main", in the sense that their values can change due to the called function.

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

回答by hmjd

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 sand lpointing to elements of the array arr. If you just wanted the values of integers then the alternative would be to define intvariables in main()and pass their addresses to func()and copy the relevent values from the array:

这将离开sl指向数组的元素arr。如果你只想要整数的值,那么另一种方法是定义int变量main()并将它们的地址传递给func()数组并从数组中复制相关值:

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 questionfrom the C FAQ.

请参阅C 常见问题解答中的此问题

回答by md5

Your pointers are not initialized. You have two solutions:

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

  • use integers in mainfunction (and eventually, although useless, make pointers point to them in the same function);
  • dynamically allocate memory for your pointer.
  • main函数中使用整数(最终,虽然没用,但在同一个函数中使指针指向它们);
  • 为指针动态分配内存。

Easiest code:

最简单的代码:

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

In the current code, you don't need to make land spoint to the case of the array. So, as Dan Fstated, you can just do integer's assignment.

在当前代码中,您不需要制作ls指向数组的大小写。所以,正如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);
}