-3
#include <stdlib.h>
int swap(int a,int b);
int main() {
    int x,y;
    printf("Enter the first integer:"); scanf("%d",&x);
    printf("Enter the second integer:"); scanf("%d",&y);
    printf("\nBefore swap: x=%d, y=%d\n",x,y);
    swap(x,y);
    printf("After swap: x=%d, y=%d",x,y);
    
    return 0;
}

int swap(int a, int b){
        int temp;
        temp = a;
        a=b;
        b=temp;
}

This is my code to swap 2 integers entered by the user but it doesn't work although everything seems to be in order. However if I change my code to this using pointers, it does.

#include <stdlib.h>

int swap(int *,int *);
int main() {
    int x,y;
    printf("Enter the first integer:"); scanf("%d",&x);
    printf("Enter the second integer:"); scanf("%d",&y);
    printf("\nBefore swap: x=%d, y=%d\n",x,y);
    swap(&x,&y);
    printf("After swap: x=%d, y=%d",x,y);
    
    return 0;
}

int swap(int *a, int *b){
        int temp;
        temp = *a;
        *a=*b;
        *b=temp;
}

I would really appreciate if anyone could explain me why and how it worked with pointers but why it didn't without pointers.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 2
    C uses pass-by value. Imaging the horror if I call the function in the first case like `swap(5,10);` – Sourav Ghosh Sep 28 '20 at 13:45
  • 3
    Arguments are **copied** and modifications to copies won't affect originals. – MikeCAT Sep 28 '20 at 13:45
  • With pointer works because you are passing the memory address that some value is, that is why its work. When you pass by "value", you are passing a copy of the value, so, any changes inside the inner scope, will not reflect outside. – sgtcortez Sep 28 '20 at 13:49
  • @KadirDokur The point is rather that SO was never meant to an interactive beginner tutorial nor a replacement for studies, but rather a place for professional & enthusiast programmers. Yeah, it is OK to ask beginner-level questions here, but a bare minimum knowledge of the topic might be assumed. In this case, casting a glance at the mentioned chapter about functions in the C beginner-level book might reveal the answer, in a way that is more pedagogic and easy to understand than any haphazard answer posted here. – Lundin Sep 28 '20 at 14:07

5 Answers5

4

C uses something called pass-by-value. Basically, what happens here, is that the function that is called, in this case swap(), makes its own copies of the arguments that you passed when you called the function. So, when you modify the value of these parameters, namely a and b in the swap() function, you're modifying their value inside the swap() function only, since swap() made its own copy of the arguments.

Try this analogy: You missed a few lectures, and take your friend's notebook to update your notes. Now, suppose you made a few changes in your own notes. Do these changes carry over to your friend's notebook? Obviously not. Similarly, when using pass-by-value, changes made in one function won't have any effect outside the scope of that function.

When you're using pointers though, the values are passed by reference, that is, instead of the values, you're passing the address of the memory locations that holds these values. So, if you make changes to these memory locations themselves through the use of pointers, the values are changed permanently, and the changes are reflected in the caller function too.

sanskar10100
  • 41
  • 2
  • 3
  • 3
    C does not have "passing by reference". A variable's address is also just a value that happens to correspond to a location in memory. When you pass a pointer to a function, that pointer gets passed by value, same as an int would. The difference is, you can use the value of a pointer to access some memory address and thus modify the data stored there. – Randoragon Sep 28 '20 at 14:07
  • @Randoragon "C does not have passing by reference" is kind of a myth and incorrect at that. `void func (int x[10]);`, what is `x` in this case? It's certainly not an array passed by value, so it must be an array passed by reference. – Lundin Sep 28 '20 at 14:15
  • 1
    Nice answer, but agree with 1st comment. Some additional clarity on `C`s pass by value might be gained from reading [the conversation here](https://stackoverflow.com/questions/2229498/passing-by-reference-in-c), where I think this is one of the clearest quotes: _"In C, Pass-by-reference is simulated by passing the address of a variable (a pointer) and dereferencing that address within the function to read or write the actual variable. This will be referred to as `C style pass-by-reference.`"_ – ryyker Sep 28 '20 at 14:21
  • @Lundin Arrays get automatically casted to pointers when passing them to functions though, don't they? – Randoragon Sep 28 '20 at 14:22
  • @Randoragon A cast is something done implicitly by the programmer. In this case it gets "adjusted" silently and implicitly by the compiler. The syntax is such that we may use `x` like an array inside the function though, just as if it was passed by reference. Just as C++ references are nothing but glorified `* const` pointers. – Lundin Sep 28 '20 at 14:25
  • @Lundin Well no, if you write two functions, `void foo1(int arr[])` and `void foo2(int *arr)`, pass them both the same array and make them print `sizeof(arr)`, you'll see that in both cases only the size of the pointer gets printed. That is because in both functions the argument is treated as a pointer, not an array. See [this question](https://stackoverflow.com/questions/5573310/difference-between-passing-array-and-array-pointer-into-function-in-c) – Randoragon Sep 28 '20 at 14:39
  • @Randoragon Yeah because the array decay rule works like that. And so when you type `void foo1(int arr[10])` you get a pointer, or reference if you will. Nothing is passed by value, which was exactly my point. – Lundin Sep 28 '20 at 14:55
  • 1
    _"Nothing is passed by value, which was exactly my point"_... It is true @Lundin, that an array passed as a function argument decays to a pointer, but it is the _value_ of that pointer that is passed. The function knows the value passed is a pointer, and de-references it in order to access the object contained at that address. I realize all of this is semantics, but really you are taking a very non-idiomatic position here, which understandably will confuse people who are at the beginning of picking up this language. – ryyker Sep 28 '20 at 15:07
  • ...If you really want to continue with this idea at least clarify what that really means: eg. The _value_ passed is a _reference_ to the object being changed. (or some such thing.) Because truly, C does not have the ability to literally _pass-by-reference_. – ryyker Sep 28 '20 at 15:12
1

The first function that shall have the return type void because it returns nothing

void swap(int a, int b){
        int temp;
        temp = a;
        a=b;
        b=temp;
}

deals with copies of values of expressions used as arguments.

You can imagine the function definition and its call the following way

swap(x,y);

//...

void swap( /* int a, int b */){
        int a = x;
        int b = y;
        int temp;
        temp = a;
        a=b;
        b=temp;
}

That is within the function there are swapped the function local variables a and b. The original variables x and y declared in main stay unchanged.

In the second function definition the arguments x and y are passed to the function by reference

swap(&x,&y);

In C passing by reference means passing objects indirectly through pointers to them.

From the C Standard (6.2.5 Types, p. #20)

— A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’’. A pointer type is a complete object type.

So dereferencing the pointers (that themselves are passed by value) you get a direct access to the pointed objects that are changed within the function

void swap(int *a, int *b){
        int temp;
        temp = *a;
        *a=*b;
        *b=temp;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Actually, you qualify what you are saying about this pretty clearly. I am removing my previous comments, and will remove this one once you have indicated you've seen it. – ryyker Sep 28 '20 at 16:13
1

In C, every function parameter is passed by value. This means that within the function scope, every argument is just an independent copy of the actual variable being passed to the function. It is impossible to swap two integers by passing them, and not their memory addresses, to a function, because in the function body the values you swap no longer have any connection to the original "outside" variables, other than having the same value.

It is, however, very possible to do what you want without a function:

#include <stdlib.h>

int main() {
    int x,y,temp;
    printf("Enter the first integer:"); scanf("%d",&x);
    printf("Enter the second integer:"); scanf("%d",&y);
    printf("\nBefore swap: x=%d, y=%d\n",x,y);
    temp=x;
    x=y;
    y=temp;
    printf("After swap: x=%d, y=%d",x,y);
    
    return 0;
}

Alternatively, you can write a convenient macro to do that for you. It will behave in a similar fashion to a function:

#include <stdlib.h>

#define swap(x,y) do { \
    int temp=x; \
    x=y; \
    y=temp; \
    } while (0)

int main() {
    int x,y,temp;
    printf("Enter the first integer:"); scanf("%d",&x);
    printf("Enter the second integer:"); scanf("%d",&y);
    printf("\nBefore swap: x=%d, y=%d\n",x,y);
    swap(x,y);
    printf("After swap: x=%d, y=%d",x,y);
    
    return 0;
}

This works and is quite elegant, but be aware that it is not a function and there are possible downfalls to using macros in this way.

Randoragon
  • 98
  • 1
  • 5
0

I would advise looking at the differences between pass-by-reference and pass-by-value on google, but I will summarize here.

Passing by value is when you give a value to a function directly, this value is copied to the function's scope at call. Passing by reference is when, instead of passing the value of a variable, you pass a pointer to the variable.

E.g. :

void foo_by_value(int i) {
    // i is now stored in the int in the function's scope, it is not in any way affiliated with the variable or constant used to call the function
    
    i++; // This will only update the value of i inside this function
}

void foo_by_reference(int* i) {
    // i now holds the value of the memory address to an int. You are passing the pointer by value to obtain the variable by reference

    (*i)++; // This will update the value of the variable passed to the function
}

Hope that helped clear some stuff up!

Emily-TTG
  • 531
  • 3
  • 18
  • 3
    Technically, C only has pass-by-value. Even pointers works that way, even though they simulate pass-by-reference. C++ has both pointers and pass-by-reference. – klutt Sep 28 '20 at 14:01
  • `*i++;` won't update the pointed value because `++` is applied before `*` is applied. `(*i)++;` will update the pointed value. – MikeCAT Sep 28 '20 at 14:02
  • @MikeCAT Ah that's a typo on my part. TY – Emily-TTG Sep 28 '20 at 14:04
  • Thank you for the explanation. I now realized I need to get a prior knowledge on ''pass by value'' and ''pass by reference'' topics. – Celil Hanci Sep 28 '20 at 14:05
  • @klutt That's what I said in the reference part - you are passing a pointer by value to get a variable by reference – Emily-TTG Sep 28 '20 at 14:05
  • @klutt You are wrong and are mixing terms used in C and C++. C has its own mechanism of passing by reference through pointers. It is not necessary that a language would define an entity named reference to have a mechanism of passing by reference.. – Vlad from Moscow Sep 28 '20 at 14:05
  • @VladfromMoscow to be fair, passing by reference is a more abstract topic as you are ultimately passing a pointer by value. But if you say pass-by-reference people will understand what you mean – Emily-TTG Sep 28 '20 at 14:07
  • @VladfromMoscow Are you sure about that? I had a look at this question https://stackoverflow.com/questions/2229498/passing-by-reference-in-c and the answers there does not seem to support your claim. – klutt Sep 28 '20 at 14:08
  • @klutt There are many answers of .low-qualified programmers that are upvoted. Passing by reference is a general mechanism of accessing directly objects instead of copies of their values. And such a mechanism can be implemented differently in different languages using their own terms. – Vlad from Moscow Sep 28 '20 at 14:12
  • @VladfromMoscow Hmmmm, I'm gonna do some research :) – klutt Sep 28 '20 at 14:19
0

You can also use macro for that

#define SWAP(type,x,y) do {type t_e_m_p___ = (x);(x) = (y); (y) = t_e_m_p___;} while(0)

int main(void)
{
    double d1 = 5.9,d2 = 7.4;
    SWAP(double, d1, d2);
    printf("Swapped: %f, %f\n", d1,d2);
}

No pointers needed

0___________
  • 60,014
  • 4
  • 34
  • 74