Its great to see how files at the end of the day are just 0’s and 1’s like everything else! And in featured image you can see the signature of a bitmap image. A Jpeg however has a much smaller one, just three bytes at the beginning of the file.
As you can see the bytes are written in Hexadecimal. And very interestingly, an hexadecimal is pre-poned by “0x” to know it is coming.
Structs in C
Very interestingly, seems that you can create your own datatypes on C. And this very much reminds me of the concept of a “Class” and Objects… it is pretty much the same.
Imagine you want to create and store some data for different students. This is a way you could do it with lists, but of course has immense limitations (In the case below you only have 3, what if you need more?):
- So it seems that in C you can create your own, and by convention you usually write these in a .h file.
You can see below different things:
- It is good conventions to declare constants by using #define type () like below it does with “STUDENTS 3”
- It is good convention to write the constant in capital letters
- As you can see in the #include for structs.h, it is using “” instead of <>. This is because that file is in the current directory. So to include a file in the current directory, one uses quotes “”.
As you can see we called “structs” where the “student” datatype is contained.
So below he is saying, give me a variable called students, each of type students, and specifically give me 3 of those in my array.
On line 17 you can see there is a “.name” or “.dorm”. Those are basically things inside of each student.
And below you can see how a CSV file is created in C, to store whatever a program outputs.
Pointer + strcmp
A pointer is an “address in memory”. When I say char* s = GetString()… then this doesn’t mean give me a string. It means, give me a variable who’s purpose in life is to store an address because I am about to put the address of a string into it.
And GetString does not return a string. It returns an address. The address of the first character in some string it has gotten.
Below you can see a good convention. Checking if s or t are NULL. When s or t return something different from an address… it returns NULL, that is an error. Something went wrong.
What can happen is that maybe string stored is so big that there is no memory to hold it.
C comes with a function that does that iteration
- strcmp (pointer1, pointer2)
- It distinguishes between lower case and upper case
This basically goes to those two addresses in memory and checks each character until reaching the \0.
Important below, what is happening is that t is getting the address in memory of s, not the “string” we wrote in it.
Below you can see that t doesn’t get “mom” it gets 1. The address in memory.
And below you can see that we are capitalizing first letter of the array:
And now something important but complex. This code basically it says in line 16 the following.
First create a pointer t which stores an address in memory. Then Malloc means “memory allocation” which is basically “give me a chunk of memory”.
We are saying, give me the strlen of s (which is 3), then I add 1 to account for the \0, (allocate 4 bytes, so need the length of the string + 1) and just for good measure we say, we * for “sizeof” which basically tells us the size of a (char) in that case. (I guess this is a safety measure). sizeof it tells you number of bytes needed for a certain datatype. (btw, sizeof(char) is usually 1).
And now basically we copy each character of s into t through a loop. So that now I have 2 copies of original.
Lastly you can capitalize the first letter of the copy you made!
And finally we can have an even more advance way of writing this.
*t is basically saying, go to the following address. “t”.
Pointer arithmetic (math with addresses).
So basically *(t + i) is going to each position after t… same as t[i].
So for SWAP function we did in previous class, instead of passing the values of x,y which actually become a and b as copies, you can pass the addresses… like below:
Inside of function, start means go inside… so *a means whatever is inside that integer address. (Memory knows it is an integer as we have already defined).
And remember, to that function swap we need to pass the addresses, not the values. You do that by suing the & character like below:
Below a program declares x and y who are addresses of integers (pointers). Then we allocate enough memory to store an int, and store that memory address in x. Then go to address in x, and put number 42. And *y says go to address in y… (but this is dangerous as I have not put anything in y!!)
Things they point to are “pointees”.
Initially pointers don’t point to anything.
To allocate a pointee, you need to first allocate it with the “malloc(sizeof(int));” term, for a creation of an integer pointee. And then you can point x to that by doing x = (the formula before).
So once already have the pointee we can dereference it by using *x which etches that value on the memory we had allocated.
When you do y = x; then y will be also assigned to the same pointee than x was. And if then you do *y = 13, basically you are changing the pointee stored value to 13, so if now you print x I guess it will show 13!