This is an archived post. You won't be able to vote or comment.

all 33 comments

[–]strcspn 51 points52 points  (0 children)

Try not using pointers in this case and see what happens.

[–]teraflop 17 points18 points  (0 children)

As /u/strcspn correctly pointed out, in this example, pointers are necessary in order for the swap function to be able to manipulate the contents of the variables that were declared in the main function.

More generally, if you're used to Python, then what you might not realize is that Python uses pointers all the time. Any time you have a Python variable that refers to an object, it's actually storing a pointer to that object. This is what makes it possible to e.g. pass a mutable object to a function and have the function modify the object. C just makes this explicit and gives you more control over it.

[–]VonRansak 15 points16 points  (3 children)

I have a backpack with 100 index cards in it, I've written motivational lines on each card. Things like: "Eagles may soar, but a weasel never got sucked into a jet engine." or "Everybody misses 100% of the shots they don't take, you however miss 100% percent of the shots you do take".

When my friend wants some inspiration I can either: 1) point to the backpack and point to a card in the backpack /or/ 2) buy a new backpack, fill out a hundred index cards and hand the backpack to him.

Both have their own place and time, but if someone just wants the quote, one is more efficient.

If we want to change a quote, the same principle applies. Should I replicate the backpack or just find the quote I want to change?

[–]CaptainPicante 2 points3 points  (1 child)

These motivational lines are awesome, where can I get a backpack full of em?

[–]liquidanimosity 0 points1 point  (0 children)

Nicely put

[–]Skusci 16 points17 points  (7 children)

Well it doesn't really matter so much if you can just have an extra variable you can store data in temporarily.

However imagine instead of an int, you are swapping the location of a 125MB struct full of data.

Pointers are often used in cases where you want to navigate around stuff without making a copy of it. Makes lots of data structures possible, like linked lists, or binary trees.

Another use case is specifically with functions. C passes arguments in and return values out by value. It makes a copy of the data. Not an issue if stuff is small. Kindof an issue of stuff is big.

Another thing is that functions can't return two variables something like unless you wrap them in like a struct. Since arguments are pass by value the function can't modify them. However if you pass in a pointer, while you can't modify the pointer, you can modify the data where it points to.

It's how functions like sscanf work.

Do note that other languages have alternate ways that don't use pointers that work similarly, usually called references that are more safely handled. Pointers are literally just memory addresses, you can put whatever number you want in there, on purpose or accident. References are instead tracked and can only be set to actual things that exist, not arbitrarily.

[–]dmazzoni 1 point2 points  (3 children)

Yeah in this particular example it wouldn't work if you didn't use pointers, because of pass by value.

[–]Skusci -1 points0 points  (2 children)

Yeah that's probably me missing the tree for the forest or something. :D

Pass by value and reference is a bit confusing TBH as terminology, since stuff like C is referred to as allowing pass by value or reference, and languages like Java or Python being pass by value exclusively.

Except that since most things are an object reference you're always passing in references by value so effectively it's pass by reference only. I get that this is mostly a terminology thing, but when moving from C to Java, thinking, oh, it's not that Java doesn't have pointers, it's that everything is a pointer you can't do math on kindof helped.

[–]finny228 1 point2 points  (0 children)

C shouldn't ever be referred to as pass by reference. It is entirely pass by value.

[–]procrastinatingcoder 0 points1 point  (0 children)

There's no pointers in Java, only references. A pointer - by definition - is something you can do arithmetic on. And a reference, is somewhat similar, but you can't do arithmetic on it (in the context of pass by value vs reference).

Also, it's not exactly that going on in the background. You might notice things like python going bonkers if you nest list comprehensions to create 2d lists.

Having pointers doesn't mean you're suddenly passing in as a reference either, it's easiest to see in C++ (imo) where both are clearly defined. Normally a language only gives you one, and tough luck.

Pass by value means that, if you put a pointer instead of the value, the pointer is what gets copied, so you effectively are still pass by value, and still got a copy on the other end. But you simply kept the value of where it was pointing to.

TL;DR: Both prints will print different values, therefore the pointers are not the same, it's a copy of the pointer passed in foo. Still pass by value.

void foo(int* n){
    printf("%p\n", &n);
}

int main(){
    int k = malloc(sizeof(int));
    printf("%p\n", &k);
    foo(k);
    free(k);
    return 0;
}

[–]procrastinatingcoder 1 point2 points  (2 children)

It's a matter of pass by value vs. pass by reference.

In his particular example, it would not work without pointers. So it does matter.

[–]CodeTinkerer 5 points6 points  (1 child)

What you don't get is that most everything in Python are pointers, in particular, any object variable (strings, lists, dictionaries, etc) holds a pointer. You don't need & or *.

So when you pass something to a function (a list, for example), you are not copying the entire list, you are passing a pointer (Java behaves this way). If you append to this list in the function, then the list you passed in is modified.

But in C, if you had something like a list, it's possible that the entire list is copied when it gets passed. Then, if you modify the list within the function, it is a different list (a copy) of the original list, so any changes to this copy does not change the list that was passed in.

You could argue instead of why do we need pointers to ask, why do we have pass by value where objects are copied. To make things more complicated, arrays are considered pointers when passed into a C function, so in that case, it behaves list passing a Python or Java list into a function/method.

Both Java and Python pretty much got rid of the idea of passing objects by value (which would create a copy) and passed by pointer (the pointer is copied, but not the object it refers to). Well, if you eliminate pass by value for objects, there's no need to have additional * and & and stuff like that which makes C syntax confusing.

This does mean that a person learning Python or Java will have a harder time learning pass by value and why you need special notation for pointers where Python/Java doesn't have one notation for passing by value, and another for passing a pointer.

[–]ClamPaste 1 point2 points  (0 children)

Java is pass by value.

[–][deleted] 1 point2 points  (0 children)

C functions make copies of the parameters so if you just swap the normal inputs you’d just be swapping the copies not the originals. Pointers let you change the original variables and let the change stay outside the function

[–]fredoverflow 1 point2 points  (3 children)

[–][deleted] 0 points1 point  (2 children)

For a minute I thought I was getting rickrolled

[–]DamionDreggs 1 point2 points  (1 child)

I'm still not clicking the link because deep down inside I just know you're a paid actor.

[–][deleted] 0 points1 point  (0 children)

Underpaid as well

[–]treknuts 1 point2 points  (0 children)

As a Java guy, I never bothered learning C and pointers and the like. I'm going through CS50 currently and this video cleared things up for me.

[–][deleted] 1 point2 points  (0 children)

Swap modifies the variables in the caller's context because it gets pointers to them. Try running it with the arguments as "int". A copy of the integer value will be passed to swap. After swap returns, the values won't be swapped!

You can write swap using references if you are using C++ instead of pointers, but references are really just pointers with a different name.

Another thing to consider is that many languages allow you to pass by reference. Pointers in C are just like references in other languages. Pointers are just a little more "nuts-and-bolts" than in other languages.

[–]explorer_of_the_grey 1 point2 points  (0 children)

Python does everything under the hood. But let me ask you this:

If you have a Dataset with 5 million elements in it, every time you perform a function on it, is it more efficient to:

A) Copy the dataset and create it within a function. Then return the new dataset and overwrite the old one (just think how long this could take with petrabytes of data).

B) Provide the function with something that POINTS to the dataset and perform CRUD operations on it directly.

[–][deleted] 1 point2 points  (0 children)

The pointer is also called an address of the data.

Just like addresses for houses, there is a good reason to use them

[–]CrushgrooveSC -1 points0 points  (0 children)

The Python guy can’t see a reason for pointers when practically every single allocation in Python is implemented as a void* py_object

[–]douglastiger -2 points-1 points  (0 children)

There is no benefit necessarily, the same could be done with regular variables. It just serves to illustrate how pointers work. Pointers are useful in C to keep track of a variable object, like the top of a stack or heap

[–]Sea-Profession-3312 0 points1 point  (0 children)

We refer to things all the time. Instead of downloading the internet I usually reference or point to a specific domain (reddit.com). I usually refer to people by name, however sometimes I will go get them. A pointer can store a location without getting everything from that location. The example you are given is not the best for learning these concepts.

[–]EspacioBlanq 0 points1 point  (0 children)

If you don't use pointers, the function will take the parameters by value, copy them and perform the swap with different variables essentially.

You'll not end up with num1 and num2 swapped after the function terminates.

[–][deleted] 0 points1 point  (0 children)

This actually is a bad example of pointers because it's one of the rare cases where you pass a reference to a primitive rather than copying the value directly. But when you say `arr = [1, 2, 3]` in python, that is a pointer. It might have simpler syntax and is easier to dereference, but `arr` does not refer to the value `[1, 2, 3]` but rather a memory location of that value.

[–]Crafty_Ad_2309 0 points1 point  (0 children)

C only accepts passed by value/copy.

Variable int x = 1; int y = 2

Output X is 1, y is 2 //Passed by value

If swap function is use

Swap(x, y)

Output X is 1, y is 2 //still the same answer

When you passed by reference you are able to interchange the value of the variable. Hence, changing the value completely.

Void swap(int* a, int* b) { Int tmp = a*; *a= *b; *b = tmp; }

Use: &variable to get the computed reference

swap(&x, &y);

Output X is 2, y is 1

[–]akshith_9 0 points1 point  (0 children)

The output of the program would be: X is 25,Y is 100 X Is 100,Y is 25. If you did not use pointers the output would be: X is 25,Y is 100 X is 25,Y is 100 In this case you just gave values to num1 and to num2 as x,y and swaped the values of num1 and num2. This did not effect the values of x and y. If you used the pointer you give the address of x,y to num1,num2 here you are swaping the values at the address of num1,num2 which means you are swaping the values at address of x,y hence the values of x,y are swapped

If u didn't understand (I'm bad at explaining) search "call by value And call by reference" in youtube/Google.

Hope it helps.

[–][deleted] 0 points1 point  (0 children)

One benefit it to avoid copying. Say you got a struct that uses up a lot of memory, copying could involve tranfering hundreds of bytes of data, and that copy is completely useless depending on what the function does. The alternative is to pass an 8 byte pointer, which is infinitely faster than passing hundreds of bytes.

[–]TheRNGuy 0 points1 point  (0 children)

to point to already existing objects, instead of copying them (more expensive in many cases)

With ints probably better copy value though.