Programmers Room Tips集 C/C++言語編 更新[2002.06.12]

Contents

1.バウンダリ調整について [C/C++ 1999.8.11]
2.コマンドライン引数の取得 [C/C++ 1999.10.10]
3.区切り文字で区切られた文字列を分離する [C/C++ 2000.04.17]
4.C++クラスの派生にメンバおけるアクセス特権一覧 [C++ 2002.06.16]

 

・・・初心者
・・・中級者
・・・上級者

1.バウンダリ調整について [C/C++ 1999.8.11]

バウンダリに付いて、まず、「バウンダリ」って何だかわかりますか?わかる人は読み飛ばしましょう。

バウンダリとは、OSの処理ビット数に対して、構造体を最適化すること(?)なのですが、実際はコンパイルオプションで設定可能ですが、通常はOSに依存することになります。

Windows95やNT4.0は32ビットOSなので、基本的にバウンダリは4バイトで設定されます。構造体を定義した場合、原則的には4バイト毎に境界が存在し、その境界をintやshort,WORD,DWORDはまたぐことが出来ないのですが、それでもまたいでしまった場合コンパイル時に自動的に調整が入ってしまいます。

例えば:

typedef struct{
   char szData[3];
   
long nCount;
   
char cFlag;
 }TMyData;


という構造体があった場合、intやshortのように複数バイトで構成される値は4バイトの境界をまたぐことが出来ないので実際は

typedef struct{
   
char szData[3];
   <ここに1バイト>
   
long nCount;
   
char cFlag;
   <ここに3バイト>
 }TMyData;


のように、コンパイル時に補正が入ってしまいます。
構造体をメモリ上で使用する際には、補正は見えないし、メンバに直接アクセスして問題ないのですが、実際は補正値が入りますので、
 sizeof(TMyData)
は8バイトではなく、12バイトになりますので、ファイルに書きこむときに、書きこみサイズを直値で8とか指定するとバグ発生です。sizeofで指定すればまちがいありません。...しかし

現在では便利なファイル管理クラスがあるせいか、理由は定かではありませんが、あまりバイナリでファイルを管理しなくなってきています。
かつて現場の良識ある(?)プログラマの皆さんは、気持ちが悪いのか、自分の知らないところで勝手に構造体をいじられるのが嫌なのか、ダミー値を入れて、あらかじめバウンダリ調整が入らないように調整したものです。また、ダミー値を入れなくても並べ順を変えればある程度何とかなるものです。上記の例はわかりやすくするためにこのように書いていますが、実際は

typedef struct{
   
char szData[3];
   
char cFlag;
   
long nCount;
 }TMyData;


とすれば問題無いわけです。

 

2.コマンドライン引数の取得  [C/C++ 1999.10.10]

初心者の方のために、念のためCまたはC++における標準的なコマンドライン引数の取得方法を記述しておきます。

まずメインを以下のように定義します。

int main(int argc, char * argv[])
(↑戻り値はintである必要は無い)

argcには引数の数
argvにはコマンドライン引数が設定されます。(コマンドラインの文字列を指すポインタの配列といったほうが正しい)

例として、APP.EXEという実行ファイルに

APP /A123 ABC

のようにコマンドライン引数を設定した場合argcには3が設定されます。(実行ファイル名を含む)

arcv[0]には "APP.EXE"
argv[1]には "/A123"
argv[2]には "ABC"
argv[3]には NULL がそれぞれ設定されます。

 

 

3.区切り文字で区切られた文字列を分離する  [C/C++ 2000.04.17]

strtok()を使用します。

どのように使用するのかというと、例えば、CSV形式のファイルのように「一行1レコード、各項目はカンマで区切られる」というものから各項目を取り出すことを考えます。

"<名前>,<住所>,<ID番号>"
という文字列からそれぞれの要素を取り出すプログラムを書いてみましょう。

      // それぞれの要素を格納するポインタ
      char *pName, *pAddr, *pId;
     
// 元の文字列
      char szBuff[
30] = "Takagi,Kanagawa,1234";
       
      pName = strtok(szBuff, "
,");// szBuffを,区切りで先頭文字列取得
      pAddr = strtok(NULL, "
,");  // 同じ文字列で続行する場合NULLを
      pId   = strtok(NULL, "
,");  // 指定。


pNameは、"Takagi"
pAddrは、"Kanagawa"
pIdは  "1234"
にそれぞれ設定されます。

また、区切り文字は、複数指定することも、毎回変更することも出来ます。複数指定した場合は、OR条件となり、「いずれかが発見された」場合に区切られます。
  
上記実行後はszBuffの中身は原型を留めません。カンマが存在した位置は\0が設定されます。szBuffを表示してみると、"Takagi"となります。ようするに、「一つずつ取り出して複写する」のではなく、「分離する」のです。

 

4.C++クラスの派生にメンバおけるアクセス特権一覧 [C++ 2001.06.16]


以下の表のようになります。
分かりにくい方は、表の左から順に右に向かって以下のように読むと良いでしょう。

例えば一行目なら、
基本クラスでのアクセスがパブリックの変数は、パブリックで継承された派生クラスでは、パブリックの扱いになる

なお、表で「アクセス権無し」とあるところは、基本クラス内でフレンド宣言を行うと、アクセスが明示的に許可されます。

基本クラスでのアクセス 基本クラスからの継承 派生クラスでのアクセス
パブリック パブリック パブリック
プロテクト プロテクト
プライベート アクセス権なし
 
パブリック プロテクト プロテクト
プロテクト プロテクト
プライベート アクセス権なし
 
パブリック プライベート プライベート
プロテクト プライベート
プライベート アクセス権なし

[TOPへもどる] [Soft Page TOPへもどる] [ProgramerS Room Topに戻る]  [このページのTop]