如何在C语言中检查缓冲区?

4
我有一个大小为1500的缓冲区。在这个缓冲区中,我需要检查从100到115的15个字节是否全部为零。如果不使用任何循环,我们该如何实现呢?数据类型为“unsigned char”,实际上是一个无符号字符数组。
平台:Linux,C语言,gcc编译器。
使用memcmp()是否正确?我正在从智能卡中读取一些数据并将它们存储在缓冲区中。现在我需要检查最后15个字节是否连续为零。我提到了memcmp(),因为我需要一种高效的方法;智能卡读取已经花费了一些时间。
或者采用按位比较是否正确。请给出建议。

1
听起来像是一道作业题,应该加上作业标签。 - Zan Lynx
1
听起来像是一道作业题。请查阅memcmp函数。 - Mikel
5
不,你并不需要在这里使用特别快的东西。与读取智能卡相比,一个循环仍然会在眨眼之间完成。 - Ben Voigt
1
与读取过程相比,缓冲区检查非常快。效率在这里不是问题。是的,memcmp() 是一种可行的方法。您所指的零是 ASCII 数字 '0' 还是 ASCII NUL '\0'(零字节)? - Jonathan Leffler
memcmp并不是特别适用的函数。如果存在memspnmemcchr函数,则更为适用。 - Ben Voigt
检查15(或16)个字节是否为零不会成为您代码的瓶颈。最好花费精力寻找其他地方。使用分析工具找出问题所在。 - Ed Heal
4个回答

5
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
使用循环。这是表达您意图最清晰,最准确的方式。编译器将尽可能地进行优化。通过自己“优化”,实际上可能会使事情变得更糟。
真实故事,就在几天前发生了:我正在“优化”两个256位整数之间的比较函数。旧版本使用一个for循环来比较组成256位整数的8个32位整数,我将其更改为memcmp。它反而变慢了。结果发现,我的“优化”使编译器无法看到两个缓冲区都是32位对齐的,导致它使用了一种不太有效的比较程序。它已经优化掉了我的循环。

1

100到115不是15字节,而是16字节。 我假设在您的系统中int大小为16字节。

if (0 == *((unsigned int*)(buffer + 100))) {
         // all are  zero
}

2
这是未定义行为,会在某些平台上导致未对齐访问故障(总线错误)。 - David Schwartz
这段代码难道不是检查buffer[100]的地址是否为零吗? - Sam
2
我假设在你的系统中,int类型大小为16个字节。开什么玩笑?等等,你是说他的系统中sizeof(unsigned int) == 16个字节 == 128位? - maverik

0
我是这样实现的:
699 int is_empty_buffer(unsigned char *buff , size_t size)
700 {
701         return *buff || memcmp(buff , buff+1, size);
702 }
703 

如果返回值为零,则为空。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接