如何解决C中的冲突类型错误



我正在使用堆栈为迷宫中的最短路径编写代码。但我一直在想:错误:"通过"的类型冲突

这是我的代码

#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#define N 6
#define length N * N
typedef struct
{
int x;
int y;
}Point;
typedef struct
{
Point* top;
Point* end;
int Capacity;
}Stack;
//Declaration
void PathPrint();
void Solution(Point beg, Stack* path);
void InitStack(Stack* s);
void Pass(Point now, int* arr);
void Push(Stack* s, Point x);
void Pop(Stack* s);
int IsEmpty(Stack* s);
Stack Path; //the path in maze
Stack* s = &Path;
Point beg;
Point end;
int count = 0;

void PathPrint()
{
int x = 0;
int y = 0;
int i = 0;
Point* temp = s->end;
while(s->top != s->end)
{
i++;
x = s->end->x;
y = s->end->y;
s->end++;
printf("(%d,%d)  ",x,y);
}
s->end = temp;
}
//Function to check whether the path is passable
void Pass(Point now, int arr[N][N])
{
if(end.x == now.x && end.y == now.y)
{
count++;
printf("%d: n", count);
PathPrint();
Point p = Pop(s);
arr[p.x][p.y] = 1;
return;
}
//checking the direction
if(1 == arr[now.x-1][now.y] && now.x - 1 >= 0)
{
Point up;
up.x = now.x-1;
up.y = now.y;
Push(s, up);
arr[now.x - 1][now.y] = -1;
Pass(up, arr);
}
if(1 == arr[now.x + 1][now.y] && now.x + 1 < N)
{
Point down;
down.x = now.x+1;
down.y = now.y;
Push(s, down);
arr[now.x + 1][now.y] = -1;
Pass(down, arr);
}
if(1 == arr[now.x][now.y-1] && now.y - 1 >= 0)
{
Point left;
left.x = now.x;
left.y = now.y - 1;
Push(s, left);
arr[now.x][now.y-1] = -1;
Pass(left, arr);
}
if(1 == arr[now.x][now.y + 1] && now.y + 1 <N)
{
Point right;
right.x = now.x;
right.y = now.y+1;
Push(s, right);
arr[now.x][now.y + 1] = -1;
Pass(right, arr);
}
Point p = Pop(s);
arr[p.x][p.y] = 1;
}

这个错误是什么意思?我该如何纠正它?此外,Pass功能用于检查可访问的方向和路径。另一方面,这不是一个完整的代码,但我认为主要问题在于代码的这一部分。

Pass的原型与定义不匹配。

您已将Pass声明为:

void Pass(Point now, int* arr);

但将其定义为:

void Pass(Point now, int arr[N][N])
{
...

第二个参数的类型不匹配。因此,更改声明以匹配定义:

void Pass(Point now, int arr[N][N]);

数组和指针,尤其是用作函数参数时,有点棘手。在量子力学中,数组衰变为指针的频率比波函数坍塌的频率更高,但这两件事仍然不一样。

查看它的一个简单方法是询问对象的大小。指针的大小与指针的大小无关,而数组的大小与数组中所有对象的大小相同。所以使用

// pointer of NxN integers
int *ip = malloc(N * N * sizeof *ip);
// array of NxN integers
int ia[N][N];
printf("sizeof(ip) == %zu, sizeof(ia) == %zun",
sizeof(ip), sizeof(ia));

例如,您可能会看到指针是8个字节,但如果整数是4个字节(char是1个字节),则数组是6x6x4个字节。

在实践中,数组通常只是指向数据所在位置的指针,但它是一种不同的类型。

这并没有那么复杂,但这是C,所以当然还有更多

如果我们编写像这样的函数

void f(int *ip)
{
printf("f: sizeof(ip) == %zun", sizeof(ip));
}
void g(int *ia); // notice prototype
void g(int ia[N])
{
// you probably get a warning here...
printf("g: sizeof(ia) == %zun", sizeof(ia));
}

您可以合理地假设f中的整数指针和g中的整数数组也是不同的。但事实并非如此。正如上面g定义的原型所暗示的那样,这是因为g中的数组根本不是数组,它是一个指针。数组作为函数参数衰减为指针;数组中的完整数据块不会作为值复制到函数中,您只会得到一个指向数据所在位置的指针。因此,作为函数参数的数组会悄悄地衰减为指针(编译器可能会警告您,当您询问它的大小时,您得到的是指针的大小,而不是数组的大小)。

您可以用指针或数组调用fg,C不会抱怨。这里的指针和数组之间没有任何真正的区别;数组被自动转换为CCD_ 9中的指针。

就C而言,数组参数和指针参数是相同的。

那么,为什么你的代码不起作用呢?如果一个数组成为指针,它应该成为指针。但不是那么快。数组确实变成了一个指针,但它不会变成指向底层类型的指针。您有一个二维数组(或者,实际上是一个数组数组)。它会衰减为指向数组中元素类型的指针,但这些元素是(一维)数组,而不是整数。

我们可以尝试用二维数组编写一个函数,看看会发生什么:

void g(int (*ia)[N]); // notice prototype
void g(int ia[N][N])
{
// you probably get a warning here...
printf("g: sizeof(ia) == %zun", sizeof(ia));
printf("g: sizeof(*ia) == %zun", sizeof(*ia));
}

正如原型所暗示的,ia[N][N]数组参数实际上是一个指针,但它是指向长度为N(类型为int (*)[N])的整数数组的指针。编译器应该警告您ia会衰减为指针,因此sizeof(ia)是指针的大小。然而,ia所指的仍然是长度为N的阵列,而*ia的大小反映了这一点。

这是有道理的。当我们在类似数组的内存上进行指针运算时,步长应该是底层元素的大小。对于整数指针ip,您希望ip[2] == *(ip + 2)ip中的第三个元素。如果元素是整数,则需要第三个整数,而不是第三个位或字节或第三个东西。这意味着ip + i应该是地址ip + i*(sizeof *ip)。如果元素是数组,那么它们应该仍然是ip + i*(sizeof *ip),所以sizeof *ip必须是底层数组的大小。如果这个大小是整数的大小,我们就不能用多维数组进行指针运算或索引。

如果您希望多维数组作为函数参数,则必须将该类型设置为实际数组或指向除第一维数组之外的所有数组的指针(如上面g的原型)。

使用平面数据指针没有错,数据是这样显示的,所以您可以使用纯整数指针。然后,如果你做指针运算,你必须对此进行调整。否则,您只需要确保原型与定义相匹配。

数组和指针很棘手,因为数组经常表现得像指针,所以很容易忘记它们是不同的野兽。你遇到了一个案例,他们的差异并没有被隐藏。这种情况通常发生在多维数组中。我希望这个解释能稍微澄清一下。否则,修复方法很简单:更改原型,使其与定义的类型相匹配。

最新更新