2

I am trying to grasp pointers and I have this simple code for which I need some explanation.

I need to copy one char array to another. In my main function I have this code:

const int MAX_SIZE = 100;

char x[MAX_SIZE] = "1234565";
char* y = new char[MAX_SIZE];

copyArray(x, y);    
std::cout << y;

delete [] y;

Now comes the question, how does this code (which works jut fine):

while ((*dest = *source) != '\0')
{
    dest += 1;
    source += 1;
}

Differ from this (gives strange characters at the end):

while (*source != '\0')
{
    *dest = *source;

    dest += 1;
    source += 1;
}

Looking at this it seems those two functions are pretty similar. It makes sense that we are copying until we reach a null-terminator in the source string, right (2nd function)?

But it's not working correctly - I get some strange characters at the end of the copied array. However, the first function works just fine.

void copyArray(const char* source, char* dest);
8
  • Right, I did the suggested tag twice, sorry Commented Nov 21, 2017 at 22:41
  • 5
    while ((*dest = *source) != '\0') guarantees that the necessary terminating '\0' character will be copied before the loop ends. Also see idownvotedbecau.se/nodebugging Commented Nov 21, 2017 at 22:41
  • You mean in the second example it will break the loop when it encounters '\0' meaning that it won't terminate the string? Commented Nov 21, 2017 at 22:43
  • Yes, I mean exactly that. Commented Nov 21, 2017 at 22:45
  • 1
    @daavid245 Detail: The while (*source != '\0') loop does not "won't terminate the string". It won't terminate the character array. A character array is not a string until it has a null character. Commented Nov 21, 2017 at 22:47

3 Answers 3

1

The form

while ((*dest = *source) != '\0')
{
    dest += 1;
    source += 1;
}

guarantees that the assignment of the character to copy ((*dest = *source)) is applied before testing the condition if the terminating '\0' character is reached is evaluated to false.

The second version doesn't copy the terminating '\0' character, because the loop ends before the

*dest = *source;

statement is ever reached.

Sign up to request clarification or add additional context in comments.

Comments

1

(*dest = *source) is an evaluated expression just like the 1+1 part of int i = 1+1; so, after it is evaluated, the value is usable in an other expression

The difference is that in ((*dest = *source) != '\0'), the value of *source is assigned to *dest, then the whole expression is evaluated ( expression has the same value than *source ) while the value pointed by *source is only used to evaluate *source != '\0', but never assigned during the evaluation of that statement.


EDIT

user0042 brings a realy acute observation : by doing so, the following code

while ((*dest = *source) != '\0')
{
    dest += 1;
    source += 1;
}

ensures that the final char of the array has a value of '\0'

Comments

0

In the example you incrementing the addresses of x, y thus until the last character they point to Null-terminator so you have to declare a temporary variables to hold the first address:

char* x = "1234565";
char* y = new char[MAX_SIZE];

// Temporary pointers to hold the first element's address
char* tmp1 = x;
char* tmp2 = y;

while( (*y = *x) != '\0'){
    x += 1; // X no longer points to the first element
    y += 1; // Y no longer points to the first element
}

std::cout << tmp2;
  • You can use a do while loop instead of while:

    char* x = "1234565";
    const int size = strlen(x);
    char* y = new char[size];
    
    char* tmp1 = x;
    char* tmp2 = y;
    
    do{
        *y = *x;
        x += 1;
        y += 1;
    }while( *(x - 1) != '\0');
    
    // Now no need for adding a null-terminator it is already added in the loop
    //  tmp2[size] = '\0';
    
    std::cout << tmp2;
    

Because Assigning the values before incrementing so the last character \0 will break the loop before added to the destination pointer y. Thus I made the loop breaks not on n = '\0' but on n - 1 = '\0' to ensure that it is added to y.

1 Comment

he increments x and y in both examples

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.