一文带你深入浅出C语言数据

一文带你深入浅出C语言数据,第1张

目录

🍥前言

🌰常量与变量

🌰1.概念

🌰2.局部与全局变量

🌰1.作用域

🌰2.生命周期

🌰3.全局变量与局部变量可以同名

🌰3.初识各类常量

🌰1.const修饰的常变量

🌰2.#define定义的标识符常量

🌰3.枚举常量

🌰基本数据类型详解

🌰1.关于位,字节和字的区别

🌰2.int类型

🌰1.变量声明

🌰2.注意一下变量的命名

🌰3.关于进制的显示

🌰3.其他整型

🌰4.关于原码反码与补码(这节之后有深入讲解)

🌰注意:计算机存储和运算时用的都是补码而非原码

🌰5.整数溢出问题

🌰1.问题是什么

🌰2.别急,这就涉及到有符号整数的范围规定了

🌰3.让我们回到int范围的问题上来 

🌰6.char类型

🌰1.基本介绍    

🌰2.非打印字符

🌰3.何时使用ASCII码?何时使用转义字符?

🌰4.有符号还是无符号char

🌰7.浮点数类型

🌰 1.简介

🌰2.看看C标准的规定(了解一下)

🌰3.表示形式

🌰4.打印

        如果有什么补充的话请期待博客下次的更新。


🍥前言

        本文致力于用简单浅显的方式讲解C与数据的知识,简单地介绍常量变量,基本数据类型的知识,希望的是能够用知识间的联系建立起博客间的联系,在讲到某些内容的时候,本文不细讲的地方会在我写的别的博客里深入讲解,可以点击链接进入浏览,将知识串联起来。

        笔者也是小白,写作水平有限,欢迎交流指正,觉得写的不咋地也实属正常,未来会努力进步的。

P.S.  文中若没放别的博客链接就说明还没写呢,唉,写的太慢了,边写还要边学,新手写博客的痛😥。

🌰常量与变量

🌰1.概念

        在程序中,我们使用的量无非就是常量和变量。

        听过数学里的常数没?其实差不多。所谓常量就是预先设定好值并且在程序执行过程中不发生变动的量,比如我要计算圆的的面积,那再编写程序的时候我就先定义一个常量PI为3.14嘛,而这个值在整个程序运行过程中不会改变。

#define PI 3.14

         变量顾名思义就是会随着某些条件变化的量,其实就是会在程序运行过程中根据某些条件或设计而改变的量。比如我要计算两个整数之和,定义一个整型sum初始化为零,当执行完求和语句后sum的值就变成了60嘛。

int sum = 0;
sum = 10 + 50;

🌰2.局部与全局变量

🌰1.作用域

        作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字(标识符)并不总是有效可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

        作用域有块作用域,函数作用域,函数原型作用域和文件作用域。

        在存储的类别会继续讲到作用域,这里简单理解一下。

        变量的作用域简单来说就是变量能发挥用处的范围,世间万物都有自己能起到作用和起不到作用的地方嘛,就比如说老师的作用域在哪?学校呗!

        局部变量,就是作用域在局部范围的变量。

        我们来看看下面这段代码,想一想变量a, b的作用域分别是什么?

int main()
{
    int a = 10;
    printf("%d", a);

    {
        int b = 10;
        printf("%d", b);
        printf("%d", a);
    }
    printf("%d", a);
    printf("%d", b);
    return 0;
}

        我们让代码跑起来看看,发现发生错误无法运行,警告如下:

        为什么b会未声明呢?我不是在main函数花括号里面的花括号里定义了b吗?奇怪捏。

        这就要注意了,这里的b作用域就是这个花括号,出了花括号b就没用了。

         这里可能有人就要问了,b不是定义并赋值了吗,b就算不能再使用了那应该还存在吧?怎么会未声明呢?搞得好像b不曾来过一般。(在后面会细讲好吧,别急呢米娜桑~)

        那a的作用域就是main函数的花括号范围咯,真聪明!

        实际上,局部变量作用域是块作用域,看的就是离它定义处最近的花括号,花括号括起来的范围就是它的“活动范围”,所谓的块就是花括号括起来的代码区域。

        全局变量,就是作用域为整个工程项目的变量。

        一句话,全局变量就是这条道上的爷👴,想搁哪沾花惹草那都不是事儿。

        首先,全局变量在整个文件范围内都有用,而一个文件里可能有若干个函数,这个变量也就是能够在这若干个函数内使用。(其实就是文件作用域)

        看看这段代码,全局变量c穿梭在两个函数之间。

      (函数不清楚的可以先去看看函数相关知识)  

int c = 0;//全局变量可以在函数外面定义并初始化

//求两数之和函数
int add(int a, int b)
{
    c = a + b;//在这个函数里就用到了全局变量c接收求和的值
    return c;
}

int main()
{
    int a = 10;
    printf("%d ", a);

    int b = 10;
    printf("%d ", b);

    printf("%d", c); //main函数里也用到了c

    int e = add(a, b);
    printf("%d ", e);

    return 0;
}

        这里顺便插一嘴,上面定义了一个函数嘛,那么请问函数形参的作用域是哪呢

        这形参不是搁圆括号里头嘛,我寻思这函数形参也不是全局变量吧,前面不是说局部变量找花括号,那这在花括号外头啊,咋判断呀?

        小伙汁,年纪轻轻的可别被这“奇装异服”给骗了🕵️‍♀️,虽然函数形参声明是在花括号外头,圆括号里头,但是它的作用域是块作用域,也就是后面的花括号呗。

        这就好比如啥呢,“洋装虽然穿在身,我心仍是中国人”,就算我可以到处去国外旅游,但是一到要我发光发热的时候那肯定只能为祖国发光发热嘛——虽然我函数形参待在圆括号里头,但是我真正发挥用处的地方是在花括号里面呢。🤣

        一个项目包含若干个文件,也就是说全局变量可以在各个文件中使用,只是需要标明一下告诉编译器我要在别的文件用这个文件里的全局变量呗。(讲的很片面了解一下即可)

extern int a = 100;

      这里其实就粗略了解一下即可,更多细节以后会在存储的类别里再给大家讲讲。

🌰2.生命周期

        变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。

        生命周期也可以用在人身上嘛,人的生老病死这么一个过程的时间段呗👶->👴->💀。

        变量啥时候创建的呢?在定义变量的时候开辟了相应的内存空间来存储变量的值,这个时候变量就“诞生”了。

        那变量啥时候“翘辫子”呢?其实吧这和它作用域有关系,局部变量生命周期就是从程序执行到局部变量处开始,局部变量被创建被使用,直到程序执行出了作用域,局部变量被销毁。

        再看看前面这个例子,出了花括号后b就被销毁了,自然在花括号外是被认为是未声明的。

        全局变量生命周期就是程序执行的整个过程。

     

🌰3.全局变量与局部变量可以同名

        综合上面所讲的内容,我们来看看下面的问题。

比如:

会打印哪一个值呢?还是编译失败呢?

在C语言中,

 1. 不允许在同一个作用域中定义多个相同名称的变量

   比如:在一个班级中存在两个名字相同的学生王帅,当老师点王帅回答问题时,那个回答就冲突了

  2. 允许在不同的作用域中定义多个相同名称的变量

   比如:两个班级中各有一个王帅,老师在A班中点王帅回答问题,不会有任何歧义

  3. 不同作用域中定义的变量,在访问时采用就近原则

   比如:你们村有一个小伙伴名字叫刘德华,那你在你们村喊刘德华时,你们村的刘德华就会跑过来响应你,

      而我们世界级别人见人爱的天王他不会理你,因为距离远听不见,但是两个刘德华可以同时存在这个 世界上,只要不在一个村,就不会冲突。

 根据以上描述可知,对于上面那份代码:

  1. 全局作用域中的num和main中的num可以同时存在,不会冲突,因为不是同一个作用域

  2. 在main函数中访问num时,采用就近原则,因此访问的是main中的num,相当于将全局作用域中的num屏蔽了

🌰3.初识各类常量

 这里就初步认识一下各类常量,以后会分别深入讲解的。(等到我整理完写完博客)

C语言中的常量分为以下以下几种:

字面常量     (字面常量就是单纯的常量比如3.14,1000,'a')

const 修饰的常变量

#define 定义的标识符常量

枚举常量

🌰1.const修饰的常变量

        比如说原本有一个变量float a = 20.5;,我可以任意修改它吧,a = 60.5;。

         这时候如果我想让它不能再被修改了呢?那就const float a = 10.5;

        一旦使用了const修饰后,这个变量的值就不能直接修改了, 具有类似于常量的性质。

        举个例子就是,我有一个盒子,我想装游戏机就装,想装鸭舌帽就装,完全凭我需要来使用这个盒子的空间对吧,那要是有一天我突然想让这个盒子只装我的RMB¥咋办,简单,买个🔒一上锁就搞定了,这下这个盒子里装的的东西就不能直接改变了嘛(最起码也得先解开锁)——const就像那把锁头一样嘛,锁住了变量对应的那块空间呗。

        那这玩意儿到底是变量还是常量?我们来简单检验一下

const int n = 10;

int arr[n] = {0};

代码走起来,发现出现错误

        因为数组括号内应该是常量表达式,也就是说这里的n它仍然是变量,本质未变,只是具有了与常量类似的性质。

🌰2.#define定义的标识符常量

        我想要在程序中反复用到一个常量,并且它对于我这个程序有着特定的意义,比如我要求长方体体积,我需要长宽高对吧,为了方便区分,我就想给它们起个名字,高就是height,宽就是width,长就是length,然后呢我这长宽高是给定的常量,那这时候我就可以这样

#define height 100

#define width 50

#define length 200

        这样就定义了三个常量,并且每个常量都给它们定了个名字(也就是标识符),这样我在写程序的时候就可以用标识符来代表我要使用的常量

int V = height * width * length;

        这些标识符在程序运行之前就会自动被替换为对应的变量值,也就是在预处理阶段时变成这样:int V = 100 * 50 * 200;

有什么好处?

1.能很清楚我要用到的常量代表什么意义

2.在多次中多次用到该常量的时候,如果我想要把它的值改变一下,只需要在#define定义的地方把数值改动一下就可以了,不需要在程序中一个一个地改.

🌰3.枚举常量

        什么是枚举?一一列举呗,也就是把常量一一列举出来。

        我们生活中有什么常量是可以一一列举出来的?

        比如性别

enum sex
{
    MALE,  //男性
    FEMALE  //女性
}

这里意思创建了一个数据类型enum sex,它的可能取值为MALE或FEMALE,而这个MALE和FEMALE就是所谓的枚举常量,它们的值不可改变。(不细讲,在自定义类型会讲)

🌰基本数据类型详解

🌰1.关于位,字节和字的区别

它们都是描述计算机数据单元或存储单元的术语,这里主要指存储单元。

        位(bit)是最小的存储单元,即一个二进制位,仅能存储0或1。

        字节(byte)是常用的存储单元,基本上大部分机器1字节均为8位,至少在衡量存储单位的时候是这样的。

        字(word)是设计计算机时给定的自然存储单位,目前的个人计算机有1字长为32位的,计算机字长越大,其数据转移就越快,允许的内存访问也更多。

数据类型关键字

_Complex和_Imaginary分别代表复数和虚数

🌰2.int类型

        有符号整型,必须为整数。

        取值范围与计算机系统有关,一般而言,存储一个int要占用一个机器字长,16位的机器就是用两个字节来存储int,取值范围就是-32768~32767。而目前个人计算机一般是32位的,也就是用4个字节存储int。

🌰1.变量声明

        类型关键字 + 变量名;(其他变量声明都是这样)

        int a;

        int b, c, d, e;

        可以单独声明,也可以同时声明多个变量。

🌰2.注意一下变量的命名

        名字必须是由字母,数字或下划线组成,不能有特殊字符,同时也不能以数字开头。

同时变量名不能是关键字。

如:int double = 10.0;(错)

       int 2people = 100;(错)

       int _2peo = 100;(对)

        变量获得值,有三种途径,一是赋值,如a = 10; ,二是通过函数获得值,如scanf(),三是初始化获得值,可以直接在声明中完成,如int weight  = 100; ,不过要注意不要把未初始化和初始化变量搁在一块,容易误会,如int q, p =100; 。

🌰3.关于进制的显示

转换说明

十进制--%d

八进制--%o

十六进制--%x

若要显示八进制和十六进制的前缀0,0x和0X,必须分别使用%#o,%#x,%#X。

🌰3.其他整型

        当int无法满足各种需求的时候,就需要其他整型了。

        C语言提供3个附属关键字修饰基本整数类型int,有short,long和unsigned(无符号即非负数)。

        为了适应不同的机器,C语言只规定了short占用内存不能多于int,long占用内存不能少于int,而int又与机器字长有关。现在大多都以16或32位存储int(依计算机自然字长定),32位存储long,16位存储short,为存储64位的整数引入了long long类型。

        C标准只对基本数据类型规定了允许的最小大小。

        对于16位机,short和int的最小大小是16位。对于32位机,long的最小大小是32位。

        unsigned short和unsigned int最小是16位,unsigned long最小是32位,而long long和unsigned long long就是64位。

        这也太多了吧,到底该如何选择整型来使用呢?

        对于unsigned类型,常用于计数,因为计数一般是非负数,同时unsigned可以表示更大的正数。

        对于那些long占用内存大于int的系统,一般超出int而在long范围内的数用long类型,但是使用long会减慢运算速度,所以需要斟酌一下,如非必要尽量不用long。

        对于那些long占用内存与int相同的系统,当需要用到32位的整数时使用long可能会更好,能提高可移植性,即使把程序从32位机移植到16位机后仍然可以正常工作。

        为什么呢?因为16位机的long是32位的,int是16位的,原程序若选用int存储32位的整数,移植之后会溢出,而选用long则刚好接收,不用担心溢出。

        类似地,如果是确实需要用到64位的整数才考虑用long long,不然会拖慢运行速度。

        对于常量,通常程序代码中的数字都会被存储为int类型,如果超出了int范围的话编译器会将其视为long int ,再超出就视为unsigned long,要是再超出就视为long long甚至是unsigned long long。

        八进制和十六进制常量若超出范围则是这样:int-->unsigned int-->long-->unsigned long-->long long-->unsigned long long。

        要是有某些特殊需求要把一些较小常量用long存储呢?可以在值的末尾加上后缀l(小写L)或L。

        比如0x55L,100L。LL就是long long后缀,再加上个u或U就是unsigned long long后缀了。

汇总表

🌰4.关于原码反码与补码(这节之后有深入讲解)

        有符号整数在计算机中怎么存储与计算呢?我们知道计算机是用二进制数存储一切数据,那怎么去用二进制数表示负数呢?

        前人想到了取最前面的一位作为符号位来规定正负数,我们下面拿一个字节来举例说明。

一个字节八个二进制位

        原码:第七位作为符号位,当该位值为1时表示负数,为0时表示非负数,这就是原码。

        比如:-100原码

        反码:非负数反码与原码相同,负数反码为原码除了符号位以外按位取反。

        按位取反就是对于单独的一个位的值,如果原来是0就变成1,原来是1就变成0。

        比如:-100的反码

        补码:非负数补码与原码相同,负数补码为反码+1。

        比如:-100的补码

🌰注意:计算机存储和运算时用的都是补码而非原码

        补码利于计算机准确计算,而原码便于我们识别数值。

        以一个字节范围来举例:

        计算5+6 和 -5+6

        溢出的第九位去掉,只取八位

以上就是原反补码的简单介绍了,接下来我们继续深入了解一下。

🌰5.整数溢出问题

🌰1.问题是什么

        实际上溢出行为是C标准未定义行为,不同编译器可能状况不一样,就拿VS来研究一下。

        在VS下unsigned int,int和long都是四字节,short是两字节。

        无论上网一搜还是课本一查,都发现发现int范围为-2148483648~2147483647,而unsigned int范围0~4294967295,那你有没有想过为什么有符号整数正负范围不对称?

        看看下面演示代码,思考一下为什么是这样。

在VS下,int溢出以后从最小值-2147483648开始,分析一下:

        你可能会觉得有点不对劲,按照2147483647 + 1后的补码逆推一下原码会得到0000000000000000000000000000000,那不就是0了吗??

        欸等会儿,0的原码也是这个呀,那为什么printf函数打印a+1得到的却是-2147483648??

🌰2.别急,这就涉及到有符号整数的范围规定了

        我们一点一点来讲,在还没有出现反码和补码的时候,人们发现用原码存储和计算会出现一些奇怪的结果。

(这里以下都用一个字节来演示)

        比如2-1,计算机没有减法这一概念,在执行算术减法时会用加法来计算,即2+(-1),则有

        得到结果居然是-3!

        多少有点离谱了,要是只用原码一遇到负数或减法就得出大问题。

        所以大伙就说用反码试试吧,那好咱就来试试

        还是2+(-1)

        不断往前进1得到了九位二进制数,但是我们只要八位,多出的一位舍去,就得到了1。

        这下不就对上了嘛,计算无误。

        那是不是这样就解决一切问题了呢?我们来看看下面这个例子

        对于1+(-1),得到的11111111取原码就是10000000。

        小伙汁,你看看原码10000000是什么数?是不是想说-0?是不是有点不对劲,怎么会有-0这种东西呢?0既不是负数也不是正数,况且原码00000000已经能表示0了,难不成来个+0=-0=0吗?滑天下之大稽!

        后来大伙捣鼓来捣鼓去,最终搞出了补码,那我们试试补码能不能解决问题。

        对于1+(-1),得到九位二进制数,只要八位,舍去第九位,得到00000000就是0,这不就成了嘛。

        可是原码10000000的数到底是啥?emm,反正不能是-0,实际上我们这里只能由果溯因,

        应该问一下为什么一个字节范围是-128~127而不是-127~127。首先-127~127一共有多少个数?答案是255个,而八位二进制数最多能表示256个十进制数,这不就漏了一个嘛,我们看一下:

        发现了没有?漏了哪一个呢?对,就是10000000,对它按位取反得11111111,再加1得1 00000000,就变成了九位,只要八位,去掉第九位就得到00000000即它的补码。

        现在我们看看-128如何,原码应当为1 10000000有九位,第九位作为符号位,按位取反得1 01111111,再加1得1 10000000发现补码与原码相同。一个字节只要八位,原码去掉第九位就得到了10000000对吧,这不就对上了吗。

        1000 0000  和-128原码丢弃最高位后余下的8位相同,而且即使去掉第九位后的-128和一个字节范围内的其他数(-127~127)运算也不会影响结果, 所以才敢这么表示-128。

        也就是说-128八位原码与补码都为10000000。

        比如:-128 + 125 = -3

        那么127+1结果会是多少呢?答案是-128!01111111+00000001=10000000不就是前面讲了这么一长串的-128嘛。

        这也就意味之数值溢出后从最小值重新记起。

🌰3.让我们回到int范围的问题上来 

        其实原理上差不多,意思就是达到最大正数值后再+1数值溢出了呗,具体参照先前讲的内容就行了。

         这样的话上面一行printf()的输出就弄清楚了,那下面一行的printf()输出为什么会是-1,0,1呢? 

        问题出在哪呢?

        对,b是无符号整型而使用了%d,导致出现意外结果。

        我们结合前面讲的原反补码来分析一下为什么会这样。

        首先提一下前面没讲到的,无符号整型没有所谓所谓原反补码之说,最高位不用来作符号位,所以可以表示的正数值范围更大,无符号整型对应的二进制数就是存在计算机里的二进制数,不需要经过原码到补码的变化过程。相对而言,有符号整型存在计算机里和用于参与计算的都是补码。

        有符号整型int最大正数值是2147483647 < 4294967295,而%d就是告诉计算机我要输出的类型是有符号整型,最高位看成符号位,那好,上图。

        也就是说当成有符号类型的话,4294967295对应二进制数看成补码,求出的原码对应的值就是-1,所以说会输出-1。

        那b+1输出0,b+2输出1就同理了吧。

        其实要用printf的话最好就把转换说明(比如%d之类的)和数据类型对应好,不要使用不匹配的转换说明,否则可能会出大问题。

        在使用%u后输出数值就正常了。

🌰6.char类型 🌰1.基本介绍    

        char类型用来存储字符,但要注意,char是整数类型,实际上存储还是整数。

        还记得前面讲的吗,计算机存储数据都是数字数据,由无数的0和1按一定规定排序组成的,那为啥要叫字符类型?为什么说是用它来存储字符呢?

        实际上是这样的,计算机使用数字编码来处理字符,而我们用特点的整数表示特定的字符,最常用的编码是ASCII编码,比如65代表大写字母A,所谓的存储A实际上存储的是整数65。

        标准ASCII码范围是0~127,而C语言规定char类型占用内存为1字节。

        在C语言中,用单引号括起来的单个字符被称为字符常量,编译器会自动将其转化成对应的代码值,如'A'。

        因为字符是以数值的形式存储的,所以给char类型变量赋int型整数也是没问题的,只是要注意一下范围0~127。

        比如char cat = 65;如果系统能识别ASCII码的话就会认为是把A赋给的cat,但是最好不要这样赋,我也说了如果二字,有些系统不一定用的是ASCII编码,所以用字符'A'赋值最妥当。

🌰2.非打印字符

        注意到了吗,表里有些奇怪的字符根本就打印不出来,如行为字符退格,换行,振铃等,那怎么表示这些字符呢?

方法一:使用ASCII码,比如振铃对应ASCII码值为7,那就char beep = 7;。

方法二:使用特殊的符号序列表示字符,即转义序列也叫转义字符。 

        转义字符顾名思义就是转变意义的字符,一般由\+某个字符组成。

        活跃位置指的是显示设备(如屏幕)中下一个字符将出现的位置,就是平时所说的屏幕光标位置。

        接下来介绍一下常用的转义字符

        \n就是将活跃位置移到下一行的开始处,也就是换行。

        \r把活跃位置移到当前行的开始处,会把前面打印的清除掉。

        \t把活跃位置移到下一个水平制表点(通常是第1个,第9个,第17个,第25个等)

        因为  \,',"  都有特殊作用,所以在打印的时候无法直接打印,这就要用到转义字符了。

        单纯想打印”,printf(" \" ");

        想打印\,printf(" \\ ");

        想打印',printf("\' ");

        看看最后两个转义字符:

        \0oo,\后面是一个八进制数,比如\130,printf("%c", '\130');得到结果是打印出了大写字符X,为什么呢?\130先把130转变为十进制数也就是88,然后变成对应ASCII码值的字符。

        '\0oo'就代表一个字符,前面的0表示是八进制,省略了也是八进制数。 

         \xhh,\x后面是一个十六进制数,类同上面。

        实际上就是用八进制或十六进制的ASCII码来表示一个字符。

        举个例子就是'\101'等价于65等价于'A'。

巩固一下:

        C语言中有字符类型,但是没有字符串类型,使用双引号括起来的就是字符串。

//程序输出什么?
 #include int main()
 {
	printf("%s\n","c:\test8\test.c");     
	return 0;
 } 

        提示:八进制里没有8,'\628'明显不存在,只能是'\62',对应字符'2'。

🌰3.何时使用ASCII码?何时使用转义字符?

        一般选择后者,假设使用'\f'或'\104',明显转义字符更好记并且可移植性更高,因为不使用ASCII码的系统中仍然有效。

        如果要使用ASCII码,一般写成'\032'比032更好,一是前者直接能看出来你想使用的是字符编码,二是前者能嵌入C的字符串中,如printf("hello!\007\n");,能明显把它们和普通字符区分开。

        在使用printf()打印字符的时候,使用不同的转换说明%c或%d打印结果不同。

🌰4.有符号还是无符号char

        有些C编译器把char当成有符号类型,范围为-128~127,而有些编译器把它当成无符号类型,范围为0~255,可以查阅一下limits.h头文件。

        根据C90标准,C语言允许在char前面加上unsigned和signed修饰以区分出无符号和有符号类型而不用管编译器如何。

        因为char实际上存储的是整数,所以可以用在不超过1字节范围大小的小整数的处理上,以节省空间。

🌰7.浮点数类型 🌰 1.简介

        什么是浮点数呀?简单来说就是有小数点浮动的数。

        浮点类型能表示包括小数在内的更大范围的数。

        计算机中表示方法:

        一般记数法即第一列,指数记数法(计算机中的科学记数法)即第三列。

        这里的e是10,e+数字就是10的几次幂。

 有三种类型:float,double和long double

🌰2.看看C标准的规定(了解一下)

        C标准规定float(单精度)类型必须至少能表示小数点后6位有效数字且取值范围至少是10^-37~10^37,通常占用32位,其中8位用于表示指数的值和符号,剩下24位表示非指数部分及其符号。

        C规定的另一种浮点类型为double(双精度)和float的最小取值范围相同,但它至少必须能表示10位有效数字。一般而言double占用64位而非32位,一些系统将多出来的32位全部用来表示非指数部分,增加了有效数字的位数(提高了精度),另一些系统把其中一些位分给了指数部分以容纳更大的指数,从而增加了可表示数的范围,无论哪种方法,double类型的值至少有13位有效数字。

        long double至少与double的精度相同,一般都是比double精度要求更高。

🌰3.表示形式

        浮点型常量的表示形式比较多,比如-1.56E+12,2.87e-3。

        e后面正号可以省略,可以没有小数点,如2E5,也可以没有指数部分,如19.28,但是不能同时没有小数点和指数部分。

        可以省略小数部分,如100.,也可以省略整数部分,如.45,但是不能同时省略小数部分和整数部分。

        一些例子:3.1415,.666,89.,45e-10。

        默认情况下编译器认为浮点型常量是double类型的精度,可以在浮点数后面加上f或F后缀改成float类型,如23.56f。

        也可以加上l或L后缀改成long double类型,如12.5e5L。

🌰4.打印

        打印浮点数的时候,转换说明一般用%f说明打印十进制数的float和double类型数,打印long double用%lf,如果支持C99标准的话可以有%e打印指数记数法的浮点数。


        到这里基本上就把C与数据的基本内容给讲完了,关于其他数据类型如数组,指针,结构和联合等内容还是蛮多的,会单独划分一个大章节来讲述。

        如果有什么补充的话请期待博客下次的更新。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/793872.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存