我写了一个代码来排列不同的名字,我想按字母顺序排序,到目前为止,我设法只换了第一个名字:
即:名字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;
}
答案 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
,而不是strcpy
:strcpy
}