Bo2SS

Bo2SS

1 言語入門基礎

コース内容#

C 言語の概要#

  • なぜ C 言語を学ぶ必要があるのか?
アセンブリ言語C 言語(コンパイル型言語、高級言語)
ハードウェアデバイス - レジスタに強く依存移植性
レジスタなどと直接通信し、コードが複雑で効率が高いシンプルで可読性が高く、開発効率が高い
例:外国人と交流したい
英語を学ぶ翻訳者を探す
  • C の重要性

    • 先に C があり、その後に Linux がある
      • オペレーティングシステム Unix は有料なので、Linux が生まれ、リーナスが開発した
      • Linux の基盤は C 言語で実装されている
    • Java、C++、Python の基盤も C である
      PS:Mac OS は Unix ベースである
  • 学習思考ロジック、プログラミングパラダイム

    • 単なる文法だけではない
    • 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:
      1. Unix:Ctrl+D
      1. Windows:Ctrl+Z
  • Ctrl+C を使ってループを中断することもできる

C 言語の文書とコーディング規範#

  • Wikipedia を利用して関数を確認

  • cpp reference 権威文書

  • コーディング規範(more code, more bug)Googleは親

    • 百度 + Google
    • アリババ + Google
    • バグ率を下げる
  • 参考書(1 ヶ月で十分;この本はクロスオーバーで書かれている)

    • 画像

授業中の練習#

  • 画像
  • while 関数を使わず、printf の戻り値を直接使用できる
  • printf () のネスト
  • コード
画像
  • 画像
  1. %[^\n]s

// 目的:
char str[100] ={0};
scanf ("% s", str); // 空白などの区切り文字に遭遇すると次のパラメータの代入に入る
scanf ("%[^\n] s", str); // 空白を文字として読み取ることができ、[] の後の s はあってもなくてもよい

|[]| 文字マッチ集 |
|:----:|:----|:----:|:----|
|^| 否定 / 除外 |
|\n | 改行文字 |

  1. ループで読み込むと問題が発生する

while (scanf("%[^\n]s", str) != EOF) {
...
}

  • Hello World を入力すると、出力が止まらず、ずっと Hello World を出力し続ける
  1. \n が区切り文字として次のパラメータの代入に入るが、\n は飲み込まれない

自分の理解の思考、上記とは少し異なる

  • scanf の出力を表示すると、最初に 1 つのパラメータが成功裏に読み込まれたことがわかり、その後はすべて 0 である

  • 画像
  • 私の理解によれば、\n が正規表現で【否定】された場合、\n を読み込むことができなくなるが、区切り文字として扱われるため出力文に入るが、ずっと読み込まれないので、ループで読み込むことになる;

  • 正規表現がない場合、\n は区切り文字として読み込まれ、次の文字を読み続けるため停止するが、空白に遭遇すると次のパラメータの代入に入る。

  • 画像
  1. 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 ポインタ,"", ...);
    • “...”:可変引数リスト変数のアドレスを読む
      • 文字列変数自体はその先頭アドレスを渡す
画像

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;
}

練習#

  1. n の末尾 3 ビットの値に基づいて、str に異なるタイプの括弧を追加する
  • 画像
  • n の定義は printf の冒頭部分にある

  • マクロ定義方式で swap 関数を定義する

  • 画像

  • __typeof で変数の型を取得し、中間変数の型を直接宣言する

  • sprintf の 2 つの引数は同じにできない?

    • 💡名前は同じにできない
      • 前後の引数を両方 str にすると、以下のようになる:
  • 画像
  • 結果は以下の通り:() 内の値の長さは元の値と同じで、出力内容 ()は元の内容を上書きするように見える

    • 画像
    • 必ずポインタ方式でアドレスを渡す必要がある?
      • 変数を直接使用することもできる、以下を参照:
  • 画像
      • しかし、複数の条件判断がある場合、ポインタを使用しないと文字配列を交換するのは簡単か???
        • ❓実際には文字配列の変数名は文字配列の先頭アドレスを表すので、アドレスを直接交換できる?失敗に終わるべきで、配列は簡単に移動できないが、配列を指すポインタは移動できる
        • だからやはりポインタを使うことを学ぶべき~
        • fprintf の FILE ポインタも stdout と stderr である
  • 画像
      • 最後の出力は以下の通り:
  • 画像
      • stdout と stderr の違いは何か?
        • を使用して標準出力 stdoutをリダイレクトすることができ、stderr はリダイレクトされない、以下を参照:

  • 画像

​ ⭐:エラー情報を個別に確認でき、大量の正常出力を遮断することができる

        • 同様に、**2>** を使用してエラー出力のみをリダイレクトすることができる、以下を参照:
  • 画像

追加知識#

考察点#

  • なぜ scanf のパラメータリストにアドレスを渡す必要があるのか?
    • scanf はパラメータの値を変更する必要があるため、値を渡すとその値を変更できなくなる
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。