0

このコードは友人の 1 人から入手しましたが、perl を使用したことがないため、どのように機能するのかわかりません。それを理解するのを手伝ってもらえますか。

このファイルは、遅延を示すいくつかのデータを含むファイルを取得し、間隔内で累積分布関数を取得する必要があります。

#!/usr/bin/perl


#print "Starting converter on file $ARGV[0]\n";

if ($#ARGV < 2 || $#ARGV > 3) {
    print "Usage: ac_hist_gen.pl <input file> <num intervals> <output file> [ <interval size> ]\n";
    exit(-1);
}

open(infile,"$ARGV[0]") || die "Couldn't open $ARGV[0] for reading.\n";
open(outfile,">$ARGV[2]") || die "Couldn't open $ARGV[2] for writing.\n";

for ($i=0; $i< 100 / $ARGV[1]; $i++) {
    $dist[$i] = 0;
    $acum[$i] = 0;
}

$max=0;



if ($#ARGV == 2) {

while (<infile>) {

    if ($_ > $max) {
    $max=$_;
    }    
}

$intsize = $max / $ARGV[1];
} else {
    $intsize= $ARGV[3];
}

close(infile);



#print "size is $numpkts, max is $max, div is $intsize , test is $test\n";


open(infile,"$ARGV[0]") || die "Couldn't open $ARGV[0] for reading.\n";

while (<infile>) {

    $val = int($_ / $intsize);

    if (($_ / $intsize) == $val) {
    $dist[$val-1]++;
    } else {
    $dist[$val]++;
    }

#  print "val is $val\n";


}

for ($i=0; $i< $ARGV[1]; $i++) {
    $limit = ($i+1) * $intsize;
    $acum[$i]+= $dist[$i];
    $acum[$i+1] = $acum[$i];   
    print outfile "$limit $acum[$i]\n";
}


close(outfile);
4

2 に答える 2

1

わかりました、最初に ARGV について簡単に説明します。これは、C プログラムの main() 宣言で使用される char **argv のようなものです。

perl の ARGV は暗黙的に配列として宣言されます。perl では、このように配列全体を参照します

@ARGV

そして、このような配列のサイズに

$#ARGV

そして、このような配列内の個々の要素に

$ARGV[0]

配列はゼロからインデックス付けされるため$ARGV[0]、配列 @ARGV の最初の要素です。

それがプログラムのコマンドライン引数が読み取られる方法であり、ARGVへのすべての参照が関係しているものです

次のアイテム

open(infile,"$ARGV[0]") || die "Couldn't open $ARGV[0] for reading.\n";
open(outfile,">$ARGV[2]") || die "Couldn't open $ARGV[2] for writing.\n";

これは、私がARGVと話し合ったことを考えると、自己文書化です. これにより、入力用と出力用のファイルハンドルのペアが作成されます。二重引用符で囲まれた変数は、"その値に補間されます。したがって、「filename1.txt」の場合$ARGV[0]"ARGV[0]"「filename1.txt」としてコンパイルされます

perl では、配列だけでなく、単純な単一値の変数 (スカラーと呼ばれる) も使用できます。

$x=1x=1Cと似ています。

ただし、perl では、メモリを割り当てずに文字列を割り当てることができます。これは自動です。文字列の「型」変数は簡単に数値に変換できます。単純な変数は、数値として開始し、文字列に変換してから、コンテキストに応じて自動的に数値に戻すことができます。また、変数を宣言することは必須ではありません! Cint xでは宣言する必要がありますが、これは perl では厳密には強制されていません。

次のコード

for ($i=0; $i< 100 / $ARGV[1]; $i++) {
    $dist[$i] = 0;
    $acum[$i] = 0;
}

これは、変数の前に余分な $ 記号がいくつかあり、配列 @dist と @acum のサイズ、またはそれらの型を宣言する必要がないことを除いて、C の場合とまったく同じです。

考慮すべき次のビット

while (<infile>) {

    if ($_ > $max) {
    $max=$_;
    }    
}

infileはファイル ハンドルであり、構文<infile>はファイルから 1 行を読み取ります。しかし、perl プログラムのどこでデータが読み取られるかが明確ではないことに注意してください。ここで使用される perl のトリックは、最後に読み取った行を含むデフォルト変数があることです。変数は$_. したがって、このループが行っているのは、ファイル内の最大値を探すことだけです。

ちょっと飛ばして最後までいきます

for ($i=0; $i< $ARGV[1]; $i++) {
    $limit = ($i+1) * $intsize;
    $acum[$i]+= $dist[$i];
    $acum[$i+1] = $acum[$i];   
    print outfile "$limit $acum[$i]\n";
}

@acumこれは、上記のループと同様に、配列に対して操作を行うforループです。出力行は、出力ハンドルに書き込みます。変数は、前述のように補間されます。

これがあなたの理解に役立つことを願っています

于 2013-05-23T09:30:23.237 に答える