C语言学习笔记 (1)
-
数据类型
(1) 基本类型
操作系统分配给基本类型的变量的空间大小是固定的。
这些基本类型是C语言已经为我们定义好了的类型。
整型:
short 占2个字节(16bits)
unsigned short 取值范围 0 ~ 2^16 - 1 (0 ~ 65535)
(signed) short 取值范围 -32768 ~ 32767int 占4个字节(32bits) unsigned int 取值范围 0 ~ 2^32 - 1 **(0~4294967295)** (signed) int 取值范围 -2^31 ~ 2^31 - 1 **(-2147483648 ~ 2147483648)** long 占4个字节(32bits) unsigned long 取值范围 0 ~ 2^32 - 1 **(0~4294967295)** (signed) long 取值范围 -2^31 ~ 2^31 - 1 **(-2147483648 ~ 2147483648)** 有符号的: 符号位(最高位) + 数值位 1 ---> 负数 0 ---> 正数 无符号的: 所有bit位都是数值位
浮点型(实型):
float 单精度浮点型 占4个字节double 双精度浮点型 占8个字节 所有的浮点型默认都是有符号的,没有无符号的浮点型。
字符型:
char 占1个字节(8bits)
unsigned char 取值范围 0 ~ 255
(signed) char 取值范围 -128 ~ 127
例子:
char a = 260;//1 0000 0100
printf("a = %d\n",a);//4
(2) 构造类型
系统分配给构造类型的变量所占的空间大小取决于该类型是怎么定义的。
数组类型
结构体类型
联合体类型(共用体)
枚举类型
(3) 指针类型
(4) 空类型(void类型)
sizeof(int) --> 4
sizeof(7.8) --> 8
例子:
int a = sizeof(void);//sizeof 求对象所占空间大小的一个运算符
printf("%d\n",a);//1 (看编译器来的)
- 常量和变量
数据分为常量和变量。
常量:其值不能被改变的量称之为常量。
1/2/3.14…
3 = 4;//error
常量在代码中有多种情况:
(1) 整型常量
在代码文本中,代表整数的常量值
a. 二进制常量
1111 1010 --> 250
b. 八进制常量
以字符0开头后面跟0个或者多个0~7的字符。
格式化输出用%o表示。
如:
0123
0777
0127561243145234125
088//error
八进制与二进制对应的关系:一个八进制对应三个二进制
1 001
....
6 110
7 111
c. 十进制常量
0~9
格式化输出%d表示
d. 十六进制常量
以0x或0X开头的后面接一个或多个09afA~F
格式化输出%x表示
如:
0x1a
0xFF
0xcxkv//error
十六进制与二进制对应的关系:一个十六进制对应四个二进制
1 0001
....
6 0110
7 0111
...
F 1111
转换成十进制 —> 直接乘以权相加
0777 --> 78^2 + 78^1 + 7*8^0
转换成非十进制 —> 先转换成二进制,在转换为其它进制
0777 --> 000111 111 111 —> 0x1ff
(2) 浮点型常量
单精度浮点型 格式化输出%f表示
双精度浮点型 格式化输出%lf表示
例子:
printf("%f\n",4.2111111);//默认小数点后为6位
printf("%5.2f\n",4444444.2);//整个小数占5位(包括小数点),小数部分占2位
//向右靠齐,当实际位数大于小数点前面的数字时,按实际位输出
printf("%-5.2f\n",4.2);//整个小数占5位(包括小数点),小数部分占2位
//向左靠齐,当实际位数大于小数点前面的数字时,按实际位输出
(3) 字符常量
字符常量是用单引号引起来的一个或者多个字符的序列,格式化输出%c表示。
如:
‘A’ ‘a’ ‘\n’ ‘\t’…
在计算机中,保存一个字符,保存的是这个字符的ASCII码,而不是这个字符本身。
我们规定每一个字符都有一个唯一的整数值对应,这个整数值我们就称之为ASCII码。
查看ASCII码表:man ascii
由于字符个数没有超过256个,所以我们只需要8bit就可以保存所有字符了。
char c = 'A' <==> char c = 65 char c = 0x41 char c = 0101
'A' ~ 'Z' 65 ~ 90
'a' ~ 'z' 97 ~ 122
'0' ~ '9' 48 ~ 57
人为的把字符分为两类:
1. 普通字符
可以打印出来的字符,有形状的字符
如:
'A' ~ 'Z'、'a' ~ 'z'、'0' ~ '9'
2. 转义字符
不可以打印出来的字符,没有形状的字符
如:
'\n' 换行符
'\t' 制表符
'\r' 回车符
'\\' 反斜杠
'%%' %百分号
'\ddd' ddd表示1到3位的八进制数,打印效果为该数字对应的ASCII码的字符
printf("\43");//#
'\xhh' hh表示的是1到2位的十进制数,打印效果为该数字对应的ASCII码的字符
printf("\x40");//@
....
(4) 字符串常量
双引号引起来的一串字符就是字符串。
字符串在内存中保存一定会有一个’\0’为结尾,我们称之为终止符,’\0’的ASCII码就是0。
字符串是没有变量的,用字符数组保存字符串,格式化输出%s表示。
例子:
printf("%s\n","cxkdlq");//cxkdlq
变量:在程序运行期间其值能被改变的量称之为变量
变量的定义:
数据类型 变量名;
“数据类型”:所有C语言中合法的数据类型都可以
"变量名":变量的名字
变量的命名要符合C语言中标识符的规则:
1. 必须由字母、数字以及下划线组成。
2. 不能以数字开头。
3. 不能与关键字重名。
关键字:int double char.....
for while if.....
4. 要区分大小写。
例子:
char a;
变量实质上是内存的一个具有特定属性的存储单元,他是用来存储数据的。
这个存储单元中的数据就是变量的值,而这个值是可以在程序运行期间是可以被改变的。
地址:
操作系统会将内存以一个字节为单位进行划分,每一个字节(单位)都有一个独特的编号
这个编号就是地址。
在定义变量时,会在内存分配空间(这个空间的大小根据变量的类型),这时变量名就与这个
空间的地址相关联了起来,操作系统根据这个变量名就知道了该空间的地址。
变量的访问(读/写):
(1) 从变量中取值(读),实际上就是通过变量名找到对应的内存空间,从该地址相对应的
存储空间中读取数据。这时变量一般在赋值符号的(=)的右边,称之为右值。表示变量的值。
(2) 往变量中存值(写),实际上就是通过变量名找到对应的内存空间,把数据写入到该地址
对应的存储单元中去,覆盖掉原来的值。这时变量一般在赋值符号的(=)左边,称之为左值
表示的是变量的内存空间。
给变量的第一次赋值就称之为初始化,如果没有对变量进行初始化,那么变量的值就是不确定的。
我们对变量进行读操作或者计算的时候要先初始化,否则是没有意义的。
-
整数的存储问题
整数是以二进制的补码形式存放的。
正数:
正数的补码就是其原码本身。原码: 就是把对应的数值转换为二进制。 char a = 13; a ---> 0000 1101 --->13的原码,也是13的补码 int a = 9; a ---> 0000 0000 0000 0000 0000 0000 0000 1001
负数:
负数的补码是其绝对值的原码取反+1得到。
char a = -13;
-13 求绝对值
13 求出原码
0000 1101 取反
1111 0010 +1
1111 0011 -13补码,a所对应的空间内保存的就是1111 0011-2 1111 1110 254 1111 1110 -3 1111 1101 253 1111 1101 .... 结论: 一个负整数(-x)会和2^n-x的正整数的补码形式一样的。 即意味着他们在计算机中存储方式是一样的。 n表示的是多少个BIT来存储的这个数。 那么一个负数的补码,怎么求出这个负数的十进制呢? 求负数的补码: 求出这个负数的绝对值的原码 ---> 取反 ---> +1 ---> 得到负数的补码 根据负数的补码求这个负数,逆运算: 补码-1 ---> 取反 ---> 负数的绝对值的原码 ---> 负数 例子: 1111 1110 -1 1111 1101 取反 0000 0010 -2 注意: (1) 当编译器以整型输出(%d)时,是以补码还原的方式去解读的。 (2) 当CPU进行数据运算时,直接是以内存中存放的形式去进行运算的,即补码的形式。 (3) 当编译器以无符号整数输出(%u)时,就没有符号位的概念了,就会把所有位都当成 数值位直接转化为十进制输出。
-
整数之间的赋值问题
在C语言中,允许不同类型之间的整数之间相互赋值。
char --> int
int --> char
unsigned int --> int规则: 1. 长的数据类型 ---> 短的数据类型 int --> short short --> char 低字节直接拷贝,高字节全部舍弃。 2. 短的数据类型 ---> 长的数据类型 低字节直接拷贝,高字节需要分情况考虑: 1) 如果短的是无符号的,高位就全部补0 2) 如果短的是有符号的,高位就全部补符号位 例子: char d = -56; printf("d_d = %d\n",d);//-56 printf("d_u = %u\n",d);//2^32 - 56 0011 1000 |-56| 1100 0111 取反 1100 1000 +1 char ---> int 1111 1111 1111 1111 1111 1111 1100 1000