【问题标题】:How does this string comparison program work for same sized strings?这个字符串比较程序如何处理相同大小的字符串?
【发布时间】:2021-03-01 20:05:48
【问题描述】:

我们的教授给了我们以下 C 代码,用于比较两个相同大小的字符串,我不明白它是如何工作的。

int compare(char *a, char *b)
{
 int *pa = (int *)a;
 int *pb = (int *)b;
 return *pa == *pb;
}

当我有以下两个字符串时:

char *a = "你好"; char *b = "你好";

程序输出1,没什么异常。

char *a = "直升机"; char *b = "帮助";

程序输出0。这是怎么回事?我试图打印出以下内容:

 printf("%c,  %c\n%d,  %d\n", *a, *b, *pa, *pb);
 printf("%d\n", *pa == *pb);

我明白了:

h,  h
1869374824,  1886152040
0

为什么在对char指针进行类型转换并取消引用后值会发生变化?

【问题讨论】:

  • 因为您的环境中的int 占用4 个字节,而char 占用1 个字节?
  • 试试char *a="hello"; char *b="hellp";。它只识别前 4 个字符的差异。

标签: c string pointers type-conversion


【解决方案1】:

只要int 在您的目标系统上,给定函数仅适用于字符串。 (不过,还有更多的微妙之处。)

内存内容的含义仅取决于上下文。如果您在程序中说某些单元格形成一个字符数组,它将被解释为这样。如果相同的内存单元组成一个整数,它将被解释为整数。

现在让我们看看你的例子:

“helo”是一个由 5 个字符组成的字符串,'h'、'e'、'l'、'o' 和 '\0'。

“帮助”是一个由 5 个字符组成的字符串,'h'、'e'、'l'、'p' 和 '\0'。

这些是十六进制字节,假设它们是 ASCII:

  • “直升机”:0x68 0x65 0x6C 0x6F 0x00
  • “帮助”:0x68 0x65 0x6C 0x70 0x00

假设您的系统使用 32 位整数和小端序,将这些字节解释为整数:

  • “直升机”:0x68 0x65 0x6C 0x6F 0x00:0x6F6C6568 = 1869374824
  • “帮助”:0x68 0x65 0x6C 0x70 0x00:0x706C6568 = 1886152040

要查看限制,请尝试比较以下字符串:

  • “hello Dear”和“hello pal”=>在 32 位整数系统上报告为相等
  • "a" 和 "a" => 可能报告为不相等,具体取决于系统
  • “真的,真的很长”和“真的,真的很长,甚至更长” => 将在任何公共系统上报告为相等

回答您的具体问题

为什么在对char指针进行类型转换并取消引用后值会发生变化?

值不会因类型转换而改变。值的解释发生了变化。这是类型转换的目的之一。

编辑:

为什么compare("a", "a") 在某些系统或情况下返回“0” (false)?

试试这个小例子:

#include <stdio.h>

int compare(char *a, char *b)
{
    int *pa = (int *)a;
    int *pb = (int *)b;
    return *pa == *pb;
}

int main(void)
{
    static char a[] = "a";
    char b[2];
    
    b[0] = 'a';
    b[1] = '\0';
    
    printf("a = \"%s\", b = \"%s\", compare gives %d\n", a, b, compare(a, b));
    
    return 0;
}

结果将是:

a = "a", b = "a", compare gives 0

这是因为比较了 4 或 8 个字节,但字符串 a 只有 2 个字节长,字符串 b 也是如此。然而,该函数比较更多,在这种情况下字节太多。由于字符串后面的内存中包含不同的值,所以报字符串不相等。

【讨论】:

  • 这很清楚。谢谢你的解释。另外,我们是否可以通过使用更长字节大小的数据类型(可能是 double 或 long)来增加相似度范围?
  • 你可以试试这个并摆脱它。然而,想想“a”与“a”的例子,为什么它会给出错误的结果。最后,你教授的例子很好地介绍了记忆解释,但作为代码它是垃圾。
  • 不过,有些系统对对齐很挑剔。请使用您最喜欢的网络搜索引擎来查找“对齐”、“字节序”等技术术语。
  • 您能解释一下“a”和“a”在什么情况下会断开吗?它在我的 64 位电脑上运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多