Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

correct way to change values of c pointers

Tags:

arrays

c

pointers

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);
} 
like image 223
crispyfriedchicken Avatar asked Nov 14 '12 15:11

crispyfriedchicken


People also ask

How do I change the value of a pointer?

To update the value of a variable via pointer we have to first get the address of the variable and then set the new value in that memory address. We get the address via address of & operator and then we set the value using the value at the address of * operator.

What is the proper way to declare pointers?

The syntax of declaring a pointer is to place a * in front of the name. A pointer is associated with a type (such as int and double) too. Naming Convention of Pointers: Include a "p" or "ptr" as prefix or suffix, e.g., iPtr, numberPtr, pNumber, pStudent.

Can we change the value of this pointer in C++?

You can change the address value stored in a pointer.

Can you change the value of a variable in C?

In C or C++, we can use the constant variables. The constant variable values cannot be changed after its initialization.


3 Answers

When you pass a pointer as an argument to a function in C, a copy of 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 by the pointer will take effect everywhere, as you want. In your case, you would need to do this:

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 main is 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 int variables there, we can take another approach to passing them "by reference":

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 copy of 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 l and s inside main", in the sense that their values can change due to the called function.

like image 79
Chris Hayes Avatar answered Sep 22 '22 01:09

Chris Hayes


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.

like image 42
hmjd Avatar answered Sep 19 '22 01:09

hmjd


Your pointers are not initialized. You have two solutions:

  • use integers in main function (and eventually, although useless, make pointers point to them in the same function);
  • dynamically allocate memory for your pointer.

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 l and s point to the case of the array. So, as Dan F stated, you can just do integer's assignment.

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);
}
like image 27
md5 Avatar answered Sep 18 '22 01:09

md5