不交换
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;
}
}
}
输出应该是经过排列的,但是和输入完全一样
对于初学者来说,如果数组 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
这样的魔数(Magic Number)也不是个好主意。您可以在结构中声明一个静态数据成员,例如
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;
}
}
}