为什么需要类型转换?
计算机硬件只能对相同类型数据进行运算。
何时发生类型转换?
给定的数据类型与需要的数据类型不匹配时。
如何进行类型转换?
隐式(编译器自动完成)和显示类型转换。
硬件处理int最自然 故ch+ch short+short结果都会自动转换为Int
小的类型自动转换成大的类型 有符号自动转化为无符号。
显式类型转换的用途:
比如,想要获取double i=3.145798的小数部分时 i-(int)i
int i=(int)3.14f 为了提高可读性
int a=3,b=4 double res=a/b 会得到一个00000 但是我们想要0.小数部分时 (double)a/b
long long a=100*20*100*1000*100; 因为后面常量自动为int 类型 后面表达式超出了Int类型所能表示的范围
Typedef 类型 别名
给类型取别名
宏定义的区别是?
宏定义发生在预处理阶段,此时编译器还不能识别别名,不能给出友好提示
编译器可以识别Typedef 定义的别名,可以发出友好提示。
定义别名时候,一律使用Typedef
为什么要给类型起别名?1. 提高可读性 2.提高可移植性(比如INT所占字节在不同机器下不固定,移植时可能溢出造成错误,把所有int改成long,容易遗漏,直接Typedef int QQ,更改别名即可)
SIZEOF 运算符 得出的结果以字节为单位
是在编译阶段计算的 故sizeof(名字)的结果是可以作为数组数量
表达式
计算某个值的公式
变量和常量就是最简单的表达式。
运算符的作用:连接表达式,创建更复杂的表达式
运算符:算数/赋值/关系/比较/位/逻辑运算符 函数调用也是运算符。
运算符的优先级
算术运算符
+ - * / (前四个可以作用于浮点数) %(要求两个操作数都为整数)
两个整数相除,其结果为整数 (舍入规则为向0取整)
i%j运算的结果 可能为负 结果的符号与相同
i%j=i-j*(i/j) 计算机是靠这个式子 实现取余运算的
不能用n%2==1来判断是否为奇数 因为结果可能为负
n&0x1是更好的判断方法,位运算效率更高。按位与运算。 用位运算时,最好把数字写成16进制。
赋值运算符
=,简单赋值
V=E 把表达式E的值赋值给变量V(副作用),整个表达式的值为赋值后V的值
1.赋值过程中,可能会发生隐式类型转换
2.从右到左结合 i=j=k k的值先赋给j j的值赋给i。
float f; int i;
f=i=3.14f; i=3,f=3.000000
复合赋值运算符
a+=b;
自增和自减运算符
自增:i=i+1 i+=1
自减同理
C语言提供了专门的自增/减运算符 ++/--
i++:表达式的值为i,副作用i自增
++i:表达式的值为i+1,副作用i自增
注意事项: i=i++; 会产生未定义的行为
j=(i++)+(++i) 未定义的行为 不知道哪个表达式先计算
a[i]=b[i++] 也是未定义行为 不知道左右谁先发生.
但a[i++]=不带i的值;是正确的。
关系运算符 >= <= > <
其运算结果结果要么为0,要么为1
从左向右结合
若10<j<20 此表达式结果 永远为1
判等运算符 == !=
其结果要么为0,要么为1
逻辑运算符 && || !
注意事项:&&和|| 会发生短路现象
e1&&e2 先计算表达式e1的值 如果为false,则不会计算e2表达式的值
e1||e2 若e1为真,则不会计算e2的值。
短路原则的好处:方便编写程序 (i!=0&&i/j>1) 若i为0,第二个判断无意义。
位运算符(面试重点)
<< >> & | ~ ^
移位运算 << >>
i<<j i左移J位, 右边补0。 若无溢出,相当于乘以2的j次方。
i>>j 右移动j位,1.无符号整数/正数有符号整数,则左边补0 2.若是有符号负数,行为由编译器具体实现决定。C语言标准没有对此规定,可能补0,也可能补1。
相当于除以2的j次幂 但有可能丢失精度。相当于向下取整。
注意:为了可移植性,不要对有符号整数,进行移位运算!!!
按位运算 & | ~ ^
a^0=a a^a=0 a^b=b^a (a^b)^c=a^(b^c);
判断一个数 有几个二进制的1
n&n-1的结果每次 比n少一个1
n&n-1 循环与,直到为0,循环次数即是1的个数
判断一个数 是否为奇数 A&1
如何判断一个整数,是否为2的幕?(n&n-1)==0
给定一个不为0的整数 找出权重最低的一位
输入 01000100
输出 00000100
n&(-n) -n的二进制表示 第一个1及其右边保持不变 其他位按位取反
给定一个整数数组,里面的数都是成对出现的,只有一个数例外,请找出这个数
所有数一起异或
给定一个整数数组,里面的数都是成对出现的,只有两个数例外,找出这两个数。
如果能把A,B分到不同数组 两个数组分别调用上一题。
a,b不同 那a^b至少有一位为1 找出最低有效位 根据最低有效位分组。
然后再用上题的做法。
语句
选择语句
级联式本质上是if/else嵌套。
if语句要小心悬空else问题,else应属于最近的if语句 跟缩进无关,除非用括号括起来。
每个case后可以跟任意句语句,而不需要使用花括号括起来。
case 后跟常量表达式,并且表达式的值必须是整数(字符也可以)。加'c'是因为标识符是字符,否则不用。
分支标号不可重复,但对分支的顺序没有要求,default甚至可以放最前面,default分支也可以不存在。
不能用浮点数的原因是 浮点数不精确 没法和switch标签判断相等,switch是通过==进行比较的。
字符串则是用地址代表的,switch里面比较的其实是字符串地址,因此,也不可以。
级联式if语句和switch的优劣
1.级联if比switch更通用(使用范围更广,switch限制条件太多)
2.switch语句 可读性比if强
3.switch(只需要比较一次)的执行效率比if高