zoukankan      html  css  js  c++  java
  • C语言中一些不被熟知的特性


    designated initializers(c99)

    C99允许你对结构体中指定的变量初始化,

    struct Foo {

        int x;

        int y;

        int z;

    };

    Foo foo {.z 3, .x 5};

    这其中x会默认初始化为0

    指定初始化也可适用于数组,如下面三个等价的数组定义

    int a[5{[12, [45};

    int a[] {[12, [45};

    int a[5{02005};

     

    restricted pointers(c99)

    限定词restricted用于限定一个指针(如名,告诉编译器该指针的内存访问在任何情况下都只能通过该指针进行,其余指向无效.

    int f(const intrestrict x, inty) {

        (*y)++;

        int z = *x;

    (*y)--;

        return z;

    }

    会被编译器优化为

    int f(const intrestrict x, inty) {

        return *x;

    }

    静态和限制性数组参数(c99)

    void f(int a[static 10]) {

        /* ... */

    }

    传递给f()的指针如果为null或者小于10编译器会warning!

    又如void f(int a[const]) {

        /* ... */

    }

    a不可被修改。

     

    泛型表达式(c11)

    使用X Maroc(http://en.wikipedia.org/wiki/X_Macro),编译器会在compile time选择适当的形式

    #define cbrt(X) _Generic((X), 

                            long double: cbrtl, 

                            default: cbrt, 

                            float: cbrtf 

                            )(X)

    默认形式为cbrt(),如果实参为float就会被替换为cbrtf(),etc.

     

    Switch条件判断case(c11)

    case语句可以出现在if-else结构和循环结构中

    switch (a)

    {

        case 1:;

          // ...

          if (b==2)

          {

            case 2:;

            // ...

          }

          else case 3:

          {

            // ...

            for (b=0;b<10;b++)

            {

              case 5:;

              // ...

            }

          }

          break;

        case 4:

          // ...

          break;

    }

    不使用+号实现加法操作

    #include <stdio.h>

    int add(int a,int b){

        if(a!=0&&b!=0)

            return printf("%*c%*c",a,' ',b,' ');

        else return a!=0?a:b;

    }

    int main(){

        int A = 0, B = 0;

        printf("Enter the two numbers to add ");

        scanf("%d %d",&A,&B);

        printf("Required sum is %d",add(A,B));

        return 0;

    }

    printf()返回值实现,也可以使用bitwise实现

    void返回值的函数体中使用return

    static void foo (void) { }

    static void bar (void) {

    return foo(); // Note this return statement.

    }

    int main (void) {

    bar();

    return 0;

    }

    #include in strange places

    #include <stdio.h>

    void main()

    {

        printf

    #include "fragment.c"        

    }

    ("dayum! ");#text in Fragment.c

    这我也无力吐槽..

    有范围的switch-case(gcc extension)

    switch(c) {

      case 'A' ... 'Z': 

    Doa();

      break;

      case 1 ... 5 : 

    Dob();

    }

    C属于a-z字符时执行Doa();属于1-5时执行Dob();

    编译器通过的最短C语言程序

     main;

    作者没有提到编译环境,虽然我的编译器会报错..

    四个等价

    a [ i ] == * (a + i) == * (i + a) == i [ a ];

     

    古董级键盘福利

    下表左右都是等价的




    于是就出现这样的(:乱码code 

    !E() ??!??! C();

    default替换(C++乱入)

    #include<iostream>

    int main(){

        int 2;

        switch(x){

        case 1:

            cout<<"1";

            break;

        abc1:

            cout<<"2";

        }

    }

    c++ switch-case结构中的default可以被任何标签替换,如上面的abc1


    奇怪的等价

    # 1 "1.c"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "1.c"
    int main(){ return 0;}
    等价于
    #ifdef SOME_MACRO
    void foo (){}
    #endif
    int main(){ return 0;}
    且都能编译通过(其实就是预处理器- -)

  • 相关阅读:
    C—动态内存分配之malloc与realloc的区别
    C++动态内存管理之深入探究new和delete
    Linux粘滞位的设置
    linux—find指令常见用法示例
    Linux系统date命令的参数及获取时间戳的方法
    Linux系统文件的三个重要时间详解
    《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---27
    《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---26
    《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---25
    《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---24
  • 原文地址:https://www.cnblogs.com/ysherlock/p/7822291.html
Copyright © 2011-2022 走看看