提问人:murage kibicho 提问时间:6/9/2023 更新时间:6/9/2023 访问量:93
从 Char 到 Int 的转换是否总是在 C 中给出正值
Does casting from Char to Int always give positive values in C
问:
我正在编写生产就绪的 C,我需要非常快速地找到 char 数组中字符的频率。我正在尝试删除断言调用以在强制转换期间检查正值。我的断言是多余的代码还是必要的?
char input[] = "Hello World";
int inputLength = sizeof(input)/ sizeof(char);
int *frequencies = calloc(256, sizeof(int));
for(int i = 0; i < inputLength-1; i++)
{
int value = (int) input[i];
assert(value > -1);//Is this line redundant?
frequencies[value] += 1;
}
printf("(%d)", inputLength);
PrintFrequencies(frequencies);
free(frequencies);
答:
从形式上讲,不要求标准 C 编译器支持的字符集的值具有任何特定值,无论是正值还是负值。
类型可以按 signed 或 unsigned:默认情况下是 char signed 还是 unsigned?。在它被签名并实现一些“扩展字符集”的情况下(例如,超越经典的“7 位 ASCII”),那么字符串理论上可以包含负值。char
因此,根据您需要编码的可移植性,断言可能会有一席之地。但是,如注释中所述,转换为无符号类型会消除该问题。请考虑改用它:
uint8_t value = input[i];
现在保证在 0 - 255 的范围内,并且代码是可移植的。value
从 Char 到 Int 的转换是否总是在 C 中给出正值
一般来说,不可以。 可以是有符号类型,也可以是无符号类型,由 C 实现自行决定,但很多时候它是有符号类型。char
表示基本执行字符集成员的所有值都保证为非负数。这包括大写和小写拉丁字母、十进制数字、各种标点符号、空格字符和一些控制字符。但是,表示其他字符的值可能是负数。此外,构成多字节字符表示的多个值可以包括一些被视为单个字符的负值。char
char
char
char
我正在编写生产就绪的 C,我需要非常快速地找到 char 数组中字符的频率。我正在尝试删除断言调用以在强制转换期间检查正值。我的断言是多余的代码还是必要的?
你的语义错了。如果你正在阅读任意文本,并且希望你的程序是健壮的,那么你确实需要为带有负值的 s 做好准备。但assert()
char
assert
离子是这项工作的错误工具。断言用于检查程序假定的不变量是否确实成立。例如,如果您(认为您)可以保证值始终为非负数,则可以使用断言。如果断言失败,则意味着您的代码是错误的。char
切勿使用断言来验证输入数据或执行程序所依赖的任何其他测试,因为根据编译程序的方式,断言表达式可能根本不会被计算。
如果遇到负值,程序最好处理负值,而不是失败。在这方面,请注意,将 your 显式转换为 .您可以在任何需要整数的地方直接使用 a。另一方面,投射到 可能是有意义的,因为这将是便宜的 - 可能是免费的,即使已经签名 - 并且它将解决您的签名问题。
char
char
int
char
unsigned char
char
评论
对于初学者来说,这句话
int inputLength = sizeof(input)/ sizeof(char);
是多余的。由于数组包含一个字符串,因此在 for 循环中,您可以检查当前字符是否为终止零字符 '。\0'
还要注意,通常字符数组可以比数组中存储的字符串大得多。因此,使用这个变量,以这种方式计算通常可能是错误的。如果需要存储字符串的长度,则使用标准 C 函数会更正确。
.
使用此铸件strlen
int value = (int) input[i];
实际上相当于
int value = input[i];
由于整数提升。
该类型可以表现为有符号类型或无符号类型。要使代码独立于类型的行为,您需要将每个字符强制转换为类型。char
signed char
unsigned char
char
unsigned char
所以这个断言
assert(value > -1);
没有用。
具有 256 个该类型元素的数组不是很大。因此,您可以使用自动存储持续时间来定义它。此外,在数组声明中使用类型而不是有符号类型在逻辑上是一致的。int
unsigned int
int
您的代码片段可能如下所示
char input[] = "Hello World";
unsigned int frequencies[256] = { 0 };
for ( const char *p = input; *p != '\0'; ++p )
{
++frequencies[( unsigned char )*p];
}
PrintFrequencies(frequencies);
评论
char
sizeof(char)
1
input
sizeof
size_t
%zu
int value = (unsigned char) input[i];
256
unsigned frequencies[256] = { 0 };
unsigned
assert
NDEBUG
char
unsigned char