C语言.这是指针比较还是其他什么



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

#include <stdio.h>
int main(void)
{
char *k_ptr = "home";
char *j_ptr = "pen";
printf("string: %s, address: %pn", k_ptr, &k_ptr);
printf("string: %s, address: %pn", j_ptr, &j_ptr);
if (k_ptr == j_ptr)
{
printf("It's equal.n");
}
else
{
printf("It's not equaln.");
}
}

我了解到在C中,字符串比较可以用strcmp()来完成,数组比较总是false。但随后:

-当我比较k_ptr==j_ptr时,我实际比较的是什么?

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

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

您声明了两个指针

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

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

即指针k_ptr包含第一字符串文字的字母'h'的地址,指针j_ptr包含第二字符串文字的字符'p'的地址。

字符串文字占用不同的内存范围。所以这个比较

if (k_ptr == j_ptr)

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

考虑到即使你也会写例如

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

则不需要比较的结果

if (k_ptr == j_ptr)

将生成true。结果取决于编译器选项。编译器可以将相同的字符串文字存储为一个字符串文字,也可以存储为两个不同的字符串文字。

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

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

如果要比较字符串文字本身,而不是它们的地址,则需要使用标头<string.h>中声明的标准C字符串函数strcmp

例如

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

关于你的问题

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

则字符串文字是未命名的字符数组。在表达式中使用时,它们隐式转换(极少数例外)为指向第一个元素的指针。

事实上,您可以使用相同的语法,例如像这样的整数数组

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

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

当我比较k_ptr==j_ptr时,我实际比较的是什么?

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

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

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

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

因为它们是指向常数值的指针,这允许进行此类优化。

当我比较k_ptr==j_ptr时,我实际比较的是什么?

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

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

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

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

它不起作用。

-当我比较k_ptr==j_ptr时,我实际比较的是什么?

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

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

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

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

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

不清楚你的意思是什么语法。在你的程序中,很少有特定于字符串的内容,但你当然不能写随机的胡言乱语,并期望C编译器接受它

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

最新更新