与以前的定义错误混淆

Confusion with previous definition errors

我正在用 C 语言做一些图形练习,对示例解决方案感到困惑。我在下面附上了我的代码,其中添加了我尚不理解的示例解决方案。

我的问题是为什么在 sp_algo 函数中 struct queueNode adjCell;struct Point new_point; 的多重声明和初始化有效?另一方面,例如,如果我在主函数中声明和初始化 struct Point end = {2, 6}; 两次,它 returns 一个错误:

previous definition of 'end' was here & redefinition of 'end'.

代码不是很重要,但我会简单地解释一下。任务是在数组 A 给出的迷宫中获得从起点到终点的最短路径。为此,我实现了 BFS。在 sp_algo 中还有一个队列的实现,我需要它来实现 BFS。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define GRIDSIZE 7
#define MAXQSIZE 49

struct Point{
    int x;
    int y;
};

struct queueNode
{
    struct Point pt;  // The cordinates of a cell
    int dist;  // cell's distance of from the source
};

bool isValid(int row, int col)
{
    // return true if row number and column number
    // is in range
    return (row >= 0) && (row < GRIDSIZE) &&
           (col >= 0) && (col < GRIDSIZE);
}

struct queueNode queue[MAXQSIZE]; //initialize QUEUE

int front = -1;
int rear = -1;
int size = -1;

bool q_isempty()
{
    return size < 0;
}

void q_enqueue(struct queueNode value)
{
    if(size<MAXQSIZE)
    {
        if(size<0)
        {
            queue[0] = value;
            front = rear = 0;
            size = 1;
        }
        else if(rear == MAXQSIZE-1)
        {
            queue[0] = value;
            rear = 0;
            size++;
        }
        else
        {
            queue[rear+1] = value;
            rear++;
            size++;
        }
    }
    else
    {
        printf("Queue is full\n");
    }
}

int q_dequeue()
{
    if(size<0)
    {
        printf("Queue is empty\n");
    }
    else
    {
        size--;
        front++;
    }
}

struct queueNode q_front()
{
    return queue[front];
}


////FUNCTION WE NEED TO IMPLEMENT...
int sp_algo(int A[GRIDSIZE][GRIDSIZE], struct Point start, struct Point end){
    int visited[GRIDSIZE][GRIDSIZE];
    for (int i=0; i<GRIDSIZE; ++i){
        for(int j=0; j<GRIDSIZE; ++j){
            visited[i][j] = -1;
        }
    }

    //all 4 directions we can go to (up,down,left,right)
    int row_num[] = {-1, 0, 0, 1};
    int col_num[] = {0, -1, 1, 0};
    
    struct queueNode n1;
    struct queueNode tmp;
    n1.dist = 0;
    n1.pt = start;
    q_enqueue(n1);
    
    while(q_isempty() == false){
        tmp = q_front();
        q_dequeue();
        if(tmp.pt.x == end.x && tmp.pt.y == end.y){ //we found it!!!
            return tmp.dist;
        }
        ///else, search the neighbors!
        for(int i=0; i<4; ++i){
            int new_row = tmp.pt.x + row_num[i];
            int new_col = tmp.pt.y + col_num[i];
            if (isValid(new_row, new_col) == true && visited[new_row][new_col] == -1 && A[new_row][new_col] == '.'){
                        struct queueNode adjCell;
                        struct Point new_point;
                        new_point.x = new_row;
                        new_point.y = new_col;
                        adjCell.dist = tmp.dist+1;
                        adjCell.pt = new_point;
                        visited[new_row][new_col] = 1;
                        q_enqueue(adjCell);     
            }
        }
    }
}




int main() {
  int A[7][7] =
    {
        { '.', '.', '#', '.', '.', '#', '#'},
        { '.', '.', '#', '.', '.', '.', '.'},
        { '.', '.', '#', '.', '#', '.', '.'},
        { '.', '.', '#', '.', '#', '.', '#'},
        { '#', '.', '#', '.', '#', '.', '.'},
        { '.', '.', '#', '.', '.', '#', '.'},
        { '#', '.', '.', '.', '.', '.', '.'},
    };
  struct Point start = {0, 0};
  struct Point end = {2, 6};

    int spDist = sp_algo(A, start, end);
    printf("It takes a total of %d steps to reach the destination!\n", spDist);
}

struct queueNode adjCellstruct Point new_point 被初始化两次,但不在同一范围内。

例如

{
int a = 5;
printf("%d\n", a); //The scope of a is limited to the {} braces,
}                  //meaning after the closing brace, a no longer exists

//a doesn't exist here

int a = 2 //This can even be a different data type
printf("%d\n", a);

而且它更喜欢局部变量(范围限于当前代码段的变量)而不是全局变量。例如

int a = 5;
{
    int a = 3;
    printf("%d\n", a); //This prints 3
}

与 if 循环相同,它的行为类似于:

{
    struct Point new_point;
    //Whatever code
}
{
    struct Point new_point;
    //Whatever code
}
{
    struct Point new_point;
    //Whatever code
}
 //On and on for how many loops

注意:我并不是说循环是这样工作的,我是说它的行为是这样的

...无论循环继续多少次都会继续。基本上,在一个循环迭代之后,它进入了一个新的范围,其中以前的变量不存在。

这是允许您在循环内声明变量的原因。

for (int i = 0; i < 5; i++) {
    int a; //Even though this code executed 5 times, this doesn't cause problems.
}

我的大部分解释都在评论中,所以请阅读那些。