Both arguments to strcat are pointers to char objects, and both are assumed to point to (the initial character of) a string.
For example, this:
strcat(s1, &s2[0]);
is equivalent to this:
strcat(s1, s2);
In both cases, the second argument is a pointer to the initial character of a string, which strcat uses to access the entire string up to and including the terminating '\0' null character.
But your program has undefined behavior. By declaring
char s1[] = "cat";
you let the compiler determine the size of s1 based on the initializer. In this case, s1 is an array of 4 chars (including the terminating '\0'). There is no room to append anything to it. Apparently when you ran it, it copied characters into the memory space immediately following s1, which is why it seemed to "work".
A working version of your program is:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[50] = "cat";
char s2[] = "hsklsdksdhkjadsfhjkld";
strcat(s1, &s2[1]);
printf("s1 is now %s\n", s1);
}
Note the #include directives. These are not optional, even though you might get away with omitting them.
strcat()takes two string arguments, and because&s2[1]isn't a character, its the string"sklsdksdhkjadsfhjkld";