Массив указателей
Использование указателей для связи функций
В большинстве языков программирования параметры подпрограммам (функциям) передаются либо по ссылке (by reference), либо по значению (by value). В первом случае подпрограмма (функция) работает с адресом переменной, переданным ей в качестве фактического параметра. Во втором случае ей доступна не сама переменная, а только ее значение (копия числа). Различие здесь такое: переменную, переданную по ссылке, функция может модифицировать в вызвавшей ее функции, а переданную по значению - нет.
В языке Си параметры передаются только по значению. Общепринятый способ обеспечить функции непосредственный доступ к какой-либо переменной из вызывающей подпрограммы состоит в том, чтобы вместо самой переменной в качестве параметра передавать ее адрес.
Рассмотрим программу, в которой осуществляется обмен значений переменных с помощью функции swap ().
/* программа # 1.16 */
void swap(int *,int *);
void main()
{
int a = 10,b = 20;
swap (&a,&b);
}
/*эта функция выполняет обмен значений переменных */
void swap(int *x,int *y)
{
int c; /* временная переменная */
c = *x; /* запоминаем значение переменной, на которую ссылается указатель х */
/* с = х; это неверно так как переменной с будет присвоен адрес ,а не само значение переменной, на которую ссылается указатель х */
*x =*y; /* переменной,на которую ссылается указатель х, присваиваем значение переменной, на которую ссылается указатель y */
*y = c; /* переменной,на которую ссылается указатель y, присваиваем значение из буфера */
При вызове функции передаются адреса переменных a и b. Это значит, что формальные параметры функции должны быть описаны как указатели на соответствующий тип данных. При таком описании формальных параметров вызываемой программе становятся доступными адреса переменных из вызывающей программы, которые являются в ней локальными. Если известны адреса, то применимы операции чтения и возврата по адресу.
Часто в программах требуется передавать функциям объекты классов или структурные переменные. Если передавать объект по значению, то будут иметь место большие накладные расходы на копирование памяти. Проще передавать указатель на объект – всего 4 байта памяти, содержащие адрес объекта. Доступ к члену класса в этом случае внутри функции должен осуществляться оператором ‘->’.
#include <vcl.h>
#pragma hdrstop
#pragma argsused
void calcul ( class A * ptr);
class A
{
public:
int a;
};
int main(int argc, char* argv[])
{
A a;
calcul (&a);
return 0;
}
void calcul ( class A * ptr)
{
ptr-> a = 100; // доступ к члену а класса A
}
Часто в программах требуется объявить массив строк. Это можно сделать, используя массив указателей, как показано ниже.
/* программа # 1.17 */
# define DIM(x) (sizeof(x) / sizeof( x[0] ))
void main()
{
/* char *col[3] - массив указателей (адресов) из трех элементов*/
char *color[] = {
/* это инициализация массива
адресами строк */
"RED", "BLUE","GREEN "
};
short i;
/* выводим названия цветов на экран */
for ( i = 0; i < DIM (color); I ++)
printf("%s\n", color[i]);
}
В этой программе первому элементу массива color присваивается адрес строки "RED" (индекс массива i = 0), второму элементу массива color[1] - адрес строки "BLUE" и т.д. Затем значения массива выводятся на экран с помощью функции printf( ).