== 在比较 argv[] 字符串 [duplicate] 时不起作用

== doesn't works when comparing argv[] strings [duplicate]

提问人:Satyam S 提问时间:7/28/2022 最后编辑:Vlad from MoscowSatyam S 更新时间:7/28/2022 访问量:79

问:

我注意到使用 strcmp 和 == 运算符将普通字符串变量与字符串进行比较都有效,但使用 == 比较 argv 字符串不起作用,只有它适用于 strcmp。为什么?有什么特别之处?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[]) {
    char *tempStr = "string";
    int x = atoi(argv[2]), y = atoi(argv[3]);
    
    if (strcmp(tempStr, "string") == 0) {
        printf("'strcmp' methods works in case comparing with normal string variable\n");
    }
    if (tempStr == "string") {
        printf("'strcmp' as well as '==', both the methods works in case comparing with normal string variable\n");
    }
    

    /* this works for argv[] strings*/
    if (strcmp(argv[1], "add") == 0) printf("%d", x + y);
    else if (strcmp(argv[1], "subtract") == 0) printf("%d", x - y);
    else if (strcmp(argv[1], "multiply") == 0) printf("%d", x * y);
    else if (strcmp(argv[1], "divide") == 0) printf("%d", x / y);
    
    // /* this doesn't works for argv[] strings */ 
    // if (argv[1] == "add") printf("%d", x + y);
    // else if (argv[1] == "subtract") printf("%d", x - y);
    // else if (argv[1] == "multiply") printf("%d", x * y);
    // else if (argv[1] == "divide") printf("%d", x / y);

    return 0;
}
c if 语句 比较 隐式转换 string-literals

评论

3赞 Barmar 7/28/2022
没什么特别的。你总是用来比较字符串,而不是.argvstrcmp()==
0赞 Barmar 7/28/2022
它工作的唯一原因是因为它是指向同一字符串文本的指针。编译器对它们都使用相同的内存,因此地址是相等的。如果你这样做,它就行不通了tempStrchar tempStr[] = "string";

答:

1赞 Vlad from Moscow 7/28/2022 #1

这种比较

char *tempStr = "string";
//...
if (tempStr == "string") {
    printf("'strcmp' as well as '==', both the methods works in case comparing with normal string variable\n");
}

计算结果为 logical true 或 logical false,具体取决于编译器选项,该选项确定编译器是将相同的字符串文本存储为一个字符串文本(字符数组)还是单独的字符数组。

至于这个比较

if (argv[1] == "add") printf("%d", x + y);

然后,当比较两个指向占用不同内存范围的字符串的指针时,这种比较的计算结果总是为逻辑错误。

也就是说,在上面的比较中,数组指示符被隐式转换为指向数组的第一个元素的指针,并比较指针。

上面的 if 语句等效于下面的 if 语句

if ( &argv[1][0] == &"add"[0] ) printf("%d", x + y);
2赞 Barmar 7/28/2022 #2

当您使用 时,它会比较地址,而不是内容。您声明为指向字符串文本的指针,并将其与同一字符串文本进行比较。编译器注意到文本是相同的,因此它对它们使用相同的内存,这使得地址相同。==tempStr

你不能指望这是真的,这是组合这些相似字符串的编译器优化。

如果将声明更改为

char tempStr[] = "string";

你不会得到与 相同的结果。在本例中,是本地数组,而是静态字符串文字,它们将位于不同的内存位置。==tempStr"string"