Как вызвать void функцию c
Перейти к содержимому

Как вызвать void функцию c

  • автор:

void (C++)

При использовании в качестве возвращаемого типа функции ключевое слово указывает, void что функция не возвращает значение. При использовании для списка параметров функции указывает, void что функция не принимает параметров. При использовании в объявлении указателя указывает, void что указатель является универсальным.

Если тип указателя равен void* , указатель может указывать на любую переменную, которая не объявлена с const помощью или volatile ключевое слово. void* Указатель не может быть разыменован, если только он не приведение к другому типу. void* Указатель можно преобразовать в любой другой тип указателя данных.

В C++ void указатель может указывать на бесплатную функцию (функцию, не являющуюся членом класса), или на статическую функцию-член, но не на нестатическую функцию-член.

Невозможно объявить переменную типа void .

В соответствии с стилем рекомендации по основной версии C++ не используются void для указания пустого списка формальных параметров. Дополнительные сведения см. в руководстве по C++ Core NL.25: не используйте void в качестве типа аргумента.

Пример

// void.cpp void return_nothing() < // A void function can have a return with no argument, // or no return statement. >void vobject; // C2182 void *pv; // okay int *pint; int i; int main() < pv = &i; // Cast is optional in C, required in C++ pint = (int *)pv; >

Как вызвать функцию?

Author24 — интернет-сервис помощи студентам

Как вызвать функцию ?
Вот у меня есть вот такая функция как её вызвать ? void CAimbot::pSilent(CUserCmd* pCmd)

Как вызвать функцию
Хочу создать хранилище , у базового класса есть функция virtual void parametri() < cout << ".

Как вызвать функцию ?
Не получается вызвать значение функции из number #include <iostream> int number(int x) < x.

270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#define FUNC(num) &print##num using namespace std; void print1() { cout  "print1"  endl; } void print2() { cout  "print2"  endl; } typedef void (*funcPtr)(void); int main() { funcPtr func = FUNC(1); (*func)(); system("pause"); return 0; }

Регистрация: 27.05.2010
Сообщений: 6

а мне нужно чтобы в 17 строке
funcPtr func = FUNC(1);
я вместо 1 мог указать какуюто переменную
скажем FUNC(ss);
а он сразу говорит что printss незадекларированная

2021 / 1620 / 489
Регистрация: 31.05.2009
Сообщений: 3,005

ЦитатаСообщение от marat1 Посмотреть сообщение

У меня допустим есть уже готовые функции с именами от а0 до а1000
Честно говоря уже попахивает извращением. Для чего такое понадобилось, если не секрет?

ЦитатаСообщение от marat1 Посмотреть сообщение

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

Массив указателей на функции.
Регистрация: 27.05.2010
Сообщений: 6

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

если переременная а = 10
то нужно запустить функцию b10()

может ето дело кто нибуть перевести ето дело в рабочий, минимальній код. Пожалуйста, я новичок.

Добавлено через 19 минут
rangerx просту у меня есть функция которая должна в свою очередь запускать иные уже готовые функции. каждый раз изходя из вводных параметров имя фукции меняется
пример

если переременная а = 10
то нужно запустить функцию b10()

может ето дело кто нибуть перевести ето дело в рабочий, минимальній код. Пожалуйста, я новичок.

Добавлено через 27 минут
Manjak а что ты можешь сказать?

2021 / 1620 / 489
Регистрация: 31.05.2009
Сообщений: 3,005

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include void a0(){ puts("in a0"); } void a1(){ puts("in a1"); } void a2(){ puts("in a2"); } typedef void (*pFunc)(); int main() { pFunc func[3] = {a0, a1, a2}; func[0](); func[1](); func[2](); return 0; }

но я с трудом представляю себе программу с 1000 таких функиций.
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
Можно дико извратиться со смещениями в памяти и искать так функции, но это уже неимоверный изврат
14 / 20 / 14
Регистрация: 20.03.2018
Сообщений: 485

По моему так проще для понятия что это такое
типа замены GOTO оператора BASIC по выполнению какого то кода
в другой части программы

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
// #include "stdafx.h" #include using namespace std; void menu777() { std::cout  "TEXT FROM menu777 \n\n" endl; } //__________________________________________________ int main() // код основной программы { { //какой то код cout  "TEXT MAIN PROGRAMM \n\n "; } { menu777(); // вызов всего кода из функции system("pause"); return 0; } }

Функции в C++ — урок 6

Сегодня мы поговорим о функциях в C++. Очень часто в программировании необходимо выполнять одни и те же действия. Например, мы хотим выводить пользователю сообщения об ошибке в разных местах программы, если он ввел неверное значение. без функций это выглядело бы так:

#include #include using namespace std; int main() < string valid_pass = "qwerty123"; string user_pass; cout else < cout return 0; > 

А вот аналогичный пример с функцией:

#include #include using namespace std; void check_pass (string password) < string valid_pass = "qwerty123"; if (password == valid_pass) < cout else < cout > int main()

По сути, после компиляции не будет никакой разницы для процессора, как для первого кода, так и для второго. Но ведь такую проверку пароля мы можем делать в нашей программе довольно много раз. И тогда получается копипаста и код становится нечитаемым. Функции — один из самых важных компонентов языка C++.

  • Любая функция имеет тип, также, как и любая переменная.
  • Функция может возвращать значение, тип которого в большинстве случаев аналогично типу самой функции.
  • Если функция не возвращает никакого значения, то она должна иметь тип void (такие функции иногда называют процедурами)
  • При объявлении функции, после ее типа должно находиться имя функции и две круглые скобки — открывающая и закрывающая, внутри которых могут находиться один или несколько аргументов функции, которых также может не быть вообще.
  • после списка аргументов функции ставится открывающая фигурная скобка, после которой находится само тело функции.
  • В конце тела функции обязательно ставится закрывающая фигурная скобка.

Пример построения функции

#include using namespace std; void function_name () < cout int main() < function_name(); // Вызов функции return 0; >

Перед вами тривиальная программа, Hello, world, только реализованная с использованием функций.

Если мы хотим вывести «Hello, world» где-то еще, нам просто нужно вызвать соответствующую функцию. В данном случае это делается так: function_name(); . Вызов функции имеет вид имени функции с последующими круглыми скобками. Эти скобки могут быть пустыми, если функция не имеет аргументов. Если же аргументы в самой функции есть, их необходимо указать в круглых скобках.

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

В предыдущих примерах мы использовали функции типа void , которые не возвращают никакого значения. Как многие уже догадались, оператор return используется для возвращения вычисляемого функцией значения.

Рассмотрим пример функции, возвращающей значение на примере проверки пароля.

#include #include using namespace std; string check_pass (string password) < string valid_pass = "qwerty123"; string error_message; if (password == valid_pass) < error_message = "Доступ разрешен."; >else < error_message = "Неверный пароль!"; >return error_message; > int main()

В данном случае функция check_pass имеет тип string, следовательно она будет возвращать только значение типа string, иными словами говоря строку. Давайте рассмотрим алгоритм работы этой программы.

Самой первой выполняется функция main(), которая должна присутствовать в каждой программе. Теперь мы объявляем переменную user_pass типа string, затем выводим пользователю сообщение «Введите пароль», который после ввода попадает в строку user_pass. А вот дальше начинает работать наша собственная функция check_pass() .

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

Аргумент функции — это, если сказать простым языком переменные или константы вызывающей функции, которые будет использовать вызываемая функция.

При объявлении функций создается формальный параметр, имя которого может отличаться от параметра, передаваемого при вызове этой функции. Но типы формальных параметров и передаваемых функии аргументов в большинстве случаев должны быть аналогичны.

После того, как произошел вызов функции check_pass() , начинает работать данная функция. Если функцию нигде не вызвать, то этот код будет проигнорирован программой. Итак, мы передали в качестве аргумента строку, которую ввел пользователь.

Теперь эта строка в полном распоряжении функции (хочу обратить Ваше внимание на то, что переменные и константы, объявленные в разных функциях независимы друг от друга, они даже могут иметь одинаковые имена. В следующих уроках я расскажу о том, что такое область видимости, локальные и глобальные переменные).

Теперь мы проверяем, правильный ли пароль ввел пользователь или нет. если пользователь ввел правильный пароль, присваиваем переменной error_message соответствующее значение. если нет, то сообщение об ошибке.

После этой проверки мы возвращаем переменную error_message . На этом работа нашей функции закончена. А теперь, в функции main(), то значение, которое возвратила наша функция мы присваиваем переменной error_msg и выводим это значение (строку) на экран терминала.

Также, можно организовать повторный ввод пароля с помощью рекурсии (о ней мы еще поговорим). Если объяснять вкратце, рекурсия — это когда функция вызывает сама себя. Смотрите еще один пример:

#include #include using namespace std; bool password_is_valid (string password) < string valid_pass = "qwerty123"; if (valid_pass == password) return true; else return false; >void get_pass () < string user_pass; cout else < cout > int main()

Функции очень сильно облегчают работу программисту и намного повышают читаемость и понятность кода, в том числе и для самого разработчика (не удивляйтесь этому, т. к. если вы откроете код, написанный вами полгода назад,не сразу поймете соль, поверьте на слово).

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

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

Если Вы найдете какие-либо ошибки в моем коде, обязательно напишите об этом в комментариях. здесь же можно задавать все вопросы.

Как вызвать функцию как аргумент?

Смысл такой, что нужно расписать программу для сортировки массива по функциям без использования глобальных переменных. Я решил пойти путём вызова функций как параметров для функций(ведь это же можно сделать с помощью указателей. ) Листинг моего «чудо»-кода:

#include #include using namespace std; void print(double a[10]) < //double a[10]; for (int i = 0; i < 10; i++) < cout > double find_min_element(double a[10]) < double var; // double a[10]; int n = 10; var = 9223372036854775807; int index = 0; for (int i = 0; i < n - 1; i++) < if (a[i] < var) < var = a[i]; index = i; >> return index; > double sort_array(double a[10]) < //double a[10]; int m; int n = 10; for (int i = 0; i < n; i++) < m = i; for (int j = i + 1; j < n; j++) < if (a[j] < a[i]) < m = j; swap(a[i], a[m]); >> cout return a[n]; > double filling() < int i; double a[10]; int n = 10; cout > a[i]; > return a[i]; > int main(int argc, char** argv) < //using pointer_to_function = double(*)(); //int (*pointerToFunction)(double ) = NULL; //pointerToFunction = &filling; pointer_to_function ptf = filling; filling(); find_min_element( ptf); /*В find_min_element надо отправить заполненный массив. Такой у нас имеется после вызова filling. Так как глобальные переменные использовать нельзя, то получается, что в main'е зацепить массив в переменную я не могу*/ print(ptf); return 0; >

На выходе компилятор выдаёт следующие ошибки

g++ -Wall -c «Functions.cxx» (в каталоге: /home/alex/Yandex.Disk/Программирование/1D_arrays_from_functions) Functions.cxx: In function ‘int main(int, char**)’: Functions.cxx:94:8: error: expected nested-name-specifier before ‘pointer_to_function’ using pointer_to_function = double(*)(); ^ Functions.cxx:97:2: error: ‘pointer_to_function’ was not declared in this scope pointer_to_function ptf = filling; ^ Functions.cxx:99:19: error: ‘ptf’ was not declared in this scope
find_min_element(ptf);
^ Сборка завершилась с ошибкой.

Среда — Geany, g++. ^ — разделитель между ошибками.
Отслеживать
219k 15 15 золотых знаков 120 120 серебряных знаков 230 230 бронзовых знаков
задан 18 фев 2017 в 5:13
39 7 7 бронзовых знаков

Из того, что «глобальные переменные использовать нельзя», следует, что надо использовать локальные переменные. К чему тут вдруг указатели не функции — не ясно.

18 фев 2017 в 9:36

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Вы уж извините, но у вас код. Давайте по нему пройдемся.

void print(double a[10]) < //double a[10]; for (int i = 0; i < 10; i++) < cout > 

Пожалуй, одна из реально работающих функций 🙂

double find_min_element(double a[10]) < double var; int n = 10; var = 9223372036854775807; 

Что за странная константа? Тем более что double такую точность не поддерживает, и все равно ее обрежет. А если вы хотели максимальное значение double , так это numeric_limits::max() .

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

Почему вы не рассматриваете последний элемент массива? И вообще - зачем вводить переменную, если это у вас - жестко прошитая константа?

double sort_array(double a[10])  

Честно говоря, на беглый взгляд вроде и ничего. но зачем эта переменная m ? int m;

И что вы возвращаете? Несуществующий элемент массива? Зачем? return a[n]; >

double filling() < int i; double a[10]; int n = 10; cout > a[i]; > 

Допустим. Заполнили. Заполнили локальный массив, который при выходе из функции исчезнет.

 return a[i]; 

И опять вернули несуществующий элемент.

int main(int argc, char** argv) < //using pointer_to_function = double(*)(); 

Это правильное объявление типа для указателя на filling , только раскомментировать 🙂

 //int (*pointerToFunction)(double ) = NULL; 

А это какая-то ерунда; если вы хотели так сделать указатель на filling , то писать надо double (*ptf)() = filling;

 pointer_to_function ptf = filling; filling(); find_min_element(ptf); 

Ваша функция требует передачи ей массива, а вы передаете ей указатель на функцию. И что ей с ним делать?

 print(ptf); 

Собственно, все, что от вас хотел преподаватель, я выложил вот тут (земенив только чтение массива заполнением случайными числами): http://ideone.com/w70pVj Вам нужно было передавать массив и его размер. Все. Так никаких глобальных переменных нет. Работать с указателями на функции можно (а иногда и нужно :)), но не в вашем случае.

Отслеживать
ответ дан 18 фев 2017 в 6:19
219k 15 15 золотых знаков 120 120 серебряных знаков 230 230 бронзовых знаков

Используйте std::vector вместо массива. Или же вместе с массивом передавайте его размер. В Вашем случае 10. Можно обойтись и без глобальных переменных и без указателей на функции. Функция sort_array возвращает 1 значения типа double a[10], которое выходит за пределы массива.filling - аналогично.

Отслеживать
ответ дан 18 фев 2017 в 6:18
4,030 1 1 золотой знак 11 11 серебряных знаков 19 19 бронзовых знаков

В вашей программе имеется несколько ошибок.

Функцию print правильно будет объявить, указав второй параметр - размер массива, так как в самой функции не возможно определить размер переданного ей массива в качестве аргумента, так как он неявно преобразуется в указатель на свой первый элемент. То есть в данном объявлении параметра функции

void print(double a[10]); ^^^^ 

число 10 не играет никакой роли, так как та же самая функция может быть объявлена с любым значением размера массива, который просто игнорируется в виду преобразования параметра массива в указатель на элемент массива. То есть данные объявления функций эквивалентны и объявляют одну и ту же функцию

void print(double a[100]); void print(double a[10]); void print(double a[]); void print(double *a); 

Поэтому правильно будет определить функцию следующим образом

void print( const double a[], size_t n ) < for ( size_t i = 0; i < n; i++ ) < std::cout > 

Можно объявить функцию с одним параметром. Но в этом случае тип параметра должен быть ссылкой на массив. Например

void print( const double ( &a )[10] ) < for ( size_t i = 0; i < 10; i++ ) < std::cout > 

Или, если компилятор поддерживает цикл for на основе диапазона, то можно записать

void print( const double ( &a )[10] ) < for ( double x : a ) < std::cout > 

Для функции find_min_element имеется точно такая же проблема с объявлением функции. Кроме того используется некая магическая константа, не понятно, откуда взявшаяся, использование которой может дать результат не тот, который вы ожидаете, так как при преобразовании к типу double может иметь место ее неточное представление.

К тому же почему-то последний элемент массива игнорируется

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

Имеется стандартный алгоритм std::min_element , объявленный в заголовке , который выполняет задачу по поиску минимального элемента массива. Кроме того вы объявили тип возвращаемого значения функции как double в то время, как возвращаете индекс на минимальный элемент. Логичнее было бы, если бы возвращаемый тип значения функции был целочисленным. А иначе это вводит в заблуждение читающих ваш код, так как можно подумать, что возвращается не индекс минимального значения, а само минимальное значение.

size_t find_min_element( const double a[], size_t n ) < size_t min_i = 0; for ( size_t i = 1; i < n; i++ ) < if ( a[i] < a[min_i] ) < min_i = i; >> return min_i; > 

Или если объявить первый параметр функции как ссылку на массив, то

size_t find_min_element( const double ( &a )[10] ) < size_t min_i = 0; for ( size_t i = 1; i < 10; i++ ) < if ( a[i] < a[min_i] ) < min_i = i; >> return min_i; > 

В функции сортировки существует та же самая, описанная выше проблема с объявлением функции. Измените ее объявление, как это показано для других функций. Кроме того функция имеет неопределенное поведение, так как она возвращает из функции не существующий элемент массива. То есть идет обращение к памяти за пределами массива.

return a[n]; ^^^^^ 

Нет никакого смысла что-о возвращать из функции. Поэтому лучше объявить тип возвращаемого значения как Void . Например,

void sort_array( double a[], size_t n ); 
void sort_array( double ( &a )[10] ); 

В функции filling заполняется локальный массив, который прекратит свое существование после выхода из функции, и снова возвращается из функции несуществующий элемент локального массива. ТО есть функция имеет неопределенное поведение.

Измените ее объявление как

void filling( double a[], size_t n ); 
void filling( double ( &a )[10] ); double filling() < int i; double a[10]; int n = 10; cout > a[i]; > return a[i]; > 

Судя по первому показанному сообщению об ошибке

Functions.cxx: In function ‘int main(int, char**)’: Functions.cxx:94:8: error: expected nested-name-specifier before ‘pointer_to_function’ using pointer_to_function = double(*)();

ваш компилятор не поддерживает объявление алиаса с использованием ключевого слова using .

Поэтому попробуйте заменить его на typedef объявление

typedef double( *pointer_to_function )(); 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *