Как проверить буфер в C? - PullRequest
       5

Как проверить буфер в C?

3 голосов
/ 08 февраля 2012

У меня есть буфер размером 1500. В этом буфере мне нужно проверить, все ли 15 байтов равны нулю или нет (от 100 до 115). Как мы можем это сделать (если мы не используем какой-либо цикл для этого)? Данные имеют тип "unsigned char", на самом деле это массив unsigned char.

Платформа: Linux, C, компилятор gcc

Будет ли использование memcmp() правильным или нет? Я читаю некоторые данные со смарт-карты и сохраняю их в буфере. Теперь мне нужно проверить, являются ли последние 15 байтов последовательными нулями или нет. Я упомянул memcmp() здесь, потому что мне нужен эффективный подход; чтение смарт-карты уже заняло некоторое время.

Или правильное сравнение будет побитным или нет. Пожалуйста, предложите.

Ответы [ 4 ]

4 голосов
/ 08 февраля 2012
unsigned char buffer[1500];
...
bool allZeros = true;
for (int i = 99; i < 115; ++i)
{
    if (buffer[i] != 0)
    {
        allZeros = false;
        break;
    }
}

.

static const unsigned char zeros[15] = {0};
...
unsigned char buffer[1500];
...
bool allZeros = (memcmp(&buffer[99], zeros, 15) == 0);
2 голосов
/ 08 февраля 2012

Используйте цикл. Это самый ясный, самый точный способ выразить свое намерение. Компилятор максимально оптимизирует его. «Оптимизировав» его самостоятельно, вы можете сделать все еще хуже.

Правдивая история произошла со мной несколько дней назад: я «оптимизировал» функцию сравнения двух 256-битных целых чисел. Старая версия использовала цикл for для сравнения 8 32-битных целых чисел, которые составляли 256-битные целые числа, я изменил его на memcmp. Это было медленнее . Оказывается, моя «оптимизация» ослепила компилятор тем фактом, что оба буфера были выровнены по 32-битной схеме, в результате чего он использовал менее эффективную процедуру сравнения. В любом случае он уже оптимизировал мой цикл.

1 голос
/ 08 февраля 2012

100 до 115 - это не 15 байт, это 16 байт.Я предполагаю, что размер int составляет 16 байт в вашей системе.

if (0 == *((unsigned int*)(buffer + 100))) {
         // all are  zero
}
0 голосов
/ 08 февраля 2012

Я реализовал так:

699 int is_empty_buffer(unsigned char *buff , size_t size)
700 {
701         return *buff || memcmp(buff , buff+1, size);
702 }
703 

если возвращаемое значение равно нулю, то оно пустое

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...