Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | | | | | |
Прошу прощения, невольно ввел Хэндла в заблуждение! :) 04.12.03 16:34 Число просмотров: 1353
Автор: Sandy <Alexander Stepanov> Статус: 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); вызывается в цикле с этим параметром
|
|
|