这个函数究竟是如何将 char 转换为 int 的示例?
How exactly is this function an example of a char to int conversion?
Kernighan 和 Ritchie 的 The C Programming Language 一书,第二版在第 43 页上关于 Type Conversions 的章节中指出:
Another example of char
to int
conversion is the function lower
, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter, lower
returns returns it unchanged.
/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
它没有在文本中明确提及,所以我想确保我理解正确:当您使用 char
类型的变量调用 lower
函数时会发生转换,不是吗?特别是表达式
c >= 'A'
与从 int
到 char
的转换无关,因为像 'A'
这样的字符常量
从一开始就在内部作为 int
处理,不是吗?编辑:或者对于本书涵盖的 ANSI C,这是否不同(例如,字符常量被视为 char
)?
字符常量的类型如您所料,为 int
,因此您认为此函数中没有对 int
的提升是正确的。
如果将 char
类型的变量传递给此函数,则可能会发生任何提升,这很可能是文本所指的内容。
字符常量的类型在当前C17 standard(第6.4.4.4p10节)中都是int
:
An integer character constant has type
int
并且在 C89 / ANSI C standard(语义下的第 3.1.3.4 节)中:
An integer character constant has type int
后者是K&R Second Edition所指的。
K&R C 很旧。真的老了K&R C 的许多细节在最新的标准 C 中不再适用。
在标准的最新 C11 中,您发布的函数中没有转换 to/from char
:
/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
该函数接受 int
个参数作为 int c
,并且根据 6.4.4.4 Character constants of the C standard,字符文字的类型为 int
。
因此,C11 下发布的整个 lower
函数完全处理 int
值。
转换(如果有的话)可以在调用函数时完成:
char upperA = 'A`;
// this will implicitly promote the upperA char
// value to an int value
char lowerA = lower( upperA );
请注意,这是 C 和 C++ 之间的差异之一。在 C++ 中,字符字面量是 char
类型,而不是 int
.
How exactly is this function an example of a char
to int
conversion?
/* lower: convert c to lower case; ASCII only */
int lower(int c) {
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
这不是 char
到 int
转换的示例 - 作者在技术上不正确。
文本继续讨论 tolower(c)
作为 lower()
的替代方案,因为它 "works" 正确,即使 [A -Z] 没有像 EBCDIC 那样连续编码].
没有讨论的是 tolower()
函数和其他函数 (is...()
) 仅针对 unsigned char
范围内的 int
值和 EOF
. C11 §7.4 1. 其他值调用 未定义的行为 (UB)。
正是这种要求使得这些标准 C 库函数在概念上 char
到 int
的转换仅作为(大约)[=12 中的值=] 指定范围,结果为 int
.
现在查看确实发生 char
转换的代码 .
void my_strtolower1(char *s) {
while (*s) {
*s = lower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}
void my_strtolower2(char *s) {
while (*s) {
*s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}
void my_strtolower3(char *s) {
while (*s) {
// conversion `char` to `unsigned char` to `int` and `int` to `char`.
*s = tolower((unsigned char) *s);
s++;
}
}
my_strtolower1()
定义明确,但在 [A-Z,a-z]
不连续的稀有机器上功能不正确。
my_strtolower2()
预期的功能,除了 *s < 0
(而非 EOF
)时技术上未定义的行为。
my_strtolower3()
*s < 0
.
时没有 UB 的预期功能
Kernighan 和 Ritchie 的 The C Programming Language 一书,第二版在第 43 页上关于 Type Conversions 的章节中指出:
Another example of
char
toint
conversion is the functionlower
, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter,lower
returns returns it unchanged./* lower: convert c to lower case; ASCII only */ int lower(int c) { if (c >= 'A' && c <= 'Z') return c + 'a' - 'A'; else return c; }
它没有在文本中明确提及,所以我想确保我理解正确:当您使用 char
类型的变量调用 lower
函数时会发生转换,不是吗?特别是表达式
c >= 'A'
与从 int
到 char
的转换无关,因为像 'A'
这样的字符常量
从一开始就在内部作为 int
处理,不是吗?编辑:或者对于本书涵盖的 ANSI C,这是否不同(例如,字符常量被视为 char
)?
字符常量的类型如您所料,为 int
,因此您认为此函数中没有对 int
的提升是正确的。
如果将 char
类型的变量传递给此函数,则可能会发生任何提升,这很可能是文本所指的内容。
字符常量的类型在当前C17 standard(第6.4.4.4p10节)中都是int
:
An integer character constant has type
int
并且在 C89 / ANSI C standard(语义下的第 3.1.3.4 节)中:
An integer character constant has type
int
后者是K&R Second Edition所指的。
K&R C 很旧。真的老了K&R C 的许多细节在最新的标准 C 中不再适用。
在标准的最新 C11 中,您发布的函数中没有转换 to/from char
:
/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
该函数接受 int
个参数作为 int c
,并且根据 6.4.4.4 Character constants of the C standard,字符文字的类型为 int
。
因此,C11 下发布的整个 lower
函数完全处理 int
值。
转换(如果有的话)可以在调用函数时完成:
char upperA = 'A`;
// this will implicitly promote the upperA char
// value to an int value
char lowerA = lower( upperA );
请注意,这是 C 和 C++ 之间的差异之一。在 C++ 中,字符字面量是 char
类型,而不是 int
.
How exactly is this function an example of a
char
toint
conversion?
/* lower: convert c to lower case; ASCII only */
int lower(int c) {
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
这不是 char
到 int
转换的示例 - 作者在技术上不正确。
文本继续讨论 tolower(c)
作为 lower()
的替代方案,因为它 "works" 正确,即使 [A -Z] 没有像 EBCDIC 那样连续编码].
没有讨论的是 tolower()
函数和其他函数 (is...()
) 仅针对 unsigned char
范围内的 int
值和 EOF
. C11 §7.4 1. 其他值调用 未定义的行为 (UB)。
正是这种要求使得这些标准 C 库函数在概念上 char
到 int
的转换仅作为(大约)[=12 中的值=] 指定范围,结果为 int
.
现在查看确实发生 char
转换的代码 .
void my_strtolower1(char *s) {
while (*s) {
*s = lower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}
void my_strtolower2(char *s) {
while (*s) {
*s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}
void my_strtolower3(char *s) {
while (*s) {
// conversion `char` to `unsigned char` to `int` and `int` to `char`.
*s = tolower((unsigned char) *s);
s++;
}
}
my_strtolower1()
定义明确,但在 [A-Z,a-z]
不连续的稀有机器上功能不正确。
my_strtolower2()
预期的功能,除了 *s < 0
(而非 EOF
)时技术上未定义的行为。
my_strtolower3()
*s < 0
.