程序开发剖解圣经(007)

本文深入解析C语言中的变量与整型常量,包括变量命名规定、规范,整型常量的十进制、八进制、十六进制表示法,以及整型变量的存储方式和内存表示法,特别是小端表示法和补码表示法的原理与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言剖解(04)

好了,我们继续开讲。本篇我们说:变量、整型常量和整型变量

       我们上一篇,着重调侃了常量,那什么是变量呢?很简单,相对于常量来说,能够改变的量就是变量。变量名本身没有什么特殊含义,只是一个表示形式,就像人名一样。确切的说,变量有三部分组成,分别是:

变量名、存储空间和变量的值。

       变量名是我重点强调的对象,我将其表述为三规定两规范。

三个规定如下:

规定一:以字母、数字和下划线构成,以字母和下划线为首位。

规定二:不能和C语言的关键字重复。

规定三:大小写严格区分。

说道这里,我不得不说,我非常佩服一些 “闲人”,这些人对C语言语法的研究,简直是登峰造极,以至于能够轻松的找到C语言的一些搞笑的东东,这些东东,我也很少见到。然而悲催的是,有些内容,研究者无非是想博大家一乐,或者警惕大家一些注意事项,可却成了一些公司的笔试题,这些题有时会让初学者对程序开发语言望而怯步。我庆幸我在刚踏上编程之路的时候,没碰到这些问题,否则,我也是欲哭无泪。若换做现在,如果哪个公司让我去面试,让我做题,我会直接扭头就走,或者抛下两句话,调侃一下面试官,然后昂首走出。为什么?因为这浪费我的时间,浪费我的青春。更不用说碰到这样悲催的事情了。

记得我有一次去一个小公司面试架构师,坐在那里等了好久,后来公司部门领导出来说:“不好意思,久等了,刚我们讨论了一下,我们很想录用你,也熟知你的能力,只是你看,你能不能把工资降一下,降到和我一个级别,你看行不?”

我有点晕,他们怎么熟知我的能力?事后才知道,原来他们本来打算对我进行技术面试的那个家伙,竟然是我带过的徒弟,经常因为能力问题被我骂的体无完肤。没想到来这个公司当开发经理了,他看到是我之后,直接就去和部门经理谈了,根本就没走出办公室。于是才有刚才那一出。也是从那次开始,我开始重新定位我的求职条件:研发人员在60人以上,有公司自己的技术储备和技术特色,否则免谈。想换工作的目的当然是要往高处走,以期尽可能多的掌握一些技能。

       这些我有时也向学生表述一番,是为了提高大家的学习热情,更为活跃一下上课的气氛。同时向他们证明,他们的老师不是一个笨蛋,是个有故事的男人哦。

       好,言归正传,我提高声音问学生:

       “三规定记住了没?”

       “记住了!”

听完学生回答,我不紧不慢的在main函数里写了如下一行代码:

        int $1 = 0;

       然后我问学生:“这个正确不?”

       “不正确!”

       说实话,我真不忍心拿这个打击学生。但无奈有些公司就这样出题,我得让学生知道这个是可以的。 于是,我书写如下代码

#include<stdio.h>

void main(void)

{

       int $1 = 123456789;

       printf("%d\n",$1);

}

我编译,是通过的,连个告警都没有,我运行,结果正确打印了123456789;

学生懵了。

“大多数情况下,规定是不会错的,但有极个别的内容,并不遵守规定,刘哥我本不想给你们说这个,但无奈有些公司那帮咸蛋们,非要这样考,偏偏这个就可以,至于为什么,大哥我也说不清。但换是我,可以淬一口吐沫到卷子上,然后一走了之,你们就不行,先找到工作才是硬道理。!”

学生们乐呵了。

“乐呵完了吧,下面咱们说两个规范,两个规范是什么呢?”

学生开始翻书,然后一头雾水,说上并没有给出总结。

“别翻了,两个规范如下:”

规范一:C语言并不规定变量名的长度,但是我们尽可能的让长度不超过16个字符。

规范二:我们尽可能的用简洁易懂的英文单词或者缩写来作为变量名,不要用汉语拼音。

“老师,错了,书上写的是8个字符”

“我呸, 尽信书不如无书,信刘哥。”

 “我们信春哥!”

  “咋不信曾哥呀,咋不信芙蓉姐姐呀!”

  我边说边写了如下一个变量名;

intabcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789;(注意了,代码中是一行)

然后,我编译,程序不报错,只给出了如下告警

warningC4786:'abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcde

fghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789': identifier was truncated to '255' characters in the debug information

即编译器在编译的时候,把字符截取为255个字符了。

“看到了吧,规范还是很重要的,中国人老闲外国人的名字长, 那是用中国规范来说的,超出了规范,我们就记起来别扭了,明白了吧,如果一个班里,每个人的名字都很长,估计班主任点完名字,这堂课就结束了。”

“呵呵”

“所以,规范虽然不是规定,我们也要遵守。”

好,接下来,我们讲整型常量和整形变量。

整型常量有三种表示法:

     十进制表示法:如:123,-456,八进制表示法:如:0123,0753;

十六进制表示法:0x123;

当然,这样讲如同读书,没什么意思,学生也难以记忆深刻。所以,通常我会举如下几个例子,并问学生;

0125

这是几进制?

“八进制”

029

这是几进制?

“八进制”

“毛,这是八进制么?八进制最大数是7,这里都到9了,还是八进制么?”

“哦!”

“哦,恍然大迷瞪吧!那这个是几进制?”我说完又写一个

“0xFG”

 “什么都不是!”

“哎,对,聪明,看看编译器怎么说的”,我边说,边写出如下代码

 int iVal = 029;

 int iVal1 = 0xFg;

结果,编译器报出如下错误。

E:\lesson\cl_04\cl04.c(4) : error C2041: illegal digit '9' for base '8'

E:\lesson\cl_04\cl04.c(5) : error C2059: syntax error : 'bad suffix onnumber'

E:\lesson\cl_04\cl04.c(5) : error C2146: syntax error : missing ';'before identifier 'g'

E:\lesson\cl_04\cl04.c(5) : error C2065: 'g' : undeclared identifier

Error executing cl.exe.

cl08.exe - 4 error(s), 0 warning(s)

意思我就不多说了,大家看吧。

随后,我会给大家讲解一下码制转换。码制转换讲完,基本耗去我将近40分钟的时间了。

整型变量

讲完了码制转换,我开始讲整型变量。前面说过,变量有三部分构成:变量名、存储空间和变量值。整型变量当然也不例外。

我在main函数下写如下这么一个例子:

int iVal = 123456789;

书上有这么一说:“数据在内存中是以二进制的形式存放的。”于是,我打开内存”memory”,将iVal的地址输入到Memeory的编辑框中,看到的内容如下:

0012FF7C  15 CD 5B 07(这里注意了,如果你用的是win7或更高版本,首地址为0012FF44)

“看到内存中的二进制了么?”

“看到了!”

“吹牛吧,在那里?”

肯定看不到,显示的是16进制的形式,前面的0012FF7C表示变量的地址;变量的值为15 CD 5B 07,他们都是16进制的,原因很简单,二进制表示一个数会写的非常长。为了显示的方便,使用16进制来表示了,每4个二进制数的最大值自然是F,因此用两个16进制来表示1个字节(8个字符) 很浅显易懂。

“那15 CD 5B 07是不是123456789呢?”

“是!”

 “真的么?”我反问道,并打开计算器,调制科学型,然后输入15 CD 5B 07,出来的结果转换为10进制是:365779719,而并非是123456789。

  “为什么”,学生迷茫了。

  “因为在我们VC中,采用的是小端表示法!”我边说,边把上面的值反过来输入到计算其中,即07 5B CD 15,然后再次转换为10进制,结果正确的显示了:123456789;那什么是小端表示法呢?我们再次把内存中的地址拉出来。如下:

0012FF7C  15 CD 5B 07.

0012FF80  C0 FF 12 00

我们看到第一行结束之后,第二行开始的地址为0012FF80,依据16进制表示法,一个地址占8个字节,每4个字节二进制数代表一个16进制数。因此216进制字符代表一个地址。0012FF7C是代表一个整数的首地址。即15所在的地址。那CD即为0012FF7D,如此 5B为0012FF7E;07为0012FF7F,所以,下一行,自然为0012FF80了,说明地址值是越来越大的。而123456789的16进制的自然表示法为:07 5B CD 15; 把最高位的07存放在最大的地址中,把最低位的15存放在最小地址中,这就是小端表示法。

“通过上面的分析,整型占几个字节?”

 “4个”;

“对了,因此int iVal = 1 在内存中的存放应该为01 00 00 00”

我用VC再次在内存中查阅了并验证了一下。

“这下大家该明白了吧。”

“明白了”

 “真的么,那么这个在内存中怎么存的呢?”我边问边改写代码如下:

  int iVal = -5;

  一个负号把学生弄的不知所措了。但也有聪明的。

  “转换为2进制,最高位是符号位”

   “聪明,那上面这个数的2进制数怎么写?”

   1000 0000 0000 0000 0000 0000 0000 0101

    “那改为16进制应该怎么写?”

     10 00 00 05

     “那在内存中应该怎么存?”

     05 00 00 10

    “好,我们看一下内存中是否是这样。”我再次打开内存查看,结果却是如下内容:

     0012FF7C  FB FF FF FF

  “哦?”

“哦~~差异了吧,为什么不是呢?”

“负数是以补码的形式存放的。”还是有学生知道的。

“嗯!聪明一半,无论正负,都是以补码的形式存放的,只不过,整数的补码是其本身,负数的补码是其绝对值取反加1.”

 于是我从新演示-5的二进制码如下。

绝对值:0000 0000 0000 0000 00000000 0000 0101

取反后:1111 1111 1111 1111 11111111 1111 1010

补码值:1111 1111 1111 1111 11111111 1111 1011

16进制码:FF FF FF FB;

内存存放:FB FF FF FF;

经过演示,学生大多笑了,笑了就对了,说明听懂了。

“为什么要用补码表示呢?”我这一问学生又不支声了。

“正5和负5之和是多少?”

“零”

“那好,我们看一下如果用原码,是多少?。”

0000 0000 00000000 0000 0000 0000 0101

   + 1000 0000 0000 0000 0000 0000 0000 0101

      10000000 0000 0000 0000 0000 0000 1010

“很明显,答案不是0”,所以,科学家为了解决这类问题,想出了补码。我们再来看一下用补码的结果。

   0000 00000000 0000 0000 0000 0000 0101

1111 1111 1111 1111 11111111 1111 1011

————————————————————————————                  0000 0000 0000 0000 0000 0000 0000 0000

到这里,学生基本明白了。

看着学生微笑的脸,我想我应该是讲懂了。于是后面的整型变量的分类:

基本整型(有符号、无符号):短整型(有符号、无符号):长整形(有符号、无符号)我基本是一笔带过,唯一强调的是:

“时代变了,谭浩强的书中针对的对象也改变了,翻到书本的第43页,改一下:基本整型为4个字节,而不是2个,短整型为2个字节,长整型和基本整型在32位机上也是4个字节。至于64位机上,大家下去试一下,前提是,硬件和软件和操作系统都得是64位的才能试出来。”

“还有,C语言并没有明确规定每种整型所占的字节数,只是说:短整型不能大于整型,整型不能大于长整型”因此,上面的总结,是大多数操作系统和编译器认可的,并非所有!“

说完了这些,对整形变量的定义和数据的溢出,我则是照书宣讲。不在话下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值