Функция с несколькими параметрами, с параметром по умолчанию.
Давайте ещё не много поговорим о функциях в Delphi, а конкретно о том, как объявить и использовать функции с несколькими параметрами и с параметрами по умолчанию.
Объявление функции с несколькими параметрами.
Delphi, как и многие другие языки позволяет определить функцию с несколькими параметрами. Давайте на примере посмотрим, как это сделать. Не пытайтесь вникнуть в смысл функции, он сугубо демонстрационный.
Принцип следующий: Перечисляем все переменные с указанием типа через «;». Если у нас несколько переменных одного типа, то можно перечислить их через запятую, а потом указать общий тип. В моем примере так и сделано. Я перечислил переменные типа string, затем поставил «;» и указал, что есть ещё целочисленная переменная i.
Давайте разберемся как вызвать такую функцию:
Функция должна могла бы вывести два сообщения.
Но этого не произойдет т.к. мы третим параметром передали «1», а единица не кратна двум, поэтому ничего и не выведется.
Функция Delphi с параметром по умолчанию
Можно преписать нашу функцию так, чтобы числовой параметр задавался по умолчанию. Выглядить это будет следующим образом:
Такое определение позхволяет нам не передавать последний параметр. Следующие два вызова эквивалентны между собой.
Стоит отметить, что если в функции необходим параметр по умолчанию, то его нужно указывать в конце списка параметров.
Директива Default используется двумя отдельными, и весьма различными способами со свойствами (property) для установки обработки заданной по умолчанию.
Когда вы имеете одно или более свойств, которые использут индекс как параметр (см. пример и Index для больших подробностей), вы можете определить директиву по умолчанию (Default). Это позволяет вам использовать более компактный способ использования свойства.
Мы можем использовать:
Имеет намного больше специализированного использования. Она не сохраняет порядковое значение свойства, заданное по умолчанию, в run time информации для класса, а просто сообщает компилятору о том, следует ли хранить текущее значение опубликованное свойство в соответствующий файл «*.dfm».
Похожие команды
Private Начинает частный (Private) раздел данных и методов в классе
Property Определяет управляемый доступ к полям класса
Protected Начинает раздел класса частных данных доступных подклассам
Public Начинает внешне доступный раздел класса
Published Начинается изданный, внешне доступный раздел класса
Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.
Возможность перегрузки
Впервые концепция перегрузки процедур и функций была реализована в Delphi 4. Она позволяет иметь несколько различных процедур и функций с одинаковыми именами, но с разными списками параметров. Такие процедуры и функции должны быть описаны с применением директивы overload.
procedure Test (I: integer); overload; procedure Test (S: string); overload; procedure Test (D: double); overload;
При вызове процедуры Test, Delphi сама решит, какую из трех процедур необходимо выполнить, в зависимости от передаваемого ей параметра. Но нужно отметить, что это не самая безопасная возможность языка. Применение перегружаемых процедур и функций может стать неиссякаемым источником трудноуловимых ошибок в программе. Поэтому пользуйтесь этой возможностью осторожно.
Передача параметров
Pascal позволяет передавать параметры в функции и процедуры либо по значению, либо по ссылке. Передаваемый параметр может иметь любой встроенный или пользовательский тип либо являться открытым массивом. Параметр также может быть константой, если его значение в процедуре или функции не меняется.
Передача параметров по значению
Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:
procedure Test(s: string);
При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.
Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно). Этот способ передачи является у большинства самым излюбленным, но в тоже время является и самым не практичным, т.к. для выполнения метода выделяется дополнительная память для создания точной копией передаваемой переменой. Для решения этой проблемы следует использовать один из способов описанных ниже.
Передача параметров по ссылке
Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.
procedure ChangeMe(var x: longint); begin x := 2; // Параметр х изменен вызванной процедурой end;
Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.
Передача параметров констант
Если нет необходимости изменять передаваемые функции или процедуре данные, можно описать параметр как константу. Ключевое слово const не только защищает параметр от изменения, но и позволяет компилятору сгенерировать более оптимальный код передачи строк и записей. Вот пример объявления параметра-константы:
procedure Test(const s: string );
Передача открытых массивов
Открытый массив параметров позволяет передавать в функцию или процедуру различное количество параметров. В качестве параметров можно передать либо открытый массив элементов одинакового типа, либо массивы констант различного типа. В приведенном ниже примере объявляется функция, которой в качестве параметра должен передаваться открытый массив целых чисел.
function AddEmUp(A: array of integer): integer;
В открытом массиве можно передавать переменные, константы или выражения из констант.
Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.
Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:
procedure WhatHaveIGot( A: array of const );
Вызвать объявленную выше функцию можно, например, с помощью такого оператора:
При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:
Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.
Поскольку массив констант способен передавать данные разных типов, это может вызвать определенные затруднения при создании обрабатывающей полученные параметры функции или процедуры. В качестве примера работы с таким массивом рассмотрим реализацию процедуры WhatHaveIGot, которая просматривает элементы полученного массива параметров и выводит их тип.
В Delphi есть одна очень полезная возможность — использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:
procedure HasDefVal( s: string; i: integer = 0 );
Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:
procedure HasDefVal( ‘Hello’, 26 );
Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:
procedure HasDefVal( ‘Hello’ );
function Add( I1, I2: integer ): integer; begin Result := I1 + I2; end;
Предположим также, что исследования показали целесообразность добавления в программу возможности сложения трех чисел. Однако замена имеющейся функции функцией сложения трех чисел приведет к тому, что вам придется переправлять немало текста, который перестанет компилироваться из-за внесения в функцию еще одного параметра. Однако при использовании значений параметров по умолчанию проблема решается легко и просто. Достаточно изменить объявление функции так, как показано ниже.
function Add( I1, I2: integer; I3: integer = 0 ): integer; begin Result := I1 + I2 + I3; end;
Директива
Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.
В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.
Процедура и функция — это ключевые понятия в любом языке программирования, без которых не обходится ни одна серьезная программа. И поэтому очень важно иметь полное понимание о механизме их работы.
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Поиск по 2 таблицам и ошибка «Параметр не имеет значения по умолчанию» Нужно сделать поиск по двум таблицам Ремонт_компьютеров и Ремонт_ноутбуков по выбранным полям «.
Сами себе и наметили структуру таблиц БД. Таблица Тип, поля: код (счетчик), тип (текст) Таблица Марка, поля: код(счетчик), марка(текст), код_типа (число) Таблица Плотность, поля: код(счетчик), плотность(число), код_марки(число) Таблица Толщина, поля: код(счетчик), толщина(число), код_плотности(число)
Если, конечно, данные эти действительно иерархически зависят друг от друга и нет никаких исключений.
Насчет ошибки трудно сказать не видя самой БД. Может надо в квадратные скобки заключать имя поля, т.к. оно кириллицей написано. Может еще в чем проблема.
Но думаю, что у вас не такая структура. Вы структуру приведите и напишите, чего хотите.
Вложения
db1.zip (78.9 Кб, 33 просмотров)
xBios, вы текст запросов в ACCESS проверяйте перед тем, как в Delphi их передавать. Думаю, что у Вас теперь проблема с кавычками. В Delphi строка должна выглядеть так:
Главное определиться со структурой базы данных: определить главные базы и справочники. Все повторяющиеся данные засовываются в справочники: класс бумаги (не понятно поле «примечание». т.к. встречается значение «не мелованная»), Поставщик, Наименование бумаги, Страна производитель. Привязка к ним осуществляется через ключевые поля. Ключевыми полями необходимо использовать числовые (целые либо счетчики).
Почитайте литературу о базах данных. Узнайте, как правильно хранить данные, как обращаться к ним. Я думаю, что пока вы не поймете это, вам будет очень трудно.
Спасибо за ответы, тогда начну с создания нормальной базы данных.
Добавлено через 20 часов 58 минут Всем Здравствуйте еще раз, я подумал что и эта Таблица хороша, а конкретно «Бумага». я загрузил значения combobox без повторяющихся данных, но столкнулся с проблемой загрузки Наименования бумаги, Например нужно загрузить только те наименования у которых класс бумаги «Мелованная» попробовал загрузить вот так:
Добавлено через 4 часа 25 минут Вроде разобрался, запросы все правильно построил. Теперь новая проблема Сначала я загрузил Классы бумаги(3 значения) Потом при выборе одного из значений загружал другую колонку но в которой имеется значение Первого комбобокса, так же само загрузил Плотность бумаги(Числовое значение) и хотел уже загрузить в След комбобокс толщину бумаги оно мне выдало ошибку:Несоответствие типов данных в выражении условия отбора Код для всех combobox:
Следует ожидать переводов разделов справочной системы Delphi, компиляций из учебников, переводы статей, «путевые заметки» и прочие интересности. Блог прежде всего ориентирован на студентов, но опытных людей я тоже буду рад видеть;-)
понедельник, 11 апреля 2011 г.
Параметры
О параметрах
Большинство заголовков процедур и функций имеют список параметров. Например, в заголовке:
Список параметров – это (X: Real; Y: Integer).
Список параметров – это последовательность объявлений параметров, разделяемых точками с запятой (;) и заключенных в круглые скобки. Каждое объявление представляет собой последовательность разделенных запятыми имен параметров, за которой в большей части случаев следует двоеточие и идентификатор типа (в некоторых случаях далее может следовать знак равенства (=) и значение по умолчанию. Имена параметров должны быть допустимыми идентификаторами. Любое объявление может предваряться ключевыми словами var, const или out. Примеры:
Список параметров определяет количество, порядок и тип параметров, которые должны быть переданы подпрограмме в момент ее вызова. Если подпрограмма не принимает никаких параметров, список параметров в объявлении подпрограммы опускается:
В теле процедуры или функции имена параметров ( X и Y в первом примере) могут быть использованы как локальные переменные. Не следует переопределять имена параметров в секции локальных объявлений в теле процедуры или функции.
Семантика параметров
Параметры могут быть классифицированы следующим образом:
Файлы и экземпляры структурированных типов, содержащие файлы могут передаваться только как параметры-переменные (var).
Передача параметров по ссылке и по значению
Большинство параметров – это параметры-значения (по умолчанию) или параметры-переменные (var). Параметры-значения передаются по значению, а параметры-переменные передаются по ссылке. Чтобы понять, что это обозначает, рассмотрим следующие функции:
После выполнение этого кода, переменная I, которая передана в DoubleByValue, имеет такое же значение, как ей было присвоено первоначально. А переменная V, которую мы передали в DoubleByRef, значение изменила.
Параметры-значения работают как локальные переменные, которые инициализируются значением, передаваемым при вызове процедуры или функции. Если вы передаете переменную как параметр-значение, процедура или функция создает ее копию. Изменения копии не влияют на значение оригинальной переменной и теряются в момент, когда управление возвращается вызывающей программе (подпрограмме).
Параметр-переменная, работает как указатель, а не как копия. Изменения значения переменной, сделанные в теле функции или процедуры, остаются после того, как управление передается вызывающей программе и имя параметра удаляется из области видимости.
Копирования не происходит даже если одна переменная передается в два или более параметров-переменных. Это может быть проиллюстрировано следующим примером:
После выполнения этого кода значение переменной I равно 3.
Если объявление подпрограммы определяет параметр-переменную, при вызове подпрограммы вы должны передать в качестве параметра выражение, которому может быть присвоено значение, то есть переменную, типизированную константу (при задействовании директивы <$J+>), ссылку указателя, поле или индексированную переменную. В нашем предыдущем примере вызов DoubleByRef(7) вызовет ошибку, а DoubleByValue(7) – будет правильным.
Индексы и ссылки указателей, переданные в параметры-переменные (как, например в вызове DoubleByRef(MyArray[I])) – вычисляются единожды перед выполнением подпрограммы.
Параметры-константы
Параметры-константы(const) действуют как локальные константы или переменные, доступные только для чтения. Параметры-константы схожи с параметрами-значениями, с тем лишь различием, что в теле процедуры или функции вы не можете присвоить параметру-константе значение или передать его в качестве параметра-переменной другой подпрограмме (но если вы передаете как параметр-констнту ссылку на объект, вы сможете изменять его свойства).
Использование параметров-констант позволяет оптимизировать код для структурированных и строковых параметров. Оно также обеспечивает защиту от случайной передачи таких параметров по ссылке в другие подпрограммы.
Далее приведен заголовок функции CompareStr в модуле SysUtils:
Поскольку S1 и S2 не изменяются в теле CompareStr, они могут быть объявлены как параметры-константы.
Выходные параметры
Выходной параметр (out), как и параметр-переменная, передается по ссылке. Но, при передаче выходного параметра, подпрограмма, в которую передается параметр, отбрасывает изначальное значение переменной.
Выходной параметр предназначен только для вывода, то есть, он показывает функции или процедуре, где сохранить данные, предназначенные для вывода, но не предоставляет никаких возможностей для ввода данных. Для примера рассмотрим заголовок процедуры:
При вызове процедуры GetInfo вы должны передать ей переменную типа SomeRecordType:
Но вы не используете MyRecord для передачи каких либо данных в процедуру GetInfo; MyRecord это просто контейнер, в котором GetInfo сохранит информацию, которую она сгенерирует. При вызове GetInfo перед передачей управления процедуре память, используемая для хранения MyRecord освобождается.
Выходные параметры часто используются с моделями распределенных объектов, подобными COM. Вдобавок вам придется использовать выходные параметры при передаче неинициализированных переменных функциям и процедурам.
Нетипизированные параметры
При объявлении параметров при помощи ключевых слов var, const и out вы можете опустить спецификации типа (параметры-значения должны быть типизированы) Например:
объявляет процедуру с именем TakeAnything, которая принимает параметры любого типа. Когда вы вызываете такую подпрограмму, вы не можете передать ей константу вещественного типа или числовую константу неопределенного типа.
В теле процедуры или функции, нетипизированные параметры несовместимы со всеми типами. Для управления нетипизированными параметрами вы должны преобразовать их тип. В общем случае компилятор не может проконтролировать правильность операций с нетипизированными параметрами.
В следующем примере нетипизированные параметры используются в функции Equal, которая сравнивает определенное количество байт в двух переменных:
Определив следующие идентификаторы: Вы можете выполнить следующие вызовы Equal:
Строковые параметры
Когда вы объявляете подпрограммы, которые принимают параметры типа shortstring, вы не можете указывать длину строк в объявлении параметров. То есть следующее объявление вызывает ошибку компиляции:
Правильным будет следующее объявление:
Специализированный идентификатор OpenString может быть использован для объявления подпрограмм, принимающих параметры типа shortstring различной длины:
Когда одновременно действуют директивы компилятора <$H>и <$P+>, зарезервированное слово string при объявлении параметров эквивалентно OpenString.
Параметры-массивы
При объявлении подпрограмм, принимающих в качестве параметров массивы, в списке параметров нельзя указывать спецификаторы индексов. То есть, объявление:
вызывает ошибку компиляции. Но объявление:
является правильным. Еще одним решением является использование в качестве параметров динамических массивов.
Поскольку язык Delphi не реализует передачу параметров по значению для динамических массивов, параметры-значения в подпрограммах не представляют полную копию динамических массивов. Например:
Следует учесть, что присваивание значения Value[0] в подпрограме p изменит содержимое динамического массива в вызывающем блоке, несмотря на то, что Value передается как параметр-значение. Если требуется создание полной копии динамического массива, следует пользоваться стандартной процедурой Copy.
Параметры-открытые массивы
Параметры-открытые массивы позволяют передавать в качестве параметров в одну и ту же процедуру или функцию массивы различных размеров. Чтобы объявить подпрограмму с параметром-открытым массивом, следует в списке параметров использовать синтаксис array of type (вместо array[X..Y] of type). Например:
объявляет функцию Find, которая в качестве параметра принимает массив символов произвольной длины и возвращает значение типа integer.
Замечание:Синтаксис для параметров-открытых массивов схож с объявлением динамических массивов, но эти два понятия различны. Предыдущий пример создает функцию, которая принимает в качестве параметра любой массив символов, включая и динамический массив (но не ограничиваясь им). Чтобы объявить параметр, который должен быть динамическим массивом, необходимо объявить соответствующий тип:
При передаче массива в качестве открытого массива в параметр-значение, компилятор создает локальную копию массива в стековом кадре подпрограммы. При передаче больших массивов может возникнуть переполнение стека.
Следующие примеры используют параметры-открытые массивы для определения процедуры Clear, которая присваивает всем элементам массива вещественных чисел значение 0 и функции Sum которая вычисляет сумму всех элементов массива вещественных чисел:
При вызове этих подпрограмм вы можете передавать им в качестве параметров конструкторы открытых массивов.
Вариантные параметры-открытые массивы
Вариантные параметры-открытые массивы позволяют передавать в процедуру или функцию массивы с различными базовыми типами. Для объявления подпрограммы с вариантным параметром-открытым массивом следует для параметра указать тип array of const. То есть:
объявляет процедуру DoSomething, которая может работать с гетерогенными массивами.
Следующи пример для Win32, использует вариантный параметр-открытый массив в функции, которая создает строковое представление каждого из элементов массива, переданного ей в качестве параметра, и возвращает эти строки в сцепленном виде. Подпрограммы для работы со строками, вызываемые в этой функции, объявлены в модуле SysUtils:
Эту функцию можно вызывать, используя конструктор открытого массива. Например: Вернет строку ‘test100 T3.14159TForm’.
Значения параметров по умолчанию
В заголовке процедуры или функции вы можете указать значения параметров по умолчанию. Указание значний по умолчанию разрешены только для типизированных параметров-констант и параметров-значений. Чтобы определить значение по умолчанию, объявление параметра следует закончить символом «=» с последующим указанием константного выражения, которое совместимо по присваиванию с типом параметра. Например, при следующем объявлении:
Следующие вызовы процедуры будут эквивалентны:
При множественном объявлении параметров указывать значения по умолчанию нельзя. То есть правильным будет объявление вида:
Параметры со значениями по умолчанию должны быть указаны в конце списка параметров. То есть все параметры, объявленные после первого параметра со значением по умолчанию должны также иметь значения по умолчанию. Например, следующее объявление неверно:
Значения по умолчанию указанные для процедурных типов перекрывают значения по умолчанию, указанные в объявлении действительных подпрограмм. То есть при объявлении:
При выполнении инструкций: В функцию Resizer будут переданы значения (N, 1.0).
Значения по умолчанию ограничены значениями, которые могут быть определены как константное выражение. Следовательно, параметры – динамические массивы, параметры процедурного типа, классы, метаклассы, интерфейсы не могут иметь значения по умолчанию, отличного от nil. Параметры типа record, variant, статические массивы, экземпляры классов вообще не могут иметь значений по умолчанию.
Значения параметров по умолчанию и перегружаемые функции
Если вы используете значение параметра по умолчанию в перегружаемой подпрограмме, избегайте неоднозначных объявлений параметров. Рассмотрим следующие объявления:
Фактически ни одна из процедур не может быть вызвана. Этот код вызовет ошибку компиляции.
Значения параметров по умолчанию в объявлениях Forward и Interface
Если подпрограмма имеет отложенное объявление или указывается в модуле в секции interface, значения параметров по умолчанию (если таковые присутствуют) должны быть указаны в объявлении forward или interface. В этом случае, значения по умолчанию могут быть опущены в последующем объявлении, но, в том случае, если последующее объявление содержит значения по умолчанию, они полностью должны совпадать с первым объявлением.