(自本章开始,就要学习符号啦!)
一、'\':续航&&转义
- 续航功能:
if (1 == a && 2 == b && 3 == c) 等同于: if (1 == a &&\ 2 == b &&\ 3 == c)
续航符之后不要出现任何符号,包括空格
-
转义:C中,有一些字符,就是他的字面意思,比如'n','b','t'。 也有一些字符,本身就是特殊含义的,如 ', " , \
-
转义的本质:字面转特殊 特殊转字面:
-
n——>'\n' ''——\"
-
回车:光标回到当前行的最开始:\r
-
换行:光标移至下一行:\n
-
C语言中\n相当于\n+\r
二、单引号和双引号
- 'a'叫整型字符常量,被看成int型
- 单引号的值为4个字节(整型字符常量),char类型为1个字节,赋值的时候会发生截断,实际上字符类型就是整型
char c = '1'; sizeof('1') = 4;(c++显示1) sizeof(c) = 1;
char c = '1','1'是4个字节(整型字符常量)——>char类型是1字节,发生截断
- 单引号内至少得有1个字符,双引号内可以为空,因为他至少有一个'\0'
-
int main() { printf("%d\n", sizeof('')); //报错 printf("%d\n", sizeof("")); //空串大小是1,实际上就是'\0'的大小 }
- ASCII码值的意义: 把计算机中的二进制通过ASCII码表将字符逐个显示出来
- 12345占四个字节,输出'1' '2' '3' '4' '5',5个字符转化过程有printf完成
- '1' '2' '3' '4' '5'——>12345,由scanf完成,实际上都是字符
三、逻辑运算符
- &&逻辑与:必须同时为真,结果才为真
- ||逻辑或:须至少一个为真,结果才为真
短路:上面的一个条件不满足,已经不需要在看后续的条件的情况,就叫做短路
flag && show(),如果flag为假show函数直接不执行,前面的条件成立时才执行后面的——相当于if语句
lag || show(),如果flag为真show函数直接不执行,前面的条件不成立时才执行后面的——相当于ifnot
四、位运算
|:按位或 ,同时为0才为0
&:按位与,同时为1才为1
^:按位异或,相异为1,相同为0
~:按位取反,符号位也要参与
1、交换两个数的三种方法
①:创建临时变量:
int a = 10; int b = 20; int tmp = a; a = b; b = tmp;
②:不创建临时变量
int a = 10; int b = 10; a = a + b; b = a - b; a = a - b; 问题:若a,b特别大时,可能会有溢出问题
方法二:
int a = 10; int b = 10; a = a ^ b; b = a ^ b; a = a ^ b; 异或没有进位,不会发生溢出问题
2、设定特定比特位为1
#include <stdio.h>
#define SETBIT(x, n) (x = (x | (1 << (n - 1)))) //1|1=1 0|1=1
void ShowBits(int x)
{
int num = sizeof(x) * 8 - 1;
while (num >= 0)
{
if (x & (1 << num))//0&1=0 1&1=1
printf("1");
else
printf("0");
num--;
}
}
int main()
{
int x = 0;
SETBIT(x,5);
ShowBits(x);
return 0;
}
3、将特定比特位设置为0
#include <stdio.h>
#define BITSET(x, n) (x &= ~(1 << (n-1)))
void ShowBits(x)
{
int num = sizeof(x) * 8 - 1;
while (num >= 0)
{
if (x & 1 << num)
printf("1");
else
printf("0");
num--;
}
}
int main()
{
int x = -1;
BITSET(x, 5);
ShowBits(x);
return 0;
}
五、整型提升
char c = 1;
int a = sizeof(c);//1
int b = sizeof(~c);//4
int c = sizeof(c << 1);//4
int d = sizeof(c >> 1);//4
无论任何位运算符,目标都是要计算机进行计算的,而计算机中只有CPU具有运算能力(先这样简单理解),但计算的数据, 都在内存中。故,计算之前(无论任何运算),都必须将数据从内存拿到CPU中,拿到CPU哪里呢?毫无疑问,在CPU 寄存器 中。 而寄存器本身,随着计算机位数的不同,寄存器的位数也不同。一般,在32位下,寄存器的位数是32位。 可是,你的char类型数据,只有8比特位。读到寄存器中,只能填补低8位,那么高24位呢? 就需要进行“整形提升”。
整型提升的规则:
1、对于无符号数,直接高位补0即可
2、对于有符号数,在高位补符号位(按照补码的最高位补位,补码最高位【最左边的一位】为0就补0,为1就补1)
#include <stdio.h> int main() { //-1的原码:10000000 00000000 00000000 00000001 // 反码:11111111 11111111 11111111 11111110 // 补码:11111111 11111111 11111111 11111111 //--->char:截断,保留8个比特位 11111111 signed char a = -1; unsigned char b = -1;//存的时候与类型无关,过程同上11111111 printf("%d\n", a);//以有符号整数打印,整型提升,a是有符号数,最高位为1补1 //11111111 11111111 11111111 11111111--->-1 printf("%d\n", b);//b是无符号数,整型提升最高位补0--->00000000 00000000 00000000 11111111 //以有符号整数打印,b最高位为0,正数,原反补相同--->255 return 0; }
若为有符号数,截断后,补码的最高位是几就补几
#include <stdio.h> int main() { //128的原码:00000000 00000000 00000000 10000000(也是补码) //128--->char,截断 10000000 char a = 128; printf("%u\n", a); //整型提升:a是有符号数,截断后最高位是1,则补1--->11111111 11111111 11111111 10000000 //以无符号数打印,原反补相同,4294967168 return 0; }
#include <stdio.h> int main() { signed char a = -192; printf("%d", a); return 0; }
-192的原码:10000000 00000000 00000000 11000000
-192的反码:11111111 11111111 11111111 00111111
-192的补码:11111111 11111111 11111111 01000000——>char,截断
在内存中:01000000,以%的形式打印,整型提升,有符号数,最高位为0,补0:
00000000 00000000 00000000 01000000,读的过程:有符号数先看符号位,为0,正数,原反补相同,64
六、移位操作
- 移的都是二进制补码
- 左移:最高位丢弃,最低位补0
- 右移:无符号数:最低位丢弃,最高位补0
- 有符号数:最低位丢弃,最高位补符号位(和内部保存什么数据无关,无论最高位是0还是1,只补符号位)
理解x<<1 && x <<= 1
- x << 1,x不受影响,因为计算是在CPU寄存器中进行的(CPU 寄存器中的变量与内存中的变量之间是一种临时的、动态的关系,CPU 会根据需要将变量从内存加载到寄存器中进行计算,并在必要时将计算结果写回内存),此时并未写回内存,x不变,类比a+10,a的值不变
- x <<== 1,x发生变化,向左移1位
是冬至呀-CSDN博客https://blog.csdn.net/2302_81218652?spm=1001.2101.3001.5343