3

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);

}
  • 2
    Note that `*d++ = *s2++` is very different from `*d++ == *s2++`. Here, you're overwriting the values in `*d` with values from `*s2`, until you reach the null terminator in `s2`. – hnefatl Dec 20 '17 at 19:11
  • The condition here is that the `*s2` is other than zero (string null-terminator). – Eugene Sh. Dec 20 '17 at 19:12
  • 1
    See [this answer](https://stackoverflow.com/a/20957532/2201041) for a breakdown of a similar thing. –  Dec 20 '17 at 19:13

1 Answers1

2

This is a rather typical didactic implementation of strcpy(). It works like this:

  • my_strcpy() takes two arguments. The first argument is a pointer to the first element of a destination character array. The second argument is a pointer to the first element of a source character string, that is, a character array terminated by a NUL (aka \0) character. The function copies the characters from the source string to the destination buffer, including the NUL terminator, and returns a pointer to the first element of the destination buffer.

    char *my_strcpy(char *s1, const char *s2) {
    
  • First things first, make a copy of the first argument, because we need to return it after the copying is done.

    char *d = s1;
    
  • Then, copy the characters; this is done in a tight loop, working like this:

    • Copy the current character * s2 to the place pointed to by d, as if executing * d = * s2; then
    • Increment d to point to the next place in the destination buffer as if executing d++ and increment s2 to point to the next character to be copied as if executing s2++; and
    • Exit the loop if the last character which was copied was NUL.

    This is written in a very concise manner:

    while (* d++ = * s2++);
    

    * s2++ means "take the character pointed to by s2 then increment s2". Similarily, * d++ as a left-hand value means "use the variable pointed to by d then increment d". The order of precedence of operators helps dispense with parentheses because ++ has higher priority than * which has higher priority than =. The value of the assignment is the assigned value, so the loop ends when the assigned character has the value 0.

  • Finally, return s1, which was not changed by the function.

    return s1;
    }
    
AlexP
  • 4,370
  • 15
  • 15
  • Thank you!! Is changing `*d` changing `s1` so that when you return `s1`, you have copied s2 to s1? – hello world Dec 20 '17 at 21:35
  • @helloworld: You have copied the character string to which `s2` points into the buffer to which `s1` points. – AlexP Dec 20 '17 at 22:12