C 具有良好的可移植性,可以在很多操作系统下使用,在 C 程序的编写过程中,源代码一般以文本文件存储在以 .c 为文件拓展名的文件中。
C 的基本机制是 源代码文件 编译为可执行文件(包括可直接运行的机器语言代码)的过程,典型步骤是 编译、链接、运行,其中编译器把源代码转换成中间代码,链接器把中间代码和其他代码合并,生成可执行文件,这种策略使得 C 可以方便地对程序进行 模块化 设计。
模块化 的好处是:对于一个项目,可以先独立编译单独的模块,然后再用 链接器 合并已编译的模块,如果需要更改某个模块,不必因此重新编译其他模块。此外 链接器 还将您编写的程序和预编译的库代码进行合并。

C 最开始为 Unix 系统开发而生,下面是 C 在 Unix 下的编译过程

GNU 编译器集合也就是 GCC,其中包含 C 的编译器 GCC C,在 UNIX、Linux、Windows 等操作系统下都可以使用,它跟随 C 标准的改动,对新标准的支持比较好。一般地,使用 gcc 命令调用 GCC C 编译器,一些使用 gcc 的系统又使用 cc 作为 gcc 的别名。
LLVM 项目是 cc 的另一个替代品,它使用 Clang 编译器处理 C,Clang 对最新的 C 标准的支持也很好。
对于 gcc 和 clang:
gcc-v # 查看使用的编译器及其版本
gcc [options][filenames] # GCC 最基本的用法:(options 是所需参数、filenames 是文件名)
gcc -std=c99 inform.c # gcc/clang 选择调用不同 C 标调,比如调用 C99 标准
gcc -std=clx inform.c # 调用 C11 之前草案标准
gcc -std=c11 inform.c # 调用 C11 标准
令牌 是程序的最小元素,令牌的类型有:关键字、标识符、常量、字符串 和 运算符 等
关键字是 C 中预定义的保留字,每个保留字均有特定功能或与特定功能与之关联,它们对编译器有特殊意义
C 中共有 32 个关键字
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| auto | double | int | struct |
| break | else | long | switch |
| case | enum | register | typedef |
| char | extern | return | union |
| continue | for | signed | void |
| do | if | static | while |
| default | goto | sizeof | volatile |
| const | float | short | unsigned |
printf() 函数是刚开始使用比较多的一个函数,它负责打印输出信息到屏幕。printf 由单词 print 和 format 组成
#include <stdio.h>
int main()
{
printf("%i \n", 6);
return 0;
}
# 输出结果是 6
printf() 可以在输出文本中指定 占位符,上面的 %i 就是一个 占位符;占位符在一个半角逗号后面的就是实际替换占位符的值,比如上面用 6 替换 %i,根据替换值的类型,需要用不同的占位符:
%a:浮点数%A:浮点数%c:字符%d:十进制整数%e:使用科学计数法的浮点数,指数部分的 e 为小写%E:使用科学计数法的浮点数,指数部分的 E 为大写%i:整数,基本等同于 %d%f:小数(包含 float 类型和 double 类型)%g:6 个有效数字的浮点数。整数部分一旦超过 6 位,就会自动转为科学计数法,指数部分的 e 为小写%G:等同于 %g,唯一的区别是指数部分的 E 为大写%hd:十进制 short int 类型%ho:八进制 short int 类型%hx:十六进制 short int 类型%hu:unsigned short int 类型%ld:十进制 long int 类型%lo:八进制 long int 类型%lx:十六进制 long int 类型%lu:unsigned long int 类型%lld:十进制 long long int 类型%llo:八进制 long long int 类型%llx:十六进制 long long int 类型%llu:unsigned long long int 类型%Le:科学计数法表示的 long double 类型浮点数%Lf:long double 类型浮点数%n:已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中%o:八进制整数%p:指针%s:字符串%u:无符号整数 unsigned int%x:十六进制整数%zd:size_t 类型%%:输出一个 %C 中 标识符 用于命名 变量、函数、数组 等,可以由用户定义这些标识符,由 字母、数字 和 下划线 组成
标识符命名规则
常量是固定值,就像是常规的变量,在定义后不能进行修改并且在程序执行期间不会改变。这些固定的值,又叫做 字面量
常量可以是任何 基本数据类型,比如:
下面是常量的数据类型的一些实例
整数常量 可以是八进制、十进制、十六进制的常量
指定基数:前缀0x/0X 表示十六进制,前缀 0 表示八进制,十进制一般不带前缀
后缀是 U 和 L 的组合:U 是无符号整数(unsigned),L 是长整数(long)U 和 L 可以是大写/小写的任意顺序,比如:
85 /* 十进制 */
0213 /* 八进制 */
0x4b /* 十六进制 */
30 /* 整数 */
30u /* 无符号整数 */
30l /* 长整数 */
30ul /* 无符号长整数 */
212 /* 合法的 */
215u /* 合法的 */
0xFeeL /* 合法的 */
078 /* 非法的:8 不是八进制的数字 */
032UU /* 非法的:不能重复后缀 */
浮点常量 由整数部分、小数点、小数部分和指数部分组成,使用小数或者指数形式来表示
e 或者 E 引入,比如:3.14159 /* 合法的 */
314159E-5L /* 合法的 */
510E /* 非法的:不完整的指数 */
210f /* 非法的:没有小数或指数 */
.e55 /* 非法的:缺少整数或分数 */
字符常量 使用 '' 包起来,比如: s 可存储在 char 类型的简单变量中,字符常量可以是一个普通字符( 如 s )、一个转义序列( 如 \n )或者一个通用字符( 如 \u02C0 )
在 C 中,一些特定的字符前面有反斜杠 \\ 时,它们就会变成有特殊含义的 转义序列 (Escape Sequence),转义序列用于代表难以表示或无法输入的字符,像 t 代表 Tab 键,\b 代表 Backspace 键
| 转义序列 | 含义 |
|---|---|
| \ | \ 字符 |
| \' | ' 字符 |
| \" | " 字符 |
| ? | ? 字符 |
| \a | 警报铃声 |
| \b | 退格键 |
| \f | 换页符 |
| \n | 换行符 |
| \r | 回车 |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \ooo | 一到三位的八进制数 |
| \xhh . . . | 一个或多个数字的十六进制数 |
字符串字面值或常量是括在双引号 "" 中的,一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符
可以使用空格做分隔符,把一个很长的字符串常量进行分行,并不影响编译程序识别
# 第一种
"hello,world"
# 第二种
"hello,\
dear"
# 第三种
"hello, " "w" "orld"
在 C 中,有两种简单的定义常量的方式( #define 和 const 关键字),定义常量时经常以 大写英文字母 形式
下面是两个实例:
#include <stdio.h>
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
int main()
{
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
#include <stdio.h>
int main()
{
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
两个例子的结果一样
value of area : 50
字符串是以 null 空字符 \\0 结尾的一维字符数组,此空字符表示字符串已结束,字符串始终用双引号 "" 引起来,C 编译器会在初始化数组时,自动把 \0 放在字符串的末尾,比如:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
也可以写成下面的:(数组初始化规则)
char greeting[] = "Hello";
上面的字符串在内存中可以如下图所示:

C 中操作字符串的函数:
| 函数 | 目的 |
|---|---|
strcpy(s1, s2); | 复制字符串 s2 到字符串 s1 |
strcat(s1, s2); | 连接字符串 s2 到字符串 s1 的末尾 |
strlen(s1); | 返回字符串 s1 的长度 |
strcmp(s1, s2); | s1 和 s2 相同,返回 0;s1<s2 返回小于 0;s1>s2 返回大于 0 |
strchr(s1, ch); | 返回一个指针,指向字符串 s1 中字符 ch 第一次出现的位置 |
strstr(s1, s2); | 返回一个指针,指向字符串 s1 中字符串 s2 第一次出现的位置 |
比如:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[12] = "Hello";
char str2[12] = "World";
char str3[12];
int len ;
/* 复制 str1 到 str3 */
strcpy(str3, str1);
printf("strcpy( str3, str1):%s\n", str3 );
/* 连接 str1 和 str2 */
strcat( str1, str2);
printf("strcat( str1, str2):%s\n", str1 );
/* 连接后,str1 的总长度 */
len = strlen(str1);
printf("strlen(str1):%d\n", len );
return 0;
}
则会有
strcpy( str3, str1 ):Hello
strcat( str1, str2 ):HelloWorld
strlen( str1 ):10
运算符 是一种告诉编译器执行特定数学或逻辑操作的符号,C 中提供了以下类型的运算符:
给定变量 A 和 B,在 C 中常用的算数运算符罗列如下:
| 运算符 | 描述 | 结果 |
|---|---|---|
+ | 两操作数相加 | A+B |
- | 前一个操作数减去后一个操作数 | A-B |
* | 两操作数相乘 | A*B |
/ | 两操作数相除(分子/分母) | A/B |
% | 取模,整除后的余数 | A/B 后的余数 |
++ | 自增运算符,整数值 +1 | A+1 或 B+1 |
-- | 自减运算符,整数值 -1 | A-1 或 B-1 |
特别地,对于 a++和++a,相同点都是给 a 的值+1,不同点是 a++ 是先赋值再+1,而 ++a 则是先 +1 再赋值
#include <stdio.h>
int main()
{
int c;
int a = 10;
c = a++;
printf( "先赋值后运算:\n" );
printf( "Line 1 - c 的值是 %d\n", c );
printf( "Line 2 - a 的值是 %d\n", a );
a = 10;
c = a--;
printf( "Line 3 - c 的值是 %d\n", c );
printf( "Line 4 - a 的值是 %d\n", a );
printf( "先运算后赋值:\n" );
a = 10;
c = ++a;
printf( "Line 5 - c 的值是 %d\n", c );
printf( "Line 6 - a 的值是 %d\n", a );
a = 10;
c = --a;
printf( "Line 7 - c 的值是 %d\n", c );
printf( "Line 8 - a 的值是 %d\n", a );
}
则会有:
先赋值后运算:
Line 1 - c 的值是 10
Line 2 - a 的值是 11
Line 3 - c 的值是 10
Line 4 - a 的值是 9
先运算后赋值:
Line 5 - c 的值是 11
Line 6 - a 的值是 11
Line 7 - c 的值是 9
Line 8 - a 的值是 9
给定变量 A 和 B,在 C 中常见的关系运算符有:
| 运算符 | 描述 | 实例 |
|---|---|---|
== | 检查两个操作数是否相等,相等则条件为真 | A==B |
!= | 检查两个操作数是否相等,不相等则条件为真 | A!=B |
> | 检查左操作数是否大于右操作数,是则条件为真 | A>B |
< | 检查左操作数是否小于右操作数,是则条件为真 | A<B |
>= | 检查左操作数是否大于或等于右操作数,是则条件为真 | A>=B |
<= | 检查左操作数是否小于或等于右操作数,是则条件为真 | A<=B |
比如:
#include <stdio.h>
int main(){
int a = 21;
int b = 10;
int c;
if( a == b ){
printf("Line 1 - a 等于 b\n");
}else{
printf("Line 1 - a 不等于 b\n");
}
if( a < b){
printf("Line 2 - a 小于 b\n");
}else{
printf("Line 2 - a 不小于 b\n");
}
if( a > b ){
printf("Line 3 - a 小大于 b\n");
}else{
printf("Line 3 - a 小大于 b\n");
}
// 改变 a 和 b 的值
a = 5;
b = 20;
if( a <= b){
printf("Line 4 - a 小于等于 b\n");
}
if( b >= a){
printf("Line 5 - b 大于或等于 b\n")
}
}
输出结果
Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 b
给定变量A和B,在 C 中常见的逻辑运算符有:
| 运算符 | 描述 | 实例 |
|---|---|---|
&& | 逻辑与运算符 | A&&B |
|| | 逻辑或运算符 | A||B |
! | 逻辑非运算符 | !(A&&B) |
所谓 位运算,就是对一个比特(Bit)位进行操作。比特(Bit)是一个电子元器件,8 个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了,C 中提供了 6 种位运算符:
| 运算符 | 说明 |
|---|---|
& | 按位与运算 |
| | 按位或运算 |
^ | 按位异或运算 |
~ | 取反运算 |
<< | 左移运算 |
>> | 右移运算 |
给定变量 A、B 和 C,在 C 语言中支持的赋值运算符:
| 运算符 | 描述 | 例子 |
|---|---|---|
= | 简单赋值运算符 | C=A+B 即把 A+B 的值赋给 C |
+= | 加且赋值运算符 | C+=A 即 C=C+A |
-= | 减且赋值运算符 | C-=A 即 C=C-A |
*= | 乘且赋值运算符 | C*=A 即 C=C*A |
/= | 除且赋值运算符 | C/=A 即 C=C/A |
%= | 求模且赋值运算符 | C%=A 即 C=C%A |
<<= | 左移且赋值运算符 | C<<=2 即 C=C<<2 |
>>= | 右移且赋值运算符 | C>>=2 即 C=C>>2 |
&= | 按位与且赋值运算符 | C&=2 即 C=C&2 |
^= | 按位异或且赋值运算符 | C^=2 即 C=C^2 |
|= | 按位或且赋值运算符 | C|=2 即 C=C|2 |
| 运算符 | 描述 | 例子 |
|---|---|---|
sizeof() | 返回变量的大小 | sizeof(a) 返回 4,其中 a 是整数 |
& | 返回变量的地址 | &a; 返回变量 a 在内存中的实际地址 |
* | 指向一个变量 | *a; 指向一个变量(指针) |
?: | 条件表达式 | 如果条件为真 ? 则值为 X : 否则值为 Y |
| 类别 | 运算符 | 结合性 |
|---|---|---|
| 后缀 | () [] -> . ++ - - | 从左到右 |
| 一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
| 乘除 | * / % | 从左到右 |
| 加减 | + - | 从左到右 |
| 移位 | << >> | 从左到右 |
| 关系 | < <= > >= | 从左到右 |
| 相等 | == != | 从左到右 |
| 位与 AND | & | 从左到右 |
| 位异或 XOR | ^ | 从左到右 |
| 位或 OR | | | 从左到右 |
| 逻辑与 AND | && | 从左到右 |
| 逻辑或 OR | || | 从左到右 |
| 条件 | ?: | 从右到左 |
| 赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
| 逗号 | , | 从左到右 |
C 具有良好的可移植性,可以在很多操作系统下使用,在 C 程序的编写过程中,源代码一般以文本文件存储在以 .c 为文件拓展名的文件中。
C 的基本机制是 源代码文件 编译为可执行文件(包括可直接运行的机器语言代码)的过程,典型步骤是 编译、链接、运行,其中编译器把源代码转换成中间代码,链接器把中间代码和其他代码合并,生成可执行文件,这种策略使得 C 可以方便地对程序进行 模块化 设计。
模块化 的好处是:对于一个项目,可以先独立编译单独的模块,然后再用 链接器 合并已编译的模块,如果需要更改某个模块,不必因此重新编译其他模块。此外 链接器 还将您编写的程序和预编译的库代码进行合并。

C 最开始为 Unix 系统开发而生,下面是 C 在 Unix 下的编译过程

GNU 编译器集合也就是 GCC,其中包含 C 的编译器 GCC C,在 UNIX、Linux、Windows 等操作系统下都可以使用,它跟随 C 标准的改动,对新标准的支持比较好。一般地,使用 gcc 命令调用 GCC C 编译器,一些使用 gcc 的系统又使用 cc 作为 gcc 的别名。
LLVM 项目是 cc 的另一个替代品,它使用 Clang 编译器处理 C,Clang 对最新的 C 标准的支持也很好。
对于 gcc 和 clang:
gcc-v # 查看使用的编译器及其版本
gcc [options][filenames] # GCC 最基本的用法:(options 是所需参数、filenames 是文件名)
gcc -std=c99 inform.c # gcc/clang 选择调用不同 C 标调,比如调用 C99 标准
gcc -std=clx inform.c # 调用 C11 之前草案标准
gcc -std=c11 inform.c # 调用 C11 标准
令牌 是程序的最小元素,令牌的类型有:关键字、标识符、常量、字符串 和 运算符 等
关键字是 C 中预定义的保留字,每个保留字均有特定功能或与特定功能与之关联,它们对编译器有特殊意义
C 中共有 32 个关键字
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| auto | double | int | struct |
| break | else | long | switch |
| case | enum | register | typedef |
| char | extern | return | union |
| continue | for | signed | void |
| do | if | static | while |
| default | goto | sizeof | volatile |
| const | float | short | unsigned |
printf() 函数是刚开始使用比较多的一个函数,它负责打印输出信息到屏幕。printf 由单词 print 和 format 组成
#include <stdio.h>
int main()
{
printf("%i \n", 6);
return 0;
}
# 输出结果是 6
printf() 可以在输出文本中指定 占位符,上面的 %i 就是一个 占位符;占位符在一个半角逗号后面的就是实际替换占位符的值,比如上面用 6 替换 %i,根据替换值的类型,需要用不同的占位符:
%a:浮点数%A:浮点数%c:字符%d:十进制整数%e:使用科学计数法的浮点数,指数部分的 e 为小写%E:使用科学计数法的浮点数,指数部分的 E 为大写%i:整数,基本等同于 %d%f:小数(包含 float 类型和 double 类型)%g:6 个有效数字的浮点数。整数部分一旦超过 6 位,就会自动转为科学计数法,指数部分的 e 为小写%G:等同于 %g,唯一的区别是指数部分的 E 为大写%hd:十进制 short int 类型%ho:八进制 short int 类型%hx:十六进制 short int 类型%hu:unsigned short int 类型%ld:十进制 long int 类型%lo:八进制 long int 类型%lx:十六进制 long int 类型%lu:unsigned long int 类型%lld:十进制 long long int 类型%llo:八进制 long long int 类型%llx:十六进制 long long int 类型%llu:unsigned long long int 类型%Le:科学计数法表示的 long double 类型浮点数%Lf:long double 类型浮点数%n:已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中%o:八进制整数%p:指针%s:字符串%u:无符号整数 unsigned int%x:十六进制整数%zd:size_t 类型%%:输出一个 %C 中 标识符 用于命名 变量、函数、数组 等,可以由用户定义这些标识符,由 字母、数字 和 下划线 组成
标识符命名规则
常量是固定值,就像是常规的变量,在定义后不能进行修改并且在程序执行期间不会改变。这些固定的值,又叫做 字面量
常量可以是任何 基本数据类型,比如:
下面是常量的数据类型的一些实例
整数常量 可以是八进制、十进制、十六进制的常量
指定基数:前缀0x/0X 表示十六进制,前缀 0 表示八进制,十进制一般不带前缀
后缀是 U 和 L 的组合:U 是无符号整数(unsigned),L 是长整数(long)U 和 L 可以是大写/小写的任意顺序,比如:
85 /* 十进制 */
0213 /* 八进制 */
0x4b /* 十六进制 */
30 /* 整数 */
30u /* 无符号整数 */
30l /* 长整数 */
30ul /* 无符号长整数 */
212 /* 合法的 */
215u /* 合法的 */
0xFeeL /* 合法的 */
078 /* 非法的:8 不是八进制的数字 */
032UU /* 非法的:不能重复后缀 */
浮点常量 由整数部分、小数点、小数部分和指数部分组成,使用小数或者指数形式来表示
e 或者 E 引入,比如:3.14159 /* 合法的 */
314159E-5L /* 合法的 */
510E /* 非法的:不完整的指数 */
210f /* 非法的:没有小数或指数 */
.e55 /* 非法的:缺少整数或分数 */
字符常量 使用 '' 包起来,比如: s 可存储在 char 类型的简单变量中,字符常量可以是一个普通字符( 如 s )、一个转义序列( 如 \n )或者一个通用字符( 如 \u02C0 )
在 C 中,一些特定的字符前面有反斜杠 \\ 时,它们就会变成有特殊含义的 转义序列 (Escape Sequence),转义序列用于代表难以表示或无法输入的字符,像 t 代表 Tab 键,\b 代表 Backspace 键
| 转义序列 | 含义 |
|---|---|
| \ | \ 字符 |
| \' | ' 字符 |
| \" | " 字符 |
| ? | ? 字符 |
| \a | 警报铃声 |
| \b | 退格键 |
| \f | 换页符 |
| \n | 换行符 |
| \r | 回车 |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \ooo | 一到三位的八进制数 |
| \xhh . . . | 一个或多个数字的十六进制数 |
字符串字面值或常量是括在双引号 "" 中的,一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符
可以使用空格做分隔符,把一个很长的字符串常量进行分行,并不影响编译程序识别
# 第一种
"hello,world"
# 第二种
"hello,\
dear"
# 第三种
"hello, " "w" "orld"
在 C 中,有两种简单的定义常量的方式( #define 和 const 关键字),定义常量时经常以 大写英文字母 形式
下面是两个实例:
#include <stdio.h>
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
int main()
{
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
#include <stdio.h>
int main()
{
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
两个例子的结果一样
value of area : 50
字符串是以 null 空字符 \\0 结尾的一维字符数组,此空字符表示字符串已结束,字符串始终用双引号 "" 引起来,C 编译器会在初始化数组时,自动把 \0 放在字符串的末尾,比如:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
也可以写成下面的:(数组初始化规则)
char greeting[] = "Hello";
上面的字符串在内存中可以如下图所示:

C 中操作字符串的函数:
| 函数 | 目的 |
|---|---|
strcpy(s1, s2); | 复制字符串 s2 到字符串 s1 |
strcat(s1, s2); | 连接字符串 s2 到字符串 s1 的末尾 |
strlen(s1); | 返回字符串 s1 的长度 |
strcmp(s1, s2); | s1 和 s2 相同,返回 0;s1<s2 返回小于 0;s1>s2 返回大于 0 |
strchr(s1, ch); | 返回一个指针,指向字符串 s1 中字符 ch 第一次出现的位置 |
strstr(s1, s2); | 返回一个指针,指向字符串 s1 中字符串 s2 第一次出现的位置 |
比如:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[12] = "Hello";
char str2[12] = "World";
char str3[12];
int len ;
/* 复制 str1 到 str3 */
strcpy(str3, str1);
printf("strcpy( str3, str1):%s\n", str3 );
/* 连接 str1 和 str2 */
strcat( str1, str2);
printf("strcat( str1, str2):%s\n", str1 );
/* 连接后,str1 的总长度 */
len = strlen(str1);
printf("strlen(str1):%d\n", len );
return 0;
}
则会有
strcpy( str3, str1 ):Hello
strcat( str1, str2 ):HelloWorld
strlen( str1 ):10
运算符 是一种告诉编译器执行特定数学或逻辑操作的符号,C 中提供了以下类型的运算符:
给定变量 A 和 B,在 C 中常用的算数运算符罗列如下:
| 运算符 | 描述 | 结果 |
|---|---|---|
+ | 两操作数相加 | A+B |
- | 前一个操作数减去后一个操作数 | A-B |
* | 两操作数相乘 | A*B |
/ | 两操作数相除(分子/分母) | A/B |
% | 取模,整除后的余数 | A/B 后的余数 |
++ | 自增运算符,整数值 +1 | A+1 或 B+1 |
-- | 自减运算符,整数值 -1 | A-1 或 B-1 |
特别地,对于 a++和++a,相同点都是给 a 的值+1,不同点是 a++ 是先赋值再+1,而 ++a 则是先 +1 再赋值
#include <stdio.h>
int main()
{
int c;
int a = 10;
c = a++;
printf( "先赋值后运算:\n" );
printf( "Line 1 - c 的值是 %d\n", c );
printf( "Line 2 - a 的值是 %d\n", a );
a = 10;
c = a--;
printf( "Line 3 - c 的值是 %d\n", c );
printf( "Line 4 - a 的值是 %d\n", a );
printf( "先运算后赋值:\n" );
a = 10;
c = ++a;
printf( "Line 5 - c 的值是 %d\n", c );
printf( "Line 6 - a 的值是 %d\n", a );
a = 10;
c = --a;
printf( "Line 7 - c 的值是 %d\n", c );
printf( "Line 8 - a 的值是 %d\n", a );
}
则会有:
先赋值后运算:
Line 1 - c 的值是 10
Line 2 - a 的值是 11
Line 3 - c 的值是 10
Line 4 - a 的值是 9
先运算后赋值:
Line 5 - c 的值是 11
Line 6 - a 的值是 11
Line 7 - c 的值是 9
Line 8 - a 的值是 9
给定变量 A 和 B,在 C 中常见的关系运算符有:
| 运算符 | 描述 | 实例 |
|---|---|---|
== | 检查两个操作数是否相等,相等则条件为真 | A==B |
!= | 检查两个操作数是否相等,不相等则条件为真 | A!=B |
> | 检查左操作数是否大于右操作数,是则条件为真 | A>B |
< | 检查左操作数是否小于右操作数,是则条件为真 | A<B |
>= | 检查左操作数是否大于或等于右操作数,是则条件为真 | A>=B |
<= | 检查左操作数是否小于或等于右操作数,是则条件为真 | A<=B |
比如:
#include <stdio.h>
int main(){
int a = 21;
int b = 10;
int c;
if( a == b ){
printf("Line 1 - a 等于 b\n");
}else{
printf("Line 1 - a 不等于 b\n");
}
if( a < b){
printf("Line 2 - a 小于 b\n");
}else{
printf("Line 2 - a 不小于 b\n");
}
if( a > b ){
printf("Line 3 - a 小大于 b\n");
}else{
printf("Line 3 - a 小大于 b\n");
}
// 改变 a 和 b 的值
a = 5;
b = 20;
if( a <= b){
printf("Line 4 - a 小于等于 b\n");
}
if( b >= a){
printf("Line 5 - b 大于或等于 b\n")
}
}
输出结果
Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 b
给定变量A和B,在 C 中常见的逻辑运算符有:
| 运算符 | 描述 | 实例 |
|---|---|---|
&& | 逻辑与运算符 | A&&B |
|| | 逻辑或运算符 | A||B |
! | 逻辑非运算符 | !(A&&B) |
所谓 位运算,就是对一个比特(Bit)位进行操作。比特(Bit)是一个电子元器件,8 个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了,C 中提供了 6 种位运算符:
| 运算符 | 说明 |
|---|---|
& | 按位与运算 |
| | 按位或运算 |
^ | 按位异或运算 |
~ | 取反运算 |
<< | 左移运算 |
>> | 右移运算 |
给定变量 A、B 和 C,在 C 语言中支持的赋值运算符:
| 运算符 | 描述 | 例子 |
|---|---|---|
= | 简单赋值运算符 | C=A+B 即把 A+B 的值赋给 C |
+= | 加且赋值运算符 | C+=A 即 C=C+A |
-= | 减且赋值运算符 | C-=A 即 C=C-A |
*= | 乘且赋值运算符 | C*=A 即 C=C*A |
/= | 除且赋值运算符 | C/=A 即 C=C/A |
%= | 求模且赋值运算符 | C%=A 即 C=C%A |
<<= | 左移且赋值运算符 | C<<=2 即 C=C<<2 |
>>= | 右移且赋值运算符 | C>>=2 即 C=C>>2 |
&= | 按位与且赋值运算符 | C&=2 即 C=C&2 |
^= | 按位异或且赋值运算符 | C^=2 即 C=C^2 |
|= | 按位或且赋值运算符 | C|=2 即 C=C|2 |
| 运算符 | 描述 | 例子 |
|---|---|---|
sizeof() | 返回变量的大小 | sizeof(a) 返回 4,其中 a 是整数 |
& | 返回变量的地址 | &a; 返回变量 a 在内存中的实际地址 |
* | 指向一个变量 | *a; 指向一个变量(指针) |
?: | 条件表达式 | 如果条件为真 ? 则值为 X : 否则值为 Y |
| 类别 | 运算符 | 结合性 |
|---|---|---|
| 后缀 | () [] -> . ++ - - | 从左到右 |
| 一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
| 乘除 | * / % | 从左到右 |
| 加减 | + - | 从左到右 |
| 移位 | << >> | 从左到右 |
| 关系 | < <= > >= | 从左到右 |
| 相等 | == != | 从左到右 |
| 位与 AND | & | 从左到右 |
| 位异或 XOR | ^ | 从左到右 |
| 位或 OR | | | 从左到右 |
| 逻辑与 AND | && | 从左到右 |
| 逻辑或 OR | || | 从左到右 |
| 条件 | ?: | 从右到左 |
| 赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
| 逗号 | , | 从左到右 |