什么时候可以通过char*相等来比较C字符串?
我知道,通过比较两个任意c字符串(什么时候可以通过char*相等来比较C字符串?,c,string-literals,C,String Literals,我知道,通过比较两个任意c字符串(const char*)的(a==b),这对它们是没有意义的 但我认为当两者都由相同的字符串文字定义时,这是合法的 例如,这里: #include <stddef.h> const char * const meals[] = { "none", "breakfast", "lunch", "dinner" }; #define NO_MEALS meals[0] #define BREAKFAST meals[
const char*
)的(a==b)
,这对它们是没有意义的
但我认为当两者都由相同的字符串文字定义时,这是合法的
例如,这里:
#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];
}
#包括
常量字符*常量餐点[]={
“没有”,
“早餐”,
“午餐”,
“晚餐”
};
#定义无食物[0]
#定义早餐[1]
#定义午餐[2]
#定义晚餐[3]
//我在午夜后的几个小时内,提供小时到小时的膳食图[楼层(i)]。
const char*hour_to_mean_map[]={
不吃饭,
不吃饭,
不吃饭,
不吃饭,
不吃饭,
早餐,//i=5
早餐,
早餐,
早餐,
早餐,
早餐,
午餐,//i=11
午餐,
午餐,
午餐,
午餐,
午餐,
晚餐,//i=17
晚餐
晚餐
晚餐
晚餐
晚餐
晚餐//i=23
};
//返回一个布尔值,表示两个小时内是否吃了相同的一餐。
同一顿饭(1号、2号){
返回小时到餐点地图[小时到餐点地图]==小时到餐点地图[小时到餐点地图];
}
(至于为什么要将hour\u to\u mean\u map
映射到字符串而不是索引,这是任何人的猜测……但我正在进行一个这样设置的项目。)
我说的对吗,这在这里是合法的,重要的是,每个值只有一个地方是以文字形式写的?(\define NO\u故意避免使用“none”
)
如果这段代码在头文件中,那没有什么区别,是吗?(我希望标准要求每餐
在每个编译单元中具有相同的值?)
我从初学者那里发现了很多问题,询问他们应该使用
strcmp
的情况,但我找不到一个能回答这个特殊情况的问题。任何帮助都将不胜感激,特别是如果你能给我指出C标准的正确部分,这样我就可以确信我理解了所有的微妙之处 我能想到一些情况下,char*
相等是有意义的:
intern()函数显式传递字符串
将同一类型的两个字符串与
==
或进行比较=代码>始终是合法的。第6.5.9节对此进行了详细说明,其中详述了等式运算符:
2下列其中一项应适用:
- 两个操作数都具有算术类型李>
- 两个操作数都是指向兼容类型的合格或不合格版本的指针李>
- 一个操作数是指向对象类型的指针,另一个是指向
void
的限定或非限定版本的指针;或
- 一个操作数是指针,另一个是空指针常量
4两个指针比较相等当且仅当两个指针都是空指针时,两个指针都是指向同一对象的指针(包括指向对象的指针)
和子对象的开头)或函数,两者都是指向的指针
一个超过同一数组对象的最后一个元素,或者一个是
指向一个超过一个数组对象末尾的指针,另一个是
指向另一个数组对象开始的指针,该数组对象发生在
紧接着地址空间中的第一个数组对象
在本例中,您有一个指针数组,并将其中一个指针的值分配到另一个数组中。因此,如果比较两个指针,并且它们都包含(例如)fines[0]
的值,例如字符串常量“none”的地址,则保证它们的比较相等
您需要注意的是,如果给定的字符串常量在多个位置使用。在这种情况下,它们不一定是相同的
例如,鉴于此:
const char *s1 = "test";
const char *s2 = "test";
s1
和s2
的值不能保证相同,因为两个字符串常量可以彼此不同,尽管编译器可以选择使它们相同。这不同于:
const char *s1 = "test";
const char *s2 = s1;
其中s1
和s2
将是相同的,这反映了您的情况
正如您所提到的,hour\u to\u mean\u map
包含数值常量(最好是enum
的成员)以及随后将这些常量映射到字符串数组将更有意义。但是字符串常量的指针实际上就是这样。在这种情况下可能更有用。在实现这些字符串常量时,您有什么问题吗?C标准也可以用实际代码进行测试。你还可以测试你的实际实现,而不是阅读它应该是什么。不,到目前为止还没有遇到任何问题。只是想确保我没有滥用C标准(并且想创建一个问题,答案不是像我发现的所有其他问题一样“使用strcmp!!”)。实际代码与此非常相似。@dvhh我同意;如果可能的话,我的目标基本上是在已经编写好的程序结构中工作。我认为初始化是不合法的。一些gcc版本接受它,但我确信它不可移植<代码>函数[0]
不是常量表达式(在C中),静态初始化器必须是所有常量。什么是“一个intern()
函数”?@MM一个返回具有给定值的唯一标识字符串的函数。使用任何类似哈希表的数据结构来实现都很简单。更糟糕的是,在两个“test”
文本的情况下,编译器可能会使用