- •Void swap(int * arg1, int * arg2)
- •Void main(void)
- •Void swap(int & arg1, int & arg2)
- •Void main(void)
- •Int &move(int&I)
- •Void main(void)
- •Int& f() { return 1; } // ошибка
- •Void f(const large& arg)
- •Void g(large& arg); // считается, что в g() arg будет меняться
- •Void CorrArr(int * Arr, int Dim)
- •Void main(void)
- •Void print_arr(int m[3][4])
- •Void print_arr(int m[][4], int dim1)
- •Void print_arr(int m[][], int dim1, int dim2) // ошибка
- •Void print_arr(int * array, int dim1, int dim2)
- •Void main(void)
- •Int sqr(int X) {return X*X;}
- •Int printf(const char*, ...);
- •Void error(char* p) { /* ... */ }
- •Void (*efct)(char*); - указатель на функцию, которая ничего не возвращает и
- •Void f()
- •Void Sort(int Arr, int Dim, int(*Compare)(int, int))
- •Int Change, tmp;
- •If(!Change)
- •Void main(int argc, char * argv[])
- •Void main(int argc, char ** argv, char ** envp)
- •Void main(void)
- •Void main(int argc, char *argv[])
Лекция N 4
Параметр функции - указатель
Указатель можно использовать в качестве параметра. Ниже приведен пример функции для обмена значений двух аргументов.
Void swap(int * arg1, int * arg2)
{
int tmp=*arg1;
*arg1=*arg2;
*arg2=tmp;
}
Void main(void)
{
int x=1,y=2;
swap(&x,&y); // в качестве фактических параметров используются
// адреса переменных x и y
// . . .
}
При каждом вызове функции в стеке создается новая копия ее формальных параметров и автоматических (локальных) переменных. Занятая ими память после
выхода из функции освобождается, поэтому некорректно возвращать указатель на
локальную переменную. Содержимое памяти, на которую настроен такой указатель,
затем может измениться непредсказуемым образом:
int* f()
{
int local = 1;
// ...
return &local; // ошибка
}
Ссылки, использование ссылок в качестве параметров
Ссылка является псевдонимом или альтернативным именем переменной. Ссылки реализуются с помощью скрытного использования указателей. Наиболее часто ссылки применяются для определения параметров и возвращаемых значений функций.
int x, i=1;
int &r=i; // теперь r ссылается на i
x=r; // x=1
r=2; // i=2
При определении ссылки она должна быть сразу же инициализирована . Инициализация ссылки есть нечто совершенно отличное от присваивания ей. Вопреки ожиданиям, ни одна операция на ссылку не действует. Например:
int i=0;
int &r=i;
r++; // i увеличивается на единицу, поскольку r “ссылается” на i
Ниже приведен пример предыдущей функции с использованием ссылок в качестве параметров.
Void swap(int & arg1, int & arg2)
{
int tmp=arg1;
arg1=arg2;
arg2=tmp;
}
Void main(void)
{
int x=1,y=2;
swap(x,y); // в качестве фактических параметров используются
// . . . ссылки на переменные x и y
}
Таким образом параметры в функцию незаметно для нас передаются через их адреса.
Ссылкой может быть возвращаемое значение функции. Например:
Int &move(int&I)
{
return i;
}
Void main(void)
{
int i=10;
move(i)=100;
printf("%d\n",i); // печатается 100
}
Некорректно возвращать ссылку на локальную переменную, так как она
перестает существовать при выходе из функции, например:
int& f()
{
int local = 1;
// ...
return local; // ошибка
}
К счастью, транслятор предупреждает о том, что возвращается ссылка на
локальную переменную. Вот другой пример:
Int& f() { return 1; } // ошибка
Использование const при описании функции.
Void f(const large& arg)
{
// подчеркивается, что значение "arg" внутри функции не меняется
}
Если в описании параметра ссылки const не указано, то это рассматривается как намерение изменять передаваемый объект:
Void g(large& arg); // считается, что в g() arg будет меняться
Точно так же, описание параметра, являющегося указателем, со спецификацией const говорит о том, что указываемый объект не будет изменяться в вызываемой функции. Например:
// из <string.h>
extern int strlen(const char*);
extern char* strcpy(char* to, const char* from);
extern int strcmp(const char*, const char*);
Объект может быть объявлен константой при обращении к нему с помощью
указателя, и в то же время быть изменяемым, если обращаться к нему другим
способом. Особенно это удобно использовать для параметров функции. Описав
параметр-указатель функции как const, мы запрещаем изменять в ней указываемый
объект.
Может быть вполне разумным и даже полезным описание функции с типом
возвращаемого значения const:
const char* peek(int i) // вернуть указатель на строку-константу
{
return hidden[i];
}
Приведенную функцию можно было бы использовать для передачи строки,
защищенной от изменения, в другую программу, где она будет читаться.
Параметр функции - массив
Если в качестве параметра функции указан массив, а как мы уже знаем
имя массива компилятор трактует как будто это указатель, то в функцию
передается указатель на его первый элемент. Поэтому функция работает с элементами оригинального массива, указатель на который загружается в стек.
Например:
