27、C语言编程新特性与实用技巧

C语言编程新特性与实用技巧

1. 运算限制与函数返回规则

在某些运算中,除法操作不被支持,并且仅适用于除普通字符(plain char)、布尔类型(bool)或位精确整数(bit - precise integers)之外的整数类型。Type1、Type2 和 Type3 可以是不同的类型。这些函数在运算的数学结果可以由 Type1 表示时返回 false,否则返回 true。虽然这些函数有助于遵循相关的编码标准和准则,但在组合操作时仍存在一定的不便。

2. unreachable 类函数宏

unreachable 类函数宏在 <stddef.h> 中提供。它会展开为一个 void 表达式,在执行过程中到达该表达式会导致未定义行为。这可以为优化器提供关于无法到达的流控制的提示,但使用时需谨慎,因为优化器会相信你给出的假设,即使假设错误。以下是一个典型的使用示例:

#include <stdlib.h>
enum Color { Red, Green, Blue };
int func(enum Color C) {
  switch (C) {
    case Red: return do_red();
    case Green: return do_green();
    case Blue: return do_blue();
  }
  unreachable(); // 未处理的值
}

3. 位和字节实用工具

C23 在 <stdbit.h> 头文件中引入了一系列位和字节实用工具,具体功能如下:
- 统计位模式中 1 或 0 的数量
- 统计前导或尾随 1 或 0 的数量
- 查找第一个前导或尾随 1 或 0
- 测试单个位是否被设置
- 确定表示一个值所需的最小位数
- 根据一个值确定下一个最小或最大的 2 的幂

例如,以下代码可用于统计一个值从最高有效位开始的连续 0 位的数量:

#include <stdbit.h>
void func(uint32_t V) {
  int N = stdc_leading_zeros(V);
  // 使用前导零计数 N
}

在 C23 之前,实现相同功能的代码更为复杂:

void func(uint32_t V) {
  int N = 32;
  unsigned R;
  R = V >> 16;
  if (R != 0) { N -= 16; V = R; }
  R = V >> 8;
  if (R != 0) { N -= 8; V = R; }
  R = V >> 4;
  if (R != 0) { N -= 4; V = R; }
  R = V >> 2;
  if (R != 0) { N -= 2; V = R; }
  R = V >> 1;
  if (R != 0) N -= 2;
  else        N -= V;
  // 使用前导零计数 N
}

4. IEEE 浮点支持

C23 通过集成 TS 18661 - 1、2 和 3 更新了 IEEE 浮点支持。现在,附录 F 与 IEEE 浮点算术标准(IEEE 754 - 2019)保持一致,并且也适用于十进制浮点数( _Decimal32 _Decimal64 _Decimal128 )。不过,不能将十进制运算与二进制、复数或虚数浮点数混合使用。附录 H 支持交换、扩展浮点类型和非算术交换格式,允许使用 binary16、图形处理单元(GPU)数据、二进制或十进制表示。

数学库的更改支持对 _DecimalN _FloatN _FloatNx 类型的 <math.h> 操作。新增了特殊的指数、对数、幂和基于 π 的三角函数变体,改进了用于最小/最大、全序和数值属性测试的函数,以及允许对浮点值与整数或字符串之间的转换进行细粒度控制的函数。

此外,新增了 memset_explicit 函数,用于在确实需要清除内存时使用。它与 memset 相同,但优化器不能移除对它的调用。 strdup strndup 函数从 POSIX 中被采用。

4.1 部分 C 语言特性总结表格

特性 描述
unreachable 宏 <stddef.h> 中,为优化器提供流控制提示,执行到展开表达式会导致未定义行为
位和字节实用工具 <stdbit.h> 中,提供多种位和字节操作功能
IEEE 浮点支持 集成相关标准,附录 F 与 IEEE 标准一致,数学库有新增功能
memset_explicit 函数 用于清除内存,优化器不能移除调用
strdup 和 strndup 函数 从 POSIX 采用

4.2 位和字节实用工具使用流程图

graph TD;
    A[开始] --> B[包含 <stdbit.h> 头文件];
    B --> C[定义 uint32_t 类型变量 V];
    C --> D[调用 stdc_leading_zeros(V) 函数];
    D --> E[获取前导零计数 N];
    E --> F[使用前导零计数 N];
    F --> G[结束];

5. 其他语言特性与操作

5.1 类型与运算符相关

  • 算术类型 :包括整数、浮点等类型。整数类型有不同的表示范围和精度,如 int long 等,其转换规则较为复杂,涉及到整数提升、通常算术转换等。例如,在进行算术运算时,不同类型的操作数会先进行转换,遵循一定的转换规则,以保证运算的正确性。
  • 运算符 :C 语言有丰富的运算符,如算术运算符( + - * / 等)、位运算符( & | ^ 等)、逻辑运算符( && || ! 等)。运算符有优先级和结合性,在表达式求值时需要遵循这些规则。例如, a + b * c 会先计算 b * c ,因为乘法运算符的优先级高于加法运算符。

5.2 存储相关

  • 存储类 :C 语言有多种存储类,如 auto static extern register 等。不同的存储类决定了变量的存储位置、生命周期和作用域。例如, static 变量在程序的整个执行期间都存在,而 auto 变量在其所在的代码块执行结束后就会被销毁。
  • 内存管理 :可以使用 malloc calloc realloc free 等函数进行动态内存分配和释放。例如,使用 malloc 分配内存:
#include <stdlib.h>
int main() {
    int *ptr = (int *)malloc(sizeof(int));
    if (ptr != NULL) {
        *ptr = 10;
        free(ptr);
    }
    return 0;
}

5.3 输入输出相关

  • 文件操作 :可以使用 fopen fclose fread fwrite 等函数进行文件的打开、关闭、读写操作。例如,读取文件内容:
#include <stdio.h>
int main() {
    FILE *fp = fopen("test.txt", "r");
    if (fp != NULL) {
        char ch;
        while ((ch = fgetc(fp)) != EOF) {
            printf("%c", ch);
        }
        fclose(fp);
    }
    return 0;
}
  • 格式化输入输出 :使用 printf scanf 等函数进行格式化的输入输出。例如,输出整数和字符串:
#include <stdio.h>
int main() {
    int num = 10;
    char str[] = "Hello";
    printf("Number: %d, String: %s\n", num, str);
    return 0;
}

5.4 部分特性总结表格

特性分类 具体特性 描述
类型与运算符 算术类型 包含整数、浮点等类型,有复杂的转换规则
运算符 丰富的运算符,有优先级和结合性
存储 存储类 auto static 等,决定变量存储位置、生命周期和作用域
内存管理 使用 malloc 等函数进行动态内存分配和释放
输入输出 文件操作 使用 fopen 等函数进行文件读写
格式化输入输出 使用 printf scanf 进行格式化操作

5.5 文件读取操作流程图

graph TD;
    A[开始] --> B[使用 fopen 打开文件];
    B --> C{文件是否打开成功};
    C -- 是 --> D[使用 fgetc 读取文件内容];
    D --> E{是否到达文件末尾};
    E -- 否 --> F[输出读取的字符];
    F --> D;
    E -- 是 --> G[使用 fclose 关闭文件];
    G --> H[结束];
    C -- 否 --> H;

6. 总结

C 语言具有丰富的特性和强大的功能,涵盖了运算、存储、输入输出等多个方面。新特性如位和字节实用工具、IEEE 浮点支持等为编程带来了更多的便利和功能扩展。同时,了解和掌握 C 语言的基本特性,如类型、运算符、存储类等,对于编写高效、正确的程序至关重要。在实际编程中,需要根据具体需求合理运用这些特性和工具,以实现所需的功能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值