c++ - 为什么交换没有完成?

标签 c++ struct reference pass-by-reference swap

<分区>

不交换

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;
            }
        }
}

关于c++ - 为什么交换没有完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57149449/

相关文章:

c++ - 悬空引用和未定义行为

c++ - 如何根据引用进行 regex_replace

c# - AutoMapper,如何保持映射对象之间的引用?

c++ - 在子字符串后插入字符串

c++ - 处理 WinAPI CreateFile 中的泄漏?

c++ - _beginthreadex 的参数类型错误

c - 总线错误 : 10 in C dealing with struct pointers

c++ - 传递用于结构定义的参数

c++ - GMP 库,C++、MinGW、Code::Blocks 中的编译错误

c - 结构声明之后的数组定义