编程训练[C语言]——从数水洼[DFS,POJ No.2386]察觉二维数组做函数参数和漏写getchar()两个问题

【题目描述和样例】

4 4
.ww.
....
w..w
.ww.
2
5 5
w.w.w
.w.w.
.....
w..ww
...w.
3
0 0
Program ended with exit code: 0

解释一下:比如上面第1行是输入空地的大小,2~5行输入空地的状态,w代表有水,.代表没水。然后第6行输出水洼个数(斜线相邻算一个水洼),然后等待用户输入下一组数据。多组输入输出,空地大小为 0 × 0 0\times0 时退出。

【错误分析和示例代码】
博主首先在自定义函数func上出了错,错因是二维数组作为函数参数的写法问题,注意以下两种问题:

⚠️(1)二维数组名不是指针的指针

设有二维数组int a[10][10]二维数组名a存储的是第0行地址,a+1是第1行地址……a的类型是int (*)[10],意思是指向含10个int类型元素的一维数组或行的指针,所以以下两种方式都是错误的:

void func(char **a,int i,int j,int n,int m)

这会导致错误:Thread 1: EXC_BAD_ACCESS (code=1, address=0x2e80e30a)

void func(char a[][],int i,int j,int n,int m)

这会导致错误:Array has incomplete element type 'char []'

由于程序中a的大小是MAX_N*MAX_M的,所以正确的写法是

void func(char a[MAX_N][MAX_M],int i,int j,int n,int m)

或者

void func(char a[][MAX_M],int i,int j,int n,int m)

或者

void func(char (*a)[MAX_M],int i,int j,int n,int m)

⚠️(2)适当使用getchar()吸收回车
在使用scanf等方式输入字符前,要检查此时是否有’\n’残留在缓冲区未被吸收,如有,需要使用getchar()将其吸收,然后再进行字符的输入。

下面是完整代码,改动痕迹和错误记录均以注释体现:

#include<stdio.h>

#define MAX_N 102
#define MAX_M 102

//void func(char **a,int i,int j,int n,int m){  //Thread 1: EXC_BAD_ACCESS (code=1, address=0x2e80e30a)
//void func(char a[][],int i,int j,int n,int m){    //Array has incomplete element type 'char []'
void func(char a[][MAX_M],int i,int j,int n,int m){
    int new_i,new_j;
    a[i][j]='.';
    for(int dx=-1;dx<=1;dx++){
        for(int dy=-1;dy<=1;dy++){
            new_i=i+dy;
            new_j=j+dx;
            if(new_i<n&&new_i>=0&&new_j<m&&new_j>=0&&a[new_i][new_j]=='w')
                func(a,new_i,new_j,n,m);
        }
    }
}

int main(){
    char a[MAX_N][MAX_M];
    int n,m;
    int total=0;
    while(scanf("%d %d",&n,&m)==2){
        getchar();      //极容易疏忽,如果不加这句,下面的字符输入部分会先吸收上一个scanf结束时的回车
        if(n==0&&m==0)break;
        else{
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    scanf("%c",*(a+i)+j);
                }
                getchar();      //极容易疏忽,如果不加这句,下面的字符输入部分会先吸收上一个scanf结束时的回车
            }
            
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(a[i][j]=='w'){       //不小心漏写了if,造成的后果是程序将每一个点都当作水洼处理
                        total++;
                        func(a,i,j,n,m);
                    }
                }
            }
            
            printf("%d\n",total);
        }
        total=0;
    }
    return 0;
}

发布了36 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/umbrellalalalala/article/details/87971984
今日推荐