C语言知识点笔记7
此笔记是我考研备考专业课期间听课的一些C语言知识点混记,可能会有一点乱,有需要的朋友们可以翻阅一下,有利于巩固C语言知识点!
1、算术操作符:+ - * / % (1)打印小数:float a=6/5.0; printf("%f\n", a); //1.200000 (2)取模:%操作符的两个操作数必须为整数。返回的是整除之后的余数。
2、移位操作符: << >>
①左移<<
(1)int a = 2; int b = a<<1; //把a的二进制位向左移动一位
(2)左移操作符:左边丢弃,右边补0
(3)
00000000000000000000000000000010 00000000000000000000000000000100
2 -->4
②右移>>
(1)int a = 10;int b = a>>1;//把a的二进制位向右移动1位
移动之后对a本身没有改变
(2)右移操作符:1:算术右移:右边丢弃,左边补原符号位 2:逻辑右移:右移丢弃,左边补0
(3)1010-->0101 10-->5
3、负数:-1 存放在内存中的是二进制的补码: 原码:直接根据数值写出来的二进制序列就是原码 反码:原码的符号位不变,其他位按位取反就是反码 补码:反码加一就是补码 这种算法只针对于负数,对于正整数来说:原码,反码,补码相同 -1: 原码:10000000000000000000000000000001 反码:11111111111111111111111111111110 补码:11111111111111111111111111111111 (-1在内存中存放的)
4、位操作符: & | ^ 操作符之间的数必须是整数 (1)&:按二进制位与 int a = 3; int b = 5; int c = a & b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000001----1 (2)|:按二进制位或 int c = a | b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000111----7 (3)^:按二进制位异或 对应的二进制位进行异或 规则:相同为0,相异为1 int c = a ^ b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000110----6
5、小练习: 交换两个值,不用第三个变量。使a=3,b=5变为a=5,b=3
int mian()
{
int a = 3;
int b = 5;
a = a ^ b; 011^101-->110-->a=6
b = a ^ b; 110^101-->011-->b=3 b=a^b^b
a = a ^ b; 110^011-->101-->a=5
}
此时用到的就是异或。
6、~:按位取反(全部取反)
int a = -1; //10000000000000000000000000000001--原码 //11111111111111111111111111111110--反码 //11111111111111111111111111111111--补码
int b =~a; //输出为0 //11111111111111111111111111111111 //00000000000000000000000000000000 小练习:
int main()
{
int a = 13;
要求:把a的二进制中的第5位置换成1
a = a | (1<<4);//按位或
//00000000000000000000000000001101 --> a
//00000000000000000000000000010000 --> 1<<4
//00000000000000000000000000011101 --> a | (1<<4) 29
要求:把a的二进制中的第5位置换成0
a = a & ~(1<<4);//按位与
//00000000000000000000000000011101--> a
//11111111111111111111111111101111--> ~(1<<4)
//00000000000000000000000000010000--> (1<<4)
//00000000000000000000000000001101--> a & ~(1<<4)
}
7、逻辑操作符: && ||
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//i = a++ &&.... ;a++为0,后面的直接不用算了
printf("a = %d\n b = %d\n c = %d\n d = %d\n", a, b, c, d);//1 2 3 4
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;//i = a++ ||....;a++为1真,后面不用算了
printf("a = %d\n b = %d\n c = %d\n d = %d\n", a, b, c, d);//2 2 3 4
}
8、 逗号表达式: 要从左向右依次计算,但是整个表达式的结果是最后一个表达式的结果 int a = 3,b = 5, c = 0; int d = (c = 5, a = c + 3, b = a - 4, c += 5);//输出为10;
9、整型提升:(低位提升为高位 例:char->int) c的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作符在使用之前被转换为普通整型,这种转换称为整型提升 例题说明1:
int main()
{
char a = 3;
//00000000000000000000000000000011
//00000011 - a
char b = 127;
//00000000000000000000000001111111
//01111111 - b
char c = a + b;
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
//10000010-c 此时首位为1,高位补1
//11111111111111111111111110000010 -- 补码
//11111111111111111111111110000001 -- 反码
//10000000000000000000000001111110 -- 原码
//-126
//发现a和b都是char类型的,都没有达到一个int的大小
//这里就会发生整型提升
//整型提升是按照变量的数据类型的符号位来提升的
printf("%d\n", c);//输出为-126
return 0;
}
例题说明2:
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a == 0xb6)
printf("a");
if(b == 0xb600)
printf("b");
if(c == 0xb6000000)
printf("c");
//输出为c
//a,b都需要整型提升
return 0;
}
10、 算术转换: 如果某个操作符的各个操作符属于不同的类型,那么除非其中一个操作数的类型转换为另一个操作数的类型,否则操作就无法进行。(向精度高的类型转换) 操作符的属性: (1)操作符的优先级 (2)操作符的结合性 (3)是否控制求值顺序 例1:
int main()
{
int arr[] = {1,2,(3,4),5};//逗号表达式,其实是4
printf("%d\n", sizeof(arr));//输出为16 4*4
}
例2:
int main()
{
char str[] = "hello bit";
// [hello bit\0] sizeof时\0算一个字节
printf("%d %d\n",sizeof(str), strlen(str));
//输出为10 9
//sizeof -- 操作符-计算变量/类型所占内存大小,单位是字节
//strlen -- 函数-求字符串长度的,找\0之前出现的字符个数
}
(1)int a = 2; int b = a<<1; //把a的二进制位向左移动一位 (2)左移操作符:左边丢弃,右边补0 (3) 00000000000000000000000000000010 00000000000000000000000000000100 2 -->4 ②右移>> (1)int a = 10;int b = a>>1;//把a的二进制位向右移动1位 移动之后对a本身没有改变 (2)右移操作符:1:算术右移:右边丢弃,左边补原符号位 2:逻辑右移:右移丢弃,左边补0 (3)1010-->0101 10-->5
3、负数:-1 存放在内存中的是二进制的补码: 原码:直接根据数值写出来的二进制序列就是原码 反码:原码的符号位不变,其他位按位取反就是反码 补码:反码加一就是补码 这种算法只针对于负数,对于正整数来说:原码,反码,补码相同 -1: 原码:10000000000000000000000000000001 反码:11111111111111111111111111111110 补码:11111111111111111111111111111111 (-1在内存中存放的)
4、位操作符: & | ^ 操作符之间的数必须是整数 (1)&:按二进制位与 int a = 3; int b = 5; int c = a & b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000001----1 (2)|:按二进制位或 int c = a | b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000111----7 (3)^:按二进制位异或 对应的二进制位进行异或 规则:相同为0,相异为1 int c = a ^ b; 00000000000000000000000000000011----3 00000000000000000000000000000101----5 00000000000000000000000000000110----6
5、小练习: 交换两个值,不用第三个变量。使a=3,b=5变为a=5,b=3
int mian()
{
int a = 3;
int b = 5;
a = a ^ b; 011^101-->110-->a=6
b = a ^ b; 110^101-->011-->b=3 b=a^b^b
a = a ^ b; 110^011-->101-->a=5
}
此时用到的就是异或。
6、~:按位取反(全部取反)
int a = -1; //10000000000000000000000000000001--原码 //11111111111111111111111111111110--反码 //11111111111111111111111111111111--补码
int b =~a; //输出为0 //11111111111111111111111111111111 //00000000000000000000000000000000 小练习:
int main()
{
int a = 13;
要求:把a的二进制中的第5位置换成1
a = a | (1<<4);//按位或
//00000000000000000000000000001101 --> a
//00000000000000000000000000010000 --> 1<<4
//00000000000000000000000000011101 --> a | (1<<4) 29
要求:把a的二进制中的第5位置换成0
a = a & ~(1<<4);//按位与
//00000000000000000000000000011101--> a
//11111111111111111111111111101111--> ~(1<<4)
//00000000000000000000000000010000--> (1<<4)
//00000000000000000000000000001101--> a & ~(1<<4)
}
7、逻辑操作符: && ||
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//i = a++ &&.... ;a++为0,后面的直接不用算了
printf("a = %d\n b = %d\n c = %d\n d = %d\n", a, b, c, d);//1 2 3 4
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;//i = a++ ||....;a++为1真,后面不用算了
printf("a = %d\n b = %d\n c = %d\n d = %d\n", a, b, c, d);//2 2 3 4
}
8、 逗号表达式: 要从左向右依次计算,但是整个表达式的结果是最后一个表达式的结果 int a = 3,b = 5, c = 0; int d = (c = 5, a = c + 3, b = a - 4, c += 5);//输出为10;
9、整型提升:(低位提升为高位 例:char->int) c的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作符在使用之前被转换为普通整型,这种转换称为整型提升 例题说明1:
int main()
{
char a = 3;
//00000000000000000000000000000011
//00000011 - a
char b = 127;
//00000000000000000000000001111111
//01111111 - b
char c = a + b;
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
//10000010-c 此时首位为1,高位补1
//11111111111111111111111110000010 -- 补码
//11111111111111111111111110000001 -- 反码
//10000000000000000000000001111110 -- 原码
//-126
//发现a和b都是char类型的,都没有达到一个int的大小
//这里就会发生整型提升
//整型提升是按照变量的数据类型的符号位来提升的
printf("%d\n", c);//输出为-126
return 0;
}
例题说明2:
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a == 0xb6)
printf("a");
if(b == 0xb600)
printf("b");
if(c == 0xb6000000)
printf("c");
//输出为c
//a,b都需要整型提升
return 0;
}
10、 算术转换: 如果某个操作符的各个操作符属于不同的类型,那么除非其中一个操作数的类型转换为另一个操作数的类型,否则操作就无法进行。(向精度高的类型转换) 操作符的属性: (1)操作符的优先级 (2)操作符的结合性 (3)是否控制求值顺序 例1:
int main()
{
int arr[] = {1,2,(3,4),5};//逗号表达式,其实是4
printf("%d\n", sizeof(arr));//输出为16 4*4
}
例2:
int main()
{
char str[] = "hello bit";
// [hello bit\0] sizeof时\0算一个字节
printf("%d %d\n",sizeof(str), strlen(str));
//输出为10 9
//sizeof -- 操作符-计算变量/类型所占内存大小,单位是字节
//strlen -- 函数-求字符串长度的,找\0之前出现的字符个数
}