当 M 为奇数且在对角线中间时,对角线互换后显示为零
When M is an odd number and if it is middle of diagonal it shows Zero after diagonal interchange
如果M的值为3,mat[1][1]处的值为5,
然后在将 mat[1][1] 与 mat[1][1] 交换后它应该仍然是 5,
但它显示为 0。
但是当 M 是偶数时,代码运行完美。
#include<iostream>
#define M 3
void swap( int &a, int &b )
{
a=a+b;
b=a-b;
a=a-b;
}
using namespace std;
int main()
{
int mat[M][M];
cout<<"Enter "<<M<<"x"<<M<<" matrix"<<endl;
for( int i=0; i<M; i++ )
for( int j=0; j<M; j++ )
cin>>mat[i][j];
cout<<endl<<"The real matrix"<<endl;
for( int i=0; i<M; i++ )
{
for( int j=0; j<M; j++ )
{
cout<<mat[i][j]<<"\t";
}
cout<<endl;
}
for( int i=0; i<M; i++ )
{
swap( mat[i][i], mat[i][M-i-1] );
}
cout<<endl<<"The matrix after diagonal interchange "<<endl;
for( int i=0; i<M; i++ )
{
for( int j=0; j<M; j++ )
{
cout<<mat[i][j]<<"\t";
}
cout<<endl;
}
return 0;
}
这背后的原因是您在 swap() 函数中通过引用传递值。
假设 M[1][1] = 5.
当您将 M[1][1] 传递给 swap() 时,它们不会 复制到 a 和 b。相反,a 和 b 成为 M[1][1].
的别名
让我们逐步了解发生了什么:
a=a+b; // equivalent to M[1][1] = M[1][1] + M[1][1];
这样操作后,M[1][1]变成10,因为a&b是M[1][1]的别名,所以a和b也变成10。
b=a-b; // equivalent to M[1][1] = M[1][1] - M[1][1];
执行此操作时,M[1][1] 变为 0。因为 a 和 b 是 M[1][1] 的别名,所以 a 和 b 也变为 0。
a=a-b; // equivalent to M[1][1] = M[1][1] - M[1][1];
执行此操作时,M[1][1] 变为 0。因为 a 和 b 是 M[1][1] 的别名,所以 a 和 b 也变为 0。
编辑:
正如@SidS 所建议的,您可以使用库函数std::swap()
。如果您想更正您的代码,只需将您的 swap() 更改为:
void swap( int &a, int &b )
{
int tmp = a;
a = b;
b = tmp;
}
问题是您为 swap()
函数的两个参数传递了相同的值 mat[1][1]
。您的 swap()
函数无法正确处理这种情况,因为对 a
的任何更改也会应用于 b
,反之亦然。
而是使用 std::swap()
:
#include <utility>
...
std::swap(mat[i][i], mat[i][M-i-1]);
或者,如果您坚持自己滚动,请使用临时变量:
void swap(int &a, int &b)
{
auto c = a;
a = b;
b = c;
}
如果M的值为3,mat[1][1]处的值为5, 然后在将 mat[1][1] 与 mat[1][1] 交换后它应该仍然是 5, 但它显示为 0。 但是当 M 是偶数时,代码运行完美。
#include<iostream>
#define M 3
void swap( int &a, int &b )
{
a=a+b;
b=a-b;
a=a-b;
}
using namespace std;
int main()
{
int mat[M][M];
cout<<"Enter "<<M<<"x"<<M<<" matrix"<<endl;
for( int i=0; i<M; i++ )
for( int j=0; j<M; j++ )
cin>>mat[i][j];
cout<<endl<<"The real matrix"<<endl;
for( int i=0; i<M; i++ )
{
for( int j=0; j<M; j++ )
{
cout<<mat[i][j]<<"\t";
}
cout<<endl;
}
for( int i=0; i<M; i++ )
{
swap( mat[i][i], mat[i][M-i-1] );
}
cout<<endl<<"The matrix after diagonal interchange "<<endl;
for( int i=0; i<M; i++ )
{
for( int j=0; j<M; j++ )
{
cout<<mat[i][j]<<"\t";
}
cout<<endl;
}
return 0;
}
这背后的原因是您在 swap() 函数中通过引用传递值。
假设 M[1][1] = 5.
当您将 M[1][1] 传递给 swap() 时,它们不会 复制到 a 和 b。相反,a 和 b 成为 M[1][1].
的别名让我们逐步了解发生了什么:
a=a+b; // equivalent to M[1][1] = M[1][1] + M[1][1];
这样操作后,M[1][1]变成10,因为a&b是M[1][1]的别名,所以a和b也变成10。
b=a-b; // equivalent to M[1][1] = M[1][1] - M[1][1];
执行此操作时,M[1][1] 变为 0。因为 a 和 b 是 M[1][1] 的别名,所以 a 和 b 也变为 0。
a=a-b; // equivalent to M[1][1] = M[1][1] - M[1][1];
执行此操作时,M[1][1] 变为 0。因为 a 和 b 是 M[1][1] 的别名,所以 a 和 b 也变为 0。
编辑:
正如@SidS 所建议的,您可以使用库函数std::swap()
。如果您想更正您的代码,只需将您的 swap() 更改为:
void swap( int &a, int &b )
{
int tmp = a;
a = b;
b = tmp;
}
问题是您为 swap()
函数的两个参数传递了相同的值 mat[1][1]
。您的 swap()
函数无法正确处理这种情况,因为对 a
的任何更改也会应用于 b
,反之亦然。
而是使用 std::swap()
:
#include <utility>
...
std::swap(mat[i][i], mat[i][M-i-1]);
或者,如果您坚持自己滚动,请使用临时变量:
void swap(int &a, int &b)
{
auto c = a;
a = b;
b = c;
}