1.实型(浮点型):float 单精度 4字节、double 双精度 8字节
① 实型常量
-
void
fun1()
-
{
-
// 实型常量
-
// 不以F结尾的实型常量,为double类型
-
printf(
"sizeof(3.14) = %u\n"
,
sizeof
(3.14));
// double
-
// 以F结尾的为float类型
-
printf(
"sizeof(3.14F) = %u\n"
,
sizeof
(3.14F));
// float
-
}
② 实型变量
-
void
fun2()
-
{
-
// 赋值语句,尽量保证 = 两边类型匹配
-
float
F = 0.0F;
-
double
D = 0.0;
-
printf(
"F = %f\n"
, F);
-
printf(
"D = %lf\n"
, D);
-
// 获取键盘输入
-
scanf(
"%f"
, &F);
-
printf(
"F = %f\n"
, F);
-
scanf(
"%lf"
, &D);
-
printf(
"D = %lf\n"
, D);
-
}
③ 实型存储
2.二进制、八进制、十进制、十六进制的转换
①
十进制转二进制、八进制、十六进制
方法:短除法
②
二进制、八进制、十六进制转十进制
方法:进制的位次方
例: 1100 1100 → 1*2^7+1*2^6+0*2^5+0*2^4+1*2^3+1*2^2+0*2^1+0*2^0
=128+64+0+0+8+4+0+0=204
0123 → 1*8^2+2*8^1+3*8^0=64+16+3=83
0x12 → 1*16^1+2*16^0=16+2=18
③
二进制转八进制、十六进制
a、二进制转八进制:二进制
从右往左,每
三位二进制对应
一位八进制
1100 1100 → 011 001 100 → 314
b、二进制转十六进制:二进制
从右往左,每
四位二进制对应
一位十六进制
1100 1110 → 12 14 → 0xCE
④
八进制、十六进制转二进制
a、八进制转二进制:八进制
从右往左,每
一
位八进制对应
三
位二进制
0567 → 101 110 111 → 1 0111 0111
b、十六进制转二进制:十六进制
从右往左,每
一
位十六进制对应
四
位二进制
0xAB → 1010 1011
一位16进制数占1字节空间
3.数值在计算机中的存取方式
① 存(任何数据在计算机存放的都是
补码)
数据的表现形式(原码、反码、补码)
a、原码:数据本身的二进制
无符号数:
15 原码 → 0000 1111
有符号数:
正数:+15 原码 →
0000 1111
负数:- 15 原码 →
1000 1111
b、反码:
无符号数:反码 = 原码
15 反码 → 0000 1111
有符号数:
正数:反码 = 原码
+15 原码 →
0000 1111
负数:
符号位不变,其他位取反
- 15 原码 →
1111 0000
c、补码:
无符号数:补码 = 原码
15 补码 → 0000 1111
有符号数:
正数:补码 = 原码
+15 原码 →
0000 1111
负数:反码
+1
- 15 原码 →
1111 0001
综上所述:
无符号数及有符号正数,计算机存放的是原码(=补码=反码)
有符号负数,计算机存放的是补码
① 取(
类型不匹配,按变量原符号输出)
a、有符号取 %d %ld %lld %f %lf
步骤:先看最高位(符号位)是否是1?
如果是1,表示该数是一个负数的补码,符号位不变,其他取反,+1
补码的补码为原码
如果是0,表示该数是一个正数的补码,原样输出
b、无符号取 %u %lu %llu %o %x
步骤:内存数据原样输出
-
void
fun3()
-
{
-
int
num = -15;
-
// 1000 1111 原码
-
// 1111 0000 反码
-
// 1111 0001 补码
-
printf(
"signed int:%d\n"
, num);
// 有符号取 -15
-
printf(
"unsiged int:%u\n"
, num);
// 无符号取 241(不对,int32位)
-
char
num2 = -15;
-
printf(
"signed char:%d\n"
, num2);
// 有符号取 -15
-
printf(
"unsiged char:%u\n"
, num2&0x00ff);
// 无符号取 241(不对,%u取32位不足补1)
-
unsigned
char
num1 = 0xff;
-
printf(
"num1 = %x\n"
, num1);
-
printf(
"num1 = %d\n"
, num1);
-
printf(
"num1 = %u\n"
, num1);
-
printf(
"num1 = %d\n"
, (
char
)num1);
-
}
补码的意义
① 统一了领的编码
② 将符号位和其他位统一处理
③ 将减法运算转换为加法运算
④ 两个用补码表示的数相加时,如果最高位(符号位)有进位则被舍弃
十六进制原样存取
-
void
fun4()
-
{
-
char
num = 0x9b;
// 1001 1011
-
printf(
"signed char:%d\n"
, num);
-
// 1001 1011 → 1110 0100 → 1110 0101 →
-
// 1*2^6+1*2^5+1*2^2+1*2^0=64+32+4+1= -101
-
printf(
"unsiged char:%x\n"
, num);
-
printf(
"unsiged char:%x\n"
, num&0x00ff);
-
}
数据的溢出
-
void
fun5()
-
{
-
char
num = 0xfe + 3;
-
// 1111 1110 + 0000 0011
-
// 计算机存储 1 0000 0001
-
printf(
"signed num = %d\n"
, num);
-
printf(
"unsigned num = %u\n"
, num &= 0x00ff);
-
printf(
"unsigned num(16) = %#x\n"
, num);
-
}
4.char的取值范围
char为例,说明有符号数、无符号数之间的范围
signed char →
1111 1111 ~
1000 0000 -127~
-0
0000 0000 ~ 0111 1111
+0 ~ 127
将-0直接定义为-128(1 0000 0000), signed char → -128~127
-
void
fun06()
-
{
-
char
num = 0x80;
// 1000 000 -127
-
printf(
"%d\n"
, num);
-
}
unsigned char → 0000 0000 ~ 1111 1111 0 ~ 255
signed\unsigned
char表示256个数(空间范围相同)
5.特殊的限定符关键字 → const extern register volatile
① const 只读变量,修饰变量为只读,不可被修改,
必须初始化(gcc随机值)
-
void
fun7()
-
{
-
// num只读变量,本质是变量,只是无法被赋值(写)
-
const
int
num = 10;
-
//num = 100;// error
-
printf(
"num = %d\n"
, num);
-
}
② register 寄存器变量,编译器
尽可能将修饰变量放入寄存器中,如果失败将存放在内存中
禁止对修饰变量
取地址操作,
&地址操作针对内存而言
-
void
fun8()
-
{
-
register
int
num = 10;
-
num = 15;
-
printf(
"num = %d\n"
, num);
-
//printf("num = %p\n", &num);// error
-
}
③ volatile 防止编译器优化,强制访问内存,修饰变量禁止存入寄存器,禁止编译器忽略编译(逐条编译修饰变量)
6.字符串常量
① 由一个或多个字符组成,且以字符
'\0'结尾(编译器自动添加的结尾标记),双引号“”作用(字符串类型说明,
取地址)
② '\0'作用:
a、字符串遍历:%s输出字符串,必须给定输出
首地址,遇到'\0'结束输出
-
void
fun9()
-
{
-
// 字符串常量
-
printf(
"sizeof(%s) = %u\n"
,
"hello world"
,
sizeof
(
"hello world"
));
// 12
-
// "hello world" 告诉编译器是字符串,取字符串首元素地址
-
printf(
"%%s = %s\n%%u = %u\n%%s+1 = %s\n"
,
"hello world"
,
"hello world"
,
"hello world"
+1);
// "hello world"-1 访问非法内存,结果未知
-
// 'A' 告诉编译器是字符,取ASCII码值
-
printf(
"%%c = %c\n%%d = %d\n%%c+1 = %c\n"
,
'A'
,
'A'
,
'A'
+1);
-
// %s遇到反'\0'结束
-
printf(
"%s\n"
,
"hello\0world"
);
// hello
-
printf(
"%s\n"
,
"\0hello\0world"
);
//
-
}
7.putchar( ) getchar( ) 区别
① getchar( ) 获取键盘缓冲区的一个字符,带阻塞
-
void
fun10()
-
{
-
printf(
"请输入一个字符:\n"
);
-
char
ch = 0;
// 0 == '\0'
-
ch = getchar();
// 获取的字符通过返回值返回
-
printf(
"ch = %c\n"
, ch);
-
getchar();
// 无变量接返回值丢弃
-
ch = getchar();
-
printf(
"ch = %c\n"
, ch);
-
}
② putchar('ch'/ASCII) 输出一个字符/ASCII码值
-
void
fun11()
-
{
-
printf(
"%c\n"
,
'a'
);
-
putchar(
'a'
);
-
putchar(
'\n'
);
-
putchar(97);
-
putchar(
'\n'
);
-
putchar(200);
// 不确定
-
}
8.printf( ) 输出格式补充 %md %0md %-md %m.nf
-
void
fun12()
-
{
-
// %md m表示所占终端的显示位宽,默认右对齐
-
printf(
"#############\n"
);
-
printf(
"##%5d##\n"
, 123);
-
printf(
"##%2d##\n"
, 123);
// 小于数据长度,原样输出
-
// %0md 空出的位置补0
-
printf(
"##%05d##\n"
, 123);
-
// %-md 左对齐
-
printf(
"##%-5d##\n"
, 123);
-
// - 和 0 不可同时使用,%-0md不会补0
-
// %m.nf m表示显示位宽,n表示小数显示位数,自动四舍五入
-
printf(
"##%6.2f##\n"
, 1.236F);
-
}
9.算数运算符 / 取整 % 取余 ++ 自加 -- 自减
① / %
-
void
fun13()
-
{
-
// / 取整
-
printf(
"1/2 = %d\n5/2 = %d\n"
, 1 / 2, 5 / 2);
-
// % 取余数 判断一个数能否被另一个数整除
-
printf(
"1%%2 = %d\n5%%2 = %d\n"
, 1 % 2, 5 % 2);
-
if
(5 % 2 == 0)
-
{
-
printf(
"5被2整除\n"
);
-
}
-
else
-
{
-
printf(
"5不被2整除\n"
);
-
}
-
// 将num的每位数字单独输出
-
int
num = 1234;
-
printf(
"%d,%d,%d,%d\n"
, num / 1000, num / 100 % 10, num / 10 % 10, num % 10);
-
printf(
"%d,%d,%d,%d\n"
, num / 1000, num % 1000 / 100, num % 100 / 10, num % 10);
-
}
① ++ --
a、作为独立语句时,i++与++i效果一致
-
void
fun14()
-
{
-
int
i = 10;
-
i++;
// i=i+1
-
printf(
"i = %d\n"
, i);
-
int
j = 10;
-
++j;
// i=j+1
-
printf(
"j = %d\n"
, j);
-
int
k = 10;
-
k--;
// k=k-1
-
printf(
"k = %d\n"
, k);
-
int
h = 10;
-
--h;
// h=h-1
-
printf(
"h = %d\n"
, h);
-
// ++ -- 作为独立语句时,i++与++i效果一致
-
}
b、非独立语句时,在变量右边i++:先使用后自增/减,在变量左边++i:先自增/减在使用
-
void
fun15()
-
{
-
int
i = 10;
-
int
j = 0;
-
int
k = 0;
-
j = i++;
// j=i; i=i+1;
-
// i=11,j=10
-
k = ++i;
// i=i+1; j=i;
-
// i=12,k=12
-
printf(
"i = %d, j = %d, k = %d\n"
, i, j, k);
-
}
10.赋值运算符 = += -= *= /= %=
① 将=右边的值,赋值给=左边
左值:能被写操作,
能在=左边,也可在右边
右值:不能在=左边的值,
只能在=右边
-
void
fun16()
-
{
-
int
num = 0;
// num左值
-
num = 100;
// 100为右值
-
const
int
data = 10;
// data为右值
-
int
num2 = 0;
-
num2 = num;
// num2,num都为左值
-
}
② [+= -= *= /= %= ]中=右边为一个整体
a+=b+c → a=a+(b+c)
-
void
fun17()
-
{
-
int
num = 10;
-
num *= 3 + 5;
// num = num*(3+5)
-
printf(
"num = %d\n"
, num);
-
}
11.关系运算符
关系运算符为双目运算符,其结合性均为左结合
当条件成立时结果为1,条件不成立结果为0
12.逻辑运算符
“真”对应的值为1,“假”对应的值为0
a、! 逻辑非
-
void
fun18()
-
{
-
printf(
"!0 = %d\n"
, !0);
-
printf(
"!1 = %d\n"
, !1);
-
printf(
"!100 = %d\n"
, !100);
-
printf(
"!-100 = %d\n"
, !-100);
-
}
b、&& 逻辑与 A&&B AB同真为真,
当A为真才会判断B表达式
-
fun19()
-
{
-
printf(
"3 > 4 && 5 < 3, %d\n"
, 3 > 4 && 5 < 3);
-
printf(
"3 < 4 && 5 < 3, %d\n"
, 3 < 4 && 5 < 3);
-
printf(
"3 < 4 && 5 > 3, %d\n"
, 3 < 4 && 5 > 3);
-
4 < 3 && printf(
"one\n"
);
-
4 > 3 && printf(
"two\n"
);
-
}