Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 04.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
83.46 Кб
Скачать

Void error(char* p) { /* ... */ }

Void (*efct)(char*); - указатель на функцию, которая ничего не возвращает и

получает указатель на строку

Void f()

{

efct = &error; // efct настроен на функцию error

efct = error; // можно написать и так, компилятор поймет

(*efct)("Not free memory!"); // вызов error через указатель efct

}

Для вызова функции с помощью указателя (efct в нашем примере) надо вначале применить операцию разадресации к указателю - *efct. Поскольку приоритет операции вызова () выше, чем приоритет косвенной адресации “ * ”, нельзя написать *efct("error"). Это будет означать *(efct("error")), что является ошибкой. По той же причине скобки нужны и при описании указателя на функцию. Однако, писать просто efct("Not free memory!") можно, так как транслятор понимает, что efct является указателем на функцию, и создает команды, делающие вызов нужной функции.

Указатели на функцию часто используются в качестве параметров другой функции для модификации ее алгоритма.

Нарпример у нас есть две функции сравнения целых чисел.

int More(int a1, int a2) { return a1>a2; }

и

int Less(int a1, int a2) { return a1>a2; }

Указатель на эти функции можно использовать для модификации алгоритма функции, предназначенной для сортировки элементов массива.

Void Sort(int Arr, int Dim, int(*Compare)(int, int))

{

Int Change, tmp;

while(1)

{

Change=0;

for(int i=0;i<Dim-1;i++)

{

if((*Compare)(Arr[i],Arr[i+1])

// if(Compare(Arr[i],Arr[i+1]) а можно и так, компилятор поймет

{

tmp=Arr[i]; Arr[i]=Arr[i+1]; Arr[i]=tmp;

Change=1;

}

}

If(!Change)

return;

}

}

мoid main(void)

{

int a[5]={1,2,3,4,5},i;

Sort(a,5,&Less);

// Sort(a,5,Less); а можно и так, компилятор поймет

for(i=0;i<5;i++)

cout<<a[i]<<" ";

cout<<'\n'; //5 4 3 2 1

Sort(a,5,More);

for(i=0;i<5;i++)

cout<<a[i]<<" "; //1 2 3 4 5

getch();

}

Отметим, что формальные параметры в указателях на функцию описываются

так же, как и в обычных функциях. При присваивании указателю на функцию

требуется точное соответствие типа функции и типа присваиваемого значения.

Например:

void (*pf)(char*); // указатель на void(char*)

void f1(char*); // void(char*);

int f2(char*); // int(char*);

void f3(int*); // void(int*);

pf = &f1; // нормально

pf = &f2; // ошибка: не тот тип возвращаемого значения

pf = &f3; // ошибка: не тот тип параметра

(*pf)("asdf"); // нормально

(*pf)(1); // ошибка: не тот тип параметра

int i = (*pf)("qwer"); // ошибка: void присваивается int

Правила передачи параметров одинаковы и для обычного вызова, и для

вызова с помощью указателя.

Передача параметров в функцию main из командной строки

Функция main, с которой начинается выполнение Си-прораммы, может быть

определена с параметрами, котороые передаются из внешнего окружения.

Принято, что два первых параметра называются argc и argv. хотя можно

взять и другие названия.

Параметр argc определяет общее число аргументов в командной строке и

объявляется как int. Параметр argv объявляется как массив указателей, каждый

из которых указывает на строковое представление аргумента в командной строке.

Если функции main передается третий параметр, то этот параметр принято

называть envp. Параметр envp определяется аналогично параметру argv как массив

указателей на строки, задающие переменные среды окружения.

Спецификация вызываемой программы тоже считается аргументом. Например, для командной строки

c:\work\dir1>copy a:\primer.txt b:\primer.txt cp vladu

значение argc будет равно 3.

При этом аргументы имеют представление в памяти, как это показано

ниже.

argv

  • c : \w o r к \ d i r 1 \ c o p y

  • a: \ p r i m e r . t x t

  • b: \ p r i m e r . t x t

NULL

. . .

envp

  • p a t h = a : \ ; c :

  • l i b = d : \ l i b

NULL

. . .

Ниже приведен пример программы echo, назначение которой печатать значения аргументов командной строки, за исключением первого. Вставляя обращения к такой программе в командные файлы, можно при их выполнении выводить нужные сообщения на экран дисплея.

#include <stdio.h>