アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちは。

下記は、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

A 回答 (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の値を表すことができます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2003/07/17 01:02

実行結果って、



パック文字列: perld

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

この回答への補足

こんにちは。この度はどうもありがとうございます。

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

よろしくお願いいたします。

補足日時:2003/07/13 19:50
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!