0:02

In this video, we're going to write a function that copies a string

from one place "the source," to another place, "the destination."

Because we don't want to risk riding past the bounds of the destination,

we're also going to specify to our function how much space

it has and stop writing if we go past that amount of space.

In working an example for ourselves,

we're going to take the string "cat" and copy it to this four element array,

which is currently uninitialized.

We don't actually know what's there,

and our function doesn't care.

So to do this, I'm going to start copying letter by letter

'C,' 'a,' 't,' null terminator, into the destination.

Now, I'm going to perform step two and write down exactly what I just did.

I made an arrow which I'll call 'p1,' so I can refer to it more concretely,

and set it pointing at the first letter of "dest."

Then I made another arrow which I'll call 'p2'

and set it pointing at the first letter of "source."

I wrote a 'C' into the box that 'p1' pointed at,

then I advanced 'p1' to point to at next letter,

and I advanced 'p2' similarly.

I wrote an 'a' into the box that 'p1' pointed at,

then I again advanced 'p1,' and advanced 'p2.'

I wrote a 't' into the box that 'p1' pointed at,

then I advanced 'p1,' and advanced 'p2.'

Finally, I wrote a null terminator into the box the 'p1' pointed at, and then I was done.

Now I'm ready to generalize these steps.

These first two steps always happen,

we'll just keep them the same,

but I'll rewrite them in the imperative mood.

Now all of these next steps look repetitive,

and you'll note that I've only boxed 'C,' 'a,' and 't,' and

not the null terminator because we want to keep the pattern of writing,

advancing 'p1' and advancing 'p2,' but for the last step we don't advance.

These steps are repetitive,

and we're doing almost the same thing,

except we're writing a different letter each time.

Why did we write capital 'C' the first time,

lowercase 'a' the second time,

and lowercase 't' the third?

If we go back and think about our example,

we'll see that in each case,

this was what 'p2' pointed at,

so we can just change each of these statements to,

I wrote the letter in the box 'p2' pointed at,

into the box 'p1' pointed at.

Now all three of these groups of steps are the same.

We have exactly the same three steps which we've repeated three times.

These steps are now repetitive.

But how do we know when to stop?

Are we always going to do this three times? Probably not.

If we go back to our example,

we will see that we stopped when we reached the end of the string we're copying,

that is, when 'p2' points at a box with a null terminator in it.

So we specify, as long as the letter in

the box 'p2' points at is not the null terminator,

then we will do these three steps.

After we finished this,

we wrote a null terminator into the box that 'p1' pointed at.

Since we are always going to want to do this,

we can write this simply as a direction.

We have finished generalizing our algorithm.

Now we should test it. We're going to

walk through our algorithm with a different test case.

"Source" is once again 'Cat,' but 'n' is only two,

so "dest" is an array with space for two letters.

Walking through these steps,

we'll make an arrow for 'p1,' make an arrow for

'p2,' as long as the letter in the box 'p2' points at is not the null terminator,

it's 'C,' so it's not,

we go inside the repetition.

Write the letter in the box 'p2' points at into the box 'p1' points at.

Advance 'p1,' advance 'p2,' then go back and continue repeating these steps.

Again, it's not the null terminator,

so we write, advance, advance.

Go back and continue repeating these steps.

'p2' is again not pointing at the null terminator.,

so we're going to write the letter in the box 'p2' points at,

which is a 't',

into the box 'p1' points at.

Unfortunately, 'p1' has gone past the end of the destination array,

and is now writing into box that should not.

We have no idea what piece of memory this is,

or what it belongs to,

and we're going to do bad things to our program.

It may misbehave in strange ways,

a segmentation fault, or who knows what.

This means we need to go back and fix our algorithm.

Reworking steps one, two and three to fix this problem.

We're not going to walk through them in this video,

but you'll see that we should only do these steps as long as

the letter in the box 'p2' points at is not the null terminator,

and 'p1' is not equal to stop,

which is going to be a new arrow that we make

pointing just past the end of the destination array,

that is 'n' letters after "dest."

Then at the end, we're going to check that 'p1' is not equal to stop,

before we write the null terminator into the box 'p1' points at.

In other words, we're going to draw an arrow past the end of the array,

and stop doing anything if we get there.

In the next video, we'll translate these improved steps into code.