1. 程式人生 > >C語言中一些很酷的技巧(cool tricks)

C語言中一些很酷的技巧(cool tricks)


1.  #if 0 ...... #endif 塊中的內容不會被編譯,因為註釋不允許巢狀,我們可以把暫時不用的程式碼塊放在
這裡面。
2. 陣列初始化的時候可以指定索引,而且可以給特定範圍的陣列賦值。
比如  int array[] = { [0 ... 9] = 1, [10 ... 20] = 2, [30 ... 40] = 3};
等價於    int array[] = { 1, 1, 1, 1, ..... 2, 2, 2 ...... 3, 3, 3};
示例:
#if 0

here will not enter into compile
we can move the code we not need now here

#endif

#include<stdio.h>

int  main(){
    int i = 0;
    int arr[] = {[1]=5, [5]=10, [2]=20};
    int arr2[] = {[0 ... 9] = 10, [10 ... 19] = 20, [20 ... 29] = 30};
    for(i = 0; i < 6; i++)
        printf("arr[%d] = %d ,", i, arr[i]);
    printf("\n");
    for(i = 0; i < 30; i++)
        printf("arr2[%d] = %d ,", i, arr2[i]);
    return 0;
}

3. 要巧妙使用scanf,支援正則式,而且可以超越每次讀到空白就終止的限制。
示例:
#include<stdio.h>
#define MAX 100

int  main(){
    int i = 0;
    char s1[MAX],s2[MAX];

    //scanf("%[^\n]\n",s1);
    //read till meet '\n',and then trash the \n
    
    //scanf("%[^,]",s1); //?? also will  trash the coma
    //scanf("%[^,],",s1); // this does not trash the coma
    
    //this * can make us skip some input
    //for example,we just care the last-name
    scanf("%*s %s",s1);

    printf("%s\n",s1);



    return 0;
}

4. 理解offset巨集定義,求一個成員在結構體中的偏移量。
示例:
#include <stdio.h>
#include <stdlib.h>

#define offset(TYPE, MEMBER) ((size_t)(&((TYPE *)0)->MEMBER))

int main(){
    struct test{
        int a;
        int b[4];
        int c;
    };  
    
    printf("offset a : %lu\n", offset(struct test, a));
    printf("offset b : %lu\n", offset(struct test, b));
    printf("offset c : %lu\n", offset(struct test, c));

    struct test *t = (struct test *)0;
    printf("%d\n", &(t->c));  // right
    printf("%d\n", t->c);  //?but cannot do this, core dump
    

    return 0;
}

5. s[i] 是 *(s + i) 的語法糖,所以等價於 i[s]。
 示例:
#include <stdio.h>

int main(){
    char s[] = "vonzhou";
    printf("%c\n", 2[s]);   

    return 0;
}

6. 再次是printf 和 scanf 的技巧。
#include <stdio.h>

int main(){
    
    int n = 6;
    int val = 1000;
    char s[100];
    printf("%*d", n, val);// with a minimum width of n,default right aligned    
    printf("hello\n");

    //scanf("%*d");//read an integer and ignore it

    //scanf has regex built into it
    //read only selected chars into a string
    //scanf("%[abcd]s", s);

    
    //read everything excepted heading with abcd
    //scanf("%[^abcd]s" ,s);

    /* some complain that scanf reads upto a whitespace, 
    so this trick can be used to consume everything upto a newline */
    scanf("%[^\n]s", s); 
    // reads all chars (including whitespaces) till newline is encountered.

    printf("s = %s\n", s); 
    /* Another trick with scanf is to consume what is required. 
    For example - If  a user enters his date of birth in YYYY-MM-DD 
    then you can directly read the year month and date into integer variables */
    //scanf("%d-%d-%d", &yy, &mm, &dd); 
    /* where yy, mm, dd are variables.
    Note that this will work only with that format of input. 
    Anything else like YYYY/MM/DD,and the program will mostly crash. 
    You specify a hyphen, it expects only a hyphen! */

    return 0;
}

7.利用scanf的返回值來識別是否到達檔案尾EOF;當errno=0時%m格式會輸出“Success”;brk(0)可以作為 return 0 的替代;