为什么交换没有完成?
Why is not swap done?
未交换
void f(struct a s)
{
int t;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
if (s.b[j] > s.b[j + 1]) {
s.c = s.b[j];
s.b[j] = s.b[j + 1];
s.b[j + 1] = s.c;
}
}
}
输出应该是排列好的,但是和输入的完全一样
void f(struct a s)
s
按值传递,即复制其内容。您需要通过引用或地址传递来修改调用者的原始结构。
void f(struct a& s)
或
void f(struct a* s)
...
f(&s);
对于初学者来说,如果数组 s.b
恰好有 10
个元素,函数似乎有未定义的行为,因为至少在这个语句中
if (s.b[j] > s.b[j + 1]) {
^^^^^^
当j = 9
(数组中没有索引为10
的元素)
时,试图访问数组之外的内存
至少按以下方式声明内循环
for (int j = 1; j < 10; j++) {
if (s.b[j - 1] > s.b[j]) {
s.c = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = s.c;
}
也不清楚为什么在结构中声明实际上用作临时对象的数据成员s.c
。它应该从结构定义中删除,并且在循环中应该使用一些局部变量来代替。例如
if (s.b[j - 1] > s.b[j]) {
auto tmp = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = tmp;
}
并且您按值传递了对象。所以函数处理原始对象的副本。
注意有标准的 c++ 函数 std::swap
可以做同样的事情。
例如
std::swap( s.b[j], s.b[j - 1] );
顺便说一句,函数中没有使用变量 t
。
将参数声明为具有引用类型。
void f(struct a &s);
或者通过指向结构的指针
void f(struct a *s);
在这种情况下,要访问结构的数据成员,您应该编写例如
s->b[j - 1]
使用像 10
这样的幻数也是个坏主意。您可以在结构中声明一个静态数据成员,例如
static const int N = 10;
并在循环中使用变量 N
。
例如
void f(struct a &s)
{
for (int i = 0; i < a::N; i++)
for (int j = 1; j < a::N; j++) {
if (s.b[j - 1] > s.b[j]) {
auto tmp = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = tmp;
}
}
}
未交换
void f(struct a s)
{
int t;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
if (s.b[j] > s.b[j + 1]) {
s.c = s.b[j];
s.b[j] = s.b[j + 1];
s.b[j + 1] = s.c;
}
}
}
输出应该是排列好的,但是和输入的完全一样
void f(struct a s)
s
按值传递,即复制其内容。您需要通过引用或地址传递来修改调用者的原始结构。
void f(struct a& s)
或
void f(struct a* s)
...
f(&s);
对于初学者来说,如果数组 s.b
恰好有 10
个元素,函数似乎有未定义的行为,因为至少在这个语句中
if (s.b[j] > s.b[j + 1]) {
^^^^^^
当j = 9
(数组中没有索引为10
的元素)
至少按以下方式声明内循环
for (int j = 1; j < 10; j++) {
if (s.b[j - 1] > s.b[j]) {
s.c = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = s.c;
}
也不清楚为什么在结构中声明实际上用作临时对象的数据成员s.c
。它应该从结构定义中删除,并且在循环中应该使用一些局部变量来代替。例如
if (s.b[j - 1] > s.b[j]) {
auto tmp = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = tmp;
}
并且您按值传递了对象。所以函数处理原始对象的副本。
注意有标准的 c++ 函数 std::swap
可以做同样的事情。
例如
std::swap( s.b[j], s.b[j - 1] );
顺便说一句,函数中没有使用变量 t
。
将参数声明为具有引用类型。
void f(struct a &s);
或者通过指向结构的指针
void f(struct a *s);
在这种情况下,要访问结构的数据成员,您应该编写例如
s->b[j - 1]
使用像 10
这样的幻数也是个坏主意。您可以在结构中声明一个静态数据成员,例如
static const int N = 10;
并在循环中使用变量 N
。
例如
void f(struct a &s)
{
for (int i = 0; i < a::N; i++)
for (int j = 1; j < a::N; j++) {
if (s.b[j - 1] > s.b[j]) {
auto tmp = s.b[j];
s.b[j] = s.b[j - 1];
s.b[j - 1] = tmp;
}
}
}