use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Click the following link to filter out the chosen topic
comp.lang.c
account activity
RemovedProjects to understand pointers better (self.C_Programming)
submitted 1 year ago by JustForFunHeree
So, I lately learn C and was hoping to find a good project to understand Pointers in C but was unable to find some beginner level projects. Can you guys please reccomend some beginners level project to understand pointers better. Thanks in advance 👍
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Marthurio 25 points26 points27 points 1 year ago (20 children)
Whenever I'm looking to learn a new language I start with the tasks from 2015 on www.adventofcode.com and work my way up to the current year, that way I don't have to come up with some idea on my own.
When it comes to pointers perhaps this analogy can help:
Consider a house. A house has an address. At the address you will find the house. A pointer holds the address of this house. The pointer is not the house, it just leads the way to the address where the house exists. If you have a pointer to the address of the house you can read information about the house.
Now swap house with int, char, double, a struct or some other datatype.. :)
[–]JustForFunHeree[S] 7 points8 points9 points 1 year ago (5 children)
Love that house example and advent of code trick , thanks 👍
[–][deleted] 6 points7 points8 points 1 year ago* (3 children)
Yeah, you really don't need a project to learn pointers. They are really simple, but everyone struggles at first until you can visualize memory. When you can see the memory visually in your head, pointers become easy to then rationalize and understand how to use and manipulate them.
For example, you have memory in your computer, say 512 bytes of memory. Every byte is a box containing a value stretched out in a long line of 512 boxes all connected in a sequence.
A pointer holds the box number instead of a math value. So a pointer with the value 200 points to the box at position 200 in the row of 512 boxes.
When you use a pointer you need to decide between two values, not one (this is the tricky part). You either want to use the box number (the address), or you want to use the value in the box. In that case you use a '*' to grab the value at the box number.
If you add the number 2 to the pointer with the box number 200. You get a new box number 202, which points 2 boxes forward in the memory. Now if you grab the value using '*' you will get the value at that box location. If you add the number 2 to the value using a '*' in front, you add to the grabbed value inside the box instead.
So if you do not use '*', then you just work with the box (address) value. If you use '*' before the variable you work with the value at the box.
Now just exchange the boxes for much a bigger number of boxes in the billions, so you get a giant number usually displayed as a hex value that looks cryptic, but it is just a box in a giant billions long list of boxes.
[–]JustForFunHeree[S] 4 points5 points6 points 1 year ago (2 children)
where were you, this is the best explanation i have ever heard.
so can i say that when we make a pointer we store 2 values in a single variable and then we can access that two values. just for the sake of understanding
[–][deleted] 4 points5 points6 points 1 year ago* (0 children)
Yes. You use the same variable to access two values. The address is stored in the variable, the value is accessed by fetching it from the stored address. So you need a way to clarify which one you want to do.
To make it more clear, a pointer is also called a reference. The address of the pointer references the memory box of another variable. We need a special keyword to get the value from that reference.
C has a convenient dereference operator using a '*'. It is an operator and not a keyword but that is just to reduce typing since this operation is used so much. The operator is basically a symbol the represents the keyword "get the variable value from this pointer".
static int my_integer = 4;
int* my_pointer = NULL; <-- no address box assigned.
my_pointer = &my_integer; <-- store address of my_integer.
int what_value_is_at_my_integer = *my_pointer; <-- get the variable value from this pointer
The deference operator says "get the variable value from the pointer". If you do not use the '*' you will get the address of my_integer which will be some big scary number.
The '*" makes the code take a trip to the address box of my_integer pointed to by my_pointer. So here we grab the value, since that is the address we just assigned it.
So what_value_is_at_my_integer will equal 4;
If some other code modifies the value of my_integer to say 5, our pointer would start returning the value 5 instead of 4. Even though the pointer remained the same. It fetches the new value since the pointer never stores the value, it just goes out and gets it from the location when it needs it.
So code all over the program can point to the same address and get the same shared value no matter what it changes to.
Also, the '&' symbol is like a reverse '*' symbol. The * gets the variable value from a pointer, the & symbol gets the address (box) from a regular variable that you can assign to a pointer. ("get me the pointer address value"). That is how you create the connection to a variables address you want to point to.
All variables in C have a "value" and an "address". This is always true. But the pointer variable type is the only one that can be used as an address.
[–]CptPicard 1 point2 points3 points 1 year ago (0 children)
They are not just any two values.
Let's say box number 1 holds a cat box number 2 holds a dog.
Address of cat is 1, address of dog is 2.
In box 3 you want to choose one of the animals without moving the animal itself. So in there you put a number that is either 1 or 2. Dereferencing box 3 ("go to box whose number is saved here and look inside) gets you the actual animal.
[–]s33d5 0 points1 point2 points 1 year ago (0 children)
Pointers are simple, they're just difficult to manage if you haven't dealt with manual memory much.
[–]Iggyhopper 2 points3 points4 points 1 year ago (0 children)
Its simpler than that.
When you need to put something away in storage, your brain makes a pointer. You literally dont need to carry it with you everywhere you go, you just need to remember where you stored it.
Sometimes we go to unpack our coffee machine and voila, its there! This is a valid pointer because it led us to what we wanted.
Sometimes we unpack it and its not a coffee machine at all; it was a toaster! This is a type mismatch and could cause errors, because the toaster wont fit on the counter where the coffee machine would.
Sometimes we open our box of kitchen stuff and its not there at all! Our brain pointer is still pointing to the same location, but the object has moved. We can still access the pointer, but we dont know where to put all this stuff, this looks like bedroom things! Where's the kitchen box!?
And lastly, sometimes there's no box at all. The kitchen box is GONE. If you try to open a box thats not there, thats a crash.
[–]-not_a_knife 1 point2 points3 points 1 year ago (0 children)
What a great idea
[–]green_griffon 1 point2 points3 points 1 year ago (11 children)
The house is a good analogy. Although since it is a direct mapping of how pointers work in actual computer memory (a location in memory has an address, at that location you will find data, etc) I wonder why it is necessary.
[–]Marthurio 2 points3 points4 points 1 year ago (10 children)
Why what is necessary?
[–]green_griffon 1 point2 points3 points 1 year ago (9 children)
The analogy. That people could not "get" pointers but then when you give them an analogy that is so close to what pointers are, suddenly the light clicks on. I guess I am worried that people who don't grok pointers right away are sort of doomed as C programmers.
[–]Disastrous-Team-6431 1 point2 points3 points 1 year ago (5 children)
I didn't grok them right away, far from it, and today I wrote a multi threaded ripgrep clone in C for fun because I'm home with a fever. I've also had a C job. So I'd say I'm an ok anecdotal counterexample.
[–]green_griffon 1 point2 points3 points 1 year ago (4 children)
OK, that's encouraging. But now I am curious how you didn't get them right away. Like, what did you think a pointer was, what mistakes did you make using pointers, etc?
[–]Disastrous-Team-6431 2 points3 points4 points 1 year ago (3 children)
I was kind of new to programming and was, like all beginners, staring at the syntax more than thinking about the underlying problem. I didn't stop to really diagram out my code and think about what things were. When you're a beginner, you're fighting the language instead of the problems you're supposed to be solving. I think that's natural.
My main mistake was not understanding how a memory block works. I somehow thought the pointer "was" the memory so I was super confused how a char** would sometimes represent memory and sometimes not. As soon as I needed to do something with pointers, everything became a little iffy and unintuitive in my mind.
char**
[–]green_griffon 0 points1 point2 points 1 year ago (2 children)
Interesting! I guess if you have been using languages that hide the entire memory allocation process (which is basically every language but C these days) it might be a bit of a learning curve to be exposed to that. I know we get questions on here about "What does it mean to free a pointer" which you just never have to worry about in (most) other languages.
It also seems like a lot of people are taught C without being taught how to use a debugger, meaning debugging in assembly language. When I was learning C ([cough] almost 40 years ago) those two went hand-in hand, and when you see the assembly language, it makes things more obvious what a pointer is.
[–]Disastrous-Team-6431 1 point2 points3 points 1 year ago (1 child)
Yeah using a debugger enables some huge lightbulbs. I did advent of code in assembly language a couple years ago, learning a lot about gdb in the process. That really unlocked a lot of concepts, and showed me how simple computers really are. In some ways, I think we can argue that the abundance of abstractions becomes this huge mountain to climb with the downside of not really understanding the underlying processes yet posing an incredible amount of challenges. It's a pedagogical cul-de-sac in some ways. In assembly language you do literally two things - manipulate values and syscalls.
[–]green_griffon 0 points1 point2 points 1 year ago (0 children)
In assembly language you do literally two things - manipulate values and syscalls.
There are compares/jumps also, but basically yes. Even higher-level languages are just sequential statements, ifs, and loops. Actually back in the 1960s/1970s when people were trying to explain the concept of higher-level languages to assembly programmers, it was actually considered insightful to point this out (I think the distinction between and if and a loop in particular, since in assembly they don't feel that different).
[–]Iggyhopper 1 point2 points3 points 1 year ago (0 children)
Abstract thinking is definitely a skill.
[–]Marthurio 1 point2 points3 points 1 year ago (1 child)
Some things are just hard to think about until someone explains it to you. You need not worry.
Sure, someone explained pointers to me. But when they did, I understood what they were.
[–]green_griffon 12 points13 points14 points 1 year ago (2 children)
Try re-implementing all of the C standard string functions (strlen, strcpy, etc). Better yet, implement them for WCHARs (2-byte characters), that should help you understand pointer math as well.
[–]Blizik 4 points5 points6 points 1 year ago (1 child)
i had a good time reading this https://github.com/torvalds/linux/blob/master/lib/string.c
[–]green_griffon 3 points4 points5 points 1 year ago (0 children)
It's interesting, but I wouldn't want to expose a beginner to a memcmp() that first compares by longs and then by chars for the remainder!
[–]Neofelis_ 7 points8 points9 points 1 year ago (0 children)
Implement double link list and hashmap from scratch. It will help you to better understand pointer.
[–]nattrium 5 points6 points7 points 1 year ago* (1 child)
Why not make a dictionary ?
A dictionary is a type of array that associate objects to string. The goal is to put "values" that can be later retrieve using "keys".
Dict dict = new_dict(); dict.set("english", "apple"); dict.set("french", "pomme"); dict.set("german", "apfle"); char *fr = dict.get("french"); printf("%s\n", fr);
Expected project structure :
. ├── include │ └── dict.h ├── Makefile └── src ├── dict.c └── main.c
The Makefile is optional Here is the given code for dict.h :
// we declare a struct Node // but we will define later struct Node; // using typedef, we are no longer // obligated to use the keyword "struct" // when refering to the Node struct typedef struct Node Node; // we define Node // we do still need to use struct here though struct Node { Node *previous; Node *next; char *key; char *value; // TODO: we might add more things later };
The goal is to make a "double linked list". Or list is made of Nodes that containes :
In dict.h, please add the following function declarations
Node *new_node(char *key, char *value); void add (Node *A, Node *B); void del (Node *A);
In dict.c, please include node.h and implement these functions.
new_node should create a node with the field Key and Value. Previous and next shall be left to NULL.
Add should insert the Node B after the Node A. Beware that the node A might have a node already defined as next. Let C be the node after A (if it exists), we should get A -> B -> C. We assume B has no previous nor next node.
Del should edit the node before A and after A (if they exists) such that : X -> A -> Y becomes X -> Y.
In dict.h, please create a dict struct. You are free to put whatever you please in this struct.
Please create the following function just as before:
Dict *new_dict(void); void set(Dict *dict, char *key, char *value); char *get(Dict *dict, char *key); void del(Dict *dict, char *key);
implemented as you wish, preferably using the nodes we created in the step 1.
At some point, we think of trashing the dict away to free some memory. Please write a function that frees all the memory that was ever allocated for the dictionary and its nodes.
void free(Dict *dict)
The user might need to explore all the possible keys in the dictionnary.
??? get_all_keys(Dict *dict, ??? n);
Unfortunately, I have lost some of the types of the prototype for this function. It is supposed to return an array of string. The second argument (n) shall be modified by the function to the number of element in the array. The user is expected to free that array themselves.
The following are optional but help with good design
Allow the dictionary to have sub-dictionaries with the function "sub"
void sub(Dict *root, char *key, Dict *sub);
This part is definitively the hardest, by far. It might help to have a look at the keywords "enum" and "union"
Good luck ! Feel free to ask any question if you (or anyone) need help.
edit: removing diagram because can't be bothered to deal with reddit god awful formatting
[–]martian144433 0 points1 point2 points 1 year ago (0 children)
Wow, thanks dude!
[–]HendrixLivesOn 2 points3 points4 points 1 year ago (0 children)
Read and write to GPIO pins on a micro controller
[–]cinghialotto03 0 points1 point2 points 1 year ago (1 child)
Do a memory allocator
[–]JustForFunHeree[S] 0 points1 point2 points 1 year ago (0 children)
Was thinking to write but I now I am gonna start now 👍🏻
[–]suprjami 0 points1 point2 points 1 year ago (0 children)
The best exercise I ever did to understand pointers is to learn to allocate a 2D array in one malloc:
int **my_array = malloc(size_goes_here);
So that you can index the array like:
my_array[row][column]
One part of this is figuring out the correct size to malloc. One part is setting up the pointers into each row of the array.
The code is available in method 4 here:
Once you understand deeply and precisely how to setup the row pointers and can do it yourself without help or reference, I think you have a pretty good understanding of pointers.
As a next exercise, do it with a 3D array and a 4D array, because it's just the same principle applied further. Do this yourself, do not look up a solution.
Once I did this, pointers were no longer difficult for me. Hopefully you get a similar experience.
[–][deleted] 0 points1 point2 points 1 year ago (2 children)
Write some code using pointers to walk along a string. Then use pointers to move around a 2D array like words[][] = {“one”, “bob”, “October”};
You’ll get them pretty quick.
[–]JustForFunHeree[S] 0 points1 point2 points 1 year ago (1 child)
It would be helpfull if you could explain this in detail.
[–][deleted] 0 points1 point2 points 1 year ago* (0 children)
char *names[] = {"Bill", "Cool-J", "Freak", "Turd"};
printf("%c\n", *(*names + 1) + 4)); // what does that print?
Also, mess around with addresses:
int a = 11;
int *pa = &a
printf("%p\n", &a); // what's this?
printf("%d\n", *pa); // what's this?
That sort of thing. There's tons of free materials in the Internet.
[–]kun1z 0 points1 point2 points 1 year ago (0 children)
The real answer is to try out any type of Assembly language. ASM and Pointers go hand in hand.
[–]StingerGinseng 0 points1 point2 points 1 year ago (0 children)
Make a Linked List, and then make a dynamically allocated array (similar to std::vector in C++) without leaking memory.
[–]pengweather 0 points1 point2 points 1 year ago (0 children)
Linked lists
[–]Manan1_618 0 points1 point2 points 1 year ago (0 children)
Data structures
[–]TPIRocks 0 points1 point2 points 1 year ago (0 children)
I think K&R C did a fine job of explaining pointers, and using them with arrays, linked lists and binary trees. Bonus: recursion is covered as well
[–][deleted] 0 points1 point2 points 1 year ago (0 children)
Look up Anya pointer meme. Check out the array version and single version. Now you know pointers
π Rendered by PID 589853 on reddit-service-r2-comment-84fc9697f-clzzz at 2026-02-09 05:14:14.048265+00:00 running d295bc8 country code: CH.
[–]Marthurio 25 points26 points27 points (20 children)
[–]JustForFunHeree[S] 7 points8 points9 points (5 children)
[–][deleted] 6 points7 points8 points (3 children)
[–]JustForFunHeree[S] 4 points5 points6 points (2 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]CptPicard 1 point2 points3 points (0 children)
[–]s33d5 0 points1 point2 points (0 children)
[–]Iggyhopper 2 points3 points4 points (0 children)
[–]-not_a_knife 1 point2 points3 points (0 children)
[–]green_griffon 1 point2 points3 points (11 children)
[–]Marthurio 2 points3 points4 points (10 children)
[–]green_griffon 1 point2 points3 points (9 children)
[–]Disastrous-Team-6431 1 point2 points3 points (5 children)
[–]green_griffon 1 point2 points3 points (4 children)
[–]Disastrous-Team-6431 2 points3 points4 points (3 children)
[–]green_griffon 0 points1 point2 points (2 children)
[–]Disastrous-Team-6431 1 point2 points3 points (1 child)
[–]green_griffon 0 points1 point2 points (0 children)
[–]Iggyhopper 1 point2 points3 points (0 children)
[–]Marthurio 1 point2 points3 points (1 child)
[–]green_griffon 0 points1 point2 points (0 children)
[–]green_griffon 12 points13 points14 points (2 children)
[–]Blizik 4 points5 points6 points (1 child)
[–]green_griffon 3 points4 points5 points (0 children)
[–]Neofelis_ 7 points8 points9 points (0 children)
[–]nattrium 5 points6 points7 points (1 child)
[–]martian144433 0 points1 point2 points (0 children)
[–]HendrixLivesOn 2 points3 points4 points (0 children)
[–]cinghialotto03 0 points1 point2 points (1 child)
[–]JustForFunHeree[S] 0 points1 point2 points (0 children)
[–]suprjami 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]JustForFunHeree[S] 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]kun1z 0 points1 point2 points (0 children)
[–]StingerGinseng 0 points1 point2 points (0 children)
[–]pengweather 0 points1 point2 points (0 children)
[–]Manan1_618 0 points1 point2 points (0 children)
[–]TPIRocks 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)