-
2018-08-19 17:22:40
实型变量
1.实型数据在内存中的存放形式
实型数据一般占4个字节(32位)内存空间。按指数形式存储。实数3.14159在内存中的存放形式如下:
+
.314159
+
1
数符 小数部分 指符 指数
小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高。
指数部分占的位数愈多,则能表示的数值范围愈大。
实际上,小数部分是一个二进制纯小数,指数部分以补码存放。
2.实型变量的分类
实型变量分为:单精度(float型)、双精度(double型)和长双精度(long double型)三类。
在Turbo C中单精度型占4个字节(32位)内存空间,其中数符1位,小数部分23位,指符1位,指数7位,所以其数值范围为3.4E-38~3.4E+38,只能提供6~7位有效数字。双精度型占8 个字节(64位)内存空间,其中数符1位,小数部分23位,指符1位,指数10位,其数值范围为1.7E-308~1.7E+308,可提供15~16位有效数字。
表2.2
类型说明符
比特数(字节数)
有效数字
数的范围
Float
32(4)
6~7
10-37~1038
Double
64(8)
15~16
10-307~10308
long double
128(16)
18~19
10-4931~104932
3.实型变量的定义形式及初始化与整型相同。
类型说明符:float(单精度实型), double(双精度实型)。
例如:
float x=1.27 , y=3.5 4; /*x,y为单精度实型变量,且初值为:1.27和3.54*/
double a,b,c; /* a,b,c为双精度实型变量*/
在计算机中,存放浮点数一般采用定点数和浮点数两种表示方法。C语言中采用的是浮点数表示法,以Turbo C中的float型的7.8125×10-2为例,其数据存储的格式如下
0
10100000000000000000000
1
0000011
数符 小数部分(23位) 指符 指数(7位)
即二进制的0.101×10-11,转化为十进制为0.625×2-3,即7.8125×10-2。
对于double型的数据小数部占53位(包括数符一位),指数部分占11位(包括指符一位)。
对于long double型的数据小数部分占113位(包括数符一位),指数部分占15位(包括指符一位)。
4.实型数据的舍入误差
实型变量也是由有限的存储单元组成的,能提供的有效数字是有限的。这样就会存在舍入误差。看一个例子:
【例2.8】一个较大实数加一个较小实数。
main()
{
float x=7.24356E10, y;
y=x+54;
printf("x=%e\n",x);
printf("y=%e\n",y);
}
程序执行的结果为:
x=7.24356E10
y=7.24356E10
这里x和y的值都是7.24356E10,显然是有问题的,原因是由于float只能保留6~7位有效数字,变量y所加的54被舍弃。因此由于舍入误差的原因,进行计算时,要避免一个较大实数和一个较小实数相加减。
5.实型数据的溢出
【例2.9】
main()
{
float a,b,c,d;
a=1.2E33;
b=0.5E-22;
c=0.25E-21;
d=a/b;
d=d*c;
printf("c=%f\n ",d);
}
结果会出现
Floating point error: Overflow
这是由于程序中a/b的运算的结果超出了float型能表示的范围产生溢出。所以在使用中应避免直接用一个较大的数除以一个较小的数。可以将程序的计算部分d=a/b; d=d*c; 改为:
d=a*c; d=d/b; 或 d=a/b*c;
以避免这种情况的发生。也许有人会提出d=a/b*c为什么不产生溢出哪?其原因是,在Turbo C中float型数据在计算时要先转换为double型数据,计算后再转换为float型数据赋给float变量d。
2.4.3实训 使用实型数据
实训目的:正确书写实型常量,合理选择实型变量存放数据
实训内容:
1、已知三角形的底为2.8cm,高为4.3cm,求三角型的面积。
编程如下:
main()
{float d=2.8,h=4.3, s;
s=d*h/2;
printf(“s=%f”,s);
}
程序运行的结果为:
s=6.020000
2、将摄氏温度27.5度转换为华氏温度。转换公式为
编程如下:
main()
{
float f=27.5,c;
c=5.0/9*(f-32);
printf(“c=%f”,c);
}
程序运行的结果为:
c=-2.500000
3、上机验证1.0/7*7的结果是否为1.0。为什么?
更多相关内容 -
内存中如何存放数据
2019-01-03 09:16:53· 计算机执行程序时,组成程序的指令和程序所操作的数据都必须存放在某个地方 · 这个地方就是计算机的内存(也称为主存或随机访问存储器),类比人类的大脑,内存就是程序员的一切,非常重要 注意:主存和...1、计算机使用内存来记忆或存储计算时使用的数据
· 计算机执行程序时,组成程序的指令和程序所操作的数据都必须存放在某个地方
· 这个地方就是计算机的内存(也称为主存或随机访问存储器),类比人类的大脑,内存就是程序员的一切,非常重要
注意:主存和RAM的区别
2、组成计算机内存的单位是bit(位)。binary digit(二进制数字)
8 bit(比特) = 1 byte (字节)
10M带宽:10M bps( bit per second )
内存分配方式
内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
常见的内存错误及其对策
发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。
常见的内存错误及其对策如下:
-
内存分配未成功,却使用了它。
编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
-
内存分配虽然成功,但是尚未初始化就引用它。
犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。
内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
-
内存分配成功并且已经初始化,但操作越过了内存的边界。
例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。
-
忘记了释放内存,造成内存泄露。
含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。
动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。
-
释放了内存却继续使用它。
有三种情况:
(1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。
(2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。(return ?)
(3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。
【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
· 动态内存会被自动释放吗?
函数体内的局部变量在函数结束时自动消亡。很多人误以为示例是正确的。理由是p是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉!
void Func(void) { char p = (char ) malloc(100); // 动态内存会自动释放吗? }
我们发现指针有一些“似是而非”的特征:
(1)指针消亡了,并不表示它所指的内存会被自动释放。
(2)内存被释放了,并不表示指针会消亡或者成了NULL指针。
这表明释放内存并不是一件可以草率对待的事。也许有人不服气,一定要找出可以草率行事的理由:
如果程序终止了运行,一切指针都会消亡,动态内存会被操作系统回收。既然如此,在程序临终前,就可以不必释放内存、不必将指针设置为NULL了。终于可以偷懒而不会发生错误了吧? 想得美。如果别人把那段程序取出来用到其它地方怎么办?
· 内存耗尽怎么办?
如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。通常有三种方式处理“内存耗尽”问题。
(1)判断指针是否为NULL,如果是则马上用return语句终止本函数。例如:
void Func(void) { A *a = new A; if(a == NULL) { return; } … }
(2)判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行。例如:
void Func(void) { A *a = new A; if(a == NULL) { cout << “Memory Exhausted” << endl; exit(1); } … }
(3)为new和malloc设置异常处理函数。例如Visual C++可以用_set_new_hander函数为new设置用户自己定义的异常处理函数,也可以让malloc享用与new相同的异常处理函数。
上述(1)(2)方式使用最普遍。如果一个函数内有多处需要申请动态内存,那么方式(1)就显得力不从心(释放内存很麻烦),应该用方式(2)来处理。 很多人不忍心用exit(1),问:“不编写出错处理程序,让操作系统自己解决行不行?”
不行。如果发生“内存耗尽”这样的事情,一般说来应用程序已经无药可救。如果不用exit(1) 把坏程序杀死,它可能会害死操作系统。道理如同:如果不把歹徒击毙,歹徒在老死之前会犯下更多的罪。
有一个很重要的现象要告诉大家。对于32位以上的应用程序而言,无论怎样使用malloc与new,几乎不可能导致“内存耗尽”。我在Windows 98下用Visual C++编写了测试程序,见示例。这个程序会无休止地运行下去,根本不会终止。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,Window 98已经累得对键盘、鼠标毫无反应。 我可以得出这么一个结论:对于32位以上的应用程序,“内存耗尽”错误处理程序毫无用处。这下可把Unix和Windows程序员们乐坏了:反正错误处理程序不起作用,我就不写了,省了很多麻烦。 必须强调:不加错误处理将导致程序的质量很差,千万不可因小失大。
void main(void) { float *p = NULL; while(TRUE) { p = new float[1000000]; cout << “eat memory” << endl; if(p==NULL) exit(1); } }
-
-
数据在内存中的存放的几个形式
2009-07-06 22:07:59详细介绍了数据在内存中的存放的几个形式:如栈区(stack)——由编译器自动分配并且释放,该区域一般存放函数的参数值、局部变量的值............. -
在C语言里二维数组在内存中的存放顺序是什么?
2021-05-19 14:38:16在c语言里二维数组在内存中的存放顺序是按行存放的,二维数组A[m][n],这是一个m行,n列的二维数组,设a[p][q]为A的第一个元素,即二维数组的行下标从p到【m+p】,列下标从q到【n+q】即可。在c语言里二维数组元素在...在c语言里二维数组在内存中的存放顺序是按行存放的,二维数组A[m][n],这是一个m行,n列的二维数组,设a[p][q]为A的第一个元素,即二维数组的行下标从p到【m+p】,列下标从q到【n+q】即可。
在c语言里二维数组元素在内存中是按行存放的。
二维数组A[m][n],这是一个m行,n列的二维数组。设a[p][q]为A的第一个元素,即二维数组的行下标从p到m+p,列下标从q到n+q,按“行优先顺序”存储时则元素a[i][j]的地址计算为:LOC(a[i][j]) = LOC(a[p][q]) + ((i − p) * n + (j − q)) * t;
按“列优先顺序”存储时,地址计算为:LOC(a[i][j]) = LOC(a[p][q]) + ((j − q) * m + (i − p)) * t;
存放该数组至少需要的单元数为(m-p+1) * (n-q+1) * t个字节。
扩展资料:
C++动态二维数组:
以整形为例,row为行数,col为列数
int **data;//存储二维数组的指针,指向指针的指针。
date=x[0][0]的地址,这样标会更好。因为sizeof(date)结果为4不可能存下二维数组。//以下实现如何申请内存
data = new int *[row];
for (int k = 0; k < row; k++)
{
data[k] = new int[col];
}//赋值跟普通二维数组一样 例如
data[0][0] = 5; //将二维数组1行1列(C++中称为0行0列)赋值为5
//删除内存
for (int i = 0 ; i < row; ++i)
{
delete [] data[i]; //此处的[]不可省略
}
delete [] data;
推荐教程:《c视频教程》
-
内存的分区与数据的存放
2018-07-23 19:34:58典型的存储器安排(Linux下的内存分配) 栈区:由编译器自动分配与释放。用于存放局部变量、函数参数、函数返回值。特点:效率高,但空间大小有限。 堆区:使用malloc或者new开辟的空间都是在堆上分配的,需要...典型的存储器安排(Linux下的内存分配)
栈区:由编译器自动分配与释放。用于存放局部变量、函数参数、函数返回值。特点:效率高,但空间大小有限。
堆区:使用malloc或者new开辟的空间都是在堆上分配的,需要程序员显示地释放。如果没有释放,在程序运行结束时可能由OS回收。特点:使用灵活,空间较大,但容易出错。
BSS:没有进行未初始化操作的全局变量和静态变量放在该区,会被自动初始化为0。
数据区:初始化后的全局变量和静态变量还有常量放在该区。
注意:有的人也会把BSS和数据都叫做数据区。
(自由存储区):实际上就是堆区,虽然网上有很多说它是跟堆类似的,但是经过我的多次测试发现它其实就是在堆区,此外,还有一个解释,那就是new的底层是调用了malloc函数的,new开辟的空间是在堆上,那么malloc不也应该是在堆上么。
只读数据区(字面常量区):该区界于代码区和数据区之间,有的人把它归类于代码区,也有的人把它归类于数据区。不管怎么归类,只要自己清楚它是在数据区和代码区的之间就行了。该区一般用于存储只读数据的,字面常量都存在这个区里边。
这里需要注意的是const修饰的变量并不会存放在该区,而是取决于它定义的地方,局部定义的就存在栈区,全局定义的就存放在静态区。可能有的人会疑惑,const修饰的变量不是不能修改的么,是只读的,那应该存在只读数据区啊,事实上,C语言中,使用const修饰了一个变量,该变量不能直接修改,但是我们可以通过拿到这个变量的地址,然后通过它的地址来修改它,如果存放在只读数据区,拿到地址也是没法修改的。
#include <iostream> using namespace std; #include <stdio.h> #include <stdlib.h> int d; //静态区(全局区) int e = 5; //静态区(全局区) static int f = 6; //静态区(全局区) static int g; //静态区(全局区) void FunTest() { int *p1 = (int*)malloc(sizeof(int)); //在堆上开辟 int *p2 = new int; //在堆上开辟 cout << "用malloc申请 p1: " << p1 << endl << endl; cout << "用new申请 p2: " << p2 << endl << endl; } int main() { int a = 2; //栈 int b; //栈 static int c = 4; //静态区(全局区) static int h; //静态区(全局区) const char* p = "abcde"; //p在栈上,“abcde”在常量区 cout << "局部变量初始化 a : " << &a << " " << a << endl << endl; cout << "局部变量未初始化 b: " << &b << " " << b << endl << endl; cout << "静态局部变量初始化 c: " << &c << " " << c << endl << endl; cout << "静态局部变量未初始化 h: " << &h << " " << h << endl << endl; cout << "全局未初始化 d: " << &d << " " << d << endl << endl; cout << "全局初始化 e: " << &e << " " << e << endl << endl; cout << "静态初始化 f: " << &f << " " << f << endl << endl; cout << "静态未初始化 g: " << &g << " " << g << endl << endl; cout << "指向常量字符串的指针 p: " << &p << endl << endl; FunTest(); return 0; }
-
数据在内存中存放的顺序之字节序(附图解、判断本机大小端程序及例题)【建议收藏食用】
2021-09-07 13:31:32数据在内存中存放的顺序(字节序之Little-Endian&Big-Endian) 引言???? 我们学习了整型在内存中是以原反补码的形式存储的,我们还学习了浮点型在内存中是以符号位(S)指数位(E)有效数字(M)的形式存储的。... -
在计算机内存中要存放256个ASCII码字符,需多大存储空间
2021-07-23 04:21:58ascii码换算的最小单位是字节,所以在计算机内存中要存放256个ASCII码字符,需要256个字节的存储空间。字节(Byte)是存储数据的基本单位,并且是硬件所能访问的最小单位。CPU 只能直接处理内存数据,不能直接处理硬盘... -
数据在内存中的存储方式——数据类型、内存地址
2019-04-20 13:33:12一、数据类型 首先必须得明白,在计算机中,任何文件、图片、视频等都是以二进制格式储存在储存介质中的一串编码,对于二进制数的每一位称作1bit(比特)。这里必须得再说一下,byte(字节)和bit(比特)不是同一... -
指令和数据均存放在内存中,计算机如何区分它们是指令还是数据
2019-05-03 15:48:12这样,虽然指令和数据都是以0、1代码形式存在存储器中,但CPU可以判断出在取指阶段访存取出的0、1代码是指令;在执行阶段访存取出的0、1代码是数据。 计算机区分指令和数据有以下2种方法: 通过不同的时间段来... -
内存条是如何存储数据的?
2021-07-28 00:12:35在计算机的组成结构中,有一个很重要的部分,就是存储器。存储器是用来存储程序和数据的部件,对于计算机来说,有了存储器,才有记忆功能,才能保证正常工作。存储器的种类很多,按其用途可分为主存储器和辅助存储器... -
整型数据在内存中的存放形式
2017-08-24 20:50:00整型数据在内存中是以其二进制的补码的形式存放的! 1.原码 就是以最高位作为符号位,0代表该数值为正,1代表为负! 比如:67和-67 2.反码 正数的原码、反码、补码相同! 负数的反码是在其符号位不变的基础... -
计算机中用来存放程序和数据的部件是什么
2021-07-15 04:38:31它们的作用就是用于存放大量的数据以及软件的,并且能够长期存放,而短期存放数据的则为内存。计算机中用来存放程序和数据的部件是什么该部件官方称呼是外存储器,也叫外辅存储器,它是计算机专门用于长时间存放数据... -
内存里数据的存放问题
2016-12-02 04:34:45int数据存放时第一位是高地址还是低地址,就是比如我存放1是按00000001还是01000000 -
深入理解数组-数组在内存中是怎么存放的
2018-11-13 16:05:422、存放数据类型相同 3、数组必须先进行初始化才能使用 如果定义数组变量时没有进行初始化、系统会为数组赋默认值 整数类型-byte、short、int、long,默认值是 0 浮点类型-float、double ,默认值是 0.0 字符类型-... -
详解数据在内存中的真实存放次序:位序、字节序、大/小端模式与结构体、位域
2016-09-26 09:54:35计算机学科中的很多问题,都是因为概念的...几经周折,结合多篇文章,对内存中数据存放次序终于有了较深入的理解,现记录如下: 一、几个概念: 1.内存中关于数据的存放顺序有三个层次(即三种不同的视角): -
java数据在内存中存储详解
2020-10-30 14:46:57说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出,此说法不虚,但掌握Java的底层实现对Java程序员来说是至关重要的,本文介绍了Java中的数据在内存中的存储。 2 内存中的堆(stack)与... -
数据在内存中的存储形式
2019-09-27 15:48:54字符数据类型,在内存中占一个字节 short 短整型,在内存中占两个字节 int 整形,在16位的平台中占两个字节,在32位平台中占四个字节 long 长整型,在32位平台中占四个字节,在64位平台中占八个... -
java数据在内存中的存放问题
2015-10-06 12:54:00问题是这样的,作为java新手,最近老搞不明白数据在内存中到底存放位置的问题。查了许多资料后,得出个结论,请有错误的帮忙指正,谢谢。 基本类型的数值会存放在栈中,执行效率高;引用对象(不包括String类型)的... -
数据在内存中的存放顺序,大端小端问题
2018-12-11 23:37:46不同的数据占用的bit不同,如int型数据为4bit,char型为2bit,那么这些数据各bit在内存中的存放顺序是什么? ##2.1这里涉及大端存储小端存储 大端存储:数据高位存放在低地址,数据低位存放在高地址 小端存储:... -
二维数组在内存中存放图解
2018-11-15 10:44:15 -
C语言中数据在内存如何存储——数据类型
2019-06-24 14:55:46数据类型 【知识点】 数据类型 整型 字符型 实数(浮点型)型 【内容】 一、数据类型 ...C语言要求在定义所有的变量时都要指定变量的类型。...在数学中,数值是不分...而在计算机中,数据是存放在存储单元中的,它是... -
ArrayList中每个数据占用的内存大小
2020-12-23 03:08:29更广义地说, 实现自动内存回收, 是要在占用内存的对象中保存更多的信息, 而不仅仅是对象的值本身. 如, 有单属性int的对象, 必然会占用超过4字节(32位系统中存储int值需要的内存数).除了要存储... -
数据在内存中的存储(详细版)
2020-11-12 17:08:57数据在内存中的存储一、整型在内存中的存储1、字节序(1)小端字节序(2)大端字节序(3)写一个程序判断是否为大端字节序2、原码补码反码(1)补码(2)补码的意义二、浮点型在内存中的存储1、浮点型2、浮点数的... -
实测数据在内存中的存放:大小端模式
2013-02-02 16:26:48最近在学习C语言深度剖析,读到了关于数据在内存中的存放:大端、小端模式... 关于 big-endian and little-endian ... 自编Test小程序: #include #include int main(void) { int a[5] ... -
在内存数据区中从BUF1为首地址存放了10个字节数据,编程完成将数据块复制到BUF2为首址的存储区中。
2021-11-18 12:37:01BUF1中内容复制到BUF2中 -
8088系统数据存放方式
2019-01-03 22:39:32通过实验掌握8088系统中数据在内存中的存放方式和内存操作数的几种寻址方式,求累加和程序和多字节加减法程序 -
java 字节流——将硬盘中的文件读到内存中,将内存中的数据写入硬盘中
2019-05-20 08:46:39分配一块内存空间 临时的空间 存放我文件的数据 byte[] b=new byte[in.available()]; //2.将数据读入到内存空间 in.read(b); //3.将数据转换为字符串 //如果编码是UTF-8 可以省略 String s=new String(b...