# 三. Issues

说明文字。

  1. [关于float类型和int类型相乘的问题](#1. 关于float类型和int类型相乘的问题)
  2. [对存储类的理解](#2. 对存储类的理解)
  3. [占位符%d、%3d、%-3d的区别](#3. 占位符%d、%3d、%-3d的区别)
  4. [计算机中的位,字节,字,字长的概念](#4. 计算机中的位,字节,字,字长的概念)
  5. [全局变量和静态变量](#5. 全局变量和静态变量)
  6. [共用体的使用](#6. 共用体的使用)

# 1. 关于float类型和int类型相乘的问题

问题描述:float类型与int类型数据相乘,会存在精度丢失的情况。

问题分析:规定输出结果为float类型,使用系统平台为win10

1.11 * 100 = 111.000000
1.111 * 100 = 111.099998
1.1111 * 100 = 111.110001
1.11111 * 100 = 111.111000
1.111111 * 100 = 111.111099
1.1111111 * 100 = 111.111107
1.11111111 * 100 = 111.111115
...
1.1111111111111 * 100 = 111.111115

原因:

1.111转化为二进制以后是1.000111000110101...,这个数字无法用二进制完全表示,这才导致了上述现象。

二进制转换网页:https://tool.oschina.net/hexconvert/

另外:

在一则博客中,在arm-linux环境下,float与int类型数据相乘,int类型首先会转化为float类型再乘,其要点在于如果一个运算符两边的运算数类型不同,先要将其转换为相同的类型,即较低类型转换为较高类型,然后再参加运算。

同时发现的小知识:

输出的时候用“%f”或者“%lf”表示double都是可以的,但是输入的时候double只能用“%lf”表示。

# 2. 对存储类的理解

存储类定义C程序中变量/函数的范围(可见性)和生命周期,这些说明符放置在它们所修饰的类型之前。

存储类 说明
auto auto是所有局部变量默认的存储类。
register register存储类用于定义存储在寄存器中而不是 RAM 中的局部变量,其最大尺寸等于寄存器的大小(通常是一个字)。
static static存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。(多次调用该局部变量,不会每次重新定义,而是用的旧值)
extern extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 extern时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。用于当有两个或多个文件共享相同的全局变量或函数的时候。

# 3. 占位符%d、%3d、%-3d的区别

/*
一般为了让输出内容对其,可以用这个知识
*/
printf("%d\n", 0); // 输出: 0
printf("%3d\n", 0); // 输出: _ _ 0 (其中_表示空格)
printf("%-3d\n", 0); // 输出: 0 _ _

# 4. 计算机中的位,字节,字,字长的概念

存储名称 概念
位表示的是二进制位,一般称为比特,是计算机存储的最小单位。
字节 字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)
计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。一个字通常由一个或多个字节构成。
字长 计算机的每个字所包含的位数称为字长,其长度由计算机平台决定。

# 5. 全局变量和静态变量

1)全局变量和静态变量存储区分为DATA段和BSS段,其中DATA段(全局初始化区)存放初始化的全局变量和静态变量,BSS段(全局位初始化区)存放未初始化的全局变量和静态变量;

2)空间分配的地方在应用程序的 main() 函数前的全局数据声明和定义处;

3)在修饰变量的时候,static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。

4)static 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。

5)static 修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。static 修饰的变量存放在全局数据区的静态变量区,包括全局静态变量和局部静态变量,都在全局数据区分配内存。初始化的时候自动初始化为 0。

6)不想被释放的时候,可以使用static修饰。比如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调用结束释放可以使用 static 修饰。

7)考虑到数据安全性(当程序想要使用全局变量的时候应该先考虑使用 static)。

综上:存储分区;存储位置;只初始化一次;本文件访问变量;本文件访问函数;生命周期;安全性

# 6. 共用体的使用

共用体最大的特点就是成员变量共用一块内存,也因此一回只能操作一个变量,如果修改一个成员变量,另一个成员变量的值会导致污染。不过基于这个特点,可以做一些有趣的应用,比如两个变量,一个用来定义结构,一个用来做访问,方便阅读;也可以用来做类型转换。

可以参考:https://blog.csdn.net/alex_xhl/article/details/8189004