C Primer Plus (第五版)中文版——第 3 章 数据和 C

3.1  示例程序

/*用GOLD衡量我的体重*/
#include <stdio.h>
int main(void)
{
	float weight;    /*体重kg*/
	float value;     /*同等质量黄金的价格*/
	printf("Hello,Mr.Gold.Are you worth your weight in gold?\n");
	printf("Let's check it out.\n");
	printf("Please enter your weight in kg: \n");
	scanf_s("%f", &weight);         /*从用户处获取输入*/
	value = 270.0 * weight * 1000;  /*假设黄金¥270/g*/
	printf("Your weight in gold is worth ¥%.2f.\n", value);
	return 0;
}

此程序中包含 C 语言的一些新元素:

  • 一种新的变量声明 float weight;声明一个浮点(float)变量类型,以便处理更大范围内的数据
  • 常量的几种新写法,现在您可以使用带小数点的数了
  • 要打印这种新的变量类型,需在代码中使用 %f 格式说明符来处理浮点值。对 %f 说明符使用 .2 修饰词可以精确控制输出格式,使浮点数显示到小数点后两位
  • 使用 scanf() 函数为程序提供键盘输入。%f 指示 scanf() 从键盘读取一个浮点数,&weight 指定将输入值赋予变量 weight 。scanf() 函数使用 & 符号指示 weight 变量的位置
  • scanf() 和 printf() 函数体现了程序的交互性

3.2  变量与常量数据

变量是一段特定的计算机内存,有一个或多个连续的字节构成。变量的三个要素为:变量名、变量类型、变量的值。每个变量有一个名字,可以用变量名引用这段内存,读取它存放的数据,或在此存放一个新数据值。变量的类型有多种,每种类型用于存储一种特定的数据。

在程序执行过程中,其值不发生改变的量称为常量。常量分为直接常量和符号常量。直接常量是指可以立即拿来用,无需任何说明的量,如整型常量 12、实型常量 6.13、字符常量 ‘a’。符号常量是指用标识符来表示常量,符号常量在使用之前必须先定义。常量一般全用大写字母命名,用下划线分割单词。定义常量有三种方式:

#define PI 3.14         /*PI 只是3.1415926的别名,在编译期间用3.1415926去取代PI的值*/
const float PI = 3.14;  /*将 PI 定义成变量,但告诉编译器它的值是固定不变的,若在程序中试图去修改 PI 值,编译时会报错*/
enum Sex{MALE,FEMALE}   /*枚举常量,值是从0开始递增,即 MALE=0,FEMALE=1*/

3.3  数据:数据类型关键字

K&R C 给出了7个数据类型相关的关键字(int、short、long、unsigned、char、float、double)。C90标准向其中添加了两个关键字(signed、void)。C99标准又添加了另外三个(_Bool、_Complex、_Imaginary)。

计算机存储的基本单位是位(bit),每一位可以存储一个二进制数(0或1);每8个位称为一个字节(byte),每个字节由一个数字标记,这种标记叫做地址,字节的地址可以唯一地引用计算机内存中的特定字节。内存常用千字节、兆字节甚至千兆字节表示:1千字节(1KB)=1024字节、1兆字节(1MB)=1024千字节(KB)、1千兆字节(1GB)=1024兆字节(MB)。

3.3.1  整数类型与浮点数类型

数据类型可以按其在计算机中的存储方式被划分为两个系列,即整数(integer)类型和浮点数(floating-point)类型。

3.3.2  整数

整数就是没有小数部分的数。在 C 中,小数点永远不会出现在整数的书写中。整数以二进制数字存储。

3.3.3  浮点数

浮点数可以与数学中的实数概念相对应。浮点数表示法将一个数分为小数部分和指数部分并分别存储。整数和浮点数的区别:

  • 整数没有小数部分,浮点数可以有小数部分
  • 浮点数可以表示比整数范围大得多的数
  • 对于一些算术运算,使用浮点数会损失更多精度
  • 计算机浮点数不能表示区域内所有的值
  • 浮点运算通常比整数运算慢

3.4  C 数据类型

3.4.1  int 类型

一、声明 int 类型变量:为变量创建、标定存储空间

int age;                   /*声明一个变量*/
int apple,pen,pinapple;    /*同时声明多个变量*/

二、初始化变量 :为变量赋一个初始值

age = 20;          /*直接赋值*/
scanf(%d,&age);    /*使用scanf()函数为程序提供键盘输入,%d指示scanf()从键盘读取一个整数,
                     &age指定将输入值赋于名为age的变量中,&符号指示age变量的位置*/
scanf("%d %d %d",&apple,&pen,&pineapple);
                    
int age = 20;      /*在声明语句中初始化变量*/
int apple = 1,pen = 2,pineapple = 3;

三、打印 int 值 

printf("%d\n",age);    /*printf()函数有两个参数,它们之间由逗号分隔;
                         参数1是控制字符串,它控制如何显示由后面的参数指定的输出;
                         参数2是变量age;
                         %d称为格式说明符,它指示printf()应使用什么格式来显示一个数值*/
printf("apple = %d,pen = %d,pineapple = %d\n",apple,pen,pineapple)
                        /*必须确保格式说明符的数目同参数2中变量数目相同*/

五、八进制和十六进制

在 C 中,允许使用三种数制书写数字:十进制、八进制、十六进制,并由专门的前缀指明哪一种进制。前缀 0 表示使用八进制值,十进制数16用八进制表示为020。前缀 0x 或 0X 表示使用十六进制值,则十进制数16用十六进制表示为 0x10 或 0X10。在 C 中,也允许以这三种数制显示数字,并由专门的格式说明符指明哪一种数制。%o 表示用八进制显示整数,%x 或 %X 表示用十六进制显示整数。若想显示C语言前缀,可以使用说明符%#o、%#x、%#X分别生成0、0x、0X前缀。

#include <stdio.h>
int main(void)	/*分别以十进制、八进制、十六进制打印数字*/
{
	int age = 20;

	printf("dec = %d,octal = %o, hex = %x\n", age, age, age, age);    /*分别以十进制、八进制、十六进制显示十进制数20*/
	printf("dec = %d,octal = %#o,hex = %#x\n", age, age, age, age);   /*分别以十进制、八进制、十六进制显示十进制数20,并显示C语言前缀*/
	return 0;
}

编译并运行上面的程序,将产生下列输出:

dec = 20,octal = 24, hex = 14
dec = 20,octal = 024,hex = 0x14

3.4.2  其他整数类型

C 提供4个附属关键字修饰基本的整数类型:short、long、signed、unsigned。

一、声明其他整数类型

short apple;/*带有修饰关键字时,可省略 int 不写,如:long int apple;与 long apple;等价*/
unsigned short apple;
int apple;
unsigned apple;
long apple;
unsigned long apple;
long long apple;
unsigned long  long apple;
/*signed可以和任何有符号类型一起使用,它使数据的类型更加明确,例如:以下四条指令等价*/
short int apple;short apple;signed short int apple;signed short apple;

二、long 常量和long long 常量

若希望把一个较小的常量作为 long 类型对待,可以使用字母L(或l)后缀,比如20L;类似地,在支持 long long 类型的系统中,可以使用 ll 或 LL 后缀标识 long long 类型值,比如3LL;u 或 U 后缀用于标识 unsigned long long 类型值,比如5ull、10LLU、9Ull。 

三、打印short、long、long long 和unsigned 类型数

#include <stdio.h>
int main(void)	/*打印 short、long、long long 和 unsigned 类型数*/
{
	short a = 1;
	unsigned short b = 2;
	int c = 3;
	unsigned d = 4;
	long e = 5;
	unsigned long f = 6;
	long long g = 7;
	unsigned long long h = 8;

	printf("a = %hd;", a);	/*short 类型使用 %hd */
	printf("b = %hu;", b);	/*unsigned short 类型使用 %hu */
	printf("c = %d;", c);	/*int 类型使用 %d */
	printf("d = %u;", d);	/*unsigned int 类型使用 %u */
	printf("e = %ld;", e);	/*long 类型使用 %ld */
	printf("f = %lu;", f);	/*unsigned long 类型使用 %lu */
	printf("g = %lld;", g);	/*long long 类型使用 %lld */
	printf("h = %llu;", h);	/*unsigned long long 类型使用 %llu */
	return 0;
}

编译并运行上面的程序,将产生下列输出:a = 1;b = 2;c = 3;d = 4;e = 5;f = 6;g = 7;h = 8;

3.4.3  使用字符:char 类型

char 类型用于存储字母和标点符号之类的字符。在技术实现上 char 是整数类型,因为 char 类型实际存储的是整数而不是字符。

一、声明char 类型变量

char table;         /*声明一个变量*/
char desk,chair;    /*同时声明多个变量*/

二、字符常量及其初始化

char grade = 'a';          /*声明变量grade赋字符A*/

单引号中的一个字符是 C 的一个字符常量,编译器遇到 ‘a’ 时会将其转化为相应的编码值,其中单引号是必不可少的。

char converged;
converged = 'T';        /*可以*/
converged = T;          /*不可以!把T看作一个变量*/
converged = "T";        /*不可以!把"T"看作一个字符串*/

三、非打印字符

有一些ASCII 字符是打印不出来的,例如以下动作描述:退格、换行、响铃等。如何表示这些字符呢?

第一种方法:使用ASCII 码,例如响铃字符的ASCII 值为7,因此:

char beep = 7;
printf("%c", beep);	/*响铃*/
ASCII 码表

第二种方法:转义序列

转义序列及其意义

给一个字符变量进行赋值时,转义序列必须用单引号括起来。

char nerf = '\n';
printf("%c", nerf);	/*换行*/

第三种方法:使用十六进制形式表示字符常量

char dollar = '\x24';
printf("%c", dollar);

四、打印字符

printf() 函数使用 %c 说明符打印一个字符。如果使用 %d 说明符打印一个 char 变量,将得到一个整数,该数为字符的十进制ASCII 码值。

char grade = 'A';
printf("%c\n", grade);	/*打印一个字符*/
printf("%d\n", grade);	/*打印一个字符的十进制ASCII码值*/

编译并运行上面的程序,将产生下列输出:

A
65

3.4.4  _Bool 类型

_Bool 类型由 C99 引入,用于标识布尔值,即逻辑值 true (真)与 false (假)。_Bool 类型实际上也是一种整数类型。

3.4.5  可移植的类型:inttypes.h

inttypes.h 头文件使用 typed 工具创建了新的类型名字,这些新的名称叫做“确切长度类型”。

/*altnames.c----可移植的整数类型名*/
#include <stdio.h>
#include <inttypes.h>	/*支持可移植类型*/
int main(void)
{
	int16_t me16;
	
	me16 = 2018;
	printf("First, assume int16_t is short: ");
	printf("me16 = %hd\n", me16);
	printf("Next, let's not make any assumptions.\n");
	printf("Instead, use a \"macro\" from inttypes.h: ");
	printf("me16 = %"PRId16"\n", me16);
	return 0;	
}

在最后的 printf() 语句中,参数 PRId16 被它在 inttypes.h 里的定义 "hd" 所替代,C 语言将三个连续的字符串合并为一个引号引起来的串,因而这行语句等价为:printf("me16 = %hd\n", me16);编译并运行上面的程序,将产生下列输出:

First, assume int16_t is short: me16 = 2018
Next, let's not make any assumptions.
Instead, use a "macro" from inttypes.h: me16 = 2018

3.4.6  float、double 和long double 类型

一、声明浮点变量

float altitude;
double height;
long double distance;

二、浮点常量

一个浮点常量最基本的形式是:包含小数点的一个带符号的数字序列,接着是字母 e 或 E,然后是代表10的指数的一个有符号值。如-6.18e2、1.3e-3。可以省略正号。可以没有小数点(3E5)或指数部分(3.14),但不能同时没有二者。可以省略纯小数部分(3.E5)或整数部分(.14E-5),但不能同时没有二者。

默认情况下,编译器会将浮点常量当作 double 类型,(通常)使用64位进行储存。乘积运算使用双精度结果被截为正常的 float长度,这能保证计算精度,但会减慢程序的执行。通过 F(或f)后缀可使编译器把浮点常量当作 float 类型,比如2.3f,3.14F。通过 L(或l)后缀可使浮点常量为long double类型,比如3.14L。没有后缀的浮点常量为 double 类型。

三、打印浮点值 

#include <stdio.h>
int main(void)	/*打印浮点值*/
{
	float a = 1.e5f;
	double b = 2E-3;
	long double c = 6.13E10L;
	
	printf("a = %f = %e;", a, a);	/*float 类型使用 %f 或%e */
	printf("b = %f = %e;", b, b);	/*double 类型使用 %f 或%e */
	printf("c = %lf= %e;", c, c);	/*long double 类型使用 %lf 或 %le */
	return 0;
}

3.4.8  其他类型

C 从基本类型中衍生出其他类型,包括数组、指针、结构和联合。

3.4.9  类型大小

C 的内置运算符 sizeof 以字节为单位给出类型的大小。

#include <stdio.h>
int main(void)			/* sizeof 以字节为单位给出类型的大小*/
{
	printf("char         %u bytes.\n", sizeof(char));
	printf("short        %u bytes.\n", sizeof(short));
	printf("int          %u bytes.\n", sizeof(int));
	printf("long         %u bytes.\n", sizeof(long));
	printf("long long    %u bytes.\n", sizeof(long long));
	printf("_Bool        %u bytes.\n", sizeof(_Bool));
	printf("float        %u bytes.\n", sizeof(float));
	printf("double       %u bytes.\n", sizeof(double));
	printf("long double  %u bytes.\n", sizeof(long double));
	return 0;
}
/*输出结果:
char         1 bytes.
short        2 bytes.
int          4 bytes.
long         4 bytes.
long long    8 bytes.
_Bool        1 bytes.
float        4 bytes.
double       8 bytes.
long double  8 bytes.

3.5  使用数据类型

开发程序时,应当注意所需变量及其类型的选择。一般地,使用 int 或 float 类型表示数字,使用 char 类型表示字符。在使用变量的函数开始处声明该变量,并为它选择有意义的名字。初始化变量使用的常量应当同变量类型相匹配。很多程序员和组织都有系统化的变量命名规则,其中变量的名字可以表示它的类型。例如:使用 i_前缀表示 int 变量,使用 us_ 前缀表示unsigned short 变量。这样通过名字就可以确定变量 i_smart 为 int 类型,变量 us_verysmart 为 unsigned short 类型。

3.9  总结

C 数据类型—字节大小—数据范围

整数可以表达为十进制、八进制或十六进制。前缀0指示八进制数,前缀0x或0X指示十六进制数 。

3.11  编程练习

 编程练习参考程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值