Home > database >  While swapping two values, the input of the function must be two const pointers and the return shoul
While swapping two values, the input of the function must be two const pointers and the return shoul

Time:04-02

I've written the code for passing the values normally with pointers My question is how to pass these values i.e. a & b as constant pointers, if it is not already.

void swap(int *x, int *y) 
    {
       int tmp;
       tmp = *x;
       *x = *y;
       *y = tmp;    
       return;
    } 
     
int main () {

   int a = 20;
   int b = 12345;
 
   printf("Before swap, value of a : %d\n", a );
   printf("Before swap, value of b : %d\n", b );
   swap(&a, &b);
   printf("After swap, value of a : %d\n", a );
   printf("After swap, value of b : %d\n", b );
 
   return 0;
}

CodePudding user response:

const in C generally goes after the type, and the * is part of the type, so the type declaration of an integer pointer constant is:

int * const

You may have tried int const *, and found that to not work. That's because, to repeat, generally const applies to the thing on its left.

Opinion: This is why I hate the pattern of writing const first, like const int. It only works because the language has a special case - if there is nothing to the left of the const, it applies to the thing on its right - and since most people learn by example, every occurrence of const at the beginning of a type declaration contributes to mis-teaching people trying to learn the language.

Tip: I like reading and saying const as "which is constant", because that phrase clearly refers to the thing before it, so it matches the left-to-right order of the parts of a type declaration: int const then reads as "an integer which is constant" and int * const reads as "an integer's address which is constant".

Putting that together with your swap function we get

void swap(int * const x, int * const y)

Opinion: This is also why I dislike * in a declaration "touching" the name. I do int * foo instead of int *foo because it's more consistent with other type declarations like int * const foo, which I feel is more important than consistency with the unary operator placement in dereferences like *foo.

But you should know that in C, or at least in all real and most conceivable implementations of C, it doesn't actually change code behavior to make function parameters const like that - the parameter itself is private to the function, so the function can't change it. The only way it could realistically make a difference for the actual code is if you had a C compiler which could better optimize a function if you tell it that it won't be modifying its own parameters, but most optimizing compilers can just notice if a parameter isn't being modified within a function. Of course, it can still be useful as a way of telling people reading your code what your intent with the parameters is, and if you have a habit of declaring things const any time you don't have specific intent to change them, you're more likely to have computers catch certain mistakes (like if you have a parameter named similarly to a variable in your function, and you mean to modify one but accidentally type the other - if the other was const, simple tooling can catch the mistake).

CodePudding user response:

Arguments are passed by value, and values are not const or non-const; only objects can be qualified that way. You can qualify the function parameters (which are objects that are initialized to the argument values), and that just means the function will not change the values of the parameters:

void swap(int * const x, int * const y)
{
    // x and y are not changed, although the objects they point to are changed.
    int temporary = *x;
    *x = *y;
    *y = temporary;
}

If you want to make the parameter types pointers to const objects, that is also possible. As long as a pointer points to an object that was not defined with const, the behavior of removing the const through a conversion and using it to modify the object is defined:

void swap(const int *x, const int *y)
{
    /* ncx and ncy are set to the original pointers to non-const
       that became the pointers to const that are x and y.
    */
    int *ncx = (int *) x, *ncy = (int *) y;
    int temporary = *ncx;
    *ncx = *ncy;
    *ncy = temporary;
}
  • Related