-2

在 Visual Studio C++ 中,我定义了一系列具有从 0 到 15 的十进制值的 channelID 常量。我将它们设为 uint8_t 类型,原因与它们在运行此代码的嵌入式上下文中的使用方式有关。

当悬停在这些常量之一上时,我希望智能感知向我显示常量的数值。相反,它向我展示了字符表示。对于某些非打印值,它显示一个转义字符,表示某个 ASCII 值,而对于其他值,它显示该字符的转义八进制值。

const uint8_t channelID_Observations = 1;     // '\001'
const uint8_t channelID_Events = 2;           // '\002'
const uint8_t channelID_Wav = 3;              // '\003'
const uint8_t channelID_FFT = 4;              // '\004'
const uint8_t channelID_Details = 5;          // '\005'
const uint8_t channelID_DebugData = 6;        // '\006'
const uint8_t channelID_Plethysmography = 7;  // '\a'
const uint8_t channelID_Oximetry = 8;         // 'b'
const uint8_t channelID_Position = 9;         // ' ' ** this is displayed as a space between single quotes
const uint8_t channelID_Excursion = 10;       // '\n'
const uint8_t channelID_Motion = 11;          // '\v'
const uint8_t channelID_Env = 12;             // '\f'
const uint8_t channelID_Cmd = 13;             // '\r'
const uint8_t channelID_AudioSnore = 14;      // '\016'
const uint8_t channelID_AccelSnore = 15;      // '\017'

一些转义代码很容易识别,十六进制或十进制等效代码很容易记住(\n == newline == 0x0A),但其他的则比较晦涩难懂。例如十进制 7 显示为 '\a',在某些系统中表示 ASCII BEL 字符。

一些表示对我来说很神秘——例如十进制 9 将是一个 ASCII 制表符,今天通常显示为 '\t',但智能感知将其显示为一个空格字符。

  1. 为什么 8 位无符号整数总是被视为字符,无论我如何尝试将其定义为数值?

  2. 为什么这些字符中只有一些但不是全部显示为 ASCII 等价物的转义符号,而其他字符则使用八进制表示?

  3. 使用的晦涩符号的起源是什么?例如,十进制 7 的 '\a' 与 ISO 定义的 Control0 集相匹配,它具有 unicode 表示 - 但是十进制 9 应该显示 '\t'。维基百科 C0 控制代码

  4. 有没有办法让智能悬停提示向我显示这些常量的数值而不是字符表示?装饰?VS设置?类型定义?#定义?

4

3 回答 3

3

你误读了智能感知。0x7 = '\a' 不是文字字符'a'。'\a' 是铃声/闹钟。

请参阅以下有关转义序列的文章 - https://en.wikipedia.org/wiki/Escape_sequences_in_C

于 2017-04-18T08:52:44.060 回答
2

'\a'确实有值 0x7。如果您分配0x07给 a uint8_t,您可以非常确定编译器不会将该分配更改为其他内容。IntelliSense 只是以另一种方式表示值,它不会改变您的值。

此外,'a'它的值是 0x61,这可能会让你大吃一惊。

于 2017-04-18T08:50:59.630 回答
0

一年多后,我决定记录我在进一步研究时发现的内容。djgandy 的答案暗示了正确的答案,该答案引用了维基百科,但我想明确表示。

除了一个值 (0x09) 之外,Intellisense 似乎确实一致地对待这些值,并且这种处理植根于权威来源:我的常量是无符号的 8 位常量,因此它们是C11 语言的“字符常量”标准(第 6.4.4 节)。

对于不映射到可显示字符的字符常量,第 6.4.4.4 节将它们的语法定义为

6.4.4.4 字符常量

句法

. . .

::简单转义序列:其中之一

\'

\"

\?

\\

\一个

\b

\F

\n

\r

\t

\v

::八进制转义序列:

\八进制数

\八进制数字八进制数字

\八进制数字八进制数字八进制数字

“转义序列”在 C 语言定义第 5.2.2 节中进一步定义:

§5.2.2 字符显示语义

2)表示执行字符集中非图形字符的字母转义序列旨在在显示设备上产生如下操作:

\a (alert) 在不改变活动位置的情况下产生声音或可见的警报。

\b (退格) 将活动位置移动到当前行的前一个位置。如果活动位置在一行的初始位置,则显示设备的行为是未指定的。

\f (换页) 将活动位置移动到下一个逻辑页面开始处的初始位置。

\n(新行)将活动位置移动到下一行的初始位置。

\r(回车)将活动位置移动到当前行的初始位置。

\t(水平制表符)将活动位置移动到当前行的下一个水平制表位置。如果活动位置位于或超过最后定义的水平制表位置,则显示设备的行为未指定。

\v(垂直制表符)将活动位置移动到下一个垂直制表位置的初始位置。如果活动位置位于或超过最后定义的垂直制表位置,则显示设备的行为未指定。

3)这些转义序列中的每一个都应产生一个唯一的实现定义的值,该值可以存储在单个 char 对象中。文本文件中的外部表示不必与内部表示相同,并且超出了本国际标准的范围。

因此,Intellisense 失败的唯一地方是处理 0x09,它应该显示为

'\t'

但实际上显示为

''

那是怎么回事?我怀疑 Intellisense 将选项卡视为可打印字符,但在其格式中抑制了选项卡操作。在我看来,这与 C 和 C++ 标准不一致,也与其对其他转义字符的处理不一致,但也许有一些理由可以“逃避”我 :)

于 2018-08-29T17:41:11.683 回答