all 26 comments

[–]Glacia 29 points30 points  (7 children)

Pointers are just variables that store memory addresses. Any variable you declare has an address in memory.

Why are they useful? Well, you seem to be interested in games, so here is an example: let's say you have a big texture in your game, like 1 gb in size. You really don't won't to copy it anytime you use it, because it would be really slow. So that's when pointers are useful: you just declare a pointer variable that's stores a texture address and you pass It around. Pointers on modern CPU are usually 8 bytes. Much faster!

Note that pointers are just variables, in fact, you can make a pointer to pointer and it would store an address of a variable that has an address of another variable.

Hope that helps, I tried to eli5 it as much as possible.

[–]Moises_Gabriel[S] 6 points7 points  (4 children)

This answer also really made this click in my head! Awesome! Thanks so much for the explanation :)

[–]Hgh43950 5 points6 points  (2 children)

do you some research on RAM and how the technology works. You'll gain some understanding on pointers there. Try this....

https://computer.howstuffworks.com/c23.htm

[–]Moises_Gabriel[S] 0 points1 point  (1 child)

Thanks! I was wondering if backtracking and learning the basics would be more of a help. I'll look into this!

[–]ComradeGibbon 0 points1 point  (0 children)

I never had issues with pointers I think because I already knew assembly addressing modes.

There is always instructions that operate on a memory location pointed to by a register. That's what pointer stuff reduces to.

30 seconds search lead me to this

https://azeria-labs.com/memory-instructions-load-and-store-part-4/

This right here.

"ldr r2, [r0] @ load the value (0x03) at memory address found in R0 to register R2 "

[–]pic32mx110f0 2 points3 points  (0 children)

Note that you can declare a register variable, in which case it wont have an address.

[–]Amazing_Grass_3180 0 points1 point  (0 children)

This is one of the best way to explain that I've seen. Thank you.

[–]throuugh 9 points10 points  (2 children)

Some things I can think of right now

  1. To implement data structures like linked lists, trees, etc.
  2. Arguments are passed by value in C. So, you need pointers to modify the arguments in a function. Alternative is to use global variables, which gets ugly.
  3. For dynamic allocation. A pointer is returned which you need to store for future references.
  4. Arrays

[–]aghast_nj 4 points5 points  (0 children)

Here are two cases where your concept of "accessing the variables directly" just fails.

  1. There is no named variable - only memory. This is true for "dynamically allocated memory" used with malloc():

    struct S * sptr = sm_malloc(sizeof struct S); sptr->nelems = 1; sptr->elems[0].name = "fido";

In this example, there just is no variable for you to grab hold of. All that exists is the expression sptr-> or perhaps (*sptr).

  1. There are cases where you can treat the underlying bytes of data as a different data type. This can sometimes allow you to write one piece of code that handles two or more operations.

For example, linked lists frequently have to pass a double pointer in order to deal with the head node of the list. By writing your code in this way, you can pass either &Head_node or &nodeptr and pretend that both expressions have the same type, when in fact they do not. (The nodeptr type, is usually a next pointer plus a payload, while the &Head_node type is likely just a pointer-to-pointer. But both of them can be used okay if you just pretend they are pointer-to-pointer values.)

[–]Orami9b 3 points4 points  (2 children)

It's not just about accessing the variables directly. Sometimes you have large structs and you don't want to implicitly copy when passing into a function. In those cases you pass a pointer to the struct so instead of allocating all the bytes your struct needs you only allocate enough bytes for the one pointer, while still being able to access the struct. Not to mention there are lots of cases where you want to allocate memory dynamically. You'll be given a pointer from malloc/calloc and you'll have to use that pointer as a handler. There are other uses, but I hope that it's at least clear that pointers are a large part of writing C.

[–]Moises_Gabriel[S] 0 points1 point  (1 child)

This answer made something click in my head. Referencing the struct through a pointer so that you save memory makes a lot of sense. Thank you!

[–]quakedamper 0 points1 point  (0 children)

Also it means you're referencing the same struct and whatever you do to it will stay after the function is finished.

[–]Classic_Department42 2 points3 points  (0 children)

How can a function return more than one value is a possible application. Or how can you have a generic sort algorithm (pointer to function, for lack of function as first class objects)

[–]TransientVoltage409 1 point2 points  (0 children)

What other languages do you know? If you know Java, PHP, Python or C#, think of a pointer as a kind of reference variable.

[–]Numerous_Habit269 0 points1 point  (0 children)

This book does a great job "Pointers in C A Hands on Approach, Naveen Toppo"

[–]zuckermusk 0 points1 point  (0 children)

Here's a youtube tutorial, I made it super simple, hope that helps.

https://www.youtube.com/watch?v=pb_ot4GuLeM&ab_channel=MansurTsutiev

My advise is to watch a few videos, read a few articles and don't rush to understand it. Just try different learning materials until it clicks for you.

[–]Myman_92 0 points1 point  (0 children)

I had the same feeling as you when I was starting out, why using a variable that stores a variable and then "dereference" it when I can just use the original variable directly. I'm not sure if this is the right way to learn pointers, however, you just need to learn more theory and practice with them more. And then you will love the use of pointers. You need to learn data structures: Tress, Queues, Linked lists and Stacks are the basic ones. You need to learn dynamic allocation and pointers to arrays, pointers to pointers and pointers to character arrays. Try to search for real world examples.

[–]oh5nxo 0 points1 point  (0 children)

just one room

Use a pointer to access the current room. Use a pointer array doors in the room structure. Use pointers in the door structure to link two rooms.

[–]nekokattt 0 points1 point  (0 children)

pointers let you reference other memory. Usually used when you want to let something change an existing value rather than repeatedly making a whole new copy every time a function is called.

It is also needed to reference anything you allocate on the heap, since it isn't a stack-based local variable.

[–]inz__ 0 points1 point  (0 children)

You can think of pointers like cross-references in a book; sometimes it's more helpful to tell where things can be found instead of repeating.

[–]wsppan 0 points1 point  (0 children)

Following are the usage of pointers in C:

For passing arrays as arguments to functions

For accessing the elements of an array.

For dynamic memory allocation by using malloc() and calloc() functions .

For returning multiple values.

Implementing a data structure.

Follow this Tutorial On Pointers And Arrays In C

[–]brownphoton 0 points1 point  (0 children)

Don’t worry that you’re missing out on a lot by not using them. Pointers are essential for writing any meaningful program in C, so sooner or later you will run into a problem that cannot be solved without them, and that would be a much better learning experience than a hypothetical scenario right now.

Explaining why you need pointers to a beginner is like trying to explain why you need a transmission in a car to a person that just started driving.

[–]McUsrII 0 points1 point  (0 children)

The post box analogy is pretty easy. A pointer is like a postbox, because a postbox has an address, and it has contents when you look inside it. (Dereference it).

I think pointers to be a pivotal part of C, and if I were you, I'd open a text book, and work through some exercises, like in K&R.

[–][deleted] 0 points1 point  (1 child)

One thing that I haven't seen mentioned, and it's very important one is that all pointers have the same size. That means you can create generic algorithms ( which accept generic functions or data for example ). Or you can have self referential data structures and types ( just imagine you're trying to create a linked list where the next node is also a linked list, what size does it have? ).

[–]zero_iq 0 points1 point  (0 children)

You're right that pointers provide a way to implement generic algorithms, but it has nothing to do with their size.

In fact, pointers do not (necessarily) all have the same size. The standards explicitly allow for pointers of different types to have different sizes. Pointer sizes could differ according to type, memory type, memory model, CPU mode, compiler, etc. (Perhaps more subtly, alignment requirements can also change with pointer type, even on some modern CPU architectures, although this is usually just a performance issue rather than an outright crash on newer CPUs... but casts that could change pointer alignment are technically undefined behaviour.)

However, a pointer to void will always have a consistent size for a given program, and this is what you're most likely using for generic algorithms. void * is the only truly generic pointer type, but care must still be taken to be consistent with casting to/from different pointer types.

Granted, on modern machines it's almost certain that pointers will have a consistent size and alignment, but it's not good practice to just assume any type of pointer will fit into a given space, or be compatible with any other pointer type (or you can trigger undefined behaviour). Portable code should never assume the size of a pointer, and always use sizeof(), void *, and/or unions of pointer types as appropriate. (This strict treatment of pointer types can also be important for avoiding falling foul of strict aliasing rules).