![C语言从入门到精通(微视频精编版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/269/27563269/b_27563269.jpg)
第2章 掌握C语言数据类型
(视频讲解:50分钟)
在所有程序语言中,C语言是十分重要的,如果学好C语言就可以很容易地掌握其他的程序语言,因为在每种语言中都会有一些共性的存在。并且一个好的程序员在编写代码时,一定要有规范性,清晰、整洁的代码才是有价值的。
本章致力于使读者掌握一个C语言中的重要环节—有关常量与变量的知识,只有明白这些知识才可以进行编写程序。
学习摘要:
编写规范的重要性
如何使用常量
变量在程序编写中的作用
2.1 C语言的编程规范
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P43_7504.jpg?sign=1738811793-Ka56L2M9S1j40LKXrOvqkIZ4rE8jrDch-0-b56caf341b697c11c293a2905acc3f15)
视频讲解
俗话说,没有规矩不成方圆。虽然在C语言中编写代码是自由的,但是为了使编写的代码具有通用性、可读性,作者提醒读者朋友们,进行编写程序时,应该尽量按照编写程序的规范进行编写设计好的程序。
2.1.1 注释的合理使用
C语言的注释为“/* …… */”格式,注释通常用于以下几种情况。
版本、版权声明
函数接口说明
重要的代码行或者段落显示
注释有助于帮助别人理解代码,但是也无须过多地使用,在使用时可遵循以下原则。
(1)注释是对代码的解释,并不是文档。程序中的注释不可喧宾夺主,注释太多会让人觉得眼花缭乱,注释的花样也不要太多。
(2)如果代码本身就很清楚,就不必加注释。
(3)边写代码边写注释,在修改代码的同时修改注释,以保证注释与代码的一致性。
(4)没有用的代码注释要及时删除。
(5)注释应当准确、易懂,防止出现二义性,错误的注释还不如没有注释。
(6)尽量避免在注释中使用不常用的缩写。
(7)注释的位置要与所描述的代码相邻,可以放在代码的上面或者右侧,不要放在代码下面。
2.1.2 程序中的“{}”要对齐
程序的分解符“{”和“}”应占据一行并且位于同一列,同时与引用它们的语句左对齐。例如下面的代码:
void funcion(int n) { }
“{}”之内的代码块在“{”右侧空4个格处做对齐。例如下面的代码:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P43_73862.jpg?sign=1738811793-6jvyILj7mL4lqv9juJYHUNh8I2UWbd81-0-e4c0cc89b2e68b339ce7bca1603fc362)
如果出现嵌套的“{}”情况,则使用缩进对齐的形式,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P44_73864.jpg?sign=1738811793-5TqJ2pu2HUSqaqKI932jL0FtmrezLREG-0-82836e8a80e5d0637ea37be08151a1c7)
2.1.3 合理使用空格使代码更规范
(1)关键字之后要留一个空格。像const、case等关键字之后要保留一个空格,否则编译器无法辨析它是否是关键字。像if、for、while等关键字之后应该留一个空格,然后再跟小括号“(”,以突出显示关键字。
(2)在函数名之后不要留空格,要紧跟“(”,以示与关键字的区别。
(3)“(”后向紧跟,“)”“,”“;”前向紧跟,紧跟处不留空格。
(4)“,”之后要留空格,如果“;”不是一行的结束,则最后要留空格。
(5)赋值操作符、比较操作符、算术操作符、逻辑操作符、位操作符等,如“=”“+=”“>=”“<=”“+”“*”“%”“&&”“||”“<<”“^”等二元操作符的前后都应该适当加空格。对于比较长的表达式,即使是使用了这些二元操作符,也应该适当地去掉一些空格,使表达式看起来紧凑。
(6)一元操作符如“!”“~”“++”“--”等前后不加空格。像“[ ]”“.”“->”等操作符,同样前后不加空格。
例如,下面的代码,属于良好的编程风格。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P44_73865.jpg?sign=1738811793-Liw1tt1mekcWVOcIBiB3IKbd8zxKMHYn-0-3c62370fedd198faf7889248bde55fc4)
2.1.4 换行使代码更清晰
代码行最大的长度应该控制在70~80个字符,代码行不用过长,否则用户不能一屏看完整,而且也不便于打印。长的表达式要在低优先级操作符处拆分成新行,操作符放在新行的前面,用于突出显示操作符。拆分出来的新行要适当地缩进,使代码版式整齐,语句可读。例如下面这些代码段。
1.按操作符优先级拆分
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P45_73866.jpg?sign=1738811793-3yNVsU6MvL5lCZfOEeRe5oETItTtlFwd-0-4fe6d0c394db5a15575893bfc5a57dc8)
2.按表达式的意义拆分
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P45_73867.jpg?sign=1738811793-YMms18iIU4ZJYy5vId1K1pqchTBnBRLy-0-f2f9ab282712186e6c93684081498b7a)
2.2 关键字
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P45_7805.jpg?sign=1738811793-UBVLa76G0N5fwVRWgR5gP1WjpmDuVsGC-0-ca52c67292a2dd7293bc4eee2827221e)
视频讲解
在C语言中有32个关键字,在此将其整理列出。在今后的学习中将会逐渐地接触到这些关键字的具体使用方法,如表2.1所示。
表2.1 C语言中的关键字
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T45_73869.jpg?sign=1738811793-PL33p63yu4bWLhlaZcQ2nLIOkVJmpz3g-0-24c95d539c2d15b8d59c25a05e7dba54)
说明
在C语言中关键字是不允许作为标识符出现在程序中的。
2.3 标识符
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P45_7831.jpg?sign=1738811793-c9M6EvXIipYLJ1QHPYBtp70cwYFitXSM-0-9e00287ac84799ccabff552ed52b941e)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P45_7818.jpg?sign=1738811793-C3X5aNe9IbJEKUnfcRSNKrerANwMWWFO-0-103367c70efadb42da63e01e29d4434e)
动图演示
在C语言程序的运行过程中,为了可以使用变量、常量、函数、数组等,就要为这些形式设定一个名称,而设定的名称就是所谓的标识符。
在国外,外国人的名字是将名字放在前面将家族的姓氏放在后面,而在中国却恰恰相反,把姓氏放在前面而将名字放在后面。从中可以看出名字是可以随便起的,但是也要按照一个地区的规则进行更改。在C语言中设定一个标识符的名称是非常自由的,可以设定自己喜欢的、容易理解的名字,但是还是应该在一定的范围内进行自由发挥。下面介绍有关设定C语言标识符应该遵守的一些命名规则。
所有标识符必须由字母或下划线开头,而不能使用数字或者符号作为开头。通过下面一些正确写法和错误写法的比较进行说明,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73871.jpg?sign=1738811793-zGrQ6j899ALYegESgpg3vz3ylEfms8JT-0-150f939653f7f774f2ec9bbe3ceeb3cb)
在设定标识符时,除作开头外,其他位置都可以用字母、下划线或数字组成。例如:
在标识符中,有下划线的情况:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73872.jpg?sign=1738811793-dWiCj9b0Sceru0Y0igSMUjxCUgwLQJLS-0-7bcb529e4784d071fc59293280fc90bd)
在标识符中,有数字的情况:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73873.jpg?sign=1738811793-A5FW6kBBeMM0RYlhCRsEVdPPdCjYxXwK-0-e8039a6ffe048cbca1b19bc5ef5eeae6)
注意
虽然在设定标识符时,数字不允许放在一个标识符的开头位置,但是数字可以放在标识符中。一些符号同样不允许放在一个标识符的开头位置,不过放在标识符中也是不允许的。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73880.jpg?sign=1738811793-JFZVMd06YG9Bpan0x1RY6TOxk4BVdM5U-0-524cba3485703ec0eddb65478625b10a)
英文字母的大小写代表不同的标识符,也就是说在C语言中是区分大小写字母的。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73874.jpg?sign=1738811793-YbVEfokDjRFzTIxEFcqWZweqekCcWziT-0-1d7c721de1fd63549031b2b7cc0c9b0c)
从这些举出的标识符中可以看出,只要标识符中的字符有一项是不同的,那么代表的就是一个新的名称。
标识符不能是关键字。关键字是进行定义一种类型使用的字符,标识符是不能做关键字进行使用。例如,定义第一个整型时,会使用int关键字进行定义,但是定义的标识符就不能使用int。如果将其中标识符的字母改写成大写字母,这样就可以通过编译,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P46_73875.jpg?sign=1738811793-nmVaDEcf7glBcx1XHYUwN6z0m44gs682-0-e2fcc7cad9347d6055012578bc143875)
标识符的命名最好具有相关的含义。将标识符设定成有一定含义的名称,这样可以方便程序的编写,并且以后再进行回顾时,或者他人进行阅读时,具有含义的标识符会使程序便于观察、阅读。例如,下面的例子是在定义一个长方体的长、宽和高时,简单的定义与有相应含义的定义的对比。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P47_73882.jpg?sign=1738811793-A1D64YXoOn9BkvnodErjmyaWKzPRZqKt-0-c68599b0551fcc7656c11b6fe053ca7b)
从上面例子的标识符可以看出,标识符的设定如果不具有一定的含义,那么在没有后面的注释时是很难理解它要代表的作用是什么。如果将标识符的设定具有其功能含义,那么通过直观地查看就可以了解到其具体的作用功能。
ANSI标准规定:标识符可以为任意长度,但外部名必须至少能由前8个字符唯一地区分。这是因为某些编译程序(如IBM PC的MS C)仅能识别前8个字符。
2.4 数据类型
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P47_8004.jpg?sign=1738811793-ugxsvnF7FvCJDrFLEw4nAQ85uD3Lt6RZ-0-55521176841ea3d51554cf09d0164026)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P47_7995.jpg?sign=1738811793-lhIKyWB79fhSMtrQhEI6OfhCDuFWZdaA-0-2a6f51f83e602a1f5c3acab40fedd4ed)
动图演示
程序在运行时要做的内容就是处理数据,程序要解决复杂的问题,就要处理不同的数据。不同的数据都是以自己本身的一种特定形式存在的(如整型、实型、字符型等),不同的数据类型占用不同的存储空间。在C语言中,有多种不同的数据类型,其中包括几个大的方向:基本数据类型、构造类型、指针类型和空类型。我们先通过图2.1看一下其组织结构,之后再对每一种类型进行相应的讲解。
基本类型
基本类型也就是C语言中的基础类型,其中包括整数类型、字符型、实型(浮点型)、枚举类型。
构造类型
构造类型就是使用基本类型的数据,或者使用已经构造好的数据类型,进行添加、设计构造出新的数据类型,使其设计的新构造类型满足待解决问题所需要的数据类型。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P47_7990.jpg?sign=1738811793-2PfsvxlIhfUixLIM8E1EQ52WlLt8UxDe-0-5b14f40f06e522766187dfcd960f9c37)
图2.1 数据类型
通过构造类型的说明可以看出,它并不像基本类型一样简单,而是由多种类型组合而成的新类型。其中每一组成部分称为“构造类型的成员”。
构造类型包括3种形式,其中有数组类型、结构体类型和共用体类型。
指针类型
C语言的精华是什么?是指针。指针类型不同于其他类型之处在于,指针的值表示的是某个内存地址。
空类型
空类型的关键字是void,其主要的两点作用在于:
对函数返回的限定。
对函数参数的限定。
也就是说,一般一个函数都会具有一个返回值,将其值返回到调用者。这个返回值应该是具有特定的类型的,如整型int。但是函数不需要返回一个值时,那么就可以使用空类型设定返回值的类型。
2.5 常量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P48_8043.jpg?sign=1738811793-Xa5GR74mKhaEo0HLxGu3jkFoyYV2wekL-0-bcce2d90088633b399487efaa4583fad)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P48_8032.jpg?sign=1738811793-GTRnCL1G4nxcAifwZhDf3TBz6a2dfIA1-0-22814040dd39393e425149a69f303eb4)
动图演示
在介绍常量之前,先来了解一下什么是常量,常量就是其值在程序运行的过程中是不可以改变的。将这些直接常量分为以下几类。
数值型常量
整型常量
实型常量
字符型常量
符号常量
下面将对有关的直接常量进行详细的说明。
2.5.1 整型常量
整型常量就是指直接使用的整型常数,如123、-456等。整型常量可以是长整型、短整型、符号整型和无符号整型。
无符号短整型的取值范围是0~65535,而符号短整型的取值范围是-32768~32767,这些都是16位整型常量的范围。
如果整型是32位的,那么无符号形式的取值范围是0~4294967295,而有符号形式的范围是-2147483648~2147483647。但是整型如果是16位的,那么同无符号短整型的范围相同。
说明
根据不同的编译器,整型数据的取值范围是不一样的。还有可能如果在16位的计算机中整型就为16位,在字长为32位的计算机上整型就为32位。
长整型是32位的,其取值范围可以参考上面有关整型的描述。
在编写整型常量时,可以在常量的后面加上符号L或者U进行修饰。L表示该常量是长整型,U表示该常量为无符号整型,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P49_73904.jpg?sign=1738811793-fCryfnn5qxrDrwSeXHwbcI7ivXrpNDH5-0-45b60fbcb818ffd49af5a6a01d878ed4)
说明
表示长整型和无符号整型的后缀字母L和U可以使用大写,也可以使用小写。
整型常量有以上的这些类型,这些类型又可以通过3种形式进行表示,即八进制形式、十进制形式和十六进制形式。下面分别进行介绍。
八进制整数
要使得使用的数据表示形式是八进制,需要在常数前加上0进行修饰。八进制所包含的数字是0~7。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P49_73905.jpg?sign=1738811793-tzXizcjWyk82gua1OFE87w0lArVsHpJe-0-e2d6445e59dbebe9786e114c954a2502)
注意
以下关于八进制的写法是错误的:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P49_73906.jpg?sign=1738811793-vuoUHf5yQpU1Te9nb12MbtUs6eFy46GO-0-2f240158cab91f492b27cfae62470978)
十六进制整数
常量前面使用0x作为前缀,表示该常量是用十六进制进行表示。十六进制中所包含的数字有0~9以及字母A~F。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P49_73907.jpg?sign=1738811793-IJqznUZf6WDgKQhwzFOgkd0w8NpSJ8x1-0-bbf31ddd2bfab0436b7027a4351cff02)
说明
其中字母A~F可以使用大写形式,也可使用a~f小写形式。
注意
以下关于十六进制的写法是错误的:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P49_73908.jpg?sign=1738811793-XUCKr1fkviScYSzo47szZaHSKbl0Oai0-0-a54e66de37d847628f56a45745492ac5)
十进制整数
十进制是不需要在其前面添加前缀的。十进制中所包含的数字有0~9。例如:
AlgorismNumber1=123; AlgorismNumber2=456;
这些整型数据都是以二进制的方式存放在计算机的内存之中,其数值是以补码的形式进行表示的。一个正数的补码与其原码的形式相同,一个负数的补码是将该数绝对值的二进制形式,按位取反再加1。例如一个十进制数11在内存中的表现形式如图2.2所示:
如果是-11的话,那么在内存中又是怎样的呢?因为是以补码进行表示,所以负数要先将其绝对值求出,如图2.2所示,然后进行取反操作,如图2.3所示,得到取反后的结果。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P50_8155.jpg?sign=1738811793-ODAdlznfXylkpeVutHwVyJGuRGOyXF38-0-d24fd896af4d43fe08aa677de2fbf80e)
图2.2 十进制数11在内存中
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P50_8156.jpg?sign=1738811793-rJWrfxcI1O1R0WI1xBHiLpPL7FA71QhV-0-6d6eef363d4545ea7d0f6696e872b19b)
图2.3 进行取反操作
进行取反之后还要进行加1操作,这样就得到最终的结果。如图2.4所示,负数-11在计算机内存中存储的情况。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P50_8160.jpg?sign=1738811793-HeNApAlhSuct3TguwAauYDX0K7fHxAVX-0-a8f839a4dda6f22e3a931b362318c98d)
图2.4 加1操作
说明
对于有符号整数,其在内存中存放的最左面一位表示符号位,如果该位为0,则说明该数为正,若为1,则说明该数为负。
技巧
Windows操作系统中,在“开始”菜单的“附件”中有一个计算器的小软件,可以使用这个小软件进行八进制、十进制和十六进制之间的转换。这里需要注意的是,要选用科学型计算器,调整的方法是在其“查看”菜单中选择“科学型”一项,之后显示的样式如图2.5所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P50_8151.jpg?sign=1738811793-W0yit1YStxfSdWIWnvoFDaNiPkgdBKJ6-0-dab2eb4b7c92aba4893cd3663537bdc6)
图2.5 科学型计算器
2.5.2 实型常量
实型也称为浮点型,由整数部分和小数部分这两块组成,其中用十进制的小数点进行隔开。表示实数的方式有两种。
科学记数方式
科学记数方式就是使用十进制的小数方法描述实型,例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P51_73924.jpg?sign=1738811793-Vr89AwxrGDVDgsgPxAGCvxJduxIScy32-0-4d258c4be96b87d26c9667063293b004)
指数方式
有时候实型非常大或者非常小,这样使用科学记数方式是不利于观察的,这时可以使用指数方法来表示实型常量。这种方法使用字母e或者E进行指数显示,如45e2表示的就是4500,而45e-2表示的就是0.45。那么例如将上面的SciNum1和SciNum2代表的实型常量,改使用指数方式表示这两个实型常量如下所示:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P51_73925.jpg?sign=1738811793-rYXCNgaB0RnNl3TxDdbAGLuH7cnT22sv-0-64682a889561605abfd39d1fc578b641)
在编写实型常量时,可以在常量的后面加上符号F或者L进行修饰。F表示该常量是float(单精度)类型,L表示该常量为long double(长双精度)类型。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P51_73926.jpg?sign=1738811793-2JYN5kR5Ofp3GrES6GlVsB9KysYfpzdf-0-b4cdbeab5166e9d514a39445778095d0)
如果不在后面加上后缀,那么在默认状态下,实型常量为double(双精度)类型。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P51_73927.jpg?sign=1738811793-AO0g5L5D72Gf04J76nzMhBFMB88hvwFb-0-63e27bed26287068fdd2d0114d8e6743)
注意
后缀的大小写是通用的。
2.5.3 字符型常量
字符型常量与之前所介绍的常量有所不同,要对其字符型常量使用指定的定界符进行限制。字符型常量可以分成字符常量和字符串常量两种。下面分别对这两种字符型常量进行介绍。
1.字符常量
使用单撇号进行括起一个字符这种形式就是字符常量。例如'A'、'#'、'b'等都是正确的字符常量。在这里需要注意以下几点有关字符常量的注意事项。
字符常量中只能包括一个字符,不是字符串。例如,'A'这样是正确的,但是用'AB'这样来表示字符常量就是错误的。
字符常量是区分大小写的。例如,'A'字符和'a'字符是不一样的,这两个字符代表着不同的字符常量。
所使用的“' '”这对单撇号代表着定界符,这是不属于字符常量中的一部分的。
【例2.1】 字符常量的输出。(实例位置:资源包\源码\02\2.1)
在这个实例中,使用putchar函数将单个字符常量进行输出,使得输出的字符常量形成一个单词Hello显示在控制台中。
运行程序,显示效果如图2.6所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P52_73930.jpg?sign=1738811793-7PhW4gXJBbyQW7iYyUWVlGbgf4PbBA9O-0-d90b7f0f87006a2916f10143ee586efc)
2.字符串常量
字符串常量是用一组双引号括起来的若干字符序列。如果在字符串中一个字符都没有,则将其称作为空串,此时字符串的长度为0。例如字符串“Have a good day!”和“bueatful day”。
C语言中存储字符串常量时,系统会在字符串的末尾自动加一个'\0'作为字符串的结束标志。例如字符串“welcome”,其在内存中存储形式如图2.7所示。
注意
在程序中编写字符串常量时,不必在一个字符串的结尾处加上‘\0’结束字符,结束字符系统会自动进行添加。
【例2.2】 输出字符串常量。(实例位置:资源包\源码\02\2.2)
在本实例中,使用printf函数将一个句字符串常量“What a nice day!”在控制台进行输出显示。
运行程序,效果如图2.8所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P52_8309.jpg?sign=1738811793-H0EfNCfalYmEeXv8xOpdxCOIuMEN4j8s-0-9ab632faf07b02b31c004f4295bb75c8)
图2.6 使用字符常量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P52_73938.jpg?sign=1738811793-jg8lXJ4r0HbQ0KI6mrh9gPnKlmoQyXOn-0-721fee5694a246bdc116e334ba062cf3)
图2.7 \0为系统所加
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P52_8335.jpg?sign=1738811793-xYguUQmgsYAg17ieuZB2PGD7UVF921st-0-5f67df8790dfac771900ca25643ab2de)
图2.8 输出字符串
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P52_73931.jpg?sign=1738811793-3qRqXlD1JfuvkjTDL1J2XaWHvzNjZdUx-0-a1bd202ef730f62dd599e3e0b14cc97e)
上面介绍了有关字符常量和字符串常量的内容,那么同样是字符它们之间有什么差别呢?字符常量和字符串常量是不一样的,不同点主要体现如下几个方面。
定界符的使用不同:字符常量使用的是单引号,而字符串常量使用的是双引号。
长度不同:在上面提到过字符常量只能有一个字符,也就是说字符常量的长度就是为1。而字符串常量的长度却可以是0,即使字符串常量中的字符数量只有1个,但是长度却不是1。例如,字符串常量“H”,其长度为2。通过图2.9可以观察到,为什么字符串常量“H”的长度为2。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P53_73943.jpg?sign=1738811793-z5y2kfvomPiWRPIojKADSBuMn4dztZbQ-0-a5bedb9c6d1c05a612410f9d29396784)
图2.9 字符串“H”
说明
还记得在字符串常量中有关结束字符的介绍吗?系统会自动在字符串的尾部添加一个字符串的结束字符‘\0’,这也就是为什么“H”的长度是2的原因。
存储的方式不同:在字符常量中存储的是字符的ASCII码值,而在字符串常量中,不仅要存储有效的字符,还要存储结尾处的结束标志‘\0’。
在学习的过程中提到过有关ASCII码的内容,那么ASCII码是什么呢?在C语言中,所使用的字符被一一映射到一个表中,这个表称为ASCII码表如表2.2所示。
表2.2 ASCII表
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T53_73947.jpg?sign=1738811793-6s0n8Y1ooNkeJcCLsFYHLdQSkRq6uaac-0-437ae08404fcea0784b1f866a9cb31d9)
续表
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T54_73949.jpg?sign=1738811793-qDk1fMvB11EuBOQ8OfkVDFH3r3mrxNYV-0-a5cdf9642090a0f581ef38fe378e508b)
续表
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T55_73951.jpg?sign=1738811793-jWpOcBnm3gOjaGsPDa5L3XvdcinHlMUh-0-79daa77afdf2281d4e051ba968c576cd)
续表
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T56_73953.jpg?sign=1738811793-5mSnw2JSNmIZJ4XfmclXBC3deMfobrzM-0-f7d632ff992a5b924f3c1fe56996d20e)
2.5.4 转义字符
在前面的例2.1和例2.2中都能看到\n这个符号,但是在输出的显示结果却没有显示该符号,只是进行了换行操作,这种情况的符号称为转义符号。
转义符号在字符常量中是一种特殊的字符。转义字符是以反斜杠“\”为开头的字符,后面跟一个或几个字符。常用的转义字符及其含义如表2.3所示。
表2.3 常用转义字符表
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T57_73955.jpg?sign=1738811793-HMncBC0f0xAFoHJBuoQ7Idguej3pODXe-0-4f049f86b59dea206f4fd934065e8490)
2.5.5 符号常量
在第1章的例1.2中,程序的功能是进行求解的一个长方体的体积是多少,其中的长方体的高度是固定的,使用一个符号名进行代替固定的常量值,这里使用的符号名称为符号常量。使用符号常量的好处在于可以为编程和阅读带来方便。
【例2.3】 符号常量的使用。(实例位置:资源包\源码\02\2.3)
在本例中使用符号常量来表示圆周率,在控制台上进行显示文字提示用户输入数据,该数据是圆半径的值。得到用户输入的半径,经过计算得到圆的面积,最后将其结果显示。
运行程序,显示效果如图2.10所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P57_9581.jpg?sign=1738811793-dMJrH2HlMksCuxYWqvvtERrN22yJE55l-0-96cd2cc56aca7a40b0a00701aefb7cd9)
图2.10 常量符号的使用
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P57_73957.jpg?sign=1738811793-j0EKGTYKSIU0eqJGFZPjldpKLSSZiiQX-0-06ed86b5520daf76ada87b9d9a265a8c)
2.6 变量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P58_9756.jpg?sign=1738811793-vskxEtMyjqVLqoj7WDRnm1UVGZBPlUs5-0-9a701d5c6f72d7d864ccc75fd0bd2581)
视频讲解
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P58_9747.jpg?sign=1738811793-kUsTlzhX48HJFrOKc6KTtMpo30jQzlDE-0-bc92f40f618d515c7e42598c499bf918)
动图演示
在前面的例子中已经多次接触过变量。变量就是在程序运行期间其值是可以进行变化的量。每一个变量都是一种类型,每一种类型都定义了变量的格式和行为。那么一个变量应该有属于自己的名字,并且在内存中占有存储空间,其中变量的大小取决于类型。在C语言中的变量类型有整型变量、实型变量和字符型变量。
2.6.1 整型变量
整型变量是用来存储整型数值的变量。整型变量可以分为6种类型,其中基本类型的符号使用int关键字,在此基础上可以根据需要加上一些符号进行修饰,如关键字short或long。表2.4中对这6种类型进行介绍。
表2.4 整型变量的分类
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T58_73960.jpg?sign=1738811793-Eyp9VIW6dftmzp9pC1jZLqX0JdM5tGRO-0-03796b712ff16409c57240a8fabc792d)
说明
表格中的“[]”为可选部分。例如[signed] int,在编写时可以省略signed关键字。
有符号基本整型
有符号基本整型是指signed int型,其值是基本的整型常数。编写时,常常将其关键字signed进行省略。有符号基本整型在内存中占4个字节,取值范围是-2147483648~2147483647。
说明
通常说到的整型,都是指有符号基本整型int。
定义一个有符号整型变量的方法,是使用关键字int定义一个变量,例如要定义一个整型的变量iNumber,为iNumber变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P58_73964.jpg?sign=1738811793-ZJZic7uaJ3KrIqMnNlQJq0hyXLeCL1mP-0-ef08904085c7b0dd4c16997e2d3b1419)
或者在定义变量的同时,为变量进行赋值:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_73966.jpg?sign=1738811793-T9A1Ilt3c2z8HoCkK9SpCqiwQA348tRz-0-dccc59e05a63403eecfe2a02d5fbbd31)
【例2.4】 有符号基本整型。(实例位置:资源包\源码\02\2.4)
实例中对有符号基本整型的变量使用,使读者更为直观地看到其作用。
运行程序,显示效果如图2.11所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_9867.jpg?sign=1738811793-pY7BBpLH4n5QMz5yAKDfjGWydfmSmlve-0-fcbb58cc793e5814fd0ae212501dc4e9)
图2.11 有符号基本整型
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_73967.jpg?sign=1738811793-oCi29pNNYTqdgx8LB5ln4E4O0kBoM3Nz-0-df694b65779e5c05070e30f923620400)
无符号基本整型
无符号基本整型使用的关键字是unsigned int,其中的关键字int在编写时是可以省略的。无符号基本整型在内存中占4个字节,取值范围是0~4294967295。
定义一个无符号基本整型变量的方法,是在变量前使用关键字unsigned定义一个变量,例如要定义一个无符号基本整型的变量iUnsignedNum,为iNumber变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_73968.jpg?sign=1738811793-CA30AVO3534dRwsQsCUEO9p43N5xkx5T-0-ece0044fadf9f9ea2b3c9607419333ce)
有符号短整型
有符号短整型使用的关键字是signed short int,其中的关键字signed和int在编写时是可以省略的。有符号短整型在内存中占2个字节,取值范围是-32768~32767。
定义一个有符号短整型变量的方法,是在变量前使用关键字short定义一个变量,例如要定义一个有符号短整型的变量iShortNum,为iShortNum变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_73969.jpg?sign=1738811793-VAQ9dMY4WUrH21dOX9ODGW7XOzAvdS2i-0-161ed5fa2a645eae50c997e5ba1251b7)
无符号短整型
无符号短整型使用的关键字是unsigned short int,其中的关键字int在编写时是可以省略的。无符号短整型在内存中占2个字节,取值范围是0~65535。
定义一个无符号短整型变量的方法,是在变量前使用关键字unsigned short定义一个变量,例如要定义一个无符号短整型的变量iUnsignedShtNum,为iUnsignedShtNum变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P59_73970.jpg?sign=1738811793-BSIkmiNVHScsDXst8iBjVjt5dJAo6At5-0-955a7395b974aed587fcf77960846152)
有符号长整型
有符号长整型使用的关键字是signed long int,其中的关键字signed和int在编写时是可以省略的。有符号长整型在内存中占4个字节,取值范围是-2147483648~2147483647。
定义一个有符号长整型变量的方法,是在变量前使用关键字long定义一个变量,例如要定义一个有符号长整型的变量iLongNum,为iLongNum变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P60_73978.jpg?sign=1738811793-vy184oCR5sPmnSI68NMZ6whxdSOhqQXG-0-41ed51a926f57e0a4b01182c31b7cd12)
无符号长整型
无符号长整型使用的关键字是unsigned long int,其中的关键字int在编写时是可以省略的。无符号长整型在内存中占4个字节,取值范围是0~4294967295。
定义一个无符号长整型变量的方法,是在变量前使用关键字unsigned long定义一个变量,例如要定义一个有符号长整型的变量iUnsignedLongNum,为iUnsignedLongNum变量赋值为10的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P60_73979.jpg?sign=1738811793-I6DFRQKM0OscUVUyzoYAIjmBxMLkWeoH-0-bc95667576de01e5be2d5c1385be6cdb)
2.6.2 实型变量
实型变量也称为浮点型变量,是指用来存储实型数值的变量,其中实型数值是由整数和小数两个部分组成的。实型变量根据实型的精度也可以分为3种类型,包括单精度类型、双精度类型和长双精度类型,如表2.5所示。
表2.5 实型变量的分类
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T60_73982.jpg?sign=1738811793-CZ4Zy1ifSgPTBCsM2TAAY5yBt0dpNqfP-0-d49022a8345a82b7482095352226ceb9)
单精度类型
单精度类型使用的关键字是float。单精度类型在内存中占4个字节,取值范围是-3.4×10-38~ 3.4×1038。
定义一个单精度类型变量的方法,是在变量前使用关键字float,例如要定义一个变量fFloatStyle,为fFloatStyle变量赋值为3.14的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P60_73980.jpg?sign=1738811793-az4Is9JfUJuYvsUjxEUDFUwZ3wOHUKeY-0-08f5222717146ce6e753bb7642339391)
【例2.5】 使用单精度类型变量。(实例位置:资源包\源码\02\2.5)
在本实例中,定义一个单精度类型变量,然后为其赋值为1.23,最后通过输出语句将其显示在控制台。
运行程序,显示效果如图2.12所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P60_9952.jpg?sign=1738811793-xeKeBE5uUGD5WD6GV8syTDE0HT8gPP3j-0-b0867d642bb328508767838d44bdd38d)
图2.12 使用单精度类型变量
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P61_73983.jpg?sign=1738811793-V6gfNgV2wkVQ6GLRi3ncUm3cSKMFG0aq-0-fc28274451309dde4fcd12bc4e408b88)
双精度类型
双精度类型使用的关键字是double。双精度类型在内存中占8个字节,取值范围是-1.7×10-308~ 1.7×10308。
定义一个双精度类型变量的方法,是在变量前使用关键字double,例如要定义一个变量dDoubleStyle,为dDoubleStyle变量赋值为5.321的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P61_73984.jpg?sign=1738811793-esJOGOfb3t0Wckb2lt4GKzFY7H5Lar0M-0-efe38dd343ea440b782275b36b247160)
【例2.6】 使用双精度类型变量。(实例位置:资源包\源码\02\2.6)
在本实例中,定义一个双精度类型变量,然后为其赋值为61.458,最后通过输出语句将其显示在控制台。
运行程序,显示效果如图2.13所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P61_10094.jpg?sign=1738811793-BdPa1S7LW2p2XDWjuwl64A2lTKajPb5a-0-c21851a90a2ab6576be5e9c6545de8d8)
图2.13 使用双精度类型变量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P61_73985.jpg?sign=1738811793-HJnoZ8PN5eAzi1UZGHL82wgYYg8A7oTL-0-eb3cee5d4d265e4142ededa4b9dbbb95)
长双精度类型
长双精度类型使用的关键字是long double。长双精度类型在内存中占8个字节,取值范围是-1.7×10-308~1.7×10308。
定义一个双精度类型变量的方法,是在变量前使用关键字long double,例如要定义一个变量fLongDouble,为fLongDouble变量赋值为46.257的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P61_73986.jpg?sign=1738811793-sxWGIAvXdNLmGuzfEa56aQ6vmXgPZzI6-0-aa834240539014776548fe0031135395)
【例2.7】 使用长双精度类型变量。(实例位置:资源包\源码\ 02\2.7)
在本实例中,定义一个双精度类型变量,然后为其赋值为46.257,最后通过输出语句将其显示在控制台。
运行程序,显示效果如图2.14所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P62_10180.jpg?sign=1738811793-CANmIF1jZPADcr8kCaSvedHAdoNqcYdd-0-767bec9866dda282a68f280de8645fcb)
图2.14 使用长双精度类型变量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P62_73990.jpg?sign=1738811793-cuFHhj2FHwNZhrY6A1UUzxYBeDaE5Bbf-0-779d34d988c8feddfa48181f8aa562ff)
2.6.3 字符型变量
字符型变量是用来存储字符常量的变量。将一个字符常量存储到一个字符变量中,实际上是将该字符的ASCII码值(无符号整数)存储到内存单元中。
字符型变量在内存空间中占1个字节,取值范围是-128~127。
定义一个字符型变量的方法是使用关键字char,例如要定义一个字符型的变量cChar,为cChar变量赋值为'a'的方法如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P62_73991.jpg?sign=1738811793-YuhH2huXIHln6oC3JJToZu4Mol5su1lT-0-b1e56f9718abcc377e9b831104e2d401)
说明
字符数据在内存中存储的是字符的ASCII码,即一个无符号整数,其形式与整数的存储形式一样,所以C语言允许字符型数据与整型数据之间通用。例如:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P62_73992.jpg?sign=1738811793-YU6ji4WAKqCYvXQoc29vUtWu6J23Gphs-0-60faded3847f9625a500dca0ac456df3)
在上面的代码中可以看到,首先定义两个字符型变量,在为两个变量进行赋值时,一个变量赋值为'a',而另一个赋值为97。最后显示结果时都是为字符'a'。
【例2.8】 使用字符型变量。(实例位置:资源包\源码\02\2.8)
在本实例中,通过为定义的字符型变量和整型变量的赋不同值,通过观察输出的结果了解有关整型变量和字符型变量之间的转换。
运行程序,显示效果如图2.15所示。
程序代码如下:
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P63_10398.jpg?sign=1738811793-KmrBPgr6qF2cvG5mN5gAbrljmMRJPxEl-0-32d616aea226545087b34c4de37be21d)
图2.15 使用字符型变量
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P63_73995.jpg?sign=1738811793-woqKXt9Tg6PaCJEF61Ekzkit19tZ34E9-0-589060945a4ff7faebf33ef4aa9c495f)
以上就是有关整型变量、实型变量和字符型变量的相关知识,在这里对这些知识使用一个表格进行总体的概括,如表2.6所示。
表2.6 数值型和字符型数据的字节数和数值范围
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-T63_73997.jpg?sign=1738811793-jHaP2sE7Rw3jKKrJ841xVfkwEQQpIqbn-0-5c1cf50e17b28a623553b6987a9063ea)
2.7 实战
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P64_10430.jpg?sign=1738811793-eJjhwzgYVocRw5p113H1vHCtX5VdzCjW-0-1c826efc5e9f178cbca554540fd68616)
视频讲解
2.7.1 输出实型变量
定义a、b、c 3个变量,数据类型分别是float、double、long double,并且都赋值为123.456,输出这3个实型变量,运行效果如图2.16所示。(实例位置:资源包\源码\02\实战\01)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P64_10419.jpg?sign=1738811793-MJW3sBHH20mjUIxCrbqK4fDAuKgYqfOK-0-d42c9c483605241b18067d638b143eae)
图2.16 实型变量的使用
2.7.2 十进制转换为二进制
在C程序中,一般主要使用十进制数。有时为了提高效率或其他一些原因,还要使用二进制数,十进制数和二进制数之间可以直接转换,本实例即将平时在纸上运算的过程写入程序中。(实例位置:资源包\源码\02\实战\02)
将十进制数转换为二进制数的具体过程程序化,有以下几个要点。
(1)本题中要用数组来存储每次对2取余的结果,所以在数据类型定义时要定义数组并将其全部数据元素赋初值为0。
(2)两处用到了for循环,第一次for循环从0到14(本题中只考虑基本整型中的正数部分的转换所以最高位始终为零),第二次for循环从15到0,这里大家要注意不能改成0到15,因为在将每次对2取余的结果存入数组时,是从a[0]开始存储的,所以输出时就要从a[15]开始输出,这也符合我们平时计算的过程。
(3)%和/的应用,%模运算符,或称求余运算符,%两侧均应为整型数据。/除法运算符,两个整数相除的结果为整数,运算的两个数中有一个数为实数,则结果是double型的。
运行结果如图2.17所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P64_10422.jpg?sign=1738811793-oyGtUvubexVKnfWJiN3nzD75aOOU5rfL-0-806346277613cf5f41d939ed19b4da77)
图2.17 十进制转换为二进制
注意
for循环体中有多个语句要执行而不是一句所以“{}”要在适当位置加上,不要忘记写。
2.7.3 利用“#”输出图形
本例利用字符变量和“#”号,输出三角形,如图2.18所示。(实例位置:资源包\源码\02\实战\03)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P64_10425.jpg?sign=1738811793-jMHZALC4ealX7mQoVIym82yWv2ABvNAo-0-005cb335bfd0b5d9697ae83e412ff8fb)
图2.18 用“#”输出图形
2.7.4 打印杨辉三角
打印出以下的杨辉三角形(要求打印出10行)。(实例位置:资源包\源码\02\实战\04)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
……
什么是杨辉三角?
杨辉三角是二项式系数在三角形中的一种几何排列,它具有以下性质。
(1)每行数的左右对称,由1开始逐渐增大,然后变小,回到1。
(2)第n行数字个数为n个。
(3)每个数字等于上一行的左右两个数字的和。
(4)第n行的第1个数为1,第2个数为1×(n-1),第3个数为1×(n-1)×(n-2)/2,第4个数为1×(n-1)×(n-2)/2×(n-3)/3,……,依此类推。
运行结果如图2.19所示。
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P65_10449.jpg?sign=1738811793-t4DxBmTn0nDw0kBzj0ZKdWyTcqZr9hLC-0-2c8039a4e703d94631d0edc943edf29f)
图2.19 杨辉三角
2.7.5 利用“*”输出矩形
本例使用“*”号输出矩形,这里让每条边都输出3个“*”号,使其相等,运行程序,如图2.20所示。(实例位置:资源包\源码\02\实战\05)
![](https://epubservercos.yuewen.com/E2F069/15825991605218906/epubprivate/OEBPS/Images/Figure-P65_10452.jpg?sign=1738811793-5rjDCEVBOoDX5jDBaieZVtHbRYSNdzbz-0-ee9e3de157b0aa648a7e5c7c9c3f3e81)
图2.20 利用“*”号输出矩形