strcmp输出的奥秘-strcmp如何实际比较字符串?

时间:2019-02-15 14:01:13

标签: c string strcmp

我想知道为什么strcmp()在同一函数中多次使用时会返回不同的值。下面是程序。我知道第一种情况为什么会显示-6。但是在第二种情况下,为什么打印-1?

#include<stdio.h>
#include<string.h>
int main()
{
    char a[10] = "aa";
    char b[10] = "ag";
    printf("%d\n",strcmp(a, b));
    printf("%d\n",strcmp("aa","ag"));
    return 0;
}

它产生的输出在下面

[sxxxx@bhlingxxx test]$ gcc -Wall t51.c
[sxxxx@bhlingxxx test]$ ./a.out
    -6
    -1

为什么第二strcmp() -1的输出是?是在这里玩的编译器吗?如果是这样,它的确切优化是什么?

3 个答案:

答案 0 :(得分:6)

C standard关于strcmp的返回值说:

第7.24.4.2p3节:

  

strcmp函数返回一个大于等于的整数,   或小于零,因此s1指向的字符串为   大于,等于或小于s2指向的字符串

只要结果符合该描述,它就符合C标准。这意味着编译器可以执行优化以适应该定义。

如果我们看一下汇编代码:

.loc 1 7 0
leaq    -32(%rbp), %rdx
leaq    -48(%rbp), %rax
movq    %rdx, %rsi
movq    %rax, %rdi
call    strcmp
movl    %eax, %esi
movl    $.LC0, %edi
movl    $0, %eax
call    printf
.loc 1 8 0
movl    $-1, %esi      # result of strcmp is precomputed!
movl    $.LC0, %edi
movl    $0, %eax
call    printf

在第一种情况下,将数组传递到strcmp,以调用strcmp,并生成对printf的调用。但是,在第二种情况下,字符串常量将传递给两个常量。编译器将看到此情况并自行生成结果,优化对strcmp的实际调用,并将硬编码值-1传递给printf

答案 1 :(得分:5)

来自https://linux.die.net/man/3/strcmp

  

strcmp()函数比较两个字符串s1和s2。如果分别找到s1小于,匹配或大于s2,则它返回小于,等于或大于零的整数。

strcmp函数仅承诺为上面给出的比较返回负值。未指定要返回的实际值。

可能发生的情况是,对于strcmp("aa","ag"),编译器知道结果为负,并将其优化为-1

答案 2 :(得分:1)

C标准为/var/run/docker.sock:/var/run/docker.sock保证的唯一事情是,如果有一个字符串,则返回值的符号将指示不等式的方向;如果字符串完全相等,则返回值为零。

虽然首先返回function ajaxCallback(id){ return $.ajax({ method: "POST", url: "../YourUrl", data: { id: id} }) } 的数值之间的差异,这是很常见的实现,但这不是必需的。如果编译器可以查看字符串常量并立即知道if (id != '')// { ajaxCallback(id) .done(function( response ) { //do something with your response }); } 的结果,则可以在其位置添加一个平面strcmpcharstrcmp而不是实际调用该函数。

对此的解决方案是,无论它多么常见,都不要编写依赖于-1的特定实现的代码。仅信任返回值的符号。