C语言关键字 restrict(一)

本文深入解析C99标准中的restrict限定符,一种用于提高代码效率的类型限定符。通过实例说明restrict如何帮助编译器优化代码,避免通过多个指针修改同一内存区域,从而提升性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念:

  restrict,C语言中的一种类型限定符(Type Qualifiers),用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。

渊源:

  restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码.如 int *restrict ptr, ptr 指向的内存单元只能被 ptr访问到,任何同样指向这个内存单元的其他指针都是未定义的,直白点就是无效指针。restrict 的出现是因为 C 语言本身固有的缺陷,C 程序员应当主动地规避这个缺陷,而编译器也会很配合地优化你的代码.

使用场景:

  • 非常需要性能。
  • 需要改写指针的所指物。
  • 明确知道某两个指针在业务逻辑上不会、也不能重叠

理论解释较为抽象,根据《C Primier Plus 6th》的解释,举出以下例子:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <string.h>

int main()
{
    int i = 0;
    int arr[10] = {0};
    int *parr = arr;
    int * restrict rstar = (int *)malloc(sizeof(int)*10);
    memset(rstar, 0x00 ,sizeof(int)*10);
    
    for(i = 0; i < 10; i++)
    {
        #if 1
        rstar[i]  += 5;
        parr[i] += 5;
        arr[i] -= 2;
        parr[i] += 3;
        rstar[i]  += 3;
        #endif
    }

    if(rstar != NULL)
    {
        free(rstar);
        rstar = NULL;
    }
    return 0;
}

该例子编译时需要加上  -std=c99 选项

        其实上述例子看不出什么问题,只是编译器在会进行一定的优化。由于用 restrict 关键字修饰的指针 rstar ,在编译过程中,编译器认为,只有 rstar 指针可以访问上面 malloc 的区域。故在循环体中的rstar[i]  += 5;和rstar[i]  += 3;能合成一条

rstar[i]  += 8;以做优化。像是 arr 或是 parr ,能够访问到其地址区域的方式太多,编译器不敢贸然进行优化,故就按照正常流程一点一点编译。书中还举了一个memcpy的例子更为形象。

        在C99中, 这两个函数的原型是:
void * memcpy(void * restrict s1, const void * restrict s2, size_t n);
void * memmove(void * s1, const void * s2, size_t n);

        在memcpy中,指针s1 和 指针s2 都加上了 restrict 优化,其意义为,s1的指向的内存区域只能用s1来调用,s2的指向的内存区域只能用s2来调用,在restrict 的限定下,s1指向的区域与s2指向的区域相重合(重叠的意思也就是s1指向的区域有可能被s2指针应用,或是相反)是不允许的,故利用memcpy不会出现两个内存区域重合的情况。memmove则要考虑复制内存重合的情况。

<think>我们被要求提供C语言关键字列表。根据引用[2]和引用[3],我们可以整理出C语言关键字列表。注意,C语言标准的不同版本(如C89、C99、C11等)可能会有细微差别,但这里我们主要参考常见的标准(如C89)中的32个关键字。 引用[2]中提到“C语言的32个基本关键字”,并特别提到了`enum`。引用[3]则给出了个更详细的列表,包括每个关键字的简要说明。 因此,我们可以整理出以下32个关键字(按照字母顺序排列): 1. auto 2. break 3. case 4. char 5. const 6. continue 7. default 8. do 9. double 10. else 11. enum 12. extern 13. float 14. for 15. goto 16. if 17. int 18. long 19. register 20. return 21. short 22. signed 23. sizeof 24. static 25. struct 26. switch 27. typedef 28. union 29. unsigned 30. void 31. volatile 32. while 注意:在C99标准中增加了5个关键字:`inline`, `restrict`, `_Bool`, `_Complex`, `_Imaginary`。在C11标准中又增加了`_Alignas`, `_Alignof`, `_Atomic`, `_Generic`, `_Noreturn`, `_Static_assert`, `_Thread_local`。但通常我们所说的“32个关键字”是指C89(或ANSI C)标准中的关键字。 如果用户需要的是最基础的C语言关键字,那么就是上面列出的32个。如果用户需要包括新标准的,我们可以补充。 但是,根据用户的问题“我想获取C语言关键字列表”,并且引用中提到了32个基本关键字,我们首先提供这32个关键字的列表。 另外,引用[3]中对每个关键字都有简要说明,我们可以选择提供部分关键字的说明,但用户问题只要求列表,所以我们可以先提供列表,然后询问是否需要详细说明。 为了清晰,我们将关键字列表按照字母顺序排列并编号。 回答如下:</think>以下是C语言的标准关键字列表(基于ANSI C/C89标准),共32个关键字[^2][^3]: | 序号 | 关键字 | 类别 | 简要说明 | |------|------------|--------------------|-----------------------------------| | 1 | `auto` | 存储类别 | 声明自动变量(通常可省略) | | 2 | `break` | 流程控制 | 跳出循环或switch语句 | | 3 | `case` | 流程控制 | switch语句的分支标记 | | 4 | `char` | 基本数据类型 | 声明字符型变量 | | 5 | `const` | 类型修饰符 | 声明只读变量 | | 6 | `continue` | 流程控制 | 跳过本次循环剩余代码 | | 7 | `default` | 流程控制 | switch语句的默认分支 | | 8 | `do` | 流程控制 | 循环语句起始 | | 9 | `double` | 基本数据类型 | 声明双精度浮点变量 | | 10 | `else` | 流程控制 | if语句的否定分支 | | 11 | `enum` | 自定义数据类型 | 声明枚举类型 | | 12 | `extern` | 存储类别 | 声明外部链接的变量/函数 | | 13 | `float` | 基本数据类型 | 声明单精度浮点变量 | | 14 | `for` | 流程控制 | 循环控制语句 | | 15 | `goto` | 流程控制 | 无条件跳转语句 | | 16 | `if` | 流程控制 | 条件判断语句 | | 17 | `int` | 基本数据类型 | 声明整型变量 | | 18 | `long` | 类型修饰符 | 修饰长整型 | | 19 | `register` | 存储类别 | 建议编译器将变量存储在寄存器 | | 20 | `return` | 函数控制 | 从函数返回值 | | 21 | `short` | 类型修饰符 | 修饰短整型 | | 22 | `signed` | 类型修饰符 | 声明有符号类型 | | 23 | `sizeof` | 运算符 | 计算数据类型或对象的内存大小 | | 24 | `static` | 存储类别 | 声明静态变量/内部链接函数 | | 25 | `struct` | 自定义数据类型 | 声明结构体类型 | | 26 | `switch` | 流程控制 | 多分支选择语句 | | 27 | `typedef` | 类型定义 | 为数据类型创建别名 | | 28 | `union` | 自定义数据类型 | 声明联合体类型 | | 29 | `unsigned` | 类型修饰符 | 声明无符号类型 | | 30 | `void` | 特殊类型 | 表示无类型/空类型 | | 31 | `volatile` | 类型修饰符 | 声明易变变量(防止编译器优化) | | 32 | `while` | 流程控制 | 循环控制语句 | ### 说明: 1. **C99新增关键字**:`_Bool`, `_Complex`, `_Imaginary`, `inline`, `restrict` 2. **C11新增关键字**:`_Alignas`, `_Alignof`, `_Atomic`, `_Generic`, `_Noreturn`, `_Static_assert`, `_Thread_local` 3. 关键字不可用作标识符(如变量名、函数名) 4. 所有关键字均为**小写字母**(C语言区分大小写) ### 应用示例 ```c // 关键字使用示例 int main(void) { const float PI = 3.14159; // const修饰常量 unsigned int count = 0; // unsigned修饰无符号整型 for (int i = 0; i < 10; i++) { // 循环控制 if (i % 2 == 0) continue; // 条件控制 count++; } return sizeof(count); // 计算变量大小 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值