第19回 マルバツその2
- Aコース
コマンドプロンプト上でプログラムを書けるように…
コマンドプロンプト上のテキストエディタを使いたい。。
(0)vimに触れてみよう。
以下のリンクを参考に
Vimの使い方
test.txt というファイルを作成して,helloと書いてみよう.
(1)Vimの設定
vimはそのままだとプログラミングのときの色が使かないので、
次のような設定ファイルをつくり/home/名前 に保存する
ーーーーーーーーーーーーーーーーーーーーーーーーーー
set encoding=cp932
set fileencoding=cp932
set termencoding=cp932
set fileencodings=iso2022-jp,uts-8,uts-16,euc-jp,cp932
set encoding=cp932
set fileencoding=cp932
set termencoding=cp932
set fileencodings=iso2022-jp,uts-8,uts-16,euc-jp,cp932
syntax on
set ruler
set number
set incsearch
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
(1)cd ~ ホームディレクトリ(/home/xxx)に移動(設定ファイルをおいておく)
(2)vim .vimrc vimが起動.
(3)iを押してinsertモードへ
(4)上の(1)--と--の間を右クリップでコピー
(5)vim上にはりつけ
(6)「ESC」を押してコマンドモードに入る
(7):wq 保存して終了する.
(8)ls コマンドで.vimrcがみえないことを確認
(9)ls -a で.vimrcが見えることを確認(.ではじまるのは,隠しファイルのため-aオプションを使わないとみえない)
(10)cat .vimrc でファイルの内容を確認
以下は、配列でマルバツを作るプログラムをvimで作る.
- Bコース
以下のを表示するプログラムを書こう
>||
* *
* *
* *
**********
* *
* *
* *
**********
* *
* *
* *
|
次に左上から枠の番号を1,2,3,4,5,6,7,8,9として,
i=1 としたら、右だから1番目が0と表示されるように
i=3 としたら、右から3番目が0が表示されるようにする.
i=5 としたら、右から5番目に0を表示されるように
18回:演習:マルバツゲームを作る1
- マルバツゲームを作りながら必要な手法を学んでいく.
- マルバツゲームは、入力->機械計算->出力->入力->機械計算->出力->入力->...の繰り返し.
- コンピュータの代表的な処理を含んでいて,かつ,難しくないのでプログラミングの演習にはもってこい
- ここでの目的はマルバルゲームを作りながらこれまでまなんだことを復習しつつ,実践的なプログラミングの方法を学んでいく
- 本日の目標
- マルバツゲームをつくるためにとりあえず対話的に入力する必要があるので,
入力ができるようになる.
-
- 2つの数字をいれてそれの和を出力するプログラムを作る
- 枠を作って,任意の場所に「0」や「○」をいれられることがポイント
- C言語における入力
scanf関数を使う.
scanf関数の基本
int a;
a=3;
みたいなのをaにコンピュータから入力をする場合,
scanf("%d",&a);
とかく.scanf("%d",&変数) するところがポイント.まず,"%d"を無視して,&の部分に着目する.
&の部分はどの変数に代入したいかでかわる.もし,bならば
int b=6;
となら、
scanf("%d",&b);
とする.
もし,testならば
int test=6;
となら、
scanf("%d",&test);
に置き換えればいい.
- 以下無視しても大丈夫
次に,"%d"の部分に着目する.これはprintfと同じ方式である.
例えば,"test1test"と入力してもらい,1を変数aに代入する場合は,
int a;
scanf("test%dtest",&a);
とすればいい.
printfと同じで2つの変数もできる.
hello13hello12と入力してaとbに入れる場合は
int a,b;
scanf("hello%dhello%d",&a,&b);
これはカンマ区切りの文章を読み取るときに応用できる.
int a,b,c;
scanf("%d,%d,%d",&a,&b,&c);
とすれば134,425,62や41,32,12のようなカンマ区切りの文章を入力をうけつけられる.
- 例えば,以下のプログラムをつくってみる
int main(){ int a; scanf("%d\n",&a); printf("a is %d.\n",a) }
入力待ちがわからないので,
int main(){ int a; printf("aの値を入力してください\n"); scanf("%d\n",&a); printf("a is %d.\n",a) }
とするとよい.
- 演習
(1)aとbの値の入力をうけつけて,「aは..です,bは..です」
というプログラムを作りなさい.
(2)aとbを足した結果を出力したプログラムをつくりなさい.
具体的には,「aを入力してください」,入力,「bを入力してください」,入力,「a+b=xxです」と表示する.例えば,a=3, b=2; 「a+b=5です」と表示.
(3)入力した数だけ,連続した数字を出力するプログラムをだしなさい
例えば,5を入力したら,1,2,3,4,5と出力,10を入力したら,1,2,3,4,5,6,7,8,9,10と出力.
(4)5個の数字の入力を受け付け、その和を求める、プログラミングを書きなさい.非配列->配列.
第12回 配列
- 今回は、
「配列」を行います。
いままで行ったC言語文法
(1)変数の扱い方
ポイント:-箱を用意して(宣言)、使う。
-整数と実数を区別する int と double
(2)繰り返し: whileループ, forループ
(3)条件分岐: if文
(4)printf の使い方
プログラムの基本自体は、ほぼこれだけ。
(1)データの入力: ソースに書きこむ。
(2)データをつかるようにコンピュータにのせる(変数)
(3)変数にのせたデータを加工する:(制御構造 for while if)
(4)出力する (printf )
これまので、一通りできるようになった。
具体的には、
- データの入力:ソースに書きこむ。
- 変数:データをコンピュータにのせる:int double
- 条件にあわせて加工:制御構造: for, while if
- 出力: printf
基本的にいままでの組み合わせ理屈の上では、なんでもできる。。
ただ、理論上はできても、やっぱり不便。。
それなので、それぞれをもっとよくしていく。
例えば、「入力->ファイルから入力したい!」、「一つの処理の流れの短縮ダイヤルみたいなのを作りたい!」、「ファイルに出力したい」、「たくさんのデータをまとめてつかいたい!」
- ということで、今回は変数のパワーアップ。たくさんの変数を番号で区別してまとめて扱う方法「配列」を勉強します。例えば,配列はIDに変数をたくさんまとめて使いたいときに使います.例えば,企業1の売上,企業2の売上,企業3の売上,...
。
- 配列
「配列」とは、番号づけられた変数です。 これまでは、一つの数字に一つの変数を用意してきた。
たとえば、10個の整数[52,51,42,45,56,45,30,23,52,50]の和を計算する場合は、
int a=52;
int b=51;
int c=42;
int d=45;
...int sum=a+b+c+d+...;
printf("合計は%d\n",sum);
とひとつひとつやってきた。 でも、これだと整数が1000個とかたくさんになるときつい。
そこで、変数を数字で区別できるといいんじゃないか->配列。
以下のように書く。
変数名[番号]
例えば,具体的には,
a[0],a[1],a[2],a[3],... という形。
配列の使い方:
まずは、普通の変数と同じように、「配列使うよ、よろしく」と宣言が必要。
宣言のしかたは,その際は、箱の型とが箱が何個いるかを伝えるのポイント。型 a[配列の数];
例えば,
int a[100]
だったら、aの数字つきの箱を整数型で100個用意して
a[0],a[1],...,a[99]
が使えるようになる。
配列へのアクセスは,
注意:普通の変数にa0,a1,a2,..という名前をつけても,
a[i]的にiを変数でアクセスできない。配列だと
#include<stdio.h> int main(){ int a[100]; //100個の配列を用意,宣言が一回でいい。 a[0]=3; a[1]=2; a[2]=5; a[3]=0; a[4]=2: //2番目の箱を表示,スタートが0なので。 printf("%d\n",a[1]); //5番目の箱を表示, printf("%d\n",a[4]); return 0; }
同じことを普通の変数だと
#include<stdio.h> int main(){ int a0; int a1; int a2; int a3; int a5; a0=3; a1=2; a2=5; a3=0; a4=0; printf("%d\n",a1); printf("%d\n",a4); return 0; }もう少し省略できる
int a[5];
a[0]=3;
a[1]=2;
a[2]=5;
a[3]=0;
a[4]=2:の部分を
int a[5]={3,2,5,0,2} //5個の要素を持つ配列を用意して,それを代入する.
と書ける.
応用として,配列のデータの合計を求める.
例2:合計の計算
http://www.cc.kyoto-su.ac.jp/~yamada/programming/array.html より。#include <stdio.h> int main() { int a[10] = {4, 2, 11, 4, 15, 7, 9, 12, 3, 6}; int i, sum; sum = 0; for (i = 0; i < 10; i++) { sum =sum+ a[i]; /* 総和の計算 */ } printf("合計は %3d\n", sum); return 0; }
例題1)算数と国語と社会のそれぞれの児童の合計点
を配列を用いたプログラムで計算せよ.
>>
A君 B君 C君 D君 E君 F君 G君 H君 I君 J君 K君
生徒番号 1 2 3 4 5 6 7 8 9 10 11 12 13 14
算数(点) 10 20 30 40 5 32 2 3 32 56 32 2 32 12 31
国語 (点)0 30 40 60 7 62 4 5 34 82 52 2 42 35 12
社会 (点)32 42 60 70 72 12 9 2 42 92 61 43 32 21 12ヒント1 echo "10 20 30 40 5 32 2 3 32 56 32 2 32 12 31" | sed "s/ /,/g"
ヒント2 int sansuu[11]={10,20,30,40,5,...}ヒント3
疑似コード配列:整数型 算数=[10 20 30 40 5 32 2 3 32 56 32 2 32 12 31] 配列:整数型 国語=[0 30 40 60 7 62 4 5 34 82 52 2 42 35 12 ] 配列:整数型 社会=[32 42 60 70 72 12 9 2 42 92 61 43 32 21 12] 整数型 生徒数=15 整数型 合計点 iが1から[生徒数]まで以下の{..}の間を繰り返す { 合計点=算数[i]+国語[i]+社会[i] "生徒番号yyyの3教科の合計点は=xxx点です.[改行]"と出力. //yyyには生徒番号1から13,xxxには合計の点数が入ります,yyyはiに対応し,xxxは合計点に対応") }出力例
生徒番号1の3教科の合計点は=324点です.
生徒番号2の3教科の合計点は=123点です.
生徒番号3の3教科の合計点は=32点です.
...例1-2)三教科の合計点50点以上が合格者とします.生徒番号ごとに合格者と不合格者を判定を出力するコードをかけ.
疑似コード配列:整数型 算数=[10 20 30 40 5 32 2 3 32 56 32 2 32 12 31] 配列:整数型 国語=[0 30 40 60 7 62 4 5 34 82 52 2 42 35 12 ] 配列:整数型 社会=[32 42 60 70 72 12 9 2 42 92 61 43 32 21 12] 整数型 生徒数=15 整数型 合計点 iが1から[生徒数]まで以下の{..}の間を繰り返す { 合計点=算数[i]+国語[i]+社会[i] もし,合計点が50点より小さかったら以下の{...}内のコードを実行 { "xxxさんは不合格です.[改行]"と出力 //xxxはiの数字を出力} それ以外は {"xxxさんは合格です.[改行]"と出力 //xxxはiの数字を出力} }出力例
1さんは不合格です.
2さんは合格です.
3さんは不合格です.
...
...
例題1-3)合計点が50点以上,国語の点数が40点以上の場合のみ合格とするときに,合格と不合格の判定プログラムを書け.
ヒント if(合計点が50点以上 かつ 国語の点数40点以上) とする.
- 「かつは &&」例: (x>2 && y>5)
例題1-4)合計点が50点以上かつ国語の点数が40点以上 もしくは,算数×国語=56点以上の場合のみ合格とするときに,合格と不合格の判定プログラムを書け.
ヒント if(合計点が50点以上 かつ 国語の点数40点以上) とする.
- 「または ||」例: (x>2 || y>5)
- if((合計点が50点以上 かつ 国語の点数40点以上) または 算数×国語>=56)
scanf 関数の参考ページ
http://ratan.dyndns.info/MicrosoftVisualC++/nyuryoku.html例題2-2)2つの入力をうけつけその数字の和を計算するプログラムをつくれ
ヒント)
変数aを入力
変数bを入力
a+bを出力例題2-3)10つの数字の入力をうけつけその数字の和を計算するプログラムをつくれ
ヒント)
配列 a[10]
ループ 0から9 はじめ
a[0]からa[9]まで入力
ループおわりa[0]~a[10]の和を求める(ループを使用).
第11回 Forループ
呪文
- まずは、#include で準備。。
- 箱をつかうときは,intで宣言する、箱の準備する。
- 箱の中身をprintfするときは,%d(int) %lf(float) あとでi,j
本日
sedの基本
forループ
コンピュータがつかえるとは、
sedは置換コマンド
sed "s/置換される文字列/置換する文字列/g" 入力ファイル
例)
置換できました。
で、これができてなにがうれしいの?
組み合わせて使うとすごい。
例)
発言数の上位20人のランキングをつくる
grep id: mos.txt | egrep ^[1-9] | sed "s/.*id//g" | sort | uniq -c | sort -k1,1gr | head -20
sedの便利さ
w3m -dumbをつかえば、、任意のスレッドできる。
w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ | grep ID: | egrep ^[1-9] | sed "s/.*ID//g" | sort | uniq -c | sort -k1,1gr | head -20
41 :XNHSBaLb0
29 :2kUo8A0Q0
26 :Hex50I1R0
21 :C6SxJR8Ei
21 :u5/mHqZg0
18 :APnpQBLz0
17 :7aHefTDS0
17 :k0Piz1rM0
16 :7s4G8Qtii
15 :h6zqwMyV0
14 :0hunu4GS0
14 :M49pSyca0
14 :Y4Xv99erO
13 :McM1bTAa0
13 :U2NmTN180
13 :wBfC8oQv0
12 :QI6fWUcO0
11 :VE5CClVa0
11 :xncE2u280
10 :qFDPNu8JO
w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ grep XNHSBaLb0
何を書き込んでる?
w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ | grep -A10 2kUo8A0Q0
URLをとりだす。
grep href subback.html | awk -F"\"" '{print $2}' | sed "s/\/.*//
他の同じ板のスレにはかきこんでるのか?
for i in `grep href subback.html | awk -F"\"" '{print $2}' | sed "s/\/.*//g" | egrep ^[0-9]`;do w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/| grep -A10 2kUo8A0Q0 ; sleep 10;done
「おい」の2ちゃんねるスレッドの検索
for i in `grep href subback.html | awk -F"\"" '{print $2}' | sed "s/\/.*//g" | egrep ^[0-9]`;do w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/$i | grep -A10 おい ; sleep 10;done
何分ごとに書き込んでる?
w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ | grep XNHSBaLb0 | sed "s/ID.*//g" | sed "s/.*) //g" | sed "s/:/ /g" | awk '{str=3600*$1+60*$2+$3;print (str-str2)/60;str2=str}'
平均は?
$ w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ | grep XNHSBaLb0 | sed "s/ID.*//g" | sed "s/.*) //g" | sed "s/:/ /g" | awk '{str=3600*$1+60*$2+$3;print (str-str2)/60;str2=str}' | awk 'NR!=1{str=str+$1}END{print str/NR}'
2位の人は?
w3m -dump http://daily.2ch.net/test/read.cgi/newsplus/1410998447/ | grep 2kUo8A0Q0 | sed "s/ID.*//g" | sed "s/.*) //g" | sed "s/:/ /g" | awk '{str=3600*$1+60*$2+$3;print (str-str2)/60;str2=str}' | awk 'NR!=1{str=str+$1}END{print str/NR}'
11.2797
forループ
繰り返しにはwhileループとforループの2種類あります。
前々回には,whileループをやりました。
- これまでの復習 whileループ
while(条件){
条件が真のとき実行
}
1から100までの数字を3おきに表示
例:1,3,5,7
- while文
#include<stdio.h> int main(){ int i; i=1; while(i<=100){ printf("%d\n",i); i=i+3; } }
i=1とか
i=i+3繰り返しに関することがバラバラになっていて,みにくい。
そこで,for文:
#include<stdio.h> int main(){ int i; for(i=1;i<=10;i=i+2){ printf("%d\n",i); } return i; }
繰り返しに関することは,前に書いてしまおう。
第10回 演習
今回は演習です。
以下の問題に答えてください
(1)以下の文字列がコマンドプロンプトに表示するプログラムを作りましょう。
(2)1673 ×4649 の値を求めよ.
ヒント int i;i=1673*4649; iを表示.
(3)以下の文字列が表示されるプログラムを書きましょう
ヒント1重ループを使います.
*...の部分は省略なので、abc6efg, abc7efgと続きます。
abc1efg
abc2efg
abc3efg
abc4efg
abc5efg
.....
....
...
abc99efg
abc100efg
(4)以下の画面を表示するプログラムを作れ.
ヒント:2重ループを使ってください.
1abc1
1abc2
1abc3
2abc1
2abc2
2abc2
3abc1
3abc2
3abc3
(5)まずは,A×B=24 となる,正の整数Aと正の整数Bをすべて求めよ.
ヒント:2重ループとif分を使います.等しいは「=」でなく「==」であることに注意,「×」は「*」.
(i)2重ループでA=1,B=1;A=1,B=2;A=1,B=2,...A=1,B=23;A=1,B=24;,A=2,B=1;A=2,B=2,...,A=23,B=24,A=24,B=24
としてすべての場合のA*Bを確かめる
(ii)if文で24になるものだけを表示する.
イメージ
while(Aのループ){
while(Bのループ){
if(A×Bは24に等しい){
AとBを表示
}
}
}
(6)A×B=25252525 (ニコニコニコ)
となる整数Aと整数Bは存在するか? (A=1 もしくは B=1の場合は除く.)
存在するとしたらその値はなにか?求めよ.
例えば,A×B=6 ならば、A=2とB=3に分解できる.A×B=15 なら,A=3とB=5に分解できる.
ヒント:2重ループとif分を使います.等しいは「=」でなく「==」であることに注意,「×」は「*」.
(i)2重ループでA=1,B=1;A=1,B=2;A=1,B=2,...,A=2,B=1;A=2,B=2,...,A=10000,B=9999,A=10000,B=10000
としてすべての場合のA*Bを確かめる
(ii)if文で25252525になるものだけを表示する.
まずは,A×B=6の場合で確かめるといいかも。
(7)A×B=724106(何してる)や A×B= 14106 (愛してる)は同様の分解は存在するか?
第九回 分岐:if文
コマンド
- いままでのでてきたコマンド
必修
cd, pwd, ls, grep, cat, head, tail
そのほか
history, wc, w3m,
- 今回は地味なもの.
- mkdirコマンド: フォルダをつくる.
mkdir フォルダ名
例 tmp1という名前のフォルダをつくる。
mkdir tmp1
-
- mvコマンド:ファイルの名前を変える
mv 元のファイル名 変えたいファイル名
echo "test"
testと表示するコマンド
echo "test" > test.txt
リダイレクトでtext.txtファイルを作成。
mv test.txt test.c
今作った,test.txt をtest.cに変更.
-
- mvコマンドは移動もできる.
mv 元のファイル名 移動したいフォルダ名
mv test1.txt tmp1
例)
mkdir tmp1
tmp1というフォルダをつくる.
C言語
条件分岐をやります.
条件分岐は,大雑把にいうと,
「~のとき(条件)」に「...」を実行する
というものです.
- 基本的には,以下のように書きます.if文といいます.
if(条件){ 条件をみたしたときの実行内容 }
- elseを後ろにつけると条件をみたさない場合も書けます.If Else文といいます。
if(条件){ 条件をみたしたときのの実行内容 }else{ 条件をみたさないときの実行内容 }
条件は,
i<j: iがjより小さい場合 i>j: iがjより大きい場合 i<=j: iがjより小さい場合(iとjが等しいを含む) i>=j: iがjより大きい場合(iとjが等しいを含む) i==j: iとjが等しい場合(「i=j」でないので注意!.) i!=j: iとjが等しくない場合
ほかは、おいおいやる.
&& かつ (and) || または (or) ! 否定
例えば,
if(i>=2 && j>=3) ならば,iが2以上かつjが3以上
if(i>=2 || j>=3) ならば,iが2以上またはjが3以上
if(i>=2 && j>=3 && k<3) ならば,iが2以上かつjかつ3以上かつkが3以上
if(!(i<=2)) 「iが2より小さく」ない、ときに実行
if(!(i<=2 && j>=3)) 「iが2より小さくかつjが3より大きい」ではない、ときに実行
- 例 iが負の値だったら警告をだすをたす.
i=2だと、、、
//はコメントなので「//」ではじまる行は無視されることに注意
int main(){ int i; i=2; printf("start\n"); if(i<0){ printf("Negative!\n"); } printf("end\n"); }
実行結果
start
end
i=-3だと、、、
int main(){ int i; i=2; //i=-3; printf("start\n"); if(i<0){ printf("Negaive!\n"); } printf("end\n"); }
実行結果
start
Negative!
end
- 例 値が10のときだけ1000をたす.
i=-3 だと,
int main(){ int i; //i=2; i=-3; printf("start\n"); if(i==10){ sum=i+1000 } printf("%d\n",sum); }
i=2 だと,
//はコメントなので「//」ではじまる行は無視されることに注意
int main(){ int i; i=2; //i=10; printf("start\n"); if(i==10){ sum=i+1000 } printf("%d\n",sum); }
出力
ik
i=10だと,
int main(){ int i; //i=2; i=10; printf("start\n"); if(i==10){ sum=i+1000 } printf("%d\n",sum); }
ポイント 「==」は等しいの意味。代入の=と区別する.
-
- 実数だと?
x=10.3のときに100を足す.
|
x=10だと,
int main(){ double x; double sum; //i=2; x=10; printf("%lf\n",x); if(x==10.3){ sum=x+100; } printf("%lf\n",sum); }
x=10.3のときに100を足す.
|
第8回 2重ループ
前回までの復習
- 前々回
whileループとリダイレクト
- 前回
grepとパイプ
- 復習
いつものところにtest8_1.cと保存.
cygwin上で移動,
#include <stdio.h> #include <math.h> int main(){ int i; i=0; while(i<=10000){ printf("i=%d, i*i=",i,i*i); i=i+1; } return 0; }
gcc test8_1.c -o test8_1.out
./test8_1.out
while文
while(条件){
繰り返し内容
}
条件をみたすときに繰り返す.
i=i+1で1をカウントしてるのがポイント
偶数刻みならi=i+2;
リダイレクト(ファイルに書き出す)
./test8_1.out > tmp.txt
パイプ 1342の2乗を表示
./test8_1.out | grep 1342
パイプ 134の2乗を表示
./test8_1.out | grep i=134,
本日のコマンド (head tail more)
- head
- 基本 (ファイルのはじめの10行を表示)
例1:
head mos.txt
例2:
head test8_1.c
-
- オプション機能を使えば最初10行でなく何行でも表示させられませす
head -n はじめのn行を表示
例1(はじめの30行を表示):
head -n 30 mos.txt
例2(はじめの5行を表示):
head -n 5 test8_1.c
-
- headはリダイレクトと組み合わせでよく使う
最初のほうが流れてみれない!
./test8_1.out
最初10行
./test8_1.out | head
最初100行
./test8_1.out | head -100
- tail
- 基本 (ファイルの最後の10行を表示)
例1:
tail mos.txt
例2:
tail test8_1.c
-
- 応用 最後のほうを表示
tail -n 最後のn行を表示
例1(最後の30行を表示):
tail -n 30 mos.txt
例2(最後の5行を表示):
tail -n 5 test8_1.c
-
- リダイレクトとの組み合わせでよく使う
プログラムの最後のほうだけ表示したい
./test8_1.out
最後の10行
./test8_1.out | tail
最後100行
./test8_1.out | tail -100
- more
- 基本 (ファイルの内容をゆっくり表示)
例1:
more mos.txt
例2:
more test8_1.c
-
- リダイレクト組み合わせでも使う
プログラムの最後のほうだけ表示したい
./test8_1.out
最後の10行
./test8_1.out | more
-
- 実はmoreと似たコマンドのlessが高機能なので推奨,しかし,微妙に複雑なので割愛.
C言語
- 二重ループ
#include <stdio.h> #include <math.h> int main(){ int i,j; i=1; j=1; while(i<=3){ printf("i change: i=%d j=%d\n",i,j); while(j<=4){ printf("i=%d j=%d\n",i,j); j=j+1; } j=1; //jをリセット printf("j loop is over\n"); i=i+1; //iに1を加える } printf("owari\n"); return 0; }
i change i=1 j=1
i=1 j=1
i=1 j=2
i=1 j=3
i=1 j=4
j loop is over
i=change i=2 j=1
i=2 j=1
i=2 j=2
i=2 j=3
i=2 j=4
j loop is over
i change i=3 j=1
i=3 j=1
i=3 j=2
i=3 j=3
i=3 j=4
owari;
解説:
(1)i=1 ->iに1を代入 (2)j=1 ->jに1を代入 (3)while(i<=3){ ->一つ目のループに入る.i=1でi<=3 を満たすので実行 (4) printf("i change: i=%d j=%d\n",i,j); ->iは1, jは1なので i=1, j=1と表示. (5)while(j<=3){ ->j=1でj<=4を満たすので実行 (6) printf("i=%d j=%d\n",i,j); ->i=1 j=1 と表示. (7)j=j+1; ->j=1+1=2 (8) printf("i=%d j=%d\n",i,j); ->i=1 j=2 と表示. (9)j=j+1; ->j=2+1=3 (10) printf("i=%d j=%d\n",i,j); ->i=1 j=3 と表示. (11)j=j+1; (12) printf("i=%d j=%d\n",i,j); ->i=1 j=4 と表示. (13)j=j+1 ->j=4+1=5 (16)j=5なのでj<=4を満たさないのでjに関するループ脱出. (17)j=1; //jをリセット ->j=1にする. (18)printf("j loop is over\n"); ->j loop is over と表示 (19) i=i+1; i=1+1=2 (20) while(i<=3) ->iは3以下なのでループに入る. (21) printf("i change: i=%d j=%d\n",i,j); ->i change: i=2 j=1 と表示. (22) while(j<=4) -> j=2なのでループに入る (23)2つ目のループに入る j=1でj<=4を満たすので実行 (24) printf("i=%d j=%d\n",i,j); ->i=2 j=1 と表示. (25)j=1+1; ->j=1+1=2 (26) printf("i=%d j=%d\n",i,j); ->i=2 j=2 と表示. (27)j=j+1; ->j=2+1=3 (28) printf("i=%d j=%d\n",i,j); ->i=2 j=3 と表示. (29)j=j+1; (30) printf("i=%d j=%d\n",i,j); ->i=2 j=4 と表示. (31)j=j+1 ->j=4+1=5 (32)j=5なのでj<=4を満たさないのでjに関するループ脱出. (17)j=1; //jをリセット ->j=1にする. (18)printf("j loop is over\n"); ->j loop is over と表示 (19) i=i+1; ->i=1+2=3 (20) while(i<=3) ->iは3以下なのでループに入る. (21) printf("i change: i=%d j=%d\n",i,j); ->i change: i=3 j=1 と表示. (22) while(j<=4) -> j=2なのでループに入る (23)2つ目のループに入る j=1でj<=4を満たすので実行 (24) printf("i=%d j=%d\n",i,j); ->i=3 j=1 と表示. (25)j=1+1; ->j=1+1=2 (26) printf("i=%d j=%d\n",i,j); ->i=3 j=2 と表示. (27)j=j+1; ->j=2+1=3 (28) printf("i=%d j=%d\n",i,j); ->i=3 j=3 と表示. (29)j=j+1; (30) printf("i=%d j=%d\n",i,j); ->i=3 j=4 と表示. (31)j=j+1 ->j=4+1=5 (32)j=5なのでj<=4を満たさないのでjに関するループ脱出. (33)j=1; //jをリセット ->j=1にする. (34)printf("j loop is over\n"); ->j loop is over と表示 (35) i=i+1; ->i=3+1=4 (36) while(i<=3) ->i=4で3以下でないのでループに入らない (37) printf("owari\n"); ->owari と表示
- 三重ループ
#include<stdio.h> int main(){ int i; int j; int k; while(i<=3){ while(j<=3){ while(k<=3){ printf("%d %d %d\n",i,j,k); k=k+1; } k=1; j=j+1; } j=1; i=i+1; } return 0; }
#書き方がポイント ブロックごとに書いていく
step1
while(){
}
step 2
while(){ while(){ } }
step 3
while(){ while(){ while(){ } } }
step 3
while(i<=3){ while(j<=3){ while(k<=3){ printf("%d %d %d\n",i,j,k); k=k+1; } k=1; j=j+1; } j=1; i=i+1; }
課題:
2ケタのピタゴラス数を求めよ
(1)ピタゴラス数とは?
(2)i,j,kについてそれぞれ1から100までいかのように表示されるプログラムを作れ
>|sh|
1 1 1
1 1 2
1 1 3
...
2 1 1
2 1 2
...
100 100 98
100 100 99
100 100 100
|
(3) i*i j*j k*k が(2)のように表示されるプログラムを作れ
(4) i*i j*j k*k i*i+j*j-k*k が(3)のように表示されるプログラムを作れ
(5) grep を使って,上記のプログラムを改造し,grepを使って選択することでピタゴラス数を求めよ
-ヒント (3)のプログラムの4列目が0になるものがピタゴラス数
-4列目に diff= とかつけることで印をつける.