文章目录
- c语言的类型
- 整数
- 整数类型
- 整数的内部表达
- 整数的范围
- unsigned
- 整数的格式化
- 浮点型
- 浮点类型
- 输入输出
- 输出精度
- 字符类型
- 逃逸字符
- 类型转换
- 自动类型转换
- 强制类型转换
- 逻辑类型bool
- 逻辑运算
- 条件运算符
C语言的变量,必须在使用前定义,并且确定类型;
C+ +/Java更强调类型,对类型的检查更严格;
JavaScript、 Python、PHP不看重类型,甚至不需要事先定义。
c语言的类型
C语言的类型
① 整数:char、short、int、long、longlong
② 浮点数:float、double、long double
③ 逻辑:bool
④ 指针
⑤ 自定义类型
类型有何不同
① 类型名称:int、long、double
② 输入输出时的格式化:%d、%ld、%lf
③ 所表达的数的范围:char < short < int < float < double
④ 内存中所占据的大小:1个字节到16个字节
⑤ 内存中的表达形式:二进制(补码)、编码
sizeof
① 是一个运算符,得到某个类型或变量在内存中所占据的字节数,eg:sizeof(int),sizeof(i);
② 是静态运算符,它的结果在编译时刻就决定了;
③ 不能在sizeof的括号里做运算,这些运算不会执行。
整数
整数类型
① char:1字节(8比特)
② short:2字节(16比特)
③ int:取决于编译器(CPU),通常的意义是“1个字”,如:4字节(64位编译器),8字节(32位编译器)
④ long:取决于编译器(CPU),通常的意义是“1个字”,如:4字节(64位编译器),4字节(32位编译器)
⑤ long long:8字节
整数的内部表达
计算机内部一切都是二进制。
1个字节可以表达的数:
00000000–11111111(0–255)
1字节(byte)=8比特(bit)
整数的范围
char:1字节:-128~127
short:2字节:-32768~32767
int:取决于编译器(CPU),通常的意义是“1个字”
long:4字节
long long:8字节
unsigned
如果一个字面量常数想要表达自己是unsigned,可以在后面加u或U,eg:255U;
用|或L表示long(long),*unsigned的初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是为了移位。
整数的格式化
整数的输入输出只有两种形式:int或long long
%d:int
%u:unsigned
%ld:long long
%lu:unsigned long long
8进制和16进制:
一个以0开始的数字字面量是8进制;
一个以0x开始的数字字面量是16进制;
%o用于8进制,%x用于16进制;
8进制和16进制只是如何把数字表达为字符串,与内部如何表达数字无关。
char c=012;
int i=0x12;
int j=0x1A;
printf("c=%d,i=%d\n",c,i);
printf("c=%o,i=%x\n",c,i);
printf("c=0%o,i=0x%x\n",c,i);
printf("c=0%o,i=0x%X\n",c,i);//小写的x输出小写的a,大写的X输出大写的A
输出:
c=10,i=18
c=12,i=12
c=012,i=0x12
c=012,i=0x1A
选择整数类型
① 为什么整数要有那么多种?
为了准确表达内存,做底层程序的需要
② 没有特殊需要,就选择int
a.现在的CPU的字长普遍是32位或64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢;
b.现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小(虽然sizeof告诉你更小)
③ unsigned与否只是输出的不同,内部计算是一 样的。
浮点型
浮点类型
注意:趋近于0有一段范围是无法输入输出的。
带小数点的字面量是double而非float
float需要用f或F后缀来表明身份
输入输出
%e表示用科学计数法输出:
输出精度
在%和f之间加上.n可以指定输出小数点后几位,这样的输出是做4舍5入的
printf("%.3f\n", -0.0049);
printf(%.30fIn", -0.0049);
printf("%.3f\n", -0.00049);
输出:
-0.005
-0.004899……(输出小数点后30位)
-0.000
选择浮点类型:
如果没有特殊需要,只使用double;
现代CPU能直接对double做硬件运算,性能不会比float差,在64位的机器上,数据存储的速度也不比float慢。
字符类型
char是一种整数,也是一种特殊的类型:字符。
这是因为:
用单引号表示的字符字面量:‘a’,‘1’,"也是一个字符;
printf和scanf里用%c来输入输出字符。
char c;
scanf("%c",&c);
printf("c=%d\n",c);
printf("c='%c'\n",c);
输入:1
输出:
c=49
c='1'
int i;
char c;
scanf("%d",&i);
c=i;
printf("c=%d\n",c);
printf("c='%c'\n",c);
输入:49
输出:
c=49
c='1'
'1'的ASCII编码是49,所以当c==49时,它代表'1'
注意:
空格也是符号。
//两个的输出会不相同
scanf("%d %c",&i,&c);//读完整数一起把后面空格读了,再读字符
scanf("%d%c",&i,&c);//如果中间有空格,则第二个输出的是空格而不是后面的字符
字符计算:
一个字符加一个数字得到ASCII码表中那个数之后的字符;
两个字符的减,得到它们在表中的距离。
大小写转换:
字母在ASCII表中是顺序排列的;
大写字母和小写字母是分开排列的,并不在一起;
‘a’-'A’可以得到两段之间的距离,于是
a+‘a’-'A’可以把一个大写字母变成小写字母
a+‘A’-'a’可以把一个小写字母变成大写字母
逃逸字符
用来表达无法印出来的控制字符或特殊字符,它由一个反斜杠“\”开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符。
双引号里面不能直接出现双引号。
printf("收到请回复,""回复"1"表示同意");
//这样表示有三段分开的双引号
输出:收到请回复,回复1表示同意
printf("收到请回复,""回复\"1\"表示同意");
//加上\表示前面一段双引号,后面一段双引号的中间包含一段双引号
输出:收到请回复,回复"1"表示同意
制表位
一个\t使得输出从下一个制表位开始;
用\t才能使得上下两行对齐。
printf("123\t456"\n);;
printf("12\t3456"\n);
输出:
123 456
12 3456
类型转换
自动类型转换
当运算符的两边出现不一致的类型时, 会自动转换成能表达的数的范围更大的类型:
char-> short-> int-> long-> long long
int-> float-> double
注意:
对于printf, 任何小于int的类型(char,short)会被转换成int;float会被转换成double。
但是scanf不会,要输入short,需要%hd……
强制类型转换
要把一个量强制转换成另一个类型(通常是较小的类型),需要:(类型)值
(int)10.2
(short)32
注意这时候的安全性,小的变量不能表达大于它范围的量。
eg:(short)32768,short类型能表示的最大值是32767.
强制类型转换只是从那个变量计算出了一个新的类型的值,它并不改变那个变量,无论是值还是类型都不改变。
强制类型转换的优先级高于四则运算
int a=5;
int b=6;
double d=(double)(a/b);
逻辑类型bool
添加头文件#include<stdbool.h>
之后就可以使用bool和true、false
#include<stdio.h>
#include<stdbool.h>
int main(){
bool a=6>5;
bool b=6<5;
bool c=true;
bool d=false;
bool e=0;
bool f=5;//非零输出1
printf("%d %d\n%d %d\n%d %d",a,b,c,d,e,f);
return 0;
}
输出:
1 0
1 0
0 1
逻辑运算
逻辑运算是对逻辑量进行的运算,结果只有0或1;
逻辑量是关系运算或逻辑运算的结果。
短路:
逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算。
对于&&,左边是false时就不做右边了
对于||,左边是true时就不做右边了
int a=6;
if(a>7&&a++>9){//对于&&,左边false不成立了就不执行右边了
printf("OK\n");
}
if(a<7||a++>9){//对于||,左边true成立了就不执行右边了
printf("OK\n");
}
不要把赋值,包括复合赋值组合进表达式。
条件运算符
条件 ? 条件满足时的值 : 条件不满足时的值
x=(a>b)?a-1:0 //x的值在a>b时=a-1,否则=0
if(a>b)
x=a-1;
else
x=0;