繁体   English   中英

C 语言。 这是指针比较还是其他?

[英]C language. Is this pointers comparison or something else?

我一直在学习 Python 一段时间,现在我发现自己正在探索一些 C 基础知识。 在阅读了有关指针的内容后,我使用了一些相关的语法,并编写了一个非常简单的脚本:

#include <stdio.h>

int main(void)
{
    char *k_ptr = "home";
    char *j_ptr = "pen";

    printf("string: %s, address: %p\n", k_ptr, &k_ptr);
    printf("string: %s, address: %p\n", j_ptr, &j_ptr);

    if (k_ptr == j_ptr)
    {
        printf("It's equal.\n");
    }
    else
    {
        printf("It's not equal\n.");
    }
}

我了解到在 C 中,可以使用 strcmp() 进行字符串比较,而数组比较始终为 false。 但是之后:

-当我比较 k_ptr == j_ptr 时,我实际上在比较什么?

- 如果这不是字符串比较,为什么如果两个字符串相等或不相等,程序会正确返回?

- 为什么这种语法似乎只在我使用字符串时才有效?

你声明了两个指针

char *k_ptr = "home";
char *j_ptr = "pen";

指向用作初始值设定项的相应字符串文字的第一个字符。

也就是说,指针k_ptr包含第一个字符串文字的字母'h'的地址,而指针j_ptr包含第二个字符串文字的字母'p'的地址。

字符串字面量占据 memory 的不同范围。 所以这个比较

if (k_ptr == j_ptr)

总是会产生错误。 那就是字符串文字的地址(它们的第一个字符)是不同的。

考虑到即使你会写例如

char *k_ptr = "Hello";
char *j_ptr = "Hello";

那么没有必要比较的结果

if (k_ptr == j_ptr)

将产生真实的。 结果取决于编译器选项。 编译器可以将相同的字符串文字存储为一个字符串文字或两个不同的字符串文字。

来自 C 标准(6.4.5 字符串文字)

7如果这些 arrays 的元素具有适当的值,则不确定它们是否不同。 如果程序试图修改这样的数组,则行为未定义。

如果您想比较字符串文字本身而不是它们的地址,那么您需要使用在 header <string.h>中声明的标准 C 字符串 function strcmp

例如

if ( strcmp( k_ptr, j_ptr ) == 0 )
{
    // string literals are equal
}

至于你的问题

-why this syntax seems to work only if I use strings?

那么字符串文字是未命名的字符 arrays。 在表达式中使用它们隐式转换(极少数例外)到指向其第一个元素的指针。

实际上,您可以使用与例如 integer arrays 相同的语法

int a[] = { 1, 2, 3 };
int *p = a;

现在指针p指向数组a的第一个元素。

当我比较 k_ptr == j_ptr 我实际上在比较什么?

您正在比较一个整数类型的值,该值表示 memory 中数据的地址。 您在printf语句中显示的地址是指针本身的地址,而在这里您正在比较指针指向的地址。

如果这不是字符串比较,为什么如果两个字符串相等或不相等,程序会正确返回?

这是常数值优化。 如果编译器第二次在代码中看到相同的字符串常量,它会将其引用到相同的 memory。 虽然它不可靠,所以你根本不应该依赖这种行为。 顺便说一句,当您使用is运算符比较字符串时,Python 也会发生同样的情况。 两个不同的字符串对象不是同一个 object,所以操作符应该返回False ,但是如果你在这样一个简单的程序中尝试它会返回True 这与在两个不同的程序(GCC 和 CPython)中实现的优化相同。

为什么这种语法似乎只在我使用字符串时才有效?

因为它们是指向常量值的指针,所以可以进行这种优化。

当我比较 k_ptr == j_ptr 我实际上在比较什么?

k_ptr是一个指针。 j_ptr是一个指针。 k_ptr == j_ptr测试它们是否指向同一个地方。

- 如果这不是字符串比较,为什么如果两个字符串相等或不相等,程序会正确返回?

如果两个指针指向同一个地方,那么它们指向的东西当然等于它自己。 如果它们指向不同的地方,它们指向的东西可能相等也可能不相等,因此比较指针与比较它们所指向的东西是不一样的。

- 为什么这种语法似乎只在我使用字符串时才有效?

这没用。

-当我比较 k_ptr == j_ptr 时,我实际上在比较什么?

您正在比较指针值本身,而不是它们指向的数据。 有效的指针值是对象的地址。 当且仅当它们指向相同的 object 时,相同类型的两个有效指针值才相等。

- 如果这不是字符串比较,为什么如果两个字符串相等或不相等,程序会正确返回?

因为不同的字符串必然有不同的地址。 指针比较判断两个指针是否指向同一个object,而不考虑指向对象的值。

请注意,在这个意义上,通过strcmp()比较相等的不同字符串是可能的。 一种比较与另一种无关。

- 为什么这种语法似乎只在我使用字符串时才有效?

目前还不清楚你的意思是什么语法。 您的程序中几乎没有特定于字符串的内容,但是您当然不能编写随机乱码并期望 C 编译器接受它。

当然,您可以对其他类型的指针执行==比较,它的意义与我已经描述的相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM