📜  C / C++中的多字符字面量

📅  最后修改于: 2021-05-26 01:57:00             🧑  作者: Mango

C和C++的字符字面量是char, 字符串,以及它们的Unicode和Raw类型。此外,还有一个多字符字面量,其中包含多个c字符。单个c-char字面量具有char类型,而多字符字面量具有条件支持,具有int类型,并且具有实现定义的value

例子:

'a' is a character literal.
"abcd" is a string literal.
'abcd' is a multicharacter literal.

大多数C / C++编译器都支持多字符字面量。以下示例演示了多字符字面量的概念。

范例1:

C
// C program to demonstrate 
// Multicharacter literal
#pragma GCC diagnostic ignored "-Wmultichar"
  
// This disables the 
// multi-character warning
#include 
  
// Driver code
int main()
{
  printf("%d", 'abcd');
  return 0;
}


C++
// C++ program to demonstrate
// multi-character literal
#include 
  
// Due to a bug we can't disable
// multi-character warning in C++
// using #pragma GCC diagnostic
// ignored "-Wmultichar"
using namespace std;
  
// Driver code
int main()
{
    cout << 'abcd' << endl;
    return 0;
}


C++
#include 
#include 
using namespace std;
  
int main()
{
    auto a = 10;
    auto b = 'a';
    auto c = 'abcd';
    auto d = "abcd";
  
    // 10 is of type i or int
    cout << "type of 10 is "
      << typeid(a).name() << endl;
  
    // 'a' is of type c or char
    cout << "type of \'a\' is "
      << typeid(b).name() << endl;
  
    // Multicharacter literals
    // 'abcd' is of type i or int
    cout << "type of \'abcd\' is "
      << typeid(c).name() << endl;
  
    // "abcd" is of type string
    cout << "type of \"abcd\" is "
      << typeid(d).name() << endl;
  
    return 0;
}


C++
#include 
using namespace std;
  
// Driver code
int main()
{
    cout << "\'abcd\' = " << 'abcd' << " = " << hex
         << 'abcd' << endl;
  
    cout << "\'a' = " << dec << (int)'a' << " = " << hex
         << (int)'a';
  
    return 0;
}


C++
#include 
using namespace std;
  
// Driver code
int main()
{
    cout << "\'abcd\' = " << 'abcd' << endl;
    cout << "\'efgh\' = " << 'efgh' << endl;
    cout << "\'abcdefgh\' = " << 'abcdefgh' << endl;
    return 0;
}


C++
#include 
using namespace std;
  
// Driver code
int main()
{
    char c = 'abcd';
  
    // stores as, c = ' d '
    cout << c << endl;
  
    return 0;
}


C++
#include 
using namespace std;
  
// Driver code
int main()
{
    int s = 'abcd';
  
    switch (s) {
    case 'abcd':
        cout << ('abcd' == 'abcd');
  
        // s = 1633837924 and 'abcd'
        // = 1633837924 so, value of
        // s is equal to 'abcd'
    }
  
    return 0;
}


输出
1633837924

范例2:

C++

// C++ program to demonstrate
// multi-character literal
#include 
  
// Due to a bug we can't disable
// multi-character warning in C++
// using #pragma GCC diagnostic
// ignored "-Wmultichar"
using namespace std;
  
// Driver code
int main()
{
    cout << 'abcd' << endl;
    return 0;
}

输出:

这样可以编译并正常运行,并且多字符字面量存储为整数值(数字从何处出现,您将在下面找到)。由于一般的pedantic编译器标志通过,因此会在所有多字符字面量上给出警告。该警告有助于指出我们是否错误地使用而不是 。警告是:

warning: multi-character character constant [-Wmultichar]

您可以直接从源代码使用#pragma GCC诊断忽略的“ -Wmultichar”禁用警告。

下面是关于多字符字面量一些重要的信息:

1.多字符字面量量与字符串不同:多字符字面量与字符串或字符数组不同,它们完全不同。多字符字面量不是整数类型,而是字符类型。

C++

#include 
#include 
using namespace std;
  
int main()
{
    auto a = 10;
    auto b = 'a';
    auto c = 'abcd';
    auto d = "abcd";
  
    // 10 is of type i or int
    cout << "type of 10 is "
      << typeid(a).name() << endl;
  
    // 'a' is of type c or char
    cout << "type of \'a\' is "
      << typeid(b).name() << endl;
  
    // Multicharacter literals
    // 'abcd' is of type i or int
    cout << "type of \'abcd\' is "
      << typeid(c).name() << endl;
  
    // "abcd" is of type string
    cout << "type of \"abcd\" is "
      << typeid(d).name() << endl;
  
    return 0;
}

输出:

尽管不应使用typeid()来告知类型,因为标准有时会保证为您提供错误的答案。但是这里typeid()足以指出Multi-character存储为整数类型,并且不同于char和字符串。

2.多字符字面量是实现定义的,而不是错误:

C++语义的一个方面,是为每个实现定义的,而不是在标准中为每个实现指定的。一个示例是int的大小(必须至少为16位,但可以更长)。尽可能避免实现定义的行为。

任何依赖于实现定义的行为的代码都只能保证在特定的平台和/或编译器下工作。  
例子:

  • sizeof(int);取决于编译器,它可以是4个字节或8个字节。
  • int * p = malloc(0 * sizeof * o);它可能导致p为NULL或唯一指针(如C99标准的7.20.3中所指定)。

C++继承了多字符字面量从CC继承了它从B编程语言。大多数编译器(MSVC除外)都实现B中指定的多字符字面量。

并不是C或C++的创建者对此一无所知,他们只是将其交由编译器处理。

3.多字符字面量存储为int而不是char(C标准):现在的问题是整数值从何而来。在int为4字节的编译器上,多字符存储为4字节,因为它取决于编译器。对于4个字节的多字符字面量,每个字符初始化所得整数(大端,零填充,右调整顺序)的连续字节。例如,将ASCII字符转换为以4字节int表示的int值,

在这里,整数有4个字节的存储空间:

       

现在,从左开始的第一个字符的ASCII最终被存储。基本上,“大端”字节顺序为:

      a

然后对于下一个字符,整数值向左移1个字节:

    a b

等等,

a b c d

现在,这4个字节代表一个整数,其计算公式如下:

'abcd' = (('a'*256 + 'b')*256 + `c`)*256 + 'd' = 1633837924 = 0x61626364 = '0xa0xb0xc0xd'

C++

#include 
using namespace std;
  
// Driver code
int main()
{
    cout << "\'abcd\' = " << 'abcd' << " = " << hex
         << 'abcd' << endl;
  
    cout << "\'a' = " << dec << (int)'a' << " = " << hex
         << (int)'a';
  
    return 0;
}

输出:

如果“多字符”字面量中的字符超过4个,则仅存储最后4个字符,因此,“ abcdefgh” ==“ efgh”,尽管编译器将对溢出的字面量发出警告。

C++

#include 
using namespace std;
  
// Driver code
int main()
{
    cout << "\'abcd\' = " << 'abcd' << endl;
    cout << "\'efgh\' = " << 'efgh' << endl;
    cout << "\'abcdefgh\' = " << 'abcdefgh' << endl;
    return 0;
}

输出:

就像上面一样,如果我们尝试将多字符字面量存储为char,则仅存储最后一个字符。

C++

#include 
using namespace std;
  
// Driver code
int main()
{
    char c = 'abcd';
  
    // stores as, c = ' d '
    cout << c << endl;
  
    return 0;
}

输出:

在这里,我们可以看到4字节整数的多字符字面量正转换为1字节char,并且仅存储了最后一个字符。

关于多字符字面量的好处:由于多字符字面量以int的形式存储,因此可以将其用于比较,以及在交换情况下(通常不使用字符串) 。

C++

#include 
using namespace std;
  
// Driver code
int main()
{
    int s = 'abcd';
  
    switch (s) {
    case 'abcd':
        cout << ('abcd' == 'abcd');
  
        // s = 1633837924 and 'abcd'
        // = 1633837924 so, value of
        // s is equal to 'abcd'
    }
  
    return 0;
}

输出:

多字符字面量:

  • 在C++中,有条件地支持多字符字面量。因此,您的代码可能无法编译。
  • 支持它们,但是它们具有实现定义的值。如果代码可以在您的计算机上正常运行,则不能保证它将在其他计算机上运行。
  • 同样,该实现有可能选择为所有多字符字面量分配值0,从而破坏您的代码。
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”