情報処理Ⅱ 第4回 2007年10月29日(月).

Slides:



Advertisements
Similar presentations
プログラミング論 第八回数字の計算,整数の入出力. 本日の内容 前回の課題(続き) 前回の課題(続き) 数字の計算をする 数字の計算をする – 加減乗除を行う – インクリメント演算子とデクリメン ト演算子.
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
第6回条件による分岐.
演算、整数型と浮動小数点型 第3回目 [4月27日、H.16(‘04)] 本日のメニュー 1)前回の課題・宿題 2)ファイルサーバの利用
プログラミング言語としてのR 情報知能学科 白井 英俊.
初年次セミナー 第4回 整数と実数の取り扱い.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第7回 データの基本型 情報・知能工学系 山本一公
演算、整数型と浮動小数点型 第3回[平成16年4月27日(火)]:PN04ー03.ppt 今日の内容 1 復習 2 加減・乗除演算子
基礎プログラミングおよび演習 第9回
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
構造体.
情報処理Ⅱ 2007年12月10日(月).
1.12 式における型変換 1.13 代入における型変換 1.14 コメント 10月31日(金) 発表者:藤井丈明
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
情報処理3 第5回目講義         担当 鶴貝 達政 11/8/2018.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
情報処理Ⅱ 2007年11月5日(月).
プログラムの制御構造 選択・繰り返し.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
情報処理Ⅱ 第2回 2007年10月15日(月).
プログラミング演習I 2003年5月7日(第4回) 木村巌.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング 3 構造体(2).
04: 式・条件分岐 (if) C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング演習Ⅱ 課題4第3週 画像処理 (1) ビット演算子.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
計算機構成 第2回 ALUと組み合わせ回路の記述
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
2013年度 プログラミングⅡ ~ 計算してみよう ~.
2015年度 プログラミングⅡ ~ 計算してみよう ~.
情報処理Ⅱ 第2回:2003年10月14日(火).
プログラミング演習I 2004年5月19日(第5回) 理学部数学科・木村巌.
コンパイラ 2011年10月20日
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
地域情報学 C言語プログラミング 第2回 変数・配列、型変換、入力 2017年10月20日
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
情報処理Ⅱ 第3回 2007年10月22日(月).
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
情報処理Ⅱ 2005年10月28日(金).
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング演習I 数値計算における計算精度と誤差
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
情報処理Ⅱ 第2回 2004年10月12日(火).
モバイルプログラミング第2回 C言語の基礎 (1).
第3回簡単なデータの入出力.
情報処理Ⅱ 2005年11月25日(金).
プログラミング1 プログラミング演習I 第2回.
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
マスク合成(のような処理) 出力画像 Out 入力画像1 In1 In1 In2 Out 入力画像2 In
左右反転と180度回転 [0][xsize – 1] [0][0] → i ↓ j [ysize – 1][xsize – 1]
情報処理Ⅱ 小テスト 2005年2月1日(火).
JavaScript    プログラミング入門 2-3 式と演算子 2006/10/12 神津 健太.
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
情報処理Ⅱ 第3回 2004年10月19日(火).
情報処理Ⅱ 2006年10月20日(金).
C言語講座 四則演算  if ,  switch 制御文.
情報処理Ⅱ 2006年10月27日(金).
Presentation transcript:

情報処理Ⅱ 第4回 2007年10月29日(月)

本日学ぶこと 演算子(Operator) 問題 +, -, =, %, ++ ,&& ,||, == など C言語ではどんな演算子が使用できるか? 演算子間の優先順位はどうなっているか? 例: 1 + 2 * 3 と書けば,(1 + 2) * 3 ではなく 1 + (2 * 3) と解釈される.このとき,* は + よりも 優先順位が高いという. 問題 整数が与えられたとき,そのビットパターンを出力できる? 例: (char型の) 40 のビットパターンは,00101000 int型やlong型,float型のビットパターンは?

演算子一覧 関数呼び出し( ),配列の添字[ ],構造体のメンバ参照(., ->) 単項演算子(!, 単項*, ++, 単項+, sizeof, キャストなど) 乗除(2項*, /, %) 加減算(2項+, 2項-) シフト(<<, >>) 関係(<, >, <=, >=) 関係(==, !=) ビット演算(&) ビット演算(^) ビット演算(|) 論理演算(&&) 論理演算(||) 3項演算子(? :) 代入演算子(=, +=など) コンマ(,) 高い 優先順位 低い 優先順位を変えたければ,( ) で囲む.( ) が何重にもなることがある.{ } や [ ] は,この目的で使用できない. 入p.314 リpp.155-156

単項演算子 増分演算子,減分演算子: ++, -- 正負の符号: +, - sizeof演算子: sizeof キャスト演算子: (型名) sizeof(char) は 1 char x; に対して sizeof(x) も 1 キャスト演算子: (型名) 1/3 は 0 (float)1/3 は 0.333… (float)(1/3) は 0.0 実数型やポインタ型の変数もオペランドにできる. オペランドは変数名,式 もしくは型名. 慣習として ( ) をつけるが, 関数呼び出しではない. ( ) は必須 リp.158

単項演算子:注意点 原則として,オペランドの前(左)につける. 増分演算子と減分演算子はオペランドの後ろにつけることもできるが,前につけるのと意味が異なる. x = --y; ⇒ 「y = y - 1; x = y;」 と同じ(減分を先に評価). x = y--; ⇒ 「x = y; y = y - 1;」 と同じ(減分を後で評価).(x = y)--; ではない. 増分演算子と減分演算子のオペランドは,左辺値であり,かつ算術型またはポインタ型でなければならない. 入pp.209-210 リp.158

ビット演算子 整数値をビット(0と1)の並びとみなし,ビット単位(bitwise)で演算を行う. ビット単位AND: & (2項演算子) ビット単位OR: | (2項演算子) ビット単位XOR: ^ (2項演算子) ビット単位NOT: ~ (単項演算子) 例: 1 & 2 は0である. 優先順位は ~ > & > ^ > | 代入演算子 &=, |=, ^= も利用可能. 入p.203-204 リp.161

ビット演算 ビット単位の演算結果であることに注意. x y 1 x & y x | y x ^ y x ~x 1 1 ビット単位の演算結果であることに注意. 0 ^ 1 = 1 ^ 0 = 1 (相補律) 1 ^ 1 = 0 (ビットの反転), x ^ x = 0 (ビットのクリア)が成り立つ.

ビット演算子の利用例 一部のビットを0にする. 一部のビットを1にする. 一部のビットを反転する. 全部のビットを反転する. char x = 35; のとき x & 0x0f は 3,x & 0xf0 は32. 一部のビットを1にする. char x = 0x23; のとき x | 0x0f は 0x2f,x | 0xf0 は0xf3. 一部のビットを反転する. char x = 0x23; のとき x ^ 0x0f は 0x2c,x ^ 0xf0 は0xd3. 全部のビットを反転する. x = ~x; とすればよい. x=35 : 00100011 0x0f : 00001111 x & 0x0f : 00000011 x | 0x0f : 00101111 x ^ 0x0f : 00101100 ~x : 11011100 入p.205

シフト演算子 整数値をビットの並びとみなす. 左シフト: << 右シフト: >> いずれも2項演算子で,左オペランドは整数値,右オペランドはシフトするビット数(0以上の整数値). 5 << 3 は 40 m << n は m×2n m >> n は m×2-n 負の数を右シフトしたときの結果は処理系依存. 代入演算子 <<=, >>= も利用可能. 5 → 00000101 ← 40 >> 3 5 << 3 → 00101000 ← 40 入pp.205-206, p.123 リp.159

ビットパターン出力プログラム:準備 対象(入力)は,unsigned char型の値 x=40 … 1 1 簡単のため ビット長が分かれば,他の整数型にも適用可能 x=40 … 1 1 char40.c

ビットパターン出力プログラム … 検査方法 x: 1 1 b: 1 b: 1 b: 1 b: 1 bの初期値は,1 << 7 1 1 b: 1 x & bは0 ⇒ 0 を出力 b: 1 x & bは0 ⇒ 0 を出力 b: 1 x & bは非0 ⇒ 1 を出力 … b: 1 x & bは0 ⇒ 0 を出力

3項演算子 オペランド1 ? オペランド2 : オペランド3 まずオペランド1を評価する.それが真であればオペランド2を,偽であればオペランド3を評価して,その値を演算結果とする. 例: t = (a > b) ? a : b; ⇒ if (a > b) {t = a;} else {t = b;} と同じ 演算結果は左辺値ではない × a > b ? a : b = 10; ○ *(a > b ? a : b) = 10; 3項演算子の入れ子も可能だが,読みにくい a, bはポインタ変数 入p.216 リpp.162-163

これらは構文の一部であり,演算子ではない. その他の演算子 関数呼び出し: ( ) 配列の添字: [ ] コンマ演算子: , for (i=0, max=-1; scanf("%d", &d[i]) == 1; i++) これらは構文の一部であり,演算子ではない. リp.157, p.165

補足 Cらしい式の例 結合規則 代入の順序

Cらしい式の例 xの値を1だけ増やす xの値を倍にする xが偶数か奇数か判定する xが0か否か判定する x++; 実数なら,x *= 2; if (x & 1) 初回授業で紹介した「if (x % 2)」は,やや非効率 xが0か否か判定する if (!x) ただし,if (x == 0) を推奨する

結合規則 同じ優先順位の演算子が並ぶ場合にも,評価の順序があり,「結合規則」または「結合の向き」と呼ばれる. 左から右への結合(左結合) x = y - z + 2; ⇒ x = (y - z) + 2; と同じ 右結合でない演算子 右から左への結合(右結合) x += y = z + 2; ⇒ x += (y = z + 2); と同じ 単項演算子,3項演算子,代入演算子 入p.314 リp.148

代入の順序 オペランドの評価順序は,特に明記したものを除いて,不定(処理系依存)である.式の中で同一の変数などに2つ以上の代入をしないよう心がける. 例: x=2; printf("%d %d", ++x, ++x); の出力は 「3 4」かもしれないし,「4 3」かもしれない. 例: x % 2 ? (x = x * 3 + 1) : (x /= 2); は意図通りに動作する(が,if文で書くほうが自然). 「副作用完了点」という概念もあるが,授業では説明しない. リp.177

まとめ Cでは多彩な演算子が利用できる.いくつかは数学の記号に近く,いくつかはC独特である. 演算子ごとに「優先順位」と「結合規則」が決まっている. 真偽の扱い,評価されない式にも注意する.

値の評価の注意点 オーバーフロー アンダーフロー 計算誤差 暗黙の型変換

範囲を越えるとどうなるか? signed char型変数に13*13を格納すると? 13はint型定数で,13*13は,int型の169と評価される. これをsigned char型変数に格納しようとすると,169から256を引いた-87が代入される. signed char a = 127; a++; だと,aの値は128ではなく-128になる. 値が,型の取り得る範囲を超えるために,変わってしまうことを,オーバーフロー(桁あふれ)という. 入p.134 リp.151 13x13.c

無限小? 1から始めて2でどんどん割っていくと,いずれは0になる. 浮動小数点数の計算で,表現できる精度よりも小さくなり,値が変わる(0などになる)ことを,アンダーフローという. double d; for (d = 1; d > 0; d /= 2) { printf("%g\n", d); }

1なのに,1でない? for文を用いて,0, 0.1, 0.2, ..., 1.0 を取り出す,間違った方法 0.1という値を,計算機内で誤差なく表現できない.「計算誤差」により,0.1×10が1でないという事態が起こる. プログラミングの心がけ (最善) 実数型はループ用変数にしない. (次善) != ではなく,> や < を用いて判定をする. double d; for (d = 0; d != 1; d += 0.1) 入pp.136-137 リp.66 from0to1bad.c

異なる型の値同士の計算 1/3 と 1.0/3 と 1/3.0 と 1.0/3.0 は同じ値? 算術演算において,大きい範囲の型に揃えられる. int > short, int > char (汎整数拡張) long double > double > float > long long > long > int (暗黙の型変換) unsigned > signed プログラミングの心がけ unsignedとsignedの整数値を混在させて演算しない. 1/3 は,0.それ以外の上の式はすべて0.333… リpp.150-153

代入時の型変換 代入演算子では,必ず左辺の型に変換される. double d; int x; に対して x = d = 1.0/3.0; ⇒ d = 0.333…; x = 0; と同じ d = x = 1.0/3.0; ⇒ x = 0; d = 0.0; と同じ 代入演算子を使って複数の変数に代入するときは, 変数の型,および代入する値を同じものとする(例えば「x = y = 0;」)のが通常である. 一つの文で複数の変数に値を格納することを,一括代入という. プログラミング言語によっては,「x, y = 1, 2;」といった書き方で一括代入ができるが, Cでこの式は,二つあるカンマが演算子であり,優先順位に注意すると結局, 「y = 1;」となってしまう.

まとめ オーバーフロー,計算誤差,型変換に注意.