C语言数据类型和变量
有符号和无符号
关键字signed(通常省略)是有符号类型,表示这个变量可以有负值。
关键字unsigned(不能省略)是无符号类型,表示这个变量不能有负值。
有符号和无符号改变了变量的取值范围。
数据类型介绍
数据类型分为内置类型和自定义类型。内置类型指C语言本身具有的类型,自定义类型则是用户可以根据自身需求来定义的数据类型。这里主要介绍一下内置类型。内置类型包括4个大类,分别是字符型、整型、浮点型、布尔型。以下详述。
字符型
单个的字符,关键字char。占用1 Byte(8bit)空间。
定义字符类型时可能有以下几种:
char;
[signed] char;
unsigned char;
其中被[]括起来的部分 可以省略,因此上述代码中char 与signed char是一样的。
整型
表示整数,关键字int 对应integer。
//短整型
short [int];//== short
[signed] short [int]; // == short
unsigned short [int];// == unsigned short
//整型
int;
[signed] int;
unsigned int;
//长整型
long [int];
[signed] long [int];
unsigned long [int];
//加长整型
long long [int];
[signed]long long [int];
unsigned long long [int];
注意,有符号和无符号只改变取值范围,不改变类型所占空间的大小。另外,long型在不同的系统中可能占用的空间大小不一样。
浮点型
表示小数,关键字float、double 。浮点型仅用于表示小数,float和double的区别在于float占4字节空间,double占8 byte空间。因此对应的精度和范围是不一样的。
布尔类型
C99之后引入,不支持C99标准的编译器没有这个类型。布尔型仅用来表示真假,关键字是_Bool。其取值只有true 和 false两个。
代码举例:
_Bool flag = true;
if(flag)
printf("I like C\n");
会输出I like C。
数据类型大小和取值范围(部分)
参考下面的列表。
类型名称 | 字节数 | 取值范围 |
---|---|---|
char | 1 | -27 ~27 -1 |
signed char | 1 | 0 ~28 -1 |
short | 2 | -215 ~215 -1 |
int | 4 | -231 ~231 -1 |
long | 4 | -231 ~231 -1 |
float | 4 | 待讲 |
double | 8 | 待讲 |
注意long型。在不同的操作系统里,long所占空间的大小可能是不一致的。因此避免使用long。
关于取值范围的计算
其实数据的取值范围可以根据其所占空间的大小计算(浮点型除外)。例如int型所占空间大小是4,4 byte = 32 bit, 一个32位的2进制数所能表示的最大10进制数是232 -1。这正好是无符号整型(unsigned int)的上限值。可以通过这种方式方便的计算不同数据类型的取值范围。
变量
可以变换的值称为变量。C语言需要知道变量的类型,才可以对变量进行操作。
变量的创建
在使用变量前,需要创建变量。变量的创建过程如下:
data_type name;
int age;
char ch;
double weight;
首先是声明数据类型,然后是变量名称。中间需要使用空格分离。注意,变量名称不能是C语言的关键字。例如 int char
这种变量的创建方式就是错误的。
变量的初始化
变量在创建的时候赋值就称为变量的初始化。
以下代码可以看到变量的初始化过程:
int age = 18;
这个语句分两部分,首先是 int age,创建了int型变量age,然后 age = 18,将18作为值赋给age完成初始化。
变量的分类
变量分为全局变量和局部变量。二者区别在于:
- 全局变量被创建在大括号之外,可以在整个工程中使用,其使用范围比局部变量要大;
- 局部变量被创建在大括号内,其使用范围仅限于大括号内部;
- 局部变量存放与栈区, 全局变量存放于静态区;
- 当全局变量和局部变量名称相同时,优先使用局部变量;
看一下下面的代码:
#include <stdio.h>
int n = 100;
int main()
{
printf("n = %d\n",n);
int n = 1000;
printf("n = %d\n",n);
return 0;
}
运行结果是n=100 n=1000。注意这里不是局部变量改变了全局变量的数值,而是这两个变量的名称相同但位于内存中的不同位置。
算术操作符
运算使用的操作符:
操作符 | 运算示例 | 描述 |
---|---|---|
+ | a+b | 加法运算 |
- | a-b | 减法运算 |
* | a*b | 乘法运算 |
/ | a/b | 除法运算 |
% | a%b | 模运算(取余) |
除法
C语言中,除法分为整数除法与浮点数除法。当 / 左右都是整数的时候,执行的是整数除法,/ 左右有一个浮点数时,执行的是浮点数除法。代码示例如下:
int a = 3 / 2;
float b = 3 / 2.0f;
这里a =1,而b = 1.5;
取模
取模就是求余数,这个运算仅针对整数。浮点数无法取余。另外,负数取模结果的正负号由第一个运算数的正负号决定。
printf("%d\n", -11 % 5); //结果是-1,与-11符号相同
赋值操作符
就是 =。这个操作符可以随时给变量赋值。一定注意=不可以判断是否相等。
连续赋值
c = b = a+3;
C语言支持这种赋值方式,但不建议这样写。上述代码与下面的代码是等价的:
b = a+3;
c = b;
复合赋值
写代码的时候,经常会对某个变量进行自增、自减,类似:
int a = 10;
a = a+3;
a = a-2;
C语言中,可以写成:
int a = 10;
a +=3;
a -=2;
单目操作符
单目操作符,意思就是其操作数仅有一个。C语言中 ++ -- +(正) -(负)
就是单目操作符。
++ 和 –
++是自增1,–是自减1。他们分为前置和后置。区别在于前置是先操作,再使用,后置则是先使用,再操作。前置栗子:
int a = 10;
int b = ++a;
printf("%d %d",a,b);
这里,b的取值是++a,是前置操作符,那么先操作(++),然后使用。那么b=11,注意此时a = 11。
后置栗子:
int c = 10;
int d = c++;
printf("%d %d",c,d);
这里,先使用后操作,那么d = 10,c = 11。
–与++类似,不再详述。
强制类型转换
强制类型转换是将某个数据类型强行转换为别的数据类型。有如下代码:
int a = 3.14;
这里在编译的时候会报警告,因为3.14默认为double型。为了处理这个警告,可以将3.14强制类型转换为int:
int a = (int)3.14;