本文主要介绍C语言中的基本数据类型,整型(short、long、int的组合),浮点型(float、double),字符型(char)。
数据类型的体系:
整型
C语言使用int
关键字来定义整数(int 是 integer 的简写),其中分为三种类型short、int、long
,其中 int 称为整型,short 称为短整型,long 称为长整型,它们又可以相互组合成新的类型。
在现代流行的操作系统中,几乎不会用到short类型,只有在非常底层、旧的平台或者是存储容量非常有限的平台(如51单片机),用得非常的多。
int型
int型拓展:
- short int(可简写为 short),和 int 一样,也是有符号整数;
- long int(简写:long),有符号整数;
- long long int(简写:long long),C99 标准添加的类型,有符号整数;
- unsigned int(简写:unsigned),无符号整数,不能表示负数
- unsigned long int(简写:unsigned long),无符号整数,不能表示负数
- unsigned short int(简写:unsigned short),无符号整数,不能表示负数
- unsigned long long int(简写:unsigned long long)C99 添加的类型,无符号整数
- 一般我们把 short 称为短整型,把 long 称为长整型,把 long long 称为超长整型,把 int 称为整型。unsigned 打头的那些整数类型统称为无符号整型。例如:我们称 unsigned short 为无符号短整型。以此类推。
注意unsigned和signed:
- 所有没有标明 unsigned 的整数类型默认都是有符号整数。
- 在这些整数类型前面加上 signed 可以使读者更清楚地知道
- 这些是有符号整数,尽管有没有 signed 都表示有符号整数。例如:signed int 等同于 int 。
占用内存大小 | |||
类型(单位:字节Byte) | 16位 | 32位 | 64位 |
short int | 2 | 2 | 2 |
int | 2 | 4 | 4 |
unsigned int | 2 | 4 | 4 |
long int | 4 | 4 | 8 |
long long int | 8 | 8 | 8 |
int类型极值分析:
int类型占用4个字节,所以一共32位,那么按理来说,取值范围应该是:
0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111
也就是10进制的0~232 - 1。但是int类型是有正负之分的,包括了正数和负数,那怎么表示负数呢?就是拿最高位来当符号位,当最高位为0就是正数,最高位为1则是负数。即:1000 0000 1001 1011 1000 0000 1001 1011就是一个负数,0000 1001 0000 1101 0000 1001 0000 1101是一个正数。
由于最高位是0才代表正数,因此最大的正数是:
0111 1111 1111 1111 1111 1111 1111 1111,也就是231- 1。
而最小的负数就是:
1000 0000 0000 0000 0000 0000 0000 0000,也就是-231
因此,int类型的取值范围是-231~231- 1。其他类型可按照所占字节数推出!
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <limits.h> //整型数的最小最小值定义在该文件下
#include <float.h> //浮点数数的最小最小值定义在该文件下
int main()
{
printf("short型最小值:%d,最大值:%d\n", SHRT_MIN, SHRT_MAX);
printf("char型最小值:%d,最大值:%d\n", CHAR_MIN, CHAR_MAX);
printf("int型最小值:%d,最大值:%d\n", INT_MIN, INT_MAX);
putchar('\n');
printf("long型的最小值=%d,最大值=%d\n", LONG_MIN, LONG_MAX);
printf("float型的最小值=%e,最大值=%e\n", FLT_MIN, FLT_MAX);
printf("double型的最小值=%e, 最大值=%e\n", DBL_MIN, DBL_MAX);
system("pause");
return 0;
}
/*输出结果:
short型最小值:-32768,最大值:32767
char型最小值:-128,最大值:127
int型最小值:-2147483648,最大值:2147483647
long型的最小值=-2147483648,最大值=2147483647
float型的最小值=1.175494e-38,最大值=3.402823e+38
double型的最小值=2.225074e-308, 最大值=1.797693e+308
*/
long型
long和int都能够存储整型常量,为了区分long和int:
- 1. 一般会在整型常量后面加个小写字母l,比如100l,表示long类型的常量。
- 2. 如果是long long类型呢,就加2个l,比如100ll。
- 3. 如果什么都不加,就是int类型的常量。
因此,100是int类型的常量,100l是long类型的常量,100ll是long long类型的常量。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 100;
long b = 100l;
long long c = 1000ll;
printf("%d,%ld,%lld", a, b, c); //注意输出占位符
printf("\na占空间:%d,b占空间:%d,c占空间:%d\n", sizeof(a), sizeof(b), sizeof(c));
system("pause");
return 0;
}
/*输出:
100,100,1000
a占空间:4,b占空间4,c占空间8
//注意,以上结果是在32位编译器下,如果是64位编译器则是
//int占4B,long占8B,longlong占8B;
*/
字符型char型
- char型,一次只能存储一个字符,一个字节。该个字符以单引号引起来。
- char类型的取值范围为-128到127。
存储范围为什么是-128~127?
- 由于数字在计算机中是以补码形式表示,并且char类型为有符号数,则一字节(8位)中的最高位为符号位。能表示的最大正数二进制形式为“0111 1111”,由于正数补码与原码相同,其原码同样为“0111 1111”,对应十进制为127;
- 同理,能表示的最小负数二进制形式为“1000 0000”,由于这是补码形式,其原码对应为-128。
- 如果是无符号数(unsigned n),那么当八位全部是 1 的时候,1111 1111 那么就是 255。
char类型
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main()
{
char c = 'A';
printf("%c\n", c);
//char c = A;
//错误原因是:标识符A找不到。你直接写个大写A,编译器会认为这个A是一个变量。
//char c = "A";
//错误原因:"A"并不是字符常量,而是字符串常量,将字符串"A"赋值给字符变量c是错误的做法
//char c = 'ABCD';
//编译器会对上面的代码发出警告,并不会报错,因此程序还是能够运行。
//由于变量c只能存储1个单字节字符,最终变量c只存储了'ABCD'中的'D'
//char c = '男';
//在内存中,1个汉字需要用2个字节来存储,而1个字符型变量只占用1个字节的存储空间,
//所以字符型变量不能用来存储汉字。
//1个字符型变量占用1个字节,共8位,因此取值范围是 - 27~27 - 1。
//在这个范围内,你完全可以将字符型变量当做整型变量来使用。
char c1 = -10;
char c2 = 120;
printf("c1=%d c2=%d \n", c1, c2);
//区分数字6和字符6
char c1 = 6;
char c2 = '6';
printf("c1=%d c2=%d \n", c1, c2); //输出6,54('6'字符在ASCII是48+6)
system("pause");
return 0;
}
浮点型
- float称为单精度浮点型,double称为双精度浮点型,long double更长的双精度浮点型。
- 在实际开发中,建议弃用float,只采用double就可以,long double暂时没有必要,但不知道以后的操作系统和编译器对long double是否有改进。
float和double的简单对比:
float | double |
float ff = 9.99f; 后面要加个f,不然会自动转换成double型,且便器器会给出警告! | double dd = 9.999; 后面不用加任何符号 |
输入:%f,输出:%f | 输入:%lf,输出:%f |
4个字节,有效数字6~7位,可以精确到小数点后6位 | 8个字节,有效数字15~16位,也只能精确到小数点后6位 |
float型
IEEE754标准:
这里不展开对IEEE754标准的讲解,对于新手(甚至是多年的老程序员,依然不懂得float的简单特性)来说,先明白怎么在编程中使用才是至关重要的!
float可以存储6~7位有效数字
float可以存储6~7位有效数字
#include <stdio.h>
int main()
{
float f3 = 9.99f; //3位有效数字
float f5 = 99.999f; //5位有效数字
float f6 = 999.999f; //6位有效数字
float f7 = 9999.999f; //7位有效数字
float f8 = 99999.999; //8位有效数字
printf("%f\n", f3);
printf("%f\n", f5);
printf("%f\n", f6);
printf("%f\n", f7);
printf("%f\n", f8);
return 0;
}
/*
输出:
9.990000 3位有效数字,可以准确保存
99.999001 5位,只能较为准确地保存
999.999023 6位,也只能较为准确地保存
9999.999023 7位,也只能较为准确地保存
100000.000000 8位,自动进位,不能准确地保存
*/
float只能保存到小数点后6位
float只能保存到小数点后6位
#include <stdio.h>
int main()
{
float fa = 9.9f;
float fb = 9.99f;
float fc = 9.999f;
float fd = 9.9999f;
float fe = 9.99999f;
float ff = 9.999999f; //float只能精确到小数点后6位
float fg = 9.9999999f; //当小数点后超出了6位,自动进位。
printf("%f\n", fa);
printf("%f\n", fb);
printf("%f\n", fc);
printf("%f\n", fd);
printf("%f\n", fe);
printf("%f\n", ff);
printf("%f\n", fg);
return 0;
}
/*
输出:
9.900000
9.990000
9.999000
9.999900
9.999990
9.999999
10.000000
*/
//结论:float只能保存对精度要去不高(仅小数点后6位)的浮点数据
double型
IEEE754标准:
double可以存储15~16位有效数字
double可以存储15~16位有效数字
#include <stdio.h>
int main()
{
double d2 = 9.9; //两位有效数字
double d12 = 99999999.9999; //12位有效数字
double d15 = 99999999999.9999; //15位有效数字
double d16 = 999999999999.9999; //16位有效数字
double d17 = 9999999999999.9999; //17位有效数字
printf("%f\n", d2);
printf("%f\n", d12);
printf("%f\n", d15);
printf("%f\n", d16);
printf("%f\n", d17);
return 0;
}
/*
输出:
9.900000 2位有效数字,可以准确保存
99999999.999900 12位,可以准确保存
99999999999.999893 15位,只能较为准确地保存
999999999999.999878 16位,也只能较为准确地保存
10000000000000.000000 17位,自动进位,不能准确地保存
*/
double精确到小数点后6位
double精确到小数点后6位
#include <stdio.h>
int main()
{
double da = 9.999999; //小数点后6位
double db = 9.9999999; //小数点后7位,double可以胜任
double dc = 9.9999999999; //小数点后10位
double dd = 9.999999999999999; //小数点后15位
double de = 9.9999999999999999;
double df = 9.99999999999999999; //小数点后17位,不能胜任,产生自动进位
printf("%f\n", da);
printf("%f\n", db);
printf("%f\n", dc);
printf("%f\n", dd);
printf("%f\n", de);
printf("%f\n", df);
return 0;
}
/*
输出:
9.999999
10.000000
10.000000
10.000000
10.000000
10.000000
*/
输入输出控制符
整数型的输入输出的控制符有:
- %d (有符号 10 进制);%u,表示 unsigned ,即无符号 10 进制方式
- %o (无符号 8 进制)或 %x/%X (无符号 16 进制)
long long 类型的输入输出:
- "%lld"和"%llu":是linux下gcc/g++用于long long int类型(64 bits)输入输出的格式符。
- "%I64d"和"%I64u":是Microsoft VC++库里用于输入输出 __int64 类型的格式说明。
字符型的输入输出控制符有:
- %c,按字符方式;
- 也可以使用整数型的控制符,输出的就是其ASCII码;
浮点型:
- 输入时可使用 %f 、 %e/%E 或 %g/%G , scanf 会根据输入数据形式,自动处理。
- 输出时可使用 %f(普通方式)、 %e/%E (指数方式)或 %g/%G (自动选择)。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//整型
void MyInteger()
{
int a;
scanf("%d", &a); //Input a number of integer:
printf("%d\n", a);
printf("%o\n", a);
printf("%x\n", a);
long int aa = 100l;
printf("%d\n", aa); //long型的输出就等同于int型
long long int aaa = 10000ll;
printf("%lld\n", aaa);
printf("\n");
}
//字符型
void MyCharacter()
{
char c;
scanf("%c", &c);
printf("%c", c);
printf("%d", c);
}
//浮点型
void MyFloatDouble()
{
float fa = 3.141592; //最多可保留小数点后6位
double da = 3.141592; //最多也只能保留小数点后6位
printf("%f\n", fa);
printf("%f\n", da); //double和float都可以使用%f作为输出占位符
float fb;
double db;
//scanf("%f %f", &fb, &db); double类型只能使用“%lf”作为输入符,否则获取到的数据是错误的
scanf("%f %lf", &fb, &db);
printf("%f %f\n", fb, db);
}
int main()
{
MyFloatDouble();
return 0;
}
/*输出:
3.141592
3.141592
3.141592653 3.141592653
3.141593 3.141593
*/