1 示例程序
platinum.c
/* platinum.c -- your weight in platinum */
#include <stdio.h>
int main(void)
{
float weight; /* 你的体重 */
float value; /* 相同重量的白金价值 */
printf("Are you worth your weight in platinum?\n");
printf("Let's check it out.\n");
printf("Please enter your weight in pounds: ");
/* 获取用户的输入 */
scanf("%f", &weight);
/* 假设白金的价格是每盎司$1700 */
/* 14.5883用于把英镑常衡盎司转换为金衡盎司 */
value = 1700.0 * weight * 14.5833;
printf("Your weight in platinum is worth %.2f.\n", value);
printf("You are easily worth that! If platinum prices drop,\n");
printf("eat more to maintain your value!\n");
getchar();
return 0;
}
编译程序,会出现从“double”转换到“float”,可能丢失数据
原因是 1700.0 从double 转为了 float 类型。
执行结果:
数据类型关键字:
浮点数的存储方式:
特殊的存储方式,决定了浮点数可能会丢失精度。
浮点数的存储格式:0.3141E1。
2 数据类型
1 字长:
可以看到,字长实际上是处理器数据总线的宽度,反映了CPU一次能够读取多少位的数据。
2 int
可以看到,int 通常占用一个机器字长的存储空间。16位机(8086)中的 int 为16位,32位机(如stm32)中的 int 为32位。
int 类型变量的声明与初始化
八进制和十六进制
在C语言中,以特定的前缀表示使用哪种进制。如0X或0x前缀,表示十六进制,所以十进制数16,表示成16进制为0X10;类似的,0前缀表示八进制,十进制数16表示成8进制为020。
打印选项:%o 以八进制打印; %x 以十六进制打印;
如果要显示0和0x前缀,要在转换说明中加#,如%#o %#x %#X
/* 以十进制 八进制 十六进制打印十进制数100 */
#include <stdio.h>
int main(void)
{
int x = 100;
printf("十进制 = %d\t八进制 = %o\t十六进制 = %x\n", x, x, x);
printf("十进制 = %d\t八进制 = %#o\t十六进制 = %#x\t十六进制 = %#X\n", x, x, x, x);
return 0;
}
运行结果:
十进制 = 100 八进制 = 144 十六进制 = 64
十进制 = 100 八进制 = 0144 十六进制 = 0x64 十六进制 = 0X64
其他整型变量
short int 占用的空间可能比 int 少,long int 占用的空间可能比 int 多;
long long int 占用的空间可能比 long int 多,而且该类型至少占据 64 位;
long 常量和 long long 常量
通常情况下,编译器会根据常量的值,来自动确定常量的类型。但有时需要用 long 来存储较小的值,如内存地址。此时,可以通过增加后缀L来强行变为 long 类型。
打印 short long unsigned 类型
3 char
1 字符变量的声明
2 转义序列
#include <stdio.h>
int main(void)
{
printf("Gramps sez, \" \\ is a backslash.\"\n");
return 0;
}
// 输出
Gramps sez, " \ is a backslash."
%c 打印字符
可移植类型:stdint.h
4 _Bool
布尔类型:_Bool,包含头文件 stdbool.h,布尔类型取值 true 和 false
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
_Bool logic = true;
if (logic)
{
printf("This is logic \"true\"\n");
}
return 0;
}
5 浮点型
1 float 至少能精确到6位有效数字,double 至少能精确10位有效数字,long double 精度至少与 double 相同。
默认情况下,编译器假定浮点型常量是 double 类型的精度。例如,假设 some 是 float 类型的变量,编写下面的语句:
float some = 2.0 * 4.0;
通常,2.0和4.0被存储为64位的 double 类型,使用双精度的乘法计算,然后将乘积截断成 float 类型的宽度。这样做虽然精度更高,但是会减慢程序的运行速度。
在浮点数后加上 f 或 F 后缀可覆盖默认设置,编译器会将 浮点型常量看作 float 类型。使用 l 或 L后缀,可以将浮点型常量看作 long double 类型。如果不加后缀 f ,编译时可能会提示警告如下:
warning C4244: “=”: 从“double”转换到“float”,可能丢失数据
2 打印浮点值
3 类型大小 sizeof
sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小。C99提供%zd转换说明,来匹配sizeof的返回类型。一些不支持C99和C11的编译器,可以用%u或%lu代替%zd。
#include <stdio.h>
int main(void)
{
/* %zd 匹配 sizeof 的返回类型 */
printf("Type int have %zd bytes.\n", sizeof(int));
printf("Type float have %zd bytes.\n", sizeof(float));
printf("Type double have %zd bytes.\n", sizeof(double));
return 0;
}
6 使用数据类型
类型转换
浮点数(float double)转换成整数(int)类型时,小数部分会直接截断
#include <stdio.h>
int main(void)
{
int cost = 12.99;
printf("cost is %d.\n", cost);
return 0;
}
// 编译提示
“初始化”: 从“double”转换到“int”,可能丢失数据
cost is 12. // 小数部分直接截断
7 刷新缓冲区