Bo2SS

Bo2SS

1 語言入門基礎

課程內容#

C 語言概述#

  • 為什麼要學 C 語言?
匯編語言C 語言(編譯型語言、高級語言)
強依賴於硬體設備 - 寄存器可移植性
直接與寄存器等溝通,代碼複雜,效率更高簡單、可讀、開發效率高
舉例:想與外國人交流
學英語找翻譯
  • C 的重要性

    • 先有 C,再有 Linux
      • 操作系統 Unix 收費,所以有 Linux,李納斯開發的
      • Linux 底層是用 C 語言實現的
    • Java、C++、Python 底層都是 C
      PS:Mac OS 是基於 Unix 的
  • 學習思維邏輯、編程範式

    • 而不僅僅是語法
    • C 語言只支持一種:面向過程
    • C++ 支持四種:面向過程、面向對象、泛型編程、函數式編程

輸入與輸出函數#

類比人的聽、說

  • 輸出函數:printf
頭文件stdio.h
⭐原型int printf(const char *format, ...);輸出的都是字符
返回值,int,成功輸出的字符數'\n' 是一個字符
參數 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 語言文檔與編碼規範#

  • 利用維基百科查看函數

  • cpp reference 權威文檔

  • 編碼規範(more code, more bug)谷歌是爸爸

    • 百度 + 谷歌
    • 阿里 + 谷歌
    • 降低 bug 率
  • 工具書(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 (),可以吞掉一個字符,比如 \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,末尾有個 %

    • 這個百分號是 shell 給你加的,因為你自己沒有輸入換行。

​ 想想如果你沒輸入換行的話,shell 後面的那個提示符它是不是應該緊接著你的輸出 (如 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 = "that is a good new";
fp = fopen("text.dat", "w");
fprintf (fp, "% d\n", i); // 傳變量名即可,不用傳地址
fprintf(fp, "%s", s);
fclose (fp); // 記得與 fclose 呼應,關閉文件
return 0;
}

練習#

  1. 根據 n 的末尾三位二進制的值,給 str 分別加不同類型的括號
  • 圖片
  • n 的定義在 printf 開頭部分

  • 使用宏定義方式定義 swap 函數

  • 圖片

  • __typeof 獲取變量類型,直接用來聲明中間變量的類型

  • sprintf 的兩個參數不能一樣?

    • 💡名字不能一樣
      • 如果前後參數都用 str,見下:
  • 圖片
  • 結果如下:其中,() 裡的值長度與原值一樣,輸出的內容 ()似乎會覆蓋原來的內容

    • 圖片
    • 一定要用指針的方式傳地址?
      • 如果直接使用變量,可以,見下:
  • 圖片
      • 但是有多個條件判斷,琢磨琢磨不用指針的話,交換字符數組好弄嗎???
        • ❓其實字符數組的變量名代表的就是字符數組首地址,可以直接交換地址?失敗告終,應該是不行的,畢竟數組怎麼會輕易移動,但可以移動指向數組的指針
        • 所以還是學會用指針~
        • fprintf 的 FILE 指針也可以是 stdout 和 stderr
  • 圖片
      • 最後輸出如下:
  • 圖片
      • stdout 和 stderr 有什麼區別呢?
        • 可以使用 > 將標準輸出 stdout重定向,對於 stderr 不會重定向,見下:
  • 圖片

​ ⭐:可以單獨看 error 信息,而屏蔽掉大量的正常輸出

        • 同樣,也可以使用 2> 只將錯誤輸出重定向,見下:
  • 圖片

附加知識點#

思考點#

  • 為什麼 scanf 中參數列表要傳地址?
    • scanf 需要修改參數的值,如果傳值的話,將無法改變其值
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。