̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ IT ニュース&コラム 2014/ 4/14 通巻659号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ アドレスに &演算子を強制するな(1) - リーダブル・コード(21) C言語で変数を宣言すると、その変数の値を格納するためのメモリーの場所が決まり ます。 メモリーは、16進数の 0x00〜0xFF(10進数では 0〜255)の間のどれかの値を 保存できる領域を1つの単位(バイト)とし、そのバイトが大量に並んで いるものです。 それぞれのバイトに対してアドレスと呼ばれる数値が割り当て られています。 メモリーは大きな配列と見ることができ、その配列番号が アドレスと見ることができます。 内部ではメモリーにライトしたりリードしたりする(アクセスする)ときに、 アドレスと呼ばれる数字を使います。 しかし、数字ではどんな意味の数値が バイトに格納されているか分かりにくいので、変数とアドレスの対応関係を C言語のコンパイラーが処理します。 この処理によって、アドレスは不要に なるのですが、周辺機器の内部を制御したり、高速に処理することができる ようになるメリットがあるために、C言語では参照できるようにしています。 ちなみに、アドレスを参照できるようにすると、メリットよりもデメリットの 方が大きいため、C/C++言語以外ではアドレスを参照できないようになっています。 Java の JNI(Java Native Interface)や Google の NaCl(Google Native Client)、周辺機器を制御するブラウザーのAPI、などで提供される 関数の内部で動く、C言語などで作られたバイナリー(ネイティブ)のプログラム の中では、アドレスが使われているのですが、そのプログラムをサンドボックス と呼ばれる保護された領域の中に隔離して実行させることで、システムを 誤って破壊してしまう可能性があるデメリットを発生させないようにしています。 変数のアドレスを参照するときは、&演算子(アドレス演算子)を使います。 変数の前に & を付けると、変数のアドレスになります。 変数のアドレスは、 ポインター変数に格納することができます。 アドレスは数値なので、printf やデバッガーで数値を見ることができます。 int var; int* pointer = &var; printf( "%p\n", &var ); 上記の pointer 変数は、var 変数のアドレスを格納しており、そのアドレスを使って var 変数の内容を変更することもできます。 なぜそれができるのかというと、 上で説明したように、内部ではメモリーにアクセスするときはアドレスが使わ ているからです。 pointer 変数に入っている(var 変数の)アドレスを使って var 変数の内容を変更するときは、*演算子(間接演算子)を付けます。 *pointer = 2; /* var == 2 になる */ pointer 変数も var 変数と同様にメモリーのどこかに配置され、そのアドレス を持っています。 ややこしいですが、pointer 変数のアドレスと、pointer 変数に格納されている(var 変数の)アドレスの違いに注意してください。 この2つは別の値のアドレスですが、どちらもアドレスという種類の値です。 C言語のプログラムのソースを読むとき、変数の前に & 記号が付いていたら それはアドレスであると判断してよいでしょう。 しかし、& 記号が付いて いなくてもアドレスである可能性があります。 たとえば、ポインターに格納 されている値は(var 変数の)アドレスであり、アドレスは数値なので、printf やデバッガーで数値を見ることができます。 printf( "%p\n", pointer ); ポインターは、別の変数にアクセスできるだけでなく、配列のそれぞれの要素に アクセスすることもできます。 まず、普通に配列の要素番号 3 の要素にライトする コードを見てみましょう。 int array[10]; array[3] = 1; ポインターからそれぞれの要素にアクセスするには、 (アドレス)+(配列番号)×(1つの要素のバイト数) の計算をすればできます。 なぜなら、配列のそれぞれの要素はメモリーに並んで いるからです。 この性質が C言語の文法にも取り入れられ、ポインターも配列 と同じように書くことができるようになっています。 つまり、次の1行目と 2行目は、同じ内容のコードになります。 *( pointer + 3 ) = 1; /* 1つの要素のバイト数は暗黙的にかけられる */ pointer[3] = 1; 他にも、ポインターと配列を同じように書くことができる処理があります。 それは、配列のアドレスをポインターに格納するコードです。 つまり、次の1行目と2行目は、同じ内容のコードになります。 pointer2 = array; pointer2 = pointer; 注意してほしいのは、配列のアドレスを参照するときに & 記号が付いていない ことです。 配列の先頭アドレスを参照するときの C言語の文法を、配列変数の [ ] を付けないだけに決められた理由は、ポインターと配列がほぼ同じように 扱えるから同じ書き方にしてポインターと配列をわざわざ識別する必要を なくすためだと思われます。 pointer2 変数も array 変数も同じように配列の 要素にアクセスできるものなのに、& 記号で配列とは別のものであることを 示すような C言語の文法だったら、混乱の元になっていたことでしょう。 配列変数に &演算子を付けると、文法エラーになります。 アドレスには、 & 記号が必ず付いているとは限らない(型からアドレスかどうかを判定する) のですが、それでも、アドレスには & 記号を付けなければならないという コーディング・ルールが存在します。 配列に対して、そのルールを強引に 適用するテクニックを紹介しましょう。 それは、配列の先頭の要素に対して & 演算子を付けることです。 pointer2 = &array[0]; /* address of array */ ただし、このコードは、読む人に誤った情報を提供してしまっています。 それは、pointer2 が配列のアドレスではなく、配列の要素のアドレスで あると読んでしまうため、pointer2 は、配列として扱えないと判断して しまうことです。 つまり、& 記号を必ず付けるコーディング・ルールがあると思われるソースを 読むときは、配列の要素のアドレスが格納されたポインターは、配列への ポインターである可能性があることに注意しながら読まなければならない ということになります。 残念ながら、& 記号を付けることに統一することで、どちらであるかを 識別する情報を失っているため、コードからどちらであるかを判断する ことはできません。 配列のアドレスであることを、コメントに補足して おくとよいでしょう。 注目ニュース 一覧 ◇ Microsoft、9型未満のデバイスにWindows無償化を発表。Windows for IoTも発表。 http://pc.watch.impress.co.jp/docs/news/event/20140403_642657.html … かつて Windows CE が無料になったが、今度は成功するか。 ◇ Microsoft、Windows 8.1 Updateを4月8日に公開。 http://pc.watch.impress.co.jp/docs/news/event/20140403_642651.html http://internet.watch.impress.co.jp/docs/news/20140403_642662.html … デスクトップから Windows ストアアプリへの切り替えが簡単に。 ◇ 次世代USB Type-C、特徴が明らかに。数カ月以内に登場の可能性も。 http://japan.cnet.com/news/service/35046034/ … 今までの USB と互換性が無いことが大きな壁。 ◇ Heartbleedから身を守るには。セキュリティ専門家に聞く。 http://japan.cnet.com/news/commentary/35046375/ … ブラウザーの暗号化通信SSLの古いものを使っているサーバーに注意。 ◇ 空港の詳細図、グーグルから流出。メール 一般公開に。 http://www.asahi.com/articles/ASG4C149LG4BUTIL05C.html … グーグルだけは使うべきじゃない。 ◇ 無料アプリでもう十分? Microsoft Office Online は驚きの充実度。 http://techtarget.itmedia.co.jp/tt/news/1403/28/news06.html … 軽く使う程度なら使えるが、業務に使うには動作が遅すぎる。 ◇ 欧州議会、ネット中立性法案を可決。 http://japan.cnet.com/news/society/35046112/ … 通信経路に流れるライバルのサービスをブロックできないようにする。 ◇ 超日本びいきのOculus VR創設者Palmer Luckey氏インタビュー。 http://game.watch.impress.co.jp/docs/news/20140408_643230.html … こういう人が新しい技術を生む。 ソフトウェアデザイン館 Sage Plaisir 21 ホームページ >>> http://www.sage-p.com/ メルマガ >>> http://www.mag2.com/m/0000083983.html ブログ >>> http://blog.livedoor.jp/sage_p/ ツイッター >>> http://twitter.com/Ts_Neko ダウンロード >>> http://www.sage-p.com/freesoft.htm サポート掲示板 >>> http://www.sage-p.com/kg_ban09/z6037C8.cgi 東日本大震災 >>> http://www.sage-p.com/saigai.html メール >>> ts-neko◇sage-p.com ←◇を@に変えてください 緊急メールは件名に「うどんメール」を付けてください。 このメルマガの登録・解除 - http://www.mag2.com/m/0000083983.htm