需要编写一个强制转换操作符

时间:2014-02-21 18:49:45

标签: c gcc

该函数需要一个指向二维数组[4][5]的指针。实际上,我们可以改为提交指向一维数组[20]的指针。即源代码如下:

extern f (int a[4][5]);
int b[20];
void func (void)
{
  f (b);
}

即它是完美的工作代码(假设数组b的内部,我们将按照它们在二维数组中的布局)。但是,编译将发出警告(由于类型不合适):<​​/ p>

$ gcc t.c -c
t.c: In function 'func':
t.c:7: warning: passing argument 1 of 'f' from incompatible pointer type

需要编写一个强制转换操作符警告已经消失

3 个答案:

答案 0 :(得分:1)

您的函数期望一个指向1D数组的类型指针的参数,即int (*)[5]。原型类似于

extern f (int (*a)[5]);

答案 1 :(得分:1)

你的功能论证被视为

int (*)[5];//as in function argument arrays are treated as pointer

但是当你传递b时,因为它是int [20]类型,它被隐式地视为

int *

那么如何在没有编译器的愤怒的情况下用int *分配int(*)[5]!甚至你可以在其他编译器上遇到错误

答案 2 :(得分:1)

extern f (int a[4][5]);

在编译时使用数组类型定义的参数是调整,因此它实际上是指针类型,特别是指向数组元素类型的指针。在这种情况下,int a[4][5]是一个包含4个元素的数组,每个元素都是5 int个元素的数组。调整后,实际类型是指向5 int数组的指针,因此上述内容完全等同于:

extern f(int (*a)[5]);

请注意,4会被忽略。 (说得客气一点,这不是我最喜欢的C语言功能。)

现在声明一个20 int s的数组:

int b[20];

并尝试将其传递给f

void func (void)
{
  f (b);
}

由于b是数组类型的表达式,因此它(在大多数但不是所有上下文中)被隐式转换为指向数组的第一个元素的指针。 (例外情况是数组表达式是sizeof,一元&的操作数,或者当它是用于初始化数组的字符串文字时,这些都不适用于此处。所以这个电话:

f(b);

相当于:

f(&b[0]);

参数类型为int*,与预期类型int(*)[5]不兼容。

如果f的参数类型是固定的,那么你需要传递一个指向数组的指针。例如,您可以更改b的定义,使其与f期望的内容兼容。

以下是我的写作方式:

extern f (int (*a)[5]);

int b[4][5];

void func (void)
{
    f(b);
}

我已更改f的声明,因此它更清楚地表明参数的实际类型,并且我已将b重新定义为二维数组。 b仍然包含20个int元素,但它们的类型不同。

请记住,这里有两个不同的数组/指针语言规则。一个是数组类型的参数是调整(在编译时),因此它确实是指针类型。另一个是在大多数但不是所有上下文中,数组类型的表达式被隐式地转换到指向数组的第一个元素的指针。

这两个规则共同使新C程序员混淆数组和指针之间的关系。

另见comp.lang.c FAQ的第6部分。