输出一个奇怪的方式排序 [英] Output sorted in a weird way

查看:133
本文介绍了输出一个奇怪的方式排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面code,但由于从输出看到的东西是错误的。
我也许做了一个指针错误。你能帮忙吗?

未分类名称:

纽约
格鲁吉亚
波士顿

排序名称:

Bostork
格鲁吉亚
Newyon

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
的#define SIZE 3空隙排序(字符×〔3] [100]);
无效掉期(字符**,**字符);INT I,J;
焦炭名[SIZE] [100];
字符*温度;诠释主要(无效){//获取城市的名称
看跌期权(输入城市名称);
对于(i = 0; I<大小;我++)
{
    与fgets(名称[I],99,标准输入);
}
//打印输入的名称
看跌期权(\\ nUnsorted名称:\\ n);
对于(i = 0; I<大小;我++)
{
    的printf(%S,名称由[i]);
}排序(名称);//打印分类名称
看跌期权(\\ nSorted名称:\\ n);
对于(i = 0; I<大小;我++)
{
    的printf(%S,名称由[i]);
}残培();
 }//排序功能
空隙排序(炭angut [3] [100]){对于(i = 0; I<尺寸-1;我++)
{
    为(J = I + 1; J<大小; J ++)
    {
        如果(STRCMP(angut [I],angut [J])0)
        {
            掉期(安培; angut [I],和放大器; angut [J]);
        }    }}}  //交换功能
  无效掉期(焦**第一,焦炭**秒){TEMP = *第二;
*第二= *第一;
*第一=气温;}


解决方案

您是在不确定的行为境界。让我们编译code与真正的编译器,如gcc。这是(相关)输出:

 交流转换器:在函数'排序':
交流转换器:50:13:警告:传递从兼容的指针类型'交换'的参数1 [默认启用]
交流转换器:8:6:注:应为**字符',但参数的类型为CHAR(*)[100]
交流转换器:50:13:警告:传递从兼容的指针类型'交换'的论据2 [默认启用]
交流转换器:8:6:注:应为**字符',但参数的类型为CHAR(*)[100]

正如你所看到的,你给坏的参数交换。这是为什么不好的说法?这里的原因:

angut 是一个二维数组,这在现实中仅仅是一个单一的数组,它是行划分。 angut [I] 是阵列的行。请注意,这不是一个指针,它真的是整排的阵列中,类型的char [100] 。 (附注:如果你把它传递给一个函数,它的衰减以指针)。现在你正在服用它的地址,即数组中的一行,这是类型的地址字符(*)[100]

这是现在,你试图传递给交换的指针。别急,这不是一个指针的指针(为char),这是一个指针数组的一行。这是不兼容来自这就是为什么你会得到错误的结果。


这应该足以回答你的问题,但在这里发生的事情下方,因此奇怪的结果。让我们来看看一个的char **

  + ---------- + + ---------- + + ---------- +
|焦炭** A | ----> |字符* B | ----> |字符B |
+ ---------- + + ---------- + + ---------- +

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

  + ---------------- + -------------- +
|炭(* a)个[100] | ----> |炭B〔100] |
+ ---------------- + -------------- +

所以现在改变 *一个实际上改变了 B ,这是你的数据,而不是指针您的数据。在交换函数不知道这一点,所以它认为 A 的char ** 。那么是什么交换认为 *一个表示是一个指向一些字符串,对吧?什么你实际上是给它是字符串本身。

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

你看到发生了什么?基本上,前四个字节的字符串被交换,诬陷为指针。这就是为什么你看到 Bostork Newyon ,其中前四个字符进行交换。

I wrote below code but something is wrong as seen from the output. I made a pointer mistake maybe. Can you help?

Unsorted Names:

Newyork Georgia Boston

Sorted Names:

Bostork Georgia 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;

}

解决方案

You're in the realm of undefined behavior. Let's compile your code with a real compiler, such as gcc. This is the (relevant) output:

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]'

As you can see, you are giving bad arguments to swap. Why is that bad argument? Here's why:

angut is a 2d array, which in reality is just a single array that is divided in rows. angut[i] is a row of that array. Note that this is not a pointer, it's really the whole row of that array, of type char [100]. (Side note: If you pass it to a function, it decays to a pointer). Now you are taking its address, i.e., the address of a row in that array, which is of type char (*)[100].

This is now a pointer that you are trying to pass to swap. But wait, this is not a pointer to a pointer (to char), it's a pointer to a row of an array. That's were the incompatibility comes from and that's why you get wrong results.


This should be enough of an answer to your problem, but here's what's happening underneath and hence the strange results. Let's look at a char **:

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

by changing *a, you are changing b. Now let's see what you have actually sent to that function:

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

So now changing *a actually changes b, which is your data, not pointer to your data. The swap function doesn't know that, so it thinks a is a char **. So what swap thinks *a means is a pointer to some string, right? What you are actually giving it is the string itself.

So when you do *a1 = *a2;, the compiler takes 4 bytes (in your architecture) from where a2 points to and writes it to 4 bytes from a1 points to.

Do you see what's happening? Basically, the first four bytes of your strings are being swapped, framed as pointers. That's why you see Bostork and Newyon where the first four characters are swapped.

这篇关于输出一个奇怪的方式排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆