C言語

Last-modified: 2011-01-25 (火) 10:26:44

マクロを用いたデバッグ

 デバッグのときには#DEBUGを宣言することで、printfするようにする。
gcc のオプションで -DDEBUG とすると、DEBUG というマクロ変数が定義されるので、これを使っても良い。
例として、以下のマクロを書く。

#ifdef
#define
#else
#define
#endif

表示させる場所では次のように書けばよい

DPRINT("debug message %d\n", i);

gccのエラー・警告

(PDF)GCCのエラーと警告、その対処法

warning: ignoring return value of ‘hogehoge’, declared with attribute warn_unused_result

 戻り値を使用しないと起こる警告。例えば戻り値がintであるfscanf()で起こる。EOFのチェックで回避。

 

以下は次のURL先から引用 http://docs.hp.com/ja/5992-4660/ch02s02.html

warn_unused_result 属性は、この属性が指定された関数の呼び出し元がその戻り値を使わない場合に警告を発するようにコンパイラに指示します。これは、realloc() のように、結果をチェックしないとセキュリティ上の問題やプログラムのバグになる関数で便利です。

次のURL先が詳しい
http://d.hatena.ne.jp/qnighy/20100116/1263647584

fopenのエラー

ファイルシステムの仕様によって2G以上のファイルは読み込み/書き込みすることはできない。
コンパイル時にオプションとして以下を加える。または、Makefileにオプションとして追加する。

-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 

参考URL

<math.h>での定数

http://www.cs.cf.ac.uk/Dave/C/node17.html

enum型とswitch文

enum型を次のように、case(値)の値として使用することができる。

typedef enum {
  BCC,
  FCC,
  HCP
} CrystalStructure;

CrystalStructure eCrystalStructure = xx;

switch (eCrystalStructure) {
 case BCC:
   GenerateBCC();
   break;
 case FCC:
   GenerateFCC();
   break;
 case HCP:
   GenerateHCP();
   break;
 default:
   exit(1);
}

エラーラップ関数の例

ファイルの例 ewrap.h

  • 使用ヘッダファイル
    #include
    #include
    #include
  • void eprintf(char *fmt, ...)
    エラーメッセージを出力する関数
    //eprintf : エラーメッセージを出力する関数
    void eprintf(char *fmt, ...)
    {
      va_list args;
    
      fflush(stdout);
      if(progname() != NULL){
        fprintf(stderr,"%s: ",progname());
      }
    
      va_start(args,fmt);
      vfprintf(stderr,fmt,args);
      va_end(args);
    
      if(fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':'){
        fprintf(stderr,"%s",strerror(errno));
      }
      fprintf(stderr,"\n");
      exit(2);
    }
  • char *estrdup(char *s)
    文字列のコピー.エラー時にはそれを知らせる
    //estrdup : 文字列のコピー.エラー時にはそれを知らせる
    char *estrdup(char *s)
    {
      char *t;
    
      t = (char *)malloc(strlen(s) + 1);
      if(t == NULL){
        eprintf("estrdup(\"%.20s\")failed:",s);
      }
      strcpy(t,s);
      return t;
    }
  • void *emalloc(size_t n)
    mallocし、エラー時にはそれを知らせる
    //emalloc : mallocで、エラー時にはそれを知らせる
    void *emalloc(size_t n)
    {
      void *p;
    
      p = malloc(n);
      if(p == NULL){
        eprintf("malloc of %u bytes failed:",n);
      }
      return p;
    }
  • void setprogname(char *str)
  • char *progname(void)
    プログラム名の設定と、返す関数
    static char *name = NULL;//プログラム名
    
    //setprogname : プログラム名を設定
    void setprogname(char *str)
    {
      name = estrdup(str);
    }
    
    //progname : プログラム名を返す
    char *progname(void)
    {
      return name;
    }

3項演算子

「三項演算子?:の正しい書き方」http://hp.vector.co.jp/authors/VA010341/conditional.html

condition ? true-expression : false-expression
condition ? true-expression
            : false-expression

typedefとstruct

最も誤解の少ない書き方

struct __point{
  double x;
  double y;
};
typedef struct __point Point_t;

Point_t p1,p2;

タグ名と変数リストを定義

typedef struct __point{
  double x;
  double y;
}p1,p2;

タグ名と型名を同時に定義

typedef struct __point{
  double x;
  double y;
}Point_t;

Point_t p1,p2;

型名のみ定義

typedef struct{
  double x;
  double y;
}Point_t;

Point_t p1,p2;
 

参考文献

  • プログラミング作法(Brian Kernighan,Rob Pike,訳 福崎 俊博,2000,アスキー)

参考URL