您的位置:3983金沙网站在线平台 > 母婴 > C核心 那些个关键字

C核心 那些个关键字

发布时间:2019-11-26 15:11编辑:母婴浏览(96)

    解释:

    演示:

    演示:

    多扯一点, 对于case也便是标志点. switch 中值决定case跳转到哪个地方.再一直往下推行, 境遇break再甘休switch嵌套.

    唯独还相当不足, 因为越发丑了. C11为C引进了线程 在 头文件<threads.h>中定义.但也允许编写翻译可以不完成.

     

    • 免除编写翻译器对从未 return的函数的警报. 
    • 同意某种只针对不回来函数的优化.

      程序重回语句太多了. 用于函数重临中. 重返void 直接 return;

    do while 循环不时候能够减少三回口径剖断. 品质越来越好, 代码更加长.

     

    #include <stdint.h>
    
    int8_t   -> signed char 
    uint8_t  -> unsigned char
    

    14) volatile

      if 分支语句. 用法太多了. 程序语句中拨出正是智能.

    可以预知料定程度上暗中同意启用register寄放器变量.

     

    解释:

    解释:

    for(;;) {  } 比 while(true) { } 写法好, 有生机勃勃种不走条件决断的意图, 尽管汇编代码是平等的.

     

    23) default

    那样的结果是接济理编辑译器实行越来越好的代码优化,生成更有功能的汇编代码。

    解释:

    解释:

    譬喻 abort恐怕 exit之类,调用它们就象征甘休程序. 所以 warning就显得无需.

    贮存器变量不可能取地址.

     

    讲的能够.
    演示:

     

    #include <stdbool.h>
    
    bool flag = true;
    
    // 或者直接用
    _Bool flag = !0;
    

      注脚变量的时候用! short 占2字节, 为无符号的. 暗中同意自带signed. 范围[-2^15, 2^15 - 1] 2^15 = 32800.

    演示:

    演示:

    后记 - 大家也不青春了

    9) union

    解释:

    自然当您用这些修饰变量的时候. 再利用 - 和 -- 运算的时候必定要小心

    演示:

      评释变量的时候用!八字节,精度在15-13位左右.有个别时候压缩内部存款和储蓄器用float替代.

    演示:

    现实的实施结果, 你也懂就那样. 原子操作, 对于写出高速代码很主要.

      原子操作, 原子锁. gcc 很已经支持. 详细用法能够参照 CAS

    29) return

     

      假设不符合规律招待补充, 关键字当字典用也是好的 哈哈啊

    C89 32个关键**

    演示:

      bool类型变量, 等价于 unsigned char . 独有0和1.

     上边容小编细细解析起实际用法.(存在平台差别, 非凡特地款待商酌补充, 那就也正是叁个首要字字典)

    演示:

     

    暗许变量都以auto的. 基本都以不写, 除非装B!

    具有校订该指针所指向内容的操作全都以基于(base on)该指针的,即不设有任何举办改善操作的门径;

    演示:

    它不是说函数没有重临值,而是说只要你调了那几个函数,它世代不会回到。一些函数是永世不会重回的,

    替代宏. 宏能不用就不用. 函数评释的时候绝不加inline 须求加extern, 定义的时候要求加inline.

    -> C89关键字

    解释:

    地方是摘自GCC 的 string.h中. 其实正式用法

       

    32) sizeof

      虚数类型. _Complex 复数类型的虚部. 举个例子 10.0i, 10.8if 等等.  那些重中之重字在VS 上还未有贯彻. 其实笔者也感觉没有供给.

    演示:

    for(int i = 0; i < 2; ++i) {
        if(i == 1)
           continue;
        if(i == 2)
           break;
    }
    
    等价于下面这个
    int i = 0;
    while(i < 2) {
      if(i == 1) {
         ++i;
         continue;
      }
      if(i == 2)
         break;  
    
      ++i;
    }
    
    // for 最好的写法, 在于死循环写法
    for(;;) {
       // xxxx
    }
    
        if ((n = *tar) == '') // 判断下一个字符
            goto __err_ext;    
    
        if(cl % rl){ // 检测 , 号是个数是否正常
        __err_ext:
            SL_WARNING("now csv file is illegal! c = %d, n = %d, cl = %d, rl = %d."
                , c, n, cl, rl);
            return false;
        }
    

    演示:

    int hoge = 24;
    printf("hoge = %d.n", hoge);
    
    #ifndef __cplusplus
    
    #define alignas _Alignas
    #define alignof _Alignof
    
    #define __alignas_is_defined 1
    #define __alignof_is_defined 1
    
    #endif
    
    /*
     * 对json字符串解析返回解析后的结果
     * jstr        : 待解析的字符串
     */
    extern cjson_t cjson_newtstr(tstr_t str);
    
    
    inline cjson_t 
    cjson_newtstr(tstr_t str) {
        str->len = _cjson_mini(str->str);
        return _cjson_parse(str->str);
    }
    
    
    // 还有就是和static 一起使用
    static inline int _sconf_acmp(tstr_t tstr, struct sconf * rnode) {
        return strcmp(tstr->str, rnode->key);
    }
    
    sizeof (main)   -> x86 上四字节
    
    // 获取数组长度,只能是数组类型或""字符串常量,后者包含''
    #define LEN(arr) (sizeof(arr) / sizeof(*(arr))) 
    

    _Thread_local是新的寄存类修饰符, 限制了变量不可能在三十二线程之间分享。
    演示:

    解释:

    解释:

    20) break

    28) if

      变量声明类型修饰符. 有符号型, 相比较 unsigned 无符号型. 变量表明暗中同意基本都以 signed, 所以多数外人就回顾了.

    枚举变量完全可以等效 int 变量使用, 枚举值等同于宏INT常量使用. 枚举的私下认可值是以1位单位从上向下依次增加.

      变量类型注脚符, auto变量存放在动态存款和储蓄区,随着生命周期{起头}结束而那个时候释放.贮存在栈上. 

    22) continue

       

      你会心疼吧, 已经心疼了 /(ㄒoㄒ)/~~

    解释:

    理所必然了, 平时无需着意加. 会令人嫌麻烦. O(∩_∩)O哈哈~

    -> C99新增添关键字

      else 是 if 的反分支. 具体看演示

    register i = 0;
    do {
        if(i % 2 == 0) 
               continue;
    
        printf("i = %d.n", i);   
    
    } while(++i < 10);
    

    演示:

    #define complex         _Complex
    

    42) _Noreturn

    解释:

    演示:

      extern 关键字表示评释, 变量申明, 函数证明.  奇葩的用法比相当多.

    static修饰的变量成效域只能在这个时候此刻文件范围内. 能够视作上层语言的private. 除了auto就是static.

     

      定义公用体, 用法很花哨. 常在优秀库函数封装中用到.技艺性强

    演示:

     

    解释:

     

    #include <stdlib.h>
    
    int main(int argc, char * argv[]) {
    
       return EXIT_SUCCESS;
    }
    

    解释:

    11) enum

     

    解释:

      类型重定义修饰符. 重新定义新的类型.

    25) else

    5) long

    31) while

    解释:

      变量类型修饰符! 被修饰的变量正是无符号的.范围 >= 0.  unsigned 只好修饰整型的变量.

    static修饰函数表示前段时间函数是私家的,只好在当下文件中接收. 尤其详细的看演示部分.

    解释:

    解释:

      那一个首要字不可能在代码中表示. 系统一保险留, 大家不能够使用.

    再扯一点, GCC中等同于 __attribute__((__noreturn__)), 在VC中日常成效是 __declspec(noreturn).

    15) typedef

    解释:

    _Thread_local static int i;
    // Thread local isn't local!
    

    演示:

    事实上在c中挑大梁未有啥变动不了的. 全都以内部存款和储蓄器来回搞, 软件不行硬件~~

    13) const

    演示:

    由于CPU存放器是轻便的, 不经常候你正是评释的贮存器变量也会有可能只是平凡变量. printf("&i = %pn", &i) 这种用法是不合法.

     

    解释:

     

     

     

    // case 普通用法 和 break成对出现
    switch ((c = *++ptr)) {
    case 'b': *nptr++ = 'b'; break;
    case 'f': *nptr++ = 'f'; break;
    case 'n': *nptr++ = 'n'; break;
    case 'r': *nptr++ = 'r'; break;
    case 't': *nptr++ = 't'; break;
    }
    

      内部存储器对齐的操作符. 须求和_Alignof合作使用, 内定结构的对齐形式.
    演示:

    演示:

    演示:

    解释:

      对于C99 标准定义, 存在 float _Complex, double _Complex, long double _Complex 复数类型. 上边先演示gcc 中关于复数的用法.

    2) short

    解释:

    再有正是在工程支出中, goto 常用于复制的事情逻辑.

    解释:

    解释:

    演示:

      变量修饰符,只好修饰整形变量.表示愿意以此变量存放在CPU的存放器上.今世编写翻译器在拉开优化时候,

    解释: 

      内联函数,从C++中引进的概念. 便是将小函数直接嵌入到代码中. C的代码损耗在于函数的出入栈. 若是足以引入用内联函数

    演示:

    演示:

    #include <limits.h>
    
    register int i = 0;
    while (i < INT_MAX) {
    
       ++i;
    }
    

    现在采纳loop的时候, 别的线程校订, 当前线程也能科学获取它的值.

    演示:

    27) goto

    float f = -0.12f;        // 四字节
    long float lf = 0;       // 八字节 等同于 double, 不推荐这么写
    
    __loop:
       // xxx 死循环用法
    goto __loop;
    __exitloop:
    

    此地VS 和 GCC完结不相通. 用起来必要注意.

    解释:

     

    30) switch

      那是很装B的十分重要字用于编写翻译器优化. 关键字restrict只用于限制指针;该重大字用于告知编写翻译器,

    // 简单演示用法, GCC 和 VS 都是 __restrict 推荐加在 * 后面
    static void _strlove(char * __restrict dest) {
        *dest = '';
    }
    
    _Static_assert(__STDC_VERSION__ >= 201112L, "C11 support required");
    // Guess I don't really need _Static_assert to tell me this :-(
    

     

    // for 循环 continue
    for(int i = 0; i < 20; ++i) {
        if(i % 2 == 0)
             continue;
    
         // 上面continue 调到 ++i -> i < 20 代码块
    }
    

      循环语句, 有do while 和 while 语句三种.

    解释:

     

    演示:

     

      const修饰的变量表示是个不足修正的量. 和常量有一些分化. 可以大致认为const type val 是个只读的.

      申明变量的时候用! int 阐明的变量, 占4字节, 有号子. 范围 [-2^31, 2^31-1].

    #include <stdio.h>
    #include <stdatomic.h>
    
    int main(int argc, char * argv[]) {
    
        _Atomic int hoge = ATOMIC_VAR_INIT(100);
        int piyo = atomic_load(&hoge);  
        printf("piyo = %d.n", piyo);
        piyo += 2;
        atomic_store(&hoge, piyo);
        printf("hoge = %d.n", hoge);
    
        return 0;
    }
    

    struct 正是概念结构的东西, 能够看看上边演示

    _Alignas _Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local

    C99 5个新扩张关键**

    8) struct

    解释:

    if(false) {
       puts("我想做个好人!");
    }
    

    概述 - C语言老了

    signed int piyo = 0x1314520;
    signed char * str = u8"你好吗";
    
        long l = 4;
        long long ll = l;
        printf("l = %ld, ll = %lld.n", l, ll);
    

     

    _Bool _Complex _Imaginary inline restrict

    解释:

    _Noreturn void suicide(void) {
        abort(); // Actually, abort is _Noreturn as well
    }
    

     

    再来风流罗曼蒂克种 union用法, 利用内部存款和储蓄器对齐. 

    常用在二十四线程代码中.

      注明变量的时候用! 四字节. 精度是6-7位左右.  详细精度能够看 float与double的范围和精度

    #include <stdbool.h>
    
    if(true) {
       puts("你好吗?");
    }
    else {
      puts("我们分手吧.");
    }
    
    
    
    // 附赠个else 语法
    #if defined(__GNUC__)
    
    // 定义了 __GNUC__ 环境, 就是gcc环境
    
    #else
    
    #error "NOT __GNUC__, NEED GCC!";
    
    #enfif
    

     

    #include <stdio.h>
    #include <stdalign.h>
    
    struct per {
        int age;
        double secl;
        char sex;
    };
    
    int main(int argc, char * argv[]) {
        char c[100];
        alignas(struct per) struct per * per = (struct per *)&c;
        printf("per = %p, c = %p.n", per, c); 
    
        return 0;
    }
    

    演示:

    演示:

      static 用法很遍布. 修饰变量, 表示变量存在于静态区, 基本正是全局区. 生存周期同系统生存周期.

      实在男士汉 
    **

      结束语句. 首要用以循环的跳转, 只可以跳转到当前层级. 也用于switch 语句中, 跳出switch嵌套.

    // 函数声明
    extern void foo();
    
    // 函数参数约束
    extern void foo(void);   // ()中加了void表示函数是无参的, 否则是任意的
    
    // 万能类型定义, 指针随便转
    void * arg = NULL;
    

      这些关键字也称得上 sizeof 运算符. 总计变量或项目标字节大小. 那么些十分重要字特别好用!

    39) _Alignof

      近些日子来说(二〇一七年七月17日) C语言中有 32 + 5 + 7 = 44 个至关心珍视要字. 具体如下 O(∩_∩)O哈哈~

    43) _Static_assert

    40) _Atomic

    1) char

     

    7) double

    实则在复数类型中, gcc标准兑现

     

    37) restrict

      switch 语句中分支语句. 明显走如何分支.

     

    解释:

    #ifndef _C_COMPLEX_T
        #define _C_COMPLEX_T
        typedef struct _C_double_complex
        {
            double _Val[2];
        } _C_double_complex;
    
        typedef struct _C_float_complex
        {
            float _Val[2];
        } _C_float_complex;
    
        typedef struct _C_ldouble_complex
        {
            long double _Val[2];
        } _C_ldouble_complex;
    #endif
    
    typedef _C_double_complex  _Dcomplex;
    typedef _C_float_complex   _Fcomplex;
    typedef _C_ldouble_complex _Lcomplex;
    

    4) unsigned

    理之当然有的时候候候extern不写, 对于变量不行相会世重定义. 对于函数是足以缺省写法. 再扯一点

      do 循环. 先施行循环体, 后再实行准绳决断.

     

    //12.0 判断是大端序还是小端序,大端序返回true
    inline bool
    sh_isbig(void) {
        static union {
            unsigned short _s;
            unsigned char _c;
        } _u = { 1 };
        return _u._c == 0;
    }
    

    解释:

    {
        // 生存期开始
        int hoge = 0;
        auto int piyo = 1;
        // 生存期结束
    }
    

      枚举类型, C中枚举类型很简陋. 其实就约等于黄金年代种变相的INT宏常量. 推测那只怕也是 INT宏常量和枚举并存的原因.

    解释:

    演示:

    16) auto

    演示:

     

    24) do

    36) inline

    演示:

     

     

    C11 7个新扩充关键字

    解释:

      评释变量的时候用! char占1字节, 8bit. 比很多种类(vs or gcc)上是有标记的(arm 上无符号), 范围是[-128, 127]. 

    演示:

    short port = 8080;
    printf("port = %d.n", port);
    

      goto 是本人第二爱好的关键字.  可以在脚下函数内跳转. goto 能够代替全部循环.

     

    Pelles C 编写翻译器能够完全协助 restrict.

    解释:

    再有十分久从前利用union 达成内部存储器字节对齐, 太多了. 种种首要字用法, 确实超级多, 很意外.

      注解变量修饰符, 可变的. 当变量后面有其意气风发修饰符. 编译器不再从存放器中取值, 间接内存读取写入. 保证实时性.

    演示:

      证明变量的时候用!长整型 x86上四字节, x64上8字节. 一定不如int字节数少.  C99今后现身long long类型8字节.

    到这里C89保留的首要字基本解释实现.

    19) extern

      那些是空关键字. 用法非常多. 也是自个儿最欢跃的重视字. 用在函数注明中, 类型定义中.

    解释:

    #define _INT_CNT (10)
    
    int i = -1;
    while(++i < _INT_CNT) {
         // ...... 
    }
    

    演示:

     

     

    在工程项目开辟中引入用 

    for(;;) {
       // 符合条件跳转
       if(six == 6)    
           break;
    }
    
    
    // break 跳出while循环
    int i = 0;
    while(i < 6) {
       if(i == 3)
          break;
    } 
    

    解释:

     

    总的来讲, 学习C 最佳的阳台便是 *nix 平台上利用 Best new GCC. 当然除了科学总括会用到复数, 其余少之又少.

    #include <stdio.h>
    
    char c;
    c = getchar();
    rewind(stdin);
    printf("c = %d, c = %c.n", c);
    

    演示:

    和_Complex有重叠.

    而在VS 中贯彻具体为

    推荐用 int32_t 和 uint32_t类型开荒. 方便移植

    21) case

    17) register

    演示:

    永不用生命周期停止的变量, 存在各个意外. 

    演示:

    演示:

    推荐使用 int16_t or uint16_t 类型.

    44) _Thread_local

    解释:

    诸如大器晚成种用法

     

      获得类型和变量的对齐方式.
    演示:

    // 具体轮询器
    struct srl {
        mq_t mq;                 // 消息队列
        pthread_t th;            // 具体奔跑的线程
        die_f run;               // 每个消息都会调用 run(pop())
        volatile bool loop;      // true表示还在继续 
    };
    
    double d = 2e13;               // 8字节
    long double ld = -0.99;        // x86也是8字节, 不推荐这么用
    long long double lld = 99;     // 写法错误, 不支持
    

    解释:

    3) int

    #include <unistd.h>
    
    do {
        int rt = write(fd, buf, sizeof buf)
        if(rt < 0) {
           switch(errno) {
           case EINTER
               continue;
           default:
               perror("write error");
           }
        }
    } while(rt > 0);
    
    // 声明普通类型
    typedef void * list_t;
    
    // 声明不完全类型, 头文件中不存在struct tree
    typedef struct tree * tree_t;
    

     

    break用法首要和循环一块使用, 还会有do while. 但不能不跳转当前层循环. 

    解释:

     

    聊天一点, 程序开垦最常遭逢的正是自解释难题. 鸡生蛋, 蛋生鸡. 前边再分析signed 和 unsigned

    printf("alignof(struct per) = %zd.n", alignof(struct per));
    

      图片 1

    解释:

    解释:

     

    // 修饰全局变量, 只对当前文件可见
    static int _fd = 0;
    
    // 修饰局部变量, 存储在全局区, 具有记忆功能
    {
        static int _cnt = 0;
    }
    
    // 修饰函数, 函数只能在当前文件可见
    static void * _run(void * arg) {
       ......
       return arg;
    }
    
    //
    // C99之后加的static新用法, 编译器优化
    // static 只能修饰函数第一维,表示数组最小长度, 方便编译器一下取出所有内存进行优化
    //
    int sum(int a[static 10]) { ... }
    
    // extern 主动声明, 希望外部可以调用
    extern int kill(int sig, int val);
    
    // extern 缺省,不推荐外部调用
    int kill(int sig, int val);
    

     

    33) _Bool

     

    解释:

    // 普通定义
    union type {
        char c;
        int i;
        float f;
    };
    
    union type t = { .f = 3.33f };
    
    // 匿名定义
    union { ... } t = { .... };
    
    // 类型匿名定义
    struct cjson {
        struct cjson * next;     // 采用链表结构处理, 放弃二叉树结构, 优化内存
        struct cjson * child;    // type == ( _CJSON_ARRAY or _CJSON_OBJECT ) 那么 child 就不为空
    
        unsigned char type;      // 数据类型和方式定义, 一个美好的意愿
        char * key;       // json内容那块的 key名称     
        union {
            char * vs;    // type == _CJSON_STRING, 是一个字符串     
            double vd;    // type == _CJSON_NUMBER, 是一个num值, ((int)c->vd) 转成int 或 bool
        };
    };
    

    12) signed

     

     

    unsigned int i = 0;          // 正确
    unsigned short s = 0;        // 正确
    unisgned float f = 0.11f;    // 错误
    

    34) _Complex

     

    // 声明不可修改的量
    const int age = 24;
    
    // 修饰指针
    const int * pi = NULL;         // *pi 不能修改指向变量
    int * const pt = NULL;         // pt 不能指向新的指针 
    const int * const pc = NULL;   // *pc 和 pc 都不能动
    

      编写翻译器时期断言, 当 #if #error 搞实现(预编译)之后, 编写翻译器断言. assert是运作时断言.用的时候看现实的须要.
    演示:

    解释:

     

    38) _Alignas

    18) static

    语义上正是线程的私家变量.

      for 循环其实正是while循环的语法糖. 也可能有独出心裁的地点.

    演示:

    -> C11新扩充关键字

    26) for

    宏泛型真的很给力. 宏又能玩上帝了.

    //
    // flag_e - 全局操作基本行为返回的枚举, 用于判断返回值状态的状态码
    // >= 0 标识 Success状态, < 0 标识 Error状态
    //
    typedef enum {
        Success_Exist    = +2,           //希望存在,设置之前已经存在了.
        Success_Close    = +1,           //文件描述符读取关闭, 读取完毕也会返回这个
        Success_Base     = +0,           //结果正确的返回宏
    
        Error_Base       = -1,           //错误基类型, 所有错误都可用它, 在不清楚的情况下
        Error_Param      = -2,           //调用的参数错误
        Error_Alloc      = -3,           //内存分配错误
        Error_Fd         = -4,           //文件打开失败
    } flag_e;
    
    // 普通结构体定义
    struct node {
        int id;
        struct node * next;   
    };
    
    struct node node = { 1, NULL };
    
    // 匿名结构定义
    struct {
       int id;
       char * name;   
    } per = { 2, "王志" };
    

      条件分支语句. 很复杂的if else if 时候能够switch.

      那么些相比叼, C的泛函机制. 高等函数宏. 下边来个老套路用法
    演示:

    解释:

    41) _Generic

      修饰函数,相对不会有重返值. _Noreturn 证明的函数不会再次来到. 引入此新的函数修饰符有两个目标:

      定义结构体, 这些主要字用法广泛, 是大头. c 的首要思路便是面向进度编制程序. 撑起面向进度的金锭就是构造体.

    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ABS(x) 
            _Generic((x), int:abs, float:fabsf, double:fabs)(x)
    
    //
    // 测试 C11 语法
    //
    int main(int argc, char * argv[]) {
    
            int a = 1, b = 2, c = 3;
    
            _Generic(a + 0.1f, int:b, float:c, default:a)++;
            printf("a = %d, b = %d, c = %dn", a, b, c); 
    
            printf("int abs: %dn", ABS(-12));
            printf("float abs: %fn", ABS(-12.04f));
            printf("double abs: %fn", ABS(-13.09876));
    
            return EXIT_SUCCESS;
    }
    
    extern void *mempcpy (void *__restrict __dest,
                          const void *__restrict __src, size_t __n)
         __THROW __nonnull ((1, 2));
    

    将c 数组以 struct per 对齐格局对齐重返回去.

    #include <math.h>
    #include <stdio.h>
    #include <complex.h>
    
    //
    // 测试 c99 complex 复数
    //
    int main(int argc, char * argv[]) {
    
        float complex f = -1.0f + 1.0if;
        printf("The complex number is: %f + %fin",crealf(f), cimagf(f));
    
        double complex d = csqrt(4.0 + 4.0i);
        printf("d = %lf + %lfin", creal(d), cimag(d));
    
        return 0;
    }
    

      到此处快扯完了, 其实C11行业内部是个很好的尝试. 为C引进了线程和原子操作. 种种安全特点补充. 能够说C强大了.

      跳过此番循环. 直接开展规范剖断操作. for 和 while 某些局别. for 会推行第一个前面包车型地铁语句.

    解释:

    char short int unsigned
    long float double struct
    union void enum signed
    const volatile typedef auto
    register static extern break
    case continue default do
    else for goto if
    return switch while sizeof

    35) _Imaginary

    // 声明引用全局变量
    extern int g_cnt;
    
    // 声明引用全局函数
    extern int kill(int sig, int val);
    

    演示:

    10) void

    6) float

      switch 分支的暗中同意分支, 假若case都并未有进去那就走入default分支. default 能够轻巧break. c 语法中可行.

    演示:

    uint32_t 
    skynet_queryname(struct skynet_context * context, const char * name) {
        switch(name[0]) {
        case ':':
            return strtoul(name+1,NULL,16);
        case '.':
            return skynet_handle_findname(name + 1);
        default:
            skynet_error(context, "Don't support query global name %s",name);    
        }
        return 0;
    }
    

    本文由3983金沙网站在线平台发布于母婴,转载请注明出处:C核心 那些个关键字

    关键词: