使用比较运算符比较 C++ 中的两个字符数组

Comparison of two Character Arrays in C++ using Comparison Operator

在两个字符数组之间进行比较时,比较运算符如何工作?

考虑以下程序,

#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 而 [=15= 的第一个字符的 ASCII 值] 是 116 所以技术上它应该打印 Yes.

但是,当 运行 on 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 作为输出,这意味着字符数组的地址在比较中并不重要。

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

在if语句的条件下

if (arr1 < arr2)

这两个数组都被隐式转换为指向它们第一个元素的指针,并且比较这些地址导致 operator <.

的未定义行为

注意你是否会比较像

这样的字符串文字
if ( "Hello" == "Hello" )
//...

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

至于比较不包含字符串的字符数组可以使用标准算法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

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

总之,你可以检查一下:

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

考虑使用 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;
}