Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么时候可以通过char*相等来比较C字符串?_C_String Literals - Fatal编程技术网

什么时候可以通过char*相等来比较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[

我知道,通过比较两个任意c字符串(
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”
    文本的情况下,编译器可能会使用