Автор: Александр Ковалев aka Ray
Адреса и УказателиМногие начинающие программисты, которые начинают писать на С/C++ часто испытывают
проблемы при работе с адресами и указателями. Здесь я покажу зачем они вообще нужны
и как правильно их использовать.
В функцию параметры можно передавать "по значению" и "по ссылке".
При первом способе в функции создается локальная переменная, которая является
точной копией переданного параметра. Именно с этой копией мы и работаем.
При изменении этой копии результат не отразится на первоначальном параметре, который
мы передали в нашу функцию.
При втором способе результат отразится на параметрах, переданных в функцию.
Пример1 - Передача параметров "по значению".
//------------------------------------------------------------------------------
#include <stdio.h>
int foo(int a,int b);
int main(int argc,char* argv[])
{
int a,b;
a=10;
b=20;
foo(a,b);//В функцию foo() передаются по значению переменные a и b.
printf("a=%i\nb=%i\n",a,b);
return 0;
};
/*В функции foo создаются копии, которые не изменяют описанные выше переменные, но
* сами копии могут изменяться.
*/
int foo(int a,int b)
{
a=50;
b=100;
printf("a=%i\nb=%i\n",a,b) ;
return 0;
};
Результат выполнения этого кода:
50
100
10
20
//------------------------------------------------------------------------------
При передаче "по ссылке", в функции не создаются копии переданных параметров, а
используется адрес ячейки памяти, в которой находится значение переданного параметра.
Получается, что мы работаем не с копией, а непосредственно с самой переменной,
хранящейся по адресу, который мы передаем в функцию.
Для того, чтобы получить адрес требуемой переменной надо использовать
оператор взятия адреса "&"(без кавычек).
При передаче параметров "по ссылке" в теле функции мы можем изменять значение переданного
параметра. В этом случае переменная, описанная выше, также будет изменяться.
Пример2 - Передача параметров "по ссылке".
//------------------------------------------------------------------------------
#include <stdio.h>
int foo(int &i,int &d);
int main(int argc, char* argv[])
{
int i,d;
i=15;d=5;
foo(i,d);
printf("i=%i\nd=%i\n",i,d);
return 0;
};
//В функцию foo() передаются адреса переменных i и d.
int foo(int &i,int &d)
{
i+=5;
d+=5;
printf("i=%i\nd=%i\n",i,d);
return 0;
};
Результат выполнения этого кода:
20
10
20
10
//------------------------------------------------------------------------------
Указатели.
Название "указатель" говорит само за себя. Указатель указывает на какую-либо ячейку памяти.
При помощи указателей мы можем оперировать как самими ячейками, так и содержимым этих ячеек.
char *s // указатель на char
int *pi // указатель на int
char **sp // указатель на указатель на char
int (*pf)(char) // указатель на функцию, в озвращающую int и принимающую char
При передаче в функцию какого-либо указателя мы можем оперировать как с содержимым
по этому адресу, так и с самим адресом.
Пример3 - Работа с указателями.
//------------------------------------------------------------------------------
#include <stdio.h>
int foo(int* i,int* d);
int main(int argc, char* argv[])
{
int i,d;
i=20;d=10;
foo(&i,&d);
printf("a=%i\nb=%i\n",i,d);
return 0;
};
//В функцию foo() передаются указатели на i и d
int foo(int* i,int* d)
{
*i+=5;//Увеличиваем имеющееся значение i на 5
*d+=5;//Увеличиваем имеющееся значение d на 5
// i - адрес некоторой ячейки памяти
// *i - значение в ячейке памяти по этому адресу
return 0;
};
результат выполнения этого кода:
25
15
//------------------------------------------------------------------------------
Описанную функцию можно вызывать двумя способами
1-й:
int i;
int d;
foo(&i,&d);
2-й:
int i;
int d;
int *pi=&i;
int *pd=&d;
foo(pi,pd);
//------------------------------------------------------------------------------
Вот в принципе и все.