你的问题是内循环的循环控制:
for (p_outer = p_inner + 1;
(p_outer-p_inner) < quantity; p_outer++)
您需要检查数组的开头:
for (p_outer = p_inner + 1;
(p_outer-p_customer_start) < quantity; p_outer++)
使用下标处理两个数组索引可能会更容易。
工作代码(修复了“交换”打印中的错误):
#include <stdio.h>
#include <string.h>
enum { MAX_NAME_LENGTH = 16 };
struct customer
{
char customer_name[MAX_NAME_LENGTH]; /* Last name of customer */
float amount_owed; /* Amount customer owes */
int priority; /* Priority of customer */
};
static void sort_customers(int quantity, struct customer *p_customer_start)
{
struct customer *p_customer,
*p_outer,
*p_inner,
temp_customer;
for (p_customer = p_customer_start;
(p_customer-p_customer_start) < quantity; p_customer++)
{
p_inner = p_customer;
printf("Inner: %s\n", p_inner->customer_name);
for (p_outer = p_inner + 1;
(p_outer-p_customer_start) < quantity; p_outer++)
{
printf("Compare: %s vs %s\n", p_inner->customer_name, p_outer->customer_name);
if (strcmp(p_inner->customer_name, p_outer->customer_name) > 0)
printf("Change!\n"),
p_inner = p_outer;
}
printf("Swap B: %s vs %s\n", p_customer->customer_name, p_inner->customer_name);
temp_customer = *p_customer;
*p_customer = *p_inner;
*p_inner = temp_customer;
printf("Swap A: %s vs %s\n", p_customer->customer_name, p_inner->customer_name);
//p_inner++;
}
}
static void dump_customers(int n, struct customer *c)
{
printf("Customers (%d):\n", n);
for (int i = 0; i < n; i++)
printf("%-10s %6.2f %4d\n", c[i].customer_name, c[i].amount_owed, c[i].priority);
}
int main(void)
{
struct customer data[] =
{
{ "Max", 23.45, 2 },
{ "Carla", 34.75, 1 },
{ "Zach", 39.21, 22 },
};
int quantity = 3;
dump_customers(quantity, data);
sort_customers(quantity, data);
dump_customers(quantity, data);
return 0;
}
失败版本的输出:
Customers (3):
Max 23.45 2
Carla 34.75 1
Zach 39.21 22
Inner: Max
Compare: Max vs Carla
Change!
Compare: Carla vs Zach
Compare: Carla vs
Change!
Compare: vs @?Q?
Compare: vs
Swap B: Max vs
Swap A: vs Max
Inner: Carla
Compare: Carla vs Zach
Compare: Carla vs Max
Swap B: Carla vs Carla
Swap A: Carla vs Carla
Inner: Zach
Compare: Zach vs Max
Change!
Compare: Max vs @?Q?
Change!
Compare: @?Q? vs
Change!
Compare: vs
Compare: vs
Swap B: Zach vs
Swap A: vs Zach
Customers (3):
0.00 0
Carla 34.75 1
-0.00 32767
Segmentation fault: 11
当它继续运行时,很明显内循环的边界存在问题。
工作版本的输出:
Customers (3):
Max 23.45 2
Carla 34.75 1
Zach 39.21 22
Inner: Max
Compare: Max vs Carla
Change!
Compare: Carla vs Zach
Swap B: Max vs Carla
Swap A: Carla vs Max
Inner: Max
Compare: Max vs Zach
Swap B: Max vs Max
Swap A: Max vs Max
Inner: Zach
Swap B: Zach vs Zach
Swap A: Zach vs Zach
Customers (3):
Carla 34.75 1
Max 23.45 2
Zach 39.21 22
请注意我如何每次都打印有用的信息。这种printf("Change!\n"),
表示法并不优雅——但它适用于调试目的。该dump_customers()
函数是您应该或多或少地为自己自动编写的东西(并且在调试时经常使用)。当事情出错时,它可以更容易地看到。这不是我最好的转储功能;它应该将标签字符串作为参数,并可能将 aFILE *fp
写入。对于更大的数组,它应该在每行前面打印行号。尽管如此,打印每个数据结构的函数的基本思想是非常有帮助的。