カフェブロトップへ
注目キーワード  コンビネゾン スパンコールカーデ / 【今週のプレゼント】しっとり!ハンドクリーム

プログラマーの独り言

コンピュータ・ソフトウェアのプログラミングに関して調査したことや思ったことを綴ります。

<< 2012年3月 >>
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
最新記事
最新コメント
最新トラックバック
リンク集
関数形式マクロでの引数省略
関数形式マクロでは、引数の省略も可能。

その場合、マクロ呼び出しでの実引数の数は、
マクロ定義内の省略記号(...)を除く仮引数の数よりも
多くなければならない。

識別子__VA_ARGS__が省略された引数を表す。
__VA_ARGS__は、仮引数に省略記号を用いる関数形式マクロの
置換要素並びの中だけで使用可能。

例:
/*
    ex_define_va.c
*/
#include <stdio.h>  /* printf */
#include <stdlib.h> /* EXIT_SUCCESS */

#define DBG(...) (fprintf(stderr, __VA_ARGS__))

int main(int argc, char *argv[])

    int x = 100;

    DBG(”x:%d\n”, x);

    return EXIT_SUCCESS;

2010年3月18日(木) 07:18 [ C言語 ]
この記事のURL / /
マクロの再定義の実験
マクロの再定義を実験してみた。

自分の環境では、
再定義可能のパターンではコンパイルがとおり、
再定義不可のパターンでは、warning: "OBJ_LIKE" redefined 等のワーニングが出た。

以下、プログラム。(表示都合上全角)

/*
    define_test.c
*/
#include <stdio.h>  /* printf */
#include <stdlib.h> /* EXIT_SUCCESS */

#define OBJ_LIKE (1−1)
#define FUNC_LIKE(a)    ( a )

int main(int argc, char *argv[])

    #define OBJ_LIKE /* コメント */ (1−1) /* コメント */
//  #define OBJ_LIKE (0) // 字句の並びが違う
//  #define OBJ_LIKE (1 − 1) // 空白類が違う

    #define FUNC_LIKE( a ) ( /* 空白類に注意 */ \
                            a /* 一部が別の行
                            */ )
//  #define FUNC_LIKE(a)    ( ’a’ ) // 仮引数の使用法が違う
//  #define FUNC_LIKE(b)    ( b ) // 仮引数のつづりが違う

    printf(”%d\n”, FUNC_LIKE(OBJ_LIKE));

    return EXIT_SUCCESS;

2010年3月18日(木) 06:47 [ C言語 ]
この記事のURL / /
マクロの再定義
C言語の仕様(JISX3010)によると、
オブジェクト形式マクロは条件付きで再定義できる、とある。

その条件は、
2番目の定義がオブジェクト形式マクロ定義であり、
かつ、2つの置換要素並びが同一、
とのこと。

また、関数形式マクロも条件付きで再定義可能だそう。

その条件は、
仮引数の個数とつづりが最初の定義と同一な関数形式マクロ定義、
かつ、2つの置換要素並びが同一。

置換要素並びとは、

#define MAX 100

でいうと、100と記されている部分のこと。

また「2つの置換要素並びは、その前処理字句列の個数、順序、
つづり及び空白類による区切り方が同じ場合、そしてその場合に限り、同一の並びとみなす。ただし、空白類による区切りは、いずれも同じものとみなす」とある。

そして、次のような例が挙げられている。

次の再定義は正しい。
#define OBJ_LIKE    (1−1)
#define OBJ_LIKE    /* 空白類 */ (1−1) /* その他 */
#define FUNC_LIKE(a)    ( a )
#define FUNC_LIKE( a ) ( /* 空白類に注意 */ ¥
                   a /* 一部が別の行
                      */ )


次の再定義は正しくない。

#define OBJ_LIKE    (0) // 字句の並びが違う
#define OBJ_LIKE    (1 − 1) // 空白類が違う
#define FUNC_LIKE(b)    ( a ) // 仮引数の使用法が違う
#define FUNC_LIKE(b)    ( b ) // 仮引数のつづりが違う

2010年3月17日(水) 21:58 [ C言語 ]
この記事のURL / /
defineとは
C言語のdefineについて調べてみた。
結果をまとめると以下のとおり。

defineとは、プリプロセッサ指示のひとつで文字列を別の文字列に置き換えることができるもの。この機能はマクロ置換と呼ばれる。

使用例:
#define MAX 100

この定義以降のプログラムでは、コンパイル時にプリプロセッサによりMAXが100と変換されてからコンパイルされる。
このようなマクロ置換をオブジェクト形式マクロと呼ぶ。

プリプロセッサとは、コンパイル前の準備的な処理を行うソフトウェアのことである。

マクロ置換は引数を取ることもできる。

使用例:
#define RND(x) (rand()%(x+1))

このケースではRND(9)は0〜9までの乱数となる。
このようなマクロ置換を関数形式マクロと呼ぶ。

関数形式マクロは、引数の型が固定されない、関数呼び出し時のオーバヘッドがない等、関数よりも便利な面がある。
反面、マクロ使用時のパラメータでインクリメントやデクリメントを行うと、それが複数回行われるケースがある等、不具合を発生させる危険もある。そのため、関数形式マクロの使用には注意が必要である。

参考ページ:C言語のdefineについて
2010年3月17日(水) 21:02 [ C言語 ]
この記事のURL / /


プロフィール
ユニオン
カテゴリアーカイブ
月別アーカイブ
日別アーカイブ
cafebloトップへ
ブログ管理画面へ