C++ 在C中对子数组进行排序会对整个数组进行排序吗?

C++ 在C中对子数组进行排序会对整个数组进行排序吗?,c++,c,arrays,sorting,C++,C,Arrays,Sorting,所以在我写的这个小游戏中,我有一副n_C卡,每个卡都有一个唯一的整数值。 有n_P玩家每人手里都拿着n_H牌 甲板和双手共享一个阵列,如下所示: 玩家i_P的手牌包含从牌组[i_P*n_H到牌组[i_P*(n_H+1)-1]的所有牌。所有玩家的牌数总和始终少于n_C 现在我想对每个玩家的手牌进行排序,但不是对整个牌组进行排序(显然,这会在玩家的手牌之间移动一些牌) void sort_hands(char * deck, size_t n_P) { for (size_t i_P = 0

所以在我写的这个小游戏中,我有一副
n_C
卡,每个卡都有一个唯一的整数值。 有
n_P
玩家每人手里都拿着
n_H

甲板和双手共享一个阵列,如下所示: 玩家
i_P
的手牌包含从
牌组[i_P*n_H
牌组[i_P*(n_H+1)-1]
的所有牌。所有玩家的牌数总和始终少于
n_C

现在我想对每个玩家的手牌进行排序,但不是对整个牌组进行排序(显然,这会在玩家的手牌之间移动一些牌)

void sort_hands(char * deck, size_t n_P) {
    for (size_t i_P = 0; i_P < n_P; i_P++)
        sort_cards(deck + i_P * n_H, n_H);
}
void sort\u hands(字符组,大小){
对于(大小i_P=0;i_P
然后,使用插入排序(此函数将对整个数组进行很好的排序):

void排序卡(字符*卡,大小){
对于(大小i=0;i=0;j--){
if(卡片[j]>卡片[j+1])
卡交换(卡,j,j+1);
其他的
打破
}
}
*注意:
card\u swap
做的正是您所期望的,它只有3条语句

n_C
n_H
都是
\define
'd常量,
n_p
是局部变量。 当我用一个混洗组运行上面的代码,并且params
n_C=104,n_H=10,n_P=3
时,我得到:

0:
74315346427572777049

1:
76 86 99 78 11 94 61 14 41 87

2:
402692599366310198

在子数组排序和类似操作之前:

0:
35911314246495374

1:
61707572767778869499

2:
142640416366879298101


之后。正如我们所看到的,一些牌在不应该移动的时候移动了手。但是牌组并没有在所有手上进行排序(参见玩家2中的
14
。这怎么可能?在我看来,我的编码技能并没有错,但编译器似乎在搞乱我


我已经观察到了这一行为,包括VS15 C++编译器和GCC。

< P>我编译了你的代码> SoTojCARDS()/<代码>函数(在提供了缺失的代码> } />代码>之后,在MAC上用GCC 7.2.0和命令行:

gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
    -Wstrict-prototypes -c cards53.c
使用这些选项(关键选项是
-Wextra
),它会立即发出警告:

cards53.c:31:34: error: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
         for (size_t j = i - 1; j >= 0; j--)
这表明了一个严重的问题。特别是在外循环的第一次迭代中,
i
0
,因此
i-1
是一个非常大的数字。坦率地说,您声称该函数将成功地对整个数组进行排序是错误的。它不会。而且我不会运行不会使用显示的命令行编译的代码

如果您修复了该函数,那么您的代码就可以了。我使用了:

#include <stdio.h>

#define n_H 10
#define n_C 104

static inline void card_swap(char *deck, int i1, int i2)
{
    char t = deck[i1];
    deck[i1] = deck[i2];
    deck[i2] = t;
}

static void sort_cards(char *cards, size_t n)
{
    for (size_t i = 1; i < n; i++)
    {
        for (size_t j = i; j-- > 0; )
        {
            if (cards[j] > cards[j + 1])
                card_swap(cards, j, j + 1);
            else
                break;
        }
    }
}

static void sort_hands(char *deck, size_t n_P)
{
    for (size_t i_P = 0; i_P < n_P; i_P++)
        sort_cards(deck + i_P * n_H, n_H);
}

static void dump_hands(const char *tag, const char *deck, size_t n_P)
{
    printf("%s:\n", tag);
    for (size_t p = 0; p < n_P; p++)
    {
        printf("Player %zu:", p + 1);
        const char *hand = deck + p * n_H;
        for (int i = 0; i < n_H; i++)
            printf(" %3d", hand[i]);
        putchar('\n');
    }
}

int main(void)
{
    char deck[n_C] =
    {
        74,  31,  53,  46,  42,  75,  72,  77,  70,  49,
        76,  86,  99,  78,  11,  94,  61,  14,  41,  87,
        40,  26,  92,   5,   9,   3,  66,  63, 101,  98,
    };
    int n_P = 3;
    dump_hands("Before", deck, n_P);
    sort_hands(deck, n_P);
    dump_hands("After", deck, n_P);
    return 0;
}

检查表明每个子数组都正确排序。

“在C中”-那么为什么要将其标记为
C++
?在
中(size\t j=i-1;j>=0;j--)
当外部循环的第一次迭代
i==0时会发生什么?类型
size\t
没有签名。这看起来像是一个执行得很糟糕的冒泡排序。“我的编码技能没有错,但编译器似乎在搞乱我。"总是怀疑。在我看来,我的编码技能不是错的,-所以你是说世界各地成千上万的人和公司使用的编译器无法正确地执行你的简单代码?在你C编程生涯的这个阶段,假设如果编译器屈尊警告你一个问题,这意味着你有一系列错误编译器并没有错。也许30年后你可以换个角度思考,但我知道当编译器抱怨时,我必须假设我错了,而且这种假设很少出错。在我看来,我的编码技能失败了,我甚至无法正确调试。谢谢你的帮助!如果你让编译器指出你的错误。这就是为什么我向你展示了我使用的编译选项;它们让我避免了很多麻烦。
#include <stdio.h>

#define n_H 10
#define n_C 104

static inline void card_swap(char *deck, int i1, int i2)
{
    char t = deck[i1];
    deck[i1] = deck[i2];
    deck[i2] = t;
}

static void sort_cards(char *cards, size_t n)
{
    for (size_t i = 1; i < n; i++)
    {
        for (size_t j = i; j-- > 0; )
        {
            if (cards[j] > cards[j + 1])
                card_swap(cards, j, j + 1);
            else
                break;
        }
    }
}

static void sort_hands(char *deck, size_t n_P)
{
    for (size_t i_P = 0; i_P < n_P; i_P++)
        sort_cards(deck + i_P * n_H, n_H);
}

static void dump_hands(const char *tag, const char *deck, size_t n_P)
{
    printf("%s:\n", tag);
    for (size_t p = 0; p < n_P; p++)
    {
        printf("Player %zu:", p + 1);
        const char *hand = deck + p * n_H;
        for (int i = 0; i < n_H; i++)
            printf(" %3d", hand[i]);
        putchar('\n');
    }
}

int main(void)
{
    char deck[n_C] =
    {
        74,  31,  53,  46,  42,  75,  72,  77,  70,  49,
        76,  86,  99,  78,  11,  94,  61,  14,  41,  87,
        40,  26,  92,   5,   9,   3,  66,  63, 101,  98,
    };
    int n_P = 3;
    dump_hands("Before", deck, n_P);
    sort_hands(deck, n_P);
    dump_hands("After", deck, n_P);
    return 0;
}
Before:
Player 1:  74  31  53  46  42  75  72  77  70  49
Player 2:  76  86  99  78  11  94  61  14  41  87
Player 3:  40  26  92   5   9   3  66  63 101  98
After:
Player 1:  31  42  46  49  53  70  72  74  75  77
Player 2:  11  14  41  61  76  78  86  87  94  99
Player 3:   3   5   9  26  40  63  66  92  98 101