C言語構造体連結リストで東京-新潟間上越新幹線駅名を表示

おはこんばんにちは!
うにゃうにゃエンジニアの猫です(=^・^=)

C言語のラスボス??でしょうか。構造体とかポインタ、

連結リストをやり始めて( ;∀;)です。
新潟から東京までの駅名を使った、上越新幹線のリストを作って勉強しようと思います。

私が東京から新潟に遊びに行くイメージで作ります。
上越新幹線の駅名を6つ選びました。

駅名、ポインタ(次の駅を指し示す)を構造体で定義します。
まずは上越新幹線がの駅を調べてみます。

1.東京
2.大宮
3.高崎
4.浦佐
5.燕三条
6.新潟

上越新幹線の路線はコチラから

この6つの駅に次の駅の場所を示すポインタを付けて表示して見ます。
このリストは駅名と次の駅のポインタがこのような図で表せます。

ポインタを逆向きにすると、新潟から東京に帰る駅の順番で逆向きに表示できます。

ではC言語でコードを書いて実行してみます。

実行結果です。

最後にコードはこのようになります。

最後までご覧頂きありがとうございました。
引き続きC言語の最後のレッスンを頑張ります。
もしも分からなくなったら、前に戻って勉強します(=^・^=)mm

C言語で日数計算と曜日求め

おはこんばんにちは!
うにゃうにゃエンジニアの猫です(=^・^=)

今日はC言語で、ある日付から別の日付まで何日あるのかカウントするプログラムと、
それを利用して曜日を求めるプログラムを作ってみました。
良かったら使って下さいにゃっ!

その年の1月1日からの日数を計算します。
それには月ごとの日数の配列を作って利用しています。
例えば1月だったら+0、2月だったら+31…と加算日数が配列に入っています。
C言語は配列の要素が0から始まる為、配列の先頭の要素はダミーとして0が入っています。

開始日と終了日を年、月、日ごとに入力して、開始日が3月より前だったら、または終了日が3月以降だったら、
閏(うるう)年かどうか調べて、閏年だったら日付を1つ増やすように計算します。

開始日と終了日の年の差×365とうるう年の調整をして日数を求めました。
では実行して見ます。

今日は2021年(令和3年)1月23日です。
1年前の2020年1月23日までの日数を求めます。
2020年はうるう年で、2月29日が含まれるので、その分加算され、365+1で366日になります。

では、私が生れた1977年5月19日から今日までの日数を調べます。

うわぁぁぁ、こんなに生きているんだ。もっと1日1日丁寧に生きないと!!

ここまでのプログラミングのコードです。

#include <stdio.h>
//ここで引き算している
int hikizan(int start,int goal){
return goal-start;
}


//うるう年かどうかの判定をしている
int isLeapYear(int uruyear){
if((uruyear%4==0 && uruyear%100!=0) || uruyear%400==0){
return 1;
}else{
return 0;
}
}

int main(void)
{
//日付の開始日、終了日の変数
int yearstart,yeargoal,yeardif; //開始年、終了年、終了年-開始年
int monthstart,monthgoal; //開始月、終了月
int daystart,daygoal; //開始日付け、終了日付け
int uruFlg; //うるう年の判定フラグ
int count=0; //うるう年の回数
//月の配列。その年の1月1日からの日数
int tukihi[]={0,0,31,59,90,120,151,181,212,243,273,304,334};

//開始日の入力
printf(“開始日の年を入力してください。開始の年:yearstart=”);
scanf(“%d”,&yearstart);
printf(“開始日の月を入力してください。開始の月:monthstart=”);
scanf(“%d”,&monthstart);
printf(“開始日の日を入力してください。開始の日:daystart=”);
scanf(“%d”,&daystart);
printf(“——————————————-\n”);

//終了日の入力
printf(“終了日の年を入力してください。\n※開始日以降の日付を入力してください※\n終了の年:yeargoal=”);
scanf(“%d”,&yeargoal);
printf(“終了日の月を入力してください。終了の月:monthgoal=”);
scanf(“%d”,&monthgoal);
printf(“終了日の日を入力してください。終了の日:daygoal=”);
scanf(“%d”,&daygoal);

//もしも開始日>終了日だったら
if(daystart>daygoal){
printf(“終了日を開始日以降の日付にしてやり直して下さい。\n”);
return 0;
}
printf(“\n”);

//その年の1月1日からの日数
daystart+=tukihi[monthstart];
daygoal+=tukihi[monthgoal];

//開始年と終了年の差は何年あるか
yeardif=hikizan(yearstart,yeargoal);
//開始日の月が3月より前だったらその年が閏(うるう)年かチェックする
if(monthstart<3){ uruFlg=isLeapYear(yearstart); if(uruFlg==1){ daystart–; } }


//終了日の月が3月以降だったらその年が閏(うるう)年かチェックして、前の年の判定の順準備をする if(monthgoal>=3){
uruFlg=isLeapYear(yeargoal);
if(uruFlg==1){
daygoal++;
}
}
yeargoal–; //終了日の前年のうるう年判定をする準備

//終了日の前年から開始日の年までうるう年か調べる
for(int i=yeargoal;yeargoal>yearstart;yeargoal–)
{
uruFlg=isLeapYear(yeargoal);
if(uruFlg==1){
count++;
}
}
daygoal+=365*yeardif+count-daystart; //日数計算
printf(“%d日です。\n”,daygoal);
}

では、上のプログラムを利用して、曜日を求めてみます。
基準日は1970年1月1日とします。その日は木曜日なので、日数差を7で割った余りが0なら木曜日、
1なら金曜日…と配列に入力して曜日を調べます。


今日2021年1月23日は土曜日ですので、ちゃんと求まりました。

では、私が高校生の頃に阪神淡路大震災や地下鉄サリン事件があった激動の年、1995年(平成7年)から任意の日付、6月21日は何曜日か調べます。


水曜日ですね。

良かったちゃんと動いていた。
では、このプログラムのコードです。


#include <stdio.h>
//ここで引き算している
int hikizan(int start,int goal){
return goal-start;
}


//うるう年かどうかの判定をしている
int isLeapYear(int uruyear){
if((uruyear%4==0 && uruyear%100!=0) || uruyear%400==0){
return 1;
}else{
return 0;
}
}

//曜日を求める
int youbihantei(int nanyou){
return nanyou%7;
}
int main(void)
{

//日付の開始日、終了日の変数
int yearstart,yeargoal,yeardif; //開始年、終了年、終了年-開始年
int monthstart,monthgoal; //開始月、終了月
int daystart,daygoal; //開始日付け、終了日付け
int uruFlg; //うるう年の判定フラグ
int count=0; //うるう年の回数
int week; //曜日を表す配列の添え字

//月の配列
int tukihi[]={0,0,31,59,90,120,151,181,212,243,273,304,334};

//開始日(基準の日を1970年1月1日とする)
yearstart=1970;
monthstart=1;
daystart=1;

//曜日の配列。基準日との日数差を7で割った余りが0になるのが木曜日
char youbi[]={“木”,”金”,”土”,”日”,”月”,”火”,”水”};

printf(“年を入力してください。年:yeargoal=”); scanf(“%d”,&yeargoal); printf(“月を入力してください。月:monthgoal=”); scanf(“%d”,&monthgoal);
printf(“日を入力してください。日:daysgoal=”);
scanf(“%d”,&daygoal); printf(“\n”); //その年の1月1日からの日数 daygoal+=tukihi[monthgoal]; //開始年と終了年の差 yeardif=hikizan(yearstart,yeargoal); //終了日の月が3月以降だったらその

年が閏(うるう)年かチェックする if(monthgoal>=3){ uruFlg=isLeapYear(yeargoal); if(uruFlg==1){ daygoal++; } } yeargoal–; //終了日の前年から1971年までうるう年か調べる for(int i=yeargoal;yeargoal>yearstart;yeargoal–) { uruFlg=isLeapYear(yeargoal); if(uruFlg==1){ count++; } } daygoal+=365yeardif+count-daystart;
week=youbihantei(daygoal);

if(yeargoal<1970){
printf(“1970年1月1日以降の日付を入力してください。\n”);
}else{
printf(“%s曜日です。\n”,youbi[week]);
}
}

ご精読ありがとうございました(=^・^=)mm

急にプレゼン資料を作ることになったから手っ取り早くパワポ教えてくれ!!!!!

この記事では、急にプレゼン資料を作ることになり、手っ取り早くパワポでサクッと資料を作れるお手伝いとして、下記の記事でパワポの要点をまとめました。
ご覧頂けましたら幸いです。

■ サクッとパワポで資料作成のレッスン記事 ■

パワポ起動

テーマとタイトルの装飾


スライド作成とスマートアート


ページ番号・スライドマスタスライドショー

図形を等間隔にする

アニメーションとページ切り替え


以降、PowerPointの学習に役立つ動画と本を紹介致します。

※ 私は動画及び書籍を紹介しているだけのただの一読者、視聴者であり、動画投稿者及び著者の方とは面識がございません。


●動画

チャンネル: ビジネス教育系ユーチューバーYouseful(ユースフル)
Yousefulの講師の方


●【超入門講座】初心者にやさしいパワーポイント(PowerPoint) 基本の使い方(時間:17:40)

PowerPointの起動の仕方や文字、表、グラフなどを入門者向けに分かりやすく
丁寧に解説して下さっています。
アイコンは使ったことが無かったので、知らないこともありました。


●【入門講座】明日の実務ですぐ使える!パワーポイント(PowerPoint)の基本機能使い方(時間:13:18)

表の色設定やグループ化、カラーやフォントについて学習しました。
グラフの誤差やYouTubeの見栄えを変える方法などは初めて知りました。


●【初級講座】生産性があがる!PowerPointの便利テクニック4選!(時間:11:10)

スライドマスタはPowerPoint学習で躓きやすい点なので、復習になりました。
ノートやセクション、オンラインテンプレートの使い方の説明もありました。


● 【生産性UP】知らないと大損!PowerPointテクニック22のショートカット技まとめ(時間:11:46)

文字揃えや図形のサイズ、回転、整列、スライドショーで便利なショートカットキーなど、かなり実践的なキーを紹介されています。


●書籍

■ 関連記事 ■

自己紹介


取りあえず事務職で働きたいから手っ取り早くExcel教えてくれ

Wordのポイントを手っ取り早く教えてくれ!!!

コロナ禍、アフターコロナの新しい働き方、テレワーク(Google Workspace)

メインメニューに戻る

C言語構造体で昨日の新型コロナ感染者数

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

おはこんばんにちは!うにゃうにゃエンジニアの猫です(=^・^=)
構造体について学んだので早速アウトプットするにゃっ!
学んでいくうちにこのプログラムをちょっとずつ改良出来ると思います。

この記事を書いているのは令和3年1月21日なので、昨日の新型コロナの感染者数を、
場所と人数と言った構造体を使ってプログラミングをしてみました。

感染者数はNHK新型コロナウイルス特設サイトから引用しました。

早速実行します。

こんな感じで実行できました。

ではプログラムです。

#include <stdio.h>

struct corona{
char city[20];
int people;
};


int main(void){

struct corona tokyo={“東京”,1274};
struct corona hokkaido={“北海道”,164};
struct corona osaka={“大阪”,506};

printf(“2021年1月20日の感染者数\n”);

printf(“%sの感染者数は%d人です。\n”,tokyo.city,tokyo.people);
printf(“%sの感染者数は%d人です。\n”,hokkaido.city,hokkaido.people);
printf(“%sの感染者数は%d人です。\n”,osaka.city,osaka.people);

}

ご覧になって分かるように、printf関数を3回も使っているので、ここは学んでいく過程で近いうちに改良できそうです。

追記
構造体配列について学んだので、要素数を追加してプログラミングして見ました。
実行結果です。

プログラムです。

#include <stdio.h>

//構造体の宣言 typedefで[struct corona]を「CORO」に省略
typedef struct{
char city[20];
int people;
}CORO;


int main(void){

CORO tokyo={“東京都”,1471};
CORO hokkaido={“北海道”,130};
CORO osaka={“大阪府”,501};
CORO saitama={“埼玉県”,436};
CORO kanagawa={“神奈川県”,731};

//構造体配列の要素
CORO corona[5];
corona[0]=tokyo;
corona[1]=hokkaido;
corona[2]=osaka;
corona[3]=saitama;
corona[4]=kanagawa;

printf(“2021年1月21日の感染者数\n”);

//ループで各都市における感染者数を取り出す
for(int i=0;i<5;i++){
printf(“%sの感染者数は%d人です。\n”,corona[i].city,corona[i].people);
}
}

ご精読ありがとうございました!

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

C言語のポインタって怖いの?怖くないの?

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

おはこんばんにちは!うにゃうにゃエンジニアの猫です(=^・^=)
ITの先輩方からC言語にはポインタっていうものがあって、それがラスボス?か大ボスみたいに大変だと聞きました。
なので、ゆっくり基礎から覚えたことを復習します。

※超超超初心者の備忘録な為、厳密には正確では無いかもしれませんが、
そういう風に理解しているんだなぁと、あたたかい目で見て下さい。

変数aというint型の変数があって、その値が5だとします。
その例を考えてみます。この図を書きました。


右側に変数aを用意しました。値は5です。

変数aは主記憶に格納されていて、変数aがある主記憶の場所には東京都新宿区何丁目…みたいな住所のような物があります。
その住所みたいなものをアドレスって言います。
仮にそのアドレスを100番地とします。


左側には変数aのアドレスを値として持つポインタpがあります。

また、p自体にも北海道稚内市何丁目…みたいなアドレスがあります。
そのアドレスを300番地とします。

ポインタpが見ているアドレスの中身(住人)はaの値で5です。
これをポインタが見ているというのを表す表記として*pを使います。
*p=5になります。

…と、文章と図だけだとイマイチ分かりづらいので、それをプログラミングしてうちのパソコンではどんな感じになるのか調べてみたいと思います。

実行結果です。

プロうグラムはこちらになります。

#include <stdio.h>
int main(void){
int a=5;
int p;    //ポインタ宣言

p=&a;   //ポインタpはaのアドレスを格納

//これらは等しい。aの値を示す
printf(“aの値…a=%d\n”,a);
printf(“pが見ている値…p=%d\n\n”,*p);

//これらは等しい。aのアドレスを示す。
printf(“aのアドレス…&a=%p\n”,&a);
printf(“ポインタpの値…p=%p\n\n”,p);

//これはpが格納されているアドレス。
printf(“ポインタpのアドレス…&p=%p\n”,&p);
}

これで私のアタマはスッキリしました。
ご精読ありがとうございました(=^・^=)

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

C言語で「ねこ」おみくじを作ってみた

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

おはこんばんにちは!うにゃうにゃエンジニアの猫です(=^・^=)
今日は、ねこみくじなるものを作りました。
おみくじの猫版です。

・ホワッツマイケル
・ナメネコ
・うちのタマ知りませんか
・ねこあつめ
・にゃんこ大戦争

といった猫にまつわる作品をランダムに表示させます。
といった、猫好きさんの猫ツボを刺激する以外は、
何の役にも立たない乱数プログラムを作りました。

配列 nekoretsuの各要素、要素番号の先頭を[0]として、
[0]ホワッツマイケル
[1]ナメネコ
[2]うちのタマ知りませんか
[3]ねこあつめ
[4]にゃんこ大戦争

という配列を用意します。
その要素番号をランダムな数にすると、猫のおみくじが出来上がります。
乱数を発生させてその乱数を配列の添え字にして、配列の中身の文字列を取り出します。

配列の要素数は5なので、ランダムな数の5で割った余りは、余り0~4になりますので、
各要素番号が乱数になる仕組みです。

では、何が出るかな…。

1回目は
「ナメネコ」

2回目は
「ねこあつめ」

これは猫好きな方にしか分からないかもしれませんが、猫の作品の名前をみるだけで、
うにゃ~~~~~つ(=^・^=)ってなるんです。

コードはこちらになります。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main(void){

srand((unsigned int)time(NULL)); //現在の時刻で乱数の初期化

char *nekoretsu[5]={“ホワッツマイケル”,”うちのタマ知りませんか”,”ナメネコ”,”ねこあつめ”,”にゃんこ大戦争”};

int num=rand()%5;
printf(“%s”,nekoretsu[num]);

}

ではでは、ご精読ありがとうございました、にゃん!

C言語自作サンプルメニューへ
これからプログラミングをはじめる方へ
基本情報技術者試験トップへ
息抜きに(=^・^=)写真で癒し

C言語で和暦と干支を求める+追加で閏(うるう)年判定

おはこんばんにちは、うにゃうにゃエンジニアの猫です(=^・^=)
年賀状を書く時期にはちょっと使えるかもしれないプログラムを作りました。

年号を入れると令和何年とか干支は何だとか求められるプログラムです。
例えばこの記事を書いているのは2021年です。西暦に2021と入力して見ます。


このように「令和3年、うし年」と求まりました。
干支を文字列の配列で初期化して、西暦年を12で割った余りを配列の要素として求めています。
12で割り切れる(割った時の余りが0になる)のが直近だと2016年さる年です。
なので、要素番号は0から始まり、配列の先頭の[0]をさる年、[1]をとり年…としています。

昭和、平成、令和をwareki年として、昭和だったら西暦マイナス1925、平成だったら西暦マイナス1988、令和は西暦-2018と
計算しています。この辺はIFとElse ifなどの分岐を使っています。

至ってシンプルですが、どなたかのお役に立てるのかなぁ…。

では、動作確認で他の年も調べてみます。
1995年は当時高校生の私にとって、阪神淡路大震災や地下鉄サリン事件などのとても重いことがあった年でした。
1995を入力して見ます。

あと、昭和では自分の生まれた年で動作確認して見ます。

プログラムはこちらになります。


#include <stdio.h>
int etosirabe(int nen){
return nen%12;
}
int main(void){
char *jyunisi[12]={“さる”,”とり”,”いぬ”,”いのしし”,”ね”,”うし”,”とら”,”うさぎ”,”たつ”,”へび”,”うま”,”ひつじ”};
char *gengo;
int year,eto,wareki;
printf(“調べる年を西暦で入力=”);
scanf(“%d”,&year);
eto=etosirabe(year);
if(year>=1989 && year<=2018){ gengo=”平成”; wareki=year-1988; }else if(year>=2019){
gengo=”令和”;
wareki=year-2018;
}else{
gengo=”昭和”;
wareki=year-1925;
}
printf(“%d年は%s%d年で干支は「%s年」です。”,year,gengo,wareki,jyunisi[eto]);
}

あとは、このプログラムをちょっとずつ改良していきたいと思います。
基本情報技術者試験を勉強して、プログラムはどんどん改良していくことで自分の力になることを学びました。

追記 2021年1月19日
このプログラムにうるう年を求める処理を追加しました。
コメントの所が追加変更した所です。
画像では赤枠でくくっています。

#include
int etosirabe(int nen){
return nen%12;
}
//ここを追加。うるう年を求める関数
int isLeapYear(int uruyear){
if((uruyear%4==0 && uruyear%100!=0) || uruyear%400==0){
return 1;
}else{
return 0;
}
}
int main(void){
char *jyunisi[12]={“さる”,”とり”,”いぬ”,”いのしし”,”ね”,”うし”,”とら”,”うさぎ”,”たつ”,”へび”,”うま”,”ひつじ”};
char *gengo;
char *uruJadge;
int year,eto,wareki;
int uruFlug;
printf(“調べる年を西暦で入力=”);
scanf(“%d”,&year);
eto=etosirabe(year);
if(year>=1989 && year<=2018){ gengo=”平成”; wareki=year-1988; }else if(year>=2019){
gengo=”令和”;
wareki=year-2018;
}else{
gengo=”昭和”;
wareki=year-1925;
}
//ここでうるう年を調べる関数を呼び出す
uruFlug=isLeapYear(year);
if(uruFlug==1){
uruJadge=”うるう年です。”;
}else{
uruJadge=”うるう年ではありません。”;
}
//表示を変更
printf(“%d年は%s%d年で干支は「%s年」です。\n%s\n”,year,gengo,wareki,jyunisi[eto],uruJadge);
}

では、実行結果を見てみます。
私が高校生の頃にとても重いことのあった1995年の実行結果です。

次に2100年を見てみます。
うるう年は4で割り切れ且つ100で割れない、または400で割れる年です。
なので2100年はうるう年にはならないです。

令和82年とか、まぁ、私はいないです。

最後に400で割れる2000年を見てみます。

ご精読ありがとうございました。

飲み込みの遅い私がアルゴリズムを攻略するまで

この記事では、基本情報技術者試験で配点が高くなったアルゴリズムの攻略法を書いています。トレースのやり方や、やっておくべき過去問3選もあるので、ぜひお役立て下さい。

基本情報技術者試験トップ
アルゴリズム無料教材
CBT試験(午前免除午後試験)お役立ちリンク集
午前免除試験
これからプログラミングをはじめる方へ



基本情報技術者試験のアルゴリズム問題の疑似言語が読めないのは、必ず原因があって読めない、ということに気づきましたのでそれをシェアしたいと思います。
私は「要領の悪さ」と「どんくささ」でしたら、少なくともあなたには負けない自信があります!!
そんな私が、何故今まで自分は疑似言語が読めなかったのかを分析してまとめましたので、もしも参考に出来そうな所がありましたら、持って帰って下さい。

●混乱による理由
疑似言語の日本語によるプログラムの説明文でいろいろと難しそうな英字が出て来ますけれど、「それが変数なのか、配列なのか、プログラム(関数)名なのか」分からないと混乱します。
なので、配列の場合はhairetsu[]など、[]を書くことにしました。
また、どこを見ているのか分からなくなったので、左手でマウスを操作して、読んでいる所にカーソルを合わせ、右手でペンを持ってトレースする練習をしました。

●遅い
トレースが遅くて悩んでいました。それは配列の場合、どの要素番号なのか分からなくなってしまっていました。
そこで、例えばhairetsu[]={100,200,300,400,500}で配列の要素が0から始まる場合は、[0]と書いて、{100,200,300,400,500}の真上に0,1,2,3,4と配列の要素番号を書き、更にその右に「5」と配列の長さを書きました。
これにより解ける問題も出て来るかも知れません。
また、訓練によってトレースは早くなります。そこで、同じ過去問をじっくり解くという勉強を×3やりました。
そのプログラムを覚えてしまうぐらい繰り返してから次の過去問に行きました。
期間として1週間同じアルゴリズムを解きました。

●間違える
ミスを防ぐためには、変数の中でも関数が戻り値として返す変数に◯を囲いました。
私は引数、戻り値が良く分からなかったので、どこかで聞いたことのある例と対応付けました。カレーライスを作るプログラムが、処理の中でカレー鍋というプログラムを呼び出し、引数として(かっこ)の中に(じゃがいも、ニンジン、などなど)の具材を入れます。そこで戻り値として料理が出て来ます。
アルゴリズムが出来なかった頃の私は、カレー鍋の中に何の材料も入れないで、カレーライスを食べたい、何で出てこないの??あ、まちがってラーメン作っちゃった、という失態をしていました。

●テクニック
プログラムを読みやすくするテクニックとして、本文を良く読んで、何をやっているプログラムなのか日本語の説明文から掴む→
先に選択肢を見る→コメントとその対応のプログラムを見る→それからプログラム自体を見るという順番で解きました。

●CBTの画面上でのトレース
この本の読者特典に「動く疑似言語」といって、PowerPointを使った特典が付いています。


基本の整列、探索などのアルゴリズムの動きを画面上でトレース出来るので、令和2年度以降のCBT試験の対策として役立ちます。また本自体も解説が分かりやすいので、私はこの本でアルゴリズムのトレースを学びました。
若干扱っている年度が古いので、このあと紹介する比較的最近の過去問も合わせてやっておくと自信付くと思います。

●計算用紙でトレース
アルゴリズムを始めた頃はExcelで枠を作ってこの様に作っても良いと思います。

しかし、試験近くなって来たらA4用紙の中央に線を引いてその状態でこの様にトレースを出来るようなるまで練習あるのみです。

試験1週間前の元旦(令和3年1月1日)に解いたアルゴリズムです。

関連リンク:平成27年秋過去問ノート

関連リンク:平成29年春午後過去問ノート

●やっておくべき過去問3選
過去問どれからやるべきか迷う所です。そこでグズでノロマな私が無理なくアルゴリズム攻略出来るのに特に役立った過去問を3選紹介します。
※私の独断と偏見です。

第1位平成30年秋
このアルゴリズムは四則演算なので、+-×÷が分かればそれ以上の知識は要らずにトレース出来ます。なので、トレースのみに集中できて、すごくトレースの練習になります。
関連リンク:平成30年秋午後過去問ノート

第2位平成27年秋
このアルゴリズムは検索です。
配列の要素の比較をしてずらしながら検索して行きます。
こういった処理は基本情報技術者試験の良くあるパターンなのでこの試験の攻略するために練習になる問題です。

関連リンク:平成27年秋午後過去問ノート

第3位平成29年春
これはちょっと難易度が高いアルゴリズムですが、これを攻略出来たら自信もって良いと思います。経路探索、ダイクストラ法と呼ばれるアルゴリズムを使っています。
頭が混乱するかもしれませんが、アルゴリズムを攻略できたかどうかの要となる過去問だと私は思います。

関連リンク:平成29年春午後過去問ノート

最後にアルゴリズムの攻略や読んでいて面白いと思った本を紹介します。
すべて同じ著者、矢沢久雄先生の本です。(回し者では無く、良いものは良いと思ったので紹介致します。)

実際に作りながら学べますので、先の本と並行して学ぶと非常に面白いと思います。
javaとCに対応しています。(C言語はこの本のリンクからダウンロードで入手可能)

C言語なるほど実験室
基本情報技術者試験の範囲も扱っている実験を通して、プログラムの流れをつかめます。

関連記事

基本情報技術者試験トップ
アルゴリズム無料教材
CBT試験(午前免除午後試験)お役立ちリンク集
午前免除試験
これからプログラミングをはじめる方へ

基本情報技術者試験CBTお役立ちリンク集

この記事では、下記について掲載しています。

●当日の持ち物
●計算用紙と筆記用具
●CBTとは
●FEのCBT
●コロナ対策
●試験会場(東京池袋)

2021年令和3年1月8日、基本情報技術者試験を受験しました。
午前免除済なので午後試験のみです。
試験問題の内容やそれを推測可能になる様な事は書けないことをご了承願います。

基本情報技術者試験トップへ
これからプログラミングをはじめる方へ
修了試験(午前免除)
令和2年度(令和3年1月)合格報告


●当日の持ち物
CBT受験で入室、退室の時間の管理をしています。
その時にコロナ対策によりペンを借りることが出来ないので、
自分で持って行きます。
シャーペンとボールペン両方持って行ってどっちがいいか聞いた所、
「ボールペンの方が良い」と言われました。
また、時計は腕時計が苦手な方は、持って行かなくても大丈夫です。
CBTでは残り時間のカウンターが付いているので、
試験会場では使いませんでした。
会場まで時間通りに着けるようにスマホを持って行っただけで十分でした。

●計算用紙と筆記用具
計算用紙は1枚だけでした。なので、真ん中に線を引いて両面使いました。
字を小さく書く訓練をして当日に臨みました。
シャーペンも計算用紙と一緒に配布されました。
こう言ったら申し訳ないのですが、シャーペン、
ちょっと書きにくかったです。
グリップの所が持ちにくいな…と思いながら使っていました。
でも、回答はCBTだからマークシートではないので、
そこは大丈夫でした。



●CBTとは
私たち基本情報技術者試験を受ける方の前提知識として、
プロメトリック社のサイトのこのページのリンクを貼ります。

●FEのCBT
試験当日の受験の流れ

●コロナ対策
新型コロナウイルス情報

●試験会場(東京 西武池袋別館9F)
※この会場は駐車場の中を通った所にあるエレベーターで向かうのですが、少し車が危険に思いましたので、利用される方は充分お気をつけて下さい!!

私が受けた試験は東京の池袋でした。
西武池袋本店別館9Fのパソコン教室、
池袋コミュニティ・カレッジ パソコン教室、
PCカレッジ 株式会社スーパーオフィスと言う所です。
地図

会場まではJR池袋駅の東口(南)を目安に41番出口から明治通りに出るので、
上記URLの地図の目印を探しながら「無印良品」まで行きました。
そこから、
「1階駐車場内エレベーター通路入り口」を歩いて行くと、
エレベータで9階に行けます。

基本情報技術者試験トップへ
これからプログラミングをはじめる方へ
修了試験(午前免除)
令和2年度(令和3年1月)合格報告

風呂グラミング(入浴剤紹介)
息抜きに、写真で癒し(=^・^=)

平成29春の過去問問12 アセンブラ のプログラミング(コメント、トレースのノート付き)

この記事では、過去問のアセンブラの問題に載っているプログラムを実際に自分の環境で作成して動かすのに使ったコードと、トレースのノートを掲載しています。
この記事を通してアセンブラだけでなくアルゴリズムのトレース力向上にもお役立て下さい。

アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
令和2年度(令和3年1月合格報告)

シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです

この問題は乗算の応用です。ちょっと心配な方は駄菓子屋で5円チョコを買ったイメージで作ったサンプルプログラムをご覧下さい。
アセンブラCASL2で「2進数の乗算」を作ってみた

この問題は、2つの数を足すプログラムです。
0002と0003を加えたら0005になります。
Aに0002、Bに0003を設定して合計をAに入れて0005とします。
疑似言語風に書くと、「A←A+B」です。

設問1と2を一気に片付けるために、設問2の具体例を使ってプログラム1をトレースします。
AとBはともに64ビットなので、1語16ビットの為箱4つずつ使います。

A:「3F1D」「B759」「2E0C」「A684」
B: 「2E0C」「A684」「3F1D」「B759」
この加算結果がAに入ります。

では、実際にシミュレーターを使って実行していきます。

主記憶に2つの数AとBが入りました。

GR1にA+0、GR2にB+0のそれぞれのアドレスが入ってプログラム1のADD64を呼び出します。

演算に使うレジスタのGR0が初期化されました。

GR3にA+3、GR2にB+3が入りました。

桁上りのフラグに使うレジスタGR5が初期化されました。

GR0にAの3番地(最後の箱)の中身の数が入りました。

GR0にA+Bの3番地の演算結果が入りました。
OFが1になっているので、オーバーフローして、上の箱(上位桁)の演算結果に
加えます。

桁上りフラグが立ちました。…空欄「a」

演算結果がAの最後の箱に入りました。

桁上りの加算用にGR0に1が入りました。

GR3の「A+3」がGR1の「A+0」と比較されました。…空欄「b」
GR3の方が大きいのでSFは0です。

アドレスがデクリメントされ、GR3が「A+2」、GR4が「B+2」になりました。

LOOPに戻ります。・・・空欄「c」
この空欄ではアドレスがデクリメントされた「B+2」の状態について問われているので
それがマイナスになったりゼロになったりは無いので、単純分岐でJUMPです。

桁上りフラグが初期化されました。

GR0に先ほどの桁上り分の1に加えてA+2の「2E0C」が入ったので、
計算結果は「2E0D」です。…設問2の空欄「d」

あとは同じことの繰り返しなので、主記憶の演算結果のみを掲載します。

プログラミングです。

;平成29春64ビットの加算とそれを使った乗算
;メインプログラム
MAIN START
RPUSH
LAD GR1,A ;足し算に使う数Aの先頭アドレス
LAD GR2,B ;足し算に使う数Bの先頭アドレス
CALL ADD64
RPOP
RET
A DC #3F1D
DC #B759
DC #2E0C
DC #A684
B DC #2E0C
DC #A684
DC #3F1D
DC #B759


;プログラム1
ADD64
RPUSH
LD GR0,=0
LAD GR3,3,GR1 ;Aの一番後ろ4つ目
LAD GR4,3,GR2 ;Bの一番後ろ4つ目
LOOP1 LD GR5,=0 ;桁上りフラグ
ADDL GR0,0,GR3 ;Aを加算
JOV OV1 ;桁上りの分岐
JUMP NOV1 ;桁上りが無かった時
OV1 LD GR5,=1 ;空欄「a」桁上りフラグを立てる
NOV1 ADDL GR0,0,GR4 ;Bを加算
JOV OV2
JUMP NOV2
OV2 LD GR5,=1 ;空欄「a」
NOV2 ST GR0,0,GR3 ;加算結果をAへ格納
LD GR0,GR5 ;フラグを読み込んで次の加算へ
CPL GR3,GR1 ;空欄「b」全ての箱で処理が終わったか比較
JZE EXIT ;プログラムの修了へ分岐
SUBL GR3,=1 ;Aの加算対象を1つ上の箱にする
SUBL GR4,=1 ;Bの加算対象を1つ上の箱にする
JUMP LOOP1 ;空欄「c」アドレスの値はゼロやマイナスにならないから単純分岐
EXIT RPOP
RET
END

ここまでの流れをノートにまとめました。

設問3はプログラム1を使った足し算を呼び出してかけ算を行うプログラム2の問題です。32ビットのAとBという数の掛け算を行います。
乗算結果を64ビットのCに入れます。作業用に64ビットのTEMPという64ビットの領域を使います。それぞれの先頭アドレスを指すレジスタと演算に使う数値についてまとめました。

(GR1→)A:「0002」「0003」(以下0023)
(GR2→)B:「0004」「0005」
(GR3→)C:64ビットの空き領域
(GR7→)TEMP:64ビットの空き領域

プログラム2を動かして見ます。
(主記憶の状態を見やすいように、TEMPはメインプログラム内に書きました。)

A、B、C、TEMPが入りました。

GR1にA+0、GR2にB+0、GR3にC+0が入って、
プログラム2のMULT32を呼び出しました。

GR0にA+0に入っている0002が読み込まれました。

0002がTEMP+2に格納されました。

GR0にA+1に入っている0003が読み込まれました。

0003がTEMP+3に格納されました。

初期化に使う0が読み込まれました。

TEMPの上位ビットが0で初期化されました。

演算結果の入るCが0で初期化されました。

ループカウンタが読み込まれました。
カウンタであり、乗数をシフトするビットを表しています。

B+0が退避されました。

カウンタが退避されました。

16を引いたらマイナスになったので、乗数の下位語を読み込む処理に入ります。

乗数の下位の「0005」が読み込まれました。
0ビットシフトなので値は変わりません。

0005の最下位ビットは1なので、論理積を取って0001になりました。

C+0が読み込まれました。

TEMP+0が読み込まれました。
演算を行う領域の先頭アドレスが設定されたので、プログラム1のADD64を呼びます。
C :「0000」
TEMP:「0023」

プログラム1の加算処理は同じなので省略します。

C:「0023」つまり、「0023」×1

カウントアップされました。

GR1とGR2にTEMPの先頭アドレスを入れてプログラム1を使って加算処理をします。2倍になります。

TEMP:「0023」
TEMP:「0023」

TEMPが「0046」になりました。

つまり、「0023」×2^1です。
べき乗の1はカウンタと一致します。

プログラム2に戻り、B+0がGR2に戻りました。
ループまで戻りました。
GR6にGR5のカウンタ1が入り、16が引かれました。
1-16なのでまだマイナス、下位語の処理です。

乗数の5が読み込まれました。

1ビット右にシフトして0002になりました。

最下位ビットは0です。

カウントアップされました。
GR1、GR2にTEMPの先頭アドレスが読み込まれてプログラム1を呼びます。

TEMP:「0023」×2^1
TEMP:「0023」×2^1

の加算結果なので、

TEMP:「0023」×2^2が入って「4倍」されました。

プログラム2に戻り、GR2にB+0のアドレスが戻りました。
ループに戻ります。

乗数の「0005」が入りました。

乗数の「0005」を2ビットシフトして、「0001」になりました。
最下位ビットが1です。

GR1にC+0が読み込まれました。

GR2にTEMP+0が入りました。
これでプログラム1を呼ぶ準備が終わりましたので、プログラム1を呼びます。
C :「0023」×1
TEMP:「0023」×4
この加算で、

C:「0023」×5が入りました。
これで、Bの「0045」の「5」の乗算結果が入りました。

カウントアップされました。
GR1、GR2にTEMP+0が読み込まれてプログラム1の加算処理が行われます。

TEMP:「0023」×2^2
TEMP:「0023」×2^2

TEMP:「0023」×2^3
カウントが3なのでべき乗も3です。
つまり、16になると、「0023」×2^16で、「0230」になります。
ここまで進めます。

カウントが16になった時の主記憶です。

TEMPで「0023」が2^16倍されて「0230」になりました。

次から上位語の処理です。

16-16で0が入り、ここで初めてマイナスに分岐しなくなります。
つまり上位語を読み込みます。

Bの「0004」「0005」の「0004」が読み込まれました。
0ビットシフトで値は変わりません。

下位桁は0です。

カウントアップされました。
GR1とGR2にTEMPの先頭アドレスが設定されました。
プログラム1を呼びます。

TEMP:「0230」×2^0
TEMP:「0230」×2^0

TEMP:「0230」×2^1
ループに戻ります。

乗数をシフトするビット数です。

「0004」が読まれました。

1ビット右にシフトされました。

最下位ビットが0です。

カウンタが加算されました。
GR1とGR22TEMPのアドレスが読み込まれ、プログラム1を呼びます。

TEMP:「0230」×2^1
TEMP:「0230」×2^1

TEMP:「0230」×2^2(4倍)

ループに戻ります。
GR0に0004が読み込まれ、2ビットシフトして0001になり、
GR1にC+0、GR2にTEMP+0が読み込まれました。
C :「0023」×5倍
TEMP:「0230」×4倍
これで、「0023」×「0045」の演算が出来ました。


プログラム1は変わっていないので画像は省きます。


;平成29春64ビットの加算とそれを使った乗算
;メインプログラム
MAIN START
RPUSH
LAD GR1,A ;掛け算に使う数Aの先頭アドレス
LAD GR2,B ;掛け算に使う数Bの先頭アドレス
LAD GR3,C ;A×Bの結果領域
CALL MUL32
RPOP
RET
A DC #0002
DC #0003
B DC #0004
DC #0005
C DS 4
TEMP DS 4 ;演算結果を見やすくする為にメインプログラムへ移動

;プログラム2
MUL32
RPUSH
LAD GR7,TEMP ;初期化
LD GR0,0,GR1 ;GR1から始まる2語の領域の値を
ST GR0,2,GR7 ;TEMPから始まる4語の領域のうち
LD GR0,1,GR1 ;下位2語に格納
ST GR0,3,GR7
LD GR0,=0
ST GR0,0,GR7 ;TEMPから始まる4語の領域のうちの
ST GR0,1,GR7 ;上位2語に0を格納
ST GR0,0,GR3 ;GR3から始まる4語の領域に0を格納
ST GR0,1,GR3
ST GR0,2,GR3
ST GR0,3,GR3
LD GR5,=0 ;ループカウンタ
LD GR4,GR2 ;GR2の値をGR4に退避
LOOP2 LD GR6,GR5
SUBL GR6,=16 ;数Bの上位語か下位語か判断
JMI LOWORD ;空欄「e」32ビットのうちマイナスになるのは下位語
LD GR0,0,GR2 ;上位語の場合の処理
SRL GR0,0,GR6
JUMP TESTBIT
LOWORD LD GR0,1,GR2 ;下位語の場合の処理
SRL GR0,0,GR5
TESTBIT AND GR0,=#0001 ;最下位ビットが0か1か
JZE ELOOP
LD GR1,GR3 ;ADD64を呼ぶ準備で乗数の末尾が1の時
LAD GR2,TEMP
CALL ADD64
ELOOP CPL GR5,=31
JZE EXIT2
ADDL GR5,=1 ;カウントアップ
LAD GR1,TEMP ;ADD64を呼ぶ準備
LAD GR2,TEMP ;空欄「f」乗数の末尾が1の時も0の時も行う
CALL ADD64
LD GR2,GR4 ;GR4に退避した値をGR2に復帰
JUMP LOOP2
EXIT2 RPOP
RET

;プログラム1
ADD64
RPUSH
LD GR0,=0
LAD GR3,3,GR1 ;Aの一番後ろ4つ目
LAD GR4,3,GR2 ;Bの一番後ろ4つ目
LOOP1 LD GR5,=0 ;桁上りフラグ
ADDL GR0,0,GR3 ;Aを加算
JOV OV1 ;桁上りの分岐
JUMP NOV1 ;桁上りが無かった時
OV1 LD GR5,=1 ;空欄「a」桁上りフラグを立てる
NOV1 ADDL GR0,0,GR4 ;Bを加算
JOV OV2
JUMP NOV2
OV2 LD GR5,=1 ;空欄「a」
NOV2 ST GR0,0,GR3 ;加算結果をAへ格納
LD GR0,GR5 ;フラグを読み込んで次の加算へ
CPL GR3,GR1 ;空欄「b」全ての箱で処理が終わったか比較
JZE EXIT ;プログラムの修了へ分岐
SUBL GR3,=1 ;Aの加算対象を1つ上の箱にする
SUBL GR4,=1 ;Bの加算対象を1つ上の箱にする
JUMP LOOP1 ;空欄「c」アドレスの値はゼロやマイナスにならないから単純分岐
EXIT RPOP
RET
END

ご精読ありがとうございました。
平成21年春から平成30年秋までの20回分のうち、16回分のプログラミング及び
トレースが出来ました。
後は試験が終わったら残りの回のプログラミングとトレースをしながら試験結果を待ちたいと思います。

シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです

アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
息抜きに、写真で癒し(=^・^=)

モバイルバージョンを終了