我编写了一个可以旋转4 x 4阵列的功能,现在我想输出它...但是我得到一堆警告,但它编译并且有效,所以我想我只做了一些"次要/正式"错误。
#include <stdio.h>
//-----------------------------------------------------------------------------
///
/// This function prints four 4x4 matrix
///
/// @param m1, m2, m3, m4 input matrix you want to print.
///
/// @return 0
//-----------------------------------------------------------------------------
void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4])
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
printf("%c ", m1[i][j]);
}
printf(" ");
for(int j = 0; j < 4; j++)
{
printf("%c ", m2[i][j]);
}
printf(" ");
for(int j = 0; j < 4; j++)
{
printf("%c ", m3[i][j]);
}
printf(" ");
for(int j = 0; j < 4; j++)
{
printf("%c ", m4[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
//-----------------------------------------------------------------------------
///
/// This function rotates a 4x4 matrix
/// (and collects tears from overworked students @2am, because wtf is )
///
/// @param m, the matrix you want to rotate
///
/// @return m_r the rotated matrix
//-----------------------------------------------------------------------------
char *rotate_matrix(char m[4][4])
{
static char m_r[4][4];
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
m_r[i][j] = m[3-j][i];
}
}
return *m_r;
}
int main(void)
{
char matrix_t [4][4] = {{ '-', '-', '-', '-' },
{ '-', 'O', '-', '-' },
{ 'O', 'O', 'O', '-' },
{ '-', '-', '-', '-' }
};
char matrix_z [4][4] = {{ '-', '-', '-', '-' },
{ '-', 'O', 'O', '-' },
{ 'O', 'O', '-', '-' },
{ '-', '-', '-', '-' }
};
char matrix_l [4][4] = {{ '-', '-', '-', '-' },
{ '-', 'O', '-', '-' },
{ '-', 'O', '-', '-' },
{ '-', 'O', 'O', '-' }
};
char matrix_i [4][4] = {{ '-', '-', 'O', '-' },
{ '-', '-', 'O', '-' },
{ '-', '-', 'O', '-' },
{ '-', '-', 'O', '-' }
};
char (*array)[4][4];
print_matrix(matrix_t, matrix_z, matrix_l, matrix_i);
array = rotate_matrix(matrix_t);
print_matrix(array, matrix_z, matrix_l, matrix_i);
return 0;
}
这是我得到的错误:
102:9: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
array = rotate_matrix(matrix_t);
,
103:16: warning: passing argument 1 of ‘print_matrix’ from incompatible pointer type [-Wincompatible-pointer-types]
print_matrix(array, matrix_z, matrix_l, matrix_i);
和
note: expected ‘char (*)[4]’ but argument is of type ‘char (*)[4][4]’
void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4])
说实话,我没有得到这些错误,因为代码似乎有效,我从未超出界限,显然我没有做任何内存违规...... < / p>
答案 0 :(得分:1)
警告是因为:
char * // pointer to char or to first element of char[]
char (*)[4] // pointer to char[4] or to first element of char[][4]
char (*)[4][4] // pointer to char[4][4] or to first element of char[][4][4]
是不同的类型。指针不仅仅表示内存位置,而且(通过其类型)应该如何解释内存位置。
一个棘手的问题是数组名称(或任何其他评估为数组的表达式)衰减指针。例如,这是完全有效的:
char abc[4] = "abc"; // abc is an array of four characters
char a = *abc; // a is 'a', the first character of abc
。 。 。相反,你可以在指针上使用数组表示法(执行指针运算并立即取消引用结果):
char * abc = "abc"; // abc is a pointer (into static memory)
char c = abc[2]; // c is 'c', the third character of abc
因此char *
与char ()[]
可互换,char (*)[4]
可与char ()[][4]
互换,char (*)[4][4]
可与char ()[][4][4]
互换。
使额外棘手的原因是C并不完全支持将数组作为函数参数传递(尽管如果你真的想要它,你可以通过包装它来实现相同的效果结构中的数组并传递它)。它确实允许您将函数参数声明为具有数组类型,但这实际上是具有指针类型的函数参数的语法糖。所以这三个签名是等价的:
void *print_matrix(char m1[4][4], char m2[4][4], char m3[4][4], char m4[4][4])
void *print_matrix(char m1[][4], char m2[][4], char m3[][4], char m4[][4])
void *print_matrix(char (*m1)[4], char (*m2)[4], char (*m3)[4], char (*m4)[4])
您的代码有效,因为您的各种警告都会被取消:
rotate_matrix
应该返回char (*)[4]
(指向char[][4]
的第一行的指针)或char (*)[4][4]
(指向一个完整的char[4][4]
)。相反,你让它返回char *
,为了实现这一点,你取消引用所需的指针,从而获得(在数组到指针衰减之后)指向矩阵第一行的第一个元素的指针。当然,所有这些指针都指向相同的内存位置,只是使用不同的类型。
char (*)[4]
声明它,您可以编写char (*rotate_matrix(char m[4][4]))[4]
。 。 。但最好是声明row
类型typedef char row[4]
,然后再写row * rotate_matrix(char m[4][4])
。在这种情况下,您将在结尾返回m_r
,它会衰减到指向m_r
第一行的指针。char (*)[4][4]
声明它,同样的事情,只需要额外的[4]
&#(和matrix
而不是row
这样的名称) 。在这种情况下,您最后会返回&m_r
,这意味着指向整个m_r
的指针。char (*)[4][4]
的版本。array
的类型为char (*)[4][4]
,很好。 array = rotate_matrix(matrix_t)
中的代码警告是由于rotate_matrix
的错误声明。但是返回指针的实际值已经很好了,至少在典型的平台上是这样。
array
,那么您应该将其称为array_ptr
,因为它是指针你通常的阵列类型。array
作为参数传递给print_matrix
,它带有char [4][4]
类型的参数,意思是char (*)[4]
。您无法将char (*)[4][4]
(指向4行4个字符的数组的指针)转换为char (*)[4]
(指向4个字符数组的指针)。要解决此问题,您只需要通过传递array
取消引用*array
。(注意:我不确定所有上述隐式转换实际上都是保证可以工作;指向不同类型对象的指针可能并非在所有平台上都是可互换的。甚至在典型的现代平台上,它们 都是可互换的,你可能会遇到严格的别名规则,这意味着你的编译器可能最终会执行完全破坏你的代码的优化。但它通常 工作。)