カテゴリ:2.ソフトウェア > 2.7 プログラミング

配列を作ると、メモリにアドレスが確保されます。その様子をプログラムで実行します。
#include <stdio.h>
void main() {
    int A[100];  // 配列変数Aを定義。保存可能個数は100個でA[1]-A[100]を使用可能。
    int k;// 整数型の変数kを定義
    // kを1から100まで、1ずつ増やす(k++)
    for (k = 1; k <= 100; k++) {
        A[k] = k; 
        printf("A[%d]_add:%p\n",k,&A[k]); //A[k]のアドレスを表示
    }
}

結果は、以下のようになります。

c:\work>pg1.exe
A[1]_add:0028FDA0
A[2]_add:0028FDA4
A[3]_add:0028FDA8
A[4]_add:0028FDAC
A[5]_add:0028FDB0
A[6]_add:0028FDB4
A[7]_add:0028FDB8
・・・・
続きを読む

プログラミング

・プログラム言語は、「コンピュータに対する一連の動作を指示するための人工言語の総称(H25春IP問53不正解選択肢)」です。


■H28春、H25春
問20 メインプログラムを実行した後,メインプログラムの変数X,Yの値は幾つになるか。ここで,仮引数Xは値呼出し(call by value),仮引数yは参照呼出し(call byreference)であるとする。

H28h-問20
【正解】イ

少し補足します。
①仮引数Xは値呼出し(call by value
main関数での「値」を呼び出します。add関数実行では、main関数とは違うアドレスに記録します。
よってmain関数のXの値が変化しません

②仮引数yは参照呼出し(call byreference)
main関数でのyの値が入った「アドレス」を呼び出します。add関数実行により、main関数でのYの値を書き換えるので、Yの値が変化します。

#include <stdio.h>

//add関数
void add(int X, int *Y)
{
 //"Y"は参照呼び出し(ポインタ)で渡されるため
 // 値を参照する場合や、値を代入する場合は"*Y"を使用

 X = X+*Y;  //"X"に"Y"の値を加えて"X"に代入
 *Y = X+*Y;  //"X"に"Y"の値を加えて"Y"に代入
}

//main関数
void main(){
 int X, Y;  //"X","Y"をint型変数で定義
 X = 2;
 Y = 2;

 //add関数の実行
 add(X,&Y);
 //add関数実行後の"X","Y"の値を表示

 printf("add(X,Y)はX=%d,Y=%dです\n", X, Y);

}

"X"は値呼び出しで渡されるため、add関数実行により値が変化しない
 "Y"は参照呼び出しで渡されるため、add関数実行により値が変化する
具体的には、X=2+2=4、Y=4+2=6

aa

■メモ
メモリ上のアドレスと、その値
http://sc.seeeko.com/archives/5377814.html

■ポインタで変数を宣言する意味

ポインタ変数はデータを格納するアドレスそのものを変数として定義します。「char *a」と宣言すると変数aにはアドレスが格納されます。このアドレスを他の関数にもアドレス情報として渡せばデータそのものをコピーしたりする必要がありません。
 一方、「char a」と宣言すると変数aはデータの中身を示します。データの中身は他の関数に渡す場合、このままだと渡す先の変数に同じデータがコピーされるため、メモリを余分に使うことになります。
もちろん、マスターのデータを変えたくないのであれば、このままでもよいと思います。

■H25春
問8 流れ図に示す処理の動作の記述として,適切なものはどれか。ここで,二重線は並列処理の同期を表す。
H25h-問8
ア ABC又はACBを実行してデッドロックになる。
イ AB又はACを実行してデッドロックになる。
ウ Aの後にBC又はCB,BC又はCB,・・・と繰り返して実行する。
エ Aの後にBの無限ループ又はCの無限ループになる。

【正解】ウ

 

1.コンパイラ

プログラムは、CやJavaなどのプログラミング言語で書かれます。これは、人間にとっては分かりやすいのですが、コンピュータはこのままでは理解できません。コンピュータが理解できるのは、01の2進数で表された機械語だけです。

そこで、プログラム言語をコンピュータが実行できる機械語に変換する処理(コンパイル)をします。この処理のソフトウェアをコンパイラと言います。
過去問では、「コンパイラ」に関して、「コンピュータが直接実行可能な機械語に,プログラムを変換するソフトウェア(H25春IP問53不正解選択肢)」とあります。

■プログラム言語
#include <stdio.h>
void main() {
int A[100];
・・・・

   →    

機械語
001010100111000
100011111010110
110101010111101
010111101

2.コンパイルの流れ

コンパイラにおける処理は、まず、ソースコードを解析します。このとき、字句解析,構文解析,意味解析の流れで解析をします。たとえば構文解析では、ソースコードの文法に誤りがないかをチェックします。
 次にプログラムの実行時間を短縮するための最適化を行います。たとえば、途中で値が変更されない変数を定数で置き換えることで、処理速度を速めます。
 最後に、最適化されたソースコード機械語に変換してコンパイルが完了します。
上記の流れを、過去問(H25秋AP問20)を基に整理します。

(1)ソースコード解析

①字句解析
プログラムを表現する文字の列を,意味のある最小の構成要素の列に変換する。
構文解析
言語の文法に基づいてプログラムを解析し,文法誤りがないかチェックする。
③意味解析
変数の宣言と使用とを対応付けたり,演算におけるデータ型の整合性をチェックする。

(2)最適化

レジスタの有効利用を目的としたレジスタ割付けや,不要な演算を省略するためのプログラム変換を行う。

応用情報技術者試験を勉強する成子 

たとえば、どんな処理がありますか?
過去問(H27秋AP問19)では、「コンパイラが行う最適化の方法」として,「定数が格納される変数を追跡し,途中で値が変更されないことが確認できれば,その変数を定数で置き換える」とあります。

(3)機械語に変換

最適化されたソースコード機械語に変換します。

3.コンパイラに関する過去問

(1)H27秋AP
問19 目的プログラムの実行時間を短くするためにコンパイラが行う最適化の方法として,適切なものはどれか。
ア 繰返し回数が多いループは,繰返し回数がより少ないループを複数回繰り返すように変形する。例えば,10,000回実行するループは,100回実行するループを100回繰り返すようにする。
イ 算術式の中で,加算でも乗算でも同じ結果が得られる演算は乗算で行うように変更する。例えば,“X+X”は“X*2”で置き換える。
ウ 定数が格納される変数を追跡し,途中で値が変更されないことが確認できれば,その変数を定数で置き換える。
エ プログラム中の2か所以上で同じ処理を行っている場合は,それらをサブルーチン化し,元のプログラムのそれらの部分をサブルーチン呼出しで置き換える。





 【正解】ウ

(2)H27春AP

問19 あるコンピュータ上で,異なる命令形式のコンピュータで実行できる目的プログラムを生成する言語処理プログラムはどれか。
ア エミュレータ     イ クロスコンパイラ
ウ 最適化コンパイラ  エ プログラムジェネレータ





 【正解】イ

(3)H25秋AP

問20 コンパイラにおける処理を字句解析,構文解析,意味解析,最適化の四つのフェーズに分けたとき,意味解析のフェーズで行う処理はどれか。
ア 言語の文法に基づいてプログラムを解析し,文法誤りがないかチェックする。
イ プログラムを表現する文字の列を,意味のある最小の構成要素の列に変換する。
ウ 変数の宣言と使用とを対応付けたり,演算におけるデータ型の整合性をチェックする。
エ レジスタの有効利用を目的としたレジスタ割付けや,不要な演算を省略するためのプログラム変換を行う。





ア:構文解析
イ:字句解析
エ:最適化

【正解】ウ

(4)H20春FE午前

問38 コンパイラによる最適化の主な目的はどれか。
ア ソースプログラムのレベルでのデバッグを容易にする。
イ プログラムの実行時間を短縮する。
ウ プログラムの保守性を改善する。
エ 目的プログラムを生成する時間を短縮する。





正解はイです。

↑このページのトップヘ