c++中易错的地方
1:scanf
int a;
int b;
scanf("%d-=%d",&a,&b);
printf("a=%d,b=%d",a,b);
在scanf中 a和b前面的&一定不能掉
在输入的时候,一定要严格的按照%d-=%d的格式写,比如这次就应该输入11-=12 11和12为a和b的int类型
2:内存的表示
物理内存的单元是“字节”
一个字节占8个位,如下图所示
0000 0000
0000 0000
0000 0000
0000 0000
0000 0000
1个字节的表示范围为
0000 0000(0)到1111 1111(256)
两个字节的表示范围为
0000 0000(0)到1111 1111(256*256)
3:变量的类型
整型
char -128到127
short
int
浮点型
float 4个字节
double 8个字节
赋值方式
float a = 12.34f 后面的f必须加
double a = 12.34
float对应的是%f %.1f 结果保留一位小数
double对应的是%lf
给变量赋值的时候,可以用十进制,也可以用16进制,用16进制需要前面加0X
prinif中的%08X 表示是用16进制打印出来,凑够8位
当用scanf来接收用户输入的整数时,只能用int型变量,不能用short/char型
4:数组
1)数组在内存中的存储
char data[5] = {1,2,3,4,5};
数组在内存所占的空间为 类型所占空间(char占一个字节)*元素的个数(5) 5个字节
int arr[10]所占的空间就为4(int占4个字节)*10(这个数组的个数为10) 10个字节
2)在按F5调试的时候,只需要输入data(数组名)就可以查看数组所占的内存,不需要加&
3)数组的赋值
char a[] = {1,2,3,4,5} //不用表名元素个数直接赋值
char a[5] = {1,2} //赋值一部分
char a[3] = {1,2,3} //全部赋值
5:字符
1)字符的存储
因为计算机上面只能存储0和1,所以想了一个办法,用数字来代替字符
65
当内存中存储了01000001时,它代表了字符串"A"
2)字符的打印方法
printf("%c",65);
printf("%c",'A'); //注意,必须用单引号 'A'
3)在键盘上所有字符用一个数字来表示,为此专门制定了一个表,成为ASSIC码表
A 65 a 97 空格为32 '0'为48 其实这个表没必要记,知道有这么个东西就行了,所以我就不写了
因为ASSIC码表中的大部分数字都比较小,所以字符用char类型的表示就行了
char str = 65;
char str = 'A';
注意 printf("%c",'str');这种形式只能打印一个字符,比如后面的参数为'str',则只能打印出r
4)转义字符 \
\n表示回车
\t表示Tab
\"双引号
\\反斜线
4)字符串数组
1:定义方法
char str[6] = {'h','e','l','l','0','\0'};
注意,字符串数组必须以'\0'或者0来结尾
我们通常用这种方式来定义
char str[6] = "hello"; 通常会直接省略str数组的元素个数
char str[] = "hello"; 系统会在后面自动补0
但是 str[5] = "hello" 这种定义方式是错误的,会提示“str”: 数组界限溢出
2:打印方式 %s
3:字符串数组在打印的时候,遇到'\0'或者0会自动结束输出,但是0后面的内容还是会存储在内存中
6:算数表达式的注意事项
1)在模运算(%)中,操作数不能是小数
2)在除法(/)运算中,整型相除的话结果去掉小数,只保留整数部分,浮点型相除则保留小数部分
3)解析加法运算
a = a + b;
①从a的内存中取出a的值,交给加法器
②从b的内存中取出b的值,交给加法器
③加法器开始运算,求得两数之和,存到输出(寄存器)中
④将加法器的输出值存到a的内存中
4)赋值表达式本身就是一个值
printf("%d",(a=10)); a=10本身就是一个值
5) a+= b-1 等价于 a = a + ( b - 1 )
6) ==通常用于整型 因为浮点型可能存在无限循环的情况,无准确的值
7:逻辑表达式
&&和||中 如果表达式左边判断成立,则会终止计算,比如下面的例子
① int a = 10;
int b = 9;
int c;
printf("%d",a>b||(c=4)); //当a>b成立的时候,直接返回真 c=4不会被运算,所以下面打印出来的c还是0
printf("%d",c);
② int a = 10;
int b = 9;
int c;
printf("%d",a<b&&(c=4)); //当a<b成立的时候,直接返回假 c=4不会被运算,所以下面打印出来的c还是0
printf("%d",c);
逗号表达式
取逗号最后面的一个值,一般不会用这个表达式
8:位操作
unsigned char 打印的时候用%u
n1*16等同于 n1<<4
单bit操作(难点)
1):把某位设置为0(设置的是第五位)
如 181的二进制为10110101
首先我们得知道一个特殊的数字
1u <<5 为 00100000
然后对1u<<5的结果取反
为 11011111 (mask掩码)
然后让11011111 | 10110101
如下图
11011111
&
10110101
10010101(所获得的结果)
所以我们最后得出的结论为 m &= ~(u1<<n) 表示的意思为把m的第n为设置为0(n的范围为0~7)
2)把某位设置为1(设置的是第6位)
如 181的二进制为10110101
首先我们得知道一个特殊的数字
1u <<6 为 01000000
然后进行|操作
01000000
|
10110101
11110101(所得到的结果)
所以我们可以得到结论 m|=(u1<<n) 表示的意思为把m的第n为设置为1(n的范围为0~7)
3)判断某位是否为1
如 181的二进制为10110101
首先我们得知道一个特殊的数字
1u <<5 为 00100000
然后我们进行&操作
10110101
&
00100000
00100000(所得结果为真)
如果是第六位的话
10110101
&
01000000
00000000(所得结果为假)
所以我们可以得出结论
bool = m&(u1<<n) 表示的意思为 如果bool为真 则m的第n位为1 如果bool为假 则m的第n位为0
多bit操作(难点)
181的二进制为10110101 假设对bit2到bit4操作
1)清空多位为0
a &= ~(0X07 <<2)
0X07代表的是 00000111 即1*2
00000111左移二位得到 00011100
然后取反得到 11100011
然后 11100011
&
10110101
10100001
a &= ~(0X07 <<2)
2)读取2bit到4bit
先把10110101向右移两位
得到00101101
然后 00101101
&
00000111(0X07)
00000101(所得结果)
3)设置2bit到4bit都为1
a |= 0X007 <<2 具体的过程就不叙述了
设置2bit到4bit都为0
a &= 0X007 <<2 具体的过程就不叙述了