Вот мое решение, но еще более важно мой подход к решению проблемы.
Я подошел к проблеме с
- рисунок ячеек памяти и рисунок стрелки от адресата к источнику.
- сделал таблицу с изображением вышеприведенного чертежа.
- маркировка каждой строки в таблице с относительным байтовым адресом.
Это показало мне закономерность:
- позволить
iL
быть низким Nybble (половина байт) a[i]
- пусть
iH
быть высокой Nybble из a[i]
iH = (i+1)L
iL = (i+2)H
Этот шаблон сохраняется для всех байтов.
Переводя в C, это означает:
a[i] = (iH << 4) OR iL
a[i] = ((a[i+1] & 0x0f) << 4) | ((a[i+2] & 0xf0) >> 4)
теперь сделать еще три замечания:
- , поскольку мы выполняем задания слева направо, нам не нужно хранить любые значения во временных переменных.
- у нас будет специальный чехол для хвоста: все
12 bits
в конце будет равно нулю.
- мы должны избегать чтения неопределенной памяти за массивом. так как мы никогда не читали более
a[i+2]
, это влияет только на последние два байта
Итак, мы
- обрабатывать общий случай, обернув для
N-2 bytes
и выполнения общего расчета выше
- обрабатывать следующий до последнего байта по ним, установив
iH = (i+1)L
- ручку последних байт, установив его в
0
дал a
длиной N
, мы получаем:
for (i = 0; i < N - 2; ++i) {
a[i] = ((a[i+1] & 0x0f) << 4) | ((a[i+2] & 0xf0) >> 4);
}
a[N-2] = (a[N-1) & 0x0f) << 4;
a[N-1] = 0;
А что у вас есть ... массив сдвигается влево на 12 bits
. Его можно было бы легко обобщить на смещение N bits
, отметив, что будут M
присваивания, где M = number of bits modulo 8
, я считаю.
Цикл может быть более эффективным на некоторых машинах путем перевода на указатели
for (p = a, p2=a+N-2; p != p2; ++p) {
*p = ((*(p+1) & 0x0f) << 4) | (((*(p+2) & 0xf0) >> 4);
}
и используя наибольшее целое число, тип данных, поддерживаемый ЦП.
(я только что напечатали это, так что теперь будет хорошее время для кого-то, чтобы просмотреть код, тем более, что немного вертел, как известно, легко ошибиться.)
Это приведет к разыменованию конца массива, когда массив имеет нулевую длину или содержит только один байт. – 2008-09-12 17:18:35