我写了下面的代码,但从输出中可以看出错误。 我可能犯了一个指针错误。你能帮忙吗?
未分类的名称:
纽约 格鲁吉亚 波士顿
已排序的名称:
Bostork 格鲁吉亚 Newyon
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 3
void sort(char x[3][100]);
void swap(char **, char **);
int i,j;
char names[SIZE][100];
char *temp;
int main(void){
//get the names of the cities
puts("Enter names of cities");
for (i = 0; i < SIZE; i++)
{
fgets( names[i], 99, stdin );
}
//print entered names
puts("\nUnsorted Names:\n");
for (i = 0; i < SIZE; i++)
{
printf("%s", names[i]);
}
sort(names);
//print sorted names
puts("\nSorted Names:\n");
for (i = 0; i < SIZE; i++)
{
printf("%s", names[i]);
}
getch();
}
//sorting function
void sort(char angut[3][100]){
for (i = 0; i < SIZE-1; i++)
{
for (j = i+1; j < SIZE; j++)
{
if (strcmp( angut[i], angut[j] ) >0)
{
swap(&angut[i],&angut[j]);
}
}
}
}
//swapping function
void swap(char **first, char **second){
temp=*second;
*second=*first;
*first=temp;
}
答案 0 :(得分:3)
你处于未定义行为的境界。让我们用真正的编译器编译你的代码,比如gcc。这是(相关)输出:
a.c: In function 'sort':
a.c:50:13: warning: passing argument 1 of 'swap' from incompatible pointer type [enabled by default]
a.c:8:6: note: expected 'char **' but argument is of type 'char (*)[100]'
a.c:50:13: warning: passing argument 2 of 'swap' from incompatible pointer type [enabled by default]
a.c:8:6: note: expected 'char **' but argument is of type 'char (*)[100]'
正如您所看到的,您正在向swap
提出错误的论据。为什么这个坏论点?原因如下:
angut
是一个二维数组,实际上它只是一个按行划分的单个数组。 angut[i]
是该数组的一行。请注意,这不是指针,它实际上是该类型的整个行,类型为char [100]
。 (旁注:如果将其传递给函数,衰减到指针)。现在您将获取其地址,即该数组中行的地址,其类型为char (*)[100]
。
现在这是您尝试传递给swap
的指针。但是等等,这不是指向指针(指向char)的指针,它是指向数组行的指针。这就是不兼容性来自,这就是你得到错误结果的原因。
这应该足以解决你的问题了,但是这里发生了什么,因此奇怪的结果。我们来看char **
:
+----------+ +----------+ +----------+
| char **a | ----> | char *b | ----> | char c |
+----------+ +----------+ +----------+
通过更改*a
,您正在更改b
。现在让我们看看您实际发送给该函数的内容:
+----------------+ +--------------+
| char (*a)[100] | ----> | char b[100] |
+----------------+ +--------------+
所以现在更改*a
实际上会更改b
,这是您的数据,而不是指向您数据的指针。 swap
函数不知道,因此它认为a
是char **
。那么swap
认为*a
意味着是指向某个字符串的指针,对吧?你实际上给它的是字符串本身。
因此,当您执行*a1 = *a2;
时,编译器会从a2
指向的位置获取4个字节(在您的体系结构中),并将其从a1
点写入4个字节。
你看到发生了什么吗?基本上,字符串的前四个字节被交换,框架为指针。这就是为什么你看到Bostork
和Newyon
交换前四个字符的原因。
答案 1 :(得分:2)
尝试在交换函数中使用实际的字符串副本,效率低下,但工作(而不是指针赋值)。
void swap(char **first, char **second){
char temp[100];
strcpy(temp, *second);
strcpy(*second, *first);
strcpy(*first, temp);
}