我是靠谱客的博主 平淡麦片,最近开发中收集的这篇文章主要介绍数据类型 ASCII,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

数据类型

0.问题的引入
我们知道计算机是人类用来解决某些问题的一种工具
那么计算机是通过什么来解决问题的呢?
计算机是解决哪一类的问题?“计算” computer

计算机通过把问题域的数据保存起来,然后通过某些运算从而得到结果。

程序=算法+数据结构

计算机首先要解决数据保存的问题,在数据保存之前,我们首先要知道
这个数据的大小、取值范围、...等等数据的属性,不然我们怎么知道开辟
多大的空间保存这些数据呢?

数据的大小、取值范围...这些数据的属性,都是我们“数据类型”要讨论的问题	
1.数据类型
就是数据的类型。 typeof(x) ==>求对象x的类型 
	typeof(3)   ===> int 
	typeof(3.0) ===> double
	...
在C语言,有如下类型:
1)基本类型:c语言已经为我们定义好的类型。
	系统分配给基本类型的变量的内存大小是固定的。
	主要用来保存数(整数/浮点数)
	整数类型
		char/unsigned char 
		short/unsigned short 
		int /unsigned int 
		long/unsigned long 
		...
		上面这些基本都是用来保存整数的,有什么区别呢?
		a.signed/unsigned
			有符号(signed):符号位(最高位)+数值位
								1 -> 负数
								0 -> 0或者整数
			无符号(unsigned):数值位
		b.char /short /int ...
			所占的空间大小不一样
			char->8bits
			unsigned char->8bits 
				unsigned char 能保存的数值的范围是[0,255]
				unsigned char a = 260;//256 1111 1111 0000 0100 
				a ?4
			short:一般16bits
			
			int:32bits的机器下,一般为32bits
			long:32bits的机器下,一般也为32bits
			...
			而且在不同的编译器,同一个类型的范围也不一样
			如:
			keil 
				int 16bits 
			ubuntu 18.04 32bits
				int 32bits 
			
			sizeof(x)求类型x的所占的字节数
			sizeof(char)=1 8bits 
			
			sizeof(long)>=sizeof(int)>=sizeof(short)>=sizeof(char)
			
		在GCC编译器,整数默认类型是int 
		typeof(3) ==> int 
		
		int a;
		typeof(a)==>int 
		typeof(3+4)==>int 
		
		typeof(3+1.0)==>double 
		"自动向高精度转”==>“自动向所占空间大的转”
		
	浮点数 
		float :单精度浮点数
		double:双精度浮点数
		long double:长双精度浮点数
		
		区别?
			所占的空间大小不一样,保存精度也不一样
			一般来说:
			sizeof(float) == 4
			sizeof(double) == 8
			
			C语言中,浮点数默认类型就是double
			typeof(2.0)==>double 
			sizeof(2.0f)==>float
			typeof(2.0+4)==>double 
					
2)构造类型:C语言允许程序自定义类型
	系统分配给构造类型的变量的内存大小,决定改类型具体是怎么定义的。
	数组:一组相同元素的数据集合
	int a[10];//定义了一个数组,数组名为a,里面有10个int元素
	int b[100];//定义了一个数组,数组名为b,里面有100个int元素
		
		typeof(a) 数组  
		a是一个里面包含10个int元素的数组
		==>int[10]
		typeof(a)==>int[10]
		
		typeof(b)
		b是一个里面包含100个int元素的数组
		==>int[100]
		typeof(b) => int[100]
		
		int c;
		c是一个int类型的
		typeof(c) => int 
	结构体
	联合体
	枚举
	
3)指针类型
	先等等 后面会专门讲
	
4)void类型
	void在C语言中,有三个作用
	a.void*
		通用指针
	
	b.void当作是函数的形参,表示该函数不需要带参数
	如:
	int func(void)
	{
	}
	调用func();
	c.void当作是函数的返回值类型,表示该函数无返回值。
	如:
	void abs(int a)
	{
	
	}
	调用abc:
	int x=abc(3);//有问题的!!!!

在研究了数据类型后,下面要保存数据啦。
在C语言中数据有两类:
1)变量
2)常量

2.变量
	变量是什么?在程序运行期间,可以改变其值的数据对象。
	存储变量会对应一个储存单元。
	并且这个储存单元一定是可写(我们要改变这个变量的值)
	
	2.1变量的定义
	变量在使用前必须要定义的。
	语法:
	变量的类型 变量名 {=变量的初始值};
	 {}可选
	 变量的类型:
		所有的合法的类型都可以。
	变量名:
		一个对象的名字,标识符。
		标识符:用来表示一个东东的符号。
		标识符其实是一个对象(“如:数组 变量 函数 标号 类型 ...”)
		的名字。
		在C语言中,取名字不能乱取。要复合一定的规则,这个规则标识符的规则
		标识符:
			只能以字母,下划线,数字组成
			第一个字符不能以数字开头
			why?
			标识符 “名如其意”
			
			int sum;
			int he;
			int sum_array;
			int he_shuzu;
		
	变量的初始值:
		定义变量时,赋值给变量的值,初始值。
		
	例子:
		int a;
		printf("%dn",a);//程序的输出结果是多少?undefine
	
	2.2 变量的属性
	变量的类型 
	变量的名 
	变量的存储单元(变量的地址)
		在程序运行时,系统会为每一个变量分配一个储存空间,用来
		保存这个变量的值。并且这个储存空间会有一个唯一的地址,
		这个地址,称之为变量的地址。
		
	变量的值:
		变量的存储单元中的内容(无非就是高电平/低电平)
		每个变量一定会有一个确定的值(不管你有没有赋值)
		why?因为储存单元中 bit要是1/0
		
		bit 计算中存储数据最小的单位,它只有两种状态
		1-->高电平
		0-->低电平
		
	2.3变量的访问
		读/写 
		读:
			从变量的存储单元中读取存储单元中的内容。
			读变量的值。
		写:
			把一个数值写到变量所对应的储存单元中去。
			“赋值”
		例子:
			int a = 5;
			
			a=1024;//把1024这个值写到变量a所对应的地址中去。 【1】
			b=a*5;//把a的值乘以5,赋值给b                    【2】
			
			上面1和2同样是一个a,但是它们的含义却是不一样的!!!!
			结论:
				在C语言中,任何变量,都有且仅有两层含义:
				1)代表变量的地址
				lvalue
				location value 可寻址(可写)的值
				left value 左值
				2)代表变量的值
				 rvlaue
				 readable value 可读的值
				 right value 右值
				 
			变量的左值:
				变量的地址,“=”的左边
			变量的右值:
				变量的值,“=”的右边
				
3.整数的存储问题
	整数在计算机是如何存放的呢?
		整数以二进制的补码的形式存放的。
		
	课后:你们知道计算机中为什么要用补码?
	
	1111 1111 2^8-1 
	2^7 +....      2^1 2^0
	正数
		正数的补码就是其原码本身
		原码:就是把相应的数值转换为二进制。
		13:8bits
			13 = 8+4+1
			0000 1101 <----13的原码 也是13的补码
		
		9:8bits
			9=8+1
			0000 1001 <---9的原码 也是9的补码
		正数的补码其原码本身
		int a=9;
		00000000 00000000 00000000 00001001
		
	负数:
		负数的补码是其绝对值的原码 取反 +1 得到
		
		-13 bits 
		|-13|=13 原码 
		0000 1101 <----绝对值的原码
		1111 0010 <----取反
		1111 0011 <--- -13(8bits)的补码 -13在计算中的存储形式 8bits
		
	练习:
		假设 8bits来存放一个整数 
		-2 的存放形式什么?
		254的存放形式是什么?		
		1111 1110
		
		-3的存放形式是什么?
		253的存放形式是什么?
		1111 1101
		
		-4的存放形式是什么?
		252的存放形式是什么?
		
		... 
		直到你们找到规律或者下课为止
	
		结论1:
			一个负整数会和一个比较大的正整数的补码形式一样的;
			一个负整数会和一个比较大的正整数在计算机中存放的形式一样的。
			-x 和 2^n-x 一样的
				2^n 表示2的n次幂
				n表示什么意思?用多少Bits来存储一个整数!!!
				
				n=8
				-37 和256-37
				
		结论2:
			CPU内部是没有符号位的概念,对于CPU来说,所有的Bit位
			都是数值位,都参与运算。至于是由符号的,还是无符号数
			就得看编译器的词义啦(意思就是说,你把它当做是一个有
			符号数,还是无符号数)。
			
		练习:假设int 32bits
		1)假设计算机中用8bits来存放一个整数,已知某个整数
		在计算机中的存放形式如下:
		1111 1110
		请问这个整数使多少?
		-2 或者 254
		到底是-2还是254
		就得看你把它当做是一个有符号(signed)还是一个无符号数(unsigned)
		unsigned :
		1111 1110 
		所有的Bits位都是数值位
		254
		signed:
		符号位 数值位
		1->负数
		0->正数
		1111 1110
		
		最高位是1,表示它是一个负数
			1111 1110是负数的补码
			已知一个负数的补码,如何求这个负数呢?
				绝对值的原码->取反->+1 ==>负数的补码
				
			逆运算
			负数的补码-->-1-->取反-->绝对值原码
			
			1111 1110
			-1
			1111 1101
			取反
			0000 0010
			该负数的绝对值是2
			==>该负数是-2				
			
		2)分析如下程序的输出结果
			int a=-2;
			printf("%dn",a);//-2
			printf("%un",a);//2^32-2
				%d把后面的玩意,当做一个有符号的int,按十进制输出
				%u把后面的玩意,当做一个无符号的int,按十进制输出
		3)分析如下程序的输出结果	
			int a=-56;
			printf("%dn",a);//-56
			printf("%un",a);//2^32-56
		
		4)分析如下程序的输出结果	
			unsigned int a=-1u;//u->unsigned 无符号 昨天有个3.0f 一样的道理
			//unsigned int a=-1;
			-1 
			00000000 00000000 00000000 00000001
			11111111 11111111 11111111 11111110
			11111111 11111111 11111111 11111111
			printf("%dn",a);//-1
			11111111 11111111 11111111 ==> 有符号数
			最高位1 负数
			11111111 11111111 11111111 11111110
			00000000 00000000 00000000 00000001
			-1
			逆运算 -1
			printf("%un",a);
			11111111 11111111 11111111 11111111==》无符号数 全部都是数值位
			2^32-1 
		
		5)分析如下程序的输出结果
			unsigned int a = 1<<31;
						// 1101 1100 << 4 ==>1100 0000
			a:
				00000000 00000000  00000000  00000001 << 31 ==>
				10000000 00000000  00000000  00000000
			printf("%dn",a);//-(2^31)
				10000000 00000000  00000000  00000000 ==> %d 
				最高位1
				负数
				-1:01111111 11111111 11111111 11111111
				取反:10000000 00000000  00000000  00000000
					2^31
					-(2^31)
			printf("%un",a);//2^31
				10000000 00000000  00000000  00000000 ==>数值位
	=========================================================================
	一个特定整数类型的取值范围的问题 
	GUN有一个标准的头文件 stdint.h   (/usr/include)
	
	int8_t   //有符号的8bits整数类型
	uint8_t //无符号的8bits整数类型
		uint8_t
			[0,255]
		int8_t
			max
				0111 1111 127
			min
				1000 0000 -128
		
		/*宏定义*/ 表示有符号数整数的最小值和最大值
		# define INT8_MIN		(-128)
		# define INT16_MIN		(-32767-1)
		...
		# define INT8_MAX		(127)
		# define INT16_MAX		(32767)	
		...
	===========================我是华丽的分割线 ================================
		char c = 250;
		char d;
		d=c+8;
		printf("d=%dn",d);//2
		printf("d=%un",d);//2
	---------------------------我是华丽的分割线--------------------------------	
	4.整数之间的赋值问题
		在C语言中允许不同类型的整数之前相互赋值的
		char -> int 
		int -> char 
		unsigned int -> int 
		...
		有一个问题,不同类型的整数,存储空间大小不一样
		char 8bits
		int 32bits
		这个问题怎么解决呢?
		
		C标准建议:
			(1)长-->短
				长的赋值给短的,低字节直接拷贝
				高字节全部discards(丢弃),没办法
				
					int -> char
					int -> short
					short -> char
					...
			(2)短-->长
				短的赋值给长的,低字节直接拷贝
				高字节补什么?
					如果短的是无符号的,高位就全部补0
					如果短的是有符号的,高位就全部补符号位。
		
		char c = 250;
		char d;
		d=c+8;
			c:1111 1010
			c+8 ==>typeof(c+8)  int
			int + int 
			c(char)-->32bits: 短的-->长的
			11111111 11111111 11111111 11111010
			00000000 00000000 00000000 00001000 8
		   100000000 00000000 00000000 00000010
			d->char 长的-->短的
			00000010
				
		printf("d=%dn",d);//2
		短-->长 
		printf("d=%un",d);//2

	练习:
	1.分析以下程序的输出结果
	unsigned char c = 250;
	c->1111 1010
	char d;
	d =c +8;//c-->自动往高精度转 char->int
	c->32bits:短的->长的 低字节直接拷贝 高字节(短的是无符号补0)
	c->0000 0000 0000 0000 0000 0000 1111 1010
	8->0000 0000 0000 0000 0000 0000 0000 1000
	   0000 0000 0000 0000 0000 0001 0000 0010
	长的->短的 低字节直接拷贝 高字节丢弃
	0000 0010
	
	printf("d=%dn",d);//2 短->长0000 0000 0000 0000 0000 0000 0000 0010
	printf("d=%un",d);//2 0000 0000 0000 0000 0000 0000 0000 0010
	---------------------
	char c = 250;
	int d;
	d=c+8;
	//00000000 00000000 00000000 00000010
	printf("d=%dn",d);//2
	printf("d=%un",d);//2
	--------------------
	unsigned char c = 250;
	int d;
	d=c+8;
	//0000 0000 0000 0000 0000 0001 0000 0010
	printf("d=%dn",d);//258 
	printf("d=%un",d);//258
	2.分析以下程序的输出结果
	char c = -3;
	printf("c=%dn",c);//-3
	printf("c=%un",c);//2^32-3
		
		c:
			0000 0011
			1111 1100
			1111 1101<-- -3在计算机中存储方式(8bits)
	%d:把后面那个对象,转换成signed int来输出
	c->signed int 短的赋值给长的
	1111 1111 1111 1111 1111 1111 1111 1101
	逆运算
	-1 1111 1111 1111 1111 1111 1111 1111 1100
	取反 0000 0000 0000 0000 0000 0000 0000 0011 3
	负数 -3
	%u:把后面的那个对象,转换成unsigned int来输出
	c->unsigned int 短的赋值给长的
	1111 1111 1111 1111 1111 1111 1111 1101
	位值*权值之和 2^31*1+2^30*1+....
	+2
	32个1 2^32-1-2
	2^32-3
    ---------------------	
	unsigned char c = -3;
		1111 1101<-- -3在计算机中存储方式(8bits)
	printf("c=%dn",c);//253
		短->长 c是无符号 高位补0
		0000 0000 0000 0000 0000 0000 1111 1101 
		253
	printf("c=%un",c);//253
		短->长 c是无符号 高位补0
		0000 0000 0000 0000 0000 0000 1111 1101
		253
	
	"溢出“问题
		“溢出”不是爆炸,相应的“溢出”会有一个确定的值!!!

5.常量
常量是指在程序运行期间,其值不能改变的数据对象。
常量在代码中有多种情况:
(1)整型常量:在代码文本中,代表整数的常量值。
八进制常量
	0[0-7]*
		以字符0开头后面接0个或者多个0-7的字符
		如:
		0123
		0777
		0134473
		088 ERROR
		int a = 0123;
		printf("%dn",a);//83
		//3*8^0+2*8^1+1*8^2=3+16+64=83
		八进制与二进制对应关系
			一个八进制对应三个二进制位
			八进制  二进制
			0       000
			1       001
			2       010
			3       011
			4       100
			5       101
			6       110
			7       111
		
十六进制常量
	0[xX][0-9A-Fa-f]+
		以0x或者0X开头后面接一个或者多个0-9A-Fa-f
		
		int a = 0xf3;
	十六进制与二进制位的对应关系
		一个十六进制对应四个二进制位
		十六进制    二进制
		0            0000
		1            0001
		2            0010
		3            0011
		4            0100
		5            0101
		6            0110
		7            0111
		8            1000
		9            1001
		a/A          1010
		b/B          1011
		c/C          1100
		d/D          1101
		e/E          1110
		f/F          1111

	255 ->0xff
十进制常量
	[0-9]+
	
(2)字符常量
	字符常量是用单引号引起来的一个或者多个字符的序列。
	如:
		'a'
		'b'
		'n'
		'r'
		...
	在计算机中,保存一个字符,保存是字符的ASCII码,而不是它的形状。
	ASCII:America standard code for Information Interchange 
		美国把每一个字符给一个唯一的整数值来表示它们,这个整数值
		就是我们称之为的ASCII码。由于美国使用的字符不超过256个,
		所以我们这个整数值只需要8bits就可以保存啦。
		man ASCII 
		ASCII码 -> char /unsigned char
		OCT 八进制
		DEC 十进制
		HEX 十六进制
		Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char
   ────────────────────────────────────────────────────────────────────────
   000   0     00    NUL '' (null character)   100   64    40    @
   001   1     01    SOH (start of heading)      101   65    41    A
   002   2     02    STX (start of text)         102   66    42    B
   003   3     03    ETX (end of text)           103   67    43    C
   004   4     04    EOT (end of transmission)   104   68    44    D
   005   5     05    ENQ (enquiry)               105   69    45    E
   006   6     06    ACK (acknowledge)           106   70    46    F
   007   7     07    BEL 'a' (bell)             107   71    47    G
   010   8     08    BS  'b' (backspace)        110   72    48    H
   011   9     09    HT  't' (horizontal tab)   111   73    49    I
   012   10    0A    LF  'n' (new line)         112   74    4A    J
   013   11    0B    VT  'v' (vertical tab)     113   75    4B    K
   014   12    0C    FF  'f' (form feed)        114   76    4C    L
   015   13    0D    CR  'r' (carriage ret)     115   77    4D    M
   016   14    0E    SO  (shift out)             116   78    4E    N
   017   15    0F    SI  (shift in)              117   79    4F    O
   020   16    10    DLE (data link escape)      120   80    50    P
   021   17    11    DC1 (device control 1)      121   81    51    Q
   022   18    12    DC2 (device control 2)      122   82    52    R
   023   19    13    DC3 (device control 3)      123   83    53    S
   024   20    14    DC4 (device control 4)      124   84    54    T
   025   21    15    NAK (negative ack.)         125   85    55    U
   026   22    16    SYN (synchronous idle)      126   86    56    V
   027   23    17    ETB (end of trans. blk)     127   87    57    W
   030   24    18    CAN (cancel)                130   88    58    X
   031   25    19    EM  (end of medium)         131   89    59    Y
	.....
	char c ='A';
	<==>
	char c = 65;
	char c = 0x41;
	char c = 0101;
	
	'A'-'Z' 连续的 ‘A’+‘z’-'Z'
	65-90
	'a'-'z'
	97-122
	'0'-'9'
	48-57

人为的把字符分为两类
	(1)普通字符:可以打印的字符 有形状的字符
		如:
		‘a’-'z'
		'A'-'Z'
		...
		
	(2)特殊字符(转义字符):不可以打印 没有形状的字符
	如:
	'n':换行符
	‘r’:回车符
	‘t’:制表符
	...
	
	'00':由后面跟1个或者2个或3个八进制数字组成
	这些八进制数字用来指定所期望的 字符的ASCII码
	如:
		‘A’ 101 65 41
	char c ='A';
	char c = 65;
	char c = 0x41;
	char c = 0101;

	char c = '101'
	----
	char c1 = '34'
	//把ASCII码为034(八进制)的那个字符(的ASCII码)赋值给c1
	-----
	char c2 = '';
	char c2 = 0;
		把空字符ASCII为0赋值给C2
	
	‘xhh’:由x后面跟1个或者2个十六进制数字组成
	这些十六进制数字用来指定所期望的字符的ASCII码
	如:
	‘A’ 101 65 41
	char c ='A';
	char c = 65;
	char c = 0x41;
	char c = 0101;

	char c = '101'
	char c = 'x41'
	
(3)浮点型常量
	由整数部分 小数点 小数部分 一个e/E 一个可选的符号的整数指数和一个可选的表示
	类型的后缀(f/F/l/L)
	f/F:float
	l/L:long double
	没有后缀:double
	
	整数部分:可以省略
	小数部分:可以省略	
		但是整数部分和小数部分不可以同时省略。
	如:
		float f = 2.3E3;//正确
		float f = .3E3;//正确
		float f = 5E-3;//正确
		float f = E3;//错误
			//整数部分和小数部分不可以同时省略,
			因为同时省略时候回产生歧义
			因为有可能有一个变量的名字叫E3
	
(4)枚举常量
	后面讲
	
6.总结
 a.变量的属性  
	变量的类型
	变量的名
	变量的值
	变量的存储单元(变量的地址)
	
	变量的左值和右值*********
	
 b.两个结论
	结论1:
	-x 和 2^n-x的补码形式一样的
	结论2:
	CPU内部没有符号位的概念
	
c.整数之间的赋值问题
	长->短 
	短->长
		
作业一:
	1.熟悉source insgiht4.0
	2.熟悉ubuntu的基本命令 
	3.在网上查找scanf printf 的资料
	
作业二:
	1.查找资料,回答为什么计算机用二进制 为什么用补码
	2.假设机器是32bits int 32bits
	a.分析如下代码的输出结果
	printf("%dn",-1);//-1
	printf("%un",-1);//2^32-1
	
	printf("%dn",(char)-1);//强制转换 -1
	printf("%un",(char)-1); 2^32-1
		typeof(-1):int 
		-1
		11111111 11111111 11111111 11111111<---- -1在计算机中的存放形式
		(char)-1: -1 -> char 长->短
		11111111 (char)-1在计算机中的存放形式
		typeof((char)-1) ==> char 
		
		%d: (char)-1 --> int  短 --> 长 
		11111111 --> 32bits 
		11111111 11111111 11111111 11111111
	
	printf("%dn",(unsigned char)-1);//255
	typeof(-1):int 
		-1
		11111111 11111111 11111111 11111111<---- -1在计算机中的存放形式
		(char)-1: -1 -> char 长->短
		11111111 (char)-1在计算机中的存放形式
		typeof((char)-1) ==> char 
		
		%d:(unsigned char)-1 --> int 短-->长
		无符号 高位补0
		00000000 00000000 00000000 11111111 <-----(unsigned char)-1
		255
		
	printf("%un",(unsigned char)-1);//255
	
	printf("%dn",-1u);//u -> unsigned int
	printf("%un",-1u);
		-1 和 -1u 有什么区别?
			typeof(-1)  => int 
			typeof(-1u) => unsigned int 
		-1 -1u在计算机中存放形式都是:
		11111111 11111111 11111111 11111111
		
		%d:32bits -> 32bits  
		-1
		%u:32bits -> 32bits 
		2^32-1
			
	printf("%dn",255);//255
	printf("%un",255);//255
		00000000 00000000 00000000 11111111
	
	printf("%dn",(char)255);
	printf("%un",(char)255);
		typeof(255)  ==> int 
		255:32bits
		00000000 00000000 00000000 11111111
		(char)255:int -> char 长->短
		11111111
		typeof((char)255) ==> char 
		%d:(char)255-->int 短->长
		11111111 11111111 11111111 11111111
		-1
		%u:(char)255-->int 短->长
		11111111 11111111 11111111 11111111
		2^32-1
	
	printf("%dn",(unsigned char)255);
	printf("%un",(unsigned char)255);
	typeof(255)  ==> int 
		255:32bits
		00000000 00000000 00000000 11111111
		(unsigned char)255:int -> char 长->短
		11111111
		%d:(unsigned char)255-->int 短->长
		00000000 00000000 00000000 11111111
		255
		%u:(unsigned char)255-->int 短->长
		00000000 00000000 00000000 11111111
		255
	
	3.(可以不做)写一个函数
	将大写字母转换成小写字母
	小写转换成大写字母

最后

以上就是平淡麦片为你收集整理的数据类型 ASCII的全部内容,希望文章能够帮你解决数据类型 ASCII所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部