C忽略"if"指令

Yxu*_*uer 1 c

我最近做的一个程序有问题.基本上,这是John Conway的生活游戏的简单版本,但它不能正常工作.问题出在代码中,它读取单元格及其邻居的状态并决定该单元格的未来状态.这是代码的一部分(它有点长):

#include<stdio.h>
#include<conio.h>

//Game grid size
#define SIZE 15

//Cell state (wall is a special state. It protects the other cells from garbage data of the heap memory)
enum cellState {dead,alive,wall};

//Function prototypes
int** load(int**);
void process(int**);

int main(){

    //Game grid (2-D matrix) and its memory allocation
    int** grid;

    grid=(int**)calloc(SIZE+2,sizeof(int*));
    for(int cont=0;cont<SIZE+2;cont++){
        *(grid+cont)=(int*)calloc(SIZE+2,sizeof(int));
    }

    load(grid);
    getch();
    process(grid);
    getch();
}

//Grid loading function
int** load(int** grid){

    int type;
    srand(12345);
    for(int cont=0;cont<SIZE+2;cont++){
        for(int cont2=0;cont2<SIZE+2;cont2++){
            if(cont==0||cont==TAMANO+1||cont2==0||cont2==TAMANO+1){
                *(*(grid+cont)+cont2)=wall;
            }
            else{
                //Cell type decision
                type=(int)((rand()*2+1)/32767);
                if(type==dead){
                    *(*(grid+cont)+cont2)=dead;
                }
                else if(type==alive){
                    *(*(grid+cont)+cont2)=alive;
                }
            }
        }
    }
    //Grid impression
    for(int cont=0;cont<SIZE+2;cont++){
        for(int cont2=0;cont2<SIZE+2;cont2++){
            if(*(*(grid+cont)+cont2)==wall){
                printf("W ");
            }
            else if(*(*(grid+cont)+cont2)==dead){
                printf(". ");
            }
            else if(*(*(grid+cont)+cont2)==alive){
                printf("C ");
            }
        }
        printf("\n");
    }
    return(grid);
}


void process(int** grid){

    //Temporary grid that saves the next state of a cell
    int** gridTemp;
    //Generations (turns) counter and live neighbours counter
    int generations=0,liveNeighbours=0;
    gridTemp=(int**)calloc(SIZE+2,sizeof(int*));
    for(int cont=0;cont<SIZE+2;cont++){
        *(gridTemp+cont)=(int*)calloc(SIZE+2,sizeof(int));
    }

    for(int cont=0;cont<SIZE+2;cont++){
        for(int cont2=0;cont2<SIZE+2;cont2++){
            if(cont==0||cont==SIZE+1||cont2==0||cont2==SIZE+1){
                *(*(gridTemp+cont)+cont2)=wall;
            }
        }
    }

    //Processing loop
    while(generations<100){

        system("cls");

        for(int cont=1;cont<SIZE+1;cont++){
            for(int cont2=1;cont2<SIZE+1;cont2++){
                for(int comp1=-1;comp1<2;comp1++){
                    for(int comp2=-1;comp2<2;comp2++){
                        if(comp1==0&&comp2==0) continue;
                        else{
                            //Here, we read the state of the neighbour cells of a certain cell
                            if(*(*(grid+cont)+cont2)==dead){
                                if(*(*(grid+cont+comp1)+cont2+comp2)==alive){
                                    liveNeighbours+=1;
                                }
                            }
                            else if(*(*(grid+cont)+cont2)==alive){
                                if(*(*(grid+cont+comp1)+cont2+comp2)==alive){
                                    liveNeighbours+=1;
                                }
                            }
                        }
                    }
                }
                //Future state calculation. Here is where the code fails. This if compares the state of a certain cell and the "dead" enumeration
                if(*(*(grid+cont)+cont2)==dead){
                    if(liveNeighbours==3){
                        *(*(gridTemp+cont)+cont2)==alive;
                    }
                    else{
                        *(*(gridTemp+cont)+cont2)==dead;
                    }
                }
                if(*(*(grid+cont)+cont2)==alive){
                    //It also fails here. This if checks the value of the liveNeighbours variable
                    if(liveNeighbours>=2&&liveNeighbours<=3){
                        *(*(gridTemp+cont)+cont2)==alive;
                    }
                    //And here too
                    if(liveNeighbours<2||liveNeighbours>3){
                        *(*(gridTemp+cont)+cont2)==dead;
                    }
                }
                liveNeighbours=0;
            }
        }
        //Here, the program copies the temporary grid onto the normal grid
        for(int cont=0;cont<SIZE+2;cont++){
            for(int cont2=0;cont2<SIZE+2;cont2++){
                *(*(grid+cont)+cont2)=*(*(gridTemp+cont)+cont2);
                if(*(*(grid+cont)+cont2)==wall){
                    printf("W ");
                }
                else if(*(*(grid+cont)+cont2)==dead){
                    printf(". ");
                }
                else if(*(*(grid+cont)+cont2)==alive){
                    printf("A ");
                }
            }
            printf("\n");
        }
        generations++;
        getch();
    }
    return;
}
Run Code Online (Sandbox Code Playgroud)

使用Dev-C++调试工具,我能够看到代码在我标记的点处失败.简单地说,即使符合条件,它也会忽略那些"if"指令中的代码.

我也重建了这个代码几次并在另一个编译器中尝试过它,它也失败了.Turbo-C++说坏的if代码中的代码没有效果.

Flo*_*ris 6

在代码段中:

                  if(liveNeighbours==3){
                                     *(*(gridTemp+cont)+cont2)==alive;
                                     }
                             else{
                                     *(*(gridTemp+cont)+cont2)==dead;
                                     }
Run Code Online (Sandbox Code Playgroud)

您没有为单元格指定值"alive"或"dead" - 您正在检查它是否相等(因为==比较).我很确定这不是你打算做的吗?

同样的事情发生在"if语句失败"的另一个地方:

             if(liveNeighbours>=2&&liveNeighbours<=3){
                                     *(*(gridTemp+cont)+cont2)==alive;
                                     }
                             //And here too
                             if(liveNeighbours<2||liveNeighbours>3){
                                     *(*(gridTemp+cont)+cont2)==dead;
                                     }
Run Code Online (Sandbox Code Playgroud)

我认为用这四个==标志取代=会有所帮助.

  • @Yxuer他们*对于这样的事情更聪明.例如,我的标记上面的所有四行都有警告,因为"代码没有效果"和"布尔评估结果被丢弃".启用编译器警告,并注意*. (4认同)
  • 实际上,@ Yxuer,他们这样做.例如,如果您使用`gcc`和`-Wall -pedantic -ansi`之类的东西,或者您可以使用[夹板](http://www.splint.org/)或其他适当的C静态分析器进行拍摄.... (3认同)
  • @Yxuer根据你原来的问题,Turbo-C++已经告诉你了. (2认同)