1、取值范围
-
CPU能读懂的最小单位——比特位,即bit也叫b;每个比特位只能存放二进制数0或者1
-
内存机构的最小寻址单位——字节,即Byte也叫B;则1个字节可以表示最大的数是11111111,转化成十进制就是255
约定:1Byte=8bit
而1个整型变量int有4个字节,那么取值范围就可以计算出来
有符号数signed范围:-2^31——2^31-1
要搞清楚这个问题需要清楚事实上计算机是用补码的形式来存放整数的值(无论是正数还是负数)
补码的规则:正数的补码就是该数的二进制形式
负数的补码是符号位不变,其他位取反再加1
无符号数unsigned范围:0到2的32次方减1
例:
127:0 1 1 1 1 1 1 1
...
1: 0 0 0 0 0 0 0 1
0: 0 0 0 0 0 0 0 0
-1: 1 1 1 1 1 1 1 1
-2: 1 1 1 1 1 1 1 0
...
-128:1 0 0 0 0 0 0 0
可以观察到正数越大对应的1越多,负数越小对应的0越多
数据类型 字节数 取值范围
char 1 -128-127
unsigned char 1 0-256
short 2 -2^15-2^15-1
unsign short 2 0-2^16-1
int 4 -2^31-2^31-1
unsigned int 4 0-2^32-1
long 4 -2^31-2^31-1
unsigned long 4 0-2^32-1
long long 8 -2^63-2^63-1
unsign long long 8 0-2^64-1
float 4 1.17549*10^-38~3.40282*10^38
double 8 2.22507*10^-308~1.79769*10^308
long double 12 2.22507*10^-308~1.79769*10^308
2、
-
存放signed类型的存储单元中,左边第一位表示符号位。
如果该位为0,表示该整数是一个正数;如果该位为1,表示该整数是一个负数
-
一个32位的整型变量,除去左边第一位符号位,剩下表示值得只有31个比特位
例:
#include<stdio.h>
#include<math.h>
int main()
{
int result=pow(2,32)-1;
printf("result=%d",result);
return 0;
}
计算结果不是2的32次方,溢出了,原因就是上述的(1)(2),如需正确计算将int改为unsigned int,把%d改为%u即可
3、运算符
-
C语言通过提供运算符来支持我们对数据进行处理
(此图转自B站小甲鱼)
注:(1)整数比整数采取舍弃小数;浮点型比浮点数结果有小数
(2)双目运算符表示该运算符有两个操作数
单目运算符表示该运算符有一个操作数
-
运算符的优先级:
略
-
类型转换:当两个不同类型的数据进行运算时,自动默认将坑位较小的转换成为坑位较大的
那个,结果也是坑位较大的那个类型
例:
#include<stdio.h>
int main()
{
printf("整型输出:%d\n”,1+2.0);
printf("浮点型输出:%f\n",1+2.0);
return 0;
}
这里打印的第一个会出错,因为不同类型的数据相加,把1转换成了1.0相加之后就是3.0,
而打印命令却是%d,整型的转义字符
第二个是对的
那如果非要用整型存放1+2.0的结果怎么办?
答案是:除了编译器可以自动转换操作数数据类型之外,C语言也允许强制转换操作数数据类型
如1+(int)2.0即强制把2.0转换为整型
如果是1+(int)1.8结果是2
这里对1.8的处理不是四舍五入,而是直接舍去小数
所以转换数据类型时当心损失精度!!!
4、关系运算符和逻辑运算符
-
关系运算符
<、<=、>、>=、==(等于)、!=(不等于)
关系运算符得到的值是一个逻辑值,即只有真或者假
-
逻辑运算符
优先级
!:逻辑非 高
&&:逻辑与 中
||:逻辑或 低
-
逻辑表达式
例:
#include<stdio.h>
int main()
{
int a=3,b=5;
printf("%d\n",3 >1 && 1<2);
printf("%d\n",3+1 || 2==0);
printf("%d\n",!(a+b));
printf("%d\n",!0+1<1 || !(3+4));
printf("%d\n",‘a’-'b' && 'c');--97-98&&99=1&&1=1
return 0;
}
编译结果:1 1 0 0 1
Tips:
事实上关系运算式或者逻辑表达式反馈给我们的值只有两个1或者0,但是我们告诉计算机的逻辑表达式中运算符的两侧只要是非0就可以认为是逻辑真)
注意运算优先级!!!
5、短路求值
- 短路求值又称最小化求值,是一种逻辑运算符的求值策略。
只有当第一个操作数的值无法确定逻辑运算的结果时,才对第二个操作数进行求值。
C语言对于逻辑与和逻辑或采用短路求值的方式
例:
#include<stdio.h>
int main()
{
int a=3,b=3;
(a=0)&&(b=5);
printf("a=%d,b=%d\n",a,b);
(a=1) || (b=5);
printf("a=%d,b=%d\n",a,b);
return 0;
}
编译结果:a=0,b=3
a=1,b=3
6、if语句
-
格式:
(1)
......//其他语句
if(表达式)--返回逻辑值的一个表达式,当然也可以直接填入逻辑值
{
......//逻辑值为真所执行的语句、程序块
}
......//其他语句
例:
#include<stdio.h>
int main()
{
int i;
printf("您老贵庚啊?\n");--这里为了美观,明了加首行缩进Tab
scanf("%d",&i);
if(i>=18) --{}可有可无,但为了避免逻辑混乱加上
{
printf("进门左拐!\n");
}
return 0;
}
(2)
......//其他语句
if(表达式)
{
......//逻辑表达式为真所执行的语句、程序块
}
else
{
...//逻辑值为假所执行的语句、程序块
}
......//其他语句
例:
#include<stdio.h>
int main()
{
int i;
printf("您老贵庚啊?\n");
scanf("%d",&i);
if(i>=18)
{
printf("进门左拐!\n");
}
else
{
printf("本站禁止未成年人进入!\n");
}
return 0;
}
(3)
......//其他语句
if(表达式1){......}
else if(表达式2){......}
else if(表达式3){......}
...
ese if(表达式n){......}
else{......}
......//其他语句
7、switch语句
-
格式:
......//其他语句
switch(表达式) --表达式跟case语句的表达式相匹配,符合哪一个跳转至哪一个
{
case 常量表达式:语句或程序块1;break;
case 常量表达式:语句或程序块1;break;
......
case 常量表达式:语句或程序块;break;
default: 语句或程序块n+1;break; --如果没有匹配的case语句,也没有default则该switch语句不会做任何动作
}
......//其他语句
8、分支结构的嵌套--就是if里面套if
例:比较输入两个数的大小关系
#include<stdio.h>
int main()
{
int a,b;
printf("请输入a和b的值:\n");
scanf("%d %d",&a,&b);
if(a!=b)
{
if(a>b)
{
printf("%d>%d\n",a,b);
}
else
{
printf("%d<%d\n",a,b);
}
}
else
{
printf("%d=%d\n",a,b);
}
return 0;
}