プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)

Slides:



Advertisements
Similar presentations
ゲームプログラミング講習 第2章 関数の使い方
Advertisements

サービス管理責任者等研修テキスト 分野別講義    「アセスメントと        支援提供の基本姿勢」 <児童発達支援管理責任者> 平成27年10月1日.
ヒトの思考プロセスの解明を目的とするワーキングメモリの研究
第27講 オームの法則 電気抵抗の役割について知る オームの法則を使えるようにする 抵抗の温度変化を理解する 教科書P.223~226
コラッツ予想の変形について 東邦大学 理学部 情報科 白柳研究室 山中 陽子.
コンパイラ 第3回 字句解析 ― 決定性有限オートマトンの導出 ―
第5章 家計に関する統計 ー 経済統計 ー.
公共財 公共経済論 II no.3 麻生良文.
VTX alignment D2 浅野秀光 2011年12月15日  放射線研ミーティング.
冷却フランシウム原子を用いた 電子の永久電気双極子能率探索のための ルビジウム磁力計の研究
生命情報学 (8) スケールフリーネットワーク
前半戦 「史上最強」風 札上げクイズ.

認知症を理解し 環境の重要性について考える
フッ化ナトリウムによる洗口 2010・9・13 宮崎市郡東諸県郡薬剤師会 学校薬剤師  日高 華代子.
食品の安全性に関わる社会システム:総括 健康弱者 ハイリスク集団 HACCP (食肉処理場・食品工場) 農場でのQAP 一般的衛生管理
規制改革とは? ○規制改革の目的は、経済の活性化と雇用の創出によって、   活力ある経済社会の実現を図ることにあります。
地域保健対策検討会 に関する私見(保健所のあり方)
公共政策大学院 鈴木一人 第8回 専門化する政治 公共政策大学院 鈴木一人
医薬品ネット販売規制について 2012年5月31日 ケンコーコム株式会社.
平成26年8月27日(水) 大阪府 健康医療部 薬務課 医療機器グループ
平成26年度 呼吸器学会からの提案結果 (オレンジ色の部分が承認された提案) 新規提案 既収載の変更 免疫組織化学染色、免疫細胞化学染色
エナジードリンクの危険性 2015年6月23日 経営学部市場戦略学科MR3195稲沢珠依.
自動吸引は 在宅を変えるか 大分協和病院 院長         山本 真.
毎月レポート ビジネスの情報 (2016年7月号).
医療の歴史と将来 医療と医薬品産業 個人的経験 3. 「これからの医療を考える」 (1)医薬品の研究開発 -タクロリムスの歴史-
社会福祉調査論 第4講 2.社会調査の概要 11月2日.
2015年12月28日-2016年3月28日 掲載分.
2010度 民事訴訟法講義 補論 関西大学法学部教授 栗田 隆.
腫瘍学概論 埼玉医科大学国際医療センター 包括的がんセンター 緩和医療科/緩和ケアチーム 奈良林 至
“企業リスクへの考え方に変化を求められています。 トータルなリスクマネジメント・サービスをプロデュースします。“
情報漏えい 経済情報学科 E  西村 諭 E  釣 洋平.
金融班(ミクロ).
第11回 2009年12月16日 今日の資料=A4・4枚+解答用紙 期末試験:2月3日(水)N2教室
【ABL用語集】(あいうえお順) No 用語 解説 12 公正市場価格 13 債権 14 指名債権 15 事業収益資産 16 集合動産 17
基礎理論(3) 情報の非対称性と逆選択 公共政策論II No.3 麻生良文.
浜中 健児 昭和42年3月27日生まれ 東京都在住 株式会社ピー・アール・エフ 代表取締役 (学歴) 高 校:千葉県立東葛飾高校 卒業
COPYRIGHT(C) 2011 KYUSHU UNIVERSITY. ALL RIGHTS RESERVED
Blosxom による CMS 構築と SEO テクニック
記入例 JAWS DAYS 2015 – JOB BOARD 会社名 採用職種 営業職/技術職/その他( ) 仕事内容 待遇 募集数
ネットビジネスの 企業と特性 MR1127 まさ.
Future Technology活用による業務改革
ネットビジネス論(杉浦) 第8回 ネットビジネスと情報技術.
g741001 長谷川 嵩 g740796 迫村 光秋 g741000 西田 健太郎 g741147 小井出 真聡
自然独占 公共経済論 II no.5 麻生良文.
Autonomic Resource Provisioning for Cloud-Based Software
Webショップにおける webデザイン 12/6 08A1022 甲斐 広大.
物理的な位置情報を活用した仮想クラウドの構築
ハイブリッドクラウドを実現させるポイントと SCSKのOSSへの取組み
寺尾 敦 青山学院大学社会情報学部 第12回 情報デザイン(4) 情報の構造化と表現 寺尾 敦 青山学院大学社会情報学部
【1−1.開発計画 – 設計・開発計画】 システム開発計画にはシステム開発を効率的、効果的に実行する根拠(人員と経験、開発手順、開発・導入するシステム・アプリケーション・サービス等)を記述すること。 システム開発の開始から終了までの全体スケジュールを記載すること。 アプリケーション機能配置、ソフトウェア、インフラ構成、ネットワーク構成について概要を示すこと。
6 日本のコーポレート・ガバナンス 2008年度「企業論」 川端 望.
急成長する中国ソフトウェア産業 中国ソフトウェアと情報サービス産業の規模 総売上高は5年間で約5.3倍の成長
米国ユタ州LDS病院胸部心臓外科フェローの経験
公益社団法人日本青年会議所 関東地区埼玉ブロック協議会 JCの情熱(おもい)育成委員会 2011年度第1回全体委員会
次世代大学教育研究会のこれまでの活動 2005年度次世代大学教育研究大会 明治大学駿河台校舎リバティタワー9階1096教室
子どもの本の情報 大阪府内の協力書店の情報 こちらをクリック 大阪府内の公立図書館・図書室の情報
第2回産業調査 小島浩道.
〈起点〉を示す格助詞「を」と「から」の選択について
広東省民弁本科高校日語専業骨幹教師研修会 ①日本語の格助詞の使い分け ②動詞の自他受身の選択について   -日本語教育と中日カルチャーショックの観点から- 名古屋大学 杉村 泰.
■5Ahバッテリー使用報告 事例紹介/東【その1】 ■iphon4S(晴れの昼間/AM8-PM3) ◆約1時間で68%⇒100%
『ワタシが!!』『地域の仲間で!!』 市民が始める自然エネルギー!!
ポイントカードの未来形を形にした「MUJI Passport」
SAP NetWeaver を支える Microsoft テクノロジーの全貌 (Appendix)
ガイダンス(内業) 測量学実習 第1回.
Python超入門 久保 幹雄 東京海洋大学.
熱力学の基礎 丸山 茂夫 東京大学大学院 工学系研究科 機械工学専攻
京都民医連中央病院 CHDF学習推進委員会
資料2-④ ④下水道.
Accessによる SQLの操作 ~実際にテーブルを操作してみよう!~.
Presentation transcript:

プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。) C言語入門 第3週 プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)

先週の復習1

各データ型のサイズ(1/4) sizeoftest.c による比較 32bit版Cygwin+gcc 64bit版Cygwin+gcc $ gcc sizetest.c && ./a char: 1 wchar_t: 2 shor: 2 int: 4 long: 4 long long: 8 float: 4 double: 8 long double: 12 $ gcc sizetest.c && ./a char: 1 wchar_t: 2 shor: 2 int: 4 long: 8 long long: 8 float: 4 double: 8 long double: 16 コンパイルする環境により 割り当てビット数や 最大値と最小値が異なる可能性がある

各データ型のサイズ(2/4) sizeoftest.c による比較 Borland C++ 5.5 コンパイルする環境により >bcc32 sizeoftest.c && sizeoftest Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland sizeoftest.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland char: 1 wchar_t: 2 shor: 2 int: 4 long: 4 float: 4 double: 8 long double: 10 コンパイルする環境により 割り当てビット数や 最大値と最小値が異なる可能性がある

各データ型のサイズ(3/4) sizeoftest.c による比較 Visual Studio 2013 Express Desktop Windows 32bit版 >cl sizeoftest.c && sizeoftest Microsoft(R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86 Copyright (C) Microsoft Corporation. All rights reserved. sizeoftest.c Microsoft (R) Incremental Linker Version 12.00.21005.1 /out:sizeoftest.exe sizeoftest.obj char: 1 wchar_t: 2 shor: 2 int: 4 long: 4 long long: 8 float: 4 double: 8 long double: 8 コンパイルする環境により 割り当てビット数や 最大値と最小値が異なる可能性がある

各データ型のサイズ(4/4) sizeoftest.c による比較 Visual Studio 2013 Express Desktop Windows 64bit版 >cl sizeoftest.c && sizeoftest Microsoft(R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64 Copyright (C) Microsoft Corporation. All rights reserved. sizeoftest.c Microsoft (R) Incremental Linker Version 12.00.21005.1 /out:sizeoftest.exe sizeoftest.obj char: 1 wchar_t: 2 shor: 2 int: 4 long: 4 long long: 8 float: 4 double: 8 long double: 8 コンパイルする環境により 割り当てビット数や 最大値と最小値が異なる可能性がある

データ型のサイズ C99における解決方法 stdint.h ヘッダファイルを使う #include <stdint.h> 補足 データ型のサイズ C99における解決方法 stdint.h ヘッダファイルを使う 第1週のサンプルプログラム wavtest.c bmptest.c でも使っています。 #include <stdint.h> // ... int8_t i8; // 符号付き 8bit整数 uint8_t ui8; // 符号なし 8bit整数 int16_t i16; // 符号付き16bit整数 uint16_t ui16; // 符号なし16bit整数 int32_t i32; // 符号付き32bit整数 uint32_t ui32; // 符号なし32bit整数 int64_t i64; // 符号付き64bit整数 uint64_t ui64; // 符号なし64bit整数 注: Boarland C++ 5.5 は C99 非対応なので stdint.h が使えない。

変数と定数

変数の割り当てとバイトオーダー 32bit int型の場合 int a; // 変数の宣言 : 0x?? 0x~00 0x?? 0x~01

変数の割り当てとバイトオーダー 32bit int型の場合(Little Endian) int a = 0x12345678; Intel の x86 系 CPU 等 32bit int型の場合(Little Endian) : int a = 0x12345678; // 変数の宣言と初期化 0x78 0x~00 0x56 0x~01 32bit 0x34 0x~02 0x12 0x~03 0x?? 0x~04 0x?? 0x~05 0x?? 0x~06 a 0x12345678 0x?? 0x~07 0x?? 0x~08 :

変数の割り当てとバイトオーダー 32bit int型の場合(Big Endian) int a = 0x12345678; ネットワーク上を流れるデータ等 32bit int型の場合(Big Endian) : int a = 0x12345678; // 変数の宣言と初期化 0x12 0x~00 0x34 0x~01 32bit 0x56 0x~02 0x78 0x~03 0x?? 0x~04 0x?? 0x~05 0x?? 0x~06 a 0x12345678 0x?? 0x~07 0x?? 0x~08 :

変数の割り当てとバイトオーダー 16bit short型の場合(Little Endian) short a = 0x1234; Intel の x86 系 CPU 等 16bit short型の場合(Little Endian) : short a = 0x1234; // 変数の宣言と初期化 0x34 0x~00 16bit 0x12 0x~01 0x?? 0x~02 a 0x1234 0x?? 0x~03 0x?? 0x~04 0x?? 0x~05 同じ場所から32bitで取ると 0x?? 0x~06 a 0x????1234 0x?? 0x~07 0x?? 0x~08 :

変数の割り当てとバイトオーダー 16bit short型の場合(Big Endian) short a = 0x1234; ネットワーク上を流れるデータ等 16bit short型の場合(Big Endian) : short a = 0x1234; // 変数の宣言と初期化 0x12 0x~00 16bit 0x34 0x~01 0x?? 0x~02 a 0x1234 0x?? 0x~03 0x?? 0x~04 0x?? 0x~05 同じ場所から32bitで取ると 0x?? 0x~06 a 0x1234???? 0x?? 0x~07 0x?? 0x~08 :

バイトオーダーに関する注意点 ファイル保存時に注意が必要 以下のコードはファイルに保存した値が実行環境により異なるかも? int32_t a = 0x12345678; // ... fwrite(&a, sizeof(a), 1, fp); 例: 第1週のサンプルプログラム wavtest.c bmptest.c Little Endian の環境では正常に動くが Big Endian の環境では正常に動かない!

バイトオーダーに関する注意点 正常な動作の例 a 0x12345678 a 0x12345678 ファイルへ 書き込み ファイルから 読み込み 0x78 0x56 0x34 0x12 Little Endian の PC Little Endian の PC

バイトオーダーに関する注意点 不具合の例 a 0x12345678 a 0x78563412 ファイルへ 書き込み ファイルから 読み込み Little Endian の PC Big Endian の PC

バイトオーダーに関する注意点 不具合の例 a 0x12345678 a 0x78563412 ファイルへ 書き込み ファイルから 読み込み Big Endian の PC Little Endian の PC

バイトオーダーの解決方法の例 ビット演算を利用 1バイトずつに切り分けてファイルへ保存する int32_t a = 0x12345678; // ... fputc((a ) & 0xFF, fp); fputc((a >> 8) & 0xFF, fp); fputc((a >> 16) & 0xFF, fp); fputc((a >> 24) & 0xFF, fp); 絶対に Little Endian で 書き込むことが出来る。

バイトオーダーの解決方法の例 よく使う処理は関数にしてまとめる 再利用し易くなる 教科書 pp.149-206. int fputle32(int32_t a) { int r; r = fputc((a ) & 0xFF, fp); if (r == EOF) return EOF; r = fputc((a >> 8) & 0xFF, fp); if (r == EOF) return EOF; r = fputc((a >> 16) & 0xFF, fp); if (r == EOF) return EOF; r = fputc((a >> 24) & 0xFF, fp); if (r == EOF) return EOF; return 4; }

バイトオーダーの解決方法の例 バイトオーダーを考慮したライブラリを使う SDL (Simple DirectMedia Layer) ライブラリ SDL_SwapBE32 関数 http://wiki.libsdl.org/SDL_SwapBE32 SDL_SwapLE32 関数 http://wiki.libsdl.org/SDL_SwapLE32 int32_t a = 0x12345678; Uint32 x = SDL_SwapLE32(a); // ... fwrite(&x, sizeof(x), 1, fp); 絶対に Little Endian で 書き込むことが出来る。

fwrite 関数 引数: 戻り値: BUF: 保存するデータへのポインタ SIZE: 1要素当りのサイズ COUNT: 保存する要素数 size_t fwrite(const void *BUF, size_t SIZE, size_t COUNT, FILE *fp); 引数: BUF: 保存するデータへのポインタ SIZE: 1要素当りのサイズ COUNT: 保存する要素数 fp: ファイル構造体へのポインタ 戻り値: 書き込んだ要素数 正常終了の場合COUNTに同じ

fputc 関数 引数: 戻り値: c: 書き込む文字 fp: ファイル構造体へのポインタ 書き込んだ文字c エラーの場合EOF int fputc(int c, FILE *fp); 引数: c: 書き込む文字 fp: ファイル構造体へのポインタ 戻り値: 書き込んだ文字c エラーの場合EOF

値の表示

値の表示 printf関数を使う printftest.c いろんな値を表示できる。 #include <stdio.h> 教科書 pp.61, 64-66, 98. 値の表示 printf関数を使う printftest.c #include <stdio.h> #include <stdlib.h> int main() { int i = 128; double d = 123e-3; char s[] = "hello, world"; printf("i = %d\n", i); printf("d = %f\n", d); printf("s = %s\n", s); return EXIT_SUCCESS; } いろんな値を表示できる。 $ gcc printftest.c && ./a i = 128 d = 0.123000 s = hello, world

printf 関数 引数: 戻り値: FORMAT: 書式 ...: 任意の数の引数 書き出された文字数。 エラーの場合負の数。 教科書 pp.61, 64-66, 98. printf 関数 int printf(const char *FORMAT, ...); 引数: FORMAT: 書式 ...: 任意の数の引数 戻り値: 書き出された文字数。 エラーの場合負の数。 参考: [1] pp.305-306.

printf: 書式 %~変換文字までをフィールドと呼ぶび、テンプレート(穴空き定規)ように扱われる フィールドは以下の要素から成る 教科書 pp.61, 64-66, 98. printf: 書式 %~変換文字までをフィールドと呼ぶび、テンプレート(穴空き定規)ように扱われる フィールドは以下の要素から成る %[フラグ][最小フィールド幅][.精度][長さ修飾子]変換文字 printf("1 + 2 = %d\n", 1 + 2); 1 + 2 = \n ここに、 int型の整数型データとして解釈した 2つ目の引数の値(上記の例では1+2の計算結果)を 符号付き10進数にして印字する 参考: [1] pp.305-306.

printf: フラグ -: 左揃えで印字 +: 数を符号付きで印字 スペース: 最初の文字が符号でない場合スペースを前に付ける 教科書 pp.61, 64-66, 98. printf: フラグ -: 左揃えで印字 +: 数を符号付きで印字 スペース: 最初の文字が符号でない場合スペースを前に付ける 0: フィールド幅いっぱいに左側から0を詰める #: 別の出力形式を指定。 o: 先頭の桁を0にする x: 0でない結果の先頭を0xにする e,f,g: 出力に必ず小数点を付ける g: 末尾の0を削除しない 参考: [1] pp.305-306.

printf: 最小フィールド幅 変換された引数は少なくともこの幅になる。 必要ならもっと広い幅のフィールドに印字。 教科書 pp.61, 64-66, 98. printf: 最小フィールド幅 変換された引数は少なくともこの幅になる。 必要ならもっと広い幅のフィールドに印字。 変換された引数がフィールド幅よりも短い場合padding(=詰め物)が行われる。 paddingは通常はスペース。フラグに0が指定された場合は0が用いられる。 *: 次の引数の値を用いる 参考: [1] pp.305-306.

printf: .精度 「.」(ピリオド): フィールド幅と精度の分離子(separator) 文字列に対しては印字する最大文字数 教科書 pp.61, 64-66, 98. printf: .精度 「.」(ピリオド): フィールド幅と精度の分離子(separator) 文字列に対しては印字する最大文字数 e,fの対しては小数点以下に印字すべき桁数 gに対しては有効数字の桁数 整数に対しては印字すべき最小桁数(頭に0が付加される) *: 次の引数の値を用いる 参考: [1] pp.305-306.

printf: 長さ修飾子 h: short または float として扱う l: long として扱う 教科書 pp.61, 64-66, 98. printf: 長さ修飾子 h: short または float として扱う l: long として扱う L: long double として扱う 参考: [1] pp.305-306.

printf: 変換文字 教科書 pp.61, 64-66, 98. 文字 変換後の引数の型 d, i int; 符号付き10進数 o x, X int; 符号なし16進数 u int; 符号なし10進数 c int; unsigned char に変換された後の単一文字 s char *; 文字列を文字列終端('\0')または指定された桁まで f double; [-]mmm.dddddd 形の10進数。dの桁数は精度で指定 e, E double; [-]m.dddddde±xx型の10進数。dの桁数は精度で指定 g, G double; 指数が-4より小さいか精度以上の場合%e、それ以外は%f扱い p void *; ポインタとして印字(処理系依存) n int *; このprintfでここまでに書き出された文字数を引数に書き込む % %を印字 参考: [1] pp.305-306.

教科書 pp.61, 64-66, 98. printf の詳細 ここでは概略しか示せていないのと一部不正確な部分もあるので、詳細は bash から man コマンドを用いて以下の方法で確認すること 邦訳は以下のページ http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/printf.3.html man sprintf

sprintf のマニュアル導入 以下のコマンドを mintty+bash から実行 学内の場合はまず以下の PROXY 設定が必要 教科書 pp.61, 64-66, 98. sprintf のマニュアル導入 以下のコマンドを mintty+bash から実行 学内の場合はまず以下の PROXY 設定が必要 export http_proxy=http://proxy.cc.yamaguchi-u.ac.jp:8080/ cygwin-doc パッケージのインストール apt-cyg install cygwin-doc

値の読み込み

値の読み込み scanf関数を使う scanftest.c キーボードから入力した値を 変数に保存して利用出来る 教科書 pp.80-83, 254. 値の読み込み scanf関数を使う scanftest.c int i; double d; char s[16]; printf("i = "); scanf("%d", &i); printf("d = "); scanf("%lf", &d); printf("s = "); scanf("%s", &s); printf("i = %d\n", i); printf("d = %f\n", d); printf("s = %s\n", s); キーボードから入力した値を 変数に保存して利用出来る $ gcc -g scanftest.c && ./a i = 1234 d = 1234e-5 s = hello, world d = 0.012340 s = hello,

scanf 関数 引数: 戻り値: FORMAT: 書式 ...: 任意の数の引数 値を格納する変数へのポインタ 教科書 pp.80-83, 254. scanf 関数 int scanf(const char *FORMAT, ...); 引数: FORMAT: 書式 ...: 任意の数の引数 値を格納する変数へのポインタ 戻り値: 変換され代入された入力項目の数。 ファイル終端またはエラーの場合EOF。 参考: [1] pp.307-309.

scanf: 書式 スペース、タブ: 無視される (%でない)普通の文字: 入力の次の空白でない文字とマッチ 変換仕様: int a; 教科書 pp.80-83, 254. scanf: 書式 スペース、タブ: 無視される (%でない)普通の文字: 入力の次の空白でない文字とマッチ 変換仕様: %[*][最大フィールド幅][ターゲット幅]変換文字 &: アドレス演算子 変数へのポインタを得る int a; scanf("%d", &a); スカラ変数の前には & を付ける 配列変数、ポインタ変数には不要 入力文字列を10進数として扱い int型の整数型変数へ代入 参考: [1] pp.250, 307-309.

scanf: 変換仕様 *: 入力フィールドはスキップされる 代入抑止 最大フィールド幅: 読み込む最大文字数 ターゲット幅: 教科書 pp.80-83, 254. scanf: 変換仕様 *: 入力フィールドはスキップされる 代入抑止 最大フィールド幅: 読み込む最大文字数 ターゲット幅: h: int を short に l: int を long に、float を double に L: float を long doubleに 参考: [1] pp.307-309.

scanf: 変換文字 教科書 pp.80-83, 254. 文字 入力データ; 引数の型 d 10進数; int * i 整数; int * (頭に0,0xが付くと8,16進数とみなす) o 8進数; int * u 符号なし10進数; unsigned int * x 16進数; int * c 文字; char * (末尾に'\0'を付加しない) s 非空白文字の文字列; char * (末尾に'\0'を付加) e,f,g 浮動小数点数; float * p printf("%p") で印字されるポインタ値; void * n これまでに読み込まれた文字数; int * [...] [...]+; char * (末尾に'\0'を付加) [^...] [^...]+; char * (末尾に'\0'を付加) % %; 参考: [1] pp.307-309.

教科書 pp.80-83, 254. scanfの詳細 ここでは概略しか示せていないのと一部不正確な部分もあるので、詳細は bash から man コマンドを用いて以下の方法で確認すること 邦訳は以下のページ http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/scanf.3.html man sscanf

scanf の引数とポインタ 値の代入するには変数のアドレスが必要 int a; scanf("%d", &a); 教科書 pp.80-83, 254. scanf の引数とポインタ 値の代入するには変数のアドレスが必要 : int a; scanf("%d", &a); &a 0x?? 0x~00 0x?? 0x~01 32bit 0x?? 0x~02 scanf に値の格納先の アドレスを渡す 0x?? 0x~03 0x?? 0x~04 &: アドレス演算子 変数が配置されているメモリ上のアドレスが得られる このアドレスのことをC言語ではポインタと呼ぶ 0x?? 0x~05 0x?? 0x~06 a 0x???????? 0x?? 0x~07 0x?? 0x~08 :

scanf: C99 の stdint.h の場合 #include<inttypes.h> して SCN~ を使う 補足 scanf: C99 の stdint.h の場合 #include<inttypes.h> して SCN~ を使う "%hd" → "%"SCNd16 "%d" → "%"SCNd32 "%u" → "%"SCNu32 使う bit 数を確実に保証出来る 実装依存なので 欲しい桁数が扱えないかも? 参考: [1] pp.307-309.

buffer obverflow の脆弱性 確保した配列よりも長い文字列を入力 他の変数の領域を 侵食してしまう 備考 buffer obverflow の脆弱性 確保した配列よりも長い文字列を入力 $ gcc -g scanftest.c && ./a i = 1234 d = 1234e-5 s = 0123456789abcdefg@@@@@@@@@@@@@@@@ i = 1077952576 d = 32.501961 他の変数の領域を 侵食してしまう

buffer obverflow の脆弱性の仕組み 備考 buffer obverflow の脆弱性の仕組み メモリ上の変数の割り当て 0x?? 0x~00 : char s[16]; 0x?? 0x~0f 0x?? 0x~10 確保したサイズ以上の データを書き込むと 他の変数のデータを 上書きしてしまう。 : double d; 0x?? 0x~17 : 0x?? 0x~1c : int i; 0x?? 0x~1f :

buffer obverflow の脆弱性の対策 備考 buffer obverflow の脆弱性の対策 最大フィールド幅を明記する! "%s" → "%15s" 終端文字列'\0'も格納する必要があるため、 最大フィールド幅は 確保したバイト数 -1 以下にする必要がある。 char s[16]; なら最大15文字まで

マクロ preprocessor のキーワード置換機能 書式: #define マクロ名 置換内容 定数等に名前を付ける際に使う area_of_a_circle.c #define PI 3.14 // ... float r; printf("circle radius = "); scanf("%f", &r); printf("Area of a circle = %f\n", PI * r * r);

マクロ 先程の EOF とか SCNd32 もマクロ それぞれの環境に 適切な数値や文字列等が設定されている 教科書 p.68. マクロ 先程の EOF とか SCNd32 もマクロ $ grep "#define.EOF" /usr/include/stdio.h #define EOF (-1) $ grep SCNd32 /usr/include/inttypes.h #define SCNd32 "d" それぞれの環境に 適切な数値や文字列等が設定されている

マクロ PI に関しては実は math.h で提供されている $ grep M_PI /usr/include/math.h #define M_PI 3.14159265358979323846 #define M_TWOPI (M_PI * 2.0) #define M_PI_2 1.57079632679489661923 #define M_PI_4 0.78539816339744830962

ファイルの包含 preprocessor のファイル取り込み機能 別のファイルに記述されたプログラムやマクロ等を取り込む際に使う 書式: 教科書 pp.203-206. ファイルの包含 preprocessor のファイル取り込み機能 別のファイルに記述されたプログラムやマクロ等を取り込む際に使う 書式: #include <ファイル名> //システム提供ファイル用 /usr/include 等から探して取り込む #include "ファイル名" //ユーザー作成ファイル用 作業ディレクトリから探して取り込む

grep コマンド grep [OPTIONS] PATTERN [FILE ...] 引数 OPTIONS: 備考: UNIX コマンド grep コマンド grep [OPTIONS] PATTERN [FILE ...] 検索文字列を含むファイルを検索する 引数 PATTERN: 正規表現等による検索文字列 FILE: 検索対象のファイルやディレクトリ OPTIONS: -R: ディレクトリ下のすべてのファイルを検索 -n: 行番号を表示 -A NUM: マッチ位置の後NUM行も表示 -B NUM: マッチ位置の前NUM行も表示 -C NUM: マッチ位置の前後NUM行も表示

正規表現 c 文字c \c 文字\c . 任意の一文字 [...] []内の任意の一文字 [^...] []内に含まれない任意の一文字 備考: UNIX コマンド 正規表現 c 文字c \c 文字\c . 任意の一文字 [...] []内の任意の一文字 [^...] []内に含まれない任意の一文字 * 直前のパターンが0回以上反復 + 直前のパターンが1回以上反復 ? 直線のパターンが0または1回出現

演算子

sizeof 演算子 変数やデータ型の割り当てバイト数を求める arraysizetest.c 教科書 p.78, 84, 195. sizeof 演算子 変数やデータ型の割り当てバイト数を求める arraysizetest.c int a[10]; // 要素数10のint型の配列変数 printf("%d\n", sizeof(int)); //int型の割り当てバイト数 printf("%d\n", sizeof(a)); //配列変数aの割り当てバイト数 printf("%d\n", sizeof(a[0]));//変数a[0]の割り当てバイト数 printf("%d\n", sizeof(a)/sizeof(a[0])); //配列変数aの要素数 $ gcc -g arraysizetest.c && ./a 4 40 10

型変換(cast)演算子 (変換したい型) 値 cast 演算子 (type) type: 任意のデータ型 casttest.c int a = 1; int b = 2; double x = a / b; double y = a / (double) b; printf("%f\n", x); printf("%f\n", y); 整数同士の割り算だと 1/2 が 0 になっている。 $ gcc casttest.c && ./a 0.000000 0.500000 b の値を double 型に 変換

算術演算子 教科書 p.69, 84. 算術演算子 演算子の機能 書式 単項演算子 + 被演算数の値 + expr - 被演算数の符号反転 二項演算子 加算 expr1 + expr2 減算 expr1 – expr2 * 乗算 expr1 * expr2 / 除算 expr1 / expr2 % 剰余算 expr1 % expr2

代入演算子、複合代入演算子 複合代入演算子はvar=var+exprのような演算と代入を同時に行う 教科書 pp.75-79, 84. 演算子の機能 書式 = 代入 var = expr 複合代入演算子 += 加算 var += expr -= 減算 var –= expr *= 乗算 var *= expr /= 除算 var /= expr %= 剰余算 var %= expr &= ビット毎のAND var &= expr ^= ビット毎のXOR var ^= expr |= ビット毎のOR var |= expr <<= 左シフト var <<= expr >>= 右シフト var >>= expr 複合代入演算子はvar=var+exprのような演算と代入を同時に行う

bit演算子 教科書 pp.78-79, 84. 算術演算子 演算子の機能 単項演算子 ~ 1の補数 ~ expr 二項演算子 << 左シフト expr1 << expr2 >> 右シフト expr1 >> expr2 & ビット毎のAND expr1 & expr2 ^ ビット毎のXOR expr1 ^ expr2 | ビット毎のOR expr1 | expr2

bitシフト(論理シフト) (符号なし整数の場合) 教科書 pp.78-79, 84. bitシフト(論理シフト) (符号なし整数の場合) 利用可能 bit の外側には 0が充填される 論理シフトであれば 左シフト、右シフト共に 符号付き、符号なしで結果は共通 0xe8 1 << 2 0x90 0xe8 1 >> 2 0x3a

bitシフト(算術シフト) (符号付き整数の場合?) 教科書 pp.78-79, 84. bitシフト(算術シフト) (符号付き整数の場合?) 最上位ビットより上位は符号拡張される 符号ビットが0なら0、1なら1が充填される 左シフトは 符号付き、符号なしで結果は共通 右シフトは最上位ビットの値により 符号付き、符号なしで結果が異なる 0x1b 1 >> 2 0x06 0xe8 1 >> 2 環境依存なので、環境によっては 論理シフトになる可能性も 考慮しておくこと。 0xfa

右シフト 実際の環境はどうなっているのか? bitshifttest.c 教科書 pp.78-79, 84. 右シフト 実際の環境はどうなっているのか? bitshifttest.c unsigned int uc = 0xe8000000; // == 0b11100100... signed int sc = 0xe8000000; // == 0b11100100... uc >>= 2 + 8 * 3; sc >>= 2 + 8 * 3; printf("%02x\n", uc & 0xff); // 0b00111001 == 0x3a printf("%02x\n", sc & 0xff); // 0b11111001 == 0xfa ?

右シフト 算術シフトになっている環境が多い? 教科書 pp.78-79, 84. $ gcc bitshifttest.c && ./a fa 64bit 版 cygwin GNU C 4.8.2 >bcc32 bitshifttest.c && bitshifttest ... 3a fa Borland C++ 5.5 >cl bitshifttest.c && bitshifttest ... 3a fa Visual Studio 2013 Express Desktop Windows 64bit 版

論理演算 論理演算子による演算結果は真(=1)または偽(=0)となる 教科書 pp.78-79, 84. X Y X AND Y X OR Y X XOR Y NOT X 1 論理演算子 ビット毎の論理演算子 意味 英語表記 && & 論理積 AND || | 論理和 OR ^ 排他的論理和 XOR (exclusive or) ! ~ 論理反転 NOT 論理演算子による演算結果は真(=1)または偽(=0)となる

C言語の論理値(真偽値) 数値を論理値として用いている 論理演算とビット毎の論理演算に注意 logictest.c 教科書 pp.78-79, 84. C言語の論理値(真偽値) 数値を論理値として用いている 論理演算とビット毎の論理演算に注意 論理値 数値 真偽値判定時 偽 0のみが偽として扱われる 真 1 0以外はすべて真として扱われる logictest.c int x = 1; // = 0b01 int y = 2; // = 0b10 printf("x && y = %d\n", x && y); printf("x || y = %d\n", x || y); printf("x & y = %d\n", x & y); printf("x | y = %d\n", x | y); $ gcc logictest.c && ./a x && y = 1 x || y = 1 x & y = 0 x | y = 3

論理演算とビット毎の論理演算 論理演算を行う単位が違う 1 1 1 1 1 1 1 1 論理演算子 ビット毎の論理演算子 1 1 教科書 pp.78-79, 84. 論理演算とビット毎の論理演算 論理演算を行う単位が違う 1 1 1 1 1 1 1 1 論理演算子 ビット毎の論理演算子 1 1 論理演算では 全体を1つの論理値として扱う ビット毎の論理演算では 各ビットを個別に扱う

bit 毎の AND による bit mask bit毎にANDを取った結果が得られる 1 1 1 1 & 1 1 1 1 1 教科書 pp.78-79., p.84. bit 毎の AND による bit mask bit毎にANDを取った結果が得られる 1 1 1 1 & 1 1 1 1 X & Y で 右辺の値をマスクとして用いた場合 0: 0でクリア 1: 元の値をそのまま通過 1

bit 毎の OR による bit mask bit毎にORを取った結果が得られる 1 1 1 1 | 1 1 1 1 1 1 1 1 1 教科書 pp.78-79., p.84. bit 毎の OR による bit mask bit毎にORを取った結果が得られる 1 1 1 1 | 1 1 1 1 1 1 1 1 X | Y で 右辺の値をマスクとして用いた場合 0: 元の値をそのまま通過 1: 1でクリア 1 1 1 1 1

bit 毎の XOR による bit 反転 bit毎にXORを取った結果が得られる 1 1 1 1 ^ 1 1 1 1 @ @ @ @ 1 教科書 pp.78-79., p.84. bit 毎の XOR による bit 反転 bit毎にXORを取った結果が得られる 1 1 1 1 ^ 1 1 1 1 @ @ @ @ X ^ Y で 右辺の値をマスクとして用いた場合 0: 元の値をそのまま通過 1: bit を 0⇔1 反転 1 1 同じ値で再度 XOR を取ると元に戻るので 簡易暗号的な使い方も出来る

1の補数演算子 要は単なるビット毎の論理反転 ~ 1 1 1 1 ビット毎の論理反転 1 1 1 1 教科書 pp.78-79., p.84. 1の補数演算子 要は単なるビット毎の論理反転 ~ 1 1 1 1 ビット毎の論理反転 1 1 1 1

補数とは 基数𝑏(𝑏進数) 𝑛桁で表現可能な整数𝑎に対し 例: 2進数8桁で表す1について 𝑏 𝑛 −𝑎 : 基数(𝑏)の補数 𝑏 𝑛 −𝑎 : 基数(𝑏)の補数 𝑏 𝑛 −𝑎−1 : 減基数(𝑏−1)の補数 例: 2進数8桁で表す1について 2の補数 0b100000000 – 0b00000001 = 0b11111111 1の補数(単なるビット毎の論理反転) 0b100000000 – 0b00000001 - 1 = 0b11111110 訂正: 2015-01-13 誤: 0c100000000 正: 0b100000000

インクレメント、デクレメントの演算子 int i = 5; printf("%d\n", ++i); 教科書 pp.73-74., p.84. インクレメント、デクレメントの演算子 算術演算子 演算子の機能 前置演算子 ++ インクレメント ++expr -- デクレメント --expr 後置演算子 expr++ expr-- 前置演算子は演算後に値を取り出す。 後置演算子は演算前に値を取り出す。 int i = 5; printf("%d\n", ++i); printf("%d\n", --i); printf("%d\n", i++); printf("%d\n", i--); $ gcc incrtest.c && ./a 6 5

比較演算子 (関係演算子、等値演算子) 演算結果は真(=1)または偽(=0)となる 教科書 pp.117-118, 147. 演算子 比較の意味 関係演算子 < 左辺が小 expr1 < expr2 <= 左辺が小または等しい expr1 <= expr2 > 左辺が大 expr1 > expr2 >= 左辺が大または等しい expr1 >= expr2 等値演算子 == 等しい expr1 == expr2 != 等しくない expr1 != expr2 演算結果は真(=1)または偽(=0)となる

演算子の優先度 優先度 高 低 [1] p.65. より 演算子 結合規則 備考 ( ) [ ] -> . 左から右→ ( ) [ ] -> . 左から右→ ! ~ ++ -- + - * & (type) sizeof 右から左← 単項演算子 * / % 二項演算子 + - << >> bitシフト < <= > >= 関係演算子 == != 等値演算子 & bit毎のAND ^ bit毎のXOR | bit毎のOR && 論理演算子(AND) || 論理演算子(OR) ?: 三項演算子 = += -= *= /= %= &= ^= |= <<= >>= 代入演算子 , 低 [1] p.65. より

配列変数

配列変数 同じ変数名で複数の要素を管理する char a[10]; // 要素数10のchar型変数の宣言 教科書 pp.85-108. 初期値式が与えられなかった場合、値は不定 a[0] ? a[1] ? a[2] ? a[3] ? a[9] ? ... 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 配列変数の要素への代入 char a[10]; // 要素数10のchar型変数の宣言 教科書 pp.85-108. 配列変数 配列変数の要素への代入 char a[10]; // 要素数10のchar型変数の宣言 a[0] = 'a'; // 0番目の要素へ代入 宣言後の代入 初期値式が与えられなかったので、値は不定 a[0] 'a' a[1] ? a[2] ? a[3] ? a[9] ? ... 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 添え字は値が取れれば変数や数式でも良い int i = 1; char a[10]; // 要素数10のchar型変数の宣言 教科書 pp.85-108. 配列変数 添え字は値が取れれば変数や数式でも良い int i = 1; char a[10]; // 要素数10のchar型変数の宣言 a[i + 1] = 'a'; // 2番目の要素へ代入 a[0] ? a[1] ? a[2] 'a' a[3] ? a[9] ? ... 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 確保した領域外はアクセスは禁止 char a[10]; // 要素数10のchar型変数の宣言 short b = 0x1234; 教科書 pp.85-108. 配列変数 確保した領域外はアクセスは禁止 char a[10]; // 要素数10のchar型変数の宣言 short b = 0x1234; a[10] = 'a';// 宣言された領域外へのアクセス ここに書き込むと何が起こるか分からない b 0x1234 a[0] ? a[1] ? a[2] ? a[3] ? a[9] ? a[10] 'a' ... 他の変数が使っていたらその値を壊してしまう 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 初期値式による配列変数の初期化 char a[10] = {'a', 'b'}; //初期値式付きの 教科書 pp.85-108. 配列変数 初期値式による配列変数の初期化 char a[10] = {'a', 'b'}; //初期値式付きの //要素数10のchar型変数の宣言 初期値式による初期化 初期値式が要素数より少ない場合、残りは0で初期化 a[0] 'a' a[1] 'b' a[2] a[3] a[9] ... 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 初期値式による配列変数の初期化 char a[] = {'a', 'b'}; //初期値式付きで 教科書 pp.85-108. 配列変数 初期値式による配列変数の初期化 char a[] = {'a', 'b'}; //初期値式付きで //要素数を省略したchar型変数の宣言 初期値式による初期化 a[0] 'a' a[1] 'b' 初期値式の要素数分確保される [1] pp.103-104., p.273.

配列変数 文字列による初期化(要素数指定) char a[10] = "ab"; //文字列による初期値付きの 教科書 pp.85-108. 配列変数 文字列による初期化(要素数指定) char a[10] = "ab"; //文字列による初期値付きの //要素数10のchar型変数の宣言 文字列と文字列終端の'\0' 初期値式が要素数より少ない場合、残りは0で初期化 a[0] 'a' a[1] 'b' a[2] a[3] a[9] ... 要素数10の添え字付き変数 [1] pp.103-104., p.273.

配列変数 文字列による初期化(要素数自動決定) char a[] = "ab";//文字列による初期値付きで 教科書 pp.85-108. 配列変数 文字列による初期化(要素数自動決定) char a[] = "ab";//文字列による初期値付きで //要素数を省略したchar型変数の宣言 文字列と文字列終端の'\0' a[0] 'a' a[1] 'b' a[2] 文字列の文字数+文字列終端'\0'の1文字分の要素 [1] pp.103-104., p.273.

変数の初期化 明示的な初期化がない場合 初期化する場合 外的変数、静的変数→0 自動変数、レジスタ変数→不定 外的変数、静的変数←定数式でのみ初期化可 コンパイル時に1度だけ初期化される 自動変数、レジスタ変数←任意の式で初期化可 実行時にブロック毎に初期化される [1] pp.103-104., p.273.

配列変数の初期化 要素数を与えない場合 要素数を与えた場合 初期値式の数で配列のサイズが決まる 初期値式を与えない場合 初期値式を与える場合 値は不定 初期値式を与える場合 要素数を超えるとエラー 要素数に足りない部分は0で初期化される [1] pp.103-104., p.273.

制御構造

条件分岐 (if 文) 真偽値による場合分け if (条件式) { // 条件式が真の場合の処理1 } 教科書 pp.130-133.

条件分岐 (if, else 文) 真偽値による場合分け if (条件式) { // 条件式が真の場合の処理1 } else { 教科書 pp.130-133. 条件分岐 (if, else 文) 真偽値による場合分け 条件式 真 偽 if (条件式) { // 条件式が真の場合の処理1 } else { // 条件式が偽の場合の処理2 } 処理1 処理2

入れ子の条件分岐 (if, else 文) 真偽値による場合分け if (条件式1) { // 条件式1が真の場合の処理1 } else { 教科書 pp.130-133. 入れ子の条件分岐 (if, else 文) 真偽値による場合分け 条件式1 真 偽 if (条件式1) { // 条件式1が真の場合の処理1 } else { if (条件式2) { // 条件式1が偽かつ // 条件式2が真の場合の処理2 // 条件式2が偽の場合の処理3 } 処理1 条件式2 真 偽 処理2 処理3 if は任意の数入れ子に出来ます。

条件分岐 (if, else if, else 文) 真偽値による場合分け if (条件式1) { // 条件式1が真の場合の処理1 教科書 pp.130-133. 条件分岐 (if, else if, else 文) 真偽値による場合分け 条件式1 真 偽 if (条件式1) { // 条件式1が真の場合の処理1 } else if (条件式2) { // 条件式1が偽かつ // 条件式2が真の場合の処理2 } else { // 条件式2が偽の場合の処理3 } 処理1 条件式2 真 偽 処理2 処理3 else if は任意の数追加出来ます。

多分岐判断機構 (switch 文) 値による場合分け switch (式) { case 値1: // 式が値1の場合の処理1 教科書 pp.134-140. 多分岐判断機構 (switch 文) 値による場合分け 式 switch (式) { case 値1: // 式が値1の場合の処理1 case 値2: // 式が値2の場合の処理2 default: // 他の条件に // 当てはまらない場合の処理N }; 値1 break 処理1 値2 break 処理2 default break 処理N break 文を入れておかないと 次の条件の処理を 連続して実行するので注意。

前判定ループ (while 文) 真偽値による繰り返し while (条件式) { // 条件式が真の場合の処理 } 教科書 pp.119-122. 前判定ループ (while 文) 真偽値による繰り返し 条件式 while (条件式) { // 条件式が真の場合の処理 } 偽 真 処理

後判定ループ (do while 文) 真偽値による繰り返し do { // 条件式 が真の場合の処理 } while (条件式); 教科書 p.123. 後判定ループ (do while 文) 真偽値による繰り返し 処理 do { // 条件式 が真の場合の処理 } while (条件式); 条件式 真 偽 do while 文は、ループ内の処理を 最低1回は実行する。

初期化・更新処理付きループ (for 文) 真偽値による繰り返し for(式1; 式2; 式3) { // 式2が真の場合の処理 }; 教科書 pp.124-129. 初期化・更新処理付きループ (for 文) 真偽値による繰り返し 式1 for(式1; 式2; 式3) { // 式2が真の場合の処理 }; 式2 偽 真 処理 前判定ループだが 式1による初期化と 式3による更新処理を ひとまとめにして書ける。 式3

参考文献 [1] B.W.カーニハン/D.M.リッチー著 石田晴久 訳、プログラミング言語C 第2版 ANSI 規格準拠、共立出版(1989)