I'll do my best to explain it line by line, hopefully this will help you figure out what part you are not understanding.
Here you define a variable (of size int), this means Test stores a value somewhere on memory.
Here you define a pointer (that can point to something of size int), this means that it stores an address on memory.
Another int just like test
Here you set Test to 50, this finds the address in memory (it doesn't matter where, the C compiler does this for you) and it changes the value at that memory to 50
First lets look at the Right side of this statement "&Test." The & Opperator retrieves the address of a variable. Whenever I write & in code I think "address of" in my head. so the right side of the equation is "Address of Test." So TestPointer now contains an address in memory. This address will stay the same no matter what you do to Test. If you write "Test = 30" TestPointer will not change still the same address, that address just holds 30 now instead of 50.
Now lets look at the Right side again. The * Operator (in an equation such as this line) means The value at this address. So *TestPointer translates to "The value at the address contained in TestPointer." So in this situation you can write ChangeMe = Test instead of ChangeMe = *TestPointer; because, they mean the same thing, Test is the value at some address, and *TestPointer is that same value. So ChangeMe was set to 50 in this line, it doesn't retain the fact that it was set to a dereferenced Pointer (*TestPointer), it just cared what the value was. If you added a new line after this that changed the value or Test, or changed the address of TestPointer; ChangeMe will not change. It will still be 50, it's now it's own variable.
| int Test2;
int ChangeMe2;
Test2 = 50;
ChangeMe2 = Test2;
|
Hopefully I explained it well and you can see how these 4 lines of code accomplish the exact same result as your first segment of code. Infact the whole thing could be boiled down to ChangeMe2 = 50. Once you set it it doesn't care how it got 50, it's just 50.
You could even write something like this
| int Test;
int ChangeMe;
Test = 50;
ChangeMe = *(&Test);
|
This again does the same thing as the other segments of code, it sets ChangeMe to 50. First the part in parenthesis (&Test) retrieves the address of Test. Then the * outside the parenthesis looks at the value of that address.
I hope this was readable, I don't always write the clearest explanations. A good way to learn about pointers is to use the Watch Window in Visual Studio.
Edit:
I re-read your original post and realized I am an idiot. It seems you know how they work you were asking Why, my mistake.