我正在测试比较器功能的实现。所以这是我的代码工作
#include <stdio.h>
#include <string.h>
int compare_names(const void* a, const void* b)
{
char* sa = (char*) a;
char* sb = (char*) b;
return strcmp(sa, sb);
}
int main()
{
char *a = "Bianca";
char *b = "Ana";
printf("Comparing %s with %s returns: %i\n", a, b, compare_names(a, b));
return 0;
}
但是我不认为这是正确的,因为a
和b
函数的compare_names
参数应该变成指向char的指针。正如我读过的一本书所指出的,compare_names
函数的正确代码是
int compare_names(const void* a, const void* b)
{
char** sa = (char**) a;
char** sb = (char**) b;
return strcmp(*sa, *sb);
}
但是当我运行代码时,我遇到了分段错误(核心转储)。
我在这里缺少什么?
编辑:我在Linux x64上使用gcc。
答案 0 :(得分:1)
#include <stdio.h>
#include <string.h>
int compare_names(const void* a, const void* b)
{
char** sa = (char**) a;
char** sb = (char**) b;
return strcmp(*sa, *sb);
}
int main()
{
char *a = "Bianca";
char *b = "Ana";
printf("Comparing %s with %s returns: %i\n", a, b, compare_names(&a, &b));
return 0;
}
现在没关系。您必须将a
和b
的地址放在printf
参数中,因为它已投放到char**
。
答案 1 :(得分:1)
char** sa = (char**) a;
这句话说:“如果您对sa
两次进行指导,最终会得到一个char
”问题在于,因为您的a
是指针char你不能两次指责它。所以你正在做的铸造通常是错误的。
在进行转换时,编译器会尝试将*a
解释为char
作为指向char的指针,因此在执行转换时,*sa
最终成为BadPtr,因为它失败了要从char
转换为char *
。
所以在strcmp()
你有两个BadPtr。
答案 2 :(得分:1)
您传递的是char *参数,而不是char **参数。您发布的显示char **的示例代码执行以下操作:
1. Change generic pointer to a pointer to a string.
2. Compare the strings by dereferencing the char** arguments, meaning you're passing char* arguments to strcmp and return the result.
但是您将char *参数传递给比较函数,因此解除引用最终会将char类型的参数传递给strcmp。由于它需要指针,因此char被解释为内存地址。比较&#34;你好&#34; to&#34; bye&#34;实际上将地址0x67处的字符串与地址0x62处的字符串进行比较,这将是段错误。
将&amp; a和&amp; b传递给您的比较功能,使其不会出现段错误。
答案 3 :(得分:0)
然而,两个版本都适用于&#34; campare_names&#34;的第二个版本。函数,你应该在调用函数时传递一个指向每个char指针的aditional指针。
但是你的函数版本是正确的,当你期望函数将改变指针位置或被指向的数据时,它只能使用双指针参数。在这种情况下,由于strcmp函数只读取char *数据并且没有对其进行任何更改,因此您不需要一个aditional指针。