2014-02-21 23 views
0

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

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

也就是说,它是完美的工作代码(前提是阵列b的内部,我们将这样他们会在一个二维阵列布局)。然而,编译就会发出警告(由于类型不足):

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

需要写一个转换运算符来警告不见了

+1

当参数的类型为int(*)[5]'时,'b'的类型是'int *'。这有点糟糕。更改原型或传递正确的参数。 – Mahesh

回答

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

与数组类型定义的参数是在编译时调整所以真的指针类型,具体的指针数组的元素类型面对错误。在这种情况下,int a[4][5]是一个由4个元素组成的数组,每个元素都是一个由5个元素组成的数组。调整后,实际类型是指针的5 int阵列,所以上述是完全等效于:

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

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

现在你申报的20 int秒的数组:

int b[20]; 

,并尝试将其传递到f

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

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

f(&b[0]); 

的说法是int*类型,这是不符合预期的类型int(*)[5]兼容的:所以这个调用:以

f(b); 

等同。

如果f的参数类型是固定的,那么您需要将它传递给一个数组的指针。例如,您可能会更改b的定义,以便与f预期相符。

以下是我可能会写它:

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

int b[4][5]; 

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

我已经改变了的f的声明,以便更清楚地表明实际的参数类型,我已经重新定义b为2维数组。 b仍然包含20 int元素,但它是不同类型的。

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

这两个规则一起工作,混淆新的C程序员关于数组和指针之间的关系。

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

1

你的函数需要指针类型的参数为一维数组,即int (*)[5]。原型是类似

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

你的函数参数被视为

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

但是,当你通过B中它的类型为int [20]这是隐含视为

int * 

因此,如何在不带编译器的愤怒的情况下将int(*)[5]赋给int *!甚至你可以在其他的编译器

+0

“隐式转换”一词具有误导性。参数的类型在编译时被调整为指针类型。这是一个与数组表达式隐式转换为(“衰减”)指针的规则不同的规则。 –

+0

规则也是该数组和指针可以在函数参数中使用可交换所以和函数参数中的数组和指针被视为相同,只有基地址得到通过 – YakRangi

+0

正如我所说,有两个不同的规则。一个是用数组类型定义的参数被调整为指针类型。另一个是数组表达式被隐式转换为指向它的第一个元素的指针,除非它是'sizeof'或'&'的操作数,或者是一个用于初始化数组对象的字符串。后者的规则并不特定于函数参数。语言*可能已经有了另一种规则。推荐阅读:[comp.lang.c常见问题](http://www.c-faq.com/)的第6部分。 –

相关问题