输出以奇怪的方式排序
我写下面的代码,但从输出中看到的是错误的。 我可能犯了一个指针错误。 你能帮我吗?
未排序的名称:
纽约乔治亚波士顿
排序名称:
Bostork Georgia Newyon
#include #include #include #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 0) { swap(&angut[i],&angut[j]); } } } } //swapping function void swap(char **first, char **second){ temp=*second; *second=*first; *first=temp; }
你处于未定义行为的境界。 让我们用真正的编译器编译你的代码,比如gcc。 这是(相关)输出:
ac: In function 'sort': ac:50:13: warning: passing argument 1 of 'swap' from incompatible pointer type [enabled by default] ac:8:6: note: expected 'char **' but argument is of type 'char (*)[100]' ac:50:13: warning: passing argument 2 of 'swap' from incompatible pointer type [enabled by default] ac: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
交换前四个字符的原因。
尝试在交换函数中使用实际的字符串副本,效率低下,但工作(而不是指针赋值)。
void swap(char **first, char **second){ char temp[100]; strcpy(temp, *second); strcpy(*second, *first); strcpy(*first, temp); }