string
is just an array (buffer) of char
s. Basically, an array of 8-bit unsigned int
s. And the last element in the array is '\0'
. The actual array can be much bigger than the string occupying it, and strcat indeed requires that the dest
is big enough to contain both the dest
string and the source
strings together. strcat
is not a ready-to-use method like in higher level languages. It's use case looks like this:
char* buffer = malloc(strlen(string1) + strlen(string2) +1)
Create a buffer that's big enough to contain both strings.
strpy(buffer, string1)
Copy the first string to the buffer
strcat(buffer, string2)
Append the second string to the buffer where the first string ends.
++
and --
operators allow a pointer to serve as enumerator. Think of those as .next()
and .prev()
. The caveat here is that they return (or accept) the value BEFORE moving the enumerator. This is critical here, this basically is what allows C to be so hard ;) If you want to recreate this in higher level, it'll be getAndNext()
and setAndNext()
*
is an accessor, working both ways, so it's enumerator's getValue()
and setValue()
.
First block just skips the dest
buffer until it reaches the end of the string in it - but NOT the end of the buffer.
while (*dest)
dest.next();
in pseudo-code is:
while (dest.get() != '\0')
dest.next();
That's because \0
is a real zero in the int
meaning, and int zero is false
in boolean meaning. Anything non-zero is true
. That means -1, 42 and 'A'
are just as true
as 1. So in C we just skip the != 0
which is as pointless as writing != false
in a language that has real booleans.
while (*dest++ = *src++)
;
Can be restated as:
while (dest.setAndNext(src.getAndNext()) != '\0')
or without the compounding:
char value;
do
{
dest.set(src.get());
value = src.get();
src.next();
dst.next();
}
while (value != '\0');
That's because in C an assignment has a value. So (*dest++ = *src++)
ultimately returns the character that had been copied. It's like an inline function that copies, advances and then returns what was copied.
A pointer can legally point beyond the array. It's like enumerator that had reached the end and there is nothing more. The big difference is that a high-level enumerator can and will tell you that (via an exception), while a pointer will keep going even though it doesn't make any sense anymore. That's why both src
and dest
pointers are ++ed one time too many, but we don't care because we've took care to never use them after that.
rdest
is simply saved position of where the buffer started. We can't return dest
, because that enumerator had been used up and now it's at the end of the string, while we need to return the beginning. "r" probably stands for "return", because the whole point of this variable is to be returned.