{0}花括号清零 VS memset清零

没有检索到摘要

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写自定义目录标题


{0}花括号清零 VS memset(dst, 0 , sizeof(dst_type))清零

============================================================

结论

在对C语言一个结构体或一块连续内存清零时,如果是在编译时,就可以确定下来类型和大小的内存区域,特别是小块内存,无疑用**{0}花括号清零**,将目标内存清零是最可取的!

为什么呢?

  • 美学角度

char dst[256] = {0};

VS

char dst[256];
memset(dst, 0, sizeof(dst));

==> {0}花括号清零无疑更简洁,而且给编译器优化留了充分空间

  • API角度

{0}花括号清零:在编译器的指导下,基本上按照机器字的单位进行清零

在x86/64的环境下,编译为64位的程序,对于char example[13] = {0};,使用素数作为长度的连续内存,是按照 ** 8 + 4 + 1 ,使用汇编mov***指令进行清零
如果长度比较长的连续内存,除内存的边角料外,是按照 机器字 ,使用汇编rep stos指令进行清零

大家可自行验证

VS

memset清零:针对于字节单位进行清零

memset(&intvar, 1, sizeof(intvar))来证明memset按照字节为单位设置内存,非常警醒和形象!

大家可自行比较:

  • memset(dst, 1, sizeof(dst))
  • memset(dst, 257, sizeof(dst))
  • memset(dst, 4099, sizeof(dst))
    一些memset特殊值情况,内存值set情况

–> 以字节为单位的内存操作,猜测来看,应该没有以机器字为单位的操作快,但具体没有考证 😦

  • 汇编角度

{0}花括号清零:编译器根据目标内存大小,使用mov*指令或rep stos指令进行清零内存,从此可见编译器对花括号清零操作的不同优化

VS

memset清零:存在函数调用和memset内部已优化的内存set实现,但已不拥有目标内存的类型信息,猜测来看,优化空间没有编译器那么大,且无可避免地存在函数调用上损失

补充

  • 在C++下,由于存在虚函数表以及多继承等特殊语言特性,在内存布局上,能够进行memset清零或者花括号清零操作的场景不多,但如果存在一些足够简单的类似C语言结构体对象,应该是可以类比的
#include<iostream> #include<cstring> using namespace std; // 邻接表存图 int h[100], e[10000], ne[10000], idx; int queue[100], hh = 0, tt = -1; // 数组模拟队列 int in[100]; // 入度表 // 添加边 a→b void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx++; } // 拓扑排序(Kahn算法) void bfs(int n) { // 统计入度 for (int i = 1; i <= n; i++) { for (int j = h[i]; j != -1; j = ne[j]) { int m = e[j]; in[m]++; } } // 初始入度为0的节点入队 for (int i = 1; i <= n; i++) { if (in[i] == 0) { queue[++tt] = i; } } // 处理队列 while (hh <= tt) { int t = queue[hh++]; // 取出队首 for (int i = h[t]; i != -1; i = ne[i]) { int m = e[i]; in[m]--; if (in[m] == 0) { // 入度降为0则入队 queue[++tt] = m; } } } } int main() { int n; cin >> n; memset(h, -1, sizeof h); // 初始化邻接表 // 读入每个人的后代 for (int i = 1; i <= n; i++) { int j; while (cin >> j, j != 0) { // 读到0结束 add(i, j); // 添加边i→j } } bfs(n); // 输出拓扑序 for (int i = 0; i < n; i++) { cout << queue[i] << " "; } return 0; }#include<iostream> #include<cstring> using namespace std; int h[100],e[10000],ne[10000],idx; int hh=0,tt=-1; int queue[100]; int in[100]; int add(int a,int b){ e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } void bfs(int n){ for(int i=1;i<=n;i++){ for(int j=h[i];j!=-1;j=ne[j]){ int m=e[j]; in[m]++; } } for(int i=1;i<=n;i++){ if(in[i]==0){ queue[++tt]=i; }} while(hh<=tt){ int t=queue[hh++]; for(int i=h[t];i!=-1;i=ne[i]){ int m=e[i]; in[m]--; if(in[m]==0){ queue[++tt]=m; } } } } int main(){ int n; cin>>n; memset(h,-1,sizeof h); for(int i=1;i<=n;i++){ int j; while(cin>>j,j!=0){ add(i,j); } } bfs(n); for(int i=0;i<n;i++){ cout<<queue[i]<<" "; } return 0; }这两段代码有什么区别
03-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值