想问一下,下面这个c语言程序错在哪里?

想问一下,下面这个程序错在哪里。为什么不能实现排序功能,为什么会得到这样的错误结果。在设想中,应该实现每13位排序,但是运行出来却不是。初学者实在想不通了,希望有人解答一下我的疑惑。

img

一付桥牌共52张牌,有四种花色,从大到小依次为:黑桃、 红桃、 方块、草花;每一种花色有十三张牌,顺序如下:A(最大)、K、Q、J、10、9、8、7、6、5、4、3、2(最小)。编写程序,实现将一付牌平均分发到4个玩家手中,按花色及牌点大小整理为有序并输出。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
void sort(int p)
{
int i=0,j=0;
for(i=0;i<13;i++)
{
for(j=0;j<13-i;j++)
{
if(*(p+j)>
(p+j+1))
{
swap((p+j),(p+j+1));
}
}
}
}
//0-12表示 黑桃
//13-25 红桃
//26-38 方块
//39-51 草花
int main(void)
{
int card[52];
int *p=card;
int i=0;
int t;
srand(time(0));
for(i=0;i<52;i++)
{
card[i]=i;
}
//洗牌
for(i=0;i<52;i++)
{
t=rand()%(52-i);
swap(&card[i],&card[i+t]);
}
//输出:
for(i=0;i<52;i++)
{
if(i%13==0)
{
if(i/13)
{
printf("\n");
}
printf("Person %d:",i/13+1);
}
printf(" ");
//输出花色
sort(p);
sort(p+13);
sort(p+26);
sort(p+39);
switch(card[i]/13)
{
case 0:printf("黑桃");break;
case 1:printf("红桃");break;
case 2:printf("方块");break;
case 3:printf("草花");break;
default:break;
}
//输出牌(2-10,j,q,k,A)
if(card[i]%13>=9)
{
switch(card[i]%13)
{
case 9:printf("J");break;
case 10:printf("Q");break;
case 11:printf("K");break;
case 12:printf("A");break;
default:break;
}
}
else
{
printf("%d",card[i]%13+2);
}

}
return 0;
}

冒泡排序时循环次数要比数组长度少1
13个数排序,下标为0到12
外循环 i从0到11循环12次(最后一个数已经是最大的了不需要再排序)
内循环j也是从0循环到11-i, 不能是循环12-i,
否则i为0时 j最后循环到12, 比较和交换时*(p + j + 1)访问13下标就越界了

另外
sort(p);
sort(p + 13);
sort(p + 26);
sort(p + 39);
排序要在循环外面, 只排序一次就可以了

你题目的解答代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void swap(int *a, int *b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}
void sort(int *p)
{
    int i = 0, j = 0;
    for (i = 0; i <= 11; i++)  //循环到11
    {
        for (j = 0; j <= 11 - i; j++)  //循环到11-i
        {
            if (*(p + j) > *(p + j + 1))
            {
                swap((p + j), (p + j + 1));
            }
        }
    }
}
//0-12表示 黑桃
//13-25 红桃
//26-38 方块
//39-51 草花
int main(void)
{
    int card[52];
    int *p = card;
    int i = 0;
    int t;
    srand(time(0));
    for (i = 0; i < 52; i++)
    {
        card[i] = i;
    }
    //洗牌
    for (i = 0; i < 52; i++)
    {
        t = rand() % (52 - i);
        swap(&card[i], &card[i + t]);
    }
    //排序要在循环外面
    sort(p);
    sort(p + 13);
    sort(p + 26);
    sort(p + 39);

    //输出:
    for (i = 0; i < 52; i++)
    {
        if (i % 13 == 0)
        {
            if (i / 13)
            {
                printf("\n");
            }
            printf("Person %d:", i / 13 + 1);
        }
        printf(" ");
        //输出花色
        switch (card[i] / 13)
        {
        case 0:
            printf("黑桃");
            break;
        case 1:
            printf("红桃");
            break;
        case 2:
            printf("方块");
            break;
        case 3:
            printf("草花");
            break;
        default:
            break;
        }
        //输出牌(2-10,j,q,k,A)
        if (card[i] % 13 >= 9)
        {
            switch (card[i] % 13)
            {
            case 9:
                printf("J");
                break;
            case 10:
                printf("Q");
                break;
            case 11:
                printf("K");
                break;
            case 12:
                printf("A");
                break;
            default:
                break;
            }
        }
        else
        {
            printf("%d", card[i] % 13 + 2);
        }
    }
    return 0;
}

如有帮助,请点击我的回答下方的【采纳该答案】按钮帮忙采纳下,谢谢!

img

你的排序函数有点问题,如果想用冒泡排序,应该是这样的

void sort(int p)
{
int i=0,j=0;
for(i=0;i<12;i++)
{
for(j=0;j<12-i;j++)
{
if(*(p+j)>*(p+j+1))
{
swap((p+j),(p+j+1));
}
}
}
}

sort的形参有问题,得改成指针