狠狠撸
Submit Search
颁言语讲习会2
?
6 likes
?
2,854 views
O
odenhadengaku
Follow
未経験者のためのC言語講習会 資料/ C language for inexperienced people
Read less
Read more
1 of 71
Download now
Downloaded 26 times
More Related Content
颁言语讲习会2
1.
C言語講習会 第2回 ロボット技術研究会 情報工学科 @odenhadengaku
2.
今日やること ? 変数,型の続き ? 制御構文 ?
関数
3.
変数 型(復習) ? 情報を数値や文字とし て保存する必要がある ?
ロボットが何回線を通過 したか ? 成績の合計値 ? C言語では数値や文字な どの情報を変数として 保持することができる a 3
4.
変数 型(復習) ? 変数にはどのデータを入れて もいいわけではない ?
整数,小数,文字などタイプを 指定する必要がある →型 ? 変数を定義するには, int a; (型)(変数名) のように記述する ? 定義せずに,いきなりaを利用す ることはできない ? 変数名は基本自由 ? int b,c,d,e;のようにまとめて定義 もできる.この場合すべてint型
5.
変数 型 [注意] ?
ここで,右のコードに ついて考えてみる ? double型の変数dを表示 させるには, printf(“%f?n”,d); とする ? 一見すると,d,eの値は 同じであるように見え るが…?
6.
変数 型 [注意] ?
出力結果は ? 結果が違う.なぜ? ? 異なる型同士の演算も 出来る場合もあり,そ の場合は精度の高い方 の型 ? intとdouble → double ? a/b はdouble型の値
7.
変数 型 [注意] ?
8行目の,a/cではint型 同士の計算のため,答 えはint型.除算の際に 小数部分が切り捨てら れてしまう.切り捨て られた後にeに代入され る ? よくあるミスで, エラーも出ないので注 意
8.
変数 型 [注意] ?
じゃあどうすれば? →キャスト演算子 ? (double) a; ? と書くと,変数aがこの 命令に限りdouble型とし て扱われる ? 8行目を ? double e = (double) a/c; ? とすればdとeは同じ値に
9.
変数 型 [注意] ?
右のプログラムはただ 2147483644から1ずつ足す だけ ? もちろん答えは…?
10.
変数 型 [注意] ?
実行結果 ? 突然負の値に ? 壊れた?
11.
変数 型 [注意] ?
数は無限には扱えない.上限,下限がある ? 変数はコンピュータのメモリ上にあるから ? よくあるバグの1つ ? 上限を超えることをオーバーフローという ? 逆に下限を下回ることをアンダーフローという ? long int,long long int とすると…? 変数の型 最小値 最大値 char -2^7(-128) 2^7-1(127) int (32bit) -2^31(-2147483648) -2^31(2147483647) float ±10^(-38)くらい ±10^(38)くらい double ±10^(-308)くらい ±10^(308)くらい
12.
演習というほどのものではない何か ? ちょっと考えてみよう 1. char型の変数cを文字’p’で初期化し,「初期化した文字 はpです」と出力させよう ?
文字の場合は ‘(シングルクォーテーション)で囲む ? printfでchar型の変数を表示させるには,%cを使う 2. double型の変数p,qを定義し,好きな値を代入してから, 1次方程式px + q = 0の解を出力せよ. ? printfでdouble型の変数を表示させるには,%fを使う
13.
演習というほどのものではない何か 1. 2.
14.
unsigned,const,volatile [応用] ? C言語では扱える数に制限がある ?
負の数にはならないから,正で扱える数を増や したい場合がある ? unsigned を使う ? 型の前につける ? unsigned char, unsigned int… 変数の型 最小値 最大値 unsigned char 0 255 unsigned int (32bit) 0 4294967295
15.
unsigned,const,volatile [応用] ? 1度定義した変数の値を絶対に変わらないことを 保証したい場合がある ?
自分で定義した定数とか ? const を使う ? 型の前につける ? const char, const int… ? constをつけた変数は,値を変更できない. ? 定義するときに,初期化しておく必要あり
16.
unsigned,const,volatile [応用] ? 実はコンパイルする際に,コンパイラはソース コードを最適化することでパフォーマンスを向 上させている ?
無駄な処理を省く,使われてない変数を消去… ? この最適化は,時として仇になる ? マイコンには割り込みという機能がある ? ある処理をしてる時に,その処理に割り込む形で他の処理をす ること ? 変数が最適化されてしまうことにより,割り込み処理が期待通 りに動かないことがある.
17.
unsigned,const,volatile [応用] ? 最適化したくない場合は,その変数の宣言時に volatile
int a; ? とすることで,この変数は最適化の影響を受け ない ? もし,マイコンの割り込み処理が期待通り行かない場合は, これを疑ってみるとよい 通常時処理 通常時処理 割り込み 処理
18.
ここで一区切り ? 今までは上から下の一本道のコードだった ? 一本道だと変数の中身によってコードを変えら れない –
aが偶数/奇数だったらこの処理を…ができない ? 同じような処理を何回もしたい場合は何回も似 たコードを書かなければならない – a[0] = 1; a[1] = 1;…a[99]=1; 100回も書くの? ? これからは1本道ではなく,分岐や繰り返しを する処理を学ぼう
19.
制御構文(if) ? 右のソースコードを書い て実行しよう – 答えは省略 –
でもなんとなくわかるよね …? ? できた人は,4行目の数 字を変えて,自分の予想 と合っているか確かめて みよう
20.
制御構文(if) ? もし~だったら~する ? こういうのはif文を用いる if(条件式){ 処理; } else
if(条件式){ 処理; } … else{ 処理; }
21.
制御構文(if) ? if-elseは省略可/複数可 ? else
は省略可 ? 条件式は非0の時,真 – if(1)は必ず中身の処理を行う – if(0)は必ず中身の処理を行わない
22.
制御構文(if) ? 関係演算子とは d >
4 ? のように2つの値を比較す る演算子 – 条件が真ならば1を – 条件が偽ならば0を返す. ? 複数の条件(AかつBなど)を 使いたい場合は,論理演 算子を使う
23.
制御構文(if) 関係演算子 意味 <,> より大きい/小さい <=,>=
以上,以下 ==,!= 等しい,等しくない 論理演算子 意味 &&,|| かつ,または ! 否定 ? if(x == 1 && y == 2) ? xが1かつyが2の時は真 ? if(x == 1 || y == 2) ? xが1もしくはyが2の時は真 ? if(!(x == 1 && y == 2)) ? xが1かつyが2の時でない時は 真
24.
制御構文(if)[注意] ? if(d ==
4)をif(d = 4) としてしまうミスが多い ? d = 4は,代入を意味し, 「d = 4」を評価すると代 入した値が返ってくる. – if(d = 4) はif(4)となり常に真 – コンパイルエラーにならない
25.
制御構文(switch) ? 右のコードを書いてみよう ? これも答えを予想してみよ う –
caseの行の最後は「;」では なく「:」です
26.
制御構文(switch) ? 右のように変数dが1か, 2か3か…を判断するのに if-elseを用いると冗長 – else
ifをたくさん繋げることになる – switch文で綺麗に ? switchで指定された条件式 の値と同じ値のcaseにジャ ンプする ? break;に達するとswitch文 の{}から脱出 ? どのcaseにも一致しない場 合,defaultにジャンプ
27.
制御構文(switch)[注意] ? switch文は整数値しか判定 できない – double,char型などの判定は できない ?
break; のつけ忘れに注意 – 付け忘れると,そのまま下の 行の命令を実行してしまう – 8行目のbreakがないと, case1の場合に,「dは1で す」と「dは2です」が両方 出力される
28.
制御構文(switch)[注意] ? 逆に,”わざと”breakを付 けないことで,次のような プログラムもかける
29.
制御構文(if,switch)[注意] ? double,float型など,実数 を扱う型で==,!=を用いる と厄介 ? 右のプログラムを実行する と”aとbは同じ”と出力され そうだが,実際は… –
理由は,内部的には2進数で 表現されているが,それでは 10進数が正確に表せないから – コンピュータサイエンスの 授業で詳しくやる(はず) ? 実数型では,==,!=を使う べきでない
30.
忘れてたやつをいくつか??? ? ideoneのホームを開いた時にある //your code
goes here ? はコメントといい,プログラムの動作には関係 ない – だから残したままでもいい – ここでこんなことをしていると書くことで,後で見返 したり,他の人が見るときにわかりやすくする – 「//」はその行の//以降がコメントされる – 「/*」と「*/」の間はすべてがコメントされる
31.
忘れてたやつをいくつか??? ? if-else文を1行で簡潔に書きたい場合がある ? 三項演算子(関係演算子) ?
(条件式) ? (A) : (B) – 条件式が真のときはAが,偽のときはBが実行される – int abs_a = (a >= 0) ? a : -a; – 可読性があまり良くないので,使うべきでない派と使ってもいい だろ派がいたりいなかったりする(気がする)
32.
忘れてたやつをいくつか??? ? 今まで様々な演算子を取り扱ってきた – =,+,-,*,/,++,--,<,… –
これらには順序/優先度がある – (2 + 3) * 4 なら()が先 – とりあえず()が一番 – 詳しいことは,必要なときにググれば良い
33.
制御構文(for) ? 今までは分岐につ いて ? これからはループ について ?
右のコードを書い て実行しよう
34.
制御構文(for) ? for文は繰り返しを 実現する機能 for(i =
1; i <= 10; i++){ 処理; } 初期化 条件式 更新
35.
制御構文(for) ? for文は繰り返しを 実現する機能 ? 「初期化」で変数 の値を決定 ?
「条件式」が真の 間変数を「更新」 し続けながら処理 を繰り返す 初期化 条件式 更新 処理ループを抜ける 偽 真
36.
制御構文(for) ? 具体的には, 初期化 iに1を代入
i : 1 条件式 i<=10は真 i : 1 処理 printfを実行 i : 1 更新 i++; i : 2 条件式 i<=10は真 i : 2 ?????? 更新 i++; i : 11 条件式 i<=10は偽 ループを抜ける 10回繰り返される
37.
制御構文(for) ? break;を使うとfor 文の{}の中から抜け 出せる – switch文の{}を抜け 出せたのと同じ ?
右下のプログラム は,iが5の時に強制 的にループから抜 ける – Hello World 5回目 は出力される…?
38.
制御構文(for) ? 実行結果は以下の 様になるはず
39.
制御構文(for) ? 前回少しだけ話した配列 – 箱がたくさんあるイメージのやつ –
int a[100];のように宣言する – for文と相性がよい 右のように[]の中にiという 変数を使うことで1度の記 述ですべての箱(変数) にアクセスできる
40.
制御構文(while) ? 以下のコードを実行してみよう
41.
制御構文(while) ? ループの回数が不明である場合がある – 下のプログラムは,1からいくつまでの値を足すと100を超え るか計算するもの.しかし,何回ループすればいいのかは不 明 –
このようなときに飞丑颈濒别文は便利
42.
制御構文(while) ? while文は,条件式が真であるかぎりループし続ける ? 下では,sum
< 100であるかぎり,countに1を足し, sumにcountをたすという処理をし続ける. ? for文と同様に内部で,break;も使用できる while(条件式){ 処理; }
43.
制御構文(while) ? 条件式は,0以外なら真,0ならば偽となる(ことを前に 説明).つまり,右下のようにすると無限ループになる. – 常時処理をループさせて,必要なときにbreak;を用いてループ から抜けるなどの手法を用いることもある. while(1){ 処理; if(何か) break; }
44.
制御構文(do-while) ? while文では,最初から条件式が偽だった場合は,中身 の処理は行われない ? 条件式の結果に関わらず,最低1回は処理をしたい場合 がある ?
そのときは,do-while文を用いる ? あまり使わない do{ 処理; }while(条件式);
45.
制御構文(while) ? 以下のコードを実行した結果は次のようになる ? 気づいた人もいるかもしれないが,for文とwhile文は 書き換え可能
46.
制御構文の演習 1. 1から2015までの和を求めるプログラムを,for文を 使って書いてみよう. 2. 1から2015までの和を求めるプログラムを,while文を 使って書いてみよう. 3.
1000 未満の 3 か 5 の倍数になっている数字の合計を 求めよ.(PE1より) ? 3の倍数かどうかはn % 3の余りを見れば… ? 「3か5の倍数」よりor,つまり「||」(論理和)が必要
47.
制御構文の演習 sum: 2031120
48.
制御構文の演習 sum: 233168
49.
忘れてたやつをここで??? ? if,for,while文の中身の処理が1行である場合は, {}を省略できる ? 右はif文の例.他も同様 ?
しかし注意して欲しいのは, {}がないと,1行しかif文の効果が適用されな いということ
50.
再びのvolatile[応用] ? 以前出てきた最適化をしないよう命令する volatileはどう使われるのか ? マイコンにおいて,割り込み処理によってflag 変数が1となるまでプログラムを停止させてお く方法として下が考えられる ?
flagが0であるかぎり無限ループ ? 処理すらない場合 … … … while(flag == 0); …
51.
再びのvolatile[応用] ? コンパイラから見ると,変数 flagは変更されない値にしか 見えない ? 割り込み処理はマイコンによる 処理のため ?
flagが変更されないので,コンパ イラは非効率と判断する ? わざわざ1回ループするごとにflagを 評価しているため ? よってコンパイラは勝手に右 のように最適化をする場合が ある ? flagの評価は1回で済む … … … while(flag == 0); … … … … if(flag == 0) while(1); …
52.
再びのvolatile[応用] ? このように書き換えられると, 割り込み処理でflagが1になっ てもループからは抜け出せな い ? flag変数にvolatileをつけるこ とで,最適化を防ぐ! ?
他にも,変数の代入順序を最 適化により勝手に変えられた くない場合などにも有効 … … … while(flag == 0); … … … … if(flag == 0) while(1); …
53.
関数 ? 今まで,if,switch,for,while文を学んできた ? これだけで結構なことができる. ?
しかしこれだと,プログラムをすべてmainの中 に記述することになる. ? プログラムが非常に見難くなり,バグに対処しにくい ? 例えば「1からkまでの和」を求めるプログラムを何度も使う 時,そこにバグがあったらすべて書きなおさねばならない ? 特定の処理をするプログラムを部品として使い たい→関数
54.
関数 ? 関数の定義方法 ? 関数には,引数と戻り値 (返り値)があり,returnに 達すると関数は終了 int
add(int a, int b){ … 処理; … return a + b; } 戻り値の型 関数名 引数 戻り値
55.
関数 ? 右では,8行目でadd(3,4)を 評価する際に,14行目の関 数の実体を呼び出す.このと き,aには3,bには4が入る. ? returnに到達すると,関数は 終了し,戻り値を持って8行 目に戻る.cには7が代入され る ?
戻り値は1つしか返せない 関数 引数 引数 引数 戻り値
56.
関数 ? 引数や戻り値がないような関 数の場合はvoidを指定する. ? この関数を呼び出す際には, 引数の情報はいらないが()は 省略できないので,10行目 のように ?
printfHW(); ? のように呼び出す
57.
関数 ? 実は,今まで使ってきた mainは,main関数という関 数 ? 引数はなく,戻り値として0を 返す関数と解釈できる ?
文字を表示するのに使ってい たprintfも関数 ? 中身を記述しているのがstdio.h
58.
関数 ? コンパイラはソースコードを上か ら解釈するので,予め「こういっ た関数を使う」と宣言をしないと, いざ関数を使うときにコンパイル エラーが発生 ? ideoneでは問題なく実行できるが,こ れは特殊.gccや他のIDEではエラー ?
予め宣言しておくことを,プロト タイプ宣言という. ? 3,4行目の部分
59.
関数 ? 実行結果は以下の様になるはず
60.
関数 ? 右のプログラムについて考え る ? 変数localと変数globalの挙動 の違いを考える.
61.
関数 ? 実は,変数には主に2種類ある ? ローカル変数 ?
グローバル変数 ? ローカル変数は,関数の内部 で宣言,定義される変数 ? 宣言した関数内でしか参照できな い ? 先ほど紹介したadd関数の変数a,b も,今までmain関数内で定義し た変数もすべてローカル変数 ? 関数が終了すると,メモリが消滅 するので値が保存されない ? 変数は定義しないと使えない ので,関数の最初で通常定義 する
62.
関数 ? グローバル変数は,関数の{}の ブロックの外側で定義される 変数 ? いろんな関数から参照できる ?
プログラムが終了するまでメモリ が消滅しないので,値が保存され る ? プログラム全体で,普遍的な変数 を表現するのに便利 ? どこからでも参照できるとい うことは,どこからでも変え ることができてしまうので, むやみに利用すべきではない.
63.
関数 ? 右のプログラムでは ? のように動作する global
local 1回目func() 0 → 1 0 → 1 2回目func() 1 → 2 0 → 1 3回目func() 2 → 3 0 → 1 保存 保存 破棄 破棄
64.
関数 ? したがって実行結果は ? のようになる
65.
関数[応用] ? 先ほど変数は2種類といった が,もう1種類存在 ? 静的なローカル変数 ?
右の17行目のローカル変数を ? static int local = 0; ? とすればいい ? ローカル変数とグローバル変数の 中間の性質を持ち,宣言した関数 からしか呼び出せないが,関数が 終了しても値は保存される. ? プログラムの実行結果はglobalと 同じ結果に
66.
関数[応用] ? 関数は自分自身を呼び出して 使うことができる.→再帰 ? 再帰を使うことで繰り返し処 理(for,while)を用いるよりもプ ログラムが簡潔に書ける場合 がある ?
右は,nの階乗を再帰あり/な しで求める関数 ? 漸化式を想像するとわかりや すい?
67.
関数[応用] ? 例えばfactorial(3);とすると, factorial(3) 3 *
factorial(2) 2*factorial(1) 1*factorial(0) 1 となるので, 3 * (2 * (1 * (1))) → 6 となる
68.
おまけ ? ローカル変数は関数内でのみ参照できる ? それは,変数にはスコープ(有効範囲)があるから ?
{}で囲まれた部分がスコープになる ? スコープを超えて参照できない. ? 右のプログラムを見ると,変数kの スコープは6行目の}まで ? なのでコンパイルエラーが起こる ? スコープに注意すると,右下 の7,9行目は何が出力される?
69.
おまけ ? 今まで条件文を習ったが,無条件分岐をするgoto文と いうものもある ? しかしこれは禁じられた条件文と言われるほど(?) 使うべきでないという暗黙の約束がある ?
goto文を使うと,プログラムに一貫性がなくなり,構造が崩れ るため ? どうしても知りたいならググってください
70.
演習 1. 次の関数を作ってみよう 1. 整数型の引数aをとり,1からaまでの合計を戻り値 として返す関数 2.
整数型の引数a,bをとり,a^2 + b^2を返す関数 2. [難?]引数nを与え,素数ならば1,そうでないならば0 を返す関数を作成し,それを利用して10001番目の素 数を求めよ.(PE7) ? なぜ素数ならば1で,そうでないなら0なのかというと,素数 判定する関数をisPrime(int n)とすると if(isPrime(n))で「nが素 数ならば」を表現できるため ? 他の言語だと真偽を表すbool型というのがある
71.
予告 ? 配列再び ? ビット演算 ?
マクロ 本日は以上です ありがとうございました
Download