• ベストアンサー

[Perl] Pack関数について教えてください。

こんにちは。 下記は、pack関数のサンプルスクリプトですが、 なんでそのような結果になるのか、よくわかりません。どなたか教えていただけますか。 print "文字列を入力してください:"; $string = <STDIN>; chomp ($string); $length = length($string); print "数値を入力してください:"; $number = <STDIN>; chomp ($number); # Do Pack! $packed = pack("A${length}i", $string, $number); print "パック文字列: $packed\n"; --- 結果 --- 文字列を入力してください:perl 数値を入力してください:100 パック文字列: perl

質問者が選んだベストアンサー

  • ベストアンサー
  • hofuhofu
  • ベストアンサー率70% (336/476)
回答No.2

Packは複数の変数をひとつにまとめるためのものですね。 書式としては Pack(テンプレート,変数,変数,......) となります。 今回の場合はテンプレートは、 A${length}i ですが、$lengthには$stringの長さですから、$string=perlなら4になるので、 A${length}i = A4i ですね。 A{n}はn文字分の領域を確保するという意味なので、A4なら4文字分の領域が確保され、そこにperlという文字列が格納されます。 もしこれがA6とかでperlという文字列を格納しようとすると、2文字分余るので余った部分にはスペースが入れられます。 'p','e','r','l'のアスキーコードはそれぞれ16進数で70,65,72,6Cなので$packedには 70 65 72 6C といった情報が格納されます。 次にiですが、これは32ビット以上の符号付整数型となっています。 PCでperlを動かしているなら、ほとんどが32ビット環境となっていると思うので、これは事実上32ビットと思ってください。 100は16進数であらわすと64ですが、これが32ビット=4バイト整数型に格納されたとすると00000064(0を増やして4バイト分の情報にしているだけ)といった感じになります。 さらにこれがメモリなどに格納される場合には1バイト単位で分解されるわけですが、ビッグエンディアンと呼ばれる形式で格納された場合には順番が反転して、 64 00 00 00 となります。 http://www.atmarkit.co.jp/icd/root/70/5784470.html A4iでこの二つのデータが結合されますから、結果としては 70 65 72 6C 64 00 00 00 となり、これをprintで表示すると、アスキーコードにしたがって、 perld となります。 後ろの3つの00はNULL文字なので見えません。 ちなみに符号有り、符号無しというのは負の値を使うか、使わないかということです。 たとえば1バイトで表現できるのは256個の数字ですが、符号ありの場合は-128~127の値を、符号無しの場合は0~255の値を表すことができます。

cgi_syoho
質問者

お礼

大変親切かつ丁寧にご説明いただき、どうもありがとうございます。 目からウロコのような解説です。 ぼくだけでなく、ぼくと同じ疑問を抱いているかも知れない人たちにもぜひ詳細したいくらい、大変よく理解できました。 もしよろしければ、今後も教えていただけたらと思います。 本当にどうもありがとうございます。

その他の回答 (1)

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

実行結果って、 パック文字列: perld ――じゃありませんか? もしそうなってないなら、表示が崩れているだけでは。 そういう話じゃなくて、「そもそもpackって何?」という話だとしたら、メモリへの値の直接書き込んでいるイメージがわかないと、ピンとこないかも。

cgi_syoho
質問者

補足

こんにちは。この度はどうもありがとうございます。 ご指摘とおり、実行結果は、「perld」です。 すみませんでした。 そうですね、。。「そもそもpackって何?」ってところが理解できてないんだと思います。 参考書には、「符号無しのchar型」など説明されていますが、ピンとこないのが正直なところですね。 よろしかったら、「packって何をするためのもの?」について教えていただけたら嬉しいです。 よろしくお願いいたします。