2013-09-24 21 views
1

我写下面的代码,但从输出中看到一些错误。也许我犯了一个指针错误。你能帮我吗?以奇怪的方式排序的输出

未分类名称:

纽约 格鲁吉亚 波士顿

排序的名字:

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

我需要波士顿格鲁吉亚纽约作为输出。 – Lyrk

+0

你在开玩笑还是什么?不好笑 – Lyrk

回答

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 **

+----------+  +----------+  +----------+ 
| char **a | ----> | char *b | ----> | char c | 
+----------+  +----------+  +----------+ 

通过改变*a,要更改b。现在让我们看看你有什么实际发送到该函数:

+----------------+  +--------------+ 
| char (*a)[100] | ----> | char b[100] | 
+----------------+  +--------------+ 

所以现在改变*a实际上改变b,这是你的数据,而不是指向您的数据。 swap函数不知道,所以它认为achar **。那么swap认为*a的意思是指向一些字符串的指针,对吧?你实际上给它的是字符串本身。

所以当你做*a1 = *a2;,编译器会从那里a2点为4个字节(在你的架构),它从a1点写入4个字节。

你看到发生了什么?基本上,你的字符串的前四个字节被交换,成为指针。这就是为什么你看到BostorkNewyon前四个字符交换。

+0

感谢这个详细的答案。非常感谢。 – Lyrk

2

试着在你的交换功能,使用实际的字符串拷贝,将效率低下,但工作(而不是点)分配)。

void swap(char **first, char **second){ 

    char temp[100]; 
    strcpy(temp, *second); 
    strcpy(*second, *first); 
    strcpy(*first, temp); 
}