在 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;
这样您就可以使用 指向名为 compare
的 strcpy
的指针来调用 strcpy
,而不是直接调用 strcpy
: cmp = compare(Name[j].nume, Name[j+1].nume);
我写了一个代码来排列不同的名字,我想按字母顺序排列,到目前为止我设法只交换了名字:
即:名字 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;
这样您就可以使用 指向名为 compare
的 strcpy
的指针来调用 strcpy
,而不是直接调用 strcpy
: cmp = compare(Name[j].nume, Name[j+1].nume);