如何解决 C 中的冲突类型错误?
Posted
技术标签:
【中文标题】如何解决 C 中的冲突类型错误?【英文标题】:How to solve conflicting type error in C? 【发布时间】:2021-12-21 11:52:57 【问题描述】:我正在使用堆栈为迷宫中的最短路径编写代码。但我不断得到这个: 错误:“通过”的类型冲突
这是我的代码
#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' 的类型冲突int arr[N][N]
!= int *arr
【参考方案1】:
Pass
的原型与定义不匹配。
您已将Pass
声明为:
void Pass(Point now, int* arr);
但定义为:
void Pass(Point now, int arr[N][N])
...
第二个参数的类型不匹配。所以更改声明以匹配定义:
void Pass(Point now, int arr[N][N]);
【讨论】:
【参考方案2】:数组和指针,尤其是用作函数参数时,有点棘手。在量子力学中,数组衰减到指针的频率比波函数崩溃的频率要高,但这两者仍然不一样。
查看它的一种简单方法是询问对象的大小。指针具有指针的大小,无论它指向什么大小,而数组具有数组中所有对象的大小。所以与
// 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) == %zu\n",
sizeof(ip), sizeof(ia));
你可能会看到指针是 8 个字节,但如果整数是 4 个字节(而 char 是 1 个字节),则数组是 6x6x4 字节。
在实践中,数组通常只是指向数据所在位置的指针,但它是不同的类型。
这并不复杂,但这是 C,所以当然还有更多。
如果我们编写这样的函数
void f(int *ip)
printf("f: sizeof(ip) == %zu\n", sizeof(ip));
void g(int *ia); // notice prototype
void g(int ia[N])
// you probably get a warning here...
printf("g: sizeof(ia) == %zu\n", sizeof(ia));
您可以合理地假设f
中的整数指针和g
中的整数数组也是不同的。但他们不是。而正如g
定义上面的原型所暗示的那样,这是因为g
中的数组根本不是数组,它是一个指针。数组作为函数参数衰减为指针;数组中的完整数据块不会作为值复制到函数中,您只会获得指向数据所在位置的指针。因此,作为函数参数的数组会默默地衰减为指针(并且您的编译器可能会警告您,当您询问它的大小时,您得到的是指针的大小而不是数组的大小)。
您可以使用指针或数组调用f
或g
,C 不会抱怨。这里的指针和数组之间没有任何真正的区别。数组会自动转换为g
中的指针。
就 C 而言,数组参数和指针参数是相同的。
那为什么你的代码不起作用呢?如果一个数组变成一个指针,它应该。但没那么快。数组确实变成了一个指针,但它没有变成指向底层类型的指针。您有一个二维数组(或者,实际上是一个数组数组)。这会衰减为指向数组内元素类型的指针,但这些元素是(一维)数组,而不是整数。
我们可以尝试用二维数组编写一个函数,看看会发生什么:
void g(int (*ia)[N]); // notice prototype
void g(int ia[N][N])
// you probably get a warning here...
printf("g: sizeof(ia) == %zu\n", sizeof(ia));
printf("g: sizeof(*ia) == %zu\n", 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
的原型)。
使用平面数据指针没有任何问题,数据是这样播放的,所以你可以使用普通整数指针。然后,如果您进行指针运算,则必须对此进行调整。否则,您只需确保原型与定义匹配即可。
数组和指针很棘手,因为数组经常表现得像指针,以至于很容易忘记它们是不同的野兽。您遇到了一个案例,他们的差异没有被隐藏。它通常发生在多维数组中。我希望这个解释能澄清一点。否则,解决方法很简单:更改原型,使其与定义的类型相匹配。
【讨论】:
以上是关于如何解决 C 中的冲突类型错误?的主要内容,如果未能解决你的问题,请参考以下文章