Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > если функция ничего не возвращает


Автор: supervladislav 5.9.2012, 21:51
Скажите , пишу первую функцию ,у меня возник  вопрос.
Какой возвращаемый результат должен  быть у функции если она ничего не возвращает



Автор: northener 5.9.2012, 22:21
Цитата(supervladislav @  5.9.2012,  21:51 Найти цитируемый пост)
если она ничего не возвращает

Функция, которая ничего не возвращает называется процедура. procedure

Автор: supervladislav 5.9.2012, 22:28
northener, тоесть хотябы да или нет функция должна возвращать так чтоли?

Добавлено через 10 минут и 42 секунды
Я имел ввиду корректно если функция сработала то она возвращает да в противном нет ,так?

Автор: Данкинг 5.9.2012, 23:12
Ну, пиши result:='' 

Автор: northener 6.9.2012, 00:41
Цитата(supervladislav @  5.9.2012,  22:28 Найти цитируемый пост)
northener, тоесть хотябы да или нет функция должна возвращать так чтоли?

Добавлено через 10 минут и 42 секунды
Я имел ввиду корректно если функция сработала то она возвращает да в противном нет ,так? 

Опять нужен учебник для начинающих.
Функция должна возвращать хоть что-то ибо она может быть в правой части выражения.
В отличии от функции процедура не должна что -либо возвращать.

Автор: supervladislav 7.9.2012, 16:17
northener, вобще если судить по примеру кода ,то везде  где объявляется  функция  в конце пишется тип возвращаемых данных,но невсегда функция чео либо возвращает.
Вобще неплохо было бы об этом написать в книге.

Автор: Данкинг 7.9.2012, 16:50
Цитата(supervladislav @  7.9.2012,  17:17 Найти цитируемый пост)
но невсегда функция чео либо возвращает.

Если функция вызывается - то она непременно что-то возвратит.

Автор: bems 8.9.2012, 07:43
Цитата(supervladislav @  7.9.2012,  16:17 Найти цитируемый пост)
везде  где объявляется  функция  в конце пишется тип возвращаемых данных,но невсегда функция чео либо возвращает
функция всегда должна что-то возвращать. Если твоя функция не при всех вариантах возвращает значение то ты должен считать это ошибкой. Но возвращаемое значение может игнорироваться. Например вызов sin(0); (без присваивания результата) вполне корректен.

Автор: Poseidon 15.9.2012, 15:02
Цитата(supervladislav @  5.9.2012,  21:51 Найти цитируемый пост)
Какой возвращаемый результат должен  быть у функции если она ничего не возвращает
Если функция ничего не возвращает, то результатом такой функции будет значение по умолчанию для объявленного типа функции. Т.е. функция, которая должна была вернуть string - вернет пустую строку. Та, что должна была вернуть integer, по идее вернет 0 (но не всегда). Но, во-первых, не стоит рассчитывать на подобный результат, особенно если от этого результата зависит ход вычислений. Во-вторых, это плохой тон, не давать результату функции значение. Даже если вычисления в функции не дали никакого результата, нужно присвоить значение Result, по которому будет понятно, что функция безрезультатна.

Автор: БелАмор 15.9.2012, 16:35
Цитата(Poseidon @  15.9.2012,  16:02 Найти цитируемый пост)
Если функция ничего не возвращает, то результатом такой функции будет значение по умолчанию для объявленного типа функции. Т.е. функция, которая должна была вернуть string - вернет пустую строку.

Вы неправы.
Конкретный пример:
http://delphikingdom.com/asp/viewitem.asp?catalogid=1435

Цитата(supervladislav @  7.9.2012,  17:17 Найти цитируемый пост)
northener, вобще если судить по примеру кода ,то везде  где объявляется  функция  в конце пишется тип возвращаемых данных,но невсегда функция чео либо возвращает.

В Языке Си, например, нет разделения подпрограмм на функции и процедуры. Там всё - функции. Функция, не возвращающая значение, имеет тип void. В Паскале же подпрограммы чётко разделены на функции и процедуры. Если в Паскале подпрограмма не должна возвращать значение, она называется процедурой. Если подпрограмма названа функцией, она обязана что-то вернуть. Причём в любом случае. Если компилятор обнаруживает, что возможна ситуация, при которой переменной Result не будет ничего присвоено, он выдаёт предупреждение. Сразу привыкайте, что при компиляции программы не должно быть ни одного предупреждения, какими бы незначительными они вам ни казались.
Вообще, пытаться что-либо писать с такими знаниями - пустая трата времени. Прочитайте какую-нибудь книжку для начинающих, чтобы знать хотя бы самые минимальные основы. Посоветовать что-то конкретное я не могу, но по содержанию можно ориентироваться, например, на эту книгу:
http://www.bhv.ru/books/full_contents.php?id=189915
Вас должны интересовать главы до 28.
Ваш нынешний вопрос относится к страницам 53 и 55.

Автор: lomaster 15.9.2012, 17:00
Чтобы функция не возвращала результат, возбудите исключение, но и ловить не забудте.
Если логика кода может или не может возвращать, то тут надо смотреть на суть. От этого зависит что применить функцию или процедуру.

Автор: БелАмор 15.9.2012, 17:42
Кстати, для начала можно почитать этот цикл статей:
http://delphikingdom.com/lyceum/seminar.asp?ID=6
Написано всё это достаточно давно, поэтому там нет многих нововведений, в частности, ничего не говорится о вопросах, связанных с поддержкой Юникода, но познакомиться с самыми азами - вполне.

Автор: Poseidon 15.9.2012, 18:58
Цитата(БелАмор @  15.9.2012,  16:35 Найти цитируемый пост)
Вы неправы.
Вы не умеете читать

Ваше
Цитата(БелАмор @  15.9.2012,  16:35 Найти цитируемый пост)
Переменная Result типа string может иметь непустое начальное значение


Мое
Цитата(Poseidon @  15.9.2012,  15:02 Найти цитируемый пост)
Если функция ничего не возвращает, то результатом такой функции будет значение по умолчанию для объявленного типа функции. Т.е. функция, которая должна была вернуть string - вернет пустую строку. Та, что должна была вернуть integer, по идее вернет 0 (но не всегда). Но, во-первых, не стоит рассчитывать на подобный результат, особенно если от этого результата зависит ход вычислений. 


Есть принципиальные отличия? Особенно если мы говорим про такой нестандартный в практике вопрос.

Добавлено через 2 минуты и 12 секунд
Цитата(БелАмор @  15.9.2012,  16:35 Найти цитируемый пост)
Сразу привыкайте, что при компиляции программы не должно быть ни одного предупреждения, какими бы незначительными они вам ни казались.
Попробуйте поработать с текстом в разных кодировках в последних версиях Delphi. Предупреждений о том, что лучше использовать одну функцию, а не другую, не оберетесь. 

Автор: bems 15.9.2012, 20:10
Цитата(Poseidon @  15.9.2012,  15:02 Найти цитируемый пост)
Если функция ничего не возвращает, то результатом такой функции будет значение по умолчанию для объявленного типа функции.
если и будет, то это случайность
компилятор гарантирует только корректность работы с автоматическими типами

То что ты говоришь что это не всегда, выглядит как-то странно, потому что такое поведение скорее случайность

Автор: БелАмор 15.9.2012, 20:20
Цитата(Poseidon @  15.9.2012,  19:58 Найти цитируемый пост)
Ваше

Цитата(БелАмор @  15.9.2012,  16:35 )
Переменная Result типа string может иметь непустое начальное значение

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

Цитата(Poseidon @  15.9.2012,  16:02 Найти цитируемый пост)
Но, во-первых, не стоит рассчитывать на подобный результат, особенно если от этого результата зависит ход вычислений.

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

Цитата(Poseidon @  15.9.2012,  16:02 Найти цитируемый пост)
Во-вторых, это плохой тон, не давать результату функции значение. Даже если вычисления в функции не дали никакого результата, нужно присвоить значение Result, по которому будет понятно, что функция безрезультатна.

Дело не только в том, что нужно, чтобы было понятно, что функция безрезультатна. Нужно ещё:
1. Исключить в принципе потенциальную возможность где-то потом нарваться на мусор в результате.
2. Убрать предупреждение компилятора, которое захлямляет окно сообщений.

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

Цитата(Poseidon @  15.9.2012,  19:58 Найти цитируемый пост)
Попробуйте поработать с текстом в разных кодировках в последних версиях Delphi. Предупреждений о том, что лучше использовать одну функцию, а не другую, не оберетесь.

Про юникодные версии я пока воздержусь высказывать мнение, но на неюникодных до сих пор удавалось придерживаться правила "ни одного предупреждения при компиляции".
Поставить else в том-же case, даже если других вариантов тут не может быть, меня пока не особо напрягало.
А предупреждения иногда указывают на действительно серьёзные упущения. И было бы хорошо не потерять такие предупреждения в горах мусора.

Автор: Poseidon 16.9.2012, 03:00
Цитата(БелАмор @  15.9.2012,  20:20 Найти цитируемый пост)
Про юникодные версии я пока воздержусь высказывать мнение, но на неюникодных до сих пор удавалось придерживаться правила "ни одного предупреждения при компиляции".
До D2010 мне тоже удавалось. Теперь уже никак. Эх, где мой любимый D7...


Цитата(bems @  15.9.2012,  20:10 Найти цитируемый пост)
если и будет, то это случайность

Блин. почему мне с такой случайностью не везет в лотерее?
Код
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function StrFunc(param: string): string;
var
  a: string;
begin
  a:= param;
end;

function IntFunc(param: Integer): Integer;
var
  a: integer;
begin
  a:= param;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(StrFunc('ahaha')); // Постоянно возвращает пустую строку
  ShowMessage(IntToStr(IntFunc(0))); // Постоянно возвращает -1
end;

end.


Хотя я еще раз повторюсь, что это все не правильно

Автор: bems 16.9.2012, 04:47
Poseidon, не надо блинов.

Цитата(Poseidon @  16.9.2012,  03:00 Найти цитируемый пост)
Постоянно возвращает -1

с каких пор -1 это "значение по умолчанию для указанного типа"? это мусор со стека (окей, компилятор может выкинуть переменную на стеке и заменить регистром, но сути дела это не меняет). И другим он будет если переменная Result будет попадать на другое место на стеке, или то же место будет содержать другой мусор. Нет причин ожидать там мифическое "значение по умолчанию"
у меня твой пример показывает не -1 а 0, а если поменять вызовы ShowMessage местами то 3211600

Цитата(Poseidon @  16.9.2012,  03:00 Найти цитируемый пост)
Постоянно возвращает пустую строку

для автоматических типов компилятор следит за значениями по умолчанию переменной Result. Это необходимо потому что если вместо строки туда попадет мусор со стека, то ты уже не сможешь присвоить туда что-то своё (потому что для этого нужно уменьшить счетчик ссылок на старую строку, а она - мусор). но при этом не гарантируется что там пустая строка. гарантируется только что там корректное строковое значение. Но какое именно - опять случайность. Модифицируй свой пример, и посмотри что получится 
Код

procedure TForm11.Button1Click(Sender: TObject);
var
  s: String;
begin
  s := 'wtf??';
  s := StrFunc('ahaha');
  ShowMessage(s); // выводит "wtf??", пока дождь не пойдет
end;

Автор: БелАмор 16.9.2012, 07:00
Цитата(Poseidon @  16.9.2012,  04:00 Найти цитируемый пост)
ShowMessage(StrFunc('ahaha')); // Постоянно возвращает пустую строку

А у меня вот этот код:

Код

function StrFunc(param: string): string;
begin
  if Length(param) > 5 then
    Result := param;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  s := 'Ну что? Не ждали?';
  s := StrFunc('ahaha');
  ShowMessage(s);
end;

Всегда выдаёт:

Цитата

---------------------------
Project1
---------------------------
Ну что? Не ждали?
---------------------------
OK   
---------------------------

Причём, что самое смешное, это - документированное поведение.
На всякий случай повторю ссылку:
http://delphikingdom.com/asp/viewitem.asp?catalogid=1435

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


Автор: БелАмор 16.9.2012, 07:31
Цитата(БелАмор @  16.9.2012,  08:00 Найти цитируемый пост)
  s := 'Ну что? Не ждали?';
  s := StrFunc('ahaha');
  ShowMessage(s);

Хотел написать так:

Код

  s := StrFunc('Ну что? Не ждали?');
  s := StrFunc('ahaha');
  ShowMessage(s);

Но результат одинаков, не стал исправлять.
Если кто пойдёт по ссылке - там внизу ещё ссылка на обсуждение.

Автор: БелАмор 16.9.2012, 11:34
Что-то я прозевал сообщение от bems и практически повторил приведённый им код...

Автор: bems 16.9.2012, 14:43
Цитата(БелАмор @  16.9.2012,  07:31 Найти цитируемый пост)
Но результат одинаков

не одинаков, кстати 

Автор: БелАмор 16.9.2012, 15:38
Цитата(bems @  16.9.2012,  14:43 Найти цитируемый пост)
не одинаков, кстати

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

Автор: bems 16.9.2012, 16:07
да, не обратил, извиняюсь

Автор: northener 17.9.2012, 00:55
Цитата(Poseidon @  16.9.2012,  03:00 Найти цитируемый пост)
Блин. почему мне с такой случайностью не везет в лотерее?

Хороший вопрос!
Ответ может быть только один. Никогда не играйте ни в какую лотерею! Помните, что выигрыш всегда гарантирован только устроителям сей лотереи. А всем прочим (в массе своей) гарантирован проигрыш!
smile

А по сути вопроса автора согласен с высказываниями БелАмор от 15.9.2012, 16:35
P.S. Простите. До сих пор не научился давать в своём ответе ссылку на конкретный ответ в теме/ветке. Если кто может что подсказать, то прошу сообщить в личку.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)