知识点1【数据类型转换】
1、自动类型转换
案例:有符号 和无符号的转换
void test02()
{
int data1 = -20;
unsigned int data2 = 10;
//有符号data1和无符号data2参加计算的时候
//会先将data1转换成无符号(-20的补码很大的正数)
//很大的数 + 10 必然 >0
if(data1+data2 > 0)
{
printf(">0\n");
}
else if(data1+data2<0)
{
printf("<0\n");
}
}
运行结果:>0
案例:int double的转换
void test03()
{
int data1 = 10;
printf("%d\n",sizeof(data1+3.14));//8字节
}
int main(int argc,char *argv[])
{
test03();
return 0;
}
案例:char 和short的类型转换
void test04()
{
char ch = 'a';
short data = 20;
//由于char short自身字节数 过小 很容易溢出
//所以 只要char short参加运算 都会将自身转换成int
printf("%d\n", sizeof(ch + ch));//4
printf("%d\n", sizeof(ch + data));//4
printf("%d\n", sizeof(data + data));//4
}
案例:强制类型转换
void test05()
{
float x = 3.14f;
int j = 0;
//强制 类型转换 只是临时的转换 当前语句有效 在后面的语句中不会更改x的值
j = (int)x;
printf("j = %d,x = %f\n", j, x);//
}
int main(int argc,char *argv[])
{
test05();
return 0;
运行结果:
知识点2【运算符】
1、算术运算符
a /b (a,b可以为整数,也可以为浮点数 如果a b为整数 表示取整 如果 a b只要有一个为浮点数 则表示除法运算) 取整 %取余 必须为整数
void test06()
{
printf("%d\n", 5/2);//取整 2
printf("%d\n", 5%2);//余数 1
}
int main(int argc,char *argv[])
{
test06();
return 0;
}
运行结果:
案例:键盘输入一个数 是否能被3整除
void test07()
{
int num = 0;
//键盘输入一个int数
printf("请输入一个整形数据:");
scanf("%d", &num);
//判断是否能被3整数
if(num%3 == 0)
{
printf("ok\n");
}
else
{
printf("no\n");
}
}
int main(int argc,char *argv[])
{
test07();
return 0;
}
运行结果:
晚上的练习:键盘输入一个4位数 请取出每位上的数值
void test08()
{
printf("%d\n", 5/2);//取整
printf("%f\n",5/2.0f);//除
}
运行结果:
2、逻辑运算符
!逻辑非 !0 == 真 !真 == 假0
void test09()
{
printf("%d\n", !1);//0
printf("%d\n", !0);//1
//C语言 0为假 其他都为真 -1
printf("%d\n", !-1);//0
}
int main(int argc,char *argv[])
{
test09();
return 0;
}
运行结果:
逻辑 && (重要)
A && B A B同时为真 整个表达式结果为真。 A B只要有一个为假 整个表达式为假
void test10()
{
if( (2>3) && (5>4) )
{
printf("ok\n");
}
else
{
printf("no\n");
}
}
int main(int argc,char *argv[])
{
test10();
return 0;
}
运行结果:no
逻辑&& 短路特性
A && B 如果A为假 系统不会执行B 这就是&&的短路特性
void test11()
{
int num=10;
printf("比较之前num = %d\n",num);
(2>3) && (num=100);
printf("比较之后num = %d\n",num);
}
int main(int argc,char *argv[])
{
test11();
return 0;
}
运行结果:逻辑||
A || B 只要A B任意一个为真 整个表达式结果为真,A B同时为假的时候 结果才为假。
逻辑|| 也有短路特性:只要A为真 编译器不会判断B的真假。
void test12()
{
int num=10;
printf("比较之前num = %d\n",num);//10
(3>2) || (num=100);//num=100得不到执行
printf("比较之后num = %d\n",num);//10
}
int main(int argc,char *argv[])
{
test12();
return 0;
}
运行结果:
综合案例:
知识点3【位运算符】二进制位操作(重要)
&:按位与
语法:全1为1 其他为0
1010 1010
& 1111 0000
1010 0000
特点:和1相与 保持不变 和0相与 清零
应用场景:将固定为清零。
|:按位或
语法:有1就为1 全0才为0
1010 1010
1111 0000 |
---|
1111 1010
特点:和0相或 保持不变 和1相或 置1.
应用场景:将固定为置1.
案例:将1010 1010的第2、3为置1 其他为保持不变
1010 1010
0000 1100 |
---|
1010 1110
~:按位取反
语法:0变1 1变0
~1010 1010 == 0101 0101
应用场景:配合 & | 操作
^:按位异或
语法:相同为0 不同为1
1010 1010
^ 0000 1111
1010 0101
特点:和0异或 保持不变 和1异或 取反。
应用场景:将固定的为 发生高低电频 翻转。
案例:将1010 1010 的第0位 发生翻转.
1010 1010
^ 0000 0001
1010 1011
^ 0000 0001
1010 1010
<< 左移运算符: 左边丢弃 右边补0
注意:移动的位数 不要 超过自身长度
1010 1100 << 2
>> 右移运算符:
右移分类:逻辑右移 算术右移
逻辑右移:右边丢弃 左边补0.
算术右移:
无符号数:右边丢弃 左边补0。
有符号数:
正数:右边丢弃 左边补0。
负数:右边丢弃 左边补1。
右移基本上是右边丢弃 左边补0 只有负数且算术右移 左边才会补1.
逻辑右移和算术右移 是编译器决定,但是我们可以检测。
作业:自己写代码 判断你的编译器 是逻辑右移还是算术右移。
综合案例:将data的第1、5清0, 第3, 4位置1 其他为保持不变
unsigned char data = 0xaa;//1010 1010
将data的第1、5清0:
data = data & 1101 1101;
1101 1101 = ~(0010 0010) =~(0010 0000 | 0000 0010)
0010 0000 = 0000 0001 << 5
0000 0010 = 0000 0001 << 1
1101 1101 = ~(0x01 <<5 | 0x01<<1)
data = data & ~(0x01<<5 | 0x01<<1);
第3, 4位置1:
data = data | 0001 1000;
0001 1000 = 0001 0000 | 0000 1000
= 0x01<<4 | 0x01<<3
data = data | (0x01<<4 | 0x01<<3);
知识点4【?:】
表达式1 ? 值1:值2
语法:如果表达式1 为真 整个表达式的值为“值1” 否则为“值2”
案例:
void test01()
{
int ret = 0;
ret = 3>2? 5:6;
printf("ret = %d\n", ret);//5
}
int main(int argc,char *argv[])
{
test01();
return 0;
案例:逗号运算符
void test02()
{
int data1 = 0;
int data2 = 0;
data1 = 3,4,5,6;
data2 = (3,4,5,6);
printf("data1 = %d\n",data1);//3
printf("data2 = %d\n",data2);//6
}
int main(int argc,char *argv[])
{
test02();
return 0;
}
知识点5【复合运算符】
+= -= *= /= %= 等等
a += b; ==> a = a + b;
a *= b; ==> a= a * b;
注意:=号 右边必须看成一个整体
案例:
void test03()
{
int data = 3;
//将=右边看成一个整体
data *= 3+5;//data = data * (3+5);
printf("data = %d\n",data);//24
}
int main(int argc,char *argv[])
{
test03();
return 0;
}
知识点6【++ – 运算符】
++i 或 --i 先加、减 后使用。
i++ 或 i-- 先 使用 后 加、减
案例:
void test04()
{
int i = 3;
int j = 0;
//++左边 先加 后使用
j = ++i;//i=i+1; j=i;
printf("i = %d, j = %d\n", i,j);//4 4
}
案例:
void test04()
{
int i = 3;
int j = 0;
//先使用 后 加、减
j = i++;//j=i; i=i+1;
printf("i = %d, j = %d\n", i,j);//4 3
}
int main(int argc,char *argv[])
{
test04();
return 0;
}
注意:i++ 或 ++i 作为单独的指令 没有区别
void test05()
{
int i=3;
int j=3;
i++;//i=i+1;
printf("i = %d\n",i);//4
++j;//j=j+1
printf("j = %d\n",j);//4
}
int main(int argc,char *argv[])
{
test05();
return 0;
}
知识点6【优先级】分析已有的代码
优先级 高 先执行, 同级别的优先级 要看结合性。自己写代码, 尽量加()。
知识点7【if语句】
1、如果只在乎项目的一个结果 选择 if
if(表达式)
{
语句1;
}
表达式为真 才会执行语句1;
案例:
void test06()
{
int data = 0;
printf("请输入一个int数据:");
scanf("%d", &data);
//判断能被2整除
if(data % 2 == 0)
{
printf("被2整除");
}
}
int main(int argc,char *argv[])
{
test06();
return 0;
}
2、如果项目的只有两种结果 且不会同时出现。 请选择 if。。。。。。else…
if(表达式)
{
语句1;
}
else
{
语句2;
}
表达式为真 执行语句1 否则执行 语句2
void test06()
{
int data = 0;
printf("请输入一个int数据:");
scanf("%d", &data);
//判断data对2的余数
if(data % 2 == 0)
{
printf("余数为0\n");
}
else
{
printf("余数为1\n");
}
}
int main(int argc,char *argv[])
{
test06();
return
3、如果一个项目 有多个结果 且 不同时 出现。选择if…else if…else if …else
if(表达式1)
{
语句1;
}
else if(表达式2)
{
语句2;
}
else//可省略
{
语句n;
}
只有表达式1为真 执行语句1,只有表达式2为真 执行语句2,所有表达式都为假 才执行语句n;
案例:
void test06()
{
int data = 0;
printf("请输入一个int数据:");
scanf("%d", &data);
//判断data对3的余数 0 1 2
if(data % 3 == 0)
{
printf("余数为0\n");
}
else if(data %3 == 1)
{
printf("余数为1\n");
}
else if(data %3 == 2)
{
printf("余数为2\n");
}
}
注意:只有前面的条件不满足 才会判断后面的条件,如果前面的条件满足 后面的条件不管真假 都不会执行。
4、一个项目有多个结果 不确定 是否同时出现。
if(表达式1)
{
语句1;
}
if(表达式2)
{
语句2;
}
if(表达式3)
{
语句3;
}
每个if语句是独立的。
作业:键盘输入一个数 能否被3和7同时整除。
知识点8【switch选择语句】
switch(表达式)
{
case 值1://不能是实型、字符串
语句1;
break;
case 值2:
语句2;
break;
case 值3:
语句3;
break;
default://可以省略
语句n;
break;
}
案例:
void test06()
{
int data = 0;
printf("请输入一个int数据:");
scanf("%d", &data);
switch(data%3)
{
case 0:
printf("余数为0\n");
break;
case 1:
printf("余数为1\n");
break;
case 2:
printf("余数为2\n");
break;
}
案例:
#include<stdio.h>
void test01()
{
int ret = 0;
ret = 3>2? 5:6;
printf("ret = %d\n", ret);//5
}
void test02()
{
int data1 = 0;
int data2 = 0;
data1 = 3,4,5,6;
data2 = (3,4,5,6);
printf("data1 = %d\n",data1);//3
printf("data2 = %d\n",data2);//6
}
void test03()
{
int data = 3;
//将=右边看成一个整体
data *= 3+5;//data = data * (3+5);
printf("data = %d\n",data);//24
}
void test04()
{
int i = 3;
int j = 0;
//先使用 后 加、减
j = i++;//j=i; i=i+1;
printf("i = %d, j = %d\n", i,j);//4 3
}
void test05()
{
int i=3;
int j=3;
i++;//i=i+1;
printf("i = %d\n",i);//4
++j;//j=j+1
printf("j = %d\n",j);//4
}
void test06()
{
char ch = 0;
printf("请输入你的方向:wasd\n");
ch = getchar();
switch(ch)
{
case 'w':
case 'W':
printf("向上移动\n");
break;
case 'a':
case 'A':
printf("向左移动\n");
break;
case 's':
case 'S':
printf("向下移动\n");
break;
case 'd':
case 'D':
printf("向右移动\n");
break;
}
}
int main(int argc,char *argv[])
{
test06();
return 0;
}
作业:键盘输入1~7的的数 用switch判断今天是星期几