为什么我的函数无法使用指针打印多维数组的元素?
Why is my function unable to print an element of a multi-dimensional array using pointers?
>我有一个 3 X 3 多维数组,我想使用指针打印第 0 行的所有 3 个元素。
这是我编写的代码:
#include <iostream>
void print(int *p){
for(int i = 0; i < 3; i++){
std::cout << (*p)[i];
}
};
int main(void){
int arr[3][3] = {
{1,2,3} ,
{4,5,6} ,
{7,8,9}
};
print(arr);
}
这将引发以下错误:
主.cpp:5:26:错误:下标值不是数组、指针或向量
std::cout << (*p)[i];
~~~~^~
主.cpp:16:4:错误:调用"打印"没有匹配函数
print(arr);
^~~~~
主.cpp:3:6:注意:候选函数不可行:第一个参数没有从"int [3][3]"到"int *"的已知转换
void print(int *p){
据我了解,arr是指向数组第一个元素的指针,该元素本身就是一个数组。那么为什么我找不到指针arr返回的值的数组[i]?
函数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;
}
数组的第一个元素arr
类型为int[3]
。因为所谓的二维数组在语言方面是一个数组的数组。
因此arr
不能等同于int*
,只能等同于int[][3]
或int(*)[3]
。
void print(int p[][3]){
for(int i = 0; i < 3; i++){
std::cout << p[0][i];
}
};
或
void print(int (*p)[3]){
for(int i = 0; i < 3; i++){
std::cout << (*p)[i];
}
};
将是函数的正确签名。任何将多维数组表示为指针的尝试都需要显式强制转换并将其洗回函数中的正确类型,否则将被视为未定义的行为,即使大多数实现都允许这样做。
在我看来,所有以前的答案都没有解决主要问题。
问题是,如何将一个普通的旧 C 数组传递给函数。
如果你想将一个普通的旧C数组传递给一个函数,你有2种可能性。
- 按引用传递
- 通过指针传递
看来你想通过引用。但是您使用了错误的语法。
请看:
void function1(int(&m)[3][4]) // For passing array by reference
{}
void function2(int(*m)[3][4]) // For passing array by pointer
{}
int main()
{
int matrix[3][4]; // Define 2 dimensional array
function1(matrix); // Call by reference
function2(&matrix); // Call via pointer
return 0;
}
传递给函数的是指向 int 数组的衰减指针。
只需更正语法即可。
附加提示:
不要在C++中使用纯 C 样式数组。从不。请使用 STL 容器。
- 数组元素打印的递归方法
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 为什么使用数组元素查找最大数字的程序不起作用?
- 数组元素更改值?
- 如何访问宏中定义的数组元素
- 将数组元素递增 1
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- 存储指向动态数组元素的指针
- C++通过别名指针以静默方式将错误的类型分配给数组元素
- 在 std::map 中插入数组元素
- 使用指针访问数组元素时出现意外结果
- c++ 使用动态分配运算符反向数组元素
- 为什么在 c++ 中分配 char 数组元素时,分配的字符会被销毁?
- 缺少数组元素问题
- 如何在类中制作 2D 数组元素,然后在其构造函数中指定其维度?
- 创建一个函数来转换数组元素的类型并返回数组的地址
- 删除在结构 c++ 中声明的数组元素
- Getter 和 Setter 用于类 C++ 中的数组元素
- 尝试递归获取数组元素的总和
- 使用SWIG将numpy数组元素(int)传递给c++int