C语言学习笔记:基本数据类型

栏目: C · 发布时间: 5年前

内容简介:C语言的整型表示的是整数,分为有符号(int)和无符号(unsigned int)。其中无符号整型只能表示非负整数(自然数),不管是有符号还是没符号都存在极限值(表示的数字不能超过或小于某个值),而在C语言中,极限值并不是固定的,不同硬件、操作系统、编译器都可能有不同的值。想要了解当前C语言环境的整型极限值,可以通过引入limits.h头文件查看。具体代码:注意,打印UINT_MAX时不能够使用%d,否则会输出-1,同样打印ULONG_MAX时,无法使用%ld,否则同样会输出-1。上述代码在我的电脑上编译执

整型 int

C语言的整型表示的是整数,分为有符号(int)和无符号(unsigned int)。其中无符号整型只能表示非负整数(自然数),不管是有符号还是没符号都存在极限值(表示的数字不能超过或小于某个值),而在 C语言 中,极限值并不是固定的,不同硬件、操作系统、编译器都可能有不同的值。想要了解当前C语言环境的整型极限值,可以通过引入limits.h头文件查看。具体代码:

#include <stdio.h>
#include <limits.h>
 
int main(void)
{
    printf("The number of bits in a byte %d\n", CHAR_BIT);
    printf("The minimum value of CHAR = %d\n", CHAR_MIN);
    printf("The maximum value of CHAR = %d\n", CHAR_MAX);
    printf("The minimum value of SIGNED CHAR = %d\n", SCHAR_MIN);
    printf("The maximum value of SIGNED CHAR = %d\n", SCHAR_MAX);
    printf("The maximum value of UNSIGNED CHAR = %d\n", UCHAR_MAX);
    printf("The minimum value of SHORT INT = %d\n", SHRT_MIN);
    printf("The maximum value of SHORT INT = %d\n", SHRT_MAX);
    printf("The maximum value of UNSIGNED SHORT INT = %d\n", USHRT_MAX);
    printf("The minimum value of INT = %d\n", INT_MIN);
    printf("The maximum value of INT = %d\n", INT_MAX);
    printf("The maximum value of UNSIGNED INT = %u\n", UINT_MAX);
    printf("The minimum value of LONG = %ld\n", LONG_MIN);
    printf("The maximum value of LONG = %ld\n", LONG_MAX);
    printf("The maximum value of UNSIGNED LONG = %lu\n", ULONG_MAX);
    return 0;
}

注意,打印UINT_MAX时不能够使用%d,否则会输出-1,同样打印ULONG_MAX时,无法使用%ld,否则同样会输出-1。上述代码在我的电脑上编译执行后,输出的内容为:

The number of bits in a byte 8
The minimum value of CHAR = -128
The maximum value of CHAR = 127
The minimum value of SIGNED CHAR = -128
The maximum value of SIGNED CHAR = 127
The maximum value of UNSIGNED CHAR = 255
The minimum value of SHORT INT = -32768
The maximum value of SHORT INT = 32767
The maximum value of UNSIGNED SHORT INT = 65535
The minimum value of INT = -2147483648
The maximum value of INT = 2147483647
The maximum value of UNSIGNED INT = 4294967295
The minimum value of LONG = -9223372036854775808
The maximum value of LONG = 9223372036854775807
The maximum value of UNSIGNED LONG = 18446744073709551615

这些值是在limits.h头文件中通过 #define 指令来定义的。具体含义如下:

描述
CHAR_BIT 定义一个字节的比特数。
SCHAR_MIN 定义一个有符号字符的最小值。
SCHAR_MAX 定义一个有符号字符的最大值。
UCHAR_MAX 定义一个无符号字符的最大值。
CHAR_MIN 定义类型 char 的最小值,如果 char 表示负值,则它的值等于 SCHAR_MIN,否则等于 0。
CHAR_MAX 定义类型 char 的最大值,如果 char 表示负值,则它的值等于 SCHAR_MAX,否则等于 UCHAR_MAX。
MB_LEN_MAX 定义多字节字符中的最大字节数。
SHRT_MIN 定义一个短整型的最小值。
SHRT_MAX 定义一个短整型的最大值。
USHRT_MAX 定义一个无符号短整型的最大值。
INT_MIN 定义一个整型的最小值。
INT_MAX 定义一个整型的最大值。
UINT_MAX 定义一个无符号整型的最大值。
LONG_MIN 定义一个长整型的最小值。
LONG_MAX 定义一个长整型的最大值。
ULONG_MAX 定义一个无符号长整型的最大值。

字符型本质上是int型,C语言把字符型当作小整数进行处理,我们常见的ASCII码表即为字符与int值之间的映射关系。例如字符’a’对应的值为97,字符’A’对应的值为65,字符’0’的值为48。在ASCII码中字符的取值范围为00000000~11111111,可以看成是0-127的整数。虽然ASCII码的取值范围是0-127,但是C语言中字符型char的表示范围和整型int一样受环境影响,具体可看上述示例。

备注:C语言中 getchar()函数返回的类型为int型而非char类型

原因:

  • getchar()除获得一般字符外,还会获得输入结束符EOF
  • EOF在stdio.h中被定义为-1
  • 部分编译器定义的char类型的范围为0-255

枚举类型 enum

枚举类型enum本质和字符类型一样,也可理解为映射表,只不过该映射关系需要自行定义。大致的使用方式如下:

#include<stdio.h>
 
enum month {
    Jan = 1, Feb, Mar, Apr, May, Jun, Jul,
    Aug, Sep, Oct, Nov, Dec
};
 
int main() {
    int i;
    for (i = Jan; i <= Dec; i++)
        printf("%d ", i);
 
    return 0;
}

其中:

  • 映射的数值可以自行指定
  • 首位如果缺省,则数字从0开始
  • 中间位缺省,则数字为前一位+1

浮点类型 float和double

浮点类型(浮点数)指的就是小数,float(单精度浮点)和double(双精度浮点)的区别是double的精度更高,在大部分环境中,double的有效数字为16位,float的有效数字为7位。相应的double消耗的内存是float的两倍,运行速度也比float慢的多。

C语言标准规定,浮点数在内存中以科学计数法的形式来存储,具体形式为:

flt = (-1)sign × mantissa × baseexponent

对各个部分的说明:

  • flt 是要表示的浮点数。
  • sign 用来表示 flt 的正负号,它的取值只能是 0 或 1:取值为 0 表示 flt 是正数,取值为 1 表示 flt 是负数。
  • base 是基数,或者说进制,它的取值大于等于 2(例如,2 表示二进制、10 表示十进制、16 表示十六进制……)。数学中常见的科学计数法是基于十进制的,例如 6.93 × 1013;计算机中的科学计数法可以基于其它进制,例如 1.001 × 27 就是基于二进制的,它等价于 1001 0000。
  • mantissa 为尾数,或者说精度,是 base 进制的小数,并且 1 ≤ mantissa < base,这意味着,小数点前面只能有一位数字;
  • exponent 为指数,是一个整数,可正可负,并且为了直观一般采用十进制表示。

浮点类型与整型一样,能够表示的范围受当前环境影响。想要了解具体的极限值信息,可以从flaot.h中查看。float.h 头文件对 float、double 和 long double 三种类型的浮点数进行了说明,并且宏的命名也非常规范,以FLT_开头的表示宏用来描述 float 类型的特性,以DBL_开头的表示宏用来描述 double 类型的特性,以LDBL_开头的表示宏用来描述 long double 类型的特性。查看方式:

#include <stdio.h>
#include <float.h>
 
int main(void)
{
    printf("FLT_EVAL_METHOD = %d\n",  FLT_EVAL_METHOD);
    printf("FLT_ROUNDS      = %d\n", FLT_ROUNDS);
    printf("FLT_RADIX       = %d\n", FLT_RADIX);
    printf("FLT_MANT_DIG    = %d\n", FLT_MANT_DIG);
    printf("DECIMAL_DIG     = %d\n", DECIMAL_DIG);
    printf("FLT_DIG         = %d\n", FLT_DIG);
    printf("FLT_MIN_EXP     = %d\n",  FLT_MIN_EXP);
    printf("FLT_MAX_EXP     = %d\n",  FLT_MAX_EXP);
    printf("FLT_MIN_10_EXP  = %d\n",  FLT_MIN_10_EXP);
    printf("FLT_MAX_10_EXP  = %d\n",  FLT_MAX_10_EXP);
    printf("FLT_MIN         = %e\n", FLT_MIN);
    printf("FLT_MAX         = %e\n", FLT_MAX);
    printf("FLT_EPSILON     = %e\n", FLT_EPSILON);
    printf("FLT_TRUE_MIN    = %e\n", FLT_TRUE_MIN);
    printf("FLT_DECIMAL_DIG = %d\n",  FLT_DECIMAL_DIG);
    printf("FLT_HAS_SUBNORM = %d\n",  FLT_HAS_SUBNORM);
}

在我电脑上返回的值如下:

FLT_EVAL_METHOD = 0
FLT_ROUNDS      = 1
FLT_RADIX       = 2
FLT_MANT_DIG    = 24
DECIMAL_DIG     = 21
FLT_DIG         = 6
FLT_MIN_EXP     = -125
FLT_MAX_EXP     = 128
FLT_MIN_10_EXP  = -37
FLT_MAX_10_EXP  = 38
FLT_MIN         = 1.175494e-38
FLT_MAX         = 3.402823e+38
FLT_EPSILON     = 1.192093e-07
FLT_TRUE_MIN    = 1.401298e-45
FLT_DECIMAL_DIG = 9
FLT_HAS_SUBNORM = 1

具体含义:

描述
FLT_EVAL_METHOD

l -1:未知的,不确定的。

l 0:不提升类型,使用当前的类型。

l 1:将浮点数提升到 double 类型,大于等于 double 类型的保持不变;也就是说,将 float 类型提升为 double 类型,double 和 long double 类型不变。

l 2:将浮点数提升到 long double;也就是说,将 float、double 提升到 long double 类型,long double 类型保持不变。

FLT_EVAL_METHOD 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的类型提升。提升类型能够提高浮点数的精度,让表达式的结果更加精确。

FLT_ROUNDS

l -1:未知的,不确定的;

l 0:向零舍入,也就是直接截断;

l 1:舍入到最接近的值,类似于“四舍五入”,但不完全相同;

l 2:向 +∞ 方向舍入(向上舍入);

l 3:向 -∞ 方向舍入(向下舍入)。

FLT_ROUNDS 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的舍入模式。

FLT_RADIX

FLT_RADIX 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的种基数(进制)。

DBL_MANT_DIG

LDBL_MANT_DIG

基数(进制)为 FLT_RADIX 时,尾数 mantissa 的最大长度(最大位数),也可以说是浮点数的精度。注意,这里所说的长度包含了整数部分和小数部分。
DECIMAL_DIG 在不损失精度精度的情况下,能够将 long double 转换成至少 DECIMAL_DIG 个十进制数字;反过来,也能将至少 DECIMAL_DIG 个十进制数字转换成 long double。也就是说,DECIMAL_DIG 是用于 long double 序列化和反序列化时的十进制精度。

DBL_DIG

LDBL_DIG

转换成十进制形式后,小数点后精确数字(能够保证精度的数字)的位数。

DBL_MIN_EXP

LDBL_MIN_EXP

基数(进制)为 FLT_RADIX 时,规格化浮点数的指数(也即 exponent)的最小值(为负数)。

DBL_MAX_EXP

LDBL_MAX_EXP

基数(进制)为 FLT_RADIX 时,规格化浮点数的指数(也即 exponent)的最大值(为正数)。

DBL_MIN_10_EXP

LDBL_MIN_10_EXP

转换成十进制形式后,规格化浮点数的指数的最小值(为负数)。

DBL_MAX_10_EXP

LDBL_MAX_10_EXP

转换成十进制形式后,规格化浮点数的指数的最大值(为正数)。

DBL_MIN

LDBL_MIN

最小的有效浮点数的值(为负数),也即浮点数的最小值。

DBL_MAX

LDBL_MAX

最大的有效浮点数的值(为正数),也即浮点数的最大值。

DBL_EPSILON

LDBL_EPSILON

1 和大于 1 的最小浮点数之间的差值(可表示的最小有效数字)。

DBL_TRUE_MIN

LDBL_TRUE_MIN

分别为 float、double 与 long double 的最小正数值

DBL_DECIMAL_DIG

LDBL_DECIMAL_DIG

从 float/double/long double 转换到至少有 FLT_DECIMAL_DIG/DBL_DECIMAL_DIG/LDBL_DECIMAL_DIG 位数字的十进制,再转换回原类型为恒等转换:这是序列化/反序列化浮点值所要求的十进制精度。分别定义为至少 6、10 和 10,对于 IEEE float 为 9,对于 IEEE double 为 17。

DBL_HAS_SUBNORM

LDBL_HAS_SUBNORM

指明类型是否支持非正规数值:-1 为不确定,0 为不支持,1 为支持。

类型转换

算术转换

所谓算数转化就是将运算(比较)前将2个操作数的类型转化为相同类型,其中表示空间较小的会自动转化为表示空间较大的。比如计算1+2.0,会将1转换为1.0,再与2相加。相关的优先级为:

C语言学习笔记:基本数据类型

其中容易遇到的坑为,当有符号的遇到无符号的时候会将去转化为无符号,如果有符号的数字为负数就会产生问题。

#include <stdio.h>
 
int x = -1;
unsigned int y = 1;
 
int main(void) {
    if (x > y) {
        puts("X > Y");
        printf("X is %u\n", x);
    } else {
        puts("X < Y");
    }
 
    return 0;
}

上述代码编译执行后输出的结果为:

X > Y
X is 4294967295

导致x从-1到4294967295的原因是,在负数从有符号转到无符号的过程中会自动加上4294967295(最到的无符号整数)+1。

赋值转换

赋值转换指的是在进行赋值操作时,赋值运算符右边的数据类型必须转换成赋值号左边的类型,若右边的数据类型的长度大于左边,则要进行截断。比如将浮点数赋值给整型变量就会直接丢失小数部分。

输出转换

输出转化是指在格式化输出(printf)的时候,会将类型转化为制定的格式,比如%d代表的就是int型。

对于ANSI C以前的C,比int小的类型会被转化成int,float会被转化成double,所以不会出现接受float类型参数的函数,针对char和short,编译器通过别的方式做了补救措施。因为ANSI C有原型声明,所以无论是char还是float,都可以直接传递。可是,对于printf()这样具有可变参数的函数,原型声明对可变长部分的参数是不产生任何影响的。因此,这部分的参数同样会被编译器进行类型转换操作。也就是说,比int小的会被转换成int,float会被转化成double。结果就是不能向printf传递char或float参数。所以:

  • float、double共用了%f,如果你使用%lf反而会提出警告。
  • char、short、int共用了%d

但是,在scanf中如果想要使用double,就必须使用%lf。  

强制转换

强制转化非常的简单,就是在变量或表达式前加上“(类型名)”,如果类型的标识的标示范围<原值,会发生截断问题。常用的强制转化比如在计算两个整数相除。int_x / int_y默认返回的是被截断的整数,如果想让除法结果返回小数,只要在人员一个变量面前添加(float)即可。比如(float) int_x / int_y,注意,这里的强制转换要比算法运算符高,所以这里会先进行强制转换后进行算数转换。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

让创意更有黏性

让创意更有黏性

[美] 奇普·希思、[美] 丹·希思 / 姜奕晖 / 中信出版社 / 2014-1-8 / 49.00元

你或许相信在太空中唯一能看到的人工建筑就是万里长城,可乐能腐蚀人体骨骼,我们的大脑使用了10%;与此同时,你却记不得上周例会上领导的安排,昨天看过的那本书里写了什么,上次参加培训的主要内容…… 为什么? 这就引发出《让创意更有黏性》的核心问题:什么样的观点或创意具有强有力的黏性,能被他人牢牢记住? 国际知名行为心理学家希思兄弟根据大量的社会心理学研究案例,揭示了让创意或观点具有黏......一起来看看 《让创意更有黏性》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试