# C 語言 - 程式筆記 (KeRong)
- 作者:陳科融 CHEN,KE-RONG 更新:2022/10/15
Exercise:Zerojudge、Leetcode、Onlinejudge
![]()
# 概述
C 語言具有高效、靈活、功能豐富、表達力強和較高的可移植性等特點,在程式設計中備受青睞,成為最近 25 年使用最為廣的程式語言 TIOBE Programming Community Index
,並且廣泛用於系統軟體與應用軟體的開發。
# 推薦的編輯器:Code::Blocks、Visual Studio、Eclipse
# 資料型態
關鍵字 |
型態 |
位元組 |
範圍 |
格式化字串 |
bool |
布林 |
1 |
false or true |
%d |
char |
字元 |
1 |
-128 ~ 127 |
%c |
short |
短整數 |
2 |
-215 ~ 215-1 |
%hd |
int |
整數 |
4 |
-231 ~ 231-1 |
%d |
long long |
長整數 |
8 |
-263 ~ 263-1 |
%lld |
float |
單精度浮點 |
4 |
2.939x10−38 ~ 3.403x1038 |
%f |
double |
雙精度浮點 |
8 |
5.563x10309 ~ 1.798x10308 |
%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 所定義的資料型態為浮點數↓
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 % 2n = a & (n-1)
- a + b = a^b + (a & b) << 1
- a / 2n = a >> n
- A * 2n = A << n
# 其他運算子
運算子名稱 |
語法 |
運算子名稱 |
語法 |
陣列下標 |
a[b] |
函數呼叫 |
a() |
取址 |
&a |
取值 |
*a |
成員 |
a.b |
成員指標 |
a->b |
逗號 |
a , b |
三元條件 |
a ? b : c |
# 註解 (用來說明程式的含意)
- /* something */ 圍繞的文字會被電腦略過,跨行註解
- // 兩個正斜線的單行註解
# 基本結構
# 選擇結構
| if(條件){ |
| actions; |
| } |
| else if(條件){ |
| actions; |
| } |
| else{ |
| actions; |
| } |
# 重複結構
| |
| for(int x=0;x<10;x++){ |
| actions; |
| if(x==5){ |
| continue; |
| } |
| } |
| |
| int n=0; |
| while(n<10){ |
| actions; |
| if(n==5){ |
| break; |
| } |
| n+=1; |
| } |
| |
| do { |
| statement; |
| } while (condition); |
# 多重選擇結構
| switch (value){ |
| case 1: |
| actions |
| break; |
| case 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
| #include<stdio.h> |
| #include<stdlib.h> |
| #include<string.h> |
| #include<ctype> |
| #include<limits.h> |
| #include<math.h> |
| #include<stdbool.h> |
| #include<iso646.h> |
- #include <filename.h> 和 #include "filename.h" 區別
- <filename.h> 編譯器先從標準庫路徑開始搜索文件名.h,使得系統文件調用較快
- "filename.h" 先從用戶的路徑開始尋找文件名,然後去尋找系統路徑,使得尋找自定義文件較快
# <stdio.h> (定義輸入、輸出函式)
標識符 |
說明 |
stderr |
標準錯誤流 |
stdin |
標準輸入流 |
stdout |
標準輸出流 |
# Marcos 巨集
| #define true 1 |
| #define max(a,b) ((a>=b)?a:b) |
| |
| #define swap(a,b){\ |
| int temp=a;\ |
| a=b;\ |
| b=temp;\ |
| } |
| #define STR(s) #x |
| #define COMBINESTR(x,y) x##y |
| #define makechar(x) #@x |
| #define max(a, b) \ |
| {(typeof(a) _a = a; \ |
| typeof(b) _b = b; \ |
| _a > _b ? _a : _b;) \ |
| } |
| #define swap(a,b){\ |
| 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),\ |
| int:is_int,\ |
| char:is_char,\ |
| char *:is_string,\ |
| double:is_double,\ |
| default:is_float\ |
| )(X) |
# EOF (通常為 - 1)
- End-of-File 以指示已到達文件結尾或指示其他一些失敗條件
# NULL (通常為 0)
# BUFSIZ (設置流緩衝區)
| void setbuf ( FILE * stream, char * buffer ); |
| int setvbuf(FILE * stream, char * buf, int type, unsigned size); |
- _IOFBF (滿緩衝):當緩衝區為空時,從流讀入資料。或當緩衝區滿時,向流寫入資料。
- _IOLBF (行緩衝):每次從流中讀入一行資料或向流中寫入 — 行資料。
- _IONBF (無緩衝):直接從流中讀入資料或直接向流中寫入資料,而沒有緩衝區。
# printf (用於將格式化後的資料輸出到標準輸出)
| 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
| |
| 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 ); |
# sprintf (發送 str 指向一個字串的格式化輸出)
| int sprintf ( char * str, const char * format, ... ); |
| example: |
| char s[99]={'\0'}; |
| sprintf(s,"%d",123); |
| sprintf(s, "%.2f", (double)100); |
# snprintf (比 sprintf 多了一個參數,能控制要寫入的長度,更加安全)
| int snprintf ( char * str, size_t size, const char * format, ... ); |
| example: |
| char s[99]={'\0'}; |
| snprintf(s,2,"%d",123); |
# scanf (格式化的輸入)
| int scanf ( const char * format, ... ); |
| 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:整行讀入
| 假設測資是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); |
# sscanf (從 s 讀取數據並依格式將它們存儲到位置)
| 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); |
# getchar (從標準輸入獲取字元)
| int getchar ( void ); |
| example: |
| do{ |
| c=getchar(); |
| putchar(c); |
| }while (c != '\n'); |
# gets (從標準輸入讀取字串並將它們儲到 str 中,直到到達換行符或文件結尾)
| char * gets ( char * str ); |
| example: |
| char string [256]; |
| gets(string); |
| printf("%s",string); |
# putchar (將一個字元寫入標準輸出)
| int putchar ( int character ); |
| example: |
| char c; |
| for (c = 'A' ; c <= 'Z' ; c++){ |
| putchar(c); |
| } |
# puts (將 str 字串寫入標準輸出,並附加一個換行符 '\n')
| int puts ( const char * str ); |
| 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 (動態內存分配,其內容不初始化)
| void* malloc (size_t size); |
| example: |
| |
| int *array=(int *)malloc(n*sizeof(int)); |
| |
| char **sentence=(char **)malloc(row*sizeof(char *)); |
| for(int y=0;y<row;y++){ |
| sentence[y]=(char *)malloc((column+1)*sizeof(char)); |
| } |
# calloc (數組的動態內存分配,且初始化為全零)
| void* calloc (size_t num, size_t size); |
| example: |
| |
| int *array=(int *)calloc(n,sizeof(int)); |
| |
| char **sentence=(char **)calloc(row,sizeof(char *)); |
| for(int y=0;y<row;y++){ |
| sentence[y]=(char *)calloc((column+1),sizeof(char)); |
| } |
# realloc (釋放舊動態內存,按照給的尺寸分配新的動態內存,舊的內存塊的內容儘量複製到新的內存)
| 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){ |
| 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); |
| free(str); |
# free (系統釋放動態分配的內存,如果是空指針,則無動作發生)
| void free (void* ptr); |
| example: |
| int *array=(int *)malloc(99*sizeof(int)); |
| free(array); |
# Searching and sorting
# bsearch (二元搜索)
| 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 (快速排序)
| 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; //remainder (餘數)
- div_t (int Numerator, int Denominator);
| div_t divresult; |
| divresult = div (38,5); |
| printf ("quot = %d,rem = %d\n", divresult.quot, divresult.rem); |
# <string.h> (字串處理)
# Copying
# memcpy (str2 複製 n 個字元到儲存到 str1,記憶體區域不能重疊)
| 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); |
| |
| d[10]='\0'; |
| printf("%s", d); |
# memmove (str2 複製 n 個字元到儲存到 str1,記憶體區域能重疊,比 memcpy 安全)
| 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); |
# strcpy (把 src 所指向的字串複製到 dest,dest 不夠大會有溢出狀況)
| char * strcpy ( char * destination, const char * source ); |
| example: |
| char str[40]; |
| char str1[]="Sample string"; |
| strcpy (str,str1); |
| puts(str); |
# strncpy (把 src 所指向的字串複製到 dest,最多複制 n 個字元)
| 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); |
| puts(str2); |
| puts(str3); |
# Concatenation
# strcat (src 指向結尾的字串的字串附加到指向 dest)
| char * strcat ( char * destination, const char * source ); |
| example: |
| char str[80]={"String are "}; |
| strcat(str,"concatenated."); |
| puts(str); |
# strncat (追加 src 指向字串結尾的字串到 dest 指向最多 n 個字元長)
| 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); |
# Comparison
返回值 |
表示 |
<0 |
str1<str2 |
=0 |
str1=str2 |
>0 |
str1>str2 |
# memcmp (把 ptr1 和 ptr2 的前 n 個字元進行比較)
| int memcmp ( const void * ptr1, const void * ptr2, size_t num ); |
| example: |
| int n=memcmp(str1, str2, 5); |
# strcmp (把 str1 和 str2 進行比較)
| int strcmp ( const char * str1, const char * str2 ); |
| example: |
| int n=memcmp(str1,str2); |
# strncmp (把 str1 和 str2 的前 n 個字元進行比較)
| int strncmp ( const char * str1, const char * str2, size_t num ); |
| example: |
| int n=memcmp(str1,str2,5); |
# Searching
# memchr (搜索 str 指向字串的前 n 個字元中第一次出現的字元 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); |
# strchr (搜索 str 指向字串第一次出現的字元 c)
| const char * strchr ( const char * str, int character ); |
| example: |
| char str[] = "Example string"; |
| char *search=strchr(str,'s');; |
| printf("%d",search-str); |
# strrchr (搜索 str 指向字串最後一次出現的字元 c)
| const char * strrchr ( const char * str, int character ); |
| example: |
| char str[] = "kerong krameri120"; |
| char *search=strrchr(str,'r');; |
| printf("%d",search-str); |
# strpbrk (str1 中找出最先含有 str2 中任一字元的位置)
| 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); |
# strspn (str1 連續有幾個字元都含字串 str2 中的字元)
| 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); |
# strcspn (str1 連續有幾個字元都不含字串 str2 中的字元)
| 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); |
# strstr (找到第一次出現在 str1 字串中的 str2 字串)
| 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); |
| strncpy(search,"sample",6); |
| search=strstr(str,"simple"); |
| printf("%d",search-str); |
# strtok (分解字串 str 為一組字串,delim 為分隔符)
| 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 (計算給定字串的長度)
| size_t strlen ( const char * str ); |
| example: |
| char str[]= "kerong"; |
| printf("Length:%d", strlen(str)); |
# memset (複製字元 value 到 ptr 指定字串 num 個字元)
| void * memset ( void * ptr, int value, size_t num ); |
| example: |
| char str[] = "kerong krameri120"; |
| memset(str,'-',6); |
| puts(str); |
# <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 |
-231 |
INT_MAX |
231 -1 |
UINT_MAX |
232 -1 |
LONG_MIN |
-231 |
LONG_MAX |
231 -1 |
ULONG_MAX |
232 -1 |
LLONG_MIN |
-263 |
LLONG_MAX |
263 -1 |
ULLONG_MAX |
264 -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) |
計算 xy |
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 (結構)
| struct <結構型態名稱>{ |
| <資料型態1> <欄位名稱1>; |
| <資料型態2> <欄位名稱2>; |
| }; |
| example: |
| struct student{ |
| int studenID; |
| char name[20]; |
| }; |
| struct student myclass; |
| scanf("%d%s",&myclass.studenID,myclass.name); |
| printf("%d %s",myclass.studenID,myclass.name); |
| struct student *ptr=&myclass; |
| printf("%d %s\n", ptr->studenID,ptr->name); |
| |
# Typedef (自定義類型)
| typedef struct{ |
| <資料型態1> <欄位名稱1>; |
| <資料型態2> <欄位名稱2>; |
| }<結構型態名稱>; |
| example: |
| typedef sturct { |
| char name[20]; |
| int id; |
| double score; |
| }studtype; |
| studtype stu1= {"kerong",38,80}; |
| |
| |
| stu1.name[] ="krameri120"; |
| stu1.id = 30; |
| stu1.score = 85; |
- 透過 Dynamic Memory 建立學生資料表
| typedef struct{ |
| int studenID; |
| char name[20]; |
| }student; |
| int main(){ |
| student *data_sheet=(student *)malloc(10*sizeof(student)); |
| for(int x=0;x<10;x++){ |
| scanf("%d%s",&data_sheet[x].studenID,data_sheet[x].name); |
| } |
| for(int x=0;x<10;x++){ |
| printf("%d %s\n",data_sheet[x].studenID,data_sheet[x].name); |
| } |
| return 0; |
| } |
# Union (聯合)
- union 中可以定義多個成員,union 的大小由最大的成員的大小決定。
- union 成員共享同一塊大小的內存,一次只能使用其中的一個成員。
- 對某一個成員賦值,會覆蓋其他成員的值
| typedef union{ |
| <資料型態1> <欄位名稱1>; |
| <資料型態2> <欄位名稱2>; |
| }<聯合型態名稱>; |
| |
| 目的: |
| 1. 解決相同信息的困擾,避免重複代碼,提高程式碼的簡潔性 |
| 2. 節省內存 |
| */ |
# Enum (列舉)
| typedef enum{ |
| <列舉值1>, |
| <列舉值2>, |
| }<列舉資料型態名稱>; |
| example: |
| typedef enum { |
| Monday=1,Tuesday,Wedsday,Thursday,Friday,Saturday,Sunday |
| }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; |
| } |