为什么80%的码农都做不了架构师?>>>   

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

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

  1. c语言入门经典+第5版+习题答案,C语言入门经典(第5版)

    摘要: C语言是每一位程序员都应该掌握的基础语言.C语言是微软.NET编程中使用的C#语言的基础;C语言是iPhone,iPad和其他苹果设备编程中使用的Objective-C语言的基础;C语言是在很 ...

  2. c语言入门经典第五版自学,C语言入门经典(第5版) PDF扫描[103MB]

    C语言入门经典(第5版)  内容简介: C语言是每一位程序员都应该掌握的基础语言.C语言是微软.NET编程中使用的C#语言的基础:C语言是iPhone.iPad和其他苹果设备编程中使用的Objecti ...

  3. c语言入门第6,c语言入门经典 第5版_c语言入门经典_c语言入门自学(6)

    1.8.5 函数体 main()函数的一般结构如图l-2 所示: 函数体是在函数名称后面位于起始及结束两个大括号之间的代码块.它包含了定义函数功能的所有语句.这个例子的main()函数体非常简单,只有 ...

  4. R语言必看推荐:R语言入门经典版(中文版)+R语言实战第二版(中文完整版)

    R语言入门经典(中文版)R for beginners R语言经典教材 第二版 适合初学者 作者:Emmanuel Paradis R 语言实战第二版(中文完整版) R语言实战(第2版)注重实用性,是 ...

  5. 计算机c语言入门.ppt,计算机c语言入门经典

    计算机c语言入门经典 C语言对编写需要进行硬件操作的场合,优于其它高级语言.小编为大家分享一些计算机c语言入门经典,欢迎参考! 一.开始之前 FAQ 那是什么 为何有这篇FAQ 编程为何物 如果这就是 ...

  6. c语言入门自学免费app,C语言入门学习最新版下载-C语言入门学习app手机版v1.0.2 安卓版-腾飞网...

    C语言入门学习app手机版是一款c语言编程自学软件,零基础也可以学习,里面有海量教学视频,针对c语言不同程度的讲解都囊括其中.随时随地学习编程都可以,不用担心自己没有基础.还支持在手机上敲代码编程哦. ...

  7. 算法竞赛入门经典(第二版)第三章习题

    声明:作者水平有限,只是会基础C语言的小菜,C++还未入门.作者仅根据算法竞赛入门经典(第二版)书上第三章习题所述题意而编写,并未严格按照原题的输入输出编写,代码仅经过个人测试(OJ网站太慢了).代码 ...

  8. 《算法竞赛入门经典(第2版)》

    <算法竞赛入门经典(第2版)> 基本信息 作者: 刘汝佳 丛书名: 算法艺术与信息学竞赛 出版社:清华大学出版社 ISBN:9787302356288 上架时间:2014-6-5 出版日期 ...

  9. C语言入门经典书目推荐--转

    国内良莠不齐的C语言教程数不胜数,同名如"C程序设计""C语言程序设计""C语言程序设计教程"的都多如牛毛,这些不知名的就不予考虑了,要看就 ...

最新文章

  1. Spring单实例、多线程安全、事务解析
  2. 这个AI模型用最少的训练数据学习对象之间的关系
  3. 常见的数据库端口及查询方法
  4. 2018年终总结(一只刚毕业的程序猿)
  5. c 连接mysql后 怎么用_使用C语言连接mysql,并进行操作
  6. 2013.09.14 不能继续,就应该趁早放弃
  7. 153. 寻找旋转排序数组中的最小值---LeetCode---JAVA
  8. algorithm -- 选择排序
  9. 乘方取模计算(模幂计算)
  10. 背景图页面缩小会变形_社团招新迎新海报背景图第321期
  11. python 多线程应用
  12. “这样使用RHEL合法吗”?
  13. Boltzmann 玻尔兹曼机(BM)
  14. 珍惜吧,这届世界杯之后,怕是再也看不到他们了
  15. RxJava学习总结
  16. 永远不要低估自己,love your fear.
  17. php优缺点ppt,ppt和pdf有什么区别
  18. DBSCAN 聚类算法
  19. 软考高级信息系统项目管理师经验分享
  20. android相关素材以及网站

热门文章

  1. No mapping for the Unicode charactor exists in the target multi-byte code page解决办法
  2. 鸿蒙操作系统系列——科普篇
  3. 举例说明层次分析的三大原则_LabVIEW面向对象编程_初窥门槛(2)_设计原则(SOLID)...
  4. Fedora27下载安装Opera浏览器和flash
  5. 01_云计算系统管理01
  6. 计算机三级信息安全技术名称的英文缩写(3)
  7. oracle create inital,ORA-01658 unable to create initial extent for segment in tablespace
  8. 【转】十大数据挖掘算法
  9. 前同事接私活年入百万,都是用这几个开源的SpringBoot项目(含小程序)改的...
  10. PyG搭建R-GCN实现链接预测