Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
1

В чем разница между типом функции и типом возвращаемого значения?

19.08.2015, 08:48. Показов 3969. Ответов 39
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Читаю статью
https:// code-live. ru/post/cpp-functions/ (ссылку изменил дабы не делать рекламу)

Там написано
- Любая функция имеет тип, также, как и любая переменная.
- Функция может возвращать значение, тип которого в большинстве случаев аналогично типу самой функции.

Пример
-----------------------------
C++
1
2
3
4
5
6
7
8
9
10
11
string check_pass (string password)
{
    string valid_pass = "qwerty123";
    string error_message;
    if (password == valid_pass) {
        error_message = "Доступ разрешен.";
    } else {
        error_message = "Неверный пароль!";
    }
    return error_message;
}
-------------------------------


Я этот код вижу так

тип_возвращаемого_значения имя_функции (тип_аргумента аргумент_функции)
{
тело_функции
возвращаемое_значение_согласно_типу_возвращаемого_значения

}

Что такое тип функции (он тут есть?), в чем разница между типом функции и типом возвращаемого значения и как тип функции и тип возвращаемого значения могут различаться?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2015, 08:48
Ответы с готовыми решениями:

Нужно сделать чтобы можно было управлять типом возвращаемого значения функции
// avg_function.cpp: определяет точку входа для консольного приложения. #include "stdafx.h"...

Сложности с типом возвращаемого значения Серийного номера
Считываю серийный номер флешки с помощью API-функции GetVolumeInformation, но проблема в том, что...

Почему ковариантный тип может быть только типом возвращаемого значения метода?
Почему ковариантный тип T может быть только типом возвращаемого значения метода? Вот мои мысли: 1)...

Нужно переменной с типом real присвоить выражение a1 mod 2, где a1 - это переменная с типом integer.
Такой вопрос . Мне нужно переменной с типом real присвоить выражение a1 mod 2 где a1 это...

39
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
19.08.2015, 13:03  [ТС] 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Ilot Посмотреть сообщение
Еще раз тип функции это правило
Тип не может быть правилом. Мы о каком типе говорим? Возможно, под типом вы подразумеваете что-то другое?
Основные типы в С++ делятся на три категории: целочисленные, с плавающей запятой и void.
int это правило? string это правило?

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

Но вы не ответили на вопрос где в коде тип функции и где тип возвращаемого значения?
Мне не нужно знать, кто и что определяет, располагает и т.д. Я не прошу вас это рассказать.
Мне нужно 2 слова.

Смотрите
int a=5; //Слово int, тип данных int. Я понимаю. Вижу ключевое слово, обозначающее тип данных.
string check_pass (string password) // Вижу ключевое слово string. Что оно обозначает? Тип функции или тип возвращаемого значения?

Вы понимаете, я уже час пытаюсь сказать - что должно быть 2 ключевых слова. Одно - тип функции, другое тип возвращаемого значения.
Два слова. А тут одно. В этом весь вопрос.
Я даже предположил, что это одно слово сразу определяет 2 типа (а какой вывод ещё может быть?). Но вы отвергли это предположение.

Где второе слово? Откуда вы взяли что тип функции string? Как вы вычислили это? Этой информации нет в коде. Физически нет.
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
19.08.2015, 13:18 22
Цитата Сообщение от useruser Посмотреть сообщение
Вы понимаете, я уже час пытаюсь сказать - что должно быть 2 ключевых слова. Одно - тип функции, другое тип возвращаемого значения.
Два слова. А тут одно. В этом весь вопрос.
Ответ на этот вопрос прозвучал:
Цитата Сообщение от Ilot Посмотреть сообщение
В тип функции входит тип возвращаемого значения, типы входящих параметров и квалификаторы (const, volatile и т.д.).
Вам ответили на все вопросы. Читайте внимательнее.
0
70 / 64 / 40
Регистрация: 17.02.2014
Сообщений: 265
19.08.2015, 13:33 23
useruser, У функции есть только возвращаемое значение и сигнатура в которую входит имя функции и его аргументы, больше там ничего нету (исключение - методы класса где добавляются некоторые другие особенности).
0
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
19.08.2015, 13:36  [ТС] 24
Цитата Сообщение от Ilot Посмотреть сообщение
Читайте внимательнее.
Я внимательно читаю и не по одному разу. Стараюсь понять и сделать выводы. Но ответа на свой вопрос не получаю.

Хорошо, попробую по другому. Многие языки программирования схожи. В основном.
Код делфи.
Delphi
1
function ReturnNumber(inText: AnsiString): Int64;
Где здесь тип функции? Его нет. Если скажете, что Int64 -это тип функции, то приведу сообщение компилятора (при комментировании Int64).
function needs result type.
Обратимся к официальной справке разработчика. You have declared a function, but have not specified a return type.
Что означает - Вы объявили функцию, но не указали тип возвращаемого значения. Вывод - Int64 тип возвращаемого значения.
Где тип функции? Подозреваю, что его нет.

В с++ синтаксис другой, но количество операторов тоже, только изменено их расположение
C++
1
string check_pass (string password)
Практически полная аналогия.
Может нет никакого типа функции, а есть только тип возвращаемого значения?

Добавлено через 33 секунды
Цитата Сообщение от smartpointer Посмотреть сообщение
больше там ничего нету
Выше утверждают что есть.
Ищу уже 3 часа. Не могу понять где.
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
19.08.2015, 14:09 25
Цитата Сообщение от useruser Посмотреть сообщение
Основные типы в С++ делятся на три категории: целочисленные, с плавающей запятой и void.
А как же массивы, указатели, классы, структуры, объединения, ссылки?
Цитата Сообщение от useruser Посмотреть сообщение
Где тип функции? Подозреваю, что его нет.
Он как суслик, ты его не видишь, но он есть.
Тут функция имеет тип Int64(AnsiString). как правильно записать это в delphi не знаю, но функциональные типы там то же есть
Функцию можно рассматривать как черный ящик, в который кладешь набор объектов, они как-то обрабатываются, и получается другой объект - возвращаемое значение.
Например
sin - принимает double, возвращает double.
Тип функции double(double). Тип Возвращаемого значения double.
cos - аналогично. Тип функции double(double), возвращаемое значение - double.
т.е. у функций sin и cos один и тот же и тип функций, и тип возвращаемого значения.
у функции с прототипом
C++
1
double foo(int);
тип double(int), а тип возвращаемого значения double.
тип возвращаемого значения такой же как у sin и cos, но тип функции уже другой.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <cmath>
using namespace std;
 
void calc(double func(double), double val) {
    cout << func(val) << endl;
}
 
double foo(int x) {
    return 0.1*x;
}
 
int main() {
    calc(cos, 0.0); // ok
    calc(sin, 0.0); // ok
    // calc(foo, 0.0); ошибка, тип 1 параметра не подходит
    return 0;
}
1
99 / 46 / 18
Регистрация: 09.08.2015
Сообщений: 367
19.08.2015, 14:19 26
Цитата Сообщение от useruser Посмотреть сообщение
Где здесь тип функции?
Int64 (AnsiString)

Ну если на С++.

double Sum(short a, const int b) - функция.
double - тип возвращаемого значения.
(short, const int) - аргументы.
double(short, const int) - тип функции.
Sum, a, b - переменные (в первой храниться функция заданного выше типа, в остальных аргументы).

Вместо одной функции можно безболезненно подставить другую функцию такого же типа.
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
19.08.2015, 14:24 27
Цитата Сообщение от useruser Посмотреть сообщение
Где тип функции?
Давай по пунктам.
1) Ты пишешь функцию:
C++
1
int check_pass (string password);
здесь:
int - это тип возвращаемого значения функции
string - тип аргумента функции.
Здесь понятно?

2) Теперь переходим к типу функции. Вот есть запись:
C++
1
int check_pass (string password);
Это объявление функции. Объявление функции неявно содержит тип функции.
Т.е. задав функцию, ты сразу же задаешь и ее тип, как head-n-shoulders, в одном флаконе.
Явно тип функции записывается так (задается псевдоним типа через typedef):
C++
1
2
3
typedef int func_type(string); // тип функции с именем func_type, функция возвращает int, принимает string
typedef int(*fync_type_p)(string); // тип указателя на функцию fync_type_p
typedef int(&func_type_r)(string); // тип ссылки на функцию fync_type_r
Получить тип функции из определения функции можно также с помощью ключевого слова decltype. Например вот таким образом можно определить функцию, которая принимает другую функцию:
C++
1
2
3
4
5
6
7
8
int func(std::string v)
{
}
 
void func1(decltype(func) f)
{
    f("test");
}
Вот работоспособный пример в онлайн компиляторе: http://rextester.com/JRRAW96132
_____
Еще раз для закрепления: объявление функции неявно в себе содержит тип этой функции.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.08.2015, 14:24 28
Цитата Сообщение от Ilot Посмотреть сообщение
Попробуйте так:
Цитата Сообщение от Ilot Посмотреть сообщение
typedef void (*func)();
есть указатель на функцию

Цитата Сообщение от Ilot Посмотреть сообщение
void baz( const func& reference_func) {
есть ссылка на указатель, через который нельзя менять объект

Цитата Сообщение от Ilot Посмотреть сообщение
baz(&foo);
аргумент - указатель на функцию

итого: везде указатели.
ессна, это будет работать.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
typedef void (&func)();
void foo() {
    std::cout << "Hello, world!\n";
}
void baz(  const func&  reference_func) {
    reference_func();
}
int main() {
 
    //error: invalid initialization of non-const reference of type ‘void (&)()’ from an rvalue of type ‘void (*)()’
    baz(&foo);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
typedef void (&func)();
void foo() {
    std::cout << "Hello, world!\n";
}
void baz(  const func  reference_func) {
    reference_func();
}
int main() {
 
     // error: invalid initialization of non-const reference of type ‘func {aka void (&)()}’ from an rvalue of type ‘void (*)()’
    baz(&foo);
}
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
19.08.2015, 14:54 29
hoggy, опять лукавите. Ни один даже стандартный тип не кастует указатель на себя в ссылку:
C++
1
2
3
4
5
6
7
8
#include <iostream>
void br(int& a) {
    std::cout << "I'm br\n";
}
int main() {
    int c = 0;
    br(&c);
}
А что будет если убрать ссылку и использовать тип самой функции:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
typedef void (func)();
void foo() {
    std::cout << "Hello, world!\n";
}
void baz(func reference_func) {
    reference_func();
}
int main() {
    baz(&foo); //<-- неявное преобразование func * к func
}
Все скомпилиться.
Однако:
C++
1
2
3
4
5
6
7
8
#include <iostream>
void bur(int r) {
    
}
int main() {
    int d = 0;
    bur(&d);//error: invalid conversion from 'int*' to 'int' [-fpermissive]|
}
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.08.2015, 19:00 30
Цитата Сообщение от Ilot Посмотреть сообщение
Ни один даже стандартный тип не кастует указатель на себя в ссылку:
вот именно!

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

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



Цитата Сообщение от Ilot Посмотреть сообщение
А что будет если убрать ссылку и использовать тип самой функции:
свободные функции подобно массивам умеют неявно каститься к указателям,

Цитата Сообщение от Ilot Посмотреть сообщение
Однако:
просто int - это и не функция, и не массив. и он такое не умеет.
0
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
20.08.2015, 06:49  [ТС] 31
Цитата Сообщение от Jewbacabra Посмотреть сообщение
А как же массивы, указатели, классы, структуры, объединения, ссылки?
Цитата Сообщение от useruser Посмотреть сообщение
Основные типы
Основные. Не я эту фразу придумал.

Цитата Сообщение от Jewbacabra Посмотреть сообщение
Тут функция имеет тип Int64(AnsiString)
Теперь ясно.
А какой это тип данных Int64(AnsiString)?

Int64 - целочисленный
AnsiString - строковый
Int64(AnsiString)?
0
196 / 197 / 120
Регистрация: 27.05.2011
Сообщений: 545
20.08.2015, 07:26 32
Цитата Сообщение от useruser Посмотреть сообщение
Int64 - целочисленный
AnsiString - строковый
Int64(AnsiString)?
Int64(AnsiString) — функциональный
0
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
20.08.2015, 09:04  [ТС] 33
Цитата Сообщение от mymedia Посмотреть сообщение
Int64(AnsiString) — функциональный
Ясно.

И какая цель этого типа? Проще говоря зачем этот "параметр" нужен функции? О чем он говорит?
int a; //Выделяем память размером 4 байт.
Int64(AnsiString) - ?
Функция это набор команд, фрагмент программного кода. Зачем фрагменту кода тип?
0
196 / 197 / 120
Регистрация: 27.05.2011
Сообщений: 545
20.08.2015, 10:23 34
В C++ у каждого объекта есть тип. В том числе и у функций. Тип нужен для того, чтобы понять, как можно использовать объект. Тип существует только лишь в сознании программиста и в компиляторе. В самом скомпилированном коде как такового типа никакого нет.
Цитата Сообщение от useruser Посмотреть сообщение
Зачем фрагменту кода тип?
Выше вам уже объясняли. И да, вы думаете фрагменту кода не нужна память? А где ж он тогда будет храниться?

Но, по-большому счёту, тип данных определяет только лишь операции, которые к нему применимы. К числам применимы одни операции, к функциям другие. Типы и занимаемая память не связаны непосредственно.
Вообще, тип — это просто некая абстракция.

Цитата Сообщение от useruser Посмотреть сообщение
int a; //Выделяем память размером 4 байт.
Нет, определяем целочисленную переменную. Это основной смысл.
Если бы вы хотели просто выделить память, то, возможно, лучший способ сделать это — написать char a[4];
0
99 / 46 / 18
Регистрация: 09.08.2015
Сообщений: 367
20.08.2015, 11:23 35
Цитата Сообщение от useruser Посмотреть сообщение
И какая цель этого типа? Проще говоря зачем этот "параметр" нужен функции?
Цитата Сообщение от AncientPenguin Посмотреть сообщение
Вместо одной функции можно безболезненно подставить другую функцию такого же типа.

Цитата Сообщение от useruser Посмотреть сообщение
О чем он говорит?
Тип это множество принимаемых значений (1, 2, 3, 'a', 'b'...) и множество операций (плюс, минус, больше, меньше). Тип функции определяет множество значений (операции и так понятны - вызвать) т.е. какие именно функции из всего многообразия подходят под конкретную ситуацию. Для того чтобы вызвать функцию нужно знать ее аргументы и возвращаемый тип, название же можно менять, ошибок это не вызовет.

Вообще это нужно для того чтобы сначала объявить тип функции, а потом по ситуации подставить одну из.
0
165 / 89 / 38
Регистрация: 29.06.2015
Сообщений: 1,098
20.08.2015, 12:05  [ТС] 36
Из всего выше прочитанного у меня сложилось впечатление, что тип функции - "несуществующая" абстракция.
Мы его нигде не задаем и нигде не используем. Он получается из типа аргумента и типа возвращаемого значения. "Побочный продукт."
Нам он не нужен.

Более того, мы не можем описать его подобно основным типам с++ (категория, размер типа) в силу бесконечности вариантов.
А вот тип аргумента и тип возвращаемого значения - мы задаем.
Мы не можем его преобразовать, наподобие inttostr(my_int). Мы ничего не можем с ним сделать. Делать что либо мы можем только с типом аргумента и возвращаемого значения. И это, возможно, повлияет на тип функции.

Ситуация очень похожа на известную поговорку - ветер дует, потому что деревья качаются или деревья качаются т.к. ветер дует...
Все вышеописанное ИМХО т.к. во всех учебниках есть функциональный тип.

Цитата Сообщение от AncientPenguin Посмотреть сообщение
Вместо одной функции можно безболезненно подставить другую функцию такого же типа.
Можно пример?
0
99 / 46 / 18
Регистрация: 09.08.2015
Сообщений: 367
20.08.2015, 12:22 37
Цитата Сообщение от useruser Посмотреть сообщение
Мы его нигде не задаем и нигде не используем. Он получается из типа аргумента и типа возвращаемого значения. "Побочный продукт."
Ага.

Цитата Сообщение от useruser Посмотреть сообщение
Нам он не нужен.
Не факт, но бывает.

Цитата Сообщение от useruser Посмотреть сообщение
Более того, мы не можем описать его подобно основным типам с++ (категория, размер типа) в силу бесконечности вариантов.
В C++ можем описать указатель на функцию.

Цитата Сообщение от useruser Посмотреть сообщение
Мы не можем его преобразовать, наподобие inttostr(my_int).
Можем, но это не имеет смысла.

Цитата Сообщение от useruser Посмотреть сообщение
Мы ничего не можем с ним сделать.
С типом? А что мы можем сделать с типом int? Конкретную функцию конкретного типа можно вызвать.

Цитата Сообщение от useruser Посмотреть сообщение
Можно пример?
C++
1
2
3
4
5
6
7
8
void f(int a) { }
void g(int b) { }
 
void (*pf)(int) = &f;
pf(10); // Вызывается f(10)
 
pf = &g;
pf(20); // Вызывается g(20)
Пример честно скопипастен с гугла, смысл думаю понять можно.
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
20.08.2015, 12:58 38
Цитата Сообщение от useruser Посмотреть сообщение
Основные. Не я эту фразу придумал.
А кто?
Цитата Сообщение от useruser Посмотреть сообщение
И какая цель этого типа? Проще говоря зачем этот "параметр" нужен функции? О чем он говорит?
Цитата Сообщение от useruser Посмотреть сообщение
Можно пример?
Выше я приводил пример использования
Цитата Сообщение от useruser Посмотреть сообщение
тип функции - "несуществующая" абстракция.
Функциональное программирование

Несколько человек привели примеры где функциональный тип используется.
Вот пример использования из стандартной библиотеке: qsort
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.08.2015, 14:29 39
Цитата Сообщение от useruser Посмотреть сообщение
Из всего выше прочитанного у меня сложилось впечатление, что тип функции - "несуществующая" абстракция.
Мы его нигде не задаем и нигде не используем. Он получается из типа аргумента и типа возвращаемого значения. "Побочный продукт."
Нам он не нужен.
ну это от незнания.
это у вас пройдет
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
20.08.2015, 14:48 40
Любые типы - "несуществующие абстракции". В Ассемблере никаких типов нет, только биты и несколько операций с ними. Так что никакие типы вообще не нужны

ЗЫ я тоже когда столкнулся с функциональными языками и типизированным лямбда-исчислением, долго в себя приходил Сейчас читаю TAPL и не могу сказать, что легко идет.
0
20.08.2015, 14:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2015, 14:48
Помогаю со студенческими работами здесь

Преобразовать массив с типом char в массив с типом int
Что-то не получается у меня найти инфу именно с преобразованием массивов с char в int. Нахожу...

Передача значения с типом DateTime в метод
Есть класс, в котором присутствует поле с типом DateTime, есть конструктор, принимающий в качестве...

В чем смысл создания шаблона с заранее известным передаваемым типом
Видел шаблоны типа: template&lt;int N&gt; struct fact{ static const int v = fact&lt;n-1&gt;::v * n; };...

Нужно перевести переменную с типом данных string в переменную с типом данных REAL
Итак, нужно перевести переменную с типом данных string в переменную с типом данных REAL. Переменную...

Перевод значения переменной с типом string в time
Есть переменая dtime с типом string в этой переменной указано время dtime:= '0:22:45'; ...

Присвоение значения полю с логическим типом в отчёте
Доброго дня, коллеги! Не уверен, что правильно сформулировал тему. Вопрос такой: В таблице...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru