首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言入門

《C和指針》核心知識點總結:從鏈接屬性到運行時環境

     編輯:C 語言入門

鏈接屬性

extern 關鍵字用於標識符第二次或以後的聲明,並不會改變第一次聲明所指定的屬性。static 則用於防止被外部訪問,這與 Java 中的 static 含義完全不同。

存儲類型

  • 變量存儲位置:普通內存、堆棧、硬件寄存器
  • 代碼塊外聲明的是靜態變量,存於靜態內存(普通內存),程序運行前存在,始終存在
  • 自動變量
  • 代碼塊內變量加 static 變為靜態變量

運算符

i+++ ++i 這種 5 個加號的表達式,GCC 中間有空格可以通過編譯,甚至可以是 6 個加號 i+++ + ++i,其中一個表示正數。

指針

  1. 定義:#define NULL (void*) 0、#define EOF -1
  2. int *a; *a=1; 在 Unix 中會導致段違例(segmentation violation)、內存錯誤或總線錯誤
  3. 對 NULL 指針間接訪問,有的編譯器訪問內存 0,有的引發錯誤並終止程序
  4. 盡量顯式初始化指針
  5. 指針與整型值的相互轉換罕見
  6. *100=25 不是對地址 100 賦值 25,這是非法的;正確寫法 *(int *)100=25; 用於訪問硬件,極少使用
  7. * 從右向左結合
  8. 後綴 ++ --、順序點:() 不是順序點;; , || && ?: 以及函數的所有賦值之後、第一條語句執行之前、函數返回值已拷貝給調用者但在該函數外代碼執行之前、每個基類和成員初始化之後
  9. *cp++ *++cp ++*cp (*cp)++ ++*++cp ++*cp++ *(*cp)++ 後綴 ++ 優先級大於 *,* 不是 ++ 順序點
  10. 指針遍歷數組的三種寫法及邊界比較規則:標准允許指向數組最後一個元素後面的內存進行比較,但不允許與數組第一個元素之前比較
  11. 指針加減法會根據類型自動調整

函數

  1. 函數原型:向編譯器提供函數特定信息,更安全
  2. 函數原型參數不是必須的
  3. 無參數原型 int *func(void); 中 void 提示無參數,而非表示一個 void 類型參數
  4. 函數缺省認定:調用無法見到原型的函數時,編譯器認為返回整型值
  5. stdarg 宏(stdarg.h):va_list、va_start、va_arg、va_end,用於可變參數處理

數組

  1. 數組名是指針常量而非指針變量,編譯器用數組名記住數組屬性
  2. 程序鏈接後,數組在內存中位置固定,不能移動,故數組名為指針常量
  3. 兩種情況數組名不作指針常量:作為 sizeof 操作數(返回整個數組長度);作為 & 操作數(返回指向數組的指針,而非指向指針常量的指針)
  4. array[subscript] 等同於 *(array+subscript),下標甚至可以為負,2[array] 與 array[2] 對編譯器無差別
  5. 下標絕不比指針更有效率,但指針有時比下標更有效率(避免重複乘法計算偏移)

字符串、字符和字節

  1. 包含 string.h 可讓編譯器更好執行錯誤檢測
  2. 自寫字符串函數保留以 str 開頭的函數名,用於標准庫擴展
  3. size_t strlen(char const *string),size_t 為 unsigned int,程序保護不會溢出
  4. 表達式中無符號數可能導致不可預料結果:strlen(x) - strlen(y) >= 0 永遠為真,因無符號數不可能為負
  5. 標准庫函數部分用匯編實現
  6. strcpy、strcat 重疊時行為未定義,需程序控制
  7. strcmp 返回負、正、零分別表示小於、大於、等於
  8. strncpy 總複製 len 長度,不足補 NUL,超長不加 NUL;strncat 總在結果後加 NUL,最多複製 len 加一個 NUL
  9. strchr/strrchr 查找字符首次/最後出現位置
  10. strpbrk 查找集合中任意字符首次出現
  11. strstr 查找子串
  12. strspn/strcspn 計算不在/在集合中的初始段長度
  13. strtok 分割字符串,會修改原串,保存局部狀態,不可同時解析多字符串
  14. strerror 根據 errno 返回錯誤描述
  15. 字符分類(ctype.h):iscntrl、isspace、isdigit 等
  16. 字符轉換(ctype.h):tolower、toupper
  17. 直接測試字符範圍降低可移植性,應用 isupper 等標准函數
  18. 內存操作函數(以長度為終止標志,解決 \0 問題):memcpy、memmove(允許重疊,較慢)、memcmp、memchr、memset

結構體

  1. 結構標簽不同視為不同類型,即使成員相同也不能互賦
  2. 跨文件使用定義在頭文件中
  3. * 優先級小於 .,-> 大於 &
  4. 可包含自身引用,但不能在未定義別名前用別名;不能包含自身實體(遞歸無法終止)
  5. 相互引用用不完整聲明
  6. 無特殊要求時按邊界重排成員優化存儲
  7. sizeof 返回整體長度,offsetof(stddef.h)返回成員偏移量
  8. 位段:只能聲明為 int、signed int、unsigned int;分配方向未定義;可用移位屏蔽實現,可移植性較弱

聯合體

初始化必須是第一個元素,位於花括號內,類型不符會轉換並賦給第一個。

動態內存分配

calloc(初始化為 0)、malloc、realloc、free。傳遞 NULL 無作用,失敗返回 NULL。定義在 stdlib.h,NULL 定義在 stdio.h。

高級指針

  1. 指向指針的指針
  2. 理解聲明:推論聲明法;聲明表達式與普通表達式求值規則相同
  3. 函數指針:初始化 int (*pf)(int) = &f;,調用 pf(12) 為正道
  4. 回調函數:C 中用 void* 實現靈活但不安全,注意強制轉換繞過類型檢查
  5. 轉換表
  6. 字符串是指針常量,表達式中即為指針常量;"0123456789ABCDEF"[value % 16] 轉二進制字符

預處理

  1. 文本操作
  2. 預定義符號:__FILE__、__LINE__、__DATE__、__TIME__、__STDC__
  3. #define 可多行,行尾加反斜槓
  4. 宏調用函數勿在末尾加分號
  5. 宏參數列表左括號必須緊鄰名稱
  6. 數值宏參數各加括號,最外層再加括號
  7. 宏可包含其他宏,不可遞歸
  8. 預處理不檢測字符串常量內容;字符串化:#argument、鄰近連接
  9. ## 連接符號
  10. 宏與函數權衡:內聯函數、類型安全、宏能處理類型無關任務
  11. 宏參數副作用:參數多次出現導致多次求值(如 MAX(x++,y++))
  12. 條件編譯:#if、#elif、#else、#endif、defined()
  13. 頭文件搜索路徑、嵌套層數限制、make 依賴關系
  14. #error、#line、#pragma、# 無效指令

輸入輸出函數

  1. ANSI 允許擴展庫函數,但關心可移植性應避免
  2. perror、errno 錯誤處理機制
  3. exit 返回狀態給操作系統
  4. 流緩衝特性:完全緩衝、行緩衝、無緩衝;fflush 強制刷新
  5. 文本流與二進制流的換行翻譯
  6. FILE 結構、標准流 stdin/stdout/stderr、重定向
  7. fopen 模式(r/w/a/rb/wb/ab/r+/w+/a+/rb+/wb+/ab+)、返回值檢查
  8. fclose、fcloseall
  9. 字符/字符串/格式化/二進制讀寫函數族
  10. 緩衝區控制:fflush、flushall、setbuf、setvbuf
  11. 隨機訪問:ftell、fseek(SEEK_SET/CUR/END)、rewind、fgetpos/fsetpos
  12. 流錯誤檢查:feof、ferror、clearerr
  13. 臨時文件:tmpfile、tmpnam
  14. 文件操作:remove、rename

標准庫函數

  1. stdlib.h:abs/labs、div/ldiv(商餘結構體)
  2. 偽隨機數:rand、srand(常用 time(0) 做種子)
  3. math.h:三角、雙曲、指數、對數、冪、平方根、取整、絕對值、餘數
  4. 定義域錯誤、范圍錯誤
  5. 字符串轉換:atoi/atol/strtol/strtoul/atof/strtod(strtol 保存結束指針,支援基數 2-36)
  6. 時間:clock、time、ctime、difftime、gmtime/localtime、asctime/strftime、mktime、tm 結構體
  7. setjmp/longjmp 非局部跳轉
  8. 信號、abort/atexit/exit、assert、getenv、system、qsort/bsearch

運行時環境

  • -S 保留匯編代碼
  • 參數逆序壓棧,便於可變參數定位
  • 函數三部分:序言、函數體、跋語
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved