Day3-数据类型

数据类型:

C是有类型的语言,C语言的变量,必须:在使用前定义,并且要确定类型

C以后的语言向两个方向发展:

  • C++/Java更强调类型,对类型的检查更严格;
  • JavaScript、Python、PHP不看重类型,甚至不需要事先定义

C语言的数据类型:

  • 整数:char、short、 int、long、long long(划线的是是C99的类型)
  • 浮点数:float、double、long double
  • 逻辑:bool
  • 指针
  • 自定义类型

类型有何不同:

  •  类型名称:int、long、double
  •  输入输出时的格式化:%d、%ld、%lf
  •  所表达的数的范围:char < short < int < float <double
  •  内存中所占据的大小:1个字节到16个字节
  •  内存中的表达形式:二进制数(补码)、编码

sizeof是一个运算符,给出某个类型或变量在内存中所占的字节数

用法如:sizeof(int)   sizeof(i)

注意:sizeof是静态运算符,它的结果在编译时刻就决定了,而且,不要在sizeof的括号里做运算,这些运算不会做的,它只会给出括号内数据在内存所占的字节数

  •  char: 1字节(8比特).
  •  short: 2字节
  •  int:取决于编译器(CPU) ,通常的意义是"1个字”
  •  long:取决于编译器(CPU),通常的意义是"1个字”
  •  long long: 8字节

 

整数在计算机内部的表达:计算机内部一切都是二进制。

1个字节可以表达的数:00000000-11111111(0-255)

二进制的负数如何表达?

三种方案:1.仿照十进制,有一个特殊的标志表示负数  2.取中间的数为0,如1000000表示0,比它小的是负数,比它大的是正数  3.补码

补码:补码的意义就是补码和原码可以加出一个溢出的“零“。

因为0-1=-1,(1)00000000-00000001=11111111,因此11111111被当作纯二进制看待是255,被当作补码看待是-1.

同理,对于-a,它的补码就是0-a,实际是,n是这种类型的位数

数的范围:

对于一个字节(8位,比如char),可以表达的是:00000000 - 11111111

其中: 00000000—>0,

11111111 ~10000000—> -1~ -128

00000001 ~01111111—> 1~127

unsigned

如果一个自变量常数想要表达自己是unsigned,可以在后面加u或U,如255U。同理,如果一个自变量常数想要表达自己是long,用l或L表示long(long)。

unsigned的初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是为了移位

Unsigned数字只有0和正整数部分。

整数越界

整数是以纯二进制方式进行计算的,所以∶

  • 11111111+1—>100000000—> 0
  • 01111111+1—>10000000—>-128
  • 10000000 - 1—>01111111—>127

 

整数的输入输出

只有两种形式: int或long long

%d: int

%u: unsigned.

%ld: long long

%lu : unsigned long long

8进制和16进制

  • 一个以O开始的数字字面量是8进制
  •  一个以Ox开始的数字字面量是16进制。
  •  %o用于8进制,%x用于16进制
  •  8进制和16进制只是如何把数字表达为字符串,与内部如何表达数字无关
  •  16进制很适合表达二进制数据,因为4位二进制正好是一个16进制位
  •  8进制的一位数字正好表达3位二进制
  •  因为早期计算机的字长是12的倍数,而非8

选择整数类型

为什么整数要有那么多种?

为了准确表达内存,做底层程序的需要。现在,没有特殊需要,就选择int

·现在的CPU的字长普遍是32位或64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢

现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小(虽然sizeof告诉你更小)

 unsigned与否只是输出的不同,内部计算是一样的

浮点数

  • float字长32范围有效数字7,scanf中用%f,printf中用%f,%e,占4个字节(32位)
  • double字长64范围有效数字15, scanf中用%lf,printf中用%f,%e(%e是指科学计数法),占8个字节(64位)
  • printf输出inf表示超过范围的浮点数:
  • printf输出nan表示不存在的浮点数
  • 带小数点的字面量是double而非float
  • float需要用f或F后缀来表明身份
  • 两个浮点数如果直接用 f1 == f2,可能是失败的。可以用fabs(f1-f2)<1e-12
  • 选择浮点类型:如果没有特殊需要,只使用double。现代CPU能直接对double做硬件运算,性能不会比float差,在64位的机器上,数据存储的速度也不比float慢。

字符类型

char是一种整数,也是一种特殊的类型:字符。这是因为:

·用单引号表示的字符字面量:'a', '1'

·’’也是一个字符

printf和scanf里用%c来输入输出字符

输出精度

在%和f之间加上.n可以指定输出小数点后几位,这样的输出是做4舍5入的

printf("%.3fn",-0.0049);

printf("%.30fn"-0.0049);

printf("%.3f\n",-0.00049);

字符计算:

一个字符加一个数字得到ASCII码表中那个数之后的字符

两个字符的减,得到它们在表中的距离

大小写转换:

字母在ASCII表中是顺序排列的

大写字母和小写字母是分开排列的,并不在一起

'a'-'A'可以得到两段之间的距离,于是a+'a'-'A"可以把一个大写字母变成小写字母,而a+'A'-'a'可以把一个小写字母变成大写字母

逃逸字符(转义字符):

用来表达无法印出来的控制字符或特殊字符,它由一个反斜杠“\”开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符

自动类型转换:

当运算符的两边出现不一致的类型时,会自动转换成较大的类型

大的意思是能表达的数的范围更大

char -> short —> int —> long -> long long.

int —> float—> double

对于printf,任何小于int的类型会被转换成int;float会被转换成double

但是scanf不会,要输入short,需要%hd

强制类型转换:

要把一个量强制转换成另一个类型(通常是较小的类型),需要:(类型)值

比如:(int)10.2,(short)32

注意:这时候的安全性,小的变量不总能表达大的量:(short)32768

注意:只是从那个变量计算出了一个新的类型的值,它并不改变那个变量,无论是值,还是类型都不改变。

强制类型转换的优先级比四则运算(加减乘除)高。

布尔类型:bool

#include<stdbool.h>,之后就可以用bool、true和false。

逻辑运算:

逻辑运算是对逻辑量进行的运算,结果只有0或1.逻辑量是关系运算或逻辑运算的结果。

逻辑运算符:!(非)、&&(与)、||(或)

优先级: !>&&>||

逻辑短路:逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算。比如:a==6 && b==1 、-a==6 && b+=1

  • 对于&&,左边是false时就不做右边了
  • 对于||,左边是true时就不做右边了

条件运算:条件、条件满足时的值和条件不满足时的值

比如:count = (count>20)?count-10:count+10

优先级高于赋值运算符,但是低于其他运算符。

条件运算符是自右向左结合的。

逗号运算:逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。逗号的优先级是所有的运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。

比如:i = (3+4,5+6)   输出i =11

i = 3+4,5+6    输出i = 7

一般在for循环中使用,如for (i=0,j=0;i<j;i++,j++)

进制转换

二进制

八进制

十进制

十六进制

posted @ 2020-12-19 17:34  Akihiii  阅读(125)  评论(0)    收藏  举报