为数组赋值:memset vs for 循环

Posted

技术标签:

【中文标题】为数组赋值:memset vs for 循环【英文标题】:Assigning values to array: memset vs for loop 【发布时间】:2018-02-06 14:11:01 【问题描述】:

目前,当我尝试将值分配给数组时,我在memset 和 for 循环之间遇到了问题。当我尝试用 for 循环替换 memset 时,我的程序的输出有所不同。当我尝试memset 时,我得到的输出为5

bool visited[21][21]; int ans[21][21];
memset(ans,10000,sizeof(ans));
 memset(visited,0,sizeof(visited));

但是当我尝试用 for 循环替换 memset 时,我得到的输出为 -1

bool visited[21][21]; int ans[21][21];
for(int a1=0;a1<21;a1++)
    
        for(int b1=0;b1<21;b1++)
        
            ans[a1][b1]=10000;
        
    


    for(int a1=0;a1<21;a1++)
    
        for(int b1=0;b1<21;b1++)
        
            visited[a1][b1]=0;
        
    

这里memset 给出了正确的输出,但for 循环不是。谁能解释一下这个原因或者用for 循环替换memset 的方法?

这是我的完整输入代码

#include<bits/stdc++.h>

using namespace std ;

bool ar[21][21]; bool visited[21][21]; int ans[21][21]; int xa[]=0,-1,0,1; int yb[]=1,0,-1,0; int n;


typedef struct Point int x,y;
P;

typedef struct C  int x,y; int dis;  C;

bool issafe(int x,int y)  return (x>=0 && x<n && y>=0 && y<n && ar[x][y] && !visited[x][y]); 

void bfs(int x,int y)  queue<C> q; C in; in.x=x; in.y=y; in.dis=0; q.push(in); visited[x][y]=1;

while(!q.empty())

    C c=q.front();
    q.pop();
    int a=c.x;
    int b=c.y;
    int d=c.dis;
    ans[a][b]=d;

    for(int i=0;i<4;i++)
    

        int nx=a+xa[i];
        int ny=b+yb[i];
        if(issafe(nx,ny))
        
            visited[nx][ny]=1;
            in.x=nx;
            in.y=ny;
            in.dis=d+1;
            q.push(in);
        
 




int main() 

cin>>n;
for(int i=0;i<n;i++)

    for(int j=0;j<n;j++)
    
        cin>>ar[i][j];
    


int q;
cin>>q;

P rare[q];

int fans=10000;
int mx=-1;


for(int i=0;i<q;i++)


    int a,b;
    cin>>a>>b;

    rare[i].x=a;
    rare[i].y=b;



for(int i=0;i<n;i++)

    for(int j=0;j<n;j++)
    
       for(int k=0;k<21;k++)
                for(int m=0;m<21;m++)
            ans[k][m]=10000;
                
            
  // memset(ans,10000,sizeof(ans));

        int flag=0;
        for(int l=0;l<21;l++)
       
           for(int n1=0;n1<21;n1++)
        visited[l][n1]=0;
           
        
       // memset(visited,0,sizeof(visited));



        mx=-1;
        if(ar[i][j])
        
            bfs(i,j);
            for(int k=0;k<q;k++)
            
                if(ans[rare[k].x][rare[k].y]==10000)
                
                    flag=1;
                    break;
                
            
            if(!flag)
            
                for(int k=0;k<q;k++)
                
                    mx=max(mx,ans[rare[k].x][rare[k].y]);
                   // cout<<mx<<endl;
                
            
          //  cout<< mx<<fans<<endl;
            fans=min(fans,mx);
        
    


cout<<fans<<endl;

/* input
8
0 0 1 0 0 1 0 0
0 0 1 0 1 1 1 1
0 0 1 0 1 0 0 1
0 0 1 1 1 0 0 0
0 1 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
3
0 2
1 7
4 7
*/

【问题讨论】:

int ans[21][21] 不会创建一个 21*21 的数组,而是创建 21 个 21 长的数组。 Memset not working的可能重复 我的 memset 提供了正确的输出,但对于 lopp 却没有。 @Mgetz 你提交的代码没有输出任何东西。 不要使用memset,不要使用内置数组,避免使用循环。如果std::fill_n 没有产生正确的结果,那么这意味着你做错了什么。这就是为什么你不应该使用memset 或手动循环的原因,因为它们经常隐藏你做错事的事实。更改您的代码以使用std::array 而不是内置数组,然后使用std::fill_n,然后从那里获取它。这将使以自然方式正确实现变得更加容易。 【参考方案1】:

您不需要在 C++ 中使用 memset it is error-prone,正如您刚刚发现的那样。

修复:

bool visited[21][21] = ; // zero-initialize

int ans[21][21]; // uninitialized
std::fill_n(*ans, sizeof ans / sizeof **ans, 10000);

【讨论】:

我明白你的意思。但问题是使用memset 我得到了正确的输出。不是 for 循环或fill_n @Yonex 你不可能得到memset(..., 10000, ...)的正确输出,不。除非你对正确的定义不正确。

以上是关于为数组赋值:memset vs for 循环的主要内容,如果未能解决你的问题,请参考以下文章

C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理

C++中能否用memset将int数组元素设为-1?

数组初始化及赋值的方法,memset的使用

如果想使一个数组中全部元素为0可以怎么写

怎么将字符数组全赋值为空

使用两个for循环给二维数组赋固定值,并输出?