C语言的基本类型

时间:2021-09-30 15:50:52

C语言包括三类基本数据类型,分别为整型浮点型字符型

整型

整型按照是否提供符号位,分为有符号整型和无符号整型。在C语言中,默认的整型变量都是有符号的。为了指定无符号整型,需要使用unsigned修饰符。

按照不同的尺寸整型又分为短整型short int, 整型int和长整型long int

这两种分类方法之间可以组合形成6种不同的类型:short int, unsigned short int, int, unsigned int, long int, unsigned long int。C语言通过省略单词int缩写整型的类型,例如unsigned short int等价于unsigned short

各种类型的整型的表示范围因平台和编译器的不同而不同。标准库limits.h文件中,定义了该编译器实现的各种整型的最大值和最小值的宏。使用这些宏,既可以帮助程序选择正确的类型定义,同时保证了程序在各平台和编译器间的可移植性。C89语言标准规定的limits.h中的宏及其标准如下表所示。

宏名 取值 描述
CHAT_BIT >=8 每个字符所占位数
SCHAR_MIN <=-127 有符号字符型可表示的最小值
SCHAR_MAX >=127 有符号字符型可表示的最大值
UCHAR_MAX >=255 无符号字符型可表示的最大值
CHAR_MIN SCHAR_MIN0 字符型可表示的最小值
CHAR_MAX SCHAR_MAX0 字符型可表示的最大值
MB_LEN_MAX >=1 多字节字符最多包含的字节数
SHRT_MIN <=-32767 短整型可表示的最小值
SHRT_MAX >=32767 短整型可表示的最大值
USHRT_MAX >=65535 无符号短整型可表示的最大值
INT_MIN <=-32767 整型可表示的最小值
INT_MAX >=32767 整型可表示的最大值
UINT_MAX >=65535 无符号整型可表示的最大值
LONG_MIN <=-2147483647 长整型可表示的最小值
LONG_MAX >=-2147483647 长整型可表示的最大值
ULONG_MAX >=4294967295 无符号长整型可表示的最大值

获得本机各宏的值的示例如下(ubuntu 14.04gcc 4.8.4 ):

/*****************************************
* value_scope.c *
* *
* 各类型整型的不同取值范围 *
*****************************************/


#include <stdio.h>
#include <limits.h>

int main()
{
unsigned long uTemp = CHAR_BIT;
printf("CHAR_BIT: %ld\n", uTemp);

long temp = 0;
temp = SCHAR_MIN;
printf("SCHAR_MIN: %ld\n", temp);
temp = SCHAR_MAX;
printf("SCHAR_MAX: %ld\n", temp);
uTemp = UCHAR_MAX;
printf("UCHAR_MAX: %lu\n", uTemp);
temp = CHAR_MIN;
printf("CHAR_MIN: %ld\n", temp);
temp = CHAR_MAX;
printf("CHAR_MAX: %ld\n", temp);
uTemp = MB_LEN_MAX;
printf("MB_LEN_MAX: %ld\n", uTemp);
temp = SHRT_MIN;
printf("SHRT_MIN: %ld\n", temp);
temp = SHRT_MAX;
printf("SHRT_MAX: %ld\n", temp);
uTemp = USHRT_MAX;
printf("USHRT_MAX: %lu\n", uTemp);
temp = INT_MIN;
printf("INT_MIN: %ld\n", temp);
temp = INT_MAX;
printf("INT_MAX: %ld\n", temp);
uTemp = UINT_MAX;
printf("UINT_MAX: %lu\n", uTemp);
temp = LONG_MIN;
printf("LONG_MIN: %ld\n", temp);
temp = LONG_MAX;
printf("LONG_MAX: %ld\n", temp);
uTemp = ULONG_MAX;
printf("ULONG_MAX: %lu\n", uTemp);

return 0;
}

C语言的基本类型

C99及以后的标准又添加了另外三个宏LLONG_MIN,LLONG_MAXULLONG_MAX,对应着其新添加的类型long long int. 为了最大限度地保证兼容性,建议尽量不要使用

常量是在程序运行过程中保持不变的量,在程序中以文本形式显示或通过宏命名。C语言支持以十进制、八进制和十六进制形式书写整型常量。不同进制的常量只是书写的一种形式,不会对实际存储方式产生影响。

  • 十进制。包含数字0-9,不能以0开头。
  • 八进制。包含数字0-9,必须以0开头。
  • 十六进制。包含数字0-9和字母a-f和A-F。

当在程序中使用整型常量时,若其在int类型的取值范围,则编译器将其作为int处理,否则作为长整型处理。为了强制编译器将其作为长整型处理,则在常量的后边加L(或l)。同样,为了强制编译器将某一个常量作为无符号整型处理,在其后边加U(或u)。组合这两个符号可以表示常量是无符号长整型。

/******************************************
* int_const.c *
* *
* 整型常量 *
******************************************/


#include <stdio.h>
#include <limits.h>

int main()
{
int x1 = 12;
int x2 = 012;
int x3 = 0x12;
int x4 = 0X12;

printf("x1 = %d, x2 = %d, x3 = %d, x4 = %d\n", x1, x2, x3, x4);


printf("%u\n", 12u);
printf("%ld\n", 99999L);
printf("%lu\n", 89233542LU);

return 0;
}

C语言的基本类型
不要不分差别地使用长整型,其操作时间可能会比较小整型长。

C语言没有提供适当的布尔类型变量存储真假值,往往利用整型定义变量,为其赋值为01的方法来模拟真值和假值。为了程序更易于理解,定义10分别为宏TRUEFALSE

#define TRUE 1
#define FALSE 0

更进一步,可以定义布尔类型的宏BOOL:

#define BOOL int

这样,声明布尔型变量时不用int而使用BOOL,可以非常清楚表明变量所表示的意思。

浮点型

浮点型用以存储带有小数点或极大、极小的数。C语言提供了3类浮点数,分别为:

  • float。 单精度浮点数,对精度要求不严格时使用。
  • double。双精度浮点数,提供更高精度,支持大多数程序使用。
  • long double。扩展双精度浮点数,支持极高精度,很少使用。

不同的计算机采用不同的方式存储浮点数,但大多数采用的都是IEEE 754标准。IEEE 754标准规定数值以科学计数法的方式存储,每个浮点数包括符号、指数和小数三部分。指数说明了数大小的程度,小数数位说明了数的精度。标准库提供了float.h头文件包含了定义浮点数特征的宏。

宏名 取值 描述
FLT_RADIX >=2 所有浮点类型的进制基数
FLT_MANT_DIG float型可表示数的有效数字的个数(基于FLT_RADIX)
DBL_MANT_DIG double型可表示数的有效数字的个数(基于FLT_RADIX)
LDBL_MANT_DIG long double型可表示数的有效数字的个数基于FLT_RADIX)
FLT_DIG >=6 float型可表示的十进制数的小数点后的有效位数
DBL_DIG >=10 double型可表示的十进制数的小数点后的有效位数
LDBL_DIG >=10 long double型可表示的十进制数的小数点后的有效位数
FLT_MIN_EXP float型可表示数的最小二进制指数
DBL_MIN_EXP double型可表示数的最小二进制指数
LDBL_MIN_EXP long double型可表示数的最小二进制指数
FLT_MIN_10_EXP <=-37 float型可表示的十进制数的最小指数
DBL_MIN_10_EXP <=-37 double型可表示的十进制数的最小指数
LDBL_MIN_10_EXP <=-37 long double型可表示的十进制数的最小指数
FLT_MAX_EXP float型可表示数的最大二进制指数
DBL_MAX_EXP double型可表示数的最大二进制指数
LDBL_MAX_EXP long double型可表示数的最大二进制指数
FLT_MAX_10_EXP >= 37 float型可表示的十进制数的最大指数
DBL_MAX_10_EXP >= 37 double型可表示的十进制数的最大指数
LDBL_MAX_10_EXP >= 37 long double型可表示的十进制数的最大指数
FLT_MAX >= 1E37 float型可表示的十进制数的最大值
DBL_MAX >= 1E37 double型可表示的十进制数的最大值
LDBL_MAX >= 1E37 long double型可表示的十进制数的最大值
FLT_EPSILON <= 1E-5 float型可表示的数中1和比1大的最小值的差,即两个float型数可区分的最小差值
DBL_EPSILON <= 1E-9 double型可表示的数中1和比1大的最小值的差,即两个double型数可区分的最小差值
LDBL_EPSILON <= 1E-9 long double型可表示的数中1和比1大的最小值的差,即两个long double型数可区分的最小差值
FLT_MIN <= -1E37 float型可表示的十进制数的最小值
DBL_MIN <= -1E37 double型可表示的十进制数的最小值
LDBL_MIN <= -1E37 long double型可表示的十进制数的最小值
FLT_ROUNDS -1,0,1,2,3 舍入选项:-1表示未定义,0表示向0舍入,1表示最近舍入,2表示向正无穷舍入,3表示向负无穷舍入
/********************************************
* float_value_scope.c *
* *
* <float.h>中定义的宏 *
********************************************/


#include <stdio.h>
#include <float.h>

int main()
{
long double dTemp = 0L;
unsigned long uTemp = 0L;

uTemp = FLT_RADIX;
printf("FLT_RADIX: %lu\n\n", uTemp);

uTemp = FLT_MANT_DIG;
printf("FLT_MANT_DIG: %lu\n", uTemp);
uTemp = DBL_MANT_DIG;
printf("DBL_MANT_DIG: %lu\n", uTemp);
uTemp = LDBL_MANT_DIG;
printf("LDBL_MANT_DIG: %lu\n\n", uTemp);

uTemp = FLT_DIG;
printf("FLT_DIG: %lu\n", uTemp);
uTemp = DBL_DIG;
printf("DBL_DIG: %lu\n", uTemp);
uTemp = LDBL_DIG;
printf("LDBL_DIG: %lu\n", uTemp);

long temp = 0L;
temp = FLT_MIN_EXP;
printf("FLT_MIN_EXP: %ld\n", temp);
temp = DBL_MIN_EXP;
printf("DBL_MIN_EXP: %ld\n", temp);
temp = LDBL_MIN_EXP;
printf("LDBL_MIN_EXP: %ld\n", temp);
temp = FLT_MIN_10_EXP;
printf("FLT_MIN_10_EXP: %ld\n", temp);
temp = DBL_MIN_10_EXP;
printf("DBL_MIN_10_EXP: %ld\n", temp);
temp = LDBL_MIN_10_EXP;
printf("LDBL_MIN_10_EXP: %ld\n", temp);

temp = FLT_MAX_EXP;
printf("FLT_MAX_EXP: %ld\n", temp);
temp = DBL_MAX_EXP;
printf("DLV_MAX_EXP: %ld\n", temp);
temp = LDBL_MAX_EXP;
printf("LDBL_MAX_EXP: %ld\n", temp);

temp = FLT_MAX_10_EXP;
printf("FLT_MAX_10_EXP: %ld\n", temp);
temp = DBL_MAX_10_EXP;
printf("DBL_MAX_10_EXP: %ld\n", temp);
temp = LDBL_MAX_10_EXP;
printf("LDBL_MAX_10_EXP: %ld\n", temp);

dTemp = FLT_MAX;
printf("FLT_MAX: %Le\n", dTemp);
dTemp = DBL_MAX;
printf("DBL_MAX: %Le\n", dTemp);
dTemp = LDBL_MAX;
printf("LDBL_MAX: %Le\n", dTemp);

dTemp = FLT_EPSILON;
printf("FLT_EPSILON: %Le\n", dTemp);
dTemp = DBL_EPSILON;
printf("DBL_EPSILON: %Le\n", dTemp);
dTemp = LDBL_EPSILON;

dTemp = FLT_MIN;
printf("FLT_MIN: %Le\n", dTemp);
dTemp = DBL_MIN;
printf("DBL_MIN: %Le\n", dTemp);
dTemp = LDBL_MIN;
printf("LDBL_MIN: %Le\n", dTemp);

temp = FLT_ROUNDS;
printf("FLT_ROUNDS: %ld\n", temp);

return 0;
}

C语言的基本类型
除了上表中列出的宏,C99及以后的C语言标准又增加了两个宏FLT_EVAL_METHODDECIMAL_DIG。为了最大程度地兼容性,除非万不得已,尽量不要使用。否则,通过其他方法处理好可能的兼容性问题。

浮点常量可写成多种形式,但必须包含小数点或指数符号eE。浮点常量默认都以双精度形式存储,当需要强制编译器以floatlong double型存储常量时,需要在常量的末尾添加Ff,Ll符号。

/*****************************************
* float_const.c *
* *
* 浮点常量 *
*****************************************/


#include <stdio.h>

int main()
{
double x1 = 8883.5;
double x2 = 8.8835e4;
float x3 = 8883.5f;
long double x4 = 8883.5L;

printf("x1 = %lf, x2 = %f, x3 = %f, x4 = %Lf\n", x1, x2, x3, x4);

return 0;
}

C语言的基本类型

字符型

字符(char)型通常占用1个字节,其取值根据计算机的不同采用的字符集的不同而不同(有符号或无符号)。ASCII(美国信息交换标准码)是最常用的字符集,利用一个字节中7位表示128个字符,还存在一种扩展ASCII集的编码,利用一个字节的全8位,提供256个字符。

字符型常量包括两类:

  • 计算机能表示的任意字符。通过使用单引号将字符括起来表示字符常量,例如'A'
  • 计算机无法表示的任意字符。通过使用单引号将表示该字符的转义序列括起来作为字符常量,例如'\n'
/*****************************************
* using_char.c *
* *
* 基本类型: char *
*****************************************/

#include <stdio.h>

int main()
{
char ch = 'A';
int i = 'a';

int diff = i - ch;
char ch2 = 'B' + diff;

printf("ch2: %c\n", ch2);

return 0;
}

C语言的基本类型
C语言按照小整数的方式处理字符,在计算中使用字符时,使用的只是它对应的整数值。C语言标准并没有明确规定字符型数据是有符号还是无符号型,因此这也可能带来兼容性问题。为此,在使用字符型时,不要假定其默认为signedunsigned, 在关系到范围问题时,应明确地给予声明。

参考文献

  1. K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
  2. http://www.cplusplus.com/reference/climits/?kw=climits
  3. http://www.cplusplus.com/reference/cfloat/?kw=float.h