我正在编写可用于生产的C语言,其中我需要非常快地找到字符数组中字符的频率.我正在try 删除Assert调用,以在强制转换期间判断正值.我的断言是冗余代码还是必需的?

    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中,从CHAR到Int的强制转换总是给出正值吗

一般说来,没有.根据C实现的判断,char可以是有符号类型,也可以是无符号类型,但通常它是有符号类型.

表示基本执行字符集成员的所有char个值都保证为非负数.这包括大小写的拉丁字母、十进制数字、各种标点符号、空格字符和一些控制字符.然而,代表其他字符的char个值可能是负数.此外,构成多字节字符的表示的多个char值可以包括被认为是单个char的一些负值.

我正在编写可用于生产的C语言,其中我需要非常快地找到字符数组中字符的频率.我正在try 删除Assert调用,以在强制转换期间判断正值.我的断言是冗余代码还是必需的?

你的assert()在语义上是wrong.如果您正在阅读任意文本,并且希望您的程序是健壮的,那么您确实需要为具有负值的char做好准备.但

  1. assert个ionic 不适合做这项工作.断言用于判断程序假定的不变量是否实际有效.例如,如果您(认为)能够保证char个值始终为非负值,则可以使用断言.如果断言失败,这意味着您的代码是错误的.

    决不能使用断言来验证输入数据或执行程序所依赖的任何其他测试,因为根据您编译程序的方式,可能根本不会计算断言的表达式.

  2. 对于您的程序来说,如果遇到负char的值,最好是handle,而不是失败.在这一点上,请注意,将char显式转换为int并没有什么特别的用处.您可以在需要整数的任何位置直接使用char.另一方面,强制转换到unsigned char可能是有意义的,因为这将是便宜的--可能是免费的,即使签署了char个--它将解决您的签名问题.

C++相关问答推荐

为什么这个C程序代码会产生以下结果?

C/SDL程序,渲染不使用我的渲染器

为什么输出不是从上到下C

C编译器是否遵循restrict的正式定义?

C:fopen是如何实现二进制模式和文本模式的?

struct 上的OpenMP缩减

为什么GDB/MI进程的FIFO循环中有read()阻塞

X86/x64上的SIGSEGV,由于原始内存访问和C中的DS寄存器之间的冲突,在Linux上用TCC编译为JIT引擎

将uintptr_t添加到指针是否对称?

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

带有数组指针的 struct 在print_stack()函数中打印随机数

unions 的原子成员是个好主意吗?

当我将偏移量更改为任何非零值时,C中的mmap共享内存出现无效参数错误

RISC-V GCC编译器错误编译ASM代码

哪些C++功能可以在外部C块中使用

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

无法理解 fgets 输出

全局变量 y0 与 mathlib 冲突,无法编译最小的 C 代码

如何确定 C 程序中的可用堆内存

C99 的 %zu 格式说明符不起作用