问题引入:计算机只是一个帮助我们解决问题的工具
解决哪些问题:就是那些可以通过计算解决的问题,不能帮助解决感情问题。
computer:计算机
计算:计算机通过把问题域中的数据抽象出来,保存起来,然后再对这些数据进行一系列有目的的计算,从而得到结果。
如:1+1=2
计算机首先要解决的就是数据的保存问题,在保存数据之前我们首先要知道这些数据的大小,取值范围等等数据的属性。
数据的大小、属性、取值范围等就是数据类型要讨论的问题
数据类型:用来描述数据的属性的,"给数据进行分类"
不同的数据类型属性不一样
c语言中有哪些数据类型?
1:基本类型
c语言内置,已经为我们定义好的类型,程序员可以直接使用
"数":整数,小数(浮点数)
整型:
char / unsigned char 1字节(8bit)
short / unsigned short 2字节(16bit)
int / unsigned int 4字节(32bit)
long int / unsigned long int 4字节/8字节(32/64bit)
long long int 8字节(64bit)
区别在哪里?
用来保存整数的bit位数(字节数)不一样
浮点型
float
double
long double
构造类型:
C语言中,允许程序员自己定义类型
数组:
结构体:
指针类型:
见指针专题
void类型
空类型
在c语言中,有且仅有三个地方可以用到void
1:函数的返回值
void main()//表示函数没有返回值
2:void可以做函数的形式参数
int sum(void)//表示函数没有参数
3:
void *:通用指针
有了数据的类型以后,我们在程序中,就可以自己定义数据对象了
数据对象:
变量:在程序运行期间可以改变的数据对象
常量:在程序运行期间不能改变的数据对象
变量的定义:
数据类型 变量名{=初始值};花括号里面的内容可以忽略
数据类型:代表该变量的类型,系统会根据这个类型来为变量分配合理的空间。
数据类型是任意合法的类型都行(基本类型、指针类型、构造类型)
变量名:
就是给变量取的名字,但是在c语言中,任何的名字都必须符合c语言标识符的规定
必须以下划线或者字母或者数字开头,并且第一个字符必须是字母或者下划线。
比如:
sb:可以
_250:可以
int:不可以,因为是内置类型
一般变量名字都是见其名,知其意
int sum;//sum就是用来求和的
int sb = 250;
变量的属性
1.变量名
2.变量的地址:
在程序运行期间,系统会自动为sb分配一个四个字节的储存空间,并且会把250这个值存入到sb对应的储存空间中
储存单元:系统会为每个存储单元分配一个唯一的编号,用于区分这些存储单元
这个编号就称为存储单元的"地址"
重点:一定要记得地址的概念
3.变量的值:
存储单元的内容
练习:分析下面代码的输出结果
int main()
{
int a;
printf("a = %d\n",a);
return 0;
}
以下描述正确的是:B
A:变量a没有值,会报错
B:变量a有一个值,但是你不知道
变量操作:
read:读一个变量的值
write:把一个值,写入到变量的存储单元中去
例如:
int a,b;
a = 5;//变量a的写操作
b = a;//变量a的读操作
上面两个a不一样
a=5;//没有用到a的值
b=a;//没有用到a的地址
在c语言中,任何变量都有两层含义
1.右值:代表变量的值
2.左值:代表变量的地址
请问什么时候代表变量的值,什么时候代表变量的地址呢?
“=”右边的变量,代表值
“=”左边的变量,代表地址
int main()
{
int a;//
scanf("%d",&a);//scanf是从键盘中获取值,存到a的地址中去,(左值)
printf("%d\n",a);//在终端打印a的值,(右值)
return 0;
}
1:整数在计算机中是如何存放的
整数在计算机中是以2进制的补码存放的
二进制补码:
非负整数:二进制补码就是原码本身
负整数:二进制补码是其绝对值的原码取反+1
二进制补码:
5(8bit):0000 0101
-5(8bit):0000 0101 →取反→ 1111 1010 →+1→ 1111 1011
练习:
写出123和-123在计算机中的存储形式(8bit)
123 0111 1011
-123 1000 0100 → 1000 0101
-1和255在计算机的存储形式(8bit)
255:
1111 1111
-1:
1111 1111
-2和254在计算机的存储形式(8bit)
254:1111 1110
-2:1111 1110
-3和253在计算机的存储形式(8bit)
……
规律:
1:一个负数在计算机中的存储形式 会与另一个正数相同
2:
假设x为正数
-x会与2^n-x在计算机中的存储形式一样
n代表,存储该整数的bit位
3:在CPU底层是没有符号概念的,都是数值位,都参与运算,至于这个数到底是正数还是负数,要看编译器的词义,意思就是,把这个数当作有符号数(signed)还是无符号数(unsigned)
有符号数:(signed)(一般省略)
符号位(最高位)+数值位(其他位)
1:负数 0:正数
无符号数:(unsigned)
全是数值位
8bit的一段内存可以表示的数的范围:
有符号:0-255
无符号:-128-127
#include<stdio.h>
printf("格式化字符串",输出列表);
格式化字符串的内容:
1:字符串常量
wjdaknd你
2:格式控制字符串
%+字符(%d/%c/%f...)
3:转义字符
\n换行
\t制表
输出到终端的内容:
按照顺序输出“格式化字符串”里面的内容,不包括转义字符
int a=5;
printf("sgdyu你好%d\n",a);
输出:sgdyu你好5
练习:
假设 int(32bit)
分析如下程序的输出结果
int main()
{
int a = -3;
printf("%d\n",a);//以signed int类型打印a的值 -3
printf("%u\n",a);//以unsigned signed int类型打印a的值 2^32-3
}
-3
1111 1111 1111 1111 1111 1111 1111 1101
4294967293
int main()
{
int a = -3u;//说明a是unsigned int类型
printf("%d\n",a);//以signed int类型打印a的值 -3
printf("%u\n",a);//以unsigned signed int类型打印a的值 2^32-1
}
int main()
{
unsigned char c = 250;
char d;
d=c+9;
printf("%d\n",d);
printf("%u\n",d);
return 0;
}
250:
1111 1010
1111 1001
256:
1 0000 0000
259:
1 0000 0011
int main()
{
char d = 255;
printf("%d\n",d);//-1
printf("%u\n",d);//2^32-1
return 0;
}
int main()
{
unsigned char d = 255;
printf("%d\n",d);//255
printf("%u\n",d);//255
return 0;
}
不同类型的整数的赋值问题
长度不一样怎么赋值?
(1)长的-->短的
低字节直接拷贝,高字节直接丢弃
(2)短的-->长的
如果短的是无符号的:高位直接补0
如果短的是有符号的:高位补符号位
int main()
{
char c = 253;
char d;
d = c+192;
printf("%d\n",d);//-67
printf("%u\n",d);//
return 0;
}
c:
11111111 11111111 11111111 11111101
192: 00000000 00000000 00000000 00000010
c+192: 00000000 00000000 00000000 10111101
(int)d
11111111 11111111 11111111 10111101
11111111 11111111 11111111 10111100 -1
00000000 00000000 00000000 01000011 (-)67
归纳:
1.整数常量默认是int类型
2.不同类型的数据进行运算,要先转化成相同类型的数据(都向高精度数据转换(最低int),精度:数据位的个数);char:精度7,还有一个是符号位,unsigned char:精度8
两个不同类型的数据进行运算,如果都没有超过int类型的精度,向int类型转换
如果都超过了int类型的精度,向超过的类型转换。
一个问题:
c程序中有些时候要定义一个8bit的整数,怎么定义?
char/unsigned char
假设要定义一个16bit/32bit/64bit的整数呢?
short有可能不是2个字节
int也有可能不是4个字节
GNU下的标准整数类型
GNU有一个头文件:<stdint.h>
在头文件<stdint.h>中定义了如下数据类型
int8_t:有符号8bit的整数类型
uint8_t:无符号的8bit整数类型
int16_t:有符号16bit的整数类型
uint16_t:无符号的16bit整数类型
int32_t:有符号32bit的整数类型
uint32_t:无符号的32bit整数类型
int64_t:有符号64bit的整数类型
uint64_t:无符号的64bit整数类型
这些整数有一个最值:
最小值 最大值
int8_t: -128 127
uint8_t: 0 255
……
在<stdint.h>中,已经为我们定义好了这些最值的“宏”,可以直接使用
INT8_MAX :127
INT8_MIN :-128
INT16_MAX
INT16_MIN
……
UINT8_MAX :255
UINT8_MIN :0
常量:常量是程序运行期间不能改变的数据对象
1、常量的形式
(1)整型常量
十进制常量:[0-9]+:任意个数的0-9组成的数字
八进制常量:
0[0-7]+:第一个数字是0,后面接若干个0-7这个范围的数字
如:0123
0777
八进制和二进制之间的关系
一个八进制数可以对应3个二进制数
八进制 二进制
1 001
6 110
7 111
十六进制常量:
0[Xx][0-9a-fA-F]+:
由0x或者0X开头,后面至少接一个或多个0-9或者a-f或者A-F的字符
例如:0xcc;
0XAB;
0x11;
十六进制数和二级制数之间的对应关系
一个十六进制数对应四个二级制数
十六进制 二进制
3 0011
8 1000
a 1010
e 1110
f 1111
2、字符常量
字符常量是用单引号''引起来的一个或者多个字符的序列。用来表示一个字符
比如:
'A'
'\n'
'\t'
'\x12'
问题:
我们要在计算机中保存字符a,b,c,d等,那么计算机中保存的是字符的什么?
字符是保存字符的ASCII码
怎么查看各个字符的ASCII码呢?
Ubuntu→终端→man ascii
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (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
032 26 1A SUB (substitute) 132 90 5A Z
033 27 1B ESC (escape) 133 91 5B [
034 28 1C FS (file separator) 134 92 5C \ '\\'
035 29 1D GS (group separator) 135 93 5D ]
036 30 1E RS (record separator) 136 94 5E ^
037 31 1F US (unit separator) 137 95 5F _
040 32 20 SPACE 140 96 60 `
041 33 21 ! 141 61 a
042 34 22 " 142 98 62 b
043 35 23 # 143 99 63 c
044 36 24 $ 144 100 64 d
045 37 25 % 145 101 65 e
046 38 26 & 146 102 66 f
047 39 27 ' 147 103 67 g
050 40 28 ( 150 104 68 h
051 41 29 ) 151 105 69 i
052 42 2A * 152 106 6A j
053 43 2B + 153 107 6B k
054 44 2C , 154 108 6C l
055 45 2D - 155 109 6D m
056 46 2E . 156 110 6E n
057 47 2F / 157 111 6F o
060 30 0 160 112 70 p
061 49 31 1 161 113 71 q
062 50 32 2 162 114 72 r
063 51 33 3 163 115 73 s
064 52 34 4 164 116 74 t
065 53 35 5 165 117 75 u
066 54 36 6 166 118 76 v
067 55 37 7 167 119 77 w
070 56 38 8 170 120 78 x
071 57 39 9 171 121 79 y
072 58 3A : 172 122 7A z
073 59 3B ; 173 123 7B {
074 60 3C < 174 124 7C |
075 61 3D = 175 125 7D }
076 62 3E > 176 126 7E ~
077 63 3F ? 177 127 7F DEL
2 3 4 5 6 7 30 40 50 60 70 80 90 100 110 120
------------- ---------------------------------
0: 0 @ P ` p 0: ( 2 < F P Z d n x
1: ! 1 A Q a q 1: ) 3 = G Q [ e o y
2: " 2 B R b r 2: * 4 > H R \ f p z
3: # 3 C S c s 3: ! + 5 ? I S ] g q {
4: $ 4 D T d t 4: " , 6 @ J T ^ h r |
5: % 5 E U e u 5: # - 7 A K U _ i s }
6: & 6 F V f v 6: $ . 8 B L V ` j t ~
7: ' 7 G W g w 7: % / 9 C M W a k u DEL
8: ( 8 H X h x 8: & 0 : D N X b l v
9: ) 9 I Y i y 9: ' 1 ; E O Y c m w
A: * : J Z j z
B: + ; K [ k {
C: , < L \ l |
D: - = M ] m }
E: . > N ^ n ~
F: / ? O _ o DEL
如:'!'ASCII码为:33/041/0x21
'A'--'Z'的ASCII码是连续的,'A'的ASCII码为:65
'0'--'9'的ASCII码是连续的,'0'的ASCII码为:48
'a'--'z'的ASCII码是连续的,'a'的ASCII码为:97
char a = 0;
char a = '0';
char a = '\0';
'\ooo':
由\后面跟着1个、2个、3个这样的八进制数,用来代表所期望的那个字符的ASCII码
'\100':代表字符'@'
'\xhh':
由\x后面接1个、2个16进制数,这些16进制数字用来代表所期望的那个字符的ASCII码
'\x40':代表字符'a';
char a = 64;
char a = '@';
char a = '\100';
char a = '\x40';
char a = 0100;
char a = 0x40;
这6句是一个意思!!
char a = '\0';
char a = 0;
a的值是0
这两句话是一个意思。'\0'是空字符,一般用来表示字符串的结束。
char a = '0';
a的值是48
3、浮点数常量
浮点数常量是由整数部分、小数点、小数部分、一个e或者E、一个可选的带符号的整型指数和一个可选的表示类型的后缀
(f/F/l/L)
后缀:
f/F:float
l/L:long double
没有后缀的情况下,默认double
double a = 3.14; √
double a = .3e3; √,整数部分可以省略,表示为0.3e3
double a = 5e3; √,小数部分也可以省略,表示小数部分为5.0e3
double a = e3; ×,小数和整数不能同时省略
double a = 3; √ 3.0e1
int a = 3.5; √,将3.5转化为int类型,再赋值给a,相当于int a = 3;
浮点数在计算机中的存储形式(32bit)
1位 8位 23位
符号位 指数位 数值位
赏
Comments | NOTHING