Какое значение будет возвращено функцией if 48
Перейти к содержимому

Какое значение будет возвращено функцией if 48

  • автор:

Явный и не явный возврат функции, что это значит и в чем разница? [закрыт]

Закрыт. Этот вопрос необходимо уточнить или дополнить подробностями. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение.

Закрыт 1 год назад .

Может кто-то по-простому объяснить, какая разница между явным и не явным возвратом функции и что это значит?

Отслеживать
3,455 3 3 золотых знака 10 10 серебряных знаков 30 30 бронзовых знаков
задан 13 фев 2023 в 2:06
Сергей Ардуанов Сергей Ардуанов
123 8 8 бронзовых знаков
Без return в стрелочной функции — неявный возврат. Что тут может озадачить?
13 фев 2023 в 3:32

2 ответа 2

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

Любая функция в JavaScript что-то возвращает. Если вы руками в функции написали ключевое слово return — то это явный возврат. Будет явно возвращено указанное значение: return ‘a’ вернет строку ‘a’ , просто return; вернет undefined .

Если же ключевое слово return отсутствует, то такой возврат называется неявным. Что именно будет возвращено, зависит от сигнатуры функции. В большинстве случаев это будет undefined , но в случае с, например, асинхронными функциями, будет неявно возвращен Promise , который разрешается в undefined .

Можно сделать функцию, которая имеет как явное, так и неявное возвращаемое значение:

function foo ()

Здесь мы явно возвращаем «bar» если выполняется условие. В противном случае будет неявно возвращен undefined .

Единственные 2 случая, когда функция не возвращает никакого значения, это в случаях:

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

Просто вопрос терминологии, не забивайте себе этим голову особо.

JavaScript: Возврат значений

Функции, которые мы определяли в предыдущих уроках, заканчивали свою работу тем, что печатали на экран какие-то данные:

const greeting = () => < console.log('Hello, Hexlet!'); >; 

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

Возьмем задачу обработки электронной почты. Когда пользователь регистрируется на каком-то сайте, то он может ввести email любым способом:

  • Добавив случайно пробелы в начале или в конце _support@hexlet.io__
  • Использовав буквы в разном регистре SUPPORT@hexlet.io

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

const saveEmail = () => < // В реальности email приходит из формы const email = ' SuppORT@hexlet.IO'; // обрезаем пробельные символы const trimmedEmail = email.trim(); const preparedEmail = trimmedEmail.toLowerCase(); console.log(preparedEmail); // здесь будет запись в базу данных >; 

Этот код стал возможен только благодаря возврату значения. Методы trim() и toLowerCase() ничего не печатают на экран (в консоль), они возвращают результат своей работы и поэтому мы можем записать его в константы. Если бы они вместо этого печатали на экран, мы бы не могли присвоить результат их работы константе. Как мы не можем сделать с определенной выше функцией greeting() :

const message = greeting(); console.log(message); // => undefined 

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

const greeting = () => < return 'Hello, Hexlet!'; >; 

return – особая инструкция, которая берёт выражение, записанное справа, и отдаёт его наружу, тому коду, который вызвал функцию. Как только JavaScript натыкается на return , выполнение функции на этом завершается.

// Теперь мы можем использовать результат работы функции const message = greeting(); console.log(message); // => Hello, Hexlet! // И даже выполнить какие-то действия над результатом console.log(message.toUpperCase()); // => HELLO, HEXLET! 

Любой код после return не выполняется:

const greetingWithCodeAfterReturn = () => < return 'Hello, Hexlet!'; console.log('Я никогда не выполнюсь'); >; 

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

const greetingWithReturnAndPrinting = () => < console.log('Я появлюсь в консоли'); return 'Hello, Hexlet!'; >; // И напечатает текст на экран и вернет значение const message = greetingWithReturnAndPrinting (); 

Возвращать можно не только конкретное значение. Так как return работает с выражениями, то справа от него может появиться почти все что угодно. Здесь нужно руководствоваться принципами читаемости кода:

const greeting = () => < const message = 'Hello, Hexlet!'; return message; >; 

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

const doubleFive = () => < // или return 5 + 5 const result = 5 + 5; return result; >; 

Вопрос на самопроверку. Что вернет вызов, определенной ниже, функции run() ?

// Определение const run = () => < return 5; return 10; >; // Что будет выведено на экран? console.log(run()); 

Ответ На экран будет выведено `5`.

Задание

Реализуйте функцию sayHurrayThreeTimes() , которая возвращает строку ‘hurray! hurray! hurray!’.

const hurray = sayHurrayThreeTimes(); console.log(hurray); // => hurray! hurray! hurray! 

Упражнение не проходит проверку — что делать? ��

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.

В моей среде код работает, а здесь нет ��

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя ��

Это нормально ��, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно ��

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

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

Полезное

Генерация случайных чисел в языке Си

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

Пример: Определение победителя в конкурсе репостов.

Имеется список из 53 человек. Необходимо выбрать из них победителя. Если вы выберете его самостоятельно, то вас могут обвинить в предвзятости. Поэтому вы решили написать программу. Она будет работать следующим образом. Вы вводите количество участников N , после чего программа выводит одно число – номер победителя.

Как получить число от игрока, вам уже известно. А вот как заставить компьютер загадать случайное число? В этом уроке вы этому научитесь.

Функция rand().

Данная функция возвращает случайное целое число в диапазоне от нуля до RAND_MAX . RAND_MAX это специальная константа языка Си, в которой содержится максимальное целое число, которое может быть возвращено функцией rand() .

Функция rand() определена в заголовочном файле stdlib.h . Поэтому, если хотите использовать rand в своей программе, не забудьте подключить этот заголовочный файл. Константа RAND_MAX тоже определена в этом файле. Вы можете найти этот файл у себя на компьютере и посмотреть её значение.

Давайте посмотрим на эту функцию в действии. Запустим следующий код:

#include // чтобы пользоваться функцией printf #include // чтобы пользоваться функцией rand int main(void) < /* генерируем пять случайных целых чисел */ printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); >

Должно получиться что-то вроде этого.

Пять случайных чисел, сгенерированных функцийе rand

Рис.1 Пять случайных чисел, сгенерированных функцийе rand

Но нам бы хотелось получить числа от 1 до 53 , а не всё подряд. Ниже описано несколько трюков, позволяющих наложить ограничения на функцию rand() .

Ограничить случайные числа сверху.

Кто в школе ждал момента, когда ему пригодится математика, приготовьтесь. Этот момент наступил. Чтобы ограничить сверху случайные числа, можно воспользоваться операцией получения остатка от деления, которую вы изучили в прошлом уроке. Наверное вы знаете, что остаток от деления на число K всегда меньше числа K . Например, при делении на 4 могут получиться остатки 0, 1, 2 и 3 . Поэтому если вы хотите ограничить сверху случайные числа числом K , то просто возьмите остаток от деления на K . Вот так:

#include #include int main(void) < /* генерируем пять случайных целых чисел меньших 100 */ printf("%d\n", rand()%100); printf("%d\n", rand()%100); printf("%d\n", rand()%100); printf("%d\n", rand()%100); printf("%d\n", rand()%100); >

Пять случайных чисел меньше 100

Рис.2 Пять случайных чисел меньше 100

Ограничить числа снизу.

Функция rand возвращает случайные числа из отрезка [0, RAND_MAX] . А что если нам нужны только числа большие числа M (например, 1000 )? Как быть? Всё просто. Просто прибавим к тому, что вернула функция rand, наше значение M . Тогда если функция вернёт 0 , итоговый ответ будет M , если 2394 , то итоговый ответ будет M + 2394 . Этим действием мы как бы сдвигаем все числа на M единиц вперёд.

Задать границы функции rand сверху и снизу.

Например, получить числа от 80 до 100 . Кажется, нужно просто объединить два способа, которые приведены выше. Получим что-то вроде этого:

#include #include int main(void) < /* генерируем пять случайных целых чисел больших 80 и меньших 100 */ printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + rand()%100); >

Попробуйте запустить эту программу. Удивлены?

Да, такой способ работать не будет. Давайте прокрутим эту программу руками, чтобы убедиться в том, что мы допустили ошибку. Допустим rand() вернула число 143 . Остаток от деления на 100 равен 43 . Дальше 80 + 43 = 123 . Значит такой способ не работает. Подобная конструкция выдаст числа от 80 до 179 .

Давайте разберём по действиям наше выражение. rand()%100 может выдать числа от 0 до 99 включительно. Т.е. из отрезка [0; 99] .
Операция + 80 сдвигает наш отрезок на 80 единиц вправо. Получаем [80; 179] .
Как видим, проблема у нас заключается в правой границе отрезка, она сдвинута вправо на 79 единиц. Это наше исходное число 80 минус 1 . Давайте наведём порядок и сдвинем правую границу назад: 80 + rand()%(100 — 80 + 1) . Тогда всё должно сработать как надо.

В общем случае если нам нужно получить числа из отрезка [A;B] , то необходимо воспользоваться следующей конструкцией:
A + rand()%(B-A+1) .

Согласно этой формуле перепишем нашу последнюю программу:

#include #include int main(void) < /* генерируем пять случайных целых чисел из отрезка [80; 100] */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("%d\n", 80 + rand()%(100 - 79)); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); >

Случайные числа из диапазона [80;100]

Рис.3 Случайные числа из диапазона [80;100]

Ну вот, теперь вы можете решить исходную задачу урока. Сгенерировать число из отрезка [1; N] . Или не можете?

Но прежде ещё немного полезной информации. Запустите последнюю программу три раза подряд и записывайте себе случайные числа, которые она генерирует. Заметили?

Функция srand().

Да, каждый раз появляются одни и те же одинаковые числа. «Так себе генератор!» – скажете вы. И будете не совсем правы. Действительно, генерируются всё время одинаковые числа. Но мы можем на это повлиять, для этого используется функция srand() , которая также определена в заголовочном файле stdlib.h . Она инициализирует генератор случайных чисел начальным числом.

Скомпилируйте и запустите несколько раз вот эту программу:

#include #include int main(void) < srand(2); /* генерируем пять случайных целых чисел из отрезка [80;100] */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("%d\n", 80 + rand()%(100 - 79)); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); >

Теперь поменяйте аргумент функции srand() на другое число (надеюсь вы ещё не забыли, что такое аргумент функции?) и снова скомпилируйте и запустите программу. Последовательность чисел должна измениться. Как только мы меняем аргумент в функции srand – меняется и последовательность. Не очень практично, не правда ли? Чтобы изменить последовательность, нужно перекомпилировать программу. Вот бы это число туда подставлялось автоматически.

И это можно сделать. Например, воспользуемся функцией time() , которая определена в заголовочном файле time.h . Данная функция, если ей в качестве аргумента передать NULL , возвращает количество секунд, прошедших c 1 января 1970 года . Вот посмотрите, как это делается.

#include #include #include // чтобы использовать функцию time() int main(void) < srand(time(NULL)); /* генерируем пять случайных целых чисел из отрезка [80;100] */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("%d\n", 80 + rand()%(100 - 79)); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); >

Вы спросите, а что такое NULL ? Резонный вопрос. А я вам пока отвечу, что это специальное зарезервированное слово такое. Могу ещё сказать, что им обозначает нулевой указатель, но т.к. это для вас никакой информации не несёт, то на данный момент рекомендую об этом не думать. А просто запомнить как некоторый хитрый трюк. В будущих уроках мы остановимся на этой штуке поподробнее.

Сохрани в закладки или поддержи проект.

Практика

Решите предложенные задачи. Для удобства работы сразу переходите в полноэкранный режим

Исследовательские задачи для хакеров:

  1. В каких ситуациях ещё может пригодиться генерация случайных чисел? Напишите ваши варианты в комментарии к этому уроку.
  2. Напишите программу, которая выводит на экран значение целочисленной константы RAND_MAX. Найдите файл stdlib.h на вашем компьютере, найдите значение этой константы в этом файле.
  3. Найдите в интернете описание функций, которые определены в заголовочном файле time.h Вы, конечно, ещё не сможете ими пользоваться, но знать, что такие функции есть, всё равно нужно. Ведь когда-то настанет момент, когда ваших знаний будет достаточно для их использования.
  4. Числа, генерируемые функцией rand(), имеют равномерное распределение. Это значит, что если запускать функцию rand очень много раз и каждый раз записывать, какое число выпало, то количество выпадения различных чисел будет одинаковым. Например, если генерировать только числа 0 и 1, то через 100 запусков примерно 50 раз выпадет ноль и 50 раз единичка. Обратите внимание, что я говорю примерно. Может быть, например, 49 и 51, или 53 и 47. Если рассматривать это в отношении к общему числу запусков, получим (49/100 и 51/100 или 53/100 и 47/100 соответственно). Но чем больше экспериментов мы проведём, тем ближе отношение количество единичек к количеству испытаний будет стремиться к 1/2. Проведите самостоятельно эксперимент с 10, 50 и 100 запусками. Это муторно и долго, если делать руками, но что поделать? В будущем мы напишем программу, чтобы проверить свойство равномерности распределения наших случайных чисел.

Дополнительные материалы

  1. Другие функции, определённые в заголовочном файле stdlib.h
  2. Хотя я и употребляю везде словосочетание «случайные числа», но на самом деле получить действительно случайные числа – сложная задача. И в компьютерах обычно используются псевдослучайные числа. Подробнее об этом можно прочитать здесь.
  3. Если не терпится узнать хоть что-то про NULL, то почитайте вот этот урок.
  4. Дата 1 января 1970 года особенная. С неё начинается отсчёт эры UNIX. Подробнее об этом и проблемах, которые нас ожидают.

Самый крупный донат:

sdanshin@yandex.ru 5000 руб.
Аноним, Юmoney * 9482 1960 руб.
Руслан Викторович П, +7(985) ***-**-99 1000 руб.
Сергей Евгеньевич С, +7 (977) ***-**-40 500 руб.

Оставить комментарий

Чтобы код красиво отображался на странице заключайте его в теги [code] здесь писать код [/code]

Комментарии

Василий Громов 25.08.2017 в 13:48

1 задача. Например, используя генератор случайных чисел можно сделать игральный кубик или подобие игрового автомата.
4 задача. Я постарался сделать, но на 30 остановился. У меня получились следующие результаты:
10 генераций: 0-2, 1-8
20 генераций: 0-12, 1-8
30 генераций: 0-15, 1-15

Т.е. 30 попыток достаточно?

KaDeaT

1 задача. Да! Очень хорошие примеры.

4 задача. Нет, 30 попыток недостаточно. То, что у вас получилось 15/15 это совпадение. Я провёл 5 опытов по 30 раз, вот результаты:
1. 15/15
2. 11/19
3. 15/15
4. 17/13
5. 12/18

Никита 08.11.2017 в 21:27
у вас ошибка в примере с генерацией числе от 80 до 100, программа выдаст значения больше 100!
KaDeaT
Проверил, вроде бы нет ошибок. Поясните, что вы имеете ввиду?
Александр 06.12.2017 в 15:24

Здравствуйте! Мой комментарий по поводу формулы расчета диапазона случайных чисел, мы тут посовещались и признали ее не совсем верной. Ваща формула: A + rand()%(B-A+1), при условии которое дано в задаче Введите максимально число, которое может быть сгенерировано следующей конструкцией: int rand_a = 66 + rand()%601; выдает максимальное число в 536. Верная формула: max (a + rand() %b) = a + b — 1 = 666

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

#include  
#include
#include
void sleep (float);
void print_symbol (int);

int main (void)
// A + rand()%(B-A+1)
// 66+rand()%601
// 600-66+1 = 535, а правильный ответ оказался 666
int a, b;
a = 66;
b = 601;

printf("a = %dn", a);
printf("b = %dnn", b);
printf("

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

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