« 2011年7月 | トップページ | 2011年10月 »

2011年8月の2件の記事

Panasonic「ビストロ(NE-R3400)」レシピ総選挙

以前、こちらの記事でPanasonic スチームオーブンレンジ「ビストロ NE-R3400」のレシピ開発を紹介しました。いよいよレシピコンテンスト(AKB風にレシピ総選挙)が開始したようです。しかも投票した方から抽選でビストロ(NE-R3400)が当選するそうなPanasonicさん太っ腹です。

O0179017611402824618_2

妻の投稿したレシピもあります。(ブログはこちら
気に入りましたら是非ご一票ください。

077番:アジアン☆エスニック親子丼

Recipe_img_077

鶏肉と玉ねぎを使ったエスニック風な親子丼(ワンプレートメニューって言った方が良いんかな?)です。10分強で1食が出来てしまう上に、短時間レシピとは思えない味わいにベトナム料理好きとしては、すっかり気に入りました。
また一緒に添えてある焼き卵(卵焼きちゃうよ)が絶品!これは単独でグリルでもできるので何かに使えるんやないかなぁ。ワンポイントにも書いてあるけど、エスニックが苦手な方はソースを別の物に変えても良いと思うのです。醤油、酒、みりん、砂糖、お酢でソースを作ると、和風な甘辛味になるかな。

ところで、エスニック親子丼と一緒に飲むのはやっぱり
333_3 そう、別名サイゴンレッドとも言われる(ビンの方だけかも?)、その名も”バーバーバー”
ベトナムでは数字のバーと言うのです。333だからバーバーバー。日本語やったら「さんさんさん」...この絶妙なネーミング...
いやぁ、このビール癖がなくて美味しいんですよ。

ちなみにベトナムの数字は

1(モッ)
2(ハイ)
3(バー)
4(ボン)
5(ナム)
6(サウ)
7(バイ)
8(タウ)
9(チー)
10(ムオイ)
0(ホン)

です。
日本語で言う「カンパーイ」ってやつは、「モッ・ハイ・バー・ヨー」と言います。
ビアホイ(日本のビアガーデンみたいな所)行くと、あちらこちらで「モッ・ハイ・バー・ヨー!」。
何かあるとすぐに「モッ・ハイ・バー・ヨー!」なのです。
日本語で言うと「1・2・3・ヨー!」なわけです。
あちらに言ったら是非使ってみてください。

【C/C++】 2次元配列の引数渡し

今日、ふと悩んだ2次元配列を関数引数で渡す方法。
やりたいのはつまり...

static void sub_func( ☆ )
{
    /* ここで2次元配列A[5][3]の各要素をA[x][y]のように読み書きする */
}
void func( void )
{
    int A[5][3];
    sub_func( A );
}

という事。
問題となるのは「☆」の部分をどのようにすれば良いのか?
いくつか方法を思いつきますね。

1. static void sub_func( int* a )

これはあくまで2次元配列の先頭アドレスをポインタ変数として受け取る形。この形式で渡すと2次元配列を格納したメモリにアクセスする事はできるけど、2次元配列である情報が渡らない。つまりA[x][y]のような形式でアクセスできない。
よく見かけるコートは、この方法でアドレスを渡して、その後中の要素番号を計算しつつアクセスする方法。でもそれじゃコンパイラの恩恵は得られないし、第一エレガントじゃない。

2. static void sub_func( int** a )

これは間違い。コンパイルできない。Aはあくまで[5][3]要素を持った2次元配列の名前であってポインタポインタで指定できるかどうか知ったこっちゃない。というかポインタポインタではない。

3. static void sub_func( int a[] )

当然これも間違い。引数は1次元配列を期待している。

4. static void sub_func( int* a[] )

一見よさげに見えるけど(実は最初こう記述してしまった)これも誤り。これだとint型のポインタ変数の配列が渡される事を期待する。2次元配列はポインタ配列では管理されていない。

5. static void sub_func( int a[5][3] )

これが正解。要素数が固定であれば、直感的にも分かりやすい。注意点としてC言語ではスカラ型データであれば値渡し(値がコピーされる)になるけど、配列の場合は無条件で先頭アドレスの参照渡しになる事。ちなみに最初の次元数は省略できる。つまり

static void sub_func( int a[][3] )

という記述も許される。2次元配列の場合2次元目の数が分かれば1次元目のインクリメントが何バイト単位かが計算できるから。

6. static void sub_func( int (*a)[] )

実はこれも正解。4との違いは括弧の位置。これが正解である事を認識するのにちょっと手間取った。

6番目が正解な理由は1次元配列を考えてみると簡単。

static void sub_func( int a[] )
static void sub_func( int *a )

この2つは呼び出し側としては等価になる。C言語の規約では配列を指定した場合には無条件で参照渡しになるから。ちなみに正確に言うと受け側での意味は異なる。前者は配列を受け取ったが、後者は配列が格納されている先頭アドレスをポインタ変数で受け取っている。これは「a = 数値」といった代入文が前者では記述できず、後者で記述できる事から分かる。後者の場合、スタック上に確保されたaというポインタ変数に呼び出し側配列が記録されているメモリの先頭アドレスが記録されるから。通常は受け側で同じ使い方をするなら同じコードが出力されるけど、コンパイラによっては前者の方が効率が良いかもね。

ちょっと脱線した。
さて、上記の2行を見れば分かるとおり、C言語の呼び出し側にとって「a[]」と「*a」は等価になる。つまり先の2次元配列「int a[][3]」は「int (*a)[3]」と等価であると言える。

では上記3がなぜダメなのか。もうお分かりでしょう。「int *a[3]」と「int (*a)[3]」は異なる。前者は「int型のポインタ変数が3つからなる配列」であるのに対して後者は「int型3つからなる配列の配列の先頭アドレスを格納したポインタ」(配列が2重になっているのはタイプミスではないですよ)という事。

やっぱりC言語のポインタは奥が深い...

« 2011年7月 | トップページ | 2011年10月 »