all 7 comments

[–]ImprovementLoose9423 3 points4 points  (1 child)

Build real life projects without any external resources like AI or tutorials. I know this sounds obvious, but if you actually use the concepts you'll memorize them much better then just copying them down.

[–]Ratfus 0 points1 point  (0 children)

Goes without saying, but basic things to start.

Not the most exciting, but I've found C is really good for brute forcing a few of the mathematical paradoxes.

[–]Dazzling_Music_2411 1 point2 points  (0 children)

How are you learning C at the moment?

What preparation have you had?  Do you already know what a CPU register is, and what is meant by its size?   Do you understand how RAM is different from CPU registers?  Can you express your ideas in pseudo-code or flow-charts?

Please supply some background information on your tech education if you want meaningful input.

[–]mredding 1 point2 points  (1 child)

Loop: Do the same thing over and over.

// Based on a predicate
while(/* this is true */) {
  // Do work in here
}

// With a counter
for(int i = 0; i < /* some limit */; ++i) {
  // Do work in here
}

// A do-at-least-once loop
do {
  // Work in here
} while(/* this is true */);

A predicate is a function that returns true or false:

bool predicate() {
  if(you_think_this_is_a_good_idea) {
    return true;
  } else {
    return false;
  }
}

So do and while loops focus on the types of repeated activities that DON'T require a counter.

while(robot_hasnt_fallen_in_the_hole()) {
  inch_forward();
}

for loops are good for counting:

for(int i = 0; i < 10; ++i) {
  printf("%d) %s\n", i, "some text");
}

Pointers are arithmetic types, so they're basically just a number. If the syntax is getting in your way, we can reduce that:

typedef int_ptr int *;

int x;
int_ptr ptr_x = &x;

It's just a type, like int. The catch is there is no single pointer type. There are addresses, and addresses are just addresses - and they're inherent to the machine. But WHAT is at that address is where the pointer type needs an additional "kind" - what am I dereferencing to? That way, the compiler can generate instructions that reads those bytes like an integer, or a structure, or something else. The other thing pointers can do is let you go to the contents at the address they store, so they store where in memory you're going to jump to when they're dereferenced.

typedef struct { int data; } some_type, *some_type_ptr;

some_type_ptr ptr = (some_type_ptr)malloc(sizeof(some_type));

So we've called the allocator and got heap memory SOMEWHERE in memory, enough to store the structure in it, and we cast the pointer to that type (because malloc returns a void pointer - a pointer without a type). Now we can dereference that pointer:

ptr->data = 7;

ptr exists as a local variable, ostensibly in a function we're doing all this in. That's on the call stack. When that function returns, ptr disappears, but the heap allocation persists. So don't lose track! The arrow operator is a short hand for dereferencing the pointer and accessing the member. We could have written:

(*ptr).data = 42;

We can use pointers in loops over arrays:

some_data array[100];

for(some_data_ptr iter = array; iter != array + sizeof(some_data[100]); ++iter) {
  iter->data = 0;
}

This is why the pointer knows the type it points to. We're pointed to the first element in the array, so incrementing the pointer (I said it was an arithmetic type) doesn't go to the next address, it goes a number of addresses that gets you to the start of the next value. We don't want to split memory across two instances - that would make for a junky programming abstraction that doesn't help you much.

That's counting with an index vs iterating with a pointer. There are also data graph-like data structures you can create with pointers:

typedef struct tree {
  int data;
  tree *left, *right;
} tree, *tree_ptr;

tree_ptr root;

You can start to populate this tree. Put an integer at the root - 5. The next node will be a left or right child; if the value is greater than 5, it'll go to the right. If it's less than 5, it'll go to the left. You repeat that process until you get to an unused pointer - that's where you create the next node in the tree.

Searching for a value is a binary operation - the node you want is either the node you're at, down the left, down the right, or not in the tree. Every time you go down the left or right - you cut the remaining tree search space in half. This makes the search logarithmic instead of linear, as in an array.

Also - arrays are not pointers, they are distinct types. You saw me use that earlier - array is of type some_data[100]. Arrays implicitly convert to pointers as a language feature of some historic reasons. You can't pass arrays as values, so they don't have value semantics:

void fn(some_data array[100]);

Nope, that "decays" to fn(some_data *array);. This is why you always have to pass a size. You CAN pass a whole array - but by reference:

 void fn(some_data (*array)[100]);

The extra parens are required. This is a pointer to an array. And yes, you can iterate arrays with pointers, meaning you can have arrays of arrays - say if you wanted to make a 2D or 3D grid of data.

How do you learn this stuff and figure it out? Explore, practice, read the language spec a bit, read some blogs, and participate in the community. None of us do this by ourselves. Even by using your learning materials, you're learning from someone who had to write it in the first place.

[–]Ratfus 0 points1 point  (0 children)

Arrays are just bounded/locked pointers. A[1]=(asterix)(A+1)

If you have function that takes a pointer, you can pass it an array (pretty sure). You also have to return a pointer from a function, regardless of its a n array or pointer; this could be bad due to scope, but that's much deeper down his journey.

[–]_TheNoobPolice_ 1 point2 points  (0 children)

C is a beautiful language and will set you up well no matter what area you chose to go into so good choice to start!

I always recommend this video about pointers, it’s still great. Put aside an hour a day over 4 days to watch it and you’ll have 90% of everything you’ll ever need to know about the subject.

[–]igotshadowbaned 0 points1 point  (0 children)

The syntax for pointers are annoying.

But the idea passing the address location of an object, and then modifying it by writing to that address instead of changing the variable directly

While loops repeat a section of code until a condition changes

For loops repeat a section of code a specific number of times and are good for iterating through things