1.int类型

C语言提供了许多整数类型,为什么一种类型不够用?因为C语言让程序员针对不同情况选择不同的类型。特别是,C语言中的整数类型可表示不同的取值范围和正负值。一般情况使用int类型即可,但是为满足特定任务和机器的要求,还可以选择其他类型。

int类型是有符号整型,即int类型的值必须是整数,可以是正整数、负整数或零。其取值范围依计算机系统而异。一般而言,存储一个int要占用一个机器字长。因此,早期的16位IBM PC兼容机使用16位来存储一个int值,其取值范围(即int值的取值范围)是-32768~32767。现在,个人计算机都为64位处理器,自然能存储更大的整数。ISO C规定int的取值范围最小为-32768~32767。一般而言,系统用一个特殊位的值表示有符号整数的正负号。第15章将介绍常用的方法。

1.1 声明int

变量第2章中已经用int声明过基本整型变量。先写上int,然后写变量名,最后加上一个分号。要声明多个变量,可以单独声明每个变量,也可在int后面列出多个变量名,变量名之间用逗号分隔。下面都是有效的声明:

int earning;int dogs, cows, cat;#+BEGIN_SRC C :results output

可以分别在4条声明中声明各变量,也可以在一条声明中声明4个变量。两种方法的效果相同,都为4个int大小的变量赋予名称并分配内存空间。以上声明创建了变量,但是并没有给它们提供值。变量如何获得值?前面介绍过在程序中获取值的两种途径。

第1种途径是赋值:

cows = 30

第2种途径是,通过函数(如,scanf())获得值。

1.2 初始化

变量初始化(initialize)变量就是为变量赋一个初始值。在C语言中,初始化可以直接在声明中完成。只需在变量名后面加上赋值运算符(=)和待赋给变量的值即可。如下所示:

int hogs = 21;int cows = 32, goats = 14;int dogs, cats = 94;        /* valid, but poor, form */

以上示例的最后一行,只初始化了cats,并未初始化dogs。这种写法很容易让人误认为dogs也被初始化为94,所以最好不要把初始化的变量和未初始化的变量放在同一条声明中。简而言之,声明为变量创建和标记存储空间,并为其指定初始值。

Defining and initializing a variable.

1.3 int类型常量

上面示例中出现的整数(21、32、14和94)都是整型常量或整型字面量。C语言把不含小数点和指数的数作为整数。因此,22和-44都是整型常量,但是22.0和2.2E1则不是。C语言把大多数整型常量视为int类型,但是非常大的整数除外。

1.4 打印int值

可以使用printf()函数打印int类型的值。

第2章中介绍过,%d指明了在一行中打印整数的位置。%d称为转换说明,它指定了printf()应使用什么格式来显示一个值。格式化字符串中的每个%d都与待打印变量列表中相应的int值匹配。这个值可以是int类型的变量、int类型的常量或其他任何值为int类型的表达式。我们要确保转换说明的数量与待打印值的数量相同,编译器不会捕获这类型的错误。程序清单3.2演示了一个简单的程序,程序中初始化了一个变量,并打印该变量的值、一个常量值和一个简单表达式的值。另外,程序还演示了如果粗心犯错会导致什么结果。

#include int main(void){    int ten = 10;    int two = 2;    printf("Doing it right: ");    printf("%d minus %d is %d", ten, 2, ten - two );    printf("Doing it wrong: ");    printf("%d minus %d is %d", ten);  // forgot 2 arguments    return 0;}

在第一行输出中,第1个%d对应int类型变量ten;第2个%d对应int类型常量2;第3个%d对应int类型表达式ten - two的值。在第二行输出中,第1个%d对应ten的值,但是由于没有给后两个%d提供任何值,所以打印出的值是内存中的任意值(读者在运行该程序时显示的这两个数值会与输出示例中的数值不同,因为内存中存储的数据不同,而且编译器管理内存的位置也不同)。你可能会抱怨编译器为何不能捕获这种明显的错误,但实际上问题出在printf()不寻常的设计。大部分函数都需要指定数目的参数,编译器会检查参数的数目是否正确。但是,printf()函数的参数数目不定,可以有1个、2个、3个或更多,编译器也爱莫能助。记住,使用printf()函数时,要确保转换说明的数量与待打印值的数量相等。

1.5 八进制和十六进制

通常,C语言都假定整型常量是十进制数。然而,许多程序员很喜欢使用八进制和十六进制数。因为8和16都是2的幂,而10却不是。显然,八进制和十六进制记数系统在表达与计算机相关的值时很方便。例如,十进制数65536经常出现在16位机中,用十六进制表示正好是10000。另外,十六进制数的每一位的数恰好由4位二进制数表示。例如,十六进制数3的二进制数是0011,十六进制数5的二进制数是0101。因此,十六进制数35的位组合(bit pattern)是00110101,十六进制数53的位组合是01010011。这种对应关系使得十六进制和二进制的转换非常方便。

但是,计算机如何知道10000是十进制、十六进制还是二进制?在C语言中,用特定的前缀表示使用哪种进制。0x或0X前缀表示十六进制值,所以十进制数16表示成十六进制是0x10或0X10。与此类似,0前缀表示八进制。例如,十进制数16表示成八进制是020。第15章将更全面地介绍进制相关的内容。

要清楚,使用不同的进制数是为了方便,不会影响数被存储的方式。也就是说,无论把数字写成16、020或0x10,存储该数的方式都相同,因为计算机内部都以二进制进行编码。

1.6 显示八进制和十六进制

在C程序中,既可以使用也可以显示不同进制的数。不同的进制要使用不同的转换说明。以十进制显示数字,使用%d;以八进制显示数字,使用%o;以十六进制显示数字,使用%x。另外,要显示各进制数的前缀0、0x和0X,必须分别使用%#o、%#x、%#X。程序清单3.3演示了一个小程序(回忆一下,在某些集成开发环境(IDE)下编写的代码中插入getchar();语句,程序在执行完毕后不会立即关闭执行窗口)。

Listing 3.3 The bases.c Program

#include int main(void){    int x = 100;    printf("dec = %d; octal = %o; hex = %x", x, x, x);    printf("dec = %d; octal = %#o; hex = %#x", x, x, x);    return 0;}

编译并运行该程序,输出如下:

: dec = 100; octal = 144; hex = 64: dec = 100; octal = 0144; hex = 0x64

该程序以3种不同记数系统显示同一个值。printf()函数做了相应的转换。注意,如果要在八进制和十六进制值前显示0和0x前缀,要分别在转换说明中加入#。

2 其他整数类型

初学C语言时,int类型应该能满足大多数程序的整数类型需求。尽管如此,还应了解一下整型的其他形式。当然,也可以略过本节跳至3.4.3节阅读char类型的相关内容,以后有需要时再阅读本节。C语言提供3个附属关键字修饰基本整数类型:short、long和unsigned。应记住以下几点。

  • short-int类型(或者简写为short)占用的存储空间可能比int类型少,常用于较小数值的场合以节省空间。与int类似,short是有符号类型。
  • long-int或long占用的存储空间可能比int多,适用于较大数值的场合。与int类似,long是有符号类型。
  • long-long int或long-long(C99标准加入)占用的存储空间可能比long多,适用于更大数值的场合。该类型至少占64位。与int类似,long long是有符号类型。
  • unsigned-int或unsigned只用于非负值的场合。这种类型与有符号类型表示的范围不同。例如,16位unsigned-int允许的取值范围是0~65535,而不是-32768~32767。用于表示正负号的位现在用于表示另一个二进制位,所以无符号整型可以表示更大的数。
  • 在C90标准中,添加了unsigned long int或unsigned long和unsigned short int或unsigned short类型。C99标准又添加了unsigned long long int或unsigned long long。
  • 在任何有符号类型前面添加关键字signed,可强调使用有符号类型的意图。例如,short、short int、signed short、signed short int都表示同一种类型。

2.1 声明其他整数类型

其他整数类型的声明方式与int类型相同,下面列出了一些例子。不是所有的C编译器都能识别最后3条声明,最后一个例子所有的类型是C99标准新增的。

long int estine;long johns;short int erns;short ribs;unsigned int s_count;unsigned players;unsigned long headcount;unsigned short yesvotes;long long ago;

2.2 使用多种整数类型的原因

为什么说short类型“可能”比int类型占用的空间少,long类型“可能”比int类型占用的空间多?因为C语言只规定了short占用的存储空间不能多于int,long占用的存储空间不能少于int。这样规定是为了适应不同的机器。 现在,个人计算机上最常见的设置是,long long占64位,long占32位,short占16位,int占16位或32位(依计算机的自然字长而定)。原则上,这4种类型代表4种不同的大小,但是在实际使用中,有些类型之间通常有重叠。

C标准对基本数据类型只规定了允许的最小大小。对于16位机,short和int的最小取值范围是[−32768,32767];对于32位机,long的最小取值范围是[−2147483648,2147483647]。对于unsigned short和unsigned int,最小取值范围是[0,65535];对于unsigned long,最小取值范围是[0,4294967295]。long long类型是为了支持64位的需求,最小取值范围是[−9223372036854775808,9223372036854775807];unsigned longlong的最小取值范围是[0,18446744073709551615]。如果要开支票,这个数是一千八百亿亿六千七百四十四万亿零七百三十七亿零九百五十五万一千六百一十五。

但是,谁会去数?int类型那么多,应该如何选择?首先,考虑unsigned类型。这种类型的数常用于计数,因为计数不用负数。而且,unsigned类型可以表示更大的正数。如果一个数超出了int类型的取值范围,且在long类型的取值范围内时,使用long类型。然而,对于那些long占用的空间比int大的系统,使用long类型会减慢运算速度。因此,如非必要,请不要使用long类型。另外要注意一点:如果在long类型和int类型占用空间相同的机器上编写代码,当确实需要32位的整数时,应使用long类型而不是int类型,以便把程序移植到16位机后仍然可以正常工作。类似地,如果确实需要64位的整数,应使用long long类型。

如果在int设置为32位的系统中要使用16位的值,应使用short类型以节省存储空间。通常,只有当程序使用相对于系统可用内存较大的整型数组时,才需要重点考虑节省空间的问题。使用short类型的另一个原因是,计算机中某些组件使用的硬件寄存器是16位。

2.3 long常量和long long常量

通常,程序代码中使用的数字(如,2345)都被存储为int类型。如果使用1000000这样的大数字,超出了int类型能表示的范围,编译器会将其视为long int类型(假设这种类型可以表示该数字)。如果数字超出long可表示的最大值,编译器则将其视为unsigned long类型。如果还不够大,编译器则将其视为long long或unsigned long long类型(前提是编译器能识别这些类型)。八进制和十六进制常量被视为int类型。如果值太大,编译器会尝试使用unsigned int。如果还不够大,编译器会依次使用long、unsignedlong、long long和unsigned long long类型。有些情况下,需要编译器以long类型存储一个小数字。例如,编程时要显式使用IBM PC上的内存地址时。另外,一些C标准函数也要求使用long类型的值。要把一个较小的常量作为long类型对待,可以在值的末尾加上l(小写的L)或L后缀。使用L后缀更好,因为l看上去和数字1很像。因此,在int为16位、long为32位的系统中,会把7作为16位存储,把7L作为32位存储。l或L后缀也可用于八进制和十六进制整数,如020L和0x10L。类似地,在支持long long类型的系统中,也可以使用ll或LL后缀来表示long long类型的值,如3LL。另外,u或U后缀表示unsigned long long,如5ull、10LLU、6LLU或9Ull。

可以把无符号整数j看作是汽车的里程表。当达到它能表示的最大值时,会重新从起始点开始。整数i也是类似的情况。它们主要的区别是,在超过最大值时,unsigned int类型的变量j从0开始;而int类型的变量i则从−2147483648开始。注意,当i超出(溢出)其相应类型所能表示的最大值时,系统并未通知用户。因此,在编程时必须自己注意这类问题。

溢出行为是未定义的行为,C标准并未定义有符号类型的溢出规则。以上描述的溢出行为比较有代表性,但是也可能会出现其他情况。

2.4 整数溢出

如果整数超出了相应类型的取值范围会怎样?下面分别将有符号类型和无符号类型的整数设置为比最大值略大,看看会发生什么(printf()函数使用%u说明显示unsigned int类型的值)。

/* toobig.c-exceeds maximum int size on our system */#include int main(void){    int i = 2147483647;    unsigned int j = 4294967295;    printf("%d %d %d", i, i+1, i+2);    printf("%u %u %u", j, j+1, j+2);    return 0;}#+RESULTS:: 2147483647 -2147483648 -2147483647: 4294967295 0 1

2.5.打印short、long、long long和unsigned类型

打印unsigned-int类型的值,使用%u转换说明;打印long类型的值,使用%ld转换说明。如果系统中int和long的大小相同,使用%d就行。但是,这样的程序被移植到其他系统(int和long类型的大小不同)中会无法正常工作。在x和o前面可以使用l前缀,%lx表示以十六进制格式打印long类型整数,%lo表示以八进制格式打印long类型整数。注意,虽然C允许使用大写或小写的常量后缀,但是在转换说明中只能用小写。

C语言有多种printf()格式。对于short类型,可以使用h前缀。%hd表示以十进制显示short类型的整数,%ho表示以八进制显示short类型的整数。h和l前缀都可以和u一起使用,用于表示无符号类型。例如,%lu表示打印unsigned long类型的值。程序清单3.4演示了一些例子。对于支持longlong类型的系统,%lld和%llu分别表示有符号和无符号类型。第4章将详细介绍转换说明。

/* print2.c-more printf() properties */#include int main(void){    unsigned int un = 3000000000; /* system with 32-bit int */    short end = 200;              /* and 16-bit short       */    long big = 65537;    long long verybig = 12345678908642;    printf("un = %u and not %d", un, un);    printf("end = %hd and %d", end, end);    printf("big = %ld and not %hd", big, big);    printf("verybig= %lld and not %ld", verybig, verybig);    return 0;}#+RESULTS:: un = 3000000000 and not -1294967296: end = 200 and 200: big = 65537 and not 1: verybig= 12345678908642 and not 12345678908642

该例表明,使用错误的转换说明会得到意想不到的结果。第1行输出,对于无符号变量un,使用%d会生成负值!其原因是,无符号值3000000000和有符号值−129496296在系统内存中的内部表示完全相同。因此,如果告诉printf()该数是无符号数,它打印一个值;如果告诉它该数是有符号数,它将打印另一个值。在待打印的值大于有符号值的最大值时,会发生这种情况。对于较小的正数(如96),有符号和无符号类型的存储、显示都相同。

第2行输出,对于short类型的变量end,在printf()中无论指定以short类型(%hd)还是int类型(%d)打印,打印出来的值都相同。这是因为在给函数传递参数时,C编译器把short类型的值自动转换成int类型的值。你可能会提出疑问:为什么要进行转换?h修饰符有什么用?第1个问题的答案是,int类型被认为是计算机处理整数类型时最高效的类型。因此,在short和int类型的大小不同的计算机中,用int类型的参数传递速度更快。第2个问题的答案是,使用h修饰符可以显示较大整数被截断成short类型值的情况。第3行输出就演示了这种情况。把65537以二进制格式写成一个32位数是00000000000000010000000000000001。使用%hd,printf()只会查看后16位,所以显示的值是1。与此类似,输出的最后一行先显示了verybig的完整值,然后由于使用了%ld,printf()只显示了存储在后32位的值。

本章前面介绍过,程序员必须确保转换说明的数量和待打印值的数量相同。以上内容也提醒读者,程序员还必须根据待打印值的类型使用正确的转换说明。

c打印无符号整数_C语言的7种整数类型相关推荐

  1. c打印无符号整数_C语言基础知识:printf的输出格式,C/C++语言编程讲解

    C语言基础知识:printf的输出格式 printf()函数是格式输出函数,请求printf()打印变量的指令取决与变量的类型.例如,在打印整数是使用%d符号,在打印字符是用%c 符号.这些符号被称为 ...

  2. python语言的三种数字类型_Python语言中的类型之数字类型--Python(10)

    数据从不一样的角度能够用不一样的含义去解释它,如: 10,011,101 对上面这个数据,咱们有以下多种含义去解释它: 1)它是1个二进制数字,或者是1个十进制数字: 2)一段文本: 3)用 , 号分 ...

  3. python是一种解释型、面向什么的计算机程序设计语言_python语言是一种什么类型...

    python语言是一种什么类型,是一种,类型,语言,是在,程序 python语言是一种什么类型 易采站长站,站长之家为您整理了python语言是一种什么类型的相关内容. python语言是一种什么类型 ...

  4. c语言饿结构_C语言的四种程序结构

    C语言的四种程序结构 尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电 ...

  5. 结构体前面加星号_C语言中带星号的类型指针有哪些特性

    C语言中带星号的类型指针有哪些特性 指针是什么?很多人说,指针就是地址,那这么说的人肯定是对指针有所了解,他们这么说也不能说全错,我只能在这里说:"他们并没有真正学会指针,如果想学好指针,请 ...

  6. c语言goto语句用法_C语言的9种控制结构

    点击蓝字关注我哦 C语言语句 goto语句:无条件转向; if语句:判断语句;while循环语句; do-while语句:先执行循环体,然后判断循环条件是否成立. 之后继续循环;for语句:循环,可替 ...

  7. bpmn文件的标签为何都以bpmn2开头_C语言之两种作用域:函数的作用域与文件作用域...

    作用域描述程序中可访问标识符的区域.一个C变量的作用域可以是块作用域.函数作用域.函数原型作用域或文件作用域. 其中,块是用一对花括号括起来的代码区域.例如,整个函数体是一个块,函数中的任意复合语句也 ...

  8. C语言,字符串转为整数类型

    在C中准确来说是字符数组转整数类型 首先判断字符串是否具有整数的形式, 如果是就直接进行转换,不是则自己另外赋一个值. #include <stdio.h> #include <st ...

  9. bool c语言_C语言面试54题

    C语言面试54题 ​ 大家好,这期呢,我们谈一下c语言的面试题. 第1题,c语言有哪些核心的特征? 可移植性很强. 模块化能力很强. 灵活性很高. 加载速度和执行速度都很好. 可扩展性很强. 第2题, ...

最新文章

  1. HDU 5616 Jam's balance(01背包)
  2. 通过timer控件和窗体的opacity属性,轻松实现窗体的淡入淡出
  3. window.print 固定表头不影响_Excel中的表头,你会处理吗
  4. qfiledialog的取消_QT对话框去掉帮助和关闭按钮
  5. 【Xamarin.Android】应用消费品
  6. 安全地创建和存储密码
  7. 阿里云SLB上http强制跳转到https问题处理
  8. 【Data Guard】Oracle DataGuard 搭建
  9. HDU5904 LCIS【LCIS】
  10. bzoj 3356: [Usaco2004 Jan]禁闭围栏(扫描线+树状数组)
  11. #pragma的一些用法
  12. android 字体加粗_Android小技巧之TextView字体加粗
  13. 阿里云服务器租用价格表,阿里云服务器优惠
  14. 使用阿里云的ip地址查询服务-购买ip地址查询服务
  15. PostgreSQL下载安装教程以及官网下载包出现的问题
  16. Redis【有与无】【Lettuce】L5.Redis Cluster
  17. 淘宝和微信的扫码登录实现原理
  18. Genymotion-ARM-Translation.zip各安卓版本合集
  19. 保研/面试复习-数据结构与算法-万字总结(近三万字)
  20. LSH 近似最近邻查找

热门文章

  1. ADPCM音频格式详解 ADPCM_IMA ADPCM_DIV4
  2. 搭建文件下载服务CentOS Apache服务
  3. 溢出显示三个圆点基本操作
  4. C2760语法错误:意外标记“标识符”,应为“;”
  5. html制作电影宣传效果,为你的网页做出电影的过场效果_html
  6. vue+relation-graphs快速实现组织机构图谱、股权架构图谱、集团关系图谱等知识图谱,树形、力学等关系图
  7. 配置高低档计算机,电脑配置高fps低怎么办
  8. IDM标准 《 BS EN ISO 29481-1-2016》 翻译(主要部分)
  9. 阿里「雪藏」三年的新制造工厂,究竟「新」在哪里?
  10. 【2022年】儿童学习桌推荐良心避坑指南,有哪些儿童学习桌品牌值得推荐