Enhanced concatenating function
Chris, you have misunderstood the text quoted about the caller supplying all of the arguments. Your original prototype was okay. I imagine the text you read meant that if a function declares parameters a, b and c, then the caller must supply arguments (ie values of some sort) for all of those parameters. If there are 3 it must supply 3,, and of the correct types.

Given the prototype you imposed upon yourself, your implementation was not bad, but you should learn to use the standard library functions.  Your loops for copying characters are better implemented using memcpy.

Also when you declare a variable, if you can it is often better to assign a value to it immediately, not on the next line. In C, this doesn't really matter, but in C++ doing this (assigning, or constructing immediately) is more efficient.

Here is my version of your function with its original prototype.  Note that instead of exiting on malloc failure, I print a message and return NULL. The caller must handle the failure.  Note also that allocated memory must be freed.  In a simple program like this, it is not important, as it will be freed on exit from the program. But remember that you have to do it normally.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

static char *
enhconcat (const char *str1, const char *str2)
{
    size_t len1 = strlen(str1);
    size_t len2 = strlen(str2);

    char *concatstr = malloc(len1 + len2 + 1);
    if (!concatstr) {
        perror("malloc");
        return NULL;
    }
    memcpy(concatstr, str1, len1);
    memcpy(concatstr + len1, str2, len2);
    concatstr[len1+len2] = '\0';
    return concatstr;
}

int main (void) 
{
     const char *part1 = "Cuius est solum, ";
     const char *part2 = "eius est usque ad coelum et ad inferos.";

     char *cat = enhconcat(part1, part2);
     if (cat != NULL) {
         printf ("%s\n", cat);
         free(cat);
     }
     return EXIT_SUCCESS;
}