C语言中一些不被熟知的特性

designated initializers(c99)

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

struct Foo {

int x;

int y;

int z;

};

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

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

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

int a[5] = {[1] = 2, [4] = 5};

int a[] = {[1] = 2, [4] = 5};

int a[5] = {0, 2, 0, 0, 5};

restricted pointers(c99)

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

int f(const int* restrict x, int* y) {

    (*y)++;

int z = *x;

(*y)--;

return z;

}

会被编译器优化为

int f(const int* restrict x, int* y) {

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,'\r',b,'\r');

    else return a!=0?a:b;

}

int main(){

    int A = 0, B = 0;

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

    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!\n");#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 x = 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;} 且都能编译通过(其实就是预处理器- -)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Albert陈凯

Scala集合练习题

//创建一个List val list0 = List(1,7,9,8,0,3,5,4,6,2) //将list0中每个元素乘以10后生...

47590
来自专栏PHP在线

php的字符串常用函数

1. str_word_count 统计单词个数 2. count_chars 得到字符串里面字符的有关情况 3. str_len 得到字符串长度,就是...

48260
来自专栏python全栈布道师

2017年8月28日技术日记

43260
来自专栏HansBug's Lab

1798: [Ahoi2009]Seq 维护序列seq

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 2930...

31150
来自专栏王小雷

Python之NumPy实践之数组和矢量计算

Python之NumPy实践之数组和矢量计算 1. NumPy(Numerical Python)是高性能科学技术和数据分析的基础包。 2. NumPy的nda...

26480
来自专栏GIS讲堂

面向对象的三个基本特征

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

19530
来自专栏mukekeheart的iOS之旅

No.015 3Sum

15. 3Sum Total Accepted: 131800 Total Submissions: 675028 Difficulty: Medium   G...

24480
来自专栏mathor

KMP(1)

11930
来自专栏伪君子的梦呓

题解~按照特定的格式输出~C++做法

一共三行,第一行:位数 第二行: 用空格分开的每个数字,注意最后一个数字后没有空格 第三行: 按逆序输出这个数

5740
来自专栏分布式系统和大数据处理

C#理解泛型(译)

Visual C# 2.0 的一个最受期待的(或许也是最让人畏惧)的一个特性就是对于泛型的支持。这篇文章将告诉你泛型用来解决什么样的问题,以及如何使用它们来提高...

8530

扫码关注云+社区

领取腾讯云代金券