《C语言程序设计》一2.2 常量、数据的存储与数据类型

简介: 本节书摘来自华章出版社《C语言程序设计》一 书中的第2章,第2.2节,作者:赵宏 陈旭东 马迪芳,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.2 常量、数据的存储与数据类型

2.2.1 基本数据类型

数据是程序加工、处理的对象,也是加工、处理的结果,所以数据是程序设计中所要涉及和描述的主要内容。程序所能处理的基本数据对象被划分成一些组,或者说是一些集合。属于同一集合的各数据对象都具有同样的性质,程序设计语言中具有这样性质的数据集合称为数据类型。
所有数据都属于某种类型。一个数据的类型决定了这个数据在内存中的存储形式、取值范围和能够对它进行的操作。
C/C++ 中的数据类型大致可以分为两大类:第一类是基本数据类型,基本数据类型是系统预定义的类型,包括整型、浮点型(实型)和字符型;第二类是非基本数据类型,即自定义数据类型,包括数组、结构体、共用体、枚举类型和指针类型。本章介绍几种基本数据类型,其他数据类型将在以后各章陆续介绍。图2-1给出了这些数据类型。

image

基本数据类型是基元,所有的数据类型都建立在基本数据类型之上。C/C++语言的基本数据类型有以下几个:
int:整型
char:字符型
float:单精度浮点型
double:双精度浮点型
long double:长双精度浮点型
另外,在基本数据类型的基础上附加一些限定词,得到扩充的数据类型。short、long可以应用到整型,unsigned可以应用到整型和字符型:
short int(或short):短整型
long int(或long):长整型
unsigned int:无符号整型
unsigned short:无符号短整型
unsigned long:无符号长整型
unsigned char:无符号字符型
1.整型
数据的取值范围服从数学式子2n,其中n是这种类型所占内存位数,例如,如果int型是16位,它的数据取值范围为-2n~2n -1,即-32 768~32 767。无符号的数总是正数或零,而unsigned int型数据取值范围为0~2n +1-1,即0~65 535。
ANSI C标准没有规定以上各类数据所占内存位数,只要求short型数据不长于int型,而long型不短于int型,具体如何实现,由各编译系统决定。表2-1列出了ANSI C标准定义的整型数据的最小取值范围。
image

2.浮点型
浮点型数据也称为实数,可以是数字0.0和包含小数点的正数或负数。
C语言支持三种浮点数据类型:浮点型(也称单精度型(float))、双精度型(double)和长双精度型(long double)。这些数据类型之间的差别是编译器为每种类型分配的存储数量。一般情况下,为双精度浮点数采用的存储数量是浮点数采用的数量的两倍,这使双精度浮点数的精度大约是浮点数的两倍。使用sizeof(类型)可以显示你的编译器为每种数据类型提供的存储数量(字节数)。
当前的C编译器所提供的float型在内存中占用4个字节(32位),提供7位有效数字,可能的取值范围为-10-38~1038;double型数据占8个字节,提供15~16位有效数据,可能的取值约为-10-308~10308。浮点型数据的存储符合IEEE浮点数格式,如float型数据,1位用于符号,8位用于指数,23位用于基数。
3.字符型
字符型数据用于存储单个字符,存储时占用8位,它实际存储的是字符对应的ASCII码(American Standard Code for Information Interchange,美国标准信息交换码)。如一个char型数据‘A’,其ASCII码为65,故实际存储的内容是65。char型数据取值范围为-128~127,unsigned char型数据取值范围为0~255。字符有符号或无符号是依赖于机器的,但是可打印的字符总是正的。
由于在内存中字符型数据是以ASCII码形式存放的,其形式与整型类似,因而在C语言中,字符型数据与整型数据可以通用,字符型数据的所有性质与一字节整型量相同。

2.2.2 常量

在程序运行过程中其值不能被改变的量称为常量。本节介绍整型常量、实型常量、字符常量、字符串常量和符号常量。
1.整型常量
整型常量即整数。一个整型常量如123即为int型。长整型常量在后面加字母“l”或“L”,如123456789L,如果一个整型数超过了int类型的范围就会被当成一个long int。无符号常量在后面加上“u”或“U”,后缀为“ul”或“UL”表明是无符号长整型unsigned long。
整型常量可以使用三种形式表示:十进制数、八进制数、十六进制数。每种进制形式的数据都有特殊标记。
1)十进制数,如128、-60、0。
2)八进制数,以0开始的数据是八进制数,如0123代表八进制数123,即十进制数83。
3)十六进制数,以0x开始的数是十六进制数,如-0x128代表十六进制数-128,即十进制数-296。
2.实型常量
实型常量又称实数或浮点数。实数有两种表示形式:
1)十进制形式。它由三部分组成:整数部分、小数点、小数部分,当整数或小数部分为0时可以省略,但小数点不能省略。它适合于表示不太大或不太小的数,如128.0、.128、128.5、128.、0.0等都是十进制数形式。
2)指数形式。它由三部分组成:尾数、字符e(或E)、指数。它适用于表示较大或较小的数。e之前必须有数字,且e后面的指数必须为整数,如128e2或128E2都代表128×102。
如果实型常量后缀是“f”或“F”,则被当成float型,如果实型常量后缀是“l”或“L”,则被当成long double型,否则,C语言编译系统总是将实型常量处理成双精度型的。
3.字符常量
字符常量是用单引号括起来的一个字符,如‘A’、‘a’、‘?’、‘0’等。字符常量的值是机器字符集中字符的数字值,如字符常量‘0’,其ASCII码为48,所以存储的实际内容为48。程序中字符常量通常用于字符之间的比较,也可以像其他整型数一样参与运算,这在程序设计中处理字符时十分有用,如要将小写字母转换成大写字母,只需减去32即可。
字符常量中不包括“’”字符和换行等符号,为表示这些符号,字符常量还有另外一种形式——转义字符形式,由一对单引号中的转义字符组成,而转义字符是一组以“”开头的特殊字符序列,用这种方法可以表示任何可输出的字母字符、专用字符、控制字符和图形字符,如表2-2所示。
image

在程序prg2-1.c中在打印函数的最后一个字符使用了转义字符n,这样可以保证使屏幕光标移到下一行开头。
【例2-2】 转义字符的使用。

/*程序名:prg2-2.c*/
/*功能:使用转义字符控制数据的输出*/
#include<stdio.h>

int main()
{
   char c1 = 'A', c2 = '\101';

   printf("a\tbc\tABC\n");
   printf("xyz\t%c,%c" , c1 ,c2);

   return 0;
}

程序中第一个printf()函数首先在第1行第1列打印字母a,然后遇到t,它的作用是制表符(横向跳格),使屏幕光标移到下一制表位。系统把一行分为10个输出区,每个输出区占8列。下一个输出位置即从第9列开始输出,所以在第9列到第10列上输出bc,之后又是t,跳到第17列,在第17列到第19列输出ABC,n的作用是回车换行。第二个printf()函数首先在第2行第1列到第3列输出xyz,然后跳到下一个输出区,在第9列上输出A,然后输出一个逗号,再输出A,因为转义字符'101'代表的ASCII码是65,对应的是字符‘A’。程序运行结果为:

a    bc    ABC
xyz   A,A

4.字符串常量
字符串常量是由一对双引号括起来的字符序列,例如:

"How do you do."

双引号不是字符串的一部分,只起定界的作用。
字符串常量在编译时可以被连接起来,例如程序

int main()
{   
   printf("This is my first program in C/C++.\n");
   return 0;
}

输出结果为:

This is my first program in C/C++.

也可以写成:

int main()
{
   printf("This is my first program");
   printf("in C/C++.\n");
   return 0;
}

输出结果相同,这对把长字符串分割成几行是很有用的。
C/C++语言中,字符串常量是作为一个字符数组来处理的,字符串在存储时末尾被系统自动加上字符‘0’,因此物理存储的字符串长度比双引号中的字符数多1个。转义字符‘0’为空操作,它既不引起任何控制动作,也不会显示出来,但系统可以据此判断一个字符串是否结束。
要仔细区分字符常量和只包含一个字符的字符串常量,如‘x’与“x”,虽然都只有一个字符,但在内存中的情况是不同的。‘x’在内存中占一个字节,是一个整数,可以产生字符x在机器字符集中的数字值,“x”在内存中占两个字节,包含字符x和转义字符‘0’。

‘x’    x    
                                      “x”    x    \0

5.符号常量
前面介绍的几种类型的常量从字面形式就可以判别出来,如123为整型常量,0.65为实型常量,‘A’为字符型常量,“CHINA”为字符串常量。也可以用一个标识符代表一个常量,称为符号常量。
【例2-3】 符号常量的使用。

/*程序名:prg2-3.c*/
/*功能:符号常量的使用,计算圆的周长和面积*/
#include<stdio.h>
#define  PI  3.14159       /*定义符号常量PI的值为3.14159*/
int main()
{   
   float r, s, area;

   scanf("%f", &r);

   s = 2 * PI * r;
   area = PI * r * r;

   printf("s=%7.2f, area=%7.2f" , s , area);

   return 0;
}

程序中定义了一个符号常量PI来代表常量3.141 59,以后程序中PI就代表3.141 59,可以和常量一样使用。与变量不同,符号常量的值在程序中不能再改变。在程序中使用符号常量代替具有一定意义的常量,增加了程序的可读性、可理解性,易于程序的修改。当程序中某个符号常量需要修改时,只须修改符号常量的定义语句即可,避免了一个常量多处修改中因失误造成的不一致的错误。

#define是编译预处理语句,有关内容详见8.2节。

2.2.3 数据的存储

1.变量和内存的概念
变量是指程序运行过程中保存变化数据的内存单元,与数学中的变量不同。数学中的变量表示未知量,通过解方程求值。程序中的变量只是系统分配的内存单元,用来存放变化的数据。在程序prg2-1.c中定义了a、b、c、s和area等变量,对于每个变量,编译系统会在编译时为其分配相应的内存,所以这些变量名实际对应计算机内存中的地址,通过编程可以把数据保存到这些地址中,也可以从这些地址中读取数据。
在程序prg2-1.c中执行下列语句:

scanf("%f,%f,%f", &a, &b, &c);

“&”为取址运算符,即将用户输入的值存入a、b、c所对应的地址中。假设输入的数据为3、4、5,则内存中a对应的地址中存放3,b对应的地址中存放4,c对应的地址中存放5。

a    3
                                                                  b    4
                                                                  c    5

程序得到a、b、c的值后,对其进行运算:

s = (a + b + c)/2;

该语句从a、b、c对应的地址中读取到3、4和5,进行运算,然后把和值存放到s变量对应的地址中,这时,s中原来的值就被新值覆盖掉了,而a、b、c变量的值和计算之前一样,虽然被使用,但并没有丢失。
变量在程序运行过程中可以不断发生变化,但瞬时只能存放一个值。从变量中读取数据不会破坏变量的值,但是向变量中写数据时将用新数据替换原来的数据。
2.变量定义和赋初值
所有的变量必须先定义其类型,然后才能使用。一个定义中可以包含一个或多个同类型的变量,例如:

int total;                    /*指定total为整型变量*/
float width , length;              /*指定width、length为单精度实型变量*/
double area;                      /*指定area为双精度实型变量*/
char c1 , c2;                     /*指定c1、c2为字符型变量*/

程序中需要对一些变量预先设置初值,即变量可以在定义时进行初始化,例如:

int total = 0, i;                 /*指定total,i为整型变量,total的初值为0*/
int a = 5 , b = 5 , c = 5;         /*指定a、b、c为整型变量,a、b、c的初值为5*/
float esp = 0.001;                 /*指定esp为单精度实数,esp的初值为0.001*/
char c = 'a';                   /*指定c为字符型变量,c的初值为‘a’*/

变量必须先定义后使用的目的是:
1)可以保证程序中变量名使用的正确性。如已定义了一个变量count,但在程序中却写成了cuont,在编译时先检查变量名的合法性,发现cuont未被定义过,按出错处理,因而可以帮助人们查找拼写错误。
2)系统根据变量的类型为变量在内存中开辟存储单元。例如,变量a定义为short,系统会为变量a分配两个字节的内存,可以存放一个整数,变量x定义为float,则系统为变量x分配4个字节的内存,可以存放一个实数。
3)变量类型确定后,也就确定了变量的取值范围和可以对其进行的运算。
3.变量命名规则
定义一个变量,即给变量一个名字和数据类型。高级语言中,用来表示变量名、符号常量名、数组名、函数名等的有效字符序列称为标识符。
标识符由字母、数字和下划线“_”三种字符组成,且第一个字符必须为字母或下划线。C语言是区分大写字母和小写字母的,因此x与X是两个不同的名字。一般用小写字母作为变量的名字,而用大写字母作为符号常量的名字。
C标识符的长度无统一的规定,一般不超过128个字符。
C语言中的关键字(也称为保留字)是编程语言为某一特定用途而预先定义的一个字,并且关键字只能用特定的方式用于它的预先的用途,如if、int、float等有专门的用途,不能用这些名字作为变量的名字,否则编译代码时将产生错误。注意,关键字必须用小写。
给变量起名时应做到见名知意,用有意义的单词作为变量的名字,以增强程序的可读性。一般局部变量用短名字,特别是循环变量,而外部变量用长名字。

相关文章
|
1月前
|
存储 程序员 C语言
深入探讨C语言中的字符型数据类型及其应用
深入探讨C语言中的字符型数据类型及其应用
13 0
|
1天前
|
存储 C语言
C语言动态存储方式与静态存储方式
C语言动态存储方式与静态存储方式
7 0
|
1天前
|
C语言
深入理解C语言中的printf函数及数据输出
深入理解C语言中的printf函数及数据输出
11 0
|
26天前
|
存储 编译器 程序员
【C语言】整形数据和浮点型数据在内存中的存储
【C语言】整形数据和浮点型数据在内存中的存储
15 0
|
27天前
|
存储 编译器 C语言
C语言3🔥:常用的数据类型
C语言3🔥:常用的数据类型
14 0
|
27天前
|
编译器 C语言
C语言2🔥:常量,输入与输出
C语言2🔥:常量,输入与输出
18 0
|
27天前
|
Java C语言 C++
C语言由入门到精通(1)介绍与数据类型
C语言由入门到精通(1)介绍与数据类型
|
30天前
|
存储 安全 编译器
【C/C++ 基本数据类型】C++ 基本数据类型深度解析与C语言对比
【C/C++ 基本数据类型】C++ 基本数据类型深度解析与C语言对比
58 0
|
1月前
|
存储 文件存储 C语言
《C语言程序设计》课程设计 -- 火车票票务管理系统
《C语言程序设计》课程设计 -- 火车票票务管理系统
23 1
|
1月前
|
程序员 C语言
在C语言中,typedef是一种用来创建新的数据类型名的关键字
在C语言中,typedef是一种用来创建新的数据类型名的关键字
9 0