long,顾名思义是“长”的意思
在C语言中long关键字常见于声明长整型变量,主要特征就是其占用内存的长度不会比int短(注意是大于等于关系,后面有解释)
而且在C99标准中还添加了long long这样的类型,相比较int其一个优势就是能表示更大的数据区间
long的作用是:
声明长整型变量。
1、长整型变量的声明
相对于普通的int整型,长整型和短整型被称之为“其他整数类型”,但它们声明变量的方式是差不多的:
int number; /* int整型 */
long int longNumber; /* 长整型 */
long longNumber2; /* 长整型的另一种声明方式 */
unsigned long uLongNumber; /* 声明为无符号的长整型 */
long long max; /* 很长的整数类型 */
2、能表示的范围
这里的举例按照Windows XP或者Macintosh PowerPC的配置,即认为int和long都是32位,long long是64位来计算:
int(4byte = 32bit):-2147483648 ~ 2147483647
unsigned int(4byte = 32bit):0 ~ 4294967295
long(4byte = 32bit):-2147483648 ~ 2147483647
unsigned long(4byte = 32bit):0 ~ 4294967295
long long(8byte = 64bit):-9223372036854775808 ~ 9223372036854775807
unsigned long long(8byte = 64bit):0 ~ 18446744073709551615
(注1:-2147483648 ~ 2147483647也是C语言标准规定的long类型的最小取值范围)
(注2:目前比较常规的情况是,long long占64位,long占32位,short短整型占16位,int占位根据机器的自然字大小而定16/32)
3、整数溢出
由上面我们知道,计算机内用整数类型表示的数据是有取值范围限制的,那如果存在程序计算过程中超出表示范围的情况呢?
这种情况在计算机科学里常称之为“溢出”,即计算结果超出了数据类型的表示范围,不能正确表示理论上的正确值
int max = INT_MAX; /* max是int类型能表示的最大值 */
unsigned umax = UINT_MAX; /* umax是unsigned int能表示的最大值 */
printf("%d, %d, %d\n", max, max + 1, max + 2);
/*
结果为:2147483647, -2147483648, -2147483647
*/
printf("%d, %d, %d\n", umax, umax + 1, umax + 2);
/*
结果为:4294967295, 0, 1
*/
通过观察你也能发现,其实整数溢出的处理形式和某些计重器类似,指针转了一圈后如果不够表示指针还会继续转圈
当然C语言不同于那种会在内环再标记转了两圈后应该是多重的秤,C语言的整数走完“一圈”,或者说溢出后,只会从头开始
而从头开始的值基本取决于是有符号类型或者说无符号类型
4、long常量和long long常量
现在你见到int MONTHS = 12;就会知道,我们把MONTHS这个整型变量赋值为12
但你是否有想过,我们为什么能这样做,C是怎样看待表达式中12这个部分的呢?
其实在显式对整型变量赋值时,这个数字在C语言中被称为整数常量
而且对于12、1024这样的单纯数字,C会默认为其是int类型,除非1000000这样的超出了int表示范围的数
那1000000这样的情况会怎样呢?其实C编译器遇到这种情况发现int不够了,就会用long int类型去尝试,再不行就unsigned long再尝试
往后会依次用long long,unsigned long long类型去尝试(前提是机器支持这些类型)
当然我们也可以显式地告诉编译器把一个数值不大的常量用long或者long long等类型存储:
/* 在支持long long类型的机器中 */
int a = 10; /* int类型常量10 */
long int b = 10L; /* long类型常量10 */
long long c = 10LL; /* long long类型常量10 */
long d = 021L; /* long类型的八进制数021 */
long long e = 0x23LL; /* long long类型的十六进制数0x23 */
unsigned long long f = 14LLU; /* unsigned long long类型常量14 */
unsigned long long g = 5ull; /* unsigned long long的第二种后缀 */
5、long的输入输出
如果你了解int的输入输出,那么long和long long等类型的输入输出则是大同小异的,需要注意的就是长整型本身的几个说明符:
long int i;
scanf("%ld", &i); /* %ld是long类型的说明符 */
printf("%lo, %lx", m, n); /* %lo和%lx分别是long类型八进制和十六进制 */
printf("%lu", p); /* %lu是unsigned long类型 */
printf("%lld, %llu", m, n); /* %lld是long long类型,%llu是unsigned long long类型 */
此处非常要注意的是,一定要注意变量是有符号类型输入输出还是无符号类型输入输出
如果你对同一个unsigned类型的变量用%u和%d输出,得到的结果可能是完全不一样的,显然%d大概率输出的是错误结果
因为计算机的存储中,一个无符号数和一个有符号数在内存中的表示可能是相同的,其根本区别就在于是否把某一位看做符号位
——参考《C Primer Plus第五版》
相关文章:
C语言关键字浅析-int
C语言关键字浅析-short
C语言关键字浅析-signed
C语言关键字浅析-unsigned