for循环
for循环由分号隔离三个表达式:初始化条件;循环条件;自增自减构成,紧接着后面是循环体
for循环是利用一个变量的值进行运转的,初始化条件表达式给定了一个变量的初始值,循环条件给这个变量一个范围,自增自减表达式给了变量一个变化的尺度,只要变量在一个范围内自增自减循环就可以执行,一旦变量的值出了循环条件规定的范围那么循环就终止
for (int i = 0; i < 5; ++i) {
static int num = 1;
num++;
printf("%d", num);
}
以上for循环的结果是23456,至于为什么是这个结果是因为static关键字修饰局部变量影响了变量的生命周期(与整个程序的生命周期相同),却没有改变变量的作用域
while循环
while循环特别简单,由循环判断语句和循环体构成,循环体中有判断语句中变量的自增自减。循环判断条件为真循环才会执行,不然就会跳出循环
将上面的for循环改成while循环
int i = 0;
while (i < 5) {
static int num = 1;
++num;
printf("%d", num);
++i;
}
do…while()循环
do
循环体
while(循环判断条件表达式);
do…while循环存在的意义及适用的场景是,无论循环条件是否成立都要执行一次的情况
将上面的while循环改成do…while循环
#include <stdio.h>
int main() {
int i = 0;
do {
static int num = 1;
++num;
printf("%d", num);
++i;
} while (i < 5);
return 0;
}
goto语句
goto语句存在的意义是打破程序执行的顺序性
使用goto 语句将上面的do…while示例改成死循环
#include <stdio.h>
#include <windows.h>
int main() {
int i = 0;
hungry:
i = 0;
do {
static int num = 1;
++num;
printf("%d", num);
Sleep(500);
++i;
goto hungry;
} while (i < 5);
return 0;
}
注意goto语句不嫩出现在变量声明的前面,有时候会警告
操作符
算术操作符
-
-
- / % 1
-
移位操作符
>> 2
<< 3
上面分别是左移和右移操作符,移动的实际是bit位,左移一位将最高位的一位丢掉并且末尾补0
举个栗子:
整数1073741825二进制:01000000 00000000 00000000 00000001
左移一位就变成了:1000000 00000000 00000000 000000010得到的是补码–>反码:1000000 00000000 00000000 000000001–>原码:11111111 11111111 1111111 11111110
就是-2147483646了
使用以下代码验证结果
#include <stdio.h>
int main() {
int num = 1073741825;
printf("%d", num << 1);
return 0;
}
位操作符
& 4
^ 5
| 6
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
单目操作符
! 逻辑反操作
- 负值
- 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
– 前置、后置–
++ 前置、后置++
- 间接访问操作符(解引用操作符)
(类型) 强制类型转换
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
逻辑操作符
&& 逻辑与 同为真才为真
|| 逻辑或 一真则真
三目条件操作符
表达式1 ?表达式2 :表达式3
表达式1成立则执行表达式2,否则执行表达式3
举例子:写一个函数求两个数的较大值
int max(int a,int b){
return a>b?a:b;
}
a>b?a:b,a>b成立则’:‘前面的,否则’:'后面的
逗号表达式
int a = (1, 2, 3, 4);
int b = 98;
printf("%d\n", (a, b));
printf("%d\n", (b, a));
结果是98, 4
整个逗号表达式的真值是最后一个逗号之后的值
赋值操作符=优先级大于,因此int a = (1, 2, 3, 4);中逗号表达式需要用括号括起来
下标引用、函数调用和结构成员
[] 下标引用
int arr[] = {1, 2, 3, 4};
printf("%d\n", arr[2]);
printf("%d\n", *(arr+2));
下表访问操作符是用于按下标访问及修改数组元素的操作符,arr[2]和*(arr+2)是等价的,数组名实际是指针,指向了开辟的数组空间首元素地址,因此[]就是先对指针偏移然后解引用
() 函数调用
函数名+()就是函数调用
. 结构成员访问符
结构体实例.访问结构体成员
#include <stdio.h>
typedef struct person {
int age;
char name[10];
}person;
int main() {
struct person person1 = {17, "denny"};
person person2 = {18, "freen"};
printf("{%d, %s}\n", person1.age, person1.name);
printf("{%d, %s}\n", person2.age, person2.name);
return 0;
}
-> 解引用操作符
结构体指针可以使用->访问指针指向的结构体实例的数据成员
#include <stdio.h>
typedef struct person {
int age;
char name[10];
}person;
int main() {
struct person person1 = {17, "denny"};
person person2 = {18, "freen"};
person* ppr1 = &person1;
person* ppr2 = &person2;
printf("{%d, %s}\n", ppr1->age, ppr1->name);
printf("{%d, %s}\n", ppr2->age, ppr2->name);
return 0;
}
操作符优先级
操作符 | 描述 | 用法示例 | 结果类型 | 结合性 | 是否控制求值顺序 | 几目 |
---|---|---|---|---|---|---|
[ ] | 下标引用 | rexp[rexp] | lexp | L-R | 否 | |
() | 聚组 | (表达式) | 与表达式同 | N/A | 否 | |
() | 函数调用 | rexp(rexp,…,rexp) | rexp | L-R | 否 | |
. | 访问结构成员 | lexp.member_name | lexp | L-R | 否 | |
-> | 访问结构指针成员 | rexp->member_name | lexp | L-R | 否 | |
++ | 后缀自增 | lexp++ | rexp | L-R | 否 | 单 |
– | 后缀自减 | lexp– | rexp | L-R | 否 | 单 |
! | 逻辑反 | !rexp | rexp | R-L | 否 | 单 |
~ | 按位取反 | ~rexp | rexp | R-L | 否 | 单 |
+ | 表示正值 | +rexp | rexp | R-L | 否 | 单 |
- | 表示负值 | -rexp | rexp | R-L | 否 | 单 |
++ | 前缀自增 | ++lexp | rexp | R-L | 否 | 单 |
– | 前缀自减 | –lexp | rexp | R-L | 否 | 单 |
* | 间接访问 | *rexp | lexp | R-L | 否 | 单 |
& | 取地址 | &lexp | rexp | R-L | 否 | 单 |
sizeof | 取其长度,以字节表示 | sizeof(类型) | rexp | R-L | 否 | |
(类型) | 类型转换 | (类型) rexp | rexp | R-L | 否 | |
* | 乘法 | rexp * rexp | rexp | L-R | 否 | 双 |
/ | 除法 | rexp / rexp | rexp | L-R | 否 | 双 |
% | 整数取余 | rexp % rexp | rexp | L-R | 否 | 双 |
+ | 加法 | rexp + rexp | rexp | L-R | 否 | 双 |
- | 减法 | rexp - rexp | rexp | L-R | 否 | 双 |
<< | 左移位 | rexp << rexp | rexp | L-R | 否 | 双 |
>> | 右移位 | rexp >> rexp | rexp | L-R | 否 | 双 |
> | 大于 | rexp > rexp | rexp | L-R | 否 | 双 |
>= | 大于等于 | rexp >= rexp | rexp | L-R | 否 | 双 |
< | 小于 | rexp < rexp | rexp | L-R | 否 | 双 |
<= | 小于等于 | rexp <= rexp | rexp | L-R | 否 | 双 |
== | 等于 | rexp == rexp | rexp | L-R | 否 | 双 |
!= | 不等于 | rexp != rexp | rexp | L-R | 否 | 双 |
& | 位与 | rexp & rexp | rexp | L-R | 否 | 双 |
^ | 位异或 | rexp ^ rexp | rexp | L-R | 否 | 双 |
| | 位或 | rexp | rexp | rexp | L-R | 否 | 双 |
&& | 逻辑与 | rexp && rexp | rexp | L-R | 是 | 双 |
|| | 逻辑或 | rexp || rexp | rexp | L-R | 是 | 双 |
? : | 条件操作符 | rexp ? rexp : rexp | rexp | N/A | 是 | 三 |
= | 赋值 | lexp = rexp | rexp | R-L | 否 | |
+= | 以…加 | lexp += rexp | rexp | R-L | 否 | |
-= | 以…减 | lexp -= rexp | rexp | R-L | 否 | |
*= | 以…乘 | lexp *= rexp | rexp | R-L | 否 | |
/= | 以…除 | lexp /= rexp | rexp | R-L | 否 | |
%= | 以…取模 | lexp %= rexp | rexp | R-L | 否 | |
<<= | 以…左移 | lexp <<= rexp | rexp | R-L | 否 | |
>>= | 以…右移 | lexp >>= rexp | rexp | R-L | 否 | |
&= | 以…与 | lexp &= rexp | rexp | R-L | 否 | |
^= | 以…异或 | lexp ^= rexp | rexp | R-L | 否 | |
|= | 以…或 | lexp |= rexp | rexp | R-L | 否 | |
, | 逗号 | rexp,rexp | rexp | L-R | 是 |
由上往下操作符优先级逐渐降低,优先级快速记忆请参考:操作符优先级分级快速记忆