C语言的基本类型

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_MINSCHAR_MIN0字符型可表示的最小值
CHAR_MAXSCHAR_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;
}

整型范围宏

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语言没有提供适当的布尔类型变量存储真假值,往往利用整型定义变量,为其赋值为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_DIGfloat型可表示数的有效数字的个数(基于FLT_RADIX)
DBL_MANT_DIGdouble型可表示数的有效数字的个数(基于FLT_RADIX)
LDBL_MANT_DIGlong double型可表示数的有效数字的个数基于FLT_RADIX)
FLT_DIG>=6float型可表示的十进制数的小数点后的有效位数
DBL_DIG>=10double型可表示的十进制数的小数点后的有效位数
LDBL_DIG>=10long double型可表示的十进制数的小数点后的有效位数
FLT_MIN_EXPfloat型可表示数的最小二进制指数
DBL_MIN_EXPdouble型可表示数的最小二进制指数
LDBL_MIN_EXPlong double型可表示数的最小二进制指数
FLT_MIN_10_EXP<=-37float型可表示的十进制数的最小指数
DBL_MIN_10_EXP<=-37double型可表示的十进制数的最小指数
LDBL_MIN_10_EXP<=-37long double型可表示的十进制数的最小指数
FLT_MAX_EXPfloat型可表示数的最大二进制指数
DBL_MAX_EXPdouble型可表示数的最大二进制指数
LDBL_MAX_EXPlong double型可表示数的最大二进制指数
FLT_MAX_10_EXP>= 37float型可表示的十进制数的最大指数
DBL_MAX_10_EXP>= 37double型可表示的十进制数的最大指数
LDBL_MAX_10_EXP>= 37long double型可表示的十进制数的最大指数
FLT_MAX>= 1E37float型可表示的十进制数的最大值
DBL_MAX>= 1E37double型可表示的十进制数的最大值
LDBL_MAX>= 1E37long double型可表示的十进制数的最大值
FLT_EPSILON<= 1E-5float型可表示的数中1和比1大的最小值的差,即两个float型数可区分的最小差值
DBL_EPSILON<= 1E-9double型可表示的数中1和比1大的最小值的差,即两个double型数可区分的最小差值
LDBL_EPSILON<= 1E-9long double型可表示的数中1和比1大的最小值的差,即两个long double型数可区分的最小差值
FLT_MIN<= -1E37float型可表示的十进制数的最小值
DBL_MIN<= -1E37double型可表示的十进制数的最小值
LDBL_MIN<= -1E37long 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;
}

Float宏及其值
除了上表中列出的宏,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;
}

浮点常量

字符型

字符(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语言标准并没有明确规定字符型数据是有符号还是无符号型,因此这也可能带来兼容性问题。为此,在使用字符型时,不要假定其默认为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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值