# 知识点 #### **1. 变量类型及其占用空间** 在C语言中,变量类型决定了变量可以存储的数据范围以及占用的内存空间大小。以下是四种常见变量类型的详细信息: | 变量类型 | 占用空间 | 数据表示范围 | 说明 | | :------- | :------- | :-------------------------------- | :----------------------------------------------------------- | | `int` | 4字节 | -2,147,483,648 到 2,147,483,647 | 用于存储整数,范围约为 -21亿 到 +21亿。 | | `float` | 4字节 | 约 ±3.4e-38 到 ±3.4e+38 | 单精度浮点数,可存储小数,但精度有限(约6-7位有效数字)。 | | `double` | 8字节 | 约 ±1.7e-308 到 ±1.7e+308 | 双精度浮点数,可存储更大范围和更高精度的小数(约15位有效数字)。 | | `char` | 1字节 | -128 到 127 或 0 到 255(无符号) | 用于存储单个字符,通常表示ASCII码(0-127)。 | #### **2.数据表示范围的限制** - **`int` 类型**: - 范围有限,超出范围会导致溢出。例如: ```c int a = 2147483647; // int 的最大值 a = a + 1; // 溢出,结果未定义 ``` - 解决方法:使用更大范围的类型(如 `long long`)。 - **`char` 类型**: - 只能表示有限数量的字符(ASCII码为0-127)。 - 如果需要表示更多字符(如中文),可以使用多字节编码(如UTF-8)。 - **浮点数类型**: - `float` 和 `double` 虽然可以表示小数,但精度有限。 - 例如: ```c float f = 0.1f; printf("%.20f\n", f); // 输出 0.10000000149011611938(精度损失) ``` #### **3. 类型转换** 在C语言中,类型转换分为两种:**隐式类型转换** 和 **强制类型转换**。 ##### **(1)隐式类型转换** - 编译器自动进行的类型转换,通常发生在不同类型的数据进行运算时。 - 规则:将低精度类型转换为高精度类型(如 `int` → `double`)。 - 示例: ```c int i1 = 5, i2 = 2; double d = 1.0 * i1 / i2; // 隐式将 i1 和 i2 转换为 double 类型 printf("隐式类型转换后的值为: %lf\n", d); // 输出 2.500000 ``` ##### **(2)强制类型转换** - 程序员手动指定类型转换,使用 `(目标类型)` 语法。 - 示例: ``` int i1 = 5, i2 = 2; double d = (double)i1 / i2; // 强制将 i1 转换为 double 类型 printf("强制类型转换后的值为: %lf\n", d); // 输出 2.500000 ``` ------ #### **4. 示例代码** 以下代码演示了类型转换的使用场景: ```c #include int main() { int i1 = 5, i2 = 2; double d; // 未进行类型转换 d = i1 / i2; // 结果为 2.000000(小数部分被丢弃) printf("未进行类型转换的值为: %lf\n", d); // 强制类型转换 d = (double)i1 / i2; // 将 i1 转换为 double 类型 printf("强制类型转换后的值为: %lf\n", d); // 隐式类型转换 d = 1.0 * i1 / i2; // 通过 1.0 触发隐式转换 printf("隐式类型转换后的值为: %lf\n", d); return 0; } ``` **输出结果**: ``` 未进行类型转换的值为: 2.000000 强制类型转换后的值为: 2.500000 隐式类型转换后的值为: 2.500000 ``` 变量类型占用的空间有限,那么使用时,数据的表示范围也就有限,例如int类型数据表示范围是**-21亿到+21亿**,而char字符只占一个字节,理论上能表示256种数据,足够表示ASCII码的128个字符。 之前我们在做运算时,会发现两个整数相除,小数位会被自动丢弃掉,那如果我们不想丢弃小数,就只能使用类型转换了,将整数类型给他转换为小数类型。 类型转换分为强制类型转换和隐式类型转换,下面用代码方式演示 ```c #include int main() { int i1 = 5, i2 = 2; double d; d = i1 / i2; printf("没有进行类型转换的值为:%lf\n", d); d = (double)i1 / i2; // 在变量名前写上想要转换的类型,即可转换为该类型 printf("强制类型转换后的值为:%lf\n", d); d = 1.0 * i1 / i2; printf("隐式类型转换后的值为:%lf\n", d); return 0; } ``` #### **5. 注意事项** 1. **精度损失**: - 强制类型转换可能导致精度损失,尤其是从高精度类型转换为低精度类型时。 - 例如: ```c double d = 3.14; int i = (int)d; // i 的值为 3(小数部分丢失) ``` 2. **溢出问题**: - 当数据超出目标类型的表示范围时,会导致溢出。 - 例如: ```c int i = 2147483647; // int 的最大值 i = i + 1; // 溢出,结果未定义 ``` 3. **隐式转换的陷阱**: - 隐式转换可能导致意外的结果,尤其是在混合类型运算时。 - 例如: ```c int i = 5; float f = i / 2; // f 的值为 2.000000(未触发隐式转换) ``` ------ #### **6. 总结** - **变量类型**决定了数据的表示范围和占用空间。 - **类型转换**分为隐式转换和强制转换,用于在不同类型之间进行数据转换。 - 使用类型转换时,需注意精度损失和溢出问题。 # 练习 ``` 1. 输入如下格式数据 (404) 817-6900 转换成如下格式输出 404.817.6900 ``` ```c #include int main() { int a, b, c; scanf("(%d) %d-%d", &a, &b, &c); printf("%d.%d.%d", a, b, c); return 0; } ``` ``` 2. 计算两个分数相加的结果,结果无需约分 输入 5/6+3/4 输出 38/24 ``` ```c #include int main() { int a, b, c, d; int fenzi, fenmu; scanf("%d/%d+%d/%d", &a, &b, &c, &d); fenzi = a * d + b * c; fenmu = b * d; printf("%d/%d", fenzi, fenmu); return 0; } ``` ``` 3. 输入一个数字x,代表需要支付的钱数,现有100元,20元,5元,1元纸币若干张,想要使用最少的纸币去结清账款,请你计算怎么付,可以让付出去的纸币数量最少 输入 256 输出 付了2张100元,还需要支付56元 付了2张20元,还需要支付16元 付了3张5元,还需要支付1元 付了1张1元,支付完成 ``` ```c #include int main() { int x; // 需要支付的钱款数额 int a100, a20, a5, a1; // a100代表100元纸币需要多少张,依次类推 printf("请输入:"); scanf("%d", &x); a100 = x / 100; // 通过除以100来计算需要付多少100张的纸币,并且C语言中,整数相除可以自动舍弃小数 x = x % 100; // 计算余数,看付完100元的纸币后,接下来还需要付多少钱 printf("付了%d张100元,还需要支付%d元\n", a100, x); a20 = x / 20; x %= 20; // 简写方式,等同于 x = x % 20; printf("付了%d张20元,还需要支付%d元\n", a20, x); a5 = x / 5; x %= 5; printf("付了%d张5元,还需要支付%d元\n", a5, x); printf("付了%d张1元,支付完成\n", x); return 0; } ``` ``` 4. 编写一个程序,输入一个四位数,分别取出他的个十百千位上的数字 输入 1234 输出 ``` ```c #include int main() { int x; int ge, shi, bai, qian; printf("请输入:"); scanf("%d", &x); // 直接除10,取得的余数就是个位的 ge = x % 10; // 除以10,将十位上的数移动到个位上,然后取余10,就可以拿到十位上的数 shi = x / 10 % 10; // 先取余1000可以理解为干掉千位以上的数,留下的三位数,在除100,干掉后面两位数 bai = x % 1000 / 100; // 除1000,直接干掉个十百位数,剩下的就是千位了 qian = x / 1000; printf("个位上的数为:%d\n", ge); printf("十位上的数为:%d\n", shi); printf("白位上的数为:%d\n", bai); printf("千位上的数为:%d\n", qian); return 0; } ```