我知道通过比较两个const char *
对任意两个c字符串((a == b)
)没有意义。
但是我认为当两者都由SAME字符串文字定义时,这是合法的。
例如,在这里:
#include <stddef.h>
const char * const meals[] = {
"none",
"breakfast",
"lunch",
"dinner"
};
#define NO_MEALS meals[0]
#define BREAKFAST meals[1]
#define LUNCH meals[2]
#define DINNER meals[3]
// i hours after midnight, hour_to_meals_map[floor(i)] is being served.
const char * hour_to_meal_map[] = {
NO_MEALS,
NO_MEALS,
NO_MEALS,
NO_MEALS,
NO_MEALS,
BREAKFAST, // i = 5
BREAKFAST,
BREAKFAST,
BREAKFAST,
BREAKFAST,
BREAKFAST,
LUNCH, // i = 11
LUNCH,
LUNCH,
LUNCH,
LUNCH,
LUNCH,
DINNER, // i = 17
DINNER,
DINNER,
DINNER,
DINNER,
DINNER,
DINNER // i = 23
};
// Returns a boolean for whether the two hours have the same meal being eaten.
int same_meal(size_t hour_one, size_t hour_two) {
return hour_to_meal_map[hour_one] == hour_to_meal_map[hour_two];
}
(关于为什么您会hour_to_meal_map
映射到字符串而不是索引的问题,这是任何人的猜测。.但是我正在一个以这种方式设置的项目中。)
我是否正确,在这里,这是合法的,重要的是,只有一个地方可以将每个值写为文字? (故意避免使用#define NO_MEALS "none"
!)
如果此代码位于头文件中,那没有什么不同,是吗? (我希望标准要求meals
在每个编译单元中具有相同的值?)。
我从初学者那里发现了很多问题,询问他们很明显应该使用strcmp
的情况,但是我找不到能回答这种特殊情况的情况。任何帮助将不胜感激,特别是如果您可以将我指向C标准的正确部分,以便使我可以真的确保我理解所有的微妙之处。
答案 0 :(得分:3)
将两个相同类型的字符串与==
或!=
进行比较始终是合法的。 C standard的6.5.9节对此进行了详细说明,其中详细介绍了平等运算符:
2 满足以下条件之一:
- 两个操作数都具有算术类型;
- 两个操作数都是指向兼容类型的合格或不合格版本的指针;
- 一个操作数是一个对象类型的指针,另一个是
void
的合格或不合格版本的指针;或者- 一个操作数是一个指针,另一个是空指针常量。
...
4 两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针) 以及子对象的开头)或函数,它们都是指向 一个数组对象的最后一个元素之后,或者一个是 指向一个数组对象末尾的指针,另一个是 指向发生的另一个数组对象的开始的指针 立即跟随地址空间中的第一个数组对象
在这种情况下,您有一个指针数组,并将这些指针之一的值分配给另一个数组。因此,如果您比较两个指针,并且它们都包含(例如)meals[0]
的值,例如字符串常量“ none”的地址,可以保证它们比较相等。
您需要注意的是,是否在多个位置使用了给定的字符串常量。在这种情况下,它们不一定相同。
例如,鉴于此:
const char *s1 = "test";
const char *s2 = "test";
s1
和s2
的值不能保证相同,因为两个字符串常量可以彼此不同,尽管编译器可以选择使它们相同。这不同于:
const char *s1 = "test";
const char *s2 = s1;
s1
和s2
相同的地方,这反映了您的情况。
正如您所提到的,hour_to_meal_map
包含数字常量(最好是enum
的成员),然后将这些常量映射到字符串数组会更有意义。但是实际上,指向字符串常量的指针就是这样。
答案 1 :(得分:0)
我想到了char *
相等有意义的几种情况:
intern()
函数显式传递字符串