如何在C语言中清空数组的所有元素?

7
volatile static uint8_t buffer[16];
void ResetBuffer(){     
   for(int i=strlen((char*)buffer);i>=0;i--) buffer[i]='\0'; 
}

缓冲区变量必须在微控制器中始终使用,因此我已经使用了volatile static和全局变量。但是,为了使所有缓冲区清除,像这样编码是否正确?如果不正确或有其他简单的代码,请向我展示一些简单的代码。
我听说如果我想要清除它,那么只需将第一个元素设置为空即可。例如:buffer[0] = '\0'; 但是,当我这样编码时,其他元素仍然保留。
我知道这是一个非常简单的问题。但是我很困惑。我通常在C++或Java中正常编程,因此对于在C中编程感到相当困惑。

2
如果您的缓冲区没有以空字符结尾,strlen可能会导致崩溃。 - cup
我错过了,谢谢! - Sean
3个回答

17

您使用的strlen()是错误的,它依赖于缓冲区的内容是有效的字符串; 它不会清除整个缓冲区。

只需使用memset()sizeof

memset(buffer, 0, sizeof buffer);

请注意,sizeof不是函数,因此在这种情况下不需要使用括号(在我看来也不应该使用)。

如果您的C库未包含memset(),当然可以使用普通循环:

for(size_t i = 0; i < sizeof buffer; ++i)
  buffer[i] = 0;

如果你只想清除已使用的部分,并且知道这是一个有效的字符串,那么你的代码当然可以工作。我可能不会使用逆向循环,因为我觉得那样不直观,但那只是我的个人喜好。

注意:如果此缓冲区用于字符串,则应将其更改为具有类型 char 而不是 uint8_t


4
终于有人意识到sizeof不是一个函数了,点赞! - The Paramagnetic Croissant
@TheParamagneticCroissant 我已经意识到有一段时间了,但当然被赞赏还是很有趣的。谢谢。 - unwind
1
是的,清空整个东西。将每个元素设置为0就可以做到这一点,而清除所有元素所需的额外时钟周期比仅清除有限数量的元素所需的算术时钟周期更少。 - David C. Rankin
2
@unwind:我认为即使强制转换,将uint8_t *传递给strlen也是违反约束的(不确定,但我认为是这样)。 - Giorgi Moniava
1
@Giorgi 很好的建议,我编辑了一下以提及类型转换的建议。 - unwind
显示剩余13条评论

6
memset(buffer, 0, sizeof(buffer));

除非 sizeof(buffer) 已经是缓冲区的大小(以字节为单位),否则应该避免使用 sizeof(*buffer) 相乘。这是错误的。@FrerichRaabe - The Paramagnetic Croissant

4
将'\0'赋值给字符数组的第一个元素就足以使其成为空字符串,但这并不清除整个数组。为了清除,您需要使用:
memset(buffer, 0, sizeof(buffer));

或者

bzero(buffer, sizeof(buffer));

4
请注意,bzero不是标准函数。从bzero手册中可以得知:4.3BSD.该函数已被弃用(在POSIX.1-2001中标记为遗留),新程序应使用memset(3)。POSIX.1-2008中删除了对bzero()的规范说明。 - Enzo Ferber
1
@sreeyesh 但是,为什么不这样编码:memset(buffer,'\0',sizeof(buffer)); 因为我知道'\0'和0之间是有区别的。 - Sean
2
@Sean 字符 '\0' 的 ASCII 值为 0。因此,无论您使用 0 还是 '\0',编译器都会在两种情况下传递值 0,这并不重要。但是,memset 的第二个参数是一个整数。由于 '\0' 是一个字符常量,编译器将进行类型转换。然而,它是由编译器处理的。 - Sreeyesh Sreedharan

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