【问题标题】:Comparison of two Character Arrays in C++ using Comparison Operator使用比较运算符比较 C++ 中的两个字符数组
【发布时间】:2021-12-30 14:25:36
【问题描述】:

比较两个字符数组时比较运算符是如何工作的?

考虑以下程序,

#include <iostream>
using namespace std;


int main()
{
    char arr1[5] = { 'T','e','s','t' };
    char arr2[10] = { 't','e' };
    if (arr1 < arr2)
        cout << "Yes";
    else if (arr1 > arr2)
        cout << "No";
    else
        cout << "0";
}

我知道它应该打印Yes,因为arr1的第一个字符的ASCII值是84,而arr2的第一个字符的ASCII值是116所以从技术上讲它应该打印是的。

但是,这个程序在 Visual Studio 上运行时会给出No 的输出。

我认为它可能是在比较字符数组的地址。为了测试这一点,我交换了变量名并运行了这个程序,

#include <iostream>
using namespace std;


int main()
{
    char arr2[5] = { 'T','e','s','t' };
    char arr1[10] = { 't','e' };
    if (arr1 < arr2)
        cout << "Yes";
    else if (arr1 > arr2)
        cout << "No";
    else
        cout << "0";
}

但这又给出了Yes 作为输出,这意味着字符数组的地址在比较中并不重要。

谁能告诉我这个比较是如何进行的?

【问题讨论】:

  • 它比较他们的地址,这几乎不是你想要的。不要求改变它们的定义顺序会改变它们的相对地址。
  • 鉴于数组的内容从不使用且从不改变,编译器可以完全消除它们。
  • 当您执行arr1 &lt; arr2 时,它相当于&amp;arr1[0] &lt; &amp;arr2[0]。也就是说,您比较两个完全不相关的指针。如果你想比较数组的 content,要么使用循环(但记住大小差异!),或者使用 std::arraystd::vectorstd::string,它们具有执行适当的东西。
  • 或者,因为你有两个 C 风格的空终止字符串,你可以使用std::strcmp。但我真的建议你切换到合适的 C++ 容器。
  • operator &lt; 的行为取决于您使用的编译器。但我的直觉是编译器会比较你在初始化程序中放入的字符数。

标签: c++ arrays if-statement comparison implicit-conversion


【解决方案1】:

在if语句的条件下

if (arr1 < arr2)

这两个数组都被隐式转换为指向它们的第一个元素的指针,并且比较这些地址会导致 operator &lt; 的未定义行为。

注意你是否会比较像这样的字符串文字

if ( "Hello" == "Hello" )
//...

那么表达式的值可以是真或假,取决于编译器选项:相同的字符串文字是存储为一个字符串文字还是单独的字符串文字。

至于不包含字符串的字符数组的比较可以使用标准算法std::lexicographical_compare

否则,如果字符数组包含示例中的字符串,则可以使用标准 C 字符串函数strcmp

这是一个演示程序

#include <iostream>
#include <algorithm>
#include <cstring>

int main()
{
    char arr1[5] = { 'T','e','s','t' };
    char arr2[10] = { 't','e' };

    if (std::lexicographical_compare( arr1, arr1 + 4, arr2, arr2 + 2 ))
    {
        std::cout << "The array arr1 is less than the array arr2\n";
    }

    if ( std::strcmp( arr1, arr2 ) < 0 )
    {
        std::cout << "The array arr1 is less than the array arr2\n";
    }
}

程序输出是

The array arr1 is less than the array arr2
The array arr1 is less than the array arr2

【讨论】:

    【解决方案2】:

    它肯定比较地址而不是数组项的值。您不应该以这种方式依赖地址分配。

    无论如何,你可以检查:

    • string.h for strcmp() // 需要用 '\0' 终止你的 char 数组
    • 字符串::compare()
    • std::lexicographical_compare()

    【讨论】:

      【解决方案3】:

      考虑使用 string_view,它几乎没有任何开销。 https://en.cppreference.com/w/cpp/string/basic_string_view

      注意:此示例在编译时比较字符串以便于测试,但它也可以在运行时工作(没有 constexpr)

      #include <cassert>
      #include <string_view>
      
      int main()
      {
          constexpr std::string_view cvw1{ "test" };
          constexpr std::string_view cvw2{ "te" };
          static_assert(cvw1 > cvw2);
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多