📜  C99编程语言简介:第二部分

📅  最后修改于: 2021-05-26 01:36:16             🧑  作者: Mango

在本文中,我们将发现对C89的一些更有趣的添加,这些添加为我们提供了C99标准:

  1. 可变参数列表: C99对预处理器进行了一些小的更改。宏可以接受可变数量的参数。这些宏在其声明中用省略号(…)表示。这些变量参数由内置的预处理程序标识符__VA_RAGS表示
    #include 
    #include 
      
    #define compare(compfunc, ...) compfunc(__VA_ARGS__)
      
    int main()
    {
        // Here compare(strlen, "one")
        // transforms to strlen("one")
        printf("Length is %lu\n",
               compare(strlen, "one"));
      
        // compares variable arguements
        printf("String Comparison Result: %d\n",
               compare(strcmp, "one", "one"));
      
        return 0;
    }
    
    输出:
    Length is 3
    String Comparison Result: 0
    
  2. _Pragma运算符: C99通过使用运算符_Pragma来指定编译指示实现。

    句法:

    _Pragma("directive")
    
    directive is the pragma being called.
    

    _Pragma运算符可帮助编译指示参与宏替换。

    一些内置的编译器是:

    Pragma Meaning
    STDC FP_CONTRACT ON/OFF/DEFAULT If STDC FP_CONTRACT is on then the floating point numbers are treated as indivisible units handled by hardware based methods.
    STDC FENV_ACCESS ON/OFF/DEFAULT STDC FENV_ACCESS ON pragma tells the compiler that the floating point environment might be accessed.
    STDC CX_LIMITED_RANGE ON/OFF/DEFAULT STDC CX_LIMITED_RANGE ON tells the compiler that certain formulas invoking complex values are safe.

    这三个宏很少使用。此功能解决了“ #pragma”的一个主要问题:作为指令,它不能作为宏扩展的结果而产生。

    修改了一些内置C89宏,并添加了新的宏,例如__STDC_HOSTED__,__STDC__VERSION,__STDC_IEC_559 __(支持浮点算术),__STDC_IEC_599_COMPLEX __(支持复杂算术),STDC_ISO_10646 __(给出了指定日期)。

  3. 循环内部的变量声明:在C89标准中,必须在代码初始化之前声明循环变量。但是在C99中,我们可以在循环初始化部分声明循环变量。在for循环中声明的变量将是该循环的局部变量。
    #include 
      
    int main(void)
    {
        // declare variable i at initialization
        int n = 5;
        for (int i = 0; i < n; i++)
            printf("%d ", i);
    }
    
    输出:
    0 1 2 3 4
    

    在这里,i的范围仅在循环内。

  4. 复合字面量:复合字面量是表示给定类型对象的数组,结构或联合表达式。

    例子:

    int *a = (int[]){11, 12, 13}

    上面的表达式创建一个指向a的整数的指针,该整数指向由三元素组成的整数值数组的第一个。

    通常通过指定括号类型名称,然后在大括号之间加上初始化列表,来创建复合字面量,如上所示。

    在文件范围内创建的复合字面量在整个程序中都存在。如果在块内创建的复合字面量将在离开该块时被销毁,即,复合字面量在该块内部是本地的,但在该块外是未知的。

    #include 
      
    int main()
    {
        int* a = (int[]){ 11, 12, 13 };
        for (int i = 0; i < 3; i++)
            printf("%d ", a[i]);
    }
    
    输出:
    11 12 13
    
  5. 灵活的数组结构成员: C99允许将未调整大小的数组指定为结构的最后一个成员。这些其他元素应在未调整大小的数组元素之前声明。这些大小将在以后使用malloc()动态分配。

    下面的示例程序演示了灵活数组结构的用法。

    #include 
    #include 
      
    struct GFG {
        int a;
        int arr[];
    };
      
    struct GFG* p;
      
    int main()
    {
        // Here arr will be instantiated
        // as a[10] as we use
        // sizeof(GFG)+10*sizeof(int)
        p = (struct GFG*)malloc(
            sizeof(struct GFG)
            + 10 * sizeof(int));
      
        // Results 0 as every element
        // will be set to zero
        printf("%d\n", p->arr[0]);
    }
    
    输出:
    0
    
  6. 数组中的指定初始化: C99标准有助于在声明过程中初始化数组的某些元素。此功能主要对处理稀疏数组的程序员很有帮助。

    下面的程序显示了数组上的指定初始化。

    #include 
      
    int main()
    {
        // initializes index 0 and 1 in a[5]
        int a[5] = {[0] = 100, [1] = 200 };
      
        for (int i = 0; i < 5; i++)
            printf("%d ", a[i]);
    }
    
    输出:
    100 200 0 0 0
    

    我们还可以按以下方式在结构中使用此指定初始化:

    #include 
      
    struct GFG {
        int a;
        int b;
        int c;
      
        // initializes a and c
        // of structure object ob
    } ob = {.a = 1, .c = 20 };
      
    int main()
    {
        printf("The values of a and c"
               " in struct GFG are %d %d",
               ob.a, ob.c);
    }
    
    输出:
    The values of a and c in struct GFG are 1 20
    
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。