# C語言-程式筆記 (KeRong) ### 作者:陳科融 CHEN,KE-RONG 更新:2022/10/15 **Exercise**:[Zerojudge](https://github.com/kerong2002/Zerojudge) 、[Leetcode](https://github.com/kerong2002/Leetcode) 、[Onlinejudge](https://github.com/kerong2002/Onlinejudge) ![](https://i.imgur.com/sKtp2HB.jpg) <!-- ![](https://i.imgur.com/vvu4QsJ.gif) --> <!-- ![](https://i.imgur.com/VQbeuk7.jpg) --> <!-- ![](https://i.imgur.com/71zVY4U.gif) --> <!-- ![](https://i.imgur.com/K4GnRjP.gif) --> <!--![](https://i.imgur.com/kApUvvh.gif)--> <!-- ![](https://i.imgur.com/dwHgLaU.png) --> <!-- ![](https://i.imgur.com/Sas5LcP.gif) --> <!-- ![](https://i.imgur.com/aU172rl.gif) --> ## 概述 **C語言**具有高效、靈活、功能豐富、表達力強和較高的[可移植性](https://zh.wikipedia.org/wiki/%E7%A7%BB%E6%A4%8D_(%E8%BB%9F%E9%AB%94) "移植 (軟體)")等特點,在[程式設計](https://zh.wikipedia.org/wiki/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1 "程式設計")中備受青睞,成為最近25年使用最為廣的程式語言[TIOBE Programming Community Index](https://www.tiobe.com/tiobe-index/) ,並且廣泛用於[系統軟體](https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6 "系統軟體")與[應用軟體](https://zh.wikipedia.org/wiki/%E5%BA%94%E7%94%A8%E8%BD%AF%E4%BB%B6 "應用軟體")的開發。 ##### 推薦的編輯器:[Code::Blocks](https://www.codeblocks.org/)、[Visual Studio](https://visualstudio.microsoft.com/zh-hant/downloads/)、[Eclipse](https://www.eclipse.org/downloads/) ## 資料型態 |關鍵字 |型態 |位元組| 範圍 |格式化字串| |:----:|:--:|:---:|:------:|:------:| |bool |布林 | 1 |<font color=Red>false</font> or <font color=Green>true</font>|%d| |char |字元 | 1 |-128 ~ 127|%c| |short |短整數| 2 |-2^15^ ~ 2^15^-1|%hd| |int |整數 | 4 |-2^31^ ~ 2^31^-1|%d| |long long|長整數| 8 |-2^63^ ~ 2^63^-1|%lld| |float |單精度浮點| 4 |2.939x10^−38^ ~ 3.403x10^38^|%f| |double|雙精度浮點|8|5.563x10^309^ ~ 1.798x10^308^|%lf| ## 運算子 ### 算術運算子 | 運算子名稱 | 語法 | 運算子名稱 | 語法 | |:-:|:-:|:-:|:-:| | 一元正號 | +a | 一元負號 | -a | | 加法 | a + b | 減法 | a - b | | 乘法 | a * b | 除法 | a / b | | 前置遞增 | ++a | 後置遞增 | a++ | | 前置遞減 | - - a | 後置遞減 | a - - | | 以( )賦值 | a(運算)= b | 取餘 | a % b | **預防除零** n=123/float(a) -> a如果是0 (非法的運算) n所定義的資料型態為int,會是INT_MIN n所定義的資料型態為浮點數↓ &nbsp;**1.#INF00**表示**無窮大的正數**(float) **-1.INF00**表示**無窮大的負數**(float) ### 比較運算子 | 運算子名稱 | 語法 | 運算子名稱 | 語法 | |:-:|:-:|:-:|:-:| | 小於 | a < b | 小於或等於 | a <= b | | 大於 | a > b | 大於或等於 | a >= b | | 不等於 | a != b | 等於 | a == b | | 邏輯取反 | !a | 邏輯 AND | a && b | | 邏輯 OR | a \|\| b |   |   | ### 位元運算子 | 運算子名稱 | 語法 | 運算子名稱 | 語法 | |:-:|:-:|:-:|:-:| | 位元左移 | a << b | 位元右移 | a >> b | | 位元 OR | a \| b | 位元 AND | a & b | | 位元一的補碼 | ~a | 位元 XOR | a ^ b | 透過**位元運算子**取代**算術運算子** - a % 2^n^ = a & (n-1) - a + b = a^b + (a & b) << 1 - a / 2^n^ = a >> n - A * 2^n^ = A << n ### 其他運算子 | 運算子名稱 | 語法 | 運算子名稱 | 語法 | |:-:|:-:|:-:|:-:| | 陣列下標 | a\[b\] | 函數呼叫 | a() | | 取址 | &a | 取值 | *a | | 成員 | a.b | 成員指標 | a->b | | 逗號 | a , b | 三元條件 | a ? b : c | ## 註解 (用來說明程式的含意) - <font color=Red>/* </font> something <font color=Red>*/</font> 圍繞的文字會被電腦略過,跨行註解 - <font color=Red>//</font> 兩個正斜線的單行註解 <!-- ## 簡單的範例程式碼 ```c #include<stdio.h> //輸入輸出函式庫 int main(){ //程式執行完回傳一個整數值 int n; //整數型態n scanf("%d",&n); //將鍵盤輸入至stdin的資料,依整數型態存入n printf("%d",n); //依整數型態,印出n return 0; //程式完成回傳0,通常0表示程式未發生錯誤 } ``` --> ## 基本結構 ### 選擇結構 ```c if(條件){ //優先判斷 actions; } else if(條件){ //次依判斷 actions; } else{ //其餘條件 actions; } ``` ### 重複結構 ```c /*=======<for>===========*/ for(int x=0;x<10;x++){ actions; if(x==5){ continue; //條件成立,單純跳脫x==5的迴圈 } } /*=======<while>===========*/ int n=0; while(n<10){ actions; if(n==5){ break; //條件成立,當x==5直接停止迴圈 } n+=1; } /*=======<do while>===========*/ do { //先做再判定條件 statement; } while (condition); ``` ### 多重選擇結構 ```c switch (value){ case 1: //當value==1做 actions break; case 2: //當value==2做 actions break; default: //其餘狀況 actions break; } ``` ## GCC(GNU Compiler Collection) - gcc -o test.exe test.c//產生executable file - gcc test.exe <input.txt> out.txt//輸出結果到out.txt - gcc -E test.c //查看預處理結果 ## 常見標頭檔 [C standard library](https://cplusplus.com/reference/clibrary/) ```c #include<stdio.h>     //定義輸入、輸出函式 #include<stdlib.h>    //定義雜項函式及記憶體分配函式 #include<string.h>    //字串處理 #include<ctype.h> //定義字元分類函式 #include<limits.h>    //定義各種資料型別最值的常量 #include<math.h>     //定義數學函式 #include<stdbool.h> //定義bool類型資料(C99) #include<iso646.h> //定義位元和邏輯運算子巨集 ``` #### #include <filename.h>和#include "filename.h"區別 #### <filename.h> 編譯器先從標準庫路徑開始搜索文件名.h,使得系統文件調用較快 #### "filename.h" 先從用戶的路徑開始尋找文件名,然後去尋找系統路徑,使得尋找自定義文件較快 ## <stdio.h> (定義輸入、輸出函式) |標識符 |說明| |:----:|:------:| |stderr|標準錯誤流| |stdin |標準輸入流| |stdout|標準輸出流| ### Marcos 巨集 ```c #define true 1 //定義true=1 #define max(a,b) ((a>=b)?a:b) //三元運算取最大值 /*====<可以透過'\'來分段編寫macro>===*/ #define swap(a,b){\ int temp=a;\ a=b;\ b=temp;\ } #define STR(s) #x //將STR(x)內轉形成字串 #define COMBINESTR(x,y) x##y //串接xy(數字) #define makechar(x) #@x //轉成字元 #define max(a, b) \ //取最大值(根據資料型態決定) {(typeof(a) _a = a; \ typeof(b) _b = b; \ _a > _b ? _a : _b;) \ } #define swap(a,b){\ //兩數交換(快速且不會overflow) a=a^b;\ b=a^b;\ a=a^b;\ } /*======<格式化輸出>=======*/ void is_int(int x) { printf("%d\n", x); } void is_char(char x) { printf("%c\n", x); } void is_string(char *x) { printf("%s\n", x); } void is_double(double x) { printf("%f",x);} void is_float(float x) {printf("%f\n",x);} #define print(X)\ _Generic((X),\ //_Generic選擇 int:is_int,\ char:is_char,\ char *:is_string,\ double:is_double,\ default:is_float\ )(X) ``` ### EOF (通常為-1) - End-of-File 以指示已到達文件結尾或指示其他一些失敗條件 ### NULL (通常為0) - 空指針常量 ### BUFSIZ (設置流緩衝區) ```c void setbuf ( FILE * stream, char * buffer ); int setvbuf(FILE * stream, char * buf, int type, unsigned size); ``` - _IOFBF (滿緩衝):當緩衝區為空時,從流讀入資料。或當緩衝區滿時,向流寫入資料。 - _IOLBF (行緩衝):每次從流中讀入一行資料或向流中寫入—行資料。 - _IONBF(無緩衝):直接從流中讀入資料或直接向流中寫入資料,而沒有緩衝區。 ### Formatted input/output: #### printf (用於將格式化後的資料輸出到標準輸出) ```c int printf(const char * restrict format, ...)//正確返回輸出的字元總數,錯誤返回負值 printf("%[格式][最小寬度][.精度][類型長度]"); setbuf(stdout,NULL); //清空緩衝區 setvbuf(stdout,NULL,_IOFBF,0);//清空緩衝區 ``` - %c:以字元方式輸出 - %s:字串輸出 - %d:以10進位整數輸出 - %f:浮點數輸出 - %o:以8進位整數方式輸出 - %u:無號整數輸出 - %x:將整數以 16 進位方式輸出 - %e:使用科學記號顯示浮點數 - %g:浮點數輸出,不輸出無意義的0 - %lu:long unsigned 型態的整數 - %p:指標型態 - %%:輸出% - \n:換行。將游標移到下一行起始點 - \t:將游標移到下一個tab定位點 - \a:警告。讓系統發出警告聲 - \\":輸出" - \\\:輸出\ - %5d:默認向右對齊,左邊補空格 - %-5d:向左對齊,右邊補空格 - %+d:輸出正負號 - % d:正號用空格替代,負號輸出- - %06d:左邊不足以0替代 - %0*d,6:(延伸上面)左邊不足以0替代 - %.8f:超過精度,截斷 - %.8f:不足精度,補後置0 ```c /*==========<三元運算子>=========*/ printf("%d", 1 > 0 ? 1 : 0); printf(1 < 0 ? "%d" : "%c", 65); /*=========<輸出由右至左推>======*/ int a=1; printf("%d %d %d %d %d %d\n",a++, ++a, a++, ++a, a++, ++a );//6 7 4 7 2 7 ``` #### sprintf (發送str指向一個字串的格式化輸出) ```c int sprintf ( char * str, const char * format, ... ); example: char s[99]={'\0'}; //存放位置 sprintf(s,"%d",123); //存放123至陣列s sprintf(s, "%.2f", (double)100); //100強制轉型double並存放至陣列s ``` #### snprintf (比sprintf多了一個參數,能控制要寫入的長度,更加安全) ```c int snprintf ( char * str, size_t size, const char * format, ... ); example: char s[99]={'\0'}; //存放位置 snprintf(s,2,"%d",123); //存放12至陣列s ``` #### scanf (格式化的輸入) ```c int scanf ( const char * format, ... );//不安全函數,會有overflow狀況 1.成功讀入(回傳1) 2.非指定格式讀入(回傳0) 3.讀入EOF(回傳-1) scanf("%[*][輸入數據寬度][類型]"); 1.遇空格、換行、跳格鍵(停止) 2.遇寬度結束(停止) 3.遇不正常輸入(停止) ``` - %c:讀入1個字元 - %(數量)c:讀入(數量)個字元 - %s:讀入字串(空白、換行中斷) - %d:讀入10進位整數 - %i:讀入10進位,8進位,16進位整數 - %o:讀入8進位整數 - %x:讀入16進位整數 - %f:讀入浮點數 - %lf:讀入雙精確(double)浮點數 - %%:讀入% - %p:讀入一個指標 - %u:讀入無符號10進位整數 - %n:至此已讀入的字元數 - %*(數量)(類型):讀取(數量)(類型),直接忽略,不存 - %[]:掃描字符集合(a-z,A-z,0-9,'\n') - %(數量)[]:掃描(數量限制)字符集合 - %[^]:掃描非字符集合 - %*[^=]:掃描非字符集合,並且不保存,而這時會存下'=' - %*[^=]=%s:掃描非字符集合,並且不保存,而這時會存下'='後面的字串 - %[^\n]%*c:整行讀入 ```c 假設測資是a=3,b=2,c=3 scanf("a=%d,b=%d,c=%d",&a,&b,&c); //非格式化存入資料 scanf("%80[a-z | A-Z | 0-9|,.-]", address); //80個指定字元讀入 ``` #### sscanf (從s讀取數據並依格式將它們存儲到位置) ```c int sscanf ( const char * s, const char * format, ...); example: char sentence []="KeRong is 18 years old"; char str [20]; int i; sscanf (sentence,"%s %*s %d",str,&i); printf ("%s -> %d\n",str,i);//KeRong -> 12 ``` ### Character input/output: #### getchar (從標準輸入獲取字元) ```c int getchar ( void );//返回的是獲取ascii值,錯誤回傳-1 example: do{ c=getchar(); putchar(c); }while (c != '\n'); ``` #### gets (從標準輸入讀取字串並將它們儲到 str 中,直到到達換行符或文件結尾) ```c char * gets ( char * str );//成功返回該字串,不成功返回(null) example: char string [256]; gets(string); //123abc printf("%s",string); //out:123abc ``` #### putchar (將一個字元寫入標準輸出) ```c int putchar ( int character );//回傳ascii值,錯誤則回傳EOF(-1) example: char c; for (c = 'A' ; c <= 'Z' ; c++){ putchar(c); //印書A~Z } ``` #### puts (將str字串寫入標準輸出,並附加一個換行符'\n') ```c int puts ( const char * str );//成功回傳一個非負整數,錯誤回傳EOF(-1) example: char string [] = "Hello world!"; puts(string); ``` ## <stdlib.h> (定義雜項函式及記憶體分配函式) ### 數據類型 | 名字 | 描述 | | --- | --- | | size_t | 算子sizeof返回結果的數據類型,實際上是無符號整數| | div_t、ldiv_t、lldiv_t| 函數div、ldiv、lldiv的返回結果的數據類型,包含兩個整數的結構類型 | ### String conversion | 名字 | 描述 | | :-: | --- | | atof | 把字串轉換為雙精度浮點數| | atoi | 把字串轉換為整數| | atol | 把字串轉換為長整數| | atoll | 把字串轉換為長長整數| | strtod | 把字串轉換為雙精度浮點數,檢查結果是否溢出,並返回字串不能轉換部分的地址 | | strtof | 把字串轉換為單精度浮點數,檢查結果是否溢出,並返回字串不能轉換部分的地址 | | strtold | 把字串轉換為長雙精度浮點數,檢查結果是否溢出,並返回字串不能轉換部分的地址 | | strtol | 把字串轉換為長整數,檢查結果是否溢出,並返回字串不能轉換部分的地址. | | strtoll | 把字串轉換為長長整數,檢查結果是否溢出,並返回字串不能轉換部分的地址. | | strtoul | 把字串轉換為無符號長整數,檢查結果是否溢出,並返回字串不能轉換部分的地址. | | strtoull | 把字串轉換為無符號長長整數,檢查結果是否溢出,並返回字串不能轉換部分的地址| ### Dynamic memory management #### malloc (動態內存分配,其內容不初始化) ```c void* malloc (size_t size); example: /*=======<一維>========*/ int *array=(int *)malloc(n*sizeof(int));//等同int array[n]; /*=======<二維>========*/ char **sentence=(char **)malloc(row*sizeof(char *)); for(int y=0;y<row;y++){ sentence[y]=(char *)malloc((column+1)*sizeof(char));//字串結尾'\0' } ``` #### calloc (數組的動態內存分配,且初始化為全零) ```c void* calloc (size_t num, size_t size); example: /*=======<一維>========*/ int *array=(int *)calloc(n,sizeof(int));//等同int array[n]={0}; /*=======<二維>========*/ char **sentence=(char **)calloc(row,sizeof(char *)); for(int y=0;y<row;y++){ sentence[y]=(char *)calloc((column+1),sizeof(char));//字串結尾'\0' } ``` #### realloc (釋放舊動態內存,按照給的尺寸分配新的動態內存,舊的內存塊的內容儘量複製到新的內存) ```c void* realloc (void* ptr, size_t size);//新位址與舊位置並不保證相同 example: int input; int count = 0; int* numbers = NULL; int* more_numbers = NULL; while(scanf("%d",&input)!=EOF && input){//輸入0停止 count+=1; more_numbers=(int *)realloc(numbers,count*sizeof(int)); numbers=more_numbers; numbers[count-1]=input; } for (int x=0;x<count;x++){ printf ("%d ",numbers[x]); //印出資料 } free (numbers); /*========<字串>=====*/ char *str=(char *)malloc(15*sizeof(char)); strcpy(str,"Hello "); char *new_str=(char *)realloc(str,25*sizeof(char)); str=new_str; strcat(str,"world"); printf("%s",str);//Hello world free(str); ``` #### free (系統釋放動態分配的內存,如果是空指針,則無動作發生) ```c void free (void* ptr); example: int *array=(int *)malloc(99*sizeof(int)); free(array); ``` ### Searching and sorting #### bsearch (二元搜索) ```c void* bsearch (const void* key, const void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); example: int cmp(const void *a,const void *b) { return (*(int*)a - *(int*)b); } int list[6]={50,20,60,40,10,30}; int main(){ int key=40; qsort(list,6,sizeof(int),cmp); int *search=(int*)bsearch(&key,list,6,sizeof(int),cmp); if(search!=NULL){ printf("%d is in the array.\n",*search); } else{ printf("%d is not in the array.\n",key); } return 0; } ``` #### qsort(快速排序) ```c void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); example: int cmp(const void *a,const void *b) { return (*(int*)a - *(int*)b); } int main(){ int list[6] = { 50, 20, 60, 40, 10, 30}; qsort(list,6,sizeof(int),cmp); for(int x=0;x<6;x++){ printf("%d ",list[x]); } return 0; } ``` ### Integer arithmetics |名字|描述| |:-:|:-:| | abs、labs、llabs| 計算整數的絕對值| | div、ldiv、lldiv | 計算整數除法的商與餘數 | - int quot; // quotient(商數) - int rem; &nbsp;// remainder(餘數) - div_t (int Numerator, int Denominator); ```c div_t divresult; divresult = div (38,5); printf ("quot = %d,rem = %d\n", divresult.quot, divresult.rem);//quot = 7,rem = 3 ``` ## <string.h> (字串處理) ### Copying #### memcpy (str2複製n個字元到儲存到str1,記憶體區域不能重疊) ```c void *memcpy(void *str1, const void *str2, size_t n); example: struct { char name[40]; int age; } person, person_copy; int main (){ char myname[] = "KeRong"; memcpy(person.name,myname,strlen(myname)+1); person.age=18; memcpy(&person_copy,&person,sizeof(person)); printf("person_copy: %s, %d \n",person_copy.name,person_copy.age); return 0; } /*=======<從第幾個字元複製>========*/ char s[]={"kerong krameri120 hello"}; char d[20]; memcpy(d, s+7,10); //memcpy(d,s+7*sizeof(char),10*sizeof(char)); d[10]='\0'; printf("%s", d);//krameri120 ``` #### memmove (str2複製n個字元到儲存到str1,記憶體區域能重疊,比memcpy安全) ```c void * memmove ( void * destination, const void * source, size_t num ); example: char str[]="memmove can be very useful......"; memmove(str+20,str+15,11); puts(str);//memmove can be very very useful. ``` #### strcpy (把src所指向的字串複製到dest,dest不夠大會有溢出狀況) ```c char * strcpy ( char * destination, const char * source ); example: char str[40]; char str1[]="Sample string"; strcpy (str,str1); puts(str);//Sample string ``` #### strncpy (把src所指向的字串複製到dest,最多複制n個字元) ```c char * strncpy ( char * destination, const char * source, size_t num ); example: char str1[]= "To be or not to be"; char str2[40]; char str3[40]; strncpy(str2,str1,sizeof(str2)); strncpy(str3,str2,5); str3[5] = '\0'; puts(str1);//To be or not to be puts(str2);//To be or not to be puts(str3);//To be ``` ### Concatenation #### strcat (src指向結尾的字串的字串附加到指向dest) ```c char * strcat ( char * destination, const char * source ); example: char str[80]={"String are "}; strcat(str,"concatenated."); puts(str);//String are concatenated. ``` #### strncat (追加src指向字串結尾的字串到dest指向最多n個字元長) ```c char * strncat ( char * destination, const char * source, size_t num ); example: char str1[20]={"To be "}; char str2[20]={"or not to be"}; strncat(str1, str2, 6); puts(str1);//To be or not to be ``` ### Comparison |返回值|表示| |:-:|:-:| |<0|str1<str2| |=0|str1=str2| |>0|str1>str2| - 根據ascii比較字元大小 #### memcmp (把ptr1和ptr2的前n個字元進行比較) ```c int memcmp ( const void * ptr1, const void * ptr2, size_t num ); example: int n=memcmp(str1, str2, 5); ``` #### strcmp (把str1和str2進行比較) ```c int strcmp ( const char * str1, const char * str2 ); example: int n=memcmp(str1,str2); ``` #### strncmp (把str1和str2的前n個字元進行比較) ```c int strncmp ( const char * str1, const char * str2, size_t num ); example: int n=memcmp(str1,str2,5); ``` ### Searching #### memchr (搜索str指向字串的前n個字元中第一次出現的字元c) ```c const void * memchr ( const void * ptr, int value, size_t num ); example: char str[] = "Example string"; char *search=(char*)memchr(str,'p',strlen(str)); printf("%d",search-str);//4 ``` #### strchr (搜索str指向字串第一次出現的字元c) ```c const char * strchr ( const char * str, int character ); example: char str[] = "Example string"; char *search=strchr(str,'s');; printf("%d",search-str);//8 ``` #### strrchr (搜索str指向字串最後一次出現的字元c) ```c const char * strrchr ( const char * str, int character ); example: char str[] = "kerong krameri120"; char *search=strrchr(str,'r');; printf("%d",search-str);//12 ``` #### strpbrk (str1中找出最先含有str2中任一字元的位置) ```c strpbrk -> string pointer break const char * strpbrk ( const char * str1, const char * str2 ); example: char str[] = "This is a sample string"; char key[] = "aeiou"; char *search=strpbrk(str,key); printf("%d",search-str);//2(i) ``` #### strspn (str1連續有幾個字元都含字串str2中的字元) ```c size_t strspn ( const char * str1, const char * str2 ); example: char strtext[] = "12s9th"; char cset[] = "1234567890"; int i=strspn(strtext,cset); printf("%d\n",i);//2 ``` #### strcspn (str1連續有幾個字元都不含字串str2中的字元) ```c strcspn -> complementary span size_t strcspn ( const char * str1, const char * str2 ); example: char str[] = "fcb7a3"; char keys[] = "1234567890"; int i=strcspn(str,keys); printf("%d\n",i);//3 ``` #### strstr (找到第一次出現在str1字串中的str2字串) ```c const char * strstr ( const char * str1, const char * str2 ); example: char str[] ="a simple b simple"; char *search=strstr(str,"simple"); printf("%d",search-str);//2 strncpy(search,"sample",6); search=strstr(str,"simple");//again printf("%d",search-str);//11 ``` #### strtok (分解字串str為一組字串,delim為分隔符) ```c char * strtok ( char * str, const char * delimiters ); example: char str[] ="- This, a sample string."; char *pick; pick=strtok(str," ,.-"); while(pick!= NULL) { printf("%s\n",pick); pick=strtok(NULL, " ,.-"); } /* out: This a sample string */ ``` ### Other #### strlen (計算給定字串的長度) ```c size_t strlen ( const char * str ); example: char str[]= "kerong"; printf("Length:%d", strlen(str));//Length:6 ``` #### memset (複製字元value到ptr指定字串num個字元) ```c void * memset ( void * ptr, int value, size_t num ); example: char str[] = "kerong krameri120"; memset(str,'-',6); puts(str);//------ krameri120 ``` ## <ctype.h> (測試字元是否屬於特定的字元類別) |名字|描述| |:-:|-| | isalnum | 是否為字母數字 | | isalpha | 是否為字母 | | islower | 是否為小寫字母 | | isupper | 是否為大寫字母 | | isdigit | 是否為數字 | | isxdigit| 是否為16進位數字| | iscntrl | 是否為控制字元 | | isgraph | 是否為圖形字元 | | isspace | 是否為空格字元(包括制表符、回車、換行)等 | | isblank | 是否為空白字元(包括水平制表符)| | isprint | 是否為可列印字元| | ispunct | 是否為標點 | | tolower | 轉換為小寫 | | toupper | 轉換為大寫 | ## <limits.h> (定義了整數類型的一些極限值) |name|value|name|value|name|value| |:-:|:-:|:-:|:-:|:-:|:-:| | CHAR_BIT | 8 |SCHAR_MIN|-128| SCHAR_MAX|127| | CHAR_MIN | -128 | CHAR_MAX | 127 | UCHAR_MAX | 255 | | SHRT_MIN | -32768 | SHRT_MAX | 32767 |USHRT_MAX | 65535 | | INT_MIN | -2^31^ |INT_MAX | 2^31^ -1 | UINT_MAX | 2^32^ -1| | LONG_MIN | -2^31^ |LONG_MAX | 2^31^ -1 | ULONG_MAX | 2^32^ -1| | LLONG_MIN | -2^63^ | LLONG_MAX | 2^63^ -1 |ULLONG_MAX |2^64^ -1| ## <math.h> (定義數學函式) ### Trigonometric functions - #define PI acos(-1) - radian=degrees*PI/180.0 - degrees=radian*180/PI | 函數原型 | 描述 | |-|:-:| | double sin(x) | 正弦 | | double cos(x) | 餘弦 | | double tan(x) | 正切 | | double asin(x) | 反正弦 | | double acos(x) | 反餘弦 | | double atan(x) | 反正切 | | double atan2(y,x)| 反正切 | | double sinh(x) | 雙曲正弦 | | double cosh(x) | 雙曲餘弦 | | double tanh(x) | 雙曲正切 | ### Exponential、Logarithmic、Power functions | 函數原型 | 描述 | |:-|-| | double exp(x) | 指數函數 | | double sqrt(x) | 開平方根 | | double cbrt(x) | 開立方根 | | double log(x) | 自然對數 | | double log10(x)| 常用對數 | | double pow(x,y)| 計算x^y^ | | double hypot(a,b)|計算直角三角形斜邊長度| ### Rounding and remainder functions | 函數原型 | 描述 | |:-|-| |double ceil(x)|上取整| |double floor(x)|下取整| |double round(x)|四捨五入| |double trunc(x)|小數直接捨去| |double fmod(x,y)|返回除以x/y的剩餘值| ### Other functions | 函數原型 | 描述 | |-|-| |double fabs(x)|求浮點數的絕對值| |double abs(x)|求整數的絕對值| |double fma(x,y,z)|x * y + z (皆為double)| ## <stdbool.h> (包含四個用於布林型的預定義巨集) |name|value| |:-:|:-:| |bool|_Bool| |true|1| |false|0| |__bool_true_false_are_defined|1| ## <iso646.h> (位元和邏輯運算子的巨集) |巨集|定義為|巨集|定義為| |:-:|:-:|:-:|:-:| |not|!|not_eq|!=| |and|&&|or|\|\|| |and_eq|&=|or_eq|\|=| |xor|^|xor_eq|^=| |bitand|&|bitor|\|| |compl|~| | | ## Struct(結構) ```c struct <結構型態名稱>{ <資料型態1> <欄位名稱1>; <資料型態2> <欄位名稱2>; }; example: struct student{ //此結構為struct student int studenID; //學號 char name[20]; //姓名 }; ``` - 使用結構變數和點號運算子 (.) ```c struct student myclass; //定義myclass類別為struct student scanf("%d%s",&myclass.studenID,myclass.name); //輸入學號和姓名到myclass printf("%d %s",myclass.studenID,myclass.name);//輸出學號和姓名 ``` - 使用指向結構變數的指標和箭號運算子(->) ```c struct student *ptr=&myclass; //承接上面程式碼 printf("%d %s\n", ptr->studenID,ptr->name); //輸出學號和姓名 //ptr->studenID 等於 (*ptr).studenID ``` ## Typedef(自定義類型) ```c typedef struct{ <資料型態1> <欄位名稱1>; <資料型態2> <欄位名稱2>; }<結構型態名稱>; example: typedef sturct { char name[20]; //姓名 int id; //學號 double score; //成績 }studtype; //studtype是結構型態的名稱 ``` - 結構型態之變項宣稱與初值設定 ```c studtype stu1= {"kerong",38,80}; //利用自訂結構型態studtype宣稱結構變項stu1 //並設定結構變項stu1各欄位之初值 ``` - 利用指定敘述以操作結構變項之內容 ```c stu1.name[] ="krameri120"; stu1.id = 30; stu1.score = 85; ``` - 透過Dynamic Memory建立學生資料表 ```c typedef struct{ int studenID; //學號 char name[20]; //姓名 }student; int main(){ student *data_sheet=(student *)malloc(10*sizeof(student)); //定義最大10名學生資料表 for(int x=0;x<10;x++){ scanf("%d%s",&data_sheet[x].studenID,data_sheet[x].name); //輸入10名學生資料 } for(int x=0;x<10;x++){ printf("%d %s\n",data_sheet[x].studenID,data_sheet[x].name);//輸出10名學生資料 } return 0; } ``` ## Union (聯合) - union中可以定義多個成員,union的大小由最大的成員的大小決定。  - union成員共享同一塊大小的內存,一次只能使用其中的一個成員。  - 對某一個成員賦值,會覆蓋其他成員的值 ```c typedef union{ <資料型態1> <欄位名稱1>; <資料型態2> <欄位名稱2>; }<聯合型態名稱>; /* 目的: 1.解決相同信息的困擾,避免重複代碼,提高程式碼的簡潔性 2.節省內存 */ ``` ## Enum(列舉) ```c typedef enum{ <列舉值1>, <列舉值2>, }<列舉資料型態名稱>; example: typedef enum {//定義禮拜一到禮拜日所代表的值1~7 Monday=1,Tuesday,Wedsday,Thursday,Friday,Saturday,Sunday }day; //結構名稱定義為day int main(){ day today; char str_day[][10]={" ","Monday","Tuesday","Wedsday", "Thursday","Friday","Saturday","Sunday"}; for(today=Monday;today<=Sunday;today++){ printf("%d %s\n",today,str_day[today]);//依序輸出大小和星期 } return 0; } ```