02: 変数と標準入出力

Similar documents
02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

PowerPoint プレゼンテーション

第1回 プログラミング演習3 センサーアプリケーション

Microsoft Word - no202.docx

Microsoft Word - 3new.doc

PowerPoint プレゼンテーション

program7app.ppt

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

Microsoft Word - Cプログラミング演習(12)

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

講習No.9

memo

02: 変数と標準入出力

Prog1_10th

slide5.pptx

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

ファイル入出力

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

プログラミング実習I

Cプログラミング1(再) 第2回

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

PowerPoint プレゼンテーション

ファイル入出力

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

02: 変数と標準入出力

PowerPoint プレゼンテーション - 物理学情報処理演習

Microsoft Word - no103.docx

PowerPoint プレゼンテーション

プログラミング演習3 - Cプログラミング -

PowerPoint Presentation

Microsoft PowerPoint - kougi6.ppt

講習No.8

Microsoft PowerPoint pptx

gengo1-11

Microsoft PowerPoint - CproNt11.ppt [互換モード]

kiso2-09.key

Microsoft PowerPoint - 計算機言語 第7回.ppt

PowerPoint プレゼンテーション - 物理学情報処理演習

講習No.1

PowerPoint Presentation

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - 11.pptx

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

02: 変数と標準入出力

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

02: 変数と標準入出力

Microsoft Word - no15.docx

目次

プログラミングI第6回

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

<4D F736F F D2091E63589F182628CBE8CEA8D758DC08E9197BF2E646F6378>

Microsoft Word - no11.docx

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

gengo1-12

memo

プログラミング演習3 - Cプログラミング -

Microsoft PowerPoint ppt

Taro-ファイル処理(公開版).jtd

PowerPoint プレゼンテーション

Microsoft PowerPoint - 5Chap15.ppt

PowerPoint プレゼンテーション

Microsoft PowerPoint - prog06.ppt

Microsoft PowerPoint - handout07.ppt [互換モード]

Microsoft PowerPoint - 09.pptx

< F2D837C E95CF CF68A4A94C5816A2E6A>

Microsoft PowerPoint - prog03.ppt

メソッドのまとめ

gengo1-12

2006年10月5日(木)実施

CプログラミングI

Prog1_12th

デジタル表現論・第6回

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

プログラミングI第5回

情報処理Ⅰ演習

PowerPoint プレゼンテーション

cp-7. 配列

Prog1_6th

プログラミング実習I

Microsoft PowerPoint - prog04.ppt

Microsoft Word - Cプログラミング演習(3)

3,, となって欲しいのだが 実際の出力結果を確認すると両方の配列とも 10, 2, 3,, となってしまっている この結果は代入後の配列 a と b は同じものになっていることを示している つまり 代入演算子 = によるの代入は全要素のコピーではなく 先をコピーする ため 代入後の a と b は

Microsoft PowerPoint pptx

Microsoft PowerPoint - kougi9.ppt

演算増幅器

6 関数 6-1 関数とは少し長いプログラムを作るようになると 同じ処理を何度も行う場面が出てくる そのたびに処 理を書いていたのでは明らかに無駄であるし プログラム全体の見通しも悪くなる そこで登場す るのが 関数 である 関数を使うことを 関数を呼び出す ともいう どのように使うのか 実際に見て

Taro-リストⅠ(公開版).jtd

Prog1_6th

Microsoft PowerPoint - bp02.ppt


Transcription:

C プログラミング入門 基幹 7 ( 水 5) 12: コマンドライン引数 Linux にログインし 以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/cpr1/ 2016-06-29 1

まとめ : ポインタを使った処理 内容呼び出し元の変数を書き換える文字列を渡す 配列を渡すファイルポインタ複数の値を返す大きな領域を確保する 説明第 9 回第 10 回第 10 回第 11 回第 11 回 2

コマンドライン引数の取り扱い シェルから引数 ( オプション ) を受け取る 技術的には二重ポインタ (double pointer) である ポインタへのポインタ 今回の内容 秋期の C プログラミング で使うが この講義ではあまり踏み込まない 文字列から数値への変換 コマンドライン引数は単なる文字列なので 数値として扱うには変換が必要 3

復習 : アドレスとポインタ メモリ上の位置を表す値 型を持つ 変数 a のアドレスは &a ポインタ変数に格納できる アドレス値のことをポインタとも呼ぶことがある int a 100 int a = 100; int *p = &a; int *p 矢印が指す位置のアドレスを持っている printf("%d", *p); 4

復習 : アドレス演算と読み書き デリファレンス演算子 * で アドレスが指す位置の内容を読み書きできる 添え字演算子 [] で ポインタの指す位置をずらして読み書きできる ポインタ p に対して *(p+n) と p[n] は同じ p -23 85 p[0] == *p == 23 矢印が指す位置のアドレスを持っている p[1] == *(p+1) == 85 メモリ上のデータをどんな値とみなすかは ポインタの型で決まる 5

配列変数名は 式中で配列の先頭へのポインタとなる 配列変数を a とすると a そのものがアドレス &a[0] (0 番要素のアドレス ) と同じ &a と書いてもよい int a[4] 復習 : 配列とポインタ 365 それぞれ型が異なる場合があるが詳細は省略する ポインタに関する専門書を参照 p a[0] == *a == p[0] == *p == 365 p = &a という代入をした場合 6

文字列 = メモリ上の文字 (char 型の値 ) が並んでいる領域 の先頭へのポインタ 復習 : 文字列 なぜ char 型なのかは歴史的な事情による 日本語を含む場合でも 基本的には char でよい 文字列リテラルを書くと その文字列がシステム領域に用意され その先頭ポインタを表す 文字列の終端は null 文字 (' 0') である 配列を文字列リテラルで初期化すると 自動的に付加される const char *s = "Hello world! n"; s 'H' 'e' 'l' 'd' '!' ' n' ' 0' 7

コマンドライン引数 シェルでコマンド名の後ろに書く文字列 ホワイトスペースで分割される ( トークン化 ) コマンドは受け取った引数を処理する [user@host]$ gcc src.c -o src -Wall -Wextra tokenize この場合 5 個の引数を gcc というプログラムに渡している [user@host]$./src hello world C 言語で書いた自作のプログラムに引数を渡した場合 どのように処理すればいいのか? 8

コマンドライン引数の受け取り方 main 関数として以下のプロトタイプを使う int main(int argc, char** argv); cf. 今までのは int main(void); 引数名は何でもよいが慣用的に argc, argv または ac, av が使われる それぞれ argument count と argument vector ( 引数の列 ) という意味 第 2 引数の書き方として char **argv char *argv[] のどちらでも 文法上は同じである 後者の書き方をする人もいるので覚えておく 9

argv の内容 文字列へのポインタの配列 最後に null ポインタで終わる./prog hello world 100 と実行した場合 char **argv argv[4] == NULL argv[0][0] 規格では argv[0] に実行したコマンドが必ず入るとは定められていないが 多くの処理系でこうなる main 関数の自動変数の領域 システムのメモリ領域 argv[0] argv[1] '.' '/' 'p' 'r' 'o' 'g' ' 0' 'h' 'e' 'l' 'l' 'o' ' 0' たとえば argv[1] が "hello" という文字列だと思えばよい 'w' 'o' 'r' 'l' 'd' ' 0' '1' '0' '0' ' 0' 10

argc の意味 null ポインタの入っている要素の番号を表す n 個の引数を指定すると argc == n+1./prog hello world 100 と実行した場合 char **argv argv[argc] == NULL この例の場合 argc == 4 つまり 指定した引数の個数 + 1 main 関数の自動変数の領域 argv[0][0] システムのメモリ領域 argv[0] argv[1] '.' '/' 'p' 'r' 'o' 'g' ' 0' 'h' 'e' 'l' 'l' 'o' ' 0' 'w' 'o' 'r' 'l' 'd' ' 0' '1' '0' '0' ' 0' 11

例題 : 引数をすべて表示する argv[i] を i = 1,..., argc-1 まで表示 int main(int argc, char **argv) int i; } printf("%d arguments: n", argc-1); for(i = 0; i < argc; ++i) printf("[%d] == "%s " n", i, argv[i]); } return 0; プログラム名が arg の場合 [user@host]$./arg hello 123 2 arguments [0] == "./arg" [1] == "hello" [2] == "123" argc までループさせない なぜなら argv[argc] == NULL なので表示できない 12

例題 : 引数をすべて表示する ( 別の書き方 ) argv はポインタ変数であり 直接移動させることもできる int main(int argc, char **argv) printf("%d arguments: n", argc-1); for( ; *argv!= NULL; ++argv) printf(" "%s " n", *argv); } return 0; NULL が現れるまで } 動かすので argc 初期化条件は空は必要ない プログラム名が arg の場合 [user@host]$./arg hello 123 2 arguments "./arg" "hello" "123" *argv は argv[0] と同じであり argv 自体を動かしていくと *argv が表す文字列が変わっていく ポインタを動かすだけでは何番目かがわからない 必要なら変数を用意してカウントする 13

難しいと思う人は とりあえず argv[i] が i 番目の引数 と考えるだけで OK ただし i は 1 からカウント 最低限 p. 12 のプログラムが使えればよい 14

コマンドライン引数の注意 引数はあくまでも文字列である たとえば 100 と書いても "100" という文字列でしかない 数値として扱うには標準ライブラリ関数で変換する ( 次のスライドで説明 ) 引数が空文字列になる場合もある たとえば./prog "" abc と書いて実行すると argv[1] は空文字列 argv[2] は "abc" 引数はシステム領域に作られるので (const はついていないが ) 書き換えてはいけない 15

"100" という 3 文字 (+ 終端 null) の文字列を int 型の 100 に変換したい そうしないと ループとか計算で使えない 代表的な 2 つの方法を紹介 1. sscanf 2. ato*, strto* 一族 文字列 数値の変換 16

文字列を数値に変換する (1) sscanf sscanf() は 文字列を解析して変数に値を書きこむ int main(int argc, char **argv) int i; 整数として変換する } printf("%d arguments: n", argc-1); for(i = 1; i < argc; ++i) int v = -1; sscanf(argv[i], "%d", &v); printf("[%d] == "%s " (%d) n", i, argv[i], v); } return 0; 変換対象の文字列 プログラム名が arg の場合 [user@host]$./arg hello 123 abc 3.14 4 arguments [1] == "hello" (-1) [2] == "123" (123) [3] == "abc" (-1) [4] == "3.14" (3) 整数として変換できない文字列だった場合は何もしない 整数として変換できるところまで使われる 17

文字列を数値に変換する (1) sscanf sscanf() は 文字列を解析して変数に値を書きこむ int main(int argc, char **argv) int i; double として変換する } printf("%d arguments: n", argc-1); for(i = 1; i < argc; ++i) double v = -1; sscanf(argv[i], "%lf", &v); printf("[%d] == "%s " (%f) n", i, argv[i], v); } return 0; l ( エル ) は不要 プログラム名が arg の場合 [user@host]$./arg hello 123 abc 3.14 4 arguments [1] == "hello" (-1.000000) [2] == "123" (123.000000) [3] == "abc" (-1.000000) [4] == "3.14" (3.140000) 小数の値として解釈されている 18

文字列を数値に変換する (2) 変換関数 文字列を数値に変換する関数として <stdlib.h> に以下の 2 種類がある atox() は簡単に使えるが 変換に失敗したかどうかを判断できない float ではない 関数名変換する型備考 atoi int 範囲外の値だった場合の戻り値は未定義 atol long int 変換に失敗した場合は 0 を返す atof double ( 関数名は ASCII to x という意味 ASCII は文字コードのこと ) strtol long int 変換に変換に失敗した場合は 0 を返す strtoul unsigned long int 失敗した位置をポインタとして得られる strtol, strtoul は基数 ( 何進法表記か ) を strtod double 指定する ( 関数名は string to x という意味 ) 19

文字列を数値に変換する (2) 変換関数 なるべく右の strtox() を使うべき // 整数に変換する例 int x; char *s = "2014.2"; x = atoi(s); printf(" "%s " == %d n", s, x); 10 進数を指定 int x; char *s = "2014.2"; char *p; x = strtol(s, &p, 10); printf(" "%s " == %d", s, x); p は変換に失敗した最初の位置である もし 文字列の先頭と同じなら 1 文字も解釈できなかったことになる atoi, strtol のプロトタイプ // 変換が完全に失敗した場合 if(str == p)... 変換の失敗位置が必要なければ NULL を渡してもよい #include <stdlib.h> int atoi(const char *str); long strtol(const char *str, char **str_end, int base ); 20