狠狠撸
Submit Search
颁言语讲习会3
?
4 likes
?
2,076 views
O
odenhadengaku
Follow
未経験者のためのC言語講習会 資料/ C language for inexperienced people
Read less
Read more
1 of 61
Download now
Downloaded 28 times
More Related Content
颁言语讲习会3
1.
C言語講習会 第3回 ロボット技術研究会 @odenhadengaku
2.
前回のまとめ ? 変数,型 ? 制御構文(if,switch,for,while) ?
関数
3.
今日やること ? 配列再び ? ビット演算 ?
プリプロセッサをちょっと ? マイコンのプログラミングをちょっと
4.
関数[復習] ? 今まで,if,switch,for,while文を学んできた ? これだけで結構なことができる. ?
しかしこれだと,プログラムをすべてmainの 中に記述することになる. ? プログラムが非常に見難くなり,バグに対処しにくい ? 例えば「1からkまでの和」を求めるプログラムを何度も 使う時,そこにバグがあったらすべて書きなおさねばな らない ? 特定の処理をするプログラムを部品として使 いたい→関数
5.
関数[復習] ? 関数の定義方法 ? 関数には,引数と戻り値 (返り値)があり,returnに 達すると関数は終了 int
add(int a, int b){ … 処理; … return a + b; } 戻り値の型 関数名 引数 戻り値
6.
関数[復習] ? コンパイラはソースコードを上か ら解釈するので,予め「こういっ た関数を使う」と宣言をしないと, いざ関数を使うときにコンパイル エラーが発生 ? ideoneでは問題なく実行できるが,こ れは特殊.gccや他のIDEではエラー ?
予め宣言しておくことを,プロト タイプ宣言という. ? 3,4行目の部分
7.
関数[復習] ? 実は,変数には主に2種類ある ? ローカル変数 ?
グローバル変数 ? ローカル変数は,関数の内部 で宣言,定義される変数 ? 宣言した関数内でしか参照できな い ? 先ほど紹介したadd関数の変数a,b も,今までmain関数内で定義し た変数もすべてローカル変数 ? 関数が終了すると,メモリが消滅 するので値が保存されない ? 変数は定義しないと使えない ので,関数の最初で通常定義 する
8.
関数[復習] ? グローバル変数は,関数の{}の ブロックの外側で定義される 変数 ? いろんな関数から参照できる ?
プログラムが終了するまでメモリ が消滅しないので,値が保存され る ? プログラム全体で,普遍的な変数 を表現するのに便利 ? どこからでも参照できるとい うことは,どこからでも変え ることができてしまうので, むやみに利用すべきではない.
9.
演習 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型というのがある
10.
演習 1.
11.
演習 2. 104743
12.
配列再び ? 前回,前々回で少しだけ登場している配列 ? 「データを入れる箱」変数を1度にたくさん宣 言する方法として,配列がある ?
変数を100個も一々宣言するのは大変 ? int型で名前がdata,要素数が20の配列を宣言 するには以下のようにする int data[20]; 型 配列名 要素数
13.
配列再び
14.
配列再び ? int data[20];と宣言した時,data[k]と書くこと でk番目の要素にアクセスできる. ?
配列は0番目から始まる ? そして(要素数-1)番目までアクセスできる ? 1番目からではない ? data[20]だとdata[0] ~ data[19]にアクセスできる ? data[20]にはアクセスできない(?) ? 配列の要素数は,コンパイル時に決まっている 定数でしか指定できない. ? ユーザーが入力した値を[]内に入れて宣言することができ ない ? const int としても変数として扱われるのでダメ(コンパイ ラによってはできる)
15.
配列再び ? 配列にも初期化する方法があり、 int hoge[]
= {2,4,6}; ? とすると、値が初期化された要素数3の配列が できる ? この例はint hoge[3];として、hoge[0] = 2;hoge[1] = 4; hoge[2] = 6;としたのと同じ ? []内に要素数を書かなくても良い ? 宣言時にしか初期化できない
16.
配列再び ? 実際に実行して みよう ? これは有名な…?
17.
配列再び ? 実行結果
18.
文字列と配列[応用] ? 右のコードは1番はじめに登 場したHello World ?
そもそも”Hello World?n” ってなに? ? 文字(char)ではなく文字列 ? C言語にはStringという文字 列の型は存在しない(他の言 語にはある) ? 文字列は文字の配列、つまり char型の配列 ? 文字列はchar型の配列なので 、右のように変数helloに代入 できる
19.
文字列と配列[応用] ? 文字列 =
文字の配列なので、下のように書き換 えることもできる ? hello[0] = ‘H’ ,hello[1] = ‘e’といった具合 ? 一番右の’?0’は、ヌル文字と呼ばれ、文字列の終 端を表す記号 ? このヌル文字を使って、文字列の終端を検知する場合が多い
20.
文字列と配列[応用] ? printf関数に渡していた引数はchar型の配列 ? 実は、’a’,’b’といった文字はC言語内部では数字と 対応付けされている ?
ASCII(アスキー)コードという規格が存在する ? これにより、下の2つのコードは同義 ? 実はb = ’a’ + 1みたいなのもできる.
21.
多重配列[応用] ? 配列のなかに配列を作るこ ともできる ? 多重配列 ?
多重配列を用いることによ り、n次元に広がるデータを 扱える ? 例えば、行列、将棋の盤面 ? 定義は、 int matrix[3][3]; ? のように書く 型名 配列名 要素数
22.
配列[演習] 1. int型で要素数が100の配列を宣言し,それぞれの要素に 対し,インデックスが奇数ならば0,偶数ならば1を代入 し,出力せよ. ? hoge[0]
= 1; ? hoge[1] = 0; 2. 好きな型で好きな要素数の配列を好きな数で初期化し, (型:int,要素数:3ならint a[] = {2,4,6};)インデックスが大き い方から出力する.(上だと6,4,2と出力) ? for文を上手に利用する ? いつもはi++でインデックスが小さい方からだが… ? わからなかったら「C言語 hoge」とググれば,大体答えが 載っている
23.
配列[演習] 1.
24.
配列[演習] 2.
25.
おまけ ? 今まではprintf関数で出力ばっかりしてきた ? 入力はないの?ーもちろんある ?
入出力関数を使用するためにstdio.hというヘッ ダファイルをincludeする必要があった ? ヘッダファイルとは,特定の機能を持った関数を使いやすい ようにファイル分割したもの(?) ? ↑うまく説明できてないかもしれない ? 入出力関数はたくさんあるので,代表的なもの だけ紹介する
26.
おまけ ? scanf関数 ? 標準入力(キーボード)からの入力を変数へ読み 込む機能をもつ ?
printf()の入力版? ? &については今は説明省略 ? これはideoneで説明するのが難しい
27.
おまけ ? fopen関数 ? ファイルからデータを読み出す準備をする関数 ?
読み取りモード,書き込みモードなど様々なモー ドを設定できる ? ファイルを使い終わったらfclose()でクローズする ? ファイル操作についてはこれ以上詳しく説明しな い
28.
ビット演算(の前に) ? C言語ではなく,一般的な話 ? bit(ビット)とbyte(バイト)について ?
bit(ビット)とは0と1によるデータの単位のこと ? 1bitで0と1の2種類のデータが表現できる ? binary digitの略らしい ? 1byteは8bitであるのが一般的 ? 1byteで2^8=256種類のデータを表現できる ? 1KB = 1024B(byte) ? 基本的にコンピュータの内部では,データは2進 数,つまりbit単位で扱われる ? 001010111101011010010001110…
29.
ビット演算(の前に) ? しかし,0と1を羅列して2進数を表現するのは長 ったらしい ? 16進数という表現がある ?
0-9,A(10),B,C,D,E,F(15)の数で表現 ? 例をいくつか – 3A = 3 * 16 + 10 = 58 – FF = 15 * 16 + 15 = 255 ? 2進数と16進数との関係 – 58 = 0011 1010 (2) 3 A 00000000 0 00000001 1 00000010 2 00000011 3 … 11111110 126 11111111 127
30.
ビット演算(の前に) ? C言語では,先頭に0xをつける ことでその数が16進数である ことを示す – 8進数の場合先頭に0をつけ る –
(コンパイラによっては)先 頭に0bをつけることで2進 数を示せる ? 右のプログラムは,変数 hoge,piyoにそれぞれ16進数で 3A,FFを代入している
31.
ビット演算(の前に) ? 変数の値に対し,2進数(0と1)を表すビット単位 でデータ操作を行うことをビット演算と呼ぶ ? n桁目のビットを1にする ?
すべてのビットを左に1つずらす ? ビット演算は,特にマイコンを扱うにあたって欠 かせないものなので,今のうちに触れておく ? 欠かせない理由は後ほど
32.
ビット演算 ? 右のプログラムを実行し てみよう
33.
ビット演算 ? unsigned char型は0~255ま での値を格納できる –
前回説明した – 16進数だと0x00~0xFFまで – char型は-128~127 ? ビット演算子には,次のよう なものがある – 論理演算子(&&,||,!)とは違う ビット演算子 意味 & AND | OR ~ NOT ^ XOR << , >> ビットシフト !aと~aはまったく違う
34.
ビット演算 ? AND演算子(&)は各桁のビッ トに対して次の演算を行う – &&と間違えないように ?
0 & 0 = 0 ? 0 & 1 = 0 ? 1 & 0 = 0 ? 1 & 1 = 1
35.
ビット演算 ? OR演算子( |
)は各桁のビット に対して次の演算を行う – ||と間違えないように ? 0 | 0 = 0 ? 0 | 1 = 1 ? 1 | 0 = 1 ? 1 | 1 = 1
36.
ビット演算 ? NOT演算子( ~
)は各桁のビッ トに対して次の演算を行う – !と間違えないように ? ~0 = 1 ? ~1 = 0 ? ビットの反転
37.
ビット演算 ? XOR演算子(^)は各桁のビッ トに対して次の演算を行う – 累乗ではない –
排他的論理和といわれる ? 0 ^ 0 = 0 ? 0 ^ 1 = 1 ? 1 ^ 0 = 1 ? 1 ^ 1 = 0
38.
ビット演算 ? ビットシフト演算子(<<,>>) は全体のビットを左/右に指 定回数分だけずらす – 左ビットシフトの場合,ずらし た後の空白は0が入る –
右ビットシフトの場合,ずらし た後の空白は処理系によって変 わる ? 1010010110100 (左へ1ビットシフト) ? 0100101101000
39.
ビット演算 ? printfで%xを用いると,変数の値 を16進数で表示できる – %dは変数の値を10進数で表示するもの だった ?
結果が次のようになることを確認 しよう ? 10ではない.0x10(=10進数だと 16)
40.
ビット演算 ? これらの演算子は, +=,-=の演算 子のように,省略して書くことが できる unsigned
char a; a = 0x2F; a &= 0x3c; a |= 0xC0; … a &= 0x3C; a = a & 0x3C;
41.
ビット演算[演習] 1. 次の計算を行うとどうなるか,16進数で値を求 めよ.ただし,値は0x00~0xFF(unsigned char) とする.自分で変数を作って表示しよう. 1.
0x13 & 0x34; 2. ~0x1D; 3. 0xE2 << 2; 2. ある数に関して,特定の位置のビットだけ1に 変えるためにはどのような演算を行えばよいか .同様に,特定の位置のビットだけを0に変え るためにはどのような演算を行えばよいか考え よう. (例) 100101 → 101101
42.
おまけ ? 先ほどprintf()内で%xを用い て変数を16進数表示した – %dは変数を10進で表示するもの だった –
このような表示形式を指定する ものをフォーマット指定子とい う – 代表例は右に掲載 ? 他にも,小数点の桁数を指定 する方法や左詰/右詰,0埋め など色々なことをprintf内で 指定できる – 使い方はググって 指 定 子 対応する型 説明 %c char 1文字を出力 %s char * char [] 文字列を出力 %d int,short 整数を10進数 で出力 %u unsigned int unsigned short 符号なし整数 を10進で出力 %o (整数値を扱え る型) 整数を8進数で 出力 %x (整数値を扱え る型) 整数を16進数 で出力 %f float 実数を出力 %lf double 倍精度実数を 出力
43.
おまけ ? 「!」は論理演算子で否定(NOT)を表す. – 「!a」の場合,aが偽なら真を,真なら偽を返す ?
「~」はビット演算子で反転を表す. – 「~a」でa = 0xF0(11110000)の場合, 0x0F(00001111) a if(a) if(~a) if(!a) 0 else文 if文 if文 1 if文 if文 else文 123 if文 if文 else文 -1 if文 else文 else文 対応
44.
おまけ[応用] ? 先ほどの表でa =
-1のときの ~aは0だった – 0をビットで表すと 00000…00000 – だとすると-1は 11111…11111??? – そもそも負の数を2進数でどう 表すの? ? unsignedなどの指定がない場 合は,2進数の最上位ビット (1番左)で正負を判断している – 詳しくは2の補数でググろう char binary +127 01111111 +126 01111110 … +2 00000010 +1 00000001 0 00000000 -1 11111111 -2 11111110 … -127 10000001 -128 10000000
45.
おまけ[応用] ? 2の補数表現の利点は,減算 を加算で行えること – たとえば,1-1をしたい –
1-1 = 1 + (-1) – すると,1 00000000となるが,char 型は8ビットなので最上位の1は捨て られる – よって答えは00000000となる ? 右ビットシフト演算子(>>)をした 場合の空白に何が入るかは処理系 依存. – 一般的には符号あり=>最上位ビット ,符号なし=>0が埋められる – 処理系によってはいきなり負の数が正 になったり? char binary +127 01111111 +126 01111110 … +2 00000010 +1 00000001 0 00000000 -1 11111111 -2 11111110 … -127 10000001 -128 10000000
46.
プリプロセッサについてちょっと ? C言語によるプログラミング(GCCの場合) 1. ソースコードの作成 2.
コンパイル ? ソースコード(プログラミング言語)を機械語に変換すること ? 機械語に変換するツールをコンパイラという 3. 実行ファイルが生成される 4. 実行!! 実行結果
47.
プリプロセッサについてちょっと ? C言語によるプログラミング(GCCの場合) 1. ソースコードの作成 2.
プリプロセス 3. コンパイル ? ソースコード(プログラミング言語)を機械語に変換すること ? 機械語に変換するツールをコンパイラという 4. 実行ファイルが生成される 5. 実行!! 実行結果
48.
プリプロセッサについてちょっと ? コンパイルされる前に,ソースコードに対して 行われる処理をプリプロセスという.そして, プリプロセスをするものをプリプロセッサとい う – コンパイルとコンパイラの関係 ?
プリプロセッサは,#includeしたファイルを読み込んだ り,コメントを消したりしてくれる. – コメントは実際の動作には関係ない – コメントは機械語に変換するのにはいらない
49.
プリプロセッサについてちょっと ? 実行して確かめてみる
50.
プリプロセッサについてちょっと ? 毎回かいていた #include<~> は<>内に指定したファイル を読み込むという意味があ る – 今回はstdio.h(printfなどの 入出力の宣言が入っている) を読み込んでいる –
stdio.hのようなファイルを ヘッダファイルという
51.
プリプロセッサについてちょっと ? #define (A)
(B) ? と書くことで,(A)がすべ て(B)に置き換わる – マクロという – 右の例だとNUMはプリプロ セッサによって10になる – (B)に当たる部分は省略可 – #defineを用いると簡単な関 数のようなものが(作ろうと 思えば)作れる
52.
プリプロセッサについてちょっと #ifdef (A) … #endif ? で挟まれた部分のコード は,(A)が#defineによっ て宣言されていれば読み 込まれるが,宣言されて いないと読み込まれない ?
逆に#ifndefにすると宣言 しないと読み込まれる
53.
プリプロセッサについてちょっと[注意] ? #defineは,文字列をその まま置き換える作業をし ているので,注意しない とバグを引き起こしやす い – そのため#defineは多用しな いほうがよい –
定数を表現したいならば, const を用いればよい
54.
マイコンプログラミング ? 今までC言語の文法について色々と学んできたが, 具体的にマイコンにどう指示を与えるのかにつ いてはあまり触れなかった ? ほんの少しだけどのようにしてマイコンに対し てプログラムをするのかを考える –
详しい内容はマイコン讲习会にて
55.
マイコンプログラミング マイコン ?マイコンの働き 外部スイッチ ラインセンサー AD変換 モーター駆動 モーター ドライバ LED点灯ピンの電位 変化 デジタル値 PWM出力 ピンの電位 変化
56.
マイコンプログラミング ? 基本的に,マイコンには様々な種類の「レジス タ」と呼ばれるものがあり,これらを操作する ことで様々な設定を行う – 下の表はAVRの入出力ポートB(Atmelデータシートより) –
わからない?俺もわからない
57.
マイコンプログラミング ? このレジスタを操作する際に,ビット演算の知識をとて も使う – マイコン講習会ではビット演算を駆使するらしい –
例えば,PORTBに0x2Aを代入すると… – 0x2A = 00101010なのでPORTB1,PORTB3,PORTB5に相当するピ ンが出力(1)になる 0 0 1 0 1 0 1 0
58.
マイコンプログラミング ? 出力が1となったピンは,電圧がオン(5V) にな る –
下の例はマイコン础迟迟颈苍测2313
59.
マイコンプログラミング ? 特定のピンだけ(例えばPORTB2)を1に変えるに は, ? PORTB
|= ( 1 << 2); ? と書けば良い ? 特定のピンだけ(例えばPORTB2)を0に変えるに は ? PORTB &= ~(1 << 2); ? と書けば良い ? どちらもビット演算で登場した演算子
60.
マイコンプログラミング ? AVRでLチカをするコード ? 何やってるかはわからなくて よい –
マイコン講習会で丁寧に教えて くれるはず – ビット演算めっちゃしてるな~ くらいに思っておけば良い
61.
予告 ? 今までの復習 ? 構造体?共用体 ?
ポインタ 本日は以上です ありがとうございました
Download