Download : sample-001.c
/* * 2017/06/16 sample-001.c */ /* * 返値を持つ関数 */ #include <stdio.h> /* * to_upper : 引数で与えられた文字が小文字なら大文字にする */ char to_upper ( char ch ) { if ( 'a' <= ch ) { /* もし、ch が 'a' 以上で.. */ if ( ch <= 'z' ) { /* 更に、ch が 'z' 以下なら.. */ return ch - 'a' + 'A'; /* 小文字なので大文字に変換して返す */ /* return 命令が実行されると、そこで関数は終了 */ } /* else {} */ /* else 以下はないので省略 */ } /* else {} */ return ch; /* 小文字でない場合は、そのまま返す */ } /* * main 関数 */ int main ( void ) { printf ( "一文字入力して、[Enter] キーを押してください : " ); putchar ( to_upper ( getchar() ) ); putchar ( '\n' ); return 0; }
k
$ ./sample-001.exe < sample-001.in 一文字入力して、[Enter] キーを押してください : k K $
Download : sample-002.c
/* * 2017/06/16 sample-002.c */ /* * main の返値 */ #include <stdio.h> /* * is_upper : ch が大文字なら 1 そうでなければ、0 を返す */ int is_upper ( int ch ) { if ( 'A' <= ch ) { if ( ch <= 'Z' ) { return 1; /* 大文字だった.. */ } } return 0; /* 大文字ではなかった.. */ } /* * main 関数 */ int main ( void ) { printf ( "一文字入力して、[Enter] キーを押してください : " ); if ( is_upper ( getchar() ) ) { printf ( "大文字なので 0 を返します。\n" ); return 0; } else { printf ( "大文字でなかったので 1 を返します。\n" ); return 1; } }
Q
$ ./sample-002.exe < sample-002.in 一文字入力して、[Enter] キーを押してください : Q 大文字なので 0 を返します。 $ echo $? 0 $
Download : sample-003.c
/* * 2017/06/16 sample-003.c * * コンパイルの方法: * cc -c -I ~/c/include sample-003.c */ /* * s_print.h の使い方 */ #include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合には必要 */ /* * main 関数 */ int main ( void ) { s_print_char ( 'A' ); /* 文字の出力 : putchar ( 'A' ) と同じ */ s_print_newline(); /* 改行の出力 : putchar ( '\n' ) と同じ */ s_print_string ( "Hello, World\n" ); /* 文字列の出力 : printf と同じ */ s_print_int ( 123 ); /* 整数値の出力 */ s_print_newline(); return 0; }
$ ./sample-003.exe A Hello, World 123 $
Download : sample-004.c
/* * 2017/06/16 sample-004.c * * コンパイルの方法: * cc -c -I ~/c/include sample-004.c */ /* * s_input.h の使い方 */ #include <stdio.h> #include "s_print.h" #include "s_input.h" /* s_input_... を利用する場合には必要 */ /* * main 関数 */ int main ( void ) { s_print_string ( "一文字を入力して、[Enter] を押してください : " ); s_print_char ( s_input_char () + 1 ); s_print_newline(); s_print_string ( "整数値を一つ入力して、[Enter] を押してください : " ); s_print_int ( s_input_int () + 1 ); s_print_newline(); return 0; }
B 123
$ ./sample-004.exe < sample-004.in 一文字を入力して、[Enter] を押してください : B C 整数値を一つ入力して、[Enter] を押してください : 123 124 $
Download : sample-005.c
/* * 2017/06/16 sample-005.c * * コンパイルの方法: * cc -c -I ~/c/include sample-005.c */ /* * 二つの入力を利用する場合 */ #include <stdio.h> #include "s_print.h" #include "s_input.h" /* * addfunc */ int addfunc ( int a ) { s_print_string ( "二つ目の整数値を入力して、[Enter] を押してください : " ); return a + s_input_int(); } /* * main 関数 */ int main ( void ) { s_print_string ( "一つ目の整数値を入力して、[Enter] を押してください : " ); s_print_int ( addfunc ( s_input_int() ) ); s_print_newline(); return 0; }
123 456
$ ./sample-005.exe < sample-005.in 一つ目の整数値を入力して、[Enter] を押してください : 123 二つ目の整数値を入力して、[Enter] を押してください : 456 579 $
Download : sample-006.c
/* * 2017/06/16 sample-006.c * * コンパイルの方法: * cc -c -I ~/c/include sample-006.c */ /* * 二つの入力を利用する場合 (失敗例) */ #include <stdio.h> #include "s_print.h" #include "s_input.h" /* * subfunc */ int subfunc ( int a, int b ) { return a - b; } /* * main 関数 */ int main ( void ) { s_print_string ( "二つの整数値を入力して、[Enter] を押してください : " ); s_print_int ( subfunc ( s_input_int(), s_input_int() ) ); s_print_newline(); return 0; }
123 456
$ ./sample-006.exe < sample-006.in 二つの整数値を入力して、[Enter] を押してください : 123 456 333 $
/* * 20170616-01-QQQQ.c * p-005.c を参考にする * p-005.c は、小文字を大文字だったので、 * この課題では、それを逆にすればよい */ #include <stdio.h> /* * to_lower : 引数で与えられた文字が大文字なら小文字にする */ char to_lower ( char ch ) { /* p-005.c では、 'a' だった.. */ if ( 'A' <= ch ) { /* もし、ch が 'A' 以上で.. */ if ( ch <= 'Z' ) { /* 更に、ch が 'Z' 以下なら.. */ return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */ /* これだと、小文字が大文字になる */ /* これを変更すればよい */ } /* else {} */ /* else 以下はないので省略 */ } /* else {} */ return ch; /* 大文字でない場合は、そのまま返す */ } /* * main 関数 */ int main ( void ) { printf ( "一文字入力して、[Enter] キーを押してください : " ); putchar ( to_lower ( getchar() ) ); putchar ( '\n' ); return 0; }
/* * 20170616-02-QQQQ.c * 二つの整数値を入力して、その商を出力する * p-014.c が参考になる * 関数の引数で、副作用が起きる場合は、順番を気にする */ #include <stdio.h> #include "s_print.h" #include "s_input.h" /* * remainder */ int remainder ( int a ) { s_print_string ( "割る整数を入力して、[Enter] を押してください : " ); /* * 割られる数 (a) は与えられているので、 * 割る数を入力し、その値を使って、 * 余りの計算をすればよい * あまりの計算を行う演算子は % なので、それを利用する */ return a % /* 入力する関数を呼ぶ */ } /* * main */ int main ( void ) { s_print_string ( "割られる整数を入力して、[Enter] を押してください : " ); s_print_int ( remainder ( s_input_int() ) ); s_print_newline(); return 0; }
#include <stdio.h> void func(void) { printf ( "Hello, World\n" ); } int main(void) { func(); func(); return 0; }
#include <stdio.h> void func(char *X) { printf ( "Hello, " ); printf ( X ); /* 変数 X には、後から文字列が指定できる */ printf ( "\n" ); } int main(void) { func( "World" ); /* 関数が呼び出されるたびに X の値が変わる */ func( "皆さん" ); return 0; }
#include <stdio.h> void func(char X) { /* 引数として、指定する値が「文字」の場合は、 「char *」ではなくて「char」とする 引数で与える値の「型」を指定する 「型」については、あまり説明していないが.. データ 型指定 文字列 char * 文字 char 整数 int */ printf ( "Hello, " ); putchar ( X ); /* 変数 X には、後から文字列が指定できる */ printf ( "\n" ); } int main(void) { func( 'A' ); /* 関数が呼び出されるたびに X の値が変わる */ func( 'z' ); return 0; }
#include <stdio.h> /* 関数が値を返す場合を考える # 「C 言語の関数」:「数学の関数」とは違っていた */ /* to_upper : 引数として、小文字を与え、それに対する大文字を返す関数 # 値(返値[かえりち])を返す関数 */ char to_upper(char ch) { /* 引数として文字を与え、結果として文字を返す */ return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */ /* ASCII 表をみると 文字 文字コード A 65 -> 65 + 0 B 66 -> 65 + 1 .. a 97 -> 65 = 97 - 32 -> 97 + 0 b 98 -> 66 = 98 - 32 -> 97 + 1 .. 小文字を大文字するにするなら 32 を引くとよい return ch - 32; 小文字があたえられたら、 'a' からいくつはなれるかを考える それに 'A' を加えれば、'A' からその数だけはなれた */ /* return 命令 return の後ろに「式」を書くと、 その「式」の値が、関数の返値として帰る # この結果として、関数はここで終了する */ } int main(void) { printf ( "小文字を一つ入力し[Enter] キーを押してください : " ); putchar ( to_upper ( getchar() ) ); /* 小文字を入力し、それを大文字に変換して出力 */ putchar ( '\n' ); return 0; }
#include <stdio.h> /* 関数が値を返す場合を考える # 「C 言語の関数」:「数学の関数」とは違っていた */ /* to_upper : 引数として、小文字を与え、それに対する大文字を返す関数 # 値(返値[かえりち])を返す関数 */ char to_upper(char ch) { /* 引数として文字を与え、結果として文字を返す */ /* 小文字の場合だけ、変換し、その他の場合はそのまま返す */ /* 小文字かどうかを判定する */ /* 小文字かどうかは 'a' <= ch <= 'z' である事で判定 */ if ( 'a' <= ch ) { /* まず、'a' 以上である事をチェック */ if ( ch <= 'z' ) { /* 次に、'z' 以下である事をチェック */ /* ここでは、ch が小文字である事が解るので.. */ return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */ /* ここで、return 命令が実行されるので、 ここで、関数は終了する */ } /* else {} */ } /* else {} */ /* ここに来るのは、23 行目の return が実行されなかった時 */ return ch; /* そうでない時は、もとまま値として返す */ } int main(void) { printf ( "小文字を一つ入力し[Enter] キーを押してください : " ); putchar ( to_upper ( getchar() ) ); /* 小文字を入力し、それを大文字に変換して出力 */ putchar ( '\n' ); return 0; }
#include <stdio.h> int main(void) { printf ( "Hello, World\n" ); return 0; }
#include <stdio.h> int main(void) { printf ( "Hello, World\n" ); return 1; /* return 0 ?????? 1 ??????牽???????? */ /* ?v???O??????яo?????u???m?v??u???s?X?e?[?^?X?v?????l????? */ /* 0 ?????A0 ??O??A?G???[?R?[?h */ }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ /* これによって、 s_print_string : 文字列を出力 s_print_char : 文字を出力 s_print_int : 整数値を出力 s_print_newline : 改行を出力 が使えるようになる */ /* コンパイルする時は、 cc -I ~/c/include -c p-008.c と、「-I ~/c/include」を先行させる必要がある */ int main(void) { s_print_string ( "abc\n" ); /* printf と同じ */ s_print_char ( 'z' ); /* putchar と同じ */ s_print_newline(); /* 改行 ( putchar( '\n' ) ) */ s_print_int ( 123 ); /* 整数値を出力 */ s_print_newline(); return 0; }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ #include "s_input.h" /* s_input_... を利用する場合 */ /* これによって、 s_input_string : 文字列を入力 s_input_char : 文字を入力 s_input_int : 整数値を入力 が使えるようになる */ /* コンパイルする時は、 cc -I ~/c/include -c p-009.c と、「-I ~/c/include」を先行させる必要がある */ int main(void) { s_print_string ( "整数値を一つ入力して[Enter]キーを押してください : " ); s_print_int ( s_input_int() * 2 ); /* 入力された数値を二倍して、画面に出力 */ s_print_newline(); return 0; }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ #include "s_input.h" /* s_input_... を利用する場合 */ int main(void) { s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " ); s_print_int ( s_input_int() + s_input_int() ); /* s_input_int() を二度呼ぶ事により、二度入力され、 それぞれが、関数の返値として与えられる */ /* 入力された数値の和を計算して、画面に出力 */ s_print_newline(); return 0; }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ #include "s_input.h" /* s_input_... を利用する場合 */ /* * add_int は二つの引数で与えらえた整数値の和を返す * 返値を持つ「関数」は、「数学の関数」とよくにている */ int add_int ( int a, int b ) { return a + b; } int main(void) { s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " ); s_print_int ( add_int ( s_input_int(), s_input_int() ) ); /* s_input_int() を二度呼ぶ事により、二度入力され、 それぞれが、関数の返値として与えられる */ /* 入力された数値の和を計算して、画面に出力 */ s_print_newline(); return 0; }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ #include "s_input.h" /* s_input_... を利用する場合 */ /* * sub_int は二つの引数で与えらえた整数値の差を返す * 返値を持つ「関数」は、「数学の関数」とよくにている */ int sub_int ( int a, int b ) { return a - b; } int main(void) { s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " ); s_print_int ( sub_int ( s_input_int(), s_input_int() ) ); /* s_input_int() を二度呼ぶ事により、二度入力され、 それぞれが、関数の返値として与えられる */ /* 入力された数値の和を計算して、画面に出力 */ s_print_newline(); return 0; }
#include <stdio.h> int sub1(void) { printf ( "関数 sub1 が呼ばれました\n" ); return 1; } int sub2(void) { printf ( "関数 sub2 が呼ばれました\n" ); return 2; } int sub3(int a, int b) { printf ( "関数 sub3 が呼ばれました\n" ); return a+b; } int main(void) { sub3 ( sub1(), sub2() ); /* とりあえず、sub1 と sub2 が呼び出され、 その結果使って、sub3 が呼び出されるので、 sub1 +--- sub2 +--- どちらが先に呼び出されるか ? 関数の引数は後ろから計算される その引数に「副作用」がある場合は、その順が問題になる 数学の関数では f(g(x),h(y))で、 関数 g と h がどちらが先に計算するかはどうでもよい # C 言語でも、g, h が純粋に計算だけをする場合は、 # 数学と同じような事がいえる # ところが、入出力(副作用)がある場合は、そうは言ってられない sub3 */ return 0; }
#include <stdio.h> #include "s_print.h" /* s_print_... を利用する場合 */ #include "s_input.h" /* s_input_... を利用する場合 */ /* * sub_int は二つの引数で与えらえた整数値の差を返す * 返値を持つ「関数」は、「数学の関数」とよくにている */ int sub_int ( int a, int b ) { return a - b; } int sub_int_from_a ( int a ) { /* ここで、二度目の s_input_int を呼び出す事により、 二つ目の引数が、二度めの入力である事が保証される */ return sub_int ( a, s_input_int() ); } int main(void) { s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " ); s_print_int ( sub_int_from_a ( s_input_int() ) ); /* s_input_int() を一度しか呼ばない事により、 一つ目の引数が、最初の入力である事を保証する /* 入力された数値の和を計算して、画面に出力 */ s_print_newline(); return 0; }
#include <stdio.h> /* おまじない(とにかくいれよう) */ int main(int argc, char *argv[]) { /* 最初は「int main (void)」と書くとはなしていた.. おまじない */ printf ( "Hello, World\n" ); /* 画面に「Hello World」+「改行」を出力する */ /* printf とはという説明もしてなかった */ /* 6 行目だけ意味がある記述として以下.. */ return 0; /* これもおまじない */ } /* おまじない */
/* 一行目の役割は ? とってしまったらどうなるか ? #include <stdio.h> ノックアウト それを取り除いたら、働かなくなるのであれば、 その働かなくなる機能が、それの役割 [結果] 次のメッセージが出るようになった p-016.c: In function ‘main’: p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default] printf ( "Hello, World\n" ); ^ 「printf が変」 */ int main(int argc, char *argv[]) { printf ( "Hello, World\n" ); return 0; }
/* 一行目の役割は ? とってしまったらどうなるか ? #include <stdio.h> ノックアウト それを取り除いたら、働かなくなるのであれば、 その働かなくなる機能が、それの役割 [結果] 次のメッセージが出るようになった p-016.c: In function ‘main’: p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default] printf ( "Hello, World\n" ); ^ 「printf が変」 */ int main(int argc, char *argv[]) { /* #include を外すと、printf の利用で、メッセージが出る printf もはずしてみよう [結果] メッセージが再び出力されなくなった --> #include <stdio.h> は、printf を利用するために必要 */ /* printf ( "Hello, World\n" ); */ return 0; }
/* 一行目の役割は ? とってしまったらどうなるか ? #include <stdio.h> ノックアウト それを取り除いたら、働かなくなるのであれば、 その働かなくなる機能が、それの役割 [結果] 次のメッセージが出るようになった p-016.c: In function ‘main’: p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default] printf ( "Hello, World\n" ); ^ 「printf が変」 */ /* #include <stdio.h> の代わりに次の行を入れる */ extern int printf (const char *__restrict __format, ...); int main(int argc, char *argv[]) { printf ( "Hello, World\n" ); return 0; }
#include "p-019.h" /* 同じフォルダの p-019.h をここに読み込む この p-019.h には、 printf を利用するための記述があるので、 printf を利用する場合に、 #include <stdio.h> をかくのと同じ効果がある */ int main(int argc, char *argv[]) { printf ( "Hello, World\n" ); return 0; }
#include <stdio.h> int main(void) { putchar ( getchar() ); return 0; }
/* #include <stdio.h> */ int main(void) { putchar ( getchar() ); return 0; }
#include <stdio.h> /* printf を利用するために必要 */ /* printf を利用しない場合は、不要 */ /* printf は、文字列を出力するという、 基本的な機能を担っているので、 まあ、必ず使うと思っていてよいし、 無駄にいれてあっても悪さはしないので、 いつでも入れると思ってよい(結局、おまじない) */ /* #include によって、他のファイルの中身が、 ここに自動的に copy されるという事がポイント 後に、数学ライブラリ ( sin, cos, log ) を 利用する時にまた、紹介する */ int main(void) { /* int argc, char *argv[] コマンドライン引数を利用する場合に、 宣言が必要になる 逆に、コマンドライン引数を参照しない場合は、 不要(voidでよい) # void 自身も省略可能なので、そもそもなくてもよい */ printf ( "Hello, World\n" ); /* return 0 の役割は ? */ /* ノックアウトしてみる [結果] 値として、何を返すかを指定しなかったので、 その結果として、(なぜか ?)13 が返った (0 じゃなかったので..)エラーとして処理された */ /* return 0; */ }
/* Hello, World 二週目(種明かし版) */ #include <stdio.h> /* /usr/include/stdio.h をここに読み込めという意味 結果的に、stdio.h の中にある printf の宣言が読み込まれ、 printf を利用する準備がなされる printf を使わない場合は、いらない # もし、stdio.h に書いてあるたの関数を利用しないのであれば.. ただ、どうせ、printf は使うので、 いつでも入れておいてよい */ int main(int argc, char *argv[]) { /* int argc, char *argv[] は、コマンドライン引数を 参照する場合に必要 main の前の int は、終了ステータスを整数値として返すため C 言語で作られたプログラムには、必ず main 関数が必要で、 それが(作成されたプログラム内では..)最初に呼び出される */ printf ( "Hello, World\n" ); /* 最初:文字列を出力する 引数は、「”」で挟まれているので、文字列 この記述は、printf という関数を呼び出している printf は、C 言語の標準ライブラリで定義されているので、 とくに自分で作らなくても、すぐ利用できる その代わりに、リンクが必要なる */ return 0; /* 正常終了 */ /* プログラムが正常終了した(関数の返値が 0 なら正常)事を プログラムを呼び出したものに伝える */ }
関数の作り方 最初 : 命令列に名前を付ける場合 void 関数名(void) {名前をつける命令} 二番目 : 引数を与える場合 void 関数名 ( char * 仮引数変数名, ... ) { } 三番目 : 引数に型がある 二番目は、引数に指定するデータ型が 「文字列」だったの char * もし、引数が、「文字」だったり、「整数」だった場合は、 それぞれ、「char(文字列)」、「int(整数)」と、 型に合わせて、変数に前を変更する 四番目 : 返値を持つ関数の場合 関数名の前の void を、関数が返す値の型にする 関数の本体の中で、「return 式」を実行して、 その式の値が、関数の値になるようにする。 s_print.h/s_input.h の使い方 #include "s_print.h" これによって、 s_print_string : 文字列を出力 s_print_char : 文字を出力 s_print_int : 整数値を出力 s_print_newline : 改行を出力 が使えるようになる コンパイルする時は、 cc -I ~/c/include -c p-008.c と、「-I ~/c/include」を先行させる必要がある s_print.h がある場所が、~/c/include である事を指定している [二周目] Hello, World 再び #include <stdio.h> の役割 #include <...> は、 /usr/include/... をここに読み込みなさい という意味 #include "..." は。 同じフォルダの ... を、ここに読み込みなさい
Download : 20170616-01.c
/* * 20170616-01-QQQQ.c * 文字を */ #include <stdio.h> /* * to_lower : 引数で与えられた文字が大文字なら小文字にする */ char to_lower ( char ch ) { if ( 'A' <= ch ) { /* もし、ch が 'A' 以上で.. */ if ( ch <= 'Z' ) { /* 更に、ch が 'Z' 以下なら.. */ /* ** この部分を完成させなさい */ } /* else {} */ /* else 以下はないので省略 */ } /* else {} */ return ch; /* 大文字でない場合は、そのまま返す */ } /* * main 関数 */ int main ( void ) { printf ( "一文字入力して、[Enter] キーを押してください : " ); putchar ( to_lower ( getchar() ) ); putchar ( '\n' ); return 0; }
D
$ ./20170616-01-QQQQ.exe 一文字入力して、[Enter] キーを押してください : d $
Download : 20170616-02.c
/* * 20170616-02-QQQQ.c * 二つの整数値を入力して、その商を出力する */ #include <stdio.h> #include "s_print.h" #include "s_input.h" /* * remainder */ int remainder ( int a ) { s_print_string ( "割る整数を入力して、[Enter] を押してください : " ); /* ** この部分を完成させなさい */ } /* * main */ int main ( void ) { s_print_string ( "割られる整数を入力して、[Enter] を押してください : " ); s_print_int ( remainder ( s_input_int() ) ); s_print_newline(); return 0; }
100 13
$ ./20170616-02-QQQQ.exe 割られる整数を入力して、[Enter] を押してください : 100 割る整数を入力して、[Enter] を押してください : 13 9 $