I'm using a debugger to read through this code, and I'm a little confused by while ((*d++ = *s2++)); - in the debugger variables, d seems to shorten after each loop (goes from 'Hello hello' to 'ello hello' while s1 changes to 'cello hello'). What is the while loop looping through (shouldn't it be while(condition); do(something))? 
Why aren't the variable values of d and s1 the same (isn't d is a pointer to s1)? And when they return to the main function, is curdst = the pointer of dst? 
/*    
  Input: char pointers for source (s2) and destination (s1)
  Output: returns the pointer to the destination (s1)
*/
char *my_strcpy(char * , const char * );
int main()
{
  char src[] = "cs23!";
  char dst[]="Hello hello";
  char *curdst;
  int len=0;
  while(src[len++]);
  // do the copy
  curdst= my_strcpy(dst, src);
  // check to see if the NULL char is copied too.
  printf("dst array %s and last element %d\n", dst, atoi(&dst[len]));
  return 0;
}
char *my_strcpy(char *s1, const char *s2) {
  register char *d = s1;
  // print the pointer variables address and their contents, and first char
  printf("s2 address %p, its contents is a pointer %p to first char %c \n", (void *)&s2, (void *)s2, *s2);
  printf("s1 address %p, its contents is a pointer %p to first char %c \n", (void *)&s1, (void *)s1, *s1);
  while ((*d++ = *s2++));
  return(s1);
}
 
    