提供基本语法和方法的 C 快速参考备忘单。
入门 hello.c 1 2 3 4 5 6 #include <stdio.h> int main () { printf ("Hello World!" ); return 0 ; }
使用 gcc 编译 hello.c 源文件
运行编译后的二进制文件可执行文件(hello)
变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int myNum = 15 ;int myNum2; myNum2 = 15 ; int myNum3 = 15 ; myNum3 = 10 ; float myFloatNum = 5.99 ; char myLetter = 'D' ; int x = 5 ;int y = 6 ;int sum = x + y; int x = 5 , y = 6 , z = 50 ;
常量 Constants 常量在 C 语言中我们一般理解为不能被改变的值,活用常量与符号常量
1 2 const int minutesPerHour = 60 ;const float PI = 3.14 ;
最佳实践
1 const int BIRTHYEAR = 1980 ;
注释 1 2 3 4 printf ("Hello World!" );
打印文本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 printf ("I am learning C." );int testInteger = 5 ;printf ("Number = %d" , testInteger);float f = 5.99 ; printf ("Value = %f" , f);short a = 0b1010110 ; int b = 02713 ; long c = 0X1DAB83 ; printf ("a=%ho, b=%o, c=%lo\n" , a, b, c);printf ("a=%hd, b=%d, c=%ld\n" , a, b, c);printf ("a=%hx, b=%x, c=%lx\n" , a, b, c);printf ("a=%hX, b=%X, c=%lX\n" , a, b, c);
控制空格数 1 2 3 4 5 6 7 8 9 int a1=20 , a2=345 , a3=700 ;int b1=56720 , b2=9999 , b3=20098 ;int c1=233 , c2=205 , c3=1 ;int d1=34 , d2=0 , d3=23 ;printf ("%-9d %-9d %-9d\n" , a1, a2, a3);printf ("%-9d %-9d %-9d\n" , b1, b2, b3);printf ("%-9d %-9d %-9d\n" , c1, c2, c3);printf ("%-9d %-9d %-9d\n" , d1, d2, d3);
输出结果
1 2 3 4 20 345 700 56720 9999 20098 233 205 1 34 0 23
%-9d 中,d 表示以 10 进制输出,9 表示最少占 9 个字符的宽度,宽度不足以空格补齐,- 表示左对齐
字符串 Strings 1 2 char greetings[] = "Hello World!" ;printf ("%s" , greetings);
访问字符串
1 2 char greetings[] = "Hello World!" ;printf ("%c" , greetings[0 ]);
修改字符串
1 2 3 4 5 char greetings[] = "Hello World!" ;greetings[0 ] = 'J' ; printf ("%s" , greetings);
另一种创建字符串的方法
1 2 3 4 char greetings[] = {'H' ,'e' ,'l' ,'l' ,'\0' };printf ("%s" , greetings);
C 没有 String 类型,使用 char 类型并创建一个字符 array
条件判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int time = 20 ;if (time < 18 ) { printf ("再会!" ); } else { printf ("晚上好!" ); } int time = 22 ;if (time < 10 ) { printf ("早上好!" ); } else if (time < 20 ) { printf ("再会!" ); } else { printf ("晚上好!" ); }
三元运算符 1 2 int time = 20 ;(time < 18 ) ? printf ("再会!" ) : printf ("晚上好!" );
Switch 1 2 3 4 5 6 7 8 9 int day = 4 ;switch (day) { case 3 : printf ("周三" ); break ; case 4 : printf ("周四" ); break ; default : printf ("期待周末" ); }
While 循环 1 2 3 4 5 6 int i = 0 ;while (i < 5 ) { printf ("%d\n" , i); i++; }
注意 :不要忘记增加条件中使用的变量,否则循环永远不会结束,成为“死循环”!
Do/While 循环 1 2 3 4 5 6 int i = 0 ;do { printf ("%d\n" , i); i++; } while (i < 5 );
For 循环 1 2 3 4 5 int i;for (i = 0 ; i < 5 ; i++) { printf ("%d\n" , i); }
跳出循环 Break/Continue 1 2 3 4 5 6 7 8 int i;for (i = 0 ; i < 10 ; i++) { if (i == 4 ) { break ; } printf ("%d\n" , i); }
在 i 等于 4 时跳出循环
1 2 3 4 5 6 7 8 int i;for (i = 0 ; i < 10 ; i++) { if (i == 4 ) { continue ; } printf ("%d\n" , i); }
示例跳过 4 的值
While Break 示例 1 2 3 4 5 6 7 8 9 int i = 0 ;while (i < 10 ) { if (i == 4 ) { break ; } printf ("%d\n" , i); i++; }
While continue 示例 1 2 3 4 5 6 7 8 9 int i = 0 ;while (i < 10 ) { i++; if (i == 4 ) { continue ; } printf ("%d\n" , i); }
数组 Arrays 1 2 3 int myNumbers[] = {25 , 50 , 75 , 100 };printf ("%d" , myNumbers[0 ]);
更改数组元素
1 2 3 4 int myNumbers[] = {25 , 50 , 75 , 100 };myNumbers[0 ] = 33 ; printf ("%d" , myNumbers[0 ]);
循环遍历数组
1 2 3 4 5 6 int myNumbers[] = {25 , 50 , 75 , 100 };int i;for (i = 0 ; i < 4 ; i++) { printf ("%d\n" , myNumbers[i]); }
设置数组大小
1 2 3 4 5 6 7 int myNumbers[4 ];myNumbers[0 ] = 25 ; myNumbers[1 ] = 50 ; myNumbers[2 ] = 75 ; myNumbers[3 ] = 100 ;
枚举 Enum 1 enum week { Mon = 1 , Tues, Wed, Thurs, Fri, Sat, Sun };
定义枚举变量
1 2 3 enum week a , b , c ;enum week { Mon = 1 , Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c;
有了枚举变量,就可以把列表中的值赋给它
1 2 3 4 enum week { Mon = 1 , Tues, Wed, Thurs, Fri, Sat, Sun };enum week a = Mon, b = Wed, c = Sat;enum week { Mon = 1 , Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat;
枚举示例应用 1 2 3 4 5 6 7 8 9 10 11 enum week { Mon = 1 , Tues, Wed, Thurs} day;scanf ("%d" , &day);switch (day){ case Mon: puts ("Monday" ); break ; case Tues: puts ("Tuesday" ); break ; case Wed: puts ("Wednesday" ); break ; case Thurs: puts ("Thursday" ); break ; default : puts ("Error!" ); }
用户输入 1 2 3 4 5 6 7 8 9 10 11 int myNum;printf ("请输入一个数字: \n" );scanf ("%d" , &myNum);printf ("您输入的数字: %d" , myNum);
用户输入字符串 1 2 3 4 5 6 7 8 char firstName[30 ];printf ("输入您的名字: \n" );scanf ("%s" , firstName);printf ("Hello %s." , firstName);
内存地址 创建变量时,会为该变量分配一个内存地址
1 2 3 4 int myAge = 43 ;printf ("%p" , &myAge);
要访问它,请使用引用运算符 (&)
创建指针 1 2 3 4 5 int myAge = 43 ; printf ("%d" , myAge); printf ("%p" , &myAge);
指针变量 1 2 3 4 5 6 7 8 int myAge = 43 ; int * ptr = &myAge; printf ("%d\n" , myAge); printf ("%p\n" , &myAge); printf ("%p\n" , ptr);
取消引用 1 2 3 4 5 6 7 8 int myAge = 43 ; int * ptr = &myAge; printf ("%p\n" , ptr);printf ("%d\n" , *ptr);
运算符 算术运算符 1 2 3 4 int myNum = 100 + 50 ;int sum1 = 100 + 50 ; int sum2 = sum1 + 250 ; int sum3 = sum2 + sum2;
Operator Name Description Example +加 将两个值相加 x + y-减 从另一个值中减去一个值 x - y*乘 将两个值相乘 x * y/除 将一个值除以另一个 x / y%取模 返回除法余数 x % y++增量 将变量的值增加 1 ++--乘量 将变量的值减 1 --x
赋值运算符 符号 示例 如同 =x = 5 x = 5 +=x += 3 x = x + 3 -=x -= 3 x = x - 3 *=x *= 3 x = x * 3 /=x /= 3 x = x / 3 %=x %= 3 x = x % 3 &=x &= 3 x = x & 3 |=x |= 3 x = x | 3 ^=x ^= 3 x = x ^ 3 >>=x >>= 3 x = x >> 3 <<=x <<= 3 x = x << 3
比较运算符 1 2 3 4 5 int x = 5 ;int y = 3 ;printf ("%d" , x > y);
符号 名称 示例 ==等于 x == y !=不等于 x != y >大于 x > y <小于 x < y >=大于或等于 x >= y <=小于或等于 x <= y
比较运算符用于比较两个值
逻辑运算符 符号 名称 说明 示例 &&与逻辑如果两个语句都为真,则返回真 x < 5 && x < 10||或逻辑如果其中一个语句为真,则返回真 x < 5 || x < 4!非逻辑反转结果,如果结果为真则返回假 !(x < 5 && x < 10)
运算符示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 unsigned int a = 60 ; unsigned int b = 13 ; int c = 0 ; c = a & b; printf ("Line 1 - c 的值是 %d\n" , c );c = a | b; printf ("Line 2 - c 的值是 %d\n" , c );c = a ^ b; printf ("Line 3 - c 的值是 %d\n" , c );c = ~a; printf ("Line 4 - c 的值是 %d\n" , c );c = a << 2 ; printf ("Line 5 - c 的值是 %d\n" , c );c = a >> 2 ; printf ("Line 6 - c 的值是 %d\n" , c );
位运算符 运算符 描述 实例 &按位与操作,按二进制位进行”与”运算 (A & B) 将得到 12 即为 0000 1100|按位或运算符,按二进制位进行”或”运算 (A | B) 将得到 61 即为 0011 1101^异或运算符,按二进制位进行”异或”运算 (A ^ B) 将得到 49 即为 0011 0001~取反运算符,按二进制位进行”取反”运算 (~A) 将得到 -61 即为 1100 0011<<二进制左移运算符 A << 2 将得到 240 即为 1111 0000>>二进制右移运算符 A >> 2 将得到 15 即为 0000 1111
数据类型 Data Types 基本数据类型 数据类型 大小 Size 范围 Range 描述 Description char1 字节 −128 ~ 127单个字符/字母/数字/ASCII signed char1 字节 −128 ~ 127- unsigned char1 字节 0 ~ 255- int2 到 4 字节−32,768 ~ 32,767存储整数 signed int2 字节 −32,768 ~ 32,767unsigned int2 字节 0 ~ 65,535short int2 字节 −32,768 ~ 32,767signed short int2 字节 −32,768 ~ 32,767unsigned short int2 字节 0 ~ 65,535long int4 字节 -2,147,483,648 ~ 2,147,483,647signed long int4 字节 -2,147,483,648 ~ 2,147,483,647unsigned long int4 字节 0 ~ 4,294,967,295float4 字节 double8 字节 long double10 字节
数据类型 1 2 3 4 5 6 7 8 9 10 11 int myNum = 5 ; float myFloatNum = 5.99 ; char myLetter = 'D' ; double myDouble = 3.2325467 ;printf ("%d\n" , myNum);printf ("%f\n" , myFloatNum);printf ("%c\n" , myLetter);printf ("%lf\n" , myDouble);
数据类型 说 明 char字符型 short短整型 int整型 long长整型 float单精度浮点型 double双精度浮点型 void无类型
基本格式说明符 格式说明符 数据类型 %d 或 %iint 整数%ffloat 单精度的十进制类型%lfdouble 高精度浮点数据或数字%cchar 字符%s用于 strings 字符串
基本格式说明符 short int long 8 进制 %ho%o%lo10 进制 %hd%d%ld16 进制 %hx / %hX%x / %X%lx / %lX
数据格式示例 1 2 3 4 5 6 7 int myNum = 5 ;float myFloatNum = 5.99 ; char myLetter = 'D' ; printf ("%d\n" , myNum);printf ("%f\n" , myFloatNum);printf ("%c\n" , myLetter);
预处理器 预处理器指令 指令 描述 #define定义宏 #include包含一个源代码文件 #undef取消已定义的宏 #ifdef如果宏已经定义,则返回真 #ifndef如果宏没有定义,则返回真 #if如果给定条件为真,则编译下面代码 #else#if 的替代方案#elif如果 #if 条件为假,当前条件为真 #endif结束一个 #if……#else 条件编译块 #error当遇到标准错误时,输出错误消息 #pragma使用标准化方法,向编译器发布特殊的命令到编译器中
1 2 3 4 5 6 7 8 #define MAX_ARRAY_LENGTH 20 #include <stdio.h> #include "myheader.h" #undef FILE_SIZE #define FILE_SIZE 42
预定义宏 宏 描述 __DATE__当前日期,一个以 “MMM DD YYYY” 格式表示的字符常量 __TIME__当前时间,一个以 “HH:MM:SS” 格式表示的字符常量 __FILE__这会包含当前文件名,一个字符串常量 __LINE__这会包含当前行号,一个十进制常量 __STDC__当编译器以 ANSI 标准编译时,则定义为 1
ANSI C 定义了许多宏,您可以使用这些宏,但是不能直接修改这些预定义的宏
预定义宏示例 1 2 3 4 5 6 7 8 9 #include <stdio.h> int main () { printf ("File :%s\n" , __FILE__); printf ("Date :%s\n" , __DATE__); printf ("Time :%s\n" , __TIME__); printf ("Line :%d\n" , __LINE__); printf ("ANSI :%d\n" , __STDC__); }
宏延续运算符(\) 一个宏通常写在一个单行上。
1 2 #define message_for(a, b) \ printf(#a " 和 " #b ": 我们爱你!\n" )
如果宏太长,一个单行容纳不下,则使用宏延续运算符 \
字符串常量化运算符(#) 1 2 3 4 5 6 7 8 9 #include <stdio.h> #define message_for(a, b) \ printf(#a " 和 " #b ": 我们爱你!\n" ) int main (void ) { message_for(Carole, Debra); return 0 ; }
当上面的代码被编译和执行时,它会产生下列结果:
需要把一个宏的参数转换为字符串常量时,使用字符串常量化运算符 #
标记粘贴运算符(##) 1 2 3 4 5 6 7 8 9 10 #include <stdio.h> #define tokenpaster(n) \ printf ("token" #n " = %d" , token##n) int main (void ) { int token34 = 40 ; tokenpaster(34 ); return 0 ; }
defined() 运算符 1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> #if !defined (MESSAGE) #define MESSAGE "You wish!" #endif int main (void ) { printf ("信息如下: %s\n" , \ MESSAGE); return 0 ; }
参数化的宏 1 2 3 int square (int x) { return x * x; }
宏重写上面的代码,如下:
1 #define square(x) ((x) * (x))
宏名称和左圆括号之间不允许有空格
1 2 3 4 5 6 7 8 #include <stdio.h> #define MAX(x,y) ((x) > (y) ? (x) : (y)) int main (void ) { printf ("20 到 10 之间的最大值是 %d\n" , \ MAX(10 , 20 )); return 0 ; }
函数 函数声明和定义 1 2 3 4 int main () { printf ("Hello World!" ); return 0 ; }
函数由两部分组成
Declaration 声明函数名称、返回类型和参数 (如果有) Definition 函数体 (要执行的代码) 1 2 3 4 5 6 7 8 9 10 void myFunction () ;int main () { myFunction(); return 0 ; } void myFunction () { printf ("晚上好!" ); }
调用函数 1 2 3 4 5 6 7 8 9 10 11 void myFunction () { printf ("晚上好!" ); } int main () { myFunction(); myFunction(); return 0 ; }
函数参数 1 2 3 4 5 6 7 8 9 10 void myFunction (char name[]) { printf ("Hello %s\n" , name); } int main () { myFunction("Liam" ); myFunction("Jenny" ); return 0 ; }
多个参数 1 2 3 4 5 6 7 8 9 10 void myFunction (char name[], int age) { printf ("你好 %s 你 %d 岁了。\n" ,name,age); } int main () { myFunction("Liam" , 3 ); myFunction("Jenny" , 14 ); return 0 ; }
返回值 1 2 3 4 5 6 7 8 9 int myFunction (int x) { return 5 + x; } int main () { printf ("结果: %d" , myFunction(3 )); return 0 ; }
两个参数
1 2 3 4 5 6 7 8 9 10 11 12 13 int myFunction (int x, int y) { return x + y; } int main () { printf ("结果: %d" , myFunction(5 , 3 )); int result = myFunction(5 , 3 ); printf ("结果 = %d" , result); return 0 ; }
递归示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int sum (int k) ;int main () { int result = sum(10 ); printf ("%d" , result); return 0 ; } int sum (int k) { if (k > 0 ) { return k + sum(k - 1 ); } else { return 0 ; } }
数学函数 1 2 3 4 5 #include <math.h> printf ("%f" , sqrt (16 )); printf ("%f" , ceil (1.4 )); printf ("%f" , floor (1.4 )); printf ("%f" , pow (4 , 3 ));
abs(x) 绝对值acos(x) 反余弦值asin(x) 反正弦值atan(x) 反正切cbrt(x) 立方根cos(x) 余弦exp(x) Ex 的值sin(x) x 的正弦值tan(x) 角度的正切Structures 结构 创建结构 1 2 3 4 struct MyStructure { int myNum; char myLetter; };
创建一个名为 s1 的结构变量
{7} 1 2 3 4 5 6 7 8 9 struct myStructure { int myNum; char myLetter; }; int main () { struct myStructure s1 ; return 0 ; }
结构中的字符串 {9} 1 2 3 4 5 6 7 8 9 10 11 12 13 struct myStructure { int myNum; char myLetter; char myString[30 ]; }; int main () { struct myStructure s1 ; strcpy (s1.myString, "Some text" ); printf ("我字符串: %s" , s1.myString); return 0 ; }
使用 strcpy 函数为字符串赋值
访问结构成员 {11,12,16} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 struct myStructure { int myNum; char myLetter; }; int main () { struct myStructure s1 ; s1.myNum = 13 ; s1.myLetter = 'B' ; struct myStructure s2 = {13 , 'B' }; printf ("My number: %d\n" , s1.myNum); printf ("My letter: %c\n" , s1.myLetter); return 0 ; }
创建不同的结构变量
1 2 3 4 5 6 7 8 struct myStructure s1 ;struct myStructure s2 ;s1.myNum = 13 ; s1.myLetter = 'B' ; s2.myNum = 20 ; s2.myLetter = 'C' ;
复制结构 {6} 1 2 3 4 5 6 struct myStructure s1 = { 13 , 'B' , "Some text" }; struct myStructure s2 ;s2 = s1;
示例中,将 s1 的值复制到 s2
修改值 {6,7} 1 2 3 4 5 6 7 8 9 10 11 struct myStructure s1 = { 13 , 'B' }; s1.myNum = 30 ; s1.myLetter = 'C' ; printf ("%d %c %s" , s1.myNum, s1.myLetter);
文件处理 文件处理函数 函数 描述 Description fopen()打开新文件或现有文件fprintf()将数据写入文件 fscanf()从文件中读取数据 fputc()将一个字符写入文件 fgetc()从文件中读取一个字符 fclose()关闭文件fseek()将文件指针设置到给定位置 fputw()将整数写入文件 fgetw()从文件中读取一个整数 ftell()返回当前位置 rewind()将文件指针设置为文件的开头
C 库中有许多函数可以打开/读取/写入/搜索和关闭文件
打开模式参数 模式 Mode 描述 Description r以读取模式打开一个文本文件,允许读取文件 w以写模式打开一个文本文件,允许写入文件 a以追加模式打开一个文本文件 如果文件不存在,则会创建一个新文件 r+以读写模式打开一个文本文件,允许读写文件 w+以读写模式打开一个文本文件,允许读写文件 a+以读写模式打开一个文本文件,允许读写文件 rb以读取模式打开二进制文件 wb以写入模式打开二进制文件 ab以追加模式打开二进制文件 rb+以读写模式打开二进制文件 wb+以读写模式打开二进制文件 ab+以读写模式打开二进制文件
打开文件:fopen() {6} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> void main ( ) { FILE *fp; char ch; fp = fopen("file_handle.c" , "r" ); while (1 ) { ch = fgetc(fp); if (ch == EOF) break ; printf ("%c" , ch); } fclose(fp); }
对文件执行所有操作后,必须关闭 fclose() 该文件
写入文件:fprintf() {7} 1 2 3 4 5 6 7 8 9 #include <stdio.h> main() { FILE *fp; fp = fopen("file.txt" , "w" ); fprintf (fp, "fprintf 的 Hello 文件..\n" ); fclose(fp); }
读取文件:fscanf() {6} 1 2 3 4 5 6 7 8 9 10 #include <stdio.h> main(){ FILE *fp; char buff[255 ]; fp = fopen("file.txt" , "r" ); while (fscanf (fp, "%s" , buff)!=EOF) { printf ("%s " , buff); } fclose(fp); }
写入文件:fputc() {6} 1 2 3 4 5 6 7 8 #include <stdio.h> main(){ FILE *fp; fp = fopen("file1.txt" , "w" ); fputc('a' ,fp); fclose(fp); }
读取文件:fgetc() {8} 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #include <conio.h> void main () { FILE *fp; char c; clrscr(); fp=fopen("myfile.txt" , "r" ); while ((c=fgetc(fp))!=EOF){ printf ("%c" , c); } fclose(fp); getch(); }
写入文件:fputs() {8} 1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> #include <conio.h> void main () { FILE *fp; clrscr(); fp = fopen("myfile2.txt" ,"w" ); fputs ("hello c programming" ,fp); fclose(fp); getch(); }
读取文件:fgets() {10} 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #include <conio.h> void main () { FILE *fp; char text[300 ]; clrscr(); fp=fopen("myfile2.txt" , "r" ); printf ("%s" , fgets(text, 200 , fp)); fclose(fp); getch(); }
fseek() {8} 1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> void main () { FILE *fp; fp = fopen("myfile.txt" ,"w+" ); fputs ("This is Book" , fp); fseek(fp, 7 , SEEK_SET); fputs ("Kenny Wong" , fp); fclose(fp); }
将文件指针设置到给定位置
rewind() {11} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdio.h> #include <conio.h> void main () { FILE *fp; char c; clrscr(); fp=fopen("file.txt" , "r" ); while ((c=fgetc(fp)) != EOF){ printf ("%c" , c); } rewind(fp); while ((c=fgetc(fp)) != EOF){ printf ("%c" , c); } fclose(fp); getch(); }
ftell() {11} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> #include <conio.h> void main () { FILE *fp; int length; clrscr(); fp = fopen("file.txt" , "r" ); fseek(fp, 0 , SEEK_END); length = ftell(fp); fclose(fp); printf ("文件大小: %d bytes" , length); getch(); }
杂项 Docker 运行环境 另见 C 教程 (jaywcjlove.github.io)