コース内容#
C 言語の概要#
- なぜ C 言語を学ぶ必要があるのか?
アセンブリ言語 | C 言語(コンパイル型言語、高級言語) |
---|---|
ハードウェアデバイス - レジスタに強く依存 | 移植性 |
レジスタなどと直接通信し、コードが複雑で効率が高い | シンプルで可読性が高く、開発効率が高い |
例:外国人と交流したい | |
英語を学ぶ | 翻訳者を探す |
-
C の重要性
- 先に C があり、その後に Linux がある
- オペレーティングシステム Unix は有料なので、Linux が生まれ、リーナスが開発した
- Linux の基盤は C 言語で実装されている
- Java、C++、Python の基盤も C である
PS:Mac OS は Unix ベースである
- 先に C があり、その後に Linux がある
-
学習思考ロジック、プログラミングパラダイム
- 単なる文法だけではない
- C 言語は 1 つのパラダイムのみをサポート:手続き型
- C++ は 4 つのパラダイムをサポート:手続き型、オブジェクト指向、ジェネリックプログラミング、関数型プログラミング
入力と出力関数#
人の聞く、話すに例える
- 出力関数:printf
ヘッダファイル | stdio.h | |
---|---|---|
⭐プロトタイプ | int printf(const char *format, ...); | 出力されるのは文字のみ |
戻り値、int、成功した出力文字数 | '\n' は 1 文字である | |
パラメータ 1、format、フォーマット制御文字列 | ||
可変引数リスト、... | 合法的な文、コンパイル可能 |
- 入力関数:scanf
ヘッダファイル | stdio.h | |
---|---|---|
⭐プロトタイプ | int scanf(const char *format, ...); | |
戻り値、int、成功した読み込まれたパラメータの数 | <0 は不正;≥0 は正(0 を含む) | |
while(scanf(...) != EOF) | -1 <=> EOF (隠れたファイル記述子) |
- キーボード入力のファイル終了符 EOF:
-
- Unix:Ctrl+D
-
- Windows:Ctrl+Z
-
- Ctrl+C を使ってループを中断することもできる
C 言語の文書とコーディング規範#
-
Wikipedia を利用して関数を確認
-
cpp reference 権威文書
- 参考に海賊宝藏公式サイト
-
コーディング規範(more code, more bug)Googleは親
- 百度 + Google
- アリババ + Google
- バグ率を下げる
-
参考書(1 ヶ月で十分;この本はクロスオーバーで書かれている)
-
授業中の練習#
-
- while 関数を使わず、printf の戻り値を直接使用できる
- printf () のネスト
- コード

- %[^\n]s
// 目的:
char str[100] ={0};
scanf ("% s", str); // 空白などの区切り文字に遭遇すると次のパラメータの代入に入る
scanf ("%[^\n] s", str); // 空白を文字として読み取ることができ、[] の後の s はあってもなくてもよい
|[]| 文字マッチ集 |
|:----:|:----|:----:|:----|
|^| 否定 / 除外 |
|\n | 改行文字 |
- ループで読み込むと問題が発生する
while (scanf("%[^\n]s", str) != EOF) {
...
}
- Hello World を入力すると、出力が止まらず、ずっと Hello World を出力し続ける
- \n が区切り文字として次のパラメータの代入に入るが、\n は飲み込まれない
- 参考に開課吧 QA--10 月 13 日の C 言語コースに関する scanf の問題:'\n' で止まるのは、%[] が先行空白文字を飲み込まないからである
自分の理解の思考、上記とは少し異なる
-
scanf の出力を表示すると、最初に 1 つのパラメータが成功裏に読み込まれたことがわかり、その後はすべて 0 である
-
-
私の理解によれば、\n が正規表現で【否定】された場合、\n を読み込むことができなくなるが、区切り文字として扱われるため出力文に入るが、ずっと読み込まれないので、ループで読み込むことになる;
-
正規表現がない場合、\n は区切り文字として読み込まれ、次の文字を読み続けるため停止するが、空白に遭遇すると次のパラメータの代入に入る。
-
-
getchar () を使用すると、1 文字(例えば \n)を飲み込むことができる
- getchar () の値を表示すると、飲み込まれたのは \n であり、次の行を読み続けることができる
-
-
赤枠は飲み込まれた文字の出力:\n、下のコードの 15〜20 行が見える
-
文字を含む文字列を読み取るために char のループ読み込みを使用することもできる。二次元文字配列を使用し、\n に遭遇すると次の行に入る。
-
別の視点からの考察、参考にscanf の \n の問題-CSDN
-
コード
-
重要なノート#
- scanf は区切り文字(空白、改行など)を利用して複数の変数入力を分ける
- 代入演算子(=、-= など)の優先度は非常に低い(結合方向:右から左)、== 演算子よりも低い
- 代入演算子で形成された式の値は代入された値である
int ret;
printf("%d\n", ret = 3);
// 出力 3
-
./a.out > output は出力を output ファイルに置き(元のファイルを上書き)、端末には表示しない
- > の意味は標準出力のリダイレクト
-
vim の基本操作、vimtutor 練習ができる、石墨文書参照 -Linux での一般的なコマンド:Vim
-
printf () のフォーマット制御文字列中で、\n を使用しない場合、末尾に % がある
- このパーセント記号はシェルが追加したもので、自分で改行を入力しなかったからである。
もし改行を入力しなかったら、シェルの後ろのプロンプトはあなたの出力(例えば hello word)にすぐ続いて書かれるべきで、乱雑に見える
- 注意:% c は慎重に使用すること、何でも読み込んでしまう
コードデモ#
printf 関数#
printf ファミリーの基本知識#
- printf:標準出力(stdout)に印刷する
- spirnf:文字列(string)に印刷する
- 文字列の結合に使用できる
- sprintf(str, "", ...);
- fprintf:ファイルに印刷する(file)
- まずファイルを開く、fopen:w 書き込み、r 読み込み、a 追加
- FILE 型のポインタを返す
- fprintf (FILE ポインタ,"", ...);
- “...”:可変引数リスト変数のアドレスを読む
- 文字列変数自体はその先頭アドレスを渡す
- まずファイルを開く、fopen:w 書き込み、r 読み込み、a 追加

int main()
{
FILE* fp;
int i = 617;
char* s = "それは良いニュースです";
fp = fopen("text.dat", "w");
fprintf (fp, "% d\n", i); // 変数名を渡すだけで、アドレスを渡す必要はない
fprintf(fp, "%s", s);
fclose (fp); //fclose と呼応して、ファイルを閉じることを忘れない
return 0;
}
練習#
- n の末尾 3 ビットの値に基づいて、str に異なるタイプの括弧を追加する
-
-
n の定義は printf の冒頭部分にある
-
マクロ定義方式で swap 関数を定義する
-
-
__typeof で変数の型を取得し、中間変数の型を直接宣言する
-
sprintf の 2 つの引数は同じにできない?
- 💡名前は同じにできない?
- 前後の引数を両方 str にすると、以下のようになる:
- 💡名前は同じにできない?
-
-
結果は以下の通り:() 内の値の長さは元の値と同じで、出力内容 ()は元の内容を上書きするように見える
- 必ずポインタ方式でアドレスを渡す必要がある?
- 変数を直接使用することもできる、以下を参照:
-
-
-
-
- しかし、複数の条件判断がある場合、ポインタを使用しないと文字配列を交換するのは簡単か???
- ❓実際には文字配列の変数名は文字配列の先頭アドレスを表すので、アドレスを直接交換できる?失敗に終わるべきで、配列は簡単に移動できないが、配列を指すポインタは移動できる
- だからやはりポインタを使うことを学ぶべき~
- fprintf の FILE ポインタも stdout と stderr である
- しかし、複数の条件判断がある場合、ポインタを使用しないと文字配列を交換するのは簡単か???
-
-
-
- 最後の出力は以下の通り:
-
-
-
- stdout と stderr の違いは何か?
-
を使用して標準出力 stdoutをリダイレクトすることができ、stderr はリダイレクトされない、以下を参照:
-
- stdout と stderr の違いは何か?
-
⭐:エラー情報を個別に確認でき、大量の正常出力を遮断することができる
-
-
-
- 同様に、**2>** を使用してエラー出力のみをリダイレクトすることができる、以下を参照:
-
-
追加知識#
- ファイル記述子
- stdin:標準入力
- stdout:標準出力
- stderr:標準エラー出力
- EOF:-1
- ファイル権限
- Linux ではすべてがファイルである~
- ls -al .:ファイル権限を表示できる
- rwx 読み取り、書き込み、実行可能
- 配列初期化の 3 つの一般的な方法({0}, memset, for ループ代入)-CSDN
考察点#
- なぜ scanf のパラメータリストにアドレスを渡す必要があるのか?
- scanf はパラメータの値を変更する必要があるため、値を渡すとその値を変更できなくなる