函数print的参数类型为int *。
print(int *p)
因此,取消引用表达式(*p)[i] 中的指针,您将获得int 类型的标量对象。您不能将下标运算符应用于int 类型的标量对象。
另一方面,在这个电话中
print(arr);
类型为int[3][3] 的参数被转换为指向其第一个元素的指针。数组元素的类型为int[3]。所以数组隐式转换为指向其第一个元素的指针后的表达式类型为int ( * )[3]。
而且错误信息指向了这个问题
Main.cpp:16:4: error: no matching function for call to 'print'
print(arr);
^~~~~
因为编译器无法找到名称为 print 且接受 int ( * )[3] 类型参数的函数。
因此函数print的参数应该声明为
print( int p[][3] )
或
print( int ( *p )[3] )
由于数组在函数中没有改变,它应该用限定符const声明。
这种情况下的函数定义看起来像(如果你想使用指针)
void print( const int p[][3] )
{
for( const int ( *row )[3] = p; row != p + 3; ++row )
{
for ( const int *col = *row; col != *row + 3; ++col )
{
std::cout << *col << ' ';
}
std::cout << '\n';
}
}
这是一个演示程序。
#include <iostream>
void print( const int p[][3] )
{
for( const int ( *row )[3] = p; row != p + 3; ++row )
{
for ( const int *col = *row; col != *row + 3; ++col )
{
std::cout << *col << ' ';
}
std::cout << '\n';
}
}
int main()
{
const size_t N = 3;
int arr[N][N] =
{
{ 1, 2, 3 } ,
{ 4, 5, 6 } ,
{ 7, 8, 9 }
};
print( arr );
return 0;
}
它的输出是
1 2 3
4 5 6
7 8 9
但是,这种方法有一个严重的缺点。该函数使用幻数3。
最好重写函数至少像
#include <iostream>
const size_t N = 3;
void print( const int p[][N], size_t rows )
{
for( const int ( *row )[N] = p; row != p + rows; ++row )
{
for ( const int *col = *row; col != *row + N; ++col )
{
std::cout << *col << ' ';
}
std::cout << '\n';
}
}
int main()
{
int arr[][N] =
{
{ 1, 2, 3 } ,
{ 4, 5, 6 } ,
{ 7, 8, 9 }
};
print( arr, sizeof( arr ) / sizeof( *arr ) );
return 0;
}
您还可以添加一个带有默认参数的参数。例如
std::ostream & print( const int p[][N], size_t rows, std::ostream &os = std::cout )
{
for( const int ( *row )[N] = p; row != p + rows; ++row )
{
for ( const int *col = *row; col != *row + N; ++col )
{
os << *col << ' ';
}
os << '\n';
}
return os;
}
例如
#include <iostream>
const size_t N = 3;
std::ostream & print( const int p[][N], size_t rows, std::ostream &os = std::cout )
{
for( const int ( *row )[N] = p; row != p + rows; ++row )
{
for ( const int *col = *row; col != *row + N; ++col )
{
os << *col << ' ';
}
os << '\n';
}
return os;
}
int main()
{
int arr[][N] =
{
{ 1, 2, 3 } ,
{ 4, 5, 6 } ,
{ 7, 8, 9 }
};
print( arr, sizeof( arr ) / sizeof( *arr ) ) << '\n';
return 0;
}
最后你可以写一个模板函数了。
#include <iostream>
template <typename T, size_t N>
std::ostream & print( const T ( &p )[N][N], std::ostream &os = std::cout )
{
for( const int ( *row )[N] = p; row != p + N; ++row )
{
for ( const int *col = *row; col != *row + N; ++col )
{
os << *col << ' ';
}
os << '\n';
}
return os;
}
int main()
{
const size_t N = 3;
int arr[][N] =
{
{ 1, 2, 3 } ,
{ 4, 5, 6 } ,
{ 7, 8, 9 }
};
print( arr ) << '\n';
return 0;
}