在C中交换2个数组时遇到的困难

时间:2017-12-21 19:20:22

标签: c arrays swap partial

我写了一个代码来排列不同的名字,我想按字母顺序排序,到目前为止,我设法只换了第一个名字:

即:名字Nicu Bogdan      第二个名字安德烈丹      第三名Martin Adrian

运行代码后我得到了 安德烈·波格丹 马丁丹 Nicu Adrian

是否可以使用指针来解决此问题?

#include<stdio.h>
#include<string.h>

struct Names {
    char nume[10];
    char prenume[10];
} Name[2];

 int main()
{
    struct Names Name[3]={{"Nicu","Bogdan"},
                          {"Andrei","Dan"}, 
                          {"Martin","Adrian"}};
    int i,j;
    char temp[20];
    int n=3;
    int cmp;
    char tmp[20];


    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cmp = strcmp(Name[j].nume, Name[j+1].nume);

            if (cmp > 0)
            {
                strcpy(tmp, Name[j+1].nume);
                strcpy(Name[j+1].nume, Name[j].nume);
                strcpy(Name[j].nume, tmp);
            }
        }
    }
    for (i = 0; i < n; i++)
        printf("%s %s \n", Name[i].nume, Name[i].prenume);

    return 0;
 }

1 个答案:

答案 0 :(得分:2)

注释表明,如果使用struct数组而不是字符串数组,以及同一结构的额外临时存储实例,则排序可能会更简单一些。以下基本上是您的代码,稍作修改。

查看评论以获取建议和解释。

#include<stdio.h>
#include<string.h>

typedef struct {
    char nume[80];   // names are often longer than 10 characters.
    char prenume[80];// for simplicity, pick 80
} NAMES;  // create a typedef NAMES

int main(void)
{
    // use NAMES typedef to create instances of struct
    NAMES Name[3] = {{"Nicu","Bogdan"},
                     {"Andrei","Dan"},
                     {"Martin","Adrian"}};
    NAMES t; /// used for temporary storage during a swap

    int i,j;
    char temp[20]; // not used
    int n=3;
    int cmp;
    char tmp[20]; // not used


    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cmp = strcmp(Name[j].nume, Name[j+1].nume);

            if (cmp > 0)
            {
//              strcpy(tmp, Name[j+1].nume);
//              strcpy(Name[j+1].nume, Name[j].nume);
//              strcpy(Name[j].nume, tmp);
                // This is what comments are suggesting
                // each NAMES array element contains both first
                // and last names, therefore allowing a single
                // swap operation rather than 2 copying
                // operations per person. 
                t = Name[j];           
                Name[j] = Name[j+1];
                Name[j+1] = t;
            }
        }
    }
    for (i = 0; i < n; i++)
        printf("%s %s \n", Name[i].nume, Name[i].prenume);

    return 0;
 }

编辑:qsort也适用。例如:

int compareNames(const void *s1, const void *s2);

int main(void)
{
    int n=3;
    int i;

    NAMES Name[]={{"Nicu","Bogdan"},
                  {"Andrei","Dan"}, 
                  {"Martin","Adrian"}};

    //replace for/if statements with following line.
    qsort(Name, n, sizeof(NAMES), compareNames);

    for (i = 0; i < n; i++)
        printf("%s %s \n", Name[i].nume, Name[i].prenume);

    getchar();
    return 0;
}



int compareNames(const void *s1, const void *s2)
{
    NAMES *e1 = (NAMES *)s1;
    NAMES *e2 = (NAMES *)s2;

    return strcmp(e1->nume, e2->nume);
}
  

是否可以使用指针来解决此问题?

是。实际上,您已经在代码中使用了指针,避免使用指针是非常不切实际的,因为这意味着您不能使用任何数组或功能有意义。有关详细信息,请参阅下面一行代码的注释。

      // v function identifier expressions get converted to function pointers
cmp = strcmp(Name[j].nume, Name[j+1].nume);
           /*  ^       ^     ^         ^
            * Array expressions typically get converted to pointers
            */

如果您想明确表达这些隐式的,微妙的转换,这是可能的,例如通过声明:

typedef int *compare_function(char const *, char const *);
compare_function *compare = strcmp;

通过这种方式,您可以使用名为strcpy的{​​{1}} 的指针直接调用compare,而不是strcpystrcpy }