imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 18.05.2006, 01:41     # 1
Kvarx
Member
 
Регистрация: 26.09.2005
Адрес: Питер
Сообщения: 336

Kvarx Известность не заставит себя ждатьKvarx Известность не заставит себя ждать
Указатель на функцию и его использование в С++

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

Спасибо.
Kvarx вне форума  
Старый 18.05.2006, 06:41     # 2
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Что-то как-то мутно сформулировано. Что нужно-то, вызов функции при обращении к элементу массива или я не понял?
__________________
Дураки не динозавры - они не вымрут...
PSyton вне форума  
Старый 18.05.2006, 11:07     # 3
GOre01
Junior Member
 
Аватар для GOre01
 
Регистрация: 10.08.2004
Адрес: Завис в конторе
Пол: Male
Сообщения: 180

GOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царстве
что-то так
Код:
// функция 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));
	}
}
или я не до конца понял задание
__________________
Не нервируйте меня. Мне скоро негде будет прятать трупы!
GOre01 вне форума  
Старый 18.05.2006, 11:16     # 4
Kvarx
Member
 
Регистрация: 26.09.2005
Адрес: Питер
Сообщения: 336

Kvarx Известность не заставит себя ждатьKvarx Известность не заставит себя ждать
GOre01,

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

Цитата:
Сообщение от GOre01
func_vect[i] = func1;
а можно тут писать func_vect[i] = func1(i);
а вызывать уже func_vect[i-1]?
Kvarx вне форума  
Старый 18.05.2006, 11:52     # 5
GOre01
Junior Member
 
Аватар для GOre01
 
Регистрация: 10.08.2004
Адрес: Завис в конторе
Пол: Male
Сообщения: 180

GOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царстве
Цитата:
Kvarx:
а можно тут писать func_vect[i] = func1(i);
а вызывать уже func_vect[i-1]?
нет, так нельзя, потомучто func(i) возвращает результат выполнения функции, но не адрес этой функции.
__________________
Не нервируйте меня. Мне скоро негде будет прятать трупы!
GOre01 вне форума  
Старый 18.05.2006, 13:14     # 6
_Lynx_
Junior Member
 
Регистрация: 11.10.2005
Сообщения: 63

_Lynx_ Путь к славе только начался
То есть такая конструкция (массив) особого смысла не имеет, разве что забить указатели на разные функции.
_Lynx_ вне форума  
Старый 18.05.2006, 15:44     # 7
GOre01
Junior Member
 
Аватар для GOre01
 
Регистрация: 10.08.2004
Адрес: Завис в конторе
Пол: Male
Сообщения: 180

GOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царствеGOre01 Луч света в тёмном царстве
да, конструкция имеет смысл, если мы хотим организовать доступ к различным функциям по индексу, например, выбор элемента меню.
гдето в программе:
Код:
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];
}
что-то вроде.
__________________
Не нервируйте меня. Мне скоро негде будет прятать трупы!
GOre01 вне форума  
Старый 18.05.2006, 21:19     # 8
alexey_ma
Member
 
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245

alexey_ma Нимб уже пробиваетсяalexey_ma Нимб уже пробивается
Такие конструкции довольно широко применяются. Если мне не изменяет память, то message map в библиотеке WTL реализован как массив указателей на функции.
__________________
Best Regards
alexey_ma вне форума  
Старый 23.05.2006, 17:56     # 9
knight
Junior Member
 
Регистрация: 12.09.2004
Сообщения: 106

knight Известность не заставит себя ждатьknight Известность не заставит себя ждать
Не уверен но по моему message map в MFC организован также, хотя проверю, благо есть GO TO DEFINITION -)))
knight вне форума  
Старый 26.05.2006, 01:14     # 10
alexey_ma
Member
 
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245

alexey_ma Нимб уже пробиваетсяalexey_ma Нимб уже пробивается
В MFC по другому
http://rsdn.ru/article/wtl/wtl-1.xml#ERPAE
__________________
Best Regards
alexey_ma вне форума  
Старый 07.02.2007, 10:58     # 11
VanHelsing
Junior Member
 
Аватар для VanHelsing
 
Регистрация: 18.04.2005
Сообщения: 157

VanHelsing Реально крут(а)VanHelsing Реально крут(а)VanHelsing Реально крут(а)VanHelsing Реально крут(а)
ситуация такая, решил замутить себе либу с функцией split (стандартные не предлагать ).
сама функция:
Код:
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++ под винду. буду признателен всем за помощь

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

Последний раз редактировалось VanHelsing; 07.02.2007 в 11:01.
VanHelsing вне форума  
Старый 07.02.2007, 16:24     # 12
Flexz
Newbie
 
Регистрация: 17.06.2002
Сообщения: 30

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

По поводу самой функции - не знаю ваши конкретные требования к этой функии, но не проще ли собрать указатели на начала строк (т.е. db[0] - будет указывать на первый символ исходной строки, db[1] на символ следующий за первым символом перевода строки) и заменить переводы строки нулями?
Flexz вне форума  
Старый 07.02.2007, 17:27     # 13
VanHelsing
Junior Member
 
Аватар для VanHelsing
 
Регистрация: 18.04.2005
Сообщения: 157

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

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

зы: я на спектруме начинал, а там только асм, и я к нему привык так, что мне даже PCшный асм не очень понятен под винду
__________________
VanHelsing вне форума  
Старый 08.02.2007, 10:47     # 14
Flexz
Newbie
 
Регистрация: 17.06.2002
Сообщения: 30

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

а я на спектруме хоть и начинал, но на асм так и не сподвигся
Flexz вне форума  
Старый 08.02.2007, 11:35     # 15
VanHelsing
Junior Member
 
Аватар для VanHelsing
 
Регистрация: 18.04.2005
Сообщения: 157

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

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

Последний раз редактировалось VanHelsing; 08.02.2007 в 11:45.
VanHelsing вне форума  


Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


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




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