Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2015.03.29;
Скачать: [xml.tar.bz2];

Вниз

Си в Делфи   Найти похожие ветки 

 
Вова   (2014-08-05 21:10) [0]

Уважаемые участники форума.
Переписываю алгоритм lzma920 на делфи
столкнулся с проблемой чтения исходного кода
вот исходная функция на си:
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
   UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
   UInt32 *distances, UInt32 maxLen)
{
 son[_cyclicBufferPos] = curMatch;
 for (;;)
 {
   UInt32 delta = pos - curMatch;
   if (cutValue-- == 0 || delta >= _cyclicBufferSize)
     return distances;
   {
     const Byte *pb = cur - delta;
     curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
     if (pb[maxLen] == cur[maxLen] && *pb == *cur)
     {
       UInt32 len = 0;
       while (++len != lenLimit)
         if (pb[len] != cur[len])
           break;
       if (maxLen < len)
       {
         *distances++ = maxLen = len;
         *distances++ = delta - 1;
         if (len == lenLimit)
           return distances;
       }
     }
   }
 }
}

и почти переписанная на делфи
 _cyclicBufferPos: UInt32; _cyclicBufferSize: UInt32; cutValue: UInt32;
 distances: PUInt32; maxLen: UInt32 ): PUInt32; // static
var
 delta: UInt32;
 pb: PByte;
 len: UInt32;
begin
 son[_cyclicBufferPos] := curMatch;
 while (True) do
 begin
   delta := pos - curMatch;
   if (cutValue-- == 0 || delta >= _cyclicBufferSize) then
     Exit(distances);
   begin
     pb := cur - delta;
     if (delta > _cyclicBufferPos) then
       curMatch := son[_cyclicBufferPos - delta + _cyclicBufferSize]
     else
       curMatch := son[_cyclicBufferPos - delta + 0];
     if (pb[maxLen] = cur[maxLen]) and (pb^ = cur^) then
     begin
       len := 0;
       while (len <> lenLimit) do
       begin
         if (pb[len] <> cur[len]) then
           break;
         Inc(len);
       end;
       if (maxLen < len) then
       begin
         *distances++ = maxLen = len;
         *distances++ = delta - 1;
         if (len = lenLimit) then
           Exit(distances);
       end;
     end;
   end;
 end;
end;

не совсем панимаю эту строчку
   if (cutValue-- == 0 || delta >= _cyclicBufferSize) then
и совсем не понимаю эти две
         *distances++ = maxLen = len;
         *distances++ = delta - 1;
не хотелось бы накосячить

прошу прощения у администрации если эта тема создана не там где надо.


 
Wladimir1987 ©   (2014-08-05 21:12) [1]

и как быть со ststic функциями/процедурами
знаю только что статичным можно объявить метод класса
а как быть с обычными процедурами/функциями?


 
Пит   (2014-08-05 21:15) [2]

все тлен.

Компиль Сишный код в obj файл и линкуй к дельфи коду и не заморачивайся. Розыч может объяснить как это сделать.


 
Wladimir1987 ©   (2014-08-05 21:22) [3]

Розыч ?


 
Inovet ©   (2014-08-05 21:25) [4]

> [3] Wladimir1987 ©   (05.08.14 21:22)
> Розыч ?

Хошь, сам объясняй.


 
Inovet ©   (2014-08-05 21:26) [5]

> [2] Пит   (05.08.14 21:15)
> Компиль Сишный код в obj

Мы же не знаем какова цель действа.


 
Inovet ©   (2014-08-05 21:29) [6]

> [0] Вова   (05.08.14 21:10)
> не совсем панимаю эту строчку
>   if (cutValue-- == 0 || delta >= _cyclicBufferSize) then
> и совсем не понимаю эти две
>         *distances++ = maxLen = len;
>         *distances++ = delta - 1;

if (cutValue = 0) or (delta >= _cyclicBufferSize) then begin
 Inc(cutValue);
 //...
end


 
Inovet ©   (2014-08-05 21:33) [7]

> и совсем не понимаю эти две
>         *distances++ = maxLen = len;
>         *distances++ = delta - 1;
maxLen := len;
distances^ := maxLen;
Inc(distances);

distances^ := delta - 1;
Inc(distances);


 
Wladimir1987 ©   (2014-08-05 21:35) [8]

премного благодарен! :)


 
Inovet ©   (2014-08-05 21:36) [9]

> [6] Inovet ©   (05.08.14 21:29)
> Inc(cutValue);

Dec(cutValue);


 
Wladimir1987 ©   (2014-08-05 21:41) [10]

Inovet

> if (cutValue-- == 0 || delta >= _cyclicBufferSize)


Dec(cutValue);
if (cutValue = 0) or (delta >= _cyclicBufferSize) then begin
Inc(cutValue);
//...
end

?


 
Wladimir1987 ©   (2014-08-05 21:43) [11]

последний мой пост считать ересью
теперь всё понял
спасибо!


 
Inovet ©   (2014-08-05 21:50) [12]

Dec(cutValue);
if (cutValue = 0) or (delta >= _cyclicBufferSize) then begin
Inc(cutValue);
//...
end

А вот и фиг. Эх, придётся смотреть исходник из [0].


 
Wladimir1987 ©   (2014-08-05 21:56) [13]

Inovet

пока только переписываю и в код особо не вникал
но кажись значение cutValue должно уменьшаться с каждой итерацией основного цикла while (True) do
и думаю должно быть так

Dec(cutValue);
if (cutValue = 0) or (delta >= _cyclicBufferSize) then
Exit(distances);


 
Inovet ©   (2014-08-05 21:58) [14]

if (cutValue-- == 0 || delta >= _cyclicBufferSize)
    return distances;
  {
вот сюда тогда уж
Dec(cutValue);

А блок там зачем? Типа, переменные pb и len перекрыть? Так чёт я их не вижу выше.


 
Wladimir1987 ©   (2014-08-05 22:04) [15]


> А блок там зачем?

фиг знает
убрал
вот так всё пучком?

function Hc_GetMatchesSpec( lenLimit: UInt32; curMatch: UInt32; pos: UInt32; const cur: PByte; son: PLzRef;
 _cyclicBufferPos: UInt32; _cyclicBufferSize: UInt32; cutValue: UInt32;
 distances: PUInt32; maxLen: UInt32 ): PUInt32; // static
var
 delta: UInt32;
 pb: PByte;
 len: UInt32;
begin
 son[_cyclicBufferPos] := curMatch;
 while (True) do
 begin
   delta := pos - curMatch;
   if (cutValue = 0) or (delta >= _cyclicBufferSize) then
     Exit(distances);
   Dec(cutValue);

   pb := cur - delta;
   if (delta > _cyclicBufferPos) then
     curMatch := son[_cyclicBufferPos - delta + _cyclicBufferSize]
   else
     curMatch := son[_cyclicBufferPos - delta + 0];
   if (pb[maxLen] = cur[maxLen]) and (pb^ = cur^) then
   begin
     len := 0;
     while (len <> lenLimit) do
     begin
       if (pb[len] <> cur[len]) then
         break;
       Inc(len);
     end;
     if (maxLen < len) then
     begin
       maxLen := len;
       distances^ := maxLen;
       Inc(distances);

       distances^ := delta - 1;
       Inc(distances);

       if (len = lenLimit) then
         Exit(distances);
     end;
   end;
 end;
end;


 
Inovet ©   (2014-08-05 22:21) [16]

Должно быть.


 
Rouse_ ©   (2014-08-06 12:10) [17]

Это не подойдет? Порт от авторов 7zip: http://www.birtles.org.uk/programming/LZMA.442b.7z


 
Wladimir1987 ©   (2014-08-06 12:30) [18]

Rouse_
нет
хотелось бы свежий
+лцма2 в старых версиях нет

да и цель у меня простая - иметь актуальный код разжатия/сжатия  
с возможностью его редактирования при необходимости или оптимизации
+улучшение понимания синтаксиса Си, тк хотя и сижу на делфи, а часто приходится иметь дело с сишным кодом
...
вот например функция выше сравнивает память так
if (pb[len] <> cur[len]) then
break;
Inc(len);
ища одинаковые участки
но сравнивать по байтам - не самый быстрый способ
можно сравнивать по инту, и потом, когда оставшийся размер станет меньше 4-х байт сравнивать по 2 или по 1 байту


 
CompareMem   (2014-08-06 13:15) [19]

> Wladimir1987 ©   (06.08.14 12:30) [18]

CompareMem


 
Wladimir1987 ©   (2014-08-06 13:32) [20]


> CompareMem

в самый раз!


 
Rouse_ ©   (2014-08-06 21:16) [21]


> да и цель у меня простая - иметь актуальный код разжатия/сжатия

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


 
Wladimir1987 ©   (2014-08-06 23:12) [22]

Rouse_
дык он уже фиг знает сколько актуален, то бишь 9.20 и 9.22 Beta висят на офф. сайте с 2010 и 2011 годов соответственно и на данный момент являются актуальными

я ж переписываю, не чтоб потом при первой возможности начать переписывать новый, если таковой появится

дело в том, что не так давно я убедился в том, что алгоритм лцма последних версий с настройками на ультре жмёт файл с избыточной информацией в белый шум,
те сжатый файл имеет максимальную энтропию данных,
а именно всех байт от 0..255 в файле в равном кол-ве (и они ещё равномерно распределены по файлу) и все отдельно взятые цепочки байт уникальны вне зависимости от их длины и местоположения, то бишь никаких или почти никаких повторов, замена которых на запись в словаре не приведёт к сжатию, или инфа о них >= их размеру, что тоже ничего не даст кроме в худшем случае раздутия архива на выходе
Дальнейшее серьёзное сжатие известными мне алгоритмами данных невозможно.
Единственное, что могу себе представить, только написание преобразователя, который будет преобразовывать участки памяти так чтоб идущий непосредственно за ним алгоритм сжатия сжал их сильнее. но для этого нужно сначала досконально изучить сам алгоритм (хотя бы LZ77), чтоб знать что ему нужно чтоб сильнее сжать.

всем этим я хочу сказать, что нынешняя версия алгоритма является близкой к идеальной в своём роде словарных алгоритмов сжатия ориентированных на сжатие данных с низкой энтропией данных (те есть повторы или одинаковые участи, короче избыточная инфа) и даже если вдруг выйдет новая ревизия рыпаться сразу переписывать смысла большого нет
:)


 
Styx   (2014-08-06 23:20) [23]

Так а чем не устраивает линковка сишного объектника-то? Всяко проще будет.


 
Rouse__   (2014-08-06 23:27) [24]

Ну теория у тебя есть, слова умные в принципе сказал, правда выводы не верные :)
Впрочем я так и не понял - зачем тебе все это руками портировать? :)


 
Wladimir1987 ©   (2014-08-06 23:52) [25]

Styx
всё просто
прежде всего скажу что я очень люблю программирование как таковое и Rouse_ прав говоря " ты идешь самым трудным путем".  Я сам это осознаю, однако все эти трудности нивеллируются моим энтузиазмом и данным форумом, где я, как уже сделал, могу спросить у старших товарищей о решении тех или иных проблем
дело в том что я со своим дружбаном на пару уже как пол года думаю о том как сжать файл со свойством белого шума и уже были предложены некоторые решения которые правда сильно хромающие и после того как я последний раз обломался достигнув сжатия и не заметив грубой ошибки, которое на нём ставит крест
само по себе сжатие мне нужно для моего проекта, а так как я пищу питаясь собственным энтузиазмом первой мыслью было не брать что-то готовое и рабочее, а написать своё и очень быстро появилась идея придумать принципиально новый алгоритм который будет жать даже белый шум, но после столького времени проб и ошибок я решил изменить подход и начать с "малого": набраться опыта занявшись сначала переписыванием самого на мой взгляд эффективного алгоритма; его доскональное изучение: потом улучшение (например вышеупомянутый преобразователь) и тем самым накопление опыта и идей для дальнейшей работы над чем-то уникальным и новым
и вот я на первом наге -- переписание.
Я не сишник и менять язык не хочу так как ценю делфи за его выразительность проистекающую из его приятного на глаз синтаксиса

если б я преследовал только цель иметь API для сжатия и просто им пользоваться, то я бы заюзал бы существующие библиотеки или как было
предложено использовал бы объекты

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


 
Rouse__   (2014-08-06 23:58) [26]

Ну чтож, в принципе похвально (серьезно) но белый шум - это энтропия равная восьми, поэтому советую немного подтянуть теорию еще чуть-чуть и не приравнивать пакованные файлы к чистому белому шуму :)
Зы: а так вообще слова правильные говоришь, надо тебя запомнить ( на перспективу:)


 
Wladimir1987 ©   (2014-08-07 00:04) [27]

Rouse__
да мы тут ещё (100%) не раз на этом форуме пересечёмся :)


 
Wladimir1987 ©   (2014-08-07 00:07) [28]

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


 
Inovet ©   (2014-08-07 08:06) [29]

> [22] Wladimir1987 ©   (06.08.14 23:12)
> Дальнейшее серьёзное сжатие известными мне алгоритмами данных невозможно.

Я, конечно, не в теме, но где-то видел таблицу, так есть архиватор, который жмёт лучше 7z там на около 1%, но работает в 10 раз медленнее из-за этого. Ну видимо, из академического интереса писался, не знаю. Российский вроде бы.


 
Wladimir1987 ©   (2014-08-07 14:43) [30]

Inovet
спасибо за инфу!
приму к сведению


 
Wladimir1987 ©   (2014-08-13 17:50) [31]

снова возник вопрос

#define DEF_GetHeads2(name, v, action) \
static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
{ action; for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } }

#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)

DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
/* DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */


нвпример (если я правильно понимаю) вот эта строка
DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
переписывается в функцию
static void GetHeads3(const Byte *p, UInt32 pos, UInt32 *hash, UInt32 hashMask,
 UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
 action;
 for (; numHeads != 0; numHeads--)
 {
const UInt32 value = (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask);
p++;
*heads++ = pos - hash[value];
hash[value] = pos++;
 }
}


вместо action; ничего не вставляется
но
вот эта строка содержит attion
DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )

даже 2 раза вроде бы
hashMask = hashMask;
crc = crc;


и по идее должно получиться следующее:
static void GetHeads2(const Byte *p, UInt32 pos, UInt32 *hash, UInt32 hashMask,
 UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
 hashMask = hashMask;
 crc = crc;

 for (; numHeads != 0; numHeads--)
 {
const UInt32 value = (p[0] | ((UInt32)p[1] << 8));
p++;
*heads++ = pos - hash[value];
hash[value] = pos++;
 }
}


но как понимать это действие?
 hashMask = hashMask;
 crc = crc;


 
Rouse_ ©   (2014-08-13 20:30) [32]

Ты как-то не правильно код запостил, у тебя скобки при декларации дефайнов не бьются, поэтому акшен там немного другой будет.

Но по сути, т.к. мы не работает с обьектами, последние приведенные тобой две строчки кода, работают как BOOL (присвоение значения можно убрать)


 
Rouse_ ©   (2014-08-13 20:34) [33]

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


 
Друг   (2014-08-13 21:10) [34]

Иногда мне кажется, что ад выглядит так - до конца дней переписывать Си код в Delphi
Тоже поддерживаю вариант компиляции Си в obj


 
Wladimir1987 ©   (2014-08-13 21:38) [35]

Rouse_
ну я не спешно превожу:
1. сначала полностью строчка в строчку на даклфи:
1.1 всё проверить, открыв оба кода в двух окнах рядом
2. начать компилить и править уже строчки на короые Rad матерится
(например var x: PUInt32; ...  x[32] это PUInt32(NativeUInt(x) + (32 * SizeOf(UInt32)))^ )
2.1 снова проверить адресную арифметику
и потом всё ещё раз пребежаться глазами на всякий случай
думаю ошибки исключены
а с вышеуказанным макросм не поможет даже "собери рабочий вариант на сях"
ибо я его попросту не понимаю :(
...
вот ещё раз этот макрос

#define DEF_GetHeads2(name, v, action) \
static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
{ action; for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } }

#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)

DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
/* DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */

это всё. дальше уже норм. процедуры идут
и на всякий случай сам .c файл
http://rghost.ru/private/57451628/6cbdf2f9bad9f5d4a3ec3e94c7709560

вот оно удобство Си! С одной стороны удобно, с другой стороны садомия это всё разгребать (имею в виду макросы)
Некоторые люди действительно таким удобством злоупотребляют

Друг
 поддерживаю, но "вариант компиляции Си в obj" - не вариант. Выше объяснял почему


 
Inovet ©   (2014-08-13 23:48) [36]

> [34] Друг   (13.08.14 21:10)
> что ад выглядит так - до конца дней переписывать Си код в Delphi

Ад - делать это вечно.


 
Wladimir1987 ©   (2014-08-14 02:38) [37]

кажется я разобрался
Rouse_: "последние приведенные тобой две строчки кода, работают как BOOL "
думал об этом, но вряд ли
для булев значения нужно в данном случае сравнение ==
например:
BOOL IsEqual( int A, int B )
{
retutn (a == b);
}

и опять же даже если это и есть какое-то действие, оно ни на что не влияет, тк ничто не проверяется и не присваивается например так x := (hashMask = hashMask); Хотя последнее тоже бессмысленно

думаю здесь всё гораздо проще.
вспомнил, что в прототипах некоторых WINAPI функций встречаются переменные типа dwResrerved или lpReserved, которые должны быть 0 и nil соответственно
здесь же автор кода возможно зарезервировал в макросе  GetHeads2 параметр  action на будущее или он был раньше, но сейчас не используется, а чтоб компилятор не матерился он просто делает "муляжное-действие" то бишь просто присваивает переменные (приравнивает) самой себе. в этих двух строчках:
hashMask = hashMask;
crc = crc;

и по сути в этих строчках и нет никакого смысла для самого алгоритма
надеюсь я правильно предположил
просьба, кто в теме, поправить меня если я ошибаюсь
а сами функции выглядят в конечном итоге так:
static void GetHeads2(const Byte *p, UInt32 pos,
 UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
  //  hashMask = hashMask;
  //crc = crc;
  for (; numHeads != 0; numHeads--)
  {
  const UInt32 value = (p[0] | ((UInt32)p[1] << 8));
  p++;
  *heads++ = pos - hash[value];
  hash[value] = pos++;
  }
}

static void GetHeads3(const Byte *p, UInt32 pos,
 UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
  for (; numHeads != 0; numHeads--)
  {
  const UInt32 value = (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask);
  p++;
  *heads++ = pos - hash[value];
  hash[value] = pos++;
  }
}

static void GetHeads4(const Byte *p, UInt32 pos,
 UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
  for (; numHeads != 0; numHeads--)
  {
  const UInt32 value = (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask);
  p++;
  *heads++ = pos - hash[value];
  hash[value] = pos++;
  }
}

static void GetHeads4b(const Byte *p, UInt32 pos,
 UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
  for (; numHeads != 0; numHeads--)
  {
  const UInt32 value = (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask);
  p++;
  *heads++ = pos - hash[value];
  hash[value] = pos++;
  }
}

/*
static void GetHeads5(const Byte *p, UInt32 pos,
 UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc)
{
  for (; numHeads != 0; numHeads--)
  {
  const UInt32 value = (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask);
  p++;
  *heads++ = pos - hash[value];
  hash[value] = pos++;
  }
}
*/


 
Пит   (2014-08-14 09:23) [38]

а прилинковать таки гораздо проще.


 
Rouse_ ©   (2014-08-14 10:18) [39]


> для булев значения нужно в данном случае сравнение ==
> например:

не, я про другое имел ввиду:

if (hashMask)
 foo();

if (hashMask = hashMask)
 foo();

if (hashMask == hashMask)
 foo();


процедура foo() в первых двух случаях выполнится если hashMask не равен нулю, а в третьем случае она выполнится всегда



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2015.03.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.003 c
2-1384890210
Denh
2013-11-19 23:43
2015.03.29
JSON сохранить "C: temp cv.txt" и обратно загрузить TJSONObject


3-1303730170
Дмитрий Тимохов
2011-04-25 15:16
2015.03.29
Код ошибки Timeout expired в MS SQL Server.


15-1408018598
Дмитрий СС
2014-08-14 16:16
2015.03.29
Как это называется?


15-1407918944
Друг
2014-08-13 12:35
2015.03.29
Помогите настроить VPN и браузер


4-1271301738
Interesting
2010-04-15 07:22
2015.03.29
Температура проца





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский