C言語のクールなテクニック(cool tricks)

5000 ワード

Quoraから来て、いいと思って、実践しました.
1.  #if 0 ...... #endifブロックの内容はコンパイルされず,凝視がネストに同意しないため,一時的に使用しないコードブロックをここに置くことができる.2.配列初期化時にインデックスを指定でき、特定範囲の配列に値を割り当てることができます.例えばint array[]={[0......9]=1,[10......20]=2,[30......40]=3}int array[]={1,1,1,1,.....2,2,...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("
"); 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("%[^
]
",s1); //read till meet '
',and then trash the
//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
",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
", offset(struct test, a)); printf("offset b : %lu
", offset(struct test, b)); printf("offset c : %lu
", offset(struct test, c)); struct test *t = (struct test *)0; printf("%d
", &(t->c)); // right printf("%d
", 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
", 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
"); //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("%[^
]s", s); // reads all chars (including whitespaces) till newline is encountered. printf("s = %s
", 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の代替とすることができる.
デモの例:
#include <stdio.h>

int main(){
    int n;
    //util reach EOF(ctrl + D) 
    while(~scanf("%d",&n)){
        //logic process
        printf("%d^2 = %d
", n, n*n); } // %m print success only if errno = 0 printf("%m
"); brk(0); }

7.変数は0と1に暗黙的に初期化されます.
デモの例:
<pre name="code" class="cpp">#include <stdio.h>

// ??
// implicit initiliazation of variables with 0 and 1
g;main(i){

    printf("%d,%d
", g, i); return 0; }