3. C 数据类型
在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。
3.1 C 中的类型可分为以下几种:
序号 | 类型与描述 |
---|---|
1 | 基本类型: 它们是算术类型,包括两种类型:整数类型和浮点类型。 |
2 | 枚举类型: 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。 |
3 | void 类型: 类型说明符 void 表明没有可用的值。 |
4 | 派生类型: 它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型。 |
**※**数组类型和结构类型统称为聚合类型。函数的类型指的是函数返回值的类型。
3.2 数据类型转换
1). 数据类型转换:
C 语言中如果一个表达式中含有不同类型的常量和变量,在计算时,会将它们自动转换为同一种类型;在 C 语言中也可以对数据类型进行强制转换;
2). 自动转换规则:
- a)浮点数赋给整型,该浮点数小数被舍去;
- b)整数赋给浮点型,数值不变,但是被存储到相应的浮点型变量中;
3). 强制类型转换形式: (类型说明符)(表达式)
b=(int)(x+y);
3.3 C 中的左值(Lvalues)和右值(Rvalues)
C 中有两种类型的表达式:
- **左值(lvalue):**指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
- **右值(rvalue):**术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。
变量是左值,因此可以出现在赋值号的左边。数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边。
但是下面这个就不是一个有效的语句,会生成编译时错误:
int g = 20; //OK
10 = 20; //NG
3.4 全局变量和局部变量在内存中的区别
全局变量保存在内存的全局存储区中,占用静态的存储单元;局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
C语言经过编译之后将内存分为以下几个区域:
- (1)栈(stack):由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作方式类似数据结构中的栈。
- (2)堆(heap):用于程序动态申请分配和释放空间。C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意:这里的“堆”并不是数据结构中的“堆”。
- (3)全局(静态)存储区:分为DATA段和BSS段。DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中BBS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
- (4)文字常量区:存放常量字符串。程序结束后由系统释放。
- (5)程序代码区:存放程序的二进制代码。
显然,C语言中的全局变量和局部变量在内存中是有区别的。C语言中的全局变量包括外部变量和静态变量,均是保存在全局存储区中,占用永久性的存储单元;局部变量,即自动变量,保存在栈中,只有在所在函数被调用时才由系统动态在栈中分配临时性的存储单元。
3.5 C 常量
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。
常量就像是常规的变量,只不过常量的值在定义后不能进行修改。
字符常量,有一些特定的字符,当它们前面有反斜杠(\)[转义序列(Escape Sequence)]时,它们就具有特殊的含义。
下表列出了一些这样的转义序列码:
转义序列 | 含义 |
---|---|
\\ | \ 字符 |
\’ | ’ 字符 |
\" | " 字符 |
? | ? 字符 |
\a | 警报铃声 |
\b | 退格键 |
\f | 换页符 |
\n | 换行符 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ooo | 一到三位的八进制数 |
\xhh . . . | 一个或多个数字的十六进制数 |
\ooo 是对用三位八进制数转义表示任意字符的形象化描述。
比如 char ch = ‘\101’; 等价于 char ch = 0101; (以0开头的表示八进制)。
\xhh 里面是 x 是固定的,表示十六进制(hexadecimal),h 也表示十六进制。
举例,char ch = ‘\x41’; 就是用十六进制来表示,它与前面的 \101 是等价的。
可用如下代码证明它们等价:
#include <stdio.h>
int main(){
printf("%c,%c,%c,%c", 0101, '\101', '\x41', 'A');
return 0;
}
3.6 关于C语言中的单双引号
在 C 语言中,单引号与双引号是有很大区别的。
在 C 语言中没有专门的字符串类型,因此双引号内的字符串会被存储到一个数组中,这个字符串代表指向这个数组起始字符的指针;
而单引号中的内容是一个 char 类型,是一个字符,这个字符对应的是 ASCII 表中的序列值。