C语言整数

 

整数的概念

       在之前的章节中,我们已经用过整数了,也定义过整型变量,好像没什么好讲的,整数就是整数。

       整数是我们生活中常用的数据类型,也是编程中常用的一种数据,C语言使用int关键字来定义整数变量(int 是 integer 的简写)。

       在定义变量的时候,可以加signed、unsigned、short和long四种修饰符。

        signed:有符号的,可以表示正数和负数。

       unsigned:无符号的,只能表示正数,例如数组的下标、人的身高等。

       short:短的,现在主流的64位操作系统下,整数占用内存4个字节,使用 4 个字节保存较小的整数绰绰有余,会空闲出两个字节来,这些字节就白白浪费掉了。现在个人电脑的内存都比较大了,配置低的也有2G,浪费一些内存无所谓;而在C语言被发明的早期,或者在单片机和嵌入式系统中,内存都是非常稀缺的资源,所有的程序都在尽可能节省内存。

       long:长的,更长的整数。

整数的取值范围

       整数的取值范围与计算机操作系统和C语言编译器有关,没有一个固定的数值,我们可以根据它占用的内存大小来推断它的取值范围。

       一个字节有8个位,表示的数据的取值范围是28-1,即255。

       如果占用的内存是两个字节,无符号型取值范围是28ⅹ28-1。

       如果占用的内存是四个字节,无符号型取值范围是28ⅹ28ⅹ28ⅹ28-1。

       如果占用的内存是八个字节,无符号型取值范围是28ⅹ28ⅹ28ⅹ28ⅹ28ⅹ28ⅹ28ⅹ28-1。

       如果是有符号,取值范围减半,包括负数部分。

       下面用一个示例代码来测试各种整数占用内存的大小。

       示例(book60.c)

      

       运行结果

      

       sizeof是C语言中保留关键字,是一种运算符,不是函数,sizeof实际上是获取了数据在内存中所占用的存储空间,以字节为单位。

              int ii;

              sizeof(int)和sizeof(ii)都可以。

       根据book60.c的测试结果,我们可以得到各种整数的取值范围。

类型简写

类型全称

长度

取值范围

short

[signed] short [int]

2字节

-32768~32767

unsigned short

unsigned short [int]

2字节

0~65535

int

[signed] int

4字节

-2147483648~2147483647

unsigned int

unsigned [int]

4字节

0~4294967295

long

[signed] long [int]

8字节

-9223372036854775808~9223372036854775807

unsigned long

unsigned long [int]

8字节

0~18446744073709551615

       注意:

       1)计算机用最高位1位来表达符号,unsigned修饰过的正整数不需要符号位,在表达正整数的时候比signed修饰的正整数取值大一倍。

       2)在写程序的时候,上表中括号[]的单词可以省略不书写。

       3)在写程序的时候,给整数变量赋值不能超出变量的取值范围,编译的时候会出现类似以下的错误,程序运行也可能产生不可预后的后果。

      

       4)现在计算机的内存不值钱,建议程序员少用short,慎用int,多用long,内存不是问题,程序的稳定高于一切。

整型的输出

       以下表格中,重点记住第一、二行十进制的输出格式,二十年来,八进制数我从来没有用过,十六进制数只在显示内存的地址时见过,所以大家不必关心八进制和十六进制的相关知识,了解即可。

 

%hd、%d、%ld

以十进制、有符号的形式输出int、long 类型的整数

%hu、%u、%lu

以十进制、无符号的形式输出int、long 类型的整数

%ho、%o、%lo

以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数

%#ho、%#o、%#lo

以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数

%hx、%x、%lx
%hX、%X、%lX

以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。

%#hx、%#x、%#lx
%#hX、%#X、%#lX

以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。

       注意一个坑:输出格式控制符的类型最好与变量的类型一一对应,否则会出现意外的后果,示例:

              int i=32767;

              printf("i %hd,%d\n",i,i);

              int j=32768;

              printf("j %hd,%d\n",j,j);

       输出结果:

              i 32767,32767

              j -32768,32768     // 得到了意外的输出结果

       %hd用于输出短整数,最大值是32767可以输出32767,但不能正常的输出32768

       用一个小碗去装一桶水,道理上说不过去。

       补充一个常用的输出方法,在输出的整数前补0,例如今天是2019年6月5日,输出可以这么写:printf("%d-%02d-%02d",2019,6,5),结果是2019-06-05,月份和日期如果不够两位,就在前面补0。

二进制数、八进制数和十六进制数的书写

       一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面加上特定的字符,也就是加前缀。

1、二进制

       二进制由 0 和 1 两个数字组成,使用时必须以0b0B(不区分大小写)开头,例如:

              // 以下是合法的二进制

              int a = 0b101;      // 换算成十进制为 5

              int b = -0b110010;  // 换算成十进制为 -50

              int c = 0B100001;   // 换算成十进制为 33

              // 以下是非法的二进制

              int m = 101010;  // 无前缀 0B,相当于十进制

              int n = 0B410;    // 4不是有效的二进制数字

       请注意,标准的C语言并不支持上面的二进制写法,只是有些编译器自己进行了扩展,才支持二进制数字。换句话说,并不是所有的编译器都支持二进制数字,只有一部分编译器支持,并且跟编译器的版本有关系。

2、八进制

       八进制由 0~7 八个数字组成,使用时必须以0开头(注意是数字 0,不是字母 o),例如:

              // 以下是合法的八进制数

              int a = 015;      // 换算成十进制为 13

              int b = -0101;    // 换算成十进制为 -65

              int c = 0177777;  // 换算成十进制为 65535

              // 以下是非法的八进制

              int m = 256;  // 无前缀 0,相当于十进制

              int n = 03A2;  // A不是有效的八进制数字

3、十六进制

       十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以0x0X(不区分大小写)开头,例如:

              // 以下是合法的十六进制

              int a = 0X2A;   // 换算成十进制为 42

              int b = -0XA0;  // 换算成十进制为 -160

              int c = 0xffff;   // 换算成十进制为 65535

              // 以下是非法的十六进制

              int m = 5A;    // 没有前缀 0X,是一个无效数字

              int n = 0X3H;  // H不是有效的十六进制数字

4、十进制

       十进制由 0~9 十个数字组成,没有任何前缀,和我们平时的书写格式一样,不再赘述。

5、需要注意的坑

       在现实生活和工作中,我们在写十进制数的时候,为了对齐或其它原因,在数值前面加0是无关紧要的,但是,在C语言中,不要在十进制数前加0,会被计算机误认为是八进制数。

常用的库函数

       C语言提供了几个常用的库函数,声明如下:

              int   atoi(const char *nptr);  // 把字符串nptr转换为int整数

              long atol(const char *nptr);  // 把字符串nptr转换为long整数

              int   abs(const int j);        // 求int整数的绝对值

              long labs(const long int j);  // 求long整数的绝对值

       示例(book61.c)

      

       运行结果

      

数据类型的别名

       C语言允许程序员使用 typedef 关键字来给数据类型定义一个别名,别名一般有两个特点:1)名称更短;2)更符合程序员的习惯。

       例如unsigned int起个size_t的别名。

              typedef unsigned int size_t;

              size_t ii; 等同于 unsigned int ii;

       我喜欢把整数这样起别名:

              int不变。

              typedef unsigned int uint;

              long也不变。

              typedef unsigned long ulong;

获取随机数

       在实际开发中,我们会用到随机数这个功能,在C语言中,编写一些关于游戏之类的程序时就需要用到随机数。同时C语言也提供了一个标准库里面一个函数来产生随机数,而对于随机数的产生是根据种子(根据一个数值按照某种公式计算的)来变化的。

1、生成随机数

       在C语言中,我们使用 <stdlib.h> 头文件中的 srand和rand 函数来生成随机数。

              void srand (unsigned int seed);   // 随机数生成器的初始化函数

              int rand ();    // 获一个取随机数

       srand函数初始化随机数发生器(俗称种子),在实际开发中,我们可以用时间作为参数,只要每次播种的时间不同,那么生成的种子就不同,最终的随机数也就不同,通常我们采用 <time.h> 头文件中的 time 函数即可得到一个精确到秒的时间作为种子。

       rand函数会随机生成一个位于 0 ~ RAND_MAX 之间的整数。而对RAND_MAX 是 <stdlib.h> 头文件中的一个宏,它用来指明 rand 所能返回的随机数的最大值(CentOS 6.9中是2147483647 )。

 

       示例(book63.c)

      

 

       运行结果

      

2、生成一定范围随机数

       在实际开发中,需求往往是一定范围内的随机数,对于产生一定范围的随机数,就需要使用一定的技巧,常用的方法是取模运算,再加上一个加法运算:

              int a = rand() % 50;   // 产生0~49的随机数

       如果要规定上下限:

              int a = rand() % 51 + 100;   // 产生100~150的随机数

       取模即取余数,rand()%51+100,rand()%51是产生 0~50 的随机数,后面+100保证 a 最小只能是 100,最大就是 50+100=150。

注意事项

       1)采用gdb调试程序,gdb调试程序是基本技能,与程序员的水平高低无关。只要看不出程序的错误原因,就可以gdb来调试。

       2)写程序不能碰运气,必须对自己写的代码有百分之百的把握,行有行的道理,不行有不行的原因,如果不行,可能是你对某个知识点没搞明白,还有坑,既然有坑,就要解决,不要绕过,要搞清楚原因。

       3)有问题不要埋头苦搞,如果一个问题20分钟还没有解决,就在群中提出来。凡事都有一个度,过之犹如不及,把一个小问题搞半天是浪费时间。

版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

来源:C语言技术网(www.freecplus.net

作者:码农有道

如果这篇文章对您有帮助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!

如果文章有错别字,或者内容有误,或其他的建议或意见,请您留言指正,非常感谢!!!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C语言技术网-码农有道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值