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

Difficulties when swapping 2 arrays in C

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

即:名字 Nicu Bogdan 第二名 安德烈·丹 第三名马丁·阿德里安

在 运行 我得到的代码之后 安德烈博格丹 马丁·丹 尼库阿德里安

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

#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;
 }

评论建议如果您使用结构数组而不是字符串数组,以及相同结构的额外临时存储实例,排序会更简单一些。以下基本上是您的代码,有一些更改。

查看评论中的建议和解释。

#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);
}

Is it possible to use pointers to solve this issue?

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

      // 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;

这样您就可以使用 指向名为 comparestrcpy 的指针来调用 strcpy,而不是直接调用 strcpy : cmp = compare(Name[j].nume, Name[j+1].nume);