Breaking it into pieces:
(*dest) /* Is *dest different than '\0' ? */
? my_strcat(++dest, src) /* *dest is different than '\0', so increment dest pointer so it'll point to the next character and call my_strcat() again. Here we're searching for the end of the string dest. */
: (*dest++ = *src++) /* *dest is equal to '\0', so we're at the end of *dest... We start to assign *src to *dest and increment both pointers to point to the next character. The lvalue of this assignment is also a comparison (is it different than '\0' ?). */
? my_strcat(dest, src) /* The previous comparison is different than '\0', so we'll call my_strcat() again (pointers have already been incremented and they now point to the next character) */
: 0; /* The previous comparison is '\0', so we've reached the end of the src, so we're done. */
Replacing ternary operators with if/else:
/* Is *dest different than '\0' ? */
if (*dest != '\0') {
/* *dest is different than '\0', so increment dest pointer so it'll point to the next character and call my_strcat() again. Here we're searching for the end of the string dest. */
my_strcat(++dest, src);
} else {
/* *dest is equal to '\0', so we're at the end of *dest... We start to assign *src to *dest and increment both pointers to point to the next character. The lvalue of this assignment is also a comparison (is it different than '\0' ?). */
if ((*dest = *src) != '\0') {
/* The previous comparison is different than '\0', so we'll call my_strcat() again (pointers have already been incremented and they now point to the next character) */
my_strcat(++ dest, ++ src); /* Moved increments down for readability */
} else {
/* The previous comparison is '\0', so we've reached the end of the src, so we're done. */
return;
}
}
If/else without comments (maybe it's more readable):
if (*dest != '\0') {
my_strcat(++dest, src);
} else {
if ((*dest = *src) != '\0') {
my_strcat(++ dest, ++ src);
} else {
return;
}
}
dest[100]will be filled with all NULs after the string.