C语言入门经典(第5版)之编程初步

现在读者一定很渴望编写程序,让计算机与外界进行实际的交互。我们不希望程序只能做打字员的工作,显示包含在程序代码中的固定信息。的确,编程的内涵远不止此。理想情况下,我们应能从键盘上输入数据,让程序把它们存储在某个地方,这会让程序更具多样性。程序可以访问和处理这些数据,而且每次执行时,都可以处理不同的数据值。每次运行程序时输入不同的信息正是整个编程业的关键。在程序中存储数据项的地方是可以变化的,所以叫做变量(variable),而这正是本章的主题。

本章的主要内容:

●      内存的用法及变量的概念

●      在C中如何计算

●      变量的不同类型及其用途

●      强制类型转换的概念及其使用场合

●      编写一个程序,计算树木的高度

2.1  计算机的内存

首先看看计算机如何存储程序要处理的数据。为此,就要了解计算机的内存,在开始编写第一个程序之前,先简要介绍计算机的内存。

计算机执行程序时,组成程序的指令和程序所操作的数据都必须存储到某个地方。这个地方就是机器的内存,也称为主内存(main memory),或随机访问存储器(Random Access Memory,RAM)。RAM是易失性存储器。关闭PC后,RAM的内容就会丢失。PC把一个或多个磁盘驱动器作为其永久存储器。要在程序结束执行后存储起来的任何数据,都应打印出来或写入磁盘,因为程序结束时,存储在RAM中的结果就会丢失。

可以将计算机的RAM想象成一排井然有序的盒子。每个盒子都有两个状态:满为l,空为0。因此每个盒子代表—个二进制数:0或1。计算机有时用真(true)和假(false)表示它们:1是真,0是假。每个盒子称为—个位(bit),即二进制数(binary digit)的缩写。

注意:

如果读者不记得或从来没学过二进制数,可参阅附录A。但如果不明白这些内容,不用担心,因为这里的重点是计算机只能处理0与1,而不能直接处理十进制数。程序使用的所有数据(包括程序指令)都是由二进制数组成的。

为了方便起见,内存中的位以8个为—组,每组的8位称为一个字节(byte)。为了使用字节的内容,每个字节用一个数字表示,第—个字节用0表示,第二个字节用1表示,直到计算机内存的最后—个字节。字节的这个标记称为字节的地址(address)。因此,每个字节的地址都是唯一的。每栋房子都有一个唯一的街道地址。同样,字节的地址唯—地表示计算机内存中的字节。

总之,内存的最小单位是位(bit),将8个位组合为一组,称为字节(byte)。每个字节都有唯一的地址。字节地址从0开始。位只能是0或1,如图2-1所示。

图2-1  内存中的字节

计算机内存的常用单位是千字节(KB)、兆字节(MB)、千兆字节 (GB)。大型磁盘驱动器使用兆兆字节(TB)。这些单位的意义如下:

●      1KB是1 024字节。

●      1MB是1 024KB,也就是1 048 576字节。

●      1GB是1 024MB,也就是1 073 741 841字节。

●      1TB是1 024GB,也就是1 099 511 627 776字节。

如果PC有1GB的RAM,字节地址就是0~1 073 741 841。为什么不使用更简单的整数,例如千、百万或亿?因为从0到1023共1024个数字,而在二进制中,1023的10个位刚好全是l:11 1111 1111,它是一个非常方便的二进制数。1000是很好用的十进制数,但是在二进制的计算机里就不再那么方便了,它是111110 1000。因此以KB(1 024字节)为单位,是为了方便计算机使用。同样,MB需要20个位,GB需要30个位。

但是硬盘的容量可能出现混乱。磁盘制造商常常宣称他们生产的磁盘的容量是256GB或1TB,而实际上这两个数字表示2560亿字节及1万亿字节。当然,2560亿字节只有231MB,而1万亿字节只有911GB,所以磁盘制造商给出的硬盘容量有误导作用。

有了字节的概念,下面看看如何在程序里使用这些内存。

2.2  什么是变量

变量是计算机里一块特定的内存,它是由一个或多个连续的字节所组成,一般是1、2、4、8或16字节。每个变量都有一个名称,可以用该名称表示内存的这个位置,以提取它包含的数据或存储一个新数值。

下面编写一个程序,用第1章介绍的printf()函数显示你的薪水。假设你的薪水是10 000元/月,则很容易编写这个程序。

// Program 2.1 What is a Variable?

#include <stdio.h>

int main(void)

{

printf("My salary is $10000");

return 0;

}

这个程序的工作方式不需要多做解释,它和第一章开发的程序差不多。如何修改这个程序,让它能够根据存储在内存中的值,定制要显示的信息?这有几种方法,它们有一个共同点:使用变量。

在这个例子里,可以分配一块名为salary的内存,把值10 000存储在该变量中。要显示薪水时,可以使用给变量指定的名称salary,将存储在其中的值10 000显示出来。程序用到变量名时,计算机就会访问存储在其中的值。变量的使用次数是不受限制的。当薪水改变时,只要改变salary变量存储的值,整个程序就会使用新的值。当然,在计算机中,所有的值都存储为二进制数。

程序中变量的数量是没有限制的。在程序执行过程中,每个变量包含的值由程序的指令来决定。变量的值不是固定的,而可以随时改变,且没有次数的限制。

注意:

变量可以有一个或多个字节,那么,计算机如何知道变量有多少个字节?下一节会提到,每个变量都有类型来指定变量可以存储的数据种类。变量的类型决定了为它分配多少个字节。

变量的命名

给变量指定的名称一般称为变量名。变量的命名是很有弹性的。它可以是一个或多个大写或小写字母、数字和下划线( _ )(有时下划线也算作字母),但要以字母开头。下面是一些正确的变量名:

Radius          diameter            Auntie_May          Knotted_Wool            D678

变量名不能以数字开头,所以8_Ball和6_pack都是不合法的名称。变量名只能包含字母、下划线和数字,所以Hash!及Mary-Lou都不能用作变量名。Mary-Lou是一个常见的错误,但是Mary_Lou就是可以接受的。变量名中不能有空格,所以Mary Lou会被视为两个变量名Mary和Lou。以一或两个下划线开头的变量名常用在头文件中,所以在给变量命名时,不要将下划线用作第一个字符,以免和标准库里的变量名冲突。例如最好避免使用_this和_that这样的变量名。变量名的另一个要点是,变量名是区分大小写的,因此Democrat和democrat是不同的。

可以在上述限制内随意指定变量名,但最好使变量名有助于了解该变量包含的内容,例如用变量名x来存储薪水信息就不好,而使用变量名salary就好得多,对其用途不会有什么疑义。

警告:

变量名可以包含的字符数取决于编译器,遵循C语言标准的编译器至少支持31个字符,只要不超过这个长度就没问题。建议变量名不要超过这个长度,因为这样的变量名比较繁琐,代码也难以理解。有些编译器会截短过长的变量名。

2.3  存储整数的变量

变量有几种不同的类型,每种变量都用于存储特定类型的数据。有几种变量可存储整数、非整数的数值和字符。一些类型存储特定的数据(例如整数),它们之间的区别是它们占用的内存量和可以存储的数值范围。首先看看用于存储整数的变量。

整数是没有小数点的数字。下面是一个例子:

123                     10,999,000,000                      20,000                      88                      1

这些数值是整数,但这对程序而言并不完全正确。整数是不能包含逗号的,所以第二个值在程序里应该写成10999000000,第三个值应写成20000。

下面是一些不是整数的例子:

1.234               999.9               2.0             –0.0005             3.14159265

2.0一般算作整数,但是计算机不将它算作整数,因为它带有小数点。在程序里,必须把这个数字写作2,不带小数点。在C程序中,整数总是写成不带小数点的数字,如果数字中有小数点,就不是整数,而是浮点数,详见后面的内容。在详细讨论整型变量之前,先看看程序里一个简单的变量,学习变量的用法。

试试看:使用变量

回到输出薪水的例子。将前面的程序改为使用一个int型变量:

// Program 2.2 Using a variable

#include <stdio.h>

int main(void)

{

int salary;                                                                                       //Declare a variable called salary

salary = 10000;                                                                           //Store 10000 in salary

printf("My salary is %d.\n", salary);

return 0;

}

输入这个例子,编译、链接并执行,会得到下面的结果:

My salary is 10000.

代码的说明

前三行和前一个例子相同,下面看看新的语句。用来存放薪水的变量声明语句如下:

intsalary;                                                                 //Declare a variable called salary

这个语句称为变量声明,因为它声明了变量的名称。在这个程序中,变量名是salary。

警告:

变量声明语句以分号结束。如果漏掉分号,程序编译时会产生错误。

变量声明也指定了这个变量存储的数据类型,这里使用关键字int指定,salary用来存放一个整数。关键字int放在变量名称之前。这是可用于存储整数的几个类型之一。

如后面所述,声明存储其他数据类型的变量时,要使用另一个关键字指定数据类型,其方式大致相同。

注意:

关键字是特殊的C保留字,对编译器有特殊的意义。不能将它们用作变量名称或代码中的其他实体,否则编译器会生成错误消息。

变量声明也称为变量的定义,因为它分配了一些存储空间,来存储整数值,该整数可以用变量名salary来引用。

注意:

声明引入了一个变量名,定义则给变量分配存储空间。有这个区别的原因在本书后面会很清楚。

当然,现在还未指定变量salary的值,所以此刻该变量包含一个垃圾值,即上次使用这块内存空间时遗留在此的值。

下一个语句是:

salary= 10000;                                                                                 //Store 10000 in salary

这是一个简单的算术赋值语句,它将等号右边的数值存储到等号左边的变量中。这里声明了变量salary,它的值是10 000。将右边的值10 000存储到左边的变量salary中。等号“=”称为赋值运算符,它将右边的值赋予左边的变量。

然后是熟悉的printf()语句,但这里的用法和之前稍有不同:

printf("My salary is %d.",salary);

括号内有两个参数,用逗号分开。参数是传递给函数的值。在这个程序语句中,传给printf()函数的两个参数如下:

●      参数1是一个控制字符串,用来控制其后的参数输出以什么方式显示,它是放在双引号内的字符串,也称为格式字符串,因为它指定了输出数据的格式。

●      参数2是变量名salary。这个变量值的显示方式是由第一个参数——控制字符串来确定。

这个控制字符串和前一个例子相当类似,都包含一些要显示的文本。但在本例的这个字符串中有一个%d,它称为变量值的转换说明符(conversion specifier)。

转换说明符确定变量在屏幕上的显示方式,换言之,它们指定最初的二进制值转换为什么形式,显示在屏幕上。在本例中使用了d,它是应用于整数值的十进制说明符,表示第二个参数salary输出为一个十进制数。

注意:

转换说明符总是以%字符开头,以便printf()函数识别出它们。控制字符串中的%总是表示转换说明符的开头,所以如果要输出%字符,就必须用转义序列%%。

试试看:使用更多的变量

试试一个稍大的程序:

// Program 2.3 Using more variables

#include <stdio.h>

int main(void)

{

int brothers;                                                                             //Declare a variable called brothers

int brides;                                                                                   //and a variable called brides

brothers = 7;                                                                             //Store 7 in the variable brothers

brides = 7;                                                                                   //Store 7 in the variable brides

// Display some output

printf("%d brides for %d brothers\n", brides, brothers);

return 0;

}

执行程序的结果如下:

7 brides for 7 brothers;

代码的说明

这个程序和前一个例子相当类似。首先声明两个变量brothers和brides,语句如下:

int brothers;                                                                                       //Declare a variable called brothers

int brides;                                                                                         //and a variable called brides

两个变量都声明为int类型,都存储整数值。注意,它们在两个语句中声明。由于这两个变量的类型相同,故可以将它们放在同一行代码上声明:

int brothers, brides;

在一个语句中声明多个变量时,必须用逗号将数据类型后面的变量名分开,该语句要用分号结束。这是一种很方便的格式,但有一个缺点:每个变量的作用不很明显,因为它们全放在一行代码上,不能加入注释来描述每个变量。因此可以将它们分成两行,语句如下:

int     brothers,                                                                                   //Declare a variable called brothers

brides;                                                                                         //and a variable called brides

将语句分成两行,就可以加入注释了。这些注释会被编译器忽略,因此和最初没加入注释的语句相同。可以将C语句分成好几行。分号决定语句的结束,而不是代码行的结束。

当然也可以编写两个声明语句。一般最好在一个语句中定义一个变量。变量声明常常放在函数的可执行语句的开头,但这不是必须的。一般把要在一块代码中使用的变量声明放在该起始括号的后面。

之后的两个语句给两个变量赋值7:

brothers = 7;                                                                                           // Store 7 in the variable brothers

brides = 7;                                                                                             // Store 7 in the variable brides

注意,声明这些变量的语句放在上述语句之前。如果遗漏了某个声明,或把声明语句放在后面,程序就不会编译。变量在其声明之前在代码中是不存在的,必须总是在使用变量之前声明它。

下一个语句调用printf()函数,它的第一个参数是一个控制字符串,以显示一行文本。这个字符串还包含规范,指定后续参数的值如何解释和显示在文本中。这个控制字符串中的两个转换说明符%d会分别被printf()函数的第二个参数brides和第三个参数brothers的值取代:

printf("%dbrides for %d brothers\n", brides, brothers);

转换说明符按顺序被printf()函数的第二个参数brides和第三个参数brothers的值取代:变量brides的值对应第一个%d,变量brothers的值对应第二个%d。如果将设置变量值的语句改为如下所示,将会更清楚:

brothers = 8;                                                                                           // Store 8 in the variable brothers

brides = 4;                                                                                             // Store 4 in the variable brides

在这个比较明确的例子中,printf()语句会清楚地显示变量和转换说明符的对应关系,因为输出如下所示:

4 brides for 8 brothers

为了演示变量名是区分大小写的,修改printf()函数,使其中一个变量名以大写字母开头,如下所示:

// Program 2.3A Using more variables

#include <stdio.h>

int main(void)

{

int brothers;                                                                                               // Declare a variable called brothers

int brides;                                                                                                     // and a variable called brides

brothers = 7;                                                                                               // Store 7 in the variable brothers

brides = 7;                                                                                                     // Store 7 in the variable brides

// Display some output

printf("%d brides for %d brothers\n", Brides, brothers);

return 0;

}

编译这个版本的程序时,会得到一个错误信息。编译器把brides和Brides解释为两个不同的变量,所以它不理解Brides这个变量,因为没有声明它。这是一个常见的错误,如前所述,打字和拼写错误是出错的一个主要原因。变量必须在使用之前声明,否则编译器就无法识别,将该语句标识为错误。

2.3.1  变量的使用

前面介绍了如何声明及命名变量,但这和在第一章学到的知识相比并没有太多用处。下面编写另一个程序,在产生输出前使用变量的值。

试试看:作一个简单的计算

这个程序用变量的值做简单的计算:

// Program 2.4 Simple calculations

#include <stdio.h>

int main(void)

{

int total_pets;

int cats;

int dogs;

int ponies;

int others;

// Set the number of each kind of pet

cats = 2;

dogs = 1;

ponies = 1;

others = 46;

// Calculate the total number of pets

total_pets = cats + dogs + ponies + others;

printf("We have %d pets in total\n", total_pets);             // Output the result

return 0;

}

执行程序的结果如下:

Wehave 50 pets in total

代码的说明

与前面的例子一样,大括号中的所有语句都有相同的缩进量,这说明这些语句都包含在这对大括号中。应当仿效此法组织程序,使位于一对大括号之间的一组语句有相同的缩进量,使程序更易于理解。

首先,定义5个int类型的变量:

int total_pets;

int cats;

int dogs;

int ponies;

int others;

因为这些变量都用来存放动物的数量,它们肯定是整数,所以都声明为int类型。

下面用4个赋值语句给变量指定特定的值:

cats = 2;

dogs = 1;

ponies = 1;

others = 46;

现在,变量Total_Pets还没有设定明确的值,它的值是使用其他变量进行计算的结果:

total_pets= cats + dogs + ponies + others;

在这个算术语句中,把每个变量的值加在一起,计算出赋值运算符右边的所有宠物数的总和,再将这个总和存储到赋值运算符左边的变量Total_Pets中。这个新值替代了存储在变量Total_Pets中的旧值。

printf()语句显示了变量Total_Pets的值,即计算结果:

printf("Wehave %d pets in total\n", total_pets);

试着改变某些宠物的值,或增加一些宠物。记住要声明它们,给它们设定数值,将它们加进变量Total_Pets中。

2.3.2  变量的初始化

在上面的例子,用下面的语句声明每个变量:

intcats;                                                               //The number of cats as pets

用下面的语句设定变量Cats的值:

Cats = 2;

将变量Cats的值设为2。这个语句执行之前,变量的值是什么?它可以是任何数。第一个语句创建了变量Cats,但它的值是上一个程序在那块内存中留下的数值。其后的赋值语句将变量Cats的值设置为2。但最好在声明变量时,就初始化它,语句如下所示:

int Cats = 2;

这个语句将变量Cat声明为int类型,并设定初值为2。声明变量时就初始化它一般是很好的做法。它可避免对初始值的怀疑,当程序运作不正常时,它有助于追踪错误。避免在创建变量时使用垃圾值,可以减少程序出错时计算机崩溃的机会。随意使用垃圾值可能导致各种问题,因此从现在起,就养成初始化变量的好习惯,即使是0也好。

上面的程序是第一个真正做了些事情的程序。它非常简单,仅仅相加了几个数字,但这是非常重要的一步。它是运用算术语句进行运算的一个基本例子。下面介绍一些更复杂的计算。

1. 基本算术运算

在C语言中,算术语句的格式如下:

变量名= 算术表达式;

赋值运算符右边的算术表达式指定使用变量中存储的值和/或明确给出的数字,以及算术运算符如加(+)、减(-)、乘(*)及除(/)进行计算。在算术表达式中也可以使用其他运算符,如后面所述。

前面例子中的算术语句如下:

total_pets= cats + dogs + ponies + others;

这个语句先计算等号右边的算术表达式,再将所得的结果存到左边的变量中。

在C语言中,符号“=”定义了一个动作,而不是像数学中那样说明两边相等。它指定将右边表达式的结果存到左边的变量中。因此可以编写下面的语句:

total_pets= total_pets + 2;

以数学的观点来看,它是很荒唐的,但对编程而言它是正确的。假定重新编写程序,添加上面的语句。添加了这个语句的程序段如下:

total_pets = cats + dogs + ponies + others;

total_pets =total_pets + 2;

printf("The total number of petsis: %d", total_pets);

在执行完第一个语句后,Total_Pets的值是50。之后,第二行提取Total_Pets的值,给该值加2,再将结果存储回变量Total_Pets。因此最后显示出来的总数是52。

注意:

在赋值运算中,先计算等号右边的表达式,然后将结果存到等号左边的变量中。新的值取代赋值运算符左边的变量中的原值。赋值运算符左边的变量称为lvalue,因为在这个位置可以存储一个值。执行赋值运算符右边的表达式所得的值称为rvalue,因为它是计算表达式所得的一个值。

计算结果是数值的表达式称为算术表达式,下面都是算术表达式:

3                       1 + 2                       total_pets                      cats + dogs – ponies                        -data

计算这些表达式,都会得到一个数值。注意,变量名也是一个表达式,它的计算结果是一个值,即该变量包含的值。最后一个例子的值是data的负值,所以如果data包含-5,表达式-data的值就是5。当然,data的值仍是-5。稍后将详细讨论如何构建表达式,并学习运算规则。这里先用基本算术运算符做一些简单的例子。表2-1列出了这些算术运算符。

表2-1  基本算术运算符

运  算  符

动    作

+

-

*

/

%

取模(Modulus)

应用运算符的数据项一般称为操作数,两边的操作数都是整数时,所有这些运算符都生成整数结果。前面没有提到过取模运算符。它用运算符左边的表达式值去除运算符右边的表达式值,并求出其余数,所以有时称为余数运算符。表达式12 % 5的结果是2。因为12除以5的余数是2。下一节将详细介绍。所有这些运算符的工作方式都与我们的常识相同,只有除法运算符例外,它应用于整数时有点不直观。下面进行一些算术运算。

注意:

应用运算符的值称为操作数。需要两个操作数的运算符(如%)称为二元运算符。应用于一个值的运算符称为一元运算符。因此-在表达式a-b中是二元运算符,在表达式-data中是一元运算符。

试试看:减和乘

下面基于食物的程序演示了减法和乘法:

// Program 2.5 Calculations with cookies

#include <stdio.h>

int main(void)

{

int cookies = 5;

int cookie_calories = 125;                                            //Calories per cookie

int total_eaten = 0;                                                              //Total cookies eaten

int eaten = 2;                                                                                      // Number to be eaten

cookies = cookies - eaten;                                            // Subtract number eaten fromcookies

total_eaten = total_eaten + eaten;

printf("\nI have eaten %d cookies. There are %d cookies left",

eaten, cookies);

eaten = 3;                                                                                              // New value for cookies eaten

cookies = cookies - eaten;                                        // Subtract number eaten from cookies

total_eaten = total_eaten + eaten;

printf("\nI have eaten %d more. Now there are %d cookiesleft\n", eaten, cookies);

printf("\nTotal energy consumed is %dcalories.\n", total_eaten*cookie_calories);

return 0;

}

这个程序产生如下输出:

I have eaten 2 cookies. There are 3 cookies left

I have eaten 3 more. Now there are 0cookies left

Total energy consumedis 625 calories.

代码的说明

首先声明并初始化3个int类型的变量:

int cookies = 5;

int cookie_calories =125;                                              //Calories per cookie

int total_eaten = 0;                                                                    //Total cookies eaten

在程序中,使用变量total_eaten计算吃掉的饼干总数,所以要将它初始化为0。

下一个声明并初始化的变量存储吃掉的饼干数,如下:

inteaten = 2;                                                                                          // Number to be eaten

用减法运算符从cookies中减掉eaten:

cookies= cookies - eaten;                                              //Subtract number eaten from cookies

减法运算的结果存回cookies变量,所以cookies的值变成3。因为吃掉了一些饼干,所以要给total_eaten增加吃掉的饼干数:

total_eaten= total_eaten + eaten;

将eaten变量的当前值2加到total_eaten的当前值0上,结果存储回变量total_eaten。printf()语句显示剩下的饼干数:

printf("\nI have eaten %d cookies. There are%d cookies left",

eaten, cookies);

这个语句在一行上放不下,所以在printf()的第一个参数后的逗号后面,将该语句的其他内容放在下一行上。可以像这样分拆语句,使程序易于理解,或放在屏幕的指定宽度之内。注意不能用这种方式拆分第一个字符串参数。不能在字符串的中间放置换行符。需要将字符串拆开成两行或多行时,一行上的每一段字符串必须有自己的一对双引号。例如,上面的语句可以写成:

printf("\nI have eaten %d cookies. "

" There are %d cookies left",

eaten, cookies);

如果两个或多个字符串彼此相邻,编译器会将它们连接起来,构成一个字符串。

用整数值的转换说明符%d将eaten和cookies的值显示出来。在输出字符串中,eaten的值取代第一个%d, cookies的值取代第二个%d。字符串在显示之前会先换行,因为开头处有一个\n。

下一个语句将变量eaten的值设为一个新值:

eaten= 3;                                                                                                          // New value for cookies to beeaten

新值3取代eaten变量中的旧值2。然后完成和以前一样的操作序列:

cookies = cookies - eaten;                                                  // Subtract numbereaten from cookies

total_eaten =total_eaten + eaten;

printf("\nI have eaten %d more.Now there are %d cookies left\n", eaten, cookies);

最后,在执行return语句,结束程序前,计算并显示被吃掉饼干的卡路里数:

printf("\nTotalenergy consumed is %d calories.\n", total_eaten*cookie_calories);

printf()函数的第二个参数是一个算术表达式,而不是变量。编译器会将表达式total_eaten*cookie_calories的计算结果存储到一个临时变量中,再把该值作为第二个参数传送给printf()函数。函数的参数总是可以使用算术表达式,只要其计算结果是需要的类型即可。

下面看看除法和取模运算符。

试试看:除法和取模运算符

假设你有一罐饼干(其中有45块饼干)和7个孩子。要把饼干平分给每个孩子,计算每个孩子可得到几块饼干,分完后剩下几块饼干。

// Program 2.6 Cookies and kids

#include <stdio.h>

int main(void)

{

int cookies = 45;                                                                             //Number of cookies in the jar

int children = 7;                                                                             //Number of children

int cookies_per_child = 0;                                                //Number of cookies per child

int cookies_left_over = 0;                                                // Number of cookiesleft over

// Calculate how many cookies each child gets when they are divided up

cookies_per_child = cookies/children;     //Number of cookies per child

printf("You have %d children and %d cookies\n", children,cookies);

printf("Give each child %d cookies.\n",cookies_per_child);

// Calculate how many cookies are left over

cookies_left_over = cookies%children;

printf("There are %d cookies left over.\n", cookies_left_over);

return 0;

}

执行程序后的输出:

You have 7 children and 45 cookies

Give each child 6cookies.

There are 3 cookiesleft over.

代码的说明

下面一步一步地解释这个程序。下面的语句声明并初始化4个整数变量:cookies、children、cookies_per_child、cookies_left_over:

int cookies = 45;                                                                                           // Number of cookies in the jar

int children = 7;                                                                                           // Number of children

int cookies_per_child= 0;                                                          //Number of cookies per child

int cookies_left_over = 0;                                                          //Number of cookies left over

使用除号运算符“/”将饼干数量除以孩子的数量,得到每个孩子分得的饼干数:

cookies_per_child= cookies/children;                   //Number of cookies per child

下面两个语句输出结果,即cookies/children变量的值:

printf("You have %d children and %dcookies\n", children, cookies);

printf("Give each child %dcookies.\n", cookies_per_child);

从输出结果可以看出,cookies_per_child的值是6。这是因为当操作数是整数时,除法运算符总是得到整数值。45除以7的结果是6,余3。下面的语句用取模运算符计算余数:

cookies_left_over= cookies%children;

赋值运算符右边的表达式计算cookies除以children得到的余数。最后一个语句输出余数:

printf("Thereare %d cookies left over.\n", cookies_left_over);

2. 深入了解整数除法

当一个操作数是负数时,使用除法和模数运算符的结果是什么?在执行除法运算时,如果操作数不同号,结果就是负数。因此,表达式-45/7和45/-7的结果相同,都是-6。如果操作数同号,都是正数或都是负数,结果就是正数。因此45/7和-45/-7结果都是6。至于模数运算符,不管操作数是否同号,其结果总是和左操作数的符号相同。因此45%-7等于3,-45/7等于-3,-45/-7也等于-3。

3. 一元运算符

例如,乘法运算符是一个二元运算符。因为它有两个操作数,其结果是一个操作数乘以另一个操作数。还有一些运算符是一元运算符,即它们只需一个操作数。后面将介绍更多的例子。但现在看看一个最常用的一元运算符。

4. 一元减号运算符

前面使用的运算符都是二元运算符,因为它们都操作两个数据项。C语言中也有操作一个数据项的一元运算符。一元减号运算符就是一个例子。若操作数为负,它就生成正的结果,若操作数为正,它就生成负的结果。要了解一元减号运算符的使用场合,考虑一下追踪银行账号。假定我们在银行存了200元。在簿子里用两列记录这笔钱的收支情况,一列记录付出的费用,另一列记录得到的收入,支出列是负数,收入列是正数。

我们决定购买一片价值50元的CD和一本价值25元的书。假使一切顺利,从银行的初始值中减掉支出的75元后,就得到了余额。表2-2说明这些项的记录情况。

表2-2  收入与支出记录

收    入

支    出

存 款 余 额

支票收入

$200

$200

CD

$50

$150

$25

$125

结余

$200

$75

$125

如果将这些数字存储到变量中,可以将收入及支出都输入为正数,只有计算余额时,才会把这些数字变成负数。为此,可以将一个负号(-)放在变量名的前面。

要把总支出输出为负数,可编写如下语句:

int expenditure = 75;

printf("Your balance has changedby %d.", -expenditure);

这会产生如下结果:

Yourbalance has changed by -75.

负号表示花掉了这笔钱,而不是赚了。注意,表达式-expenditure不会改变expenditure变量的值,它仍然是75。这个表达式的值是-75。

在表达式-expenditure中,一元减号运算符指定了一个动作,其结果是翻转expenditure变量的符号:将负数变成正数,将正数变成负数。这和编写一个负数(如-75或-1.25)时使用的负号运算符是不同的。此时,负号不表示一个动作,程序执行时,不需要执行指令。它只是告诉编译器,在程序里创建一个负的常量。



小结:C语言是每一位程序员都应该掌握的基础语言。C语言是微软.NET编程中使用的C#语言的基础;C语言是iPhone、iPad和其他苹果设备编程中使用的Objective-C语言的基础;C语言是在很多环境中(包括GNU项目)被广泛使用的C++语言的基础。C语言也是Linux操作系统及其很多功能的基础。学习C语言可以给编程职业生涯提供牢固的基础,也有助于更好地理解更为现代的语言(如Java)。 

《C语言入门经典(第5版)》主要介绍最基础的计算机语言之一——C语言。本书从最基础的内容开始,步步深入讲解作为一位称职的C语言程序员应该具备的知识和技能。





C语言入门经典(第5版)》试读电子书免费提供,有需要的留下邮箱,一有空即发送给大家。 别忘啦顶哦!



转载于:https://my.oschina.net/cjkall/blog/195969

猜你喜欢

转载自blog.csdn.net/weixin_34051201/article/details/91756377
今日推荐