Как именно эта функция является примером преобразования char
в int
?
/* 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()
, так как он "работает" правильно, даже если [A -Z] не кодируются последовательнокак в EBCDIC .
Что не обсуждается, так это то, что tolower()
функции и другие (is...()
) указаны только для значений int
в диапазоне unsigned char
и EOF
.C11 §7.4 1. Другие значения вызывают неопределенное поведение (UB).
Именно это требование делает функции библиотеки Standard C концептуально char
до int
преобразования, так как указаны только значения в (около) char
диапазоне, и результат равен 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()
ожидаемая функциональность без UB при *s < 0
.