IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   Указатель на функцию и его использование в С++ (http://www.imho.ws/showthread.php?t=103802)

Kvarx 18.05.2006 01:41

Указатель на функцию и его использование в С++
 
Есть функция1 и функция2. Предлагается создать указатель на функцию1, что из функции2 можно было бы вызывать ее(фунцию1) обращаясь к элементу массива(для разных параметров). Язык: С/С++.

Спасибо.

PSyton 18.05.2006 06:41

Что-то как-то мутно сформулировано. Что нужно-то, вызов функции при обращении к элементу массива или я не понял?

GOre01 18.05.2006 11:07

что-то так
Код:

// функция 1
double func1(float a) { return a*a; }

// указатель на функцию 1

typedef double (*pfunc1)(float a);

// функция 2
void func2();

int _tmain(int argc, _TCHAR* argv[])
{
        func2();
        return 0;
}

void func2()
{
        pfunc1 func_vect[10];
        for (int i = 0; i < 10; i++)
                func_vect[i] = func1;
        for (int i = 1; i <= 10; i++)
        {
                printf("%f ", func_vect[i-1](i));
        }
}

или я не до конца понял задание

Kvarx 18.05.2006 11:16

GOre01,

по ходу дела это мне и нужно. pfunc1 func_vect[10] только я глобальным сделаю.

Цитата:

Сообщение от GOre01
func_vect[i] = func1;

а можно тут писать func_vect[i] = func1(i);
а вызывать уже func_vect[i-1]?

GOre01 18.05.2006 11:52

Цитата:

Kvarx:
а можно тут писать func_vect[i] = func1(i);
а вызывать уже func_vect[i-1]?
нет, так нельзя, потомучто func(i) возвращает результат выполнения функции, но не адрес этой функции.

_Lynx_ 18.05.2006 13:14

То есть такая конструкция (массив) особого смысла не имеет, разве что забить указатели на разные функции.

GOre01 18.05.2006 15:44

да, конструкция имеет смысл, если мы хотим организовать доступ к различным функциям по индексу, например, выбор элемента меню.
гдето в программе:
Код:

void cut();
void copy();
void paste();

typedef void (*paction)(void);

void main()
{
  paction actions[3];
  actions[0] = cut;
  actions[1] = copy;
  actions[2] = paste;
  //..... выполняем какие-то действия
  // при которых пользователь выбрал в меню какой-то пункт
  // и получаем

  actions[menuitem];
}

что-то вроде.

alexey_ma 18.05.2006 21:19

Такие конструкции довольно широко применяются. Если мне не изменяет память, то message map в библиотеке WTL реализован как массив указателей на функции.

knight 23.05.2006 17:56

Не уверен но по моему message map в MFC организован также, хотя проверю, благо есть GO TO DEFINITION -)))

alexey_ma 26.05.2006 01:14

В MFC по другому
http://rsdn.ru/article/wtl/wtl-1.xml#ERPAE

VanHelsing 07.02.2007 10:58

ситуация такая, решил замутить себе либу с функцией split (стандартные не предлагать :rolleyes: ).
сама функция:
Код:

char ** _ARRAY;

char ** split(char _SPLITTER, char * _STRING_TO_SPLIT) {
        int _STRING_SIZE=0;
        int _LINES_QUANTITY=0;
        int _CHARS_IN_LINE=0;
        int _MOST_LONG_LINE=0;

        while(_STRING_TO_SPLIT[_STRING_SIZE]!='\0') {

                _CHARS_IN_LINE++;

                if(_STRING_TO_SPLIT[_STRING_SIZE]==_SPLITTER) {
                        _CHARS_IN_LINE=0;
                        _LINES_QUANTITY++;
                }

                if(_MOST_LONG_LINE<_CHARS_IN_LINE) {
                        _MOST_LONG_LINE=_CHARS_IN_LINE;
                }
                _STRING_SIZE++;
        }

        int _CURRENT_LINE_NUM;
        _ARRAY=new char * [_LINES_QUANTITY];
        for(_CURRENT_LINE_NUM=0;_CURRENT_LINE_NUM<_LINES_QUANTITY;_CURRENT_LINE_NUM++) {
                _ARRAY[_CURRENT_LINE_NUM]=new char [_MOST_LONG_LINE];
        }

        int _CURRENT_CHAR_IN_LINE;
        int _CURRENT_CHAR_IN_STRING=0;

        for(_CURRENT_LINE_NUM=0;_CURRENT_LINE_NUM<_LINES_QUANTITY;_CURRENT_LINE_NUM++) {
                for(_CURRENT_CHAR_IN_LINE=0;_CURRENT_CHAR_IN_LINE<_MOST_LONG_LINE;_CURRENT_CHAR_IN_LINE++) {


                        _ARRAY[_CURRENT_LINE_NUM][_CURRENT_CHAR_IN_LINE]=0x00;
                }
        }

        for(_CURRENT_LINE_NUM=0;_CURRENT_LINE_NUM<_LINES_QUANTITY;_CURRENT_LINE_NUM++) {
                for(_CURRENT_CHAR_IN_LINE=0;_CURRENT_CHAR_IN_LINE<_MOST_LONG_LINE;_CURRENT_CHAR_IN_LINE++) {

                        if(_STRING_TO_SPLIT[_CURRENT_CHAR_IN_STRING]==_SPLITTER) {

                                _CURRENT_CHAR_IN_STRING++;
                                break;
                        }

                        _ARRAY[_CURRENT_LINE_NUM][_CURRENT_CHAR_IN_LINE]=_STRING_TO_SPLIT[_CURRENT_CHAR_IN_STRING];
                        _CURRENT_CHAR_IN_STRING++;
                }
        }
}

есть массив buffer представляющий из себя текстовый файл. надо, что бы функция вызывалась так
Код:

char ** db;
db=split('\n', buffer);

и что бы потом можно было работать с массивом db как с одномерным. что бы db[0] была первая строка! файла, db[100] 99-ая строка файла etc.

не могу понять почему не работает. если функция возвращает return ** _ARRAY; то вообще ругается invalid conversion from `char' to `char**'

компилятор g++ под винду. буду признателен всем за помощь :beer:

зы: не строго судите, если не там разместил, имхо, как раз про указатели тема

Flexz 07.02.2007 16:24

В код сильно не вчитывался, но зачем две звездочки в return ** _ARRAY;?
Указатель дважды разименовывается и получается char.
Функция возвращает char** и _ARRAY имет тип char**, вот и возвращаться нужно прямо _ARRAY, т.е.
return _ARRAY;
и все.
Вообще писать в глобальные перемынные, мягко говоря, не хорошо :)

По поводу самой функции - не знаю ваши конкретные требования к этой функии, но не проще ли собрать указатели на начала строк (т.е. db[0] - будет указывать на первый символ исходной строки, db[1] на символ следующий за первым символом перевода строки) и заменить переводы строки нулями?

VanHelsing 07.02.2007 17:27

видимо надо еще почитать про функции возвращающие значения. я считал, что переменная, в которую возвращается значение (и которую функция вовзращает) должна быть того же типа, что и возвращаемое значение. все заработало, спасибо :beer:

по поводу самой функции, честно сказать, я еще не очень догоняю сам С с его "привычками", мне ближе асм, но нынче на нем писать жутко долго. если db[0] это первый символ строки, то как мне обратиться ко второму? db[0][1]? в моем случае мне понятно, что db[0][0] это первый символ первой строки.

зы: я на спектруме начинал, а там только асм, и я к нему привык так, что мне даже PCшный асм не очень понятен под винду :confused:

Flexz 08.02.2007 10:47

Если db определено как
char **db;
то db[0] - указатель на первый симовл первой строки (он имеет тип char*), db[0][0] - сам символ (тип char), и тд - db[0][1] - второй символ первой строки, db[1][0] - первый символ второй строки...
Кстати, есть стандартная функция strtok, которая по сути выполняет то, что я описал.

а я на спектруме хоть и начинал, но на асм так и не сподвигся :)

VanHelsing 08.02.2007 11:35

Цитата:

Сообщение от Flexz (Сообщение 1351830)
Если db определено как
char **db;
то db[0] - указатель на первый симовл первой строки (он имеет тип char*), db[0][0] - сам символ (тип char), и тд - db[0][1] - второй символ первой строки, db[1][0] - первый символ второй строки...
Кстати, есть стандартная функция strtok, которая по сути выполняет то, что я описал.

в моем случае так и получается, что db[0][0] первый символ первой строки db[1][0] первый символ второй строки. а strtok мне не очень нравится, да и логика ее мне не очень понятна. она обрезает до первого токена часть строки, потом дальше от текущего токена до следующего (если я все прально понял), так она тогда и получается, что делает то же, что моя только немного по другому. мне так привычней просто с символами работать :idontnow:

мой вопрос исчерпан. спасибо за помощь! (с занесением) и спасибо за совет по поводу глобальных переменных, убрал ее в функцию. я ее изначально туда вынес, так как немного иным путем реализовал вначале, т.е. я потом и работал с массивом _ARRAY :)


Часовой пояс GMT +4, время: 17:32.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.