Легенда:
   новое сообщение
    закрытая нитка
    новое сообщение
    в закрытой нитке
    старое сообщение
         
		 | 
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
 - Новичкам также крайне полезно ознакомиться с данным документом.
   
  |   |   |   |   |   | 
А почему тогда это не было сделано явно (в смысле, просто не передали указатель на vcn)?  04.12.03 15:35  Число просмотров: 1537
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
| 
 | 
 
| 
<programming>
 |  
 
[C++] Нифига не понимаю... Help, please...  04.12.03 14:46  
 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 04.12.03 14:49  Количество правок: 1
 | 
 
Итак, имеем функцию на этом бесконечно мудром языке:
 (взято из примера по low-level NTFS programming)
 
VOID ReadExternalAttribute(
  PNONRESIDENT_ATTRIBUTE attr,
  ULONGLONG vcn, ULONG count, PVOID buffer)
{
  ULONGLONG lcn, runcount;
  ULONG readcount, left;
  PUCHAR bytes = PUCHAR(buffer);
  for (left = count; left > 0; left -= readcount) {
    FindRun(attr, vcn, &lcn, &runcount);
    readcount = ULONG(min(runcount, left));
    ULONG n = readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;
    if (lcn == 0)
      memset(bytes, 0, n);
    else
      ReadLCN(lcn, readcount, bytes);
    vcn += readcount; //Вот здесь непонятки ;-)
    bytes += n;
  }
}
 ---
 Почему в параметр vcn, переданный в функцию в стеке, делают присвоение с инкрементом? Насколько я понимаю, это делать нельзя (вернее, бессмысленно ;-).
 
 Заранее всем спасибо.
 | 
 
 
  | 
[C++] Почему буссмысленно?  04.12.03 14:58  
 Автор: Sandy <Alexander Stepanov> Статус: Elderman
 | 
 
> Итак, имеем функцию на этом бесконечно мудром языке: > (взято из примера по low-level NTFS programming) > > VOID ReadExternalAttribute(
>   PNONRESIDENT_ATTRIBUTE attr,
>   ULONGLONG vcn, ULONG count, PVOID buffer)
> {
>   ULONGLONG lcn, runcount;
>   ULONG readcount, left;
>   PUCHAR bytes = PUCHAR(buffer);
> 
>   for (left = count; left > 0; left -= readcount) {
>     FindRun(attr, vcn, &lcn, &runcount);
> 
>     readcount = ULONG(min(runcount, left));
> 
>     ULONG n = readcount * bootb.BytesPerSector *
> bootb.SectorsPerCluster;
> 
>     if (lcn == 0)
>       memset(bytes, 0, n);
>     else
>       ReadLCN(lcn, readcount, bytes);
> 
>     vcn += readcount; //Вот здесь непонятки ;-)
>     bytes += n;
>   }
> }
>  ---
 > Почему в параметр vcn, переданный в функцию в стеке, делают > присвоение с инкрементом? Насколько я понимаю, это делать > нельзя (вернее, бессмысленно ;-). 
 Переменная vcn глобальна для всей процедуры и поэтому доступна до выхода из процедуры. А в данном случае она увеличивается на кол-во байтов, считанных из LCN'а и подготавливается для следующей итерации цикла.
 
 > Заранее всем спасибо.
 | 
 
 
  |   | 
[C++] Потому что мне на Delphi это переделать надо ;-) Значит ли это, что мне в своей процедуре надо заводить локальную копию vcn?  04.12.03 15:20  
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
Т.е. эквивалентно ли это вот такой конструкции:
 
//Оригинальная процедура:
VOID ReadExternalAttribute(
  PNONRESIDENT_ATTRIBUTE attr,
  ULONGLONG vcn, ULONG count, PVOID buffer)
{
  ULONGLONG lcn, runcount;
  ULONG readcount, left;
  PUCHAR bytes = PUCHAR(buffer);
  for (left = count; left > 0; left -= readcount) {
    FindRun(attr, vcn, &lcn, &runcount);
    readcount = ULONG(min(runcount, left));
    ULONG n = readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;
    if (lcn == 0)
      memset(bytes, 0, n);
    else
      ReadLCN(lcn, readcount, bytes);
    vcn += readcount; //Вот здесь непонятки ;-)
    bytes += n;
  }
}
//Эквивалент:
  Procedure ReadExternalAttribute(
    attr: PNONRESIDENT_ATTRIBUTE;
    Const vcn: ULONGLONG; count: ULONG; buffer: Pointer);
  Var
    lcn, runcount: ULONGLONG;
    readcount, left, n: ULONG;
    bytes: PUCHAR;
    _vcn: ULONGLONG;
  Begin
    bytes  := buffer;
    left := count;
    _vcn := vcn;
    While left > 0 Do
    Begin
      FindRun(attr, vcn, @lcn, @runcount);
      readcount := min(runcount, left);
      n := readcount * bootb.BytesPerSector * bootb.SectorsPerCluster;
      if lcn = 0 Then ZeroMemory(bytes, n)
      else ReadLCN(lcn, readcount, bytes);
      Inc(_vcn, readcount);
      Inc(bytes, n);
      Dec(left, readcount);
    End;
  End;
 ---
 | 
 
 
  |   |   | 
[C++] А зачем ты ее в заголовке процедуры как Const описываешь? Убери Const и ничего заводить не придется  04.12.03 15:24  
 Автор: Sandy <Alexander Stepanov> Статус: Elderman
 | 
 
| 
 | 
 
 
  |   |   |   | 
[Pascal] А потому что если я поставлю Var или передам в функцию указатель, то переменная будет изменена _вне_ процедуры. Это подразумевалось в оригинале?  04.12.03 15:30  
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
| 
 | 
 
 
  |   |   |   |   | 
[Pascal] если не ставить ничего лишнего, будет как раз локальная копия переменной, как в варианте на Си  04.12.03 15:34  
 Автор: LLL <Алексей> Статус: Member
 | 
 
| 
 | 
 
 
  |   |   |   |   |   | 
[Pascal] Да я знаю, специально разжевал, поскольку те, кто шарит в цпп, могут не шарить в delphi, и наоборот, как я ;-)  04.12.03 15:42  
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
| 
 | 
 
 
  |   |   |   |   | 
Конечно, именно так и сделано в оригинале на С  04.12.03 15:32  
 Автор: Sandy <Alexander Stepanov> Статус: Elderman Отредактировано 04.12.03 15:32  Количество правок: 1
 | 
 
| 
 | 
 
 
  |   |   |   |   |   | 
А почему тогда это не было сделано явно (в смысле, просто не передали указатель на vcn)?  04.12.03 15:35  
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
| 
 | 
 
 
  |   |   |   |   |   |   | 
Sandy что-то перепутал, сказав "конечно", в оригинале именно копия переменной в функции модифицируется, безо всякого влияния на передаваемый аргумент  04.12.03 15:46  
 Автор: LLL <Алексей> Статус: Member
 | 
 
| 
 | 
 
 
  |   |   |   |   |   |   |   | 
Прошу прощения, невольно ввел Хэндла в заблуждение! :)  04.12.03 16:34  
 Автор: Sandy <Alexander Stepanov> Статус: Elderman
 | 
 
| 
 | 
 
 
  |   |   |   |   |   |   |   | 
Всё понятно, спасибо... Глаза мои раскрылись ;-)  04.12.03 15:48  
 Автор: HandleX <Александр М.> Статус: The Elderman
 | 
 
| 
 | 
 
 
  | 
[C++] Чего же тут непонятного  04.12.03 14:56  
 Автор: Cyril <sc> Статус: Member
 | 
 
> Итак, имеем функцию на этом бесконечно мудром языке: > (взято из примера по low-level NTFS programming) > > VOID ReadExternalAttribute(
>   PNONRESIDENT_ATTRIBUTE attr,
>   ULONGLONG vcn, ULONG count, PVOID buffer)
> {
>   ULONGLONG lcn, runcount;
>   ULONG readcount, left;
>   PUCHAR bytes = PUCHAR(buffer);
> 
>   for (left = count; left > 0; left -= readcount) {
>     FindRun(attr, vcn, &lcn, &runcount);
> 
>     readcount = ULONG(min(runcount, left));
> 
>     ULONG n = readcount * bootb.BytesPerSector *
> bootb.SectorsPerCluster;
> 
>     if (lcn == 0)
>       memset(bytes, 0, n);
>     else
>       ReadLCN(lcn, readcount, bytes);
> 
>     vcn += readcount; //Вот здесь непонятки ;-)
>     bytes += n;
>   }
> }
>  ---
 > Почему в параметр vcn, переданный в функцию в стеке, делают > присвоение с инкрементом? Насколько я понимаю, это делать > нельзя (вернее, бессмысленно ;-). Почему бессмысленно
 ведь FindRun(attr, vcn, &lcn, &runcount); вызывается в цикле с этим параметром
 | 
 
 
  
 
 | 
 |