数据类型转换:
1.当赋值符号两边的数据类型不同的时候,数据类型转换是自动的,不需要程序员插手
当给 int 类型的变量赋值的时候:
1).如果我们赋值的数据超出 int 的范围,这个时候 c 会将数据为 1 个随机的 int 数据.
int num =2200000000;
printf("num = %d\n",num);//num = -2094967296(后面学了进制就知道这个数怎么来的)
2).如果我们赋值的数据超出 int 的范围太多,这个时候自动类型转换就无能为力,编译器直接报错.
3).如果我们赋值的数据是一个小数,这个时候 c 会直接截取整数部分.
当给 float 类型的变量赋值的时候:
如果我们用一个double类型的小数给float变量赋值,会把double类型的浮点数转换成float类型小数,不会报错,精度丢失
2).如果我们用一个 int类型数给float变量赋值,那么就将这个整数转换成float类型小数,所以在赋值的时候加一个 .0f!!!
当给 double 类型的变量赋值的时候:
1).如果我们用一个float类型的小数给double变量赋值,会把float类型的浮点数转换成double类型小数,不会报错,精度提高
2).如果我们用一个 int类型数给double变量赋值,那么就将这个整数转换成double类型小数,所以在赋值的时候加一个 .0!!!
当给 char 类型的变量赋值的时候:
1).ASCII码:
只要记住这3个,其他的,推出来
'A' 65
'a' 97
'0' 48
2).如果我们用一个 int类型数给 char变量赋值,其实在赋值的时候是以这个整数为 ASCII 码所对应的字符数据.
scanf函数的简单使用:
a:在格式控制符中用占位符来要求用户输入 1 个指定类型的数据.
b:在后面写上要将用户输入的数据到 1 个变量的地址,用 & 就可以取到变量的地址.
c:如果程序没有输出信息,下面的控制台输出区域不会自动弹出来的.
注意:scanf函数是一个阻塞式函数,用户不输入,就不会往下执行。
scanf函数接收各个类型的数据:
1).使用 scanf 函数接收其他类型的数据,想要让用户输入什么类型的数据,是根据格式占位符来决定的
%d用户输入 int的数据scanf("%d", &变量名);
%f用户输入 float的数据scanf("%f", &变量名);
%lf用户输入 double的数据scanf("%lf", &变量名);
%c用户输入 char的数据scanf("%c", &变量名);
2).scanf函数使用的步骤:
3).使用scanf函数需要注意的细节
1.定义变量的时候不要再用a,b,c
2.注释要写
3.scanf函数习惯性的加了\n,这个一定一定要注意,scanf函数双引号里不能加\n
\n可以过滤多个空白字符(换行符,制表符和空格),直到遇到非空白符的时候才终止输入。但那个非空白符并没有读到scanf里
4.不要忘记加& --->奔溃
5.scanf里面的格式控制符,一定要和你要输入的变量的类型一致,否则会出问题
4).使用scanf函数一次接收输入多个数据
1.没有自定义分隔符(分隔符默认是空格/回车/tab)
1).此时如果要求输入的是整数或者浮点数,输入过程中的回车/空格/tab,都会被忽略.
int num_int1 =0;
float num_f =0.0f;
int num_int2 =0;
printf("输入前%d-%f-%d\n",num_int1,num_f,num_int2);
scanf("%d%f%d",&num_int1,&num_f,&num_int2);
printf("输入后%d-%f-%d\n",num_int1,num_f,num_int2);
输入前0-0.000000-0
1 12.34 111
输入后1-12.340000-111
Program ended with exit code: 0
2).如果有字符,如果在输入字符之前有多余的操作(空格/回车/tab),数据的赋值就会有问题.
int num_int =0;
char num_char ='a';
int num_int2 =0;
printf("输入前%d-%c-%d\n",num_int,num_char,num_int2);
scanf("%d%c%d",&num_int,&num_char,&num_int2);
printf("输入后%d-%c-%d\n",num_int,num_char,num_int2);
输入前0-a-0
12 b 13 //12 空格 b 空格 13 回车
输入后12- -0 //12-空格-0
Program ended with exit code: 0
2.自定义分隔符
1).一旦指定,就要严格按照自定义的分隔符进行分割,绝对没有问题的
int num_int1 =0;
char num_char ='a';
int num_int2 =0;
printf("输入前%d-%c-%d\n",num_int1,num_char,num_int2);
scanf("%d--%c--%d",&num_int1,&num_char,&num_int2);
printf("输入后%d-%c-%d\n",num_int1,num_char,num_int2);
这里的自定义分隔符是"--"
输入前0-a-0 //没有按照自定义的分隔符 "--" 进行分割,出问题了
12-b-13 //12 - b - 13 回车
输入后12-a-0
Program ended with exit code: 0
输入前0-a-0 //按照自定义的分隔符 "--" 进行分割,没有出问题
12--b--13 //12 -- b -- 13 回车
输入后12-b-13
Program ended with exit code: 0
3.scanf函数的缓冲区
1.当控制台停下来等待你输入,说明缓冲区是空的
2.你输入的所有数据都会存储到缓冲区,然后程序从缓冲区拿数据向变量赋值
3.只要缓冲区有数据,程序再遇到scanf语句,就不会在控制台等待你输入,
4.程序从缓冲区拿数据,如果是给浮点数或者整数赋值,忽略空格/tab/回车,"给字符赋值,不忽略回车
例子1:输入1空格2空格3回车
int num1=0,num2=0,num3=0;
printf("输入前%d-%d-%d\n",num1,num2,num3);
printf("请输入:"); //输入1空格2空格3回车
scanf("%d%d",&num1,&num2);
printf("----------------\n");
scanf("%d",&num3);
printf("输入后%d-%d-%d\n",num1,num2,num3);
结果是:
输入前0-0-0
请输入:1 2 3
----------------
输入后1-2-3
Program ended with exit code: 0
从上面可以看出当从缓冲区中拿数据的时候,如果要拿的数据是整型或者实型,如果拿到的是空格 回车 Tab键,就会自动忽略,继续往下拿.
例子2:
int num1 =1;
char num_c ='a';
printf("输入前:%d-%c\n",num1,num_c);
printf("请输入:");
scanf("%d",&num1);
scanf("%c",&num_c);
printf("输入后:%d-%c\n",num1,num_c);
结果是:
从上面可以看出当从缓冲区中拿数据的时候,如果要拿的数据是字符型不会自忽略任何数据.
***所以我们可以用清空缓冲区的方式来解决上面的问题***
int num1 =1;
char num_c ='a';
printf("输入前:%d-%c\n",num1,num_c);
printf("请输入:");
scanf("%d",&num1);
rewind(stdin);//清空缓冲区
scanf("%c",&num_c);
printf("输入后:%d-%c\n",num1,num_c);
return0;
结果是:
输入前:1-a
请输入:10 //输入10回车 b回车
b
输入后:10-b
Program ended with exit code: 0
务必记住:凡是需要输入字符,请你单独写一句scanf函数,并且前面加上rewind(stdin)
交换两个变量的值:
1.第一种方式:
int num1 =5;
int num2 =10;
printf("交换前:num1 = %d num2 = %d\n", num1, num2);
int tempNum = num1;//tempNum = 5 num1 = 5
num1 = num2;//num1 = 10 num2 = 10
num2 = tempNum;//num2 = 5 tempNum = 5
printf("交换后:num1 = %d num2 = %d\n", num1, num2);
交换前:num1 = 5 num2 = 10
交换后:num1 = 10 num2 = 5
Program ended with exit code: 0
2.第二种方式:两数相加再相减
int num1 =5;//初始值
int num2 =10;//初始值
printf("交换前:num1 = %d num2 = %d\n", num1, num2);
num1 = num1 + num2;// num1 = num1的初始值+ num2的初始值
num2 = num1 - num2;//num2 = num1的初始值+ num2的初始值- num2的初始值num2 = num1的初始值
num1 = num1 - num2;// num1 = num1的初始值+ num2的初始值- num1的初始值num1 = num2的初始值
printf("交换后:num1 = %d num2 = %d\n", num1, num2);
交换前:num1 = 5 num2 = 10
交换后:num1 = 10 num2 = 5
Program ended with exit code: 0
算术运算符和算术表达式:
算术运算符:+ - * / %
算术表达式:由算术运算符连接起来的式子
1.算数表达式的值有类型.算数表达式最终结果类型,取决于精度最高的那个数.
double>float>int
2.当参与运算的数据类型一致,算数运算表达式的结果的类型就是参与运算的数据的类型
分析下面代码段:
//先声明变量,再计算表达式的结果,最后将表达式的结果赋值给变量
int result =1/3;//0.3333
printf("%d\n",result);//0
doubleresult =1/3;//0.3333333 0 --- > 0.000000
printf("%lf\n",result);//0.000000
上面的算数表达式都是 int 类型的,所以这个表达式的结果是 0 ,不是 0.3333
如何获取两个整数的真实的商?
//思路:定义操作数为double类型、或者操作数*1.0
double result = (double)1/3;
printf("%lf\n",result);//0.333333
3.%求模运算
1>浮点数不能参与求模运算,没有意义
2> m % n求余的结果一定是0~ n-1之间
m%n求余
(1)n 等于0无意义
(2)m 等于0结果为0
(3)m>n 正常求余如:8%3=2
(4)m<n 结果是m如:2%4=21%4=13%8=3
算术运算符的优先级和char数据参与算术运算:
1.* / %优先级相等并且高于+ - (+ -优先级相同),如果同级别,从左到右运算,如果有小括弧,就先算小括弧里的表达式.
2.char变量/常量和整数一起运算,直接拿ASCII码进行运算
int sum ='a'+3;// 'a' -->97 + 3 ---> 100
printf("%d\n", sum);//100
char char_b ='b';
sum =3+ char_b;// 'b' -->98 + 3 --->101
printf("%d\n", sum);//101
3.如何把小写的字母转化为大写
'A'--->65 'a'--->97
'B'--->66 'b'--->98
小写-->大写-32 大写-->小写+32
复合赋值运算符:
1.常见的复合赋值运算
int num =10;
+=比如: num +=10; --->等价于num = num +10;
-=比如: num -=10; --->等价于num = num -10;
*=比如: num *=10; --->等价于num = num *10;
/=比如: num /=10; --->等价于num = num /10;
%=比如: num %=10; --->等价于num = num %10;
2.如果以后想在一个变量自身的基础上改变当前的值,就可以使用复合赋值运算符
自增与自减运算:
1)前缀表达式:++x, --x;其中x表示变量名,先完成变量的自增自减1运算,再用x的值作为表达式的值;即“先变后用”,也就是变量的值先变,再用变量的值参与运算。
2)后缀表达式:x++, x--;先用x的当前值作为表达式的值,再进行自增自减1运算。即“先用后变”,也就是先用变量的值参与运算,变量的值再进行自增自减变化。
注意:不管“++”在前还是在后,最后变量的值都会+1
a++ -->后自增表达式-->整个a++的表达式的值是a --> a变量的值是a+1;
++a -->前自增表达式-->整个++a的表达式的值是a+1--> a变量的值是a+1;
a-- --> a--表达式的值是a --> a变量的值a-1
--a --> --a表达式的值是a-1--> a变量的值a-1
逗号表达式:
1.知道逗号表达式的结构(AAA,BBB,CCC)
2.执行过程从左向右执行
3.整个逗号表达式的结果是最后一个式子也就是CCC的值.
4.逗号表达式的目的,只要前面的表达式执行,关心最后一个表达式的结果是多少,因为我们前面的表达式一旦执行就会影响最后一个表达式的结果
比较运算符和比较表达式:
1.比较运算符:
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于
2.比较运算符的作用:比较大小的
3.比较表达式:由比较运算符连接起来的式子
4.比较表达式的结果:
比较表达式用来比较若干数据之间的大小关系,
比较表达式的结果是0或者 非0,0表示不成立非0表示成立
5.优先级:
> < >= <=的优先级相等
== !=的优先级相等
> < >= <=的优先级高于== !=的优先级
比较运算表达式的场景:
1.比较运算符的两边可以是常量或者是变量
int result =1>2;// 0//常量
int num=1;//变量
int result2 = num <2;// 1
2.比较运算符的两边可以分别是表达式
int num =10;
int result =11- num < num *2;// 1<20 --->1
算术运算符的优先级比关系运算符的优先级高,一个式子里面既有比较运算符又有算数运算符就先算数运算符,再算比较运算符.
3.char类型的变量或者常量也可以参与比较运算符,比较的是相应的ASCII码
逻辑运算符:
&&逻辑与并且
||逻辑或或者
!逻辑非取反
1.计算机的世界中,"非0就是真,0就是假
2.输入一个年份,判断是不是闰年
(年份%400==0) || (年份%4==0)&&(年份%100!=0)
逻辑与运算符
A && B
1.&&逻辑与运算符运算规则
A和B都是真结果才是真,A和B有一个是假,结果就是假)("同真则真,一假则假")
2.断路问题
A是假,B将不会再进行判断,整个式子是假的
逻辑或运算符
A || B
1.||逻辑与运算符运算规则
A和B只要有一个是真结果就是真,A和B都是假,结果才是假"一真则真,同假为假"
2.断路问题
A是真,B将不会再进行判断,整个式子是真
!逻辑非运算规则
真变假 假变真 非零变0 0变1
逻辑运算符的优先级和结合性
1.什么是优先级
当一个表达式中,有各种各样的不同类型的运算符的时候,此时应该先计算哪一个运算符?
解决这个问题的方案就是优先级
2.什么是结合性
当一个表达式中存在运算符的优先级相等的时候,此时应该从左向右运算还是从右向左运算
解决这个问题的方案就是结合性
断路问题
1.当自增自减运算和逻辑运算组合时,编译器编译代码的时候,放弃优先级,从左向右扫描,最后去判断自增自减要不要去执行
2.当逻辑&&和逻辑||组合运算时,仍然是放弃优先级,从左向右扫描,如果有断路,后面的就不执行,如果没有断路,那么就按照正常的优先级来计算