Menu Close

整数类型, 整型变量,整型变量的溢出

1.简介

整数类型用来表示较大的整数,类型声明使用int关键字。

int a;

上面示例声明了一个整数变量a

不同计算机的int类型的大小是不一样的。比较常见的是使用4个字节(32位)存储一个int类型的值,但是2个字节(16位)或8个字节(64位)也有可能使用。它们可以表示的整数范围如下。

  • 16位:-32,768 到 32,767。
  • 32位:-2,147,483,648 到 2,147,483,647。
  • 64位:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。

2. signed,unsigned 

C 语言使用signed关键字,表示一个类型带有正负号,包含负值;使用unsigned关键字,表示该类型不带有正负号,只能表示零和正整数。

对于int类型,默认是带有正负号的,也就是说int等同于signed int。由于这是默认情况,关键字signed一般都省略不写,但是写了也不算错。

signed int a; // 等同于 
int a;

int类型也可以不带正负号,只表示非负整数。这时就必须使用关键字unsigned声明变量。

unsigned int a;

整数变量声明为unsigned的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的signed int最大值为32,767,而unsigned int的最大值增大到了65,535。

unsigned int里面的int可以省略,所以上面的变量声明也可以写成下面这样。

unsigned a;

字符类型char也可以设置signed和unsigned。

signed char c; // 范围为 -128 到 127 
unsigned char c; // 范围为 0 到 255

注意,C 语言规定char类型默认是否带有正负号,由当前系统决定。这就是说,char不等同于signed char;它有可能是signed char,也有可能是unsigned char

这一点与int不同,int就是等同于signed int

3.整数的子类型

如果int类型使用4个或8个字节表示一个整数,对于小整数,这样做很浪费空间。另一方面,某些场合需要更大的整数,8个字节还不够。为了解决这些问题,C 语言在int类型之外,又提供了三个整数的子类型。这样有利于更精细地限定整数变量的范围,也有利于更好地表达代码的意图。

  • short int(简写为short):占用空间不多于int,一般占用2个字节(整数范围为-32768~32767)。
  • long int(简写为long):占用空间不少于int,至少为4个字节。
  • long long int(简写为long long):占用空间多于long,至少为8个字节。
short int a; 
long int b; 
long long int c;

上面代码分别声明了三种整数子类型的变量。

默认情况下,shortlonglong long都是带符号的(signed),即signed关键字省略了。它们也可以声明为不带符号(unsigned),使得能够表示的最大值扩大一倍。

unsigned short int a; 
unsigned long int b; 
unsigned long long int c;

C 语言允许省略int,所以变量声明语句也可以写成下面这样。


short a;
unsigned short a;
long b;
unsigned long b;
long long c;
unsigned long long c;

不同的计算机,数据类型的字节长度是不一样的。确实需要32位整数时,应使用long类型而不是int类型,可以确保不少于4个字节;确实需要64位的整数时,应该使用long long类型,可以确保不少于8个字节。另一方面,为了节省空间,只需要16位整数时,应使用short类型;需要8位整数时,应该使用char类型。

4.整数类型的极限值

有时候需要查看,当前系统不同整数类型的最大值和最小值,C 语言的头文件limits.h提供了相应的常量,比如SCHAR_MIN代表 signed char 类型的最小值-128SCHAR_MAX代表 signed char 类型的最大值127

为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。

  • SCHAR_MINSCHAR_MAX:signed char 的最小值和最大值。
  • SHRT_MINSHRT_MAX:short 的最小值和最大值。
  • INT_MININT_MAX:int 的最小值和最大值。
  • LONG_MINLONG_MAX:long 的最小值和最大值。
  • LLONG_MINLLONG_MAX:long long 的最小值和最大值。
  • UCHAR_MAX:unsigned char 的最大值。
  • USHRT_MAX:unsigned short 的最大值。
  • UINT_MAX:unsigned int 的最大值。
  • ULONG_MAX:unsigned long 的最大值。
  • ULLONG_MAX:unsigned long long 的最大值。
整型数据类型 字节 数值范围 输出输入格式说明
short int 2 -32,768 to 32,767 %hd
unsigned short int 2 0 to 65,535 %hu
unsigned int 4 0 to 4,294,967,295 %u
int 4 -2,147,483,648 to 2,147,483,647 %d
long int 4 -2,147,483,648 to 2,147,483,647 %ld
unsigned long int 4 0 to 4,294,967,295 %lu
long long int 8 -(2^63) to (2^63)-1 %lld
unsigned long long int 8 0 to 18,446,744,073,709,551,615 %llu
signed char 1 -128 to 127 %c
unsigned char 1 0 to 255 %c
float 4 %f
double 8 %lf
long double 16 %Lf

我们可以使用 thesizeof() 函数检查每个数据类型的字节大小。

例1. 整数数据占用的字节和整数类型的最大值和最小值

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main()
{
//for how many bytes
printf("size of int : %d\n",sizeof(int));
printf("size of char : %d\n",sizeof(char));
printf("size of signed char : %d\n",sizeof(signed char));
printf("size of unsigned char : %d\n",sizeof(unsigned char));
printf("size of short : %d\n",sizeof(short));
printf("size of short int : %d\n",sizeof(short int));
printf("size of signed short : %d\n",sizeof(signed short));
printf("size of signed short int : %d\n",sizeof(signed short int));
printf("size of long int : %d\n",sizeof( long int));
printf("size of float : %d\n",sizeof(float));
printf("size of double : %d\n",sizeof(double));
printf("size of long double : %d\n",sizeof(long double));
printf("CHAR_BIT : %d\n", CHAR_BIT); //how many bits

//Max Value and Min Value
printf("CHAR_MAX : %d\n", CHAR_MAX);
printf("CHAR_MIN : %d\n", CHAR_MIN);
printf("INT_MAX : %d\n", INT_MAX);
printf("INT_MIN : %d\n", INT_MIN);
printf("LONG_MAX : %ld\n", (long) LONG_MAX);
printf("LONG_MIN : %ld\n", (long) LONG_MIN);
printf("SCHAR_MAX : %d\n", SCHAR_MAX);
printf("SCHAR_MIN : %d\n", SCHAR_MIN);
printf("SHRT_MAX : %d\n", SHRT_MAX);
printf("SHRT_MIN : %d\n", SHRT_MIN);
printf("UCHAR_MAX : %d\n", UCHAR_MAX);
printf("UINT_MAX : %u\n", (unsigned int) UINT_MAX);
printf("ULONG_MAX : %lu\n", (unsigned long) ULONG_MAX);
printf("USHRT_MAX : %d\n", (unsigned short) USHRT_MAX);

return 0;
}

结果:

size of int : 4
size of char : 1
size of signed char : 1
size of unsigned char : 1
size of short : 2
size of short int : 2
size of signed short : 2
size of signed short int : 2
size of long int : 4
size of float : 4
size of double : 8
size of long double : 16
CHAR_BIT : 8
CHAR_MAX : 127
CHAR_MIN : -128
INT_MAX : 2147483647
INT_MIN : -2147483648
LONG_MAX : 2147483647
LONG_MIN : -2147483648
SCHAR_MAX : 127
SCHAR_MIN : -128
SHRT_MAX : 32767
SHRT_MIN : -32768
UCHAR_MAX : 255
UINT_MAX : 4294967295
ULONG_MAX : 4294967295
USHRT_MAX : 6553

5.整数的进制

C 语言的整数默认都是十进制数,如果要表示八进制数和十六进制数,必须使用专门的表示法。

八进制使用0作为前缀,比如0170377

int a = 012; // 八进制,相当于十进制的10

十六进制使用0x或0X作为前缀,比如0xf、0X10。

int a = 0x1A2B; // 十六进制,相当于十进制的6699

注意,不同的进制只是整数的书写方法,不会对整数的实际存储方式产生影响。所有整数都是二进制形式存储,跟书写方式无关。

不同进制可以混合使用,比如10 + 015 + 0x20是一个合法的表达式。

例2. 十进制,八进制,十六进制的存储和运算

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main()
{
    int x = 100;
    int y = 0144;
    printf("dec = %d\n", x); // 100
    printf("octal = %o\n", x); // 144
    printf("hex = %x\n", x); // 64
    printf("octal = %#o\n", x); // 0144
    printf("Dec x + y = %d\n", x+y); // 200
    return 0;
}

结果:

dec = 100
octal = 144
hex = 64
octal = 0144
Dec x + y = 200

printf()的进制相关占位符如下。

  • %d:十进制整数。
  • %o:八进制整数。
  • %x:十六进制整数。
  • %#o:显示前缀0的八进制整数。
  • %#x:显示前缀0x的十六进制整数。
  • %#X:显示前缀0X的十六进制整数。

6. 整型变量的溢出

例3. char型变量的溢出

#include <stdio.h>

int main()
{
  char a = 127;
  char b = a + 1;
  printf("a=%d\tb=%d", a,b);
  return 0;
}

结果:

a=127 b=-128
Process returned 0 (0x0) execution time : 0.036 s
Press any key to continue.

原因:127的二进制值是0111 1111 加1后变成 1000 0000,这个值是-128.

所以输出结果是溢出了。

下图能够更好的理解整型变脸的溢出,127溢出后又变成-128。

 

整型变量的溢出
整型变量的溢出

例4.整型变量的溢出

#include <stdio.h>

int main()
{
   int a, b;
   a=2147483647;
   b=a+1;
   printf("%d, %d\n",a,b);
   return 0;
}
结果

2147483647, -2147483648

Process returned 0 (0x0) execution time : 0.587 s
Press any key to continue.

原因:a的值用二进制表示是:01111111 11111111 11111111 11111111 加1后变成 10000000 00000000 00000000

实际上也是溢出了。

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Leave the field below empty!

Posted in C语言教程

Related Posts