СЛЕВА от присваивания...
*pointer = 123;
Означает "положить значение правой части (т.е. 123) в переменную (ящик), на который указывает указатель, хранящийся в переменной pointer".
Пройти по стрелке и положить значение в указываемую переменную.
В данном случае *pointer обозначает не ЗНАЧЕНИЕ указываемой переменной, а САМУ указываемую переменную.
________ /pointer/ _/_______/_ | | | &var2 | | | |_______|_| | |Положить туда 123 | V ________ / var2 / _/_______/_ | | | 123 | | | |_________|
pointer = &var2; *pointer = 123;
означает
*(&var2) = 123;
означает
var2 = 123;
То есть снова * и & взаимно СТИРАЮТ друг друга.
Ещё пример:
*pointer = *pointer + 66;
или
*pointer += 66;
Вернемся к примеру с функцией (@). Как он работает?
В строке /* #1 */ Мы вызываем функцию f(), передавая в нее УКАЗАТЕЛЬ на переменную y ("адрес переменной y").
В строке /* #2 */ Отводится локальная переменная с именем ptr, которая в качестве начального значения получает значение первого аргумента функции в точке вызова - то есть УКАЗАТЕЛЬ на y.
В строке /* #3 */ Мы видим *ptr = 7;
что следует рассматривать как
*(&y) = 7; точнее *(&main::y)=7;
то есть как
y = 7; точнее main::y=7;
Что и хотелось.
При этом отметим, что само имя "y" этой переменной внутри функции f() НЕВИДИМО и НЕИЗВЕСТНО!
ПРИМЕР: обмен значений двух переменных.
void main(){ int x, y; int temporary; /* вспомогательная переменная */
x=1; y=2;
temporary=x; x=y; y=temporary; printf("x=%d y=%d\n", x, y); /* Печатает x=2 y=1 */ }
Теперь то же с использованием адресов и указателей:
void swap(int *a, int *b){ int tmp;
tmp = *a; *a = *b; *b = tmp; }
void main(){ int x, y;
x = 1; y = 2; swap(&x, &y); printf("x=%d y=%d\n", x, y); }
Ещё пример:
int x; int *ptr1, *ptr2;
ptr1 = &x; ptr2 = &x; *ptr1 = 77; printf("%d\n", *ptr2); /* Печатает 77 */
То есть на одну переменную МОГУТ указывать несколько указателей.
Ещё пример: int x; int *ptr1; /* Не инициализирована */
x = *ptr1;
В ptr1 нет указателя ни на что, там есть мусор. Указатель указывает "в никуда" (пальцем в небо). Скорее всего произойдёт сбой в работе программы.
Мораль: ВСЕГДА инициализируй переменные, указатели в том числе.