C语言复习第一天(下篇)

浮点数的秘密

浮点数在内存中存储的形式:符号位、指数、尾数

类型符号指数尾数
float1位(第31位)8位(第23~30位23位 (第0~22)位
double1位(第63位)11位(第52~62)位52位(第0~51)位
float类型和double类型在计算机内存中的表示方法是一致的,但是由于内存大小不同,所以double类型的精度会比float类型的精度高。

浮点数的转换

1、浮点数成二进制
2、用科学计数法表示二进制数
3、计算指数偏移量之后的值	

注意计算指数时需要加上偏移量,而偏移量的值与类型有关
对于指数6偏移后的值如下:
float :127+6 -->130
double: 1023+6 -->1029
举例:8.25在内存中如何表示(三步走):
1、8.25 ----->1000.01
2、1000.01 ----->1.00001 * 2^3
3、指数偏移 127+3=130 =》
最后存储:符号位 0
指数位 1000 0010‬
尾数位 0000 1000 0000 0000 0000 000

合并起来转换成十六进制数为 —>0x41040000

代码举例查看浮点数在二进制中存储的数值:

#include <stdio.h>
int main()
{
        float f=8.25;    //4 word
        unsigned int * pf=(unsigned int *)(&f);
        printf("0x%x\n",*pf);

}

代码运行结果
在这里插入图片描述

深入思考:int类型和float类型的差异

	int类型可表示范围:2^-31 ~ 2^31-1
	float类型可表示的范围: -3.4*10^38 ~ 3.4*10^38

tips为什么int类型和float类型都是四字节类型,然后float可表示的范围却比int类型大的多呢?
答:因为浮点数是不精确的数,它在内存中的表现形式并不是连续的数,
代码举例:

#include <stdio.h>
int main()
{
    float f = 3.1415f;
    float fl = 123456789;  
    printf("%0.10f\n", f);
    printf("%0.10f\n", fl); 
    return 0;
}

然而输出的结果却是:
在这里插入图片描述
由此可见float类型并不精确。

小结:

1、浮点数类型在内存中表示的方法与整形不同
2、浮点数类型的内存表示法更加复杂
3、float类型和int类型能表示的数的个数是一样的
4、float可表示的数之间不是连续,存在间隙。

tips: 由于内存表示法不一样,浮点型的运算复杂度比整形高。

类型转换

C语言中的数据类型可以进行类型转化
1、强制类型转换
2、隐式类型转换

强制类型转换

强制类型转换的语法:
				1、<type>var_name
				2、<type>value
强制类型转换的结果:
		目标类型能搞容纳目标值-----结果不变
		目标类型不能容纳目标值-----结果产生截断

tips 不是所有类型转换都能成功,当不能进行类型转换是,编译器将报错。
代码举例

#include <stdio.h>
struct TS
{
    int i;
    int j;
};
struct TS ts;
int main()
{
    short s = 0x1122;  
    char c = (char)s;    // 0x22  
    int i = (int)s;      // 0x00001122  
    int j = (int)3.1415; // 3
    unsigned int p = (unsigned int)&ts;
    long l = (long)ts;   // error
    ts = (struct TS)l;   // error
    printf("s = %x\n", s);
    printf("c = %x\n", c);
    printf("i = %x\n", i);
    printf("j = %x\n", j);
    printf("p = %x\n", p);
    printf("&ts = %p\n", &ts);
    return 0;
}

编译结果
提示 :1、自定义结构类型不可强转成基本数据类型
2、基本数据类型也不可强转成自定义结构类型
在这里插入图片描述

隐式类型转换

编译器主动进行的类型转换:
低类型类型转换成高类型-----结果不变
高类型转换成低类型-----结果产生截断

隐式类型转换发生的发生点

在这里插入图片描述
tips
short类型和char类型结合隐式转换成int 类型
代码举例:

#include <stdio.h>

int main()
{
    char c = 'a';
    int i = c;    // safe   
    unsigned int j = 0x11223344;
    short s = j;  // unsafe   
    printf("c = %c\n", c);
    printf("i = %d\n", i);
    printf("j = %x\n", j);
    printf("s = %x\n", s);
    printf("sizeof(c + s) = %d\n", sizeof(c + s)); 
    //注意:short类型和char类型结合隐式转换成int 类型
    return 0;
}

在这里插入图片描述

小结:

1.强制类型转换
	1、强制类型转换由程序员完成
	2、强制类型转换不一定成功,编译器会报错
	3、类型不区分高低,可能产生截断   
2 隐式类型转换
	低转高 --->  安全
	高转低 ---> 不安全 ,长生截断

变量的属性

	1、C语言变量可以有自己的属性
	2、在变量定义前可以加上属性名称
	3、每个属性都有自己的特定的含义

auto

1、auto为C语言的默认属性。
2、声明自动变量,由编译器自动生成并分内存。
3、生成的变量保存在==栈区==。

register

1、register变量声明将局部变量存储与计算机寄存器中
2、只是尝试申请,但不一定成功。
3、存放的值,必须是寄存器可以接受的值。
4、不能用 & 去获得寄存器变量的地址。
5、为什么需要这个属性?
		因为在寄存器中访问变量比在内存中快的多。
#include <stdio.h>

int main()
{
  resigter int j=0;
  printf("%d",&j);
  return 0;
}

在这里插入图片描述

static

1、static 修饰的变量存储在程序静态区
2 、static修饰的变量同样具有作用域限定的作用
	1:static定义在全局的变量,作用域就在此文件
	2: 函数内staic定义的变量,作用域就在此函数

代码举例:

#include <stdio.h>

int f1()
{
    int r = 0;
    
    r++;
    
    return r;
}

int f2()
{
    static int r = 0;
    
    r++;
    
    return r;
}

int main()
{
    auto int i = 0;       // 显示声明 auto 属性,i 为栈变量
    static int k = 0;     // 局部变量 k 的存储区位于静态区,作用域位于 main 中
    register int j = 0;   // 向编译器申请将 j 存储于寄存器中

    printf("%p\n", &i);
    printf("%p\n", &k);
    printf("%p\n", &j);   // error
    for(i=0; i<5; i++)
    {
        printf("%d\n", f1());
    }
    for(i=0; i<5; i++)
    {
        printf("%d\n", f2());
    }
    return 0;
}

代码分析:
在程序没有关闭之前,static变量不会重复定义,因为存储在静态区会保存上一次的值。

extern 关键字

	1、用来声明外部的函数或变量。
		1.告诉编译器变量在其他地方已经分配内存
		2.告诉编译器函数已经在其他地方定义
		3。静态不能extern 会出现错误
	2、extern C用来告诉编译器以C的方式编译程序

在这里插入图片描述
程序举例:

//g.c
int g_i=15;
int getI()
{
    return g_i;
}
//main.c
#include <stdio.h>

extern int getI();
extern int g_i;
int main()
{
	printf("g_i=%d\n", g_i);
    printf("getI()=%d\n", getI());      
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值