我编写了一个可以旋转 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])
老实说,我没有收到这些错误,因为代码似乎工作,我从来没有超出界限,显然我没有做任何内存违规......
最佳答案
警告是因为这些:
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
反而。 (注意:我不确定上述所有隐式转换是否都能保证有效;指向不同类型对象的指针可能并非在所有平台上都可以相互转换。即使在典型的现代平台上,它们都是可相互转换的,你可能会违反严格的别名规则,这意味着您的编译器最终可能会执行完全破坏您的代码的优化。但它通常会起作用。)
关于c - 指针、数组和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40569760/