Вот и началась моя 3 статья по делфи. Здесь мы рассмотрим циклы и массивы, а также много коечто интересного. Говорю сразу, что программы придуманы не мной!... Итак, начнем ........................ ЦИКЛЫ Цикл - это многократный повтор какого-то действия. Ну, чтоб легче вам было понять, наверняка вам мама в детстве говорила что ты зациклился на какой-то вещи, тоесть вам понравилась какаето игрушка, и вы постоянно напоминали про ее покупку, вот это и есть цикл....)))) В цикле обязательно должно выполняться какое то условие. Рассмотрим 2 случая: 1.) Если условие прописуется в начале тела цикла, то этот цикл называется "ПОКА"; 2.) Если условие прописуется в конце тела цикла, то такой цикл называется "ДО"; В цикле "Пока" сначала проверяется условие, и если оно выполняется, то есть логическое выражение истинно, выполняется оператор, а потом снова проверяется условие. Как только оно перестанет выполняться, цикл завершается. Вот общий вид цикла "Пока": while условие do оператор; ПРИМЕР алгоритма Евклида: while a<>d do //Вот это то самое условие, при выполнение которого цикл останавливается if a>b then a:=a-b //Здесь используется условный оператор(если a>b тогда значению а присваиваем разность между числами a и b else b:=b-a; //В противном случае значению b присваиваем разность между b и a......))) С этим циклом думаю разобрались, поехали дальше Оператор цикла "до". Проверка условия в цикле "до" осуществляется после выполнения оператора. Ну в общем тот же цикл пока, тока перевернутый Общий вид цикла "До": repeat оператор until условие; Тот же пример алгоритма Евклида, тока осуществленный циклом "до": repeat if a>b then a:=a-b; //Это условный оператор if b>a then b:=b-a //Это условный оператор until a=b; //это условие Надеюсь вы усвоили, а если неусвоили читайте еще раз, и еще раз, ну вобщем пока не дойдет А теперь перейдем к наиболее часто используемому циклу, и имя ему - "Перечень". Он используется если известно число повторений, тоесть вы до выполнения программы уже знаете сколько раз он будет выполняться) Перечень бывает двух видов: 1.) Прямой 2.) Обратный Прямой перечень идет от известного меньшего числа к известному большему, и на каждом шаге прибавляестя единица(...К примеру...) Общий вид цикла "Перечень": for i:=n1 to n2 do оператор; читается как "для i, начиная с n1 до n2, выполняется оператор". Переменная i называется переменной цикла, которая при прямом перечне всегда изменяется от меньшего значения к большему... Вот пример: for i:=1 to 5 do j:=j+i; Работает это дело так---- У нас значение i изменяется от 1 до 5, мы вобщем невидем как компьютер считает. В наше время скорость компьютера очень велика, но всеже, для общего развития, для того чтоб программа работала быстрее лутьше записать 2+2+2+2+2 чем 2*5, ну ладно, вернемся к теме)) компьютер выполняет сложение 5 раз, вот как это выполняется 0:=0+1; 1:=1+2; 3:=3+3; 6:=6+4; 10:=10+5; И на выводе мы получаем значение j равное 15..... Надеюсь разобрались, теперь разберем оператор обратного перечня. Он работает аналогично оператору цикла прямого перечня, но переменная цикла не увеличивается на единицу с каждым шагом, а уменьшается. Этот оператор имеет вид: for i:=n2 downto n1 do оператор; К примеру for i:=5 downto 1 do j:=j+i; 0:=0+5; 5:=5+4; 9:=9+3; 12:=12+2; 14:=14+1; Ну и ответ получаем опять же 15 С ЦИКЛАМИ ЗАКОНЧИЛИ...........переходим к массивам. МАССИВЫ Массив - это упорядоченный именованный набор из фиксированного количества однотипных данных. Доступ к любому элементу массива осуществляется по его номеру. Массивы бывают одномерные, двумерные и т.д. Рассматривать будем тока одномерный массив... Одномерный массив может быть набором чисел, совокупностью символьных данных или элементов иной приводы (даже массивом массивов). Так же, как и в последовательности, в одномерном массиве можно указать элемент с конкретным номером, например номер 3. Имеем массив к примеру: a:array[1..5] of integer = (23,1,64,2,7); В нашем случае имеем массив из 5 элементов, а нам нужно выдать к примеру тока 3 элемент, чтоб вывести его на экран нужно написать a[3] Под a[3] кроется число 64..........видите как все просто Ах да, общий вид записи массива: a:array[n1..n2] of integer; array в переводе с английского - массив, n1 обычно число 0 или 1, n2 это любое число большее n1, integer это тип чисел, в данном случае стоят целочисленные цифры. А теперь рассмотрим пример нахождения максимального элемента массива: const n=7; //здесь прописуем константу, тоесть n число постоянное и равное 7 var a:array[1..n] of integer; max,i:integer; //описуем переменные begin //начало программы max:=a[1]; //присваиваем максимальному элементу массива значение 1 for i:=2 to n do //устанавливаем цикл от 2 до 7 if max<a //если максимальный элемент меньше всех элементов массива then max:=a; //тогда максимальному значению присваиваем максимальный элемент end; //конец Вот и все.... Хочу немного рассказать про упорядочивание элементов массива. Метод называется Пузырьковый Ну как бы объяснить поподробней.. Ну допустим у вас есть 2 полных стакана с водой и вам нужно воду перелить с одного стакана в другой без потери воды, а как это сделать спросите Вы, да очень просто, нужно взять третий стакан и перелить в него воду с первого стакана, а со второго перелить воду в первый, а с третьего во второй. Так и в программировании, нужно ввести новую переменную к примеру "c" и сделать следующее c:=a; a:=b; b:=c; Надеюсь теперь вы себе представляете что такое циклы и массивы, если нет, то читайте еще раз, пробуйте, изменяйте код программы сделайте допустим нахождение минимального элемента массива или ченибудь еще, фантазируйте
Такс.....а теперь рассмотрим новую программу игру-головоломку Для начала зайдите в делфи и сохраните новый проект под названием к примеру фишки... Сохранили?, тогда приступим к созданию игры. На вкладке Standard имеется компонент panel. Теперь перейдем в инспектор объектов и зададим некие свойства для панели: 1.)Height(Высота)=65; 2.)Width(Ширина)=401; 3.)Очищаем значение Caption 4.)Bevellnner(Внутренняя фаска)=bwLowered //это по своему вкусу) Добавим кнопку, но не простую, а с рисунком. Откройте в палитре компонентов вкладку Additional и выберете компонент BitBtn Изменим ее свойства: 1.) Height=49; 2.) Width=49; 3.) Left=8; 4.) Top=8; 5.) Свойство Сaption необходимо очистить Теперь создайте еще 5 таких же кнопок с помощью буфера и в итоге должно получиться 6 кнопок. Для 2-6 кнопок задайте значение left = (64,120,232,288,344) Для каждой кнопки задайте свойство Tag = (2,4,6,11,13,15); Свойство Тег может хранить целое число, а что нужно хранить нам? Нам нужно хранить два числа. Во-первых, номер клетки, в которой находится кнопка, а во-вторых, признак "цвета" фишки (от него зависит, в какую сторону она может ходить). Зайдите в Paint и нарисуйте 2 изображения (размеры рисунков 45*45 пикселов), одно для трех левых кнопок, а одно для трех правых. Лутьше нарисовать просто стрелочки, так будет понятней. Сохраните эти рисунки и после загрузите их через свойство нашей кнопки Glyph. Ну чтож, а теперь приступим непосредственно к программированию.............. Клацаем по кнопке 2 раза и появляется обработчик событий BitBtn1Click, в него пишем следующее: procedure TForm1.BitBtn1Click(Sender: TObject); var i,c,k,ak:integer; begin with Sender as TBitBtn do begin i:=Tag div 2; //деление нацело c:=Tag mod 2; //остаток от деления k:=n-i; //величина перемещения ak:=Abs(k); //и длина хода if ak<3 then //максимальная длина хода if ((c=0) and (k>0)) or ((c=1) and (k<0)) then //это порверка хода, в зависимости от цвета фишки begin Tag:=Tag+2*k; //значение должно изменяться на удвоенную величину перемещения Left:=Left+56*k; //величину перемещения умножаем на расстояние между клетками win:=win-ak; n:=i; //пустая клетка окажется там, где раньше была фишка end; end; if win = 0 then //выполняем проверку завершения решения begin Caption:='Готово'; panel1.color:=clFuchsia; Panel1.Enabled:=false; end; end; А теперь в окне инспектора объектов переходим на вкладку Events и в событии OnClick выбираем BitBtn1Click; Это сделано для уменьшения работы, чтоб для каждой кнопки не писать один и тот же код. Ах да нам еще необходимо описать глобальные переменные, они описуются здесь: var Form1: TForm1; implementation И должно получиться вот такое: var Form1: TForm1; implementation n:integer=4; win:integer=24; Вот и все осталось только нажать F9 как видите ничего сложного А сейчас я приведу пример бесконечного цикла(взято и немного переработано с книги Михаила Фленова), будем открывать-закрывать сидиром). Кстати это частенько используется в Троянах ну в общем ладно, начнем) Запустите делфи, создайте новый проект и сохраните его) Теперь перейдите на вкладку Events формы и создайте обработчик событий OnCreate и поместити туда следующий код: procedure TForm1.FormCreate(Sender: TObject); begin ok:=false; openparm.lpstrDeviceType:='CDAudio'; repeat mciSendCommand(0,mci_open,mci_open_type,longint(@OpenParm)); DI:=OpenParm.wDeviceID; mciSendCommand(Di,mci_set,mci_set_door_open,longint(@setparm)); mciSendCommand(Di,mci_set,mci_set_door_closed,longint(@setparm)); mcisendcommand(DI,mci_close,mci_notify,longint(@genparm)); sleep(5000); until ok; end; И еще описывам глобальные переменные var Form1: TForm1; openparm:tmci_open_parms; genparm:tmci_Generic_parms; setparm:tmci_set_parms; di:cardinal; ok:boolean; И еще, в раздел uses добавляем новый модуль mmsystem, и должно получиться что то типа этого: uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,mmsystem; Такс....., а теперь будем разбирать код)...... В первой строчке кода переменной ок присваивается значение false. Потом запускается цикл repeat..until, который будет выполняться, пока эта переменная не станет равной true. Но так как нигде и никто не изменяет значение этой переменной, то она всегда будет равна false, и цикл получиться бесконечным. (Кстати попробуйте сделать сами открытие и закрытие сидюка при нажатии на кнопку ). Перед началом цикла необходимо еще заполнить параметр lpstrDeviceType структуры OpenParm. Сюда нужно занести значение CDAudio, что и будет указывать на необходимость работы с CD-ROM. Ну а дальше запускается цикл, в котором поочередно то открывается дверца, то закрывается. В конце цикла ставится задержка в пять секунд sleep(5000), чтобы CD-ROM успел "увидеть" диск после того, как закрылась дверца. Ну а теперь хочу выложить прогу, которая к примеру по заданному таймеру зайдет в спящий режим) Все как обычно, создаем форму, сохраняем, и переносим вот таки компоненты: 1.) Label1; 2.) Label2; 3.) Button1; 4.) Edit1; 5.) Timer1; 6.) Timer2; Для компонента Label1 изменяем значение Caption, стираем его. Для компонента Label2 изменяем значение Caption на "Выключить в:". Для компонента Button1 изменяем значение Caption на "Активизировать". Для компонента Edit1 изменяем значение Text на "00:00:00". Для компонента Timer1 изменяем значение Interval = 1; Для компонента Timer2 изменяем значение 1.)Interval = 1; 2.)Enabled = False; Теперь клацаем по Timer1 два раза и появляется обработчик событий Timer1Timer, там пишем следующее: procedure TForm1.Timer1Timer(Sender: TObject); begin label1.Caption:=timeToStr(time); //эта "штуковина" показывает текущее время end; Теперь клацаем по Timer2 два раза и появляется обработчик событий Timer2Timer, там пишем следующее: procedure TForm1.Timer2Timer(Sender: TObject); begin if edit1.Text=label1.Caption then ExitWindowsEx(EWX_Force,0); //если текст в Label1 совпадает с текстом в Edit1 то..догадайтесь) end; И наконец клацаем на нашу родную кнопку и пишем: procedure TForm1.Button1Click(Sender: TObject); begin timer2.Enabled:=true; //Включаем таймер end; Вот и все, домашнее задание вам сделать прогу, которая будет по заданному таймеру выключать комп. Кстати удобная и полезная вещица, особенно кто на поминутке, допустим что-то начали скачивать большое, сами ложитесь спать, выставляете таймер и все...когда время законница компьютер выключится.) Продолжение следует, но наверно уже после того как я поступлю в институт (сейчас мало времени). Планирую выпустить 4 последнюю главу - это создание трояна), но к этому нужно подойти серьезно, так как это не просто программа, ее нужно сделать качественной, чтоб ее неловили антивирусы и прочая лабуда, так что ждите... А еще хочу выложить программу www.hack-viyu.h16.ru/123.zip, ее хочу встроить в будующий троян)
Тока что загрузил программу, если кто пытался скачать, то извените хост не работал(......прошу оценить эту программу
Это не статья, а мысли нездорового "новичка". Половина выдумана, а половина не имеет практического применения, так и зациклишся на ней на*** на всю жизнь)))) P.S. Очень порадовал твой хакерский сайт. Но потом жутко обидно стало за героев сериала X-Files. Они столько старались... а ты взял да и засрал-таки их честную репутацию своим ИКСхакерским сайтом. Фокс Малдер тебя бы застрелил. Потому что он такой же крутой икс-хакер и не терпит конкуренции!
Мда... Ждёмс Делфи для новичков. Урок 4, а затем 5,6,7,8,9,10,11,12,13,14,15......1001,1002,1003. Было бы проще назвать уроки по делфи =))))
вообще, это напоминает пересказ книги своими словами. Под такие статьи следует отвести отдельный форум - "уроки". И статьи следует писать более в узкой области, которые не раскрывается в книгах, или раскрывается неполностью (если уж мы пишим урок). Думаю в любой книге по программированию рассказанно про циклы и массивы.
ты так считаешь? ты не прав по ходу. Sec†orX ммм ты попутал что-то. определение к которому ты до*бался -- правильное.
а какую книжку надо читать? ну или в какой книжке не будет написано, что массив упорядочн индексом... или что массив не имеет фиксированного количества элементов ... фиксированного хотя бы функцией СетЛеннз... хм... о чем ваще спор??? ps я ваще не дочилал статью... хватило на первых 2 предложения... ну просто коммент прочитал про массивы... не увидел там ошибок..
глупейшее определение. Бывают массивы динамические, бывают массивы с элементами разных типов. Под это ламерское определение они не попадают. йух те в сокет ) чел прав. согласен. Перечень? Вроде по-русски он называется цикл со счетчиком. иногда лучше *ать, чем говорить дальше не читал, ненавижу гнилой FormDriven код )
Пинать никто не будет. Я тоже много чего не знаю поетому в спорных случаях стараюсь промолчать а не упираться рогом в стену с пеной у рта доказывать (всем) свою (свою) правоту. А данный случай не спорный. без комментариев... слышал ли ты об ассоциативных массивах?? хотя и так ясно...... если тебе будет легче можешь считать массив структурированной записью (мне тоже смешно ) и напоследок.. во-первых без обид, а во-вторых если ты выучил (выучил?) паскаль (например) ето не значит что он является универсумом и весь мир можно под него перекраивать. и при етом кричать людям, на сто порядков больше нас с тобой знающим кстати, что они не правы…
slimeб, ты ошибаешься. Почитай литературу. По поводу разных типов: Массивы могут быть не только разных типов, но можно также создавать массив с разным типом данных элементов. Code: function VarArrayCreate(const Bounds: array of Integer; AVarType: TVarType): Variant; var I, LDimCount: Integer; LVarArrayRef: PVarArray; LVarBounds: array[0..63] of TVarArrayBound; begin if (not Odd(High(Bounds)) or (High(Bounds) > 127)) or (not VarTypeIsValidArrayType(AVarType)) then VarArrayCreateError; LDimCount := (High(Bounds) + 1) div 2; for I := 0 to LDimCount - 1 do with LVarBounds[I] do begin LowBound := Bounds[I * 2]; ElementCount := Bounds[I * 2 + 1] - LowBound + 1; end; LVarArrayRef := SafeArrayCreate(AVarType, LDimCount, PVarArrayBoundArray(@LVarBounds)^); if LVarArrayRef = nil then VarArrayCreateError; _VarClear(TVarData(Result)); TVarData(Result).VType := AVarType or varArray; TVarData(Result).VArray := LVarArrayRef; end; function VarArrayOf(const Values: array of Variant): Variant; var I: Integer; begin Result := VarArrayCreate([0, High(Values)], varVariant); for I := 0 to High(Values) do Result[I] := Values[I]; end; procedure _VarArrayRedim(var A: TVarData; HighBound: Integer); var VarBound: TVarArrayBound; LVarType: TVarType; LVarArray: PVarArray; begin if not GetVarDataArrayInfo(A, LVarType, LVarArray) then VarResultCheck(VAR_INVALIDARG); with LVarArray^ do VarBound.LowBound := Bounds[DimCount - 1].LowBound; VarBound.ElementCount := HighBound - VarBound.LowBound + 1; if SafeArrayRedim(LVarArray, VarBound) <> VAR_OK then VarArrayCreateError; end;
Я же говорю, что делает делфи с людьми. Массив - сам по себе, без всяких высокоуровневых хреновин - просто набор. Динамический, статический - никакого знаения не имеет, кто отделил под него память-загрузчик карты бинарника или процесс) Гетмем? Не видел такой ф-ии в kernel32.dll. К слову, GlobalAlloc, GlobalFree, VirtualAlloc, VirtualAllocEx, и ещё пару ф-ий. Эти ф-ии выделяют память, после чего ее можно использовать. Если у тебя уже выделеные блоки памяти, это тоже массивы. Байтов, WORD'ов, DWORD'ов. Массив размещается в стеке: Code: void Func( void ) { BYTE block[10]; BYTE block[] = "..."; BYTE block[5] = "1234"; // после всего будет 0x00 ... } Code: так если судить по вашим определениям запись ничем от массива не отличается. ничем. и вообще, какая запись? БРОСАЙ ДЕЛФИ СРОЧНО. помидоры, которые я продаю тоже есть разных типов. Но все они - помидоры. Так и тут - все байты. Если ты отделишь память под 10 эл-ов массива, каждый - структура struct s { DWORD a; DWORD b; } То, у тебя будет (sizeof( DWORD ) * 2 ) * 10. Смысл в этом. Остальное делает компилятор. Открой свою прогу отладчиком и посмотри что генерируется. Все можно сделать вообще без стуктур и массивов, просто используя указатель на выделеный блок, размера (sizeof( DWORD ) * 2 ) * 10 Наверное мы говорим о разных массивах. Я-о естественных для меня, а ты, о каких-нибудь в питоне, перле или тому подобное)) На самом деле, из всего что я сказал, следует что массив всегда имеет один размер, только из-за того, что пока указатель на его N'ный эл-т не попадет в невыделеную область или ещё хрен знает куда, что просто вызовет исключение. Можно использовать 5 эл-т массива, хотя определно всего 2 ) BYTE test1, test2; BYTE arr[2]; BYTE test1, test2; пожалуйста, используй, например, arr[3] ) только такого компилятор недопустит... так что надо не явно указывать... ф-ия возвращает значение - это значит, она в AX/EAX записала число