第六 运算符、表达式和语句

C语言学习栏目目录

目录

1、赋值运算符:=

2、加法运算符:+

3、减法运算符:-

4、符号运算符:-和+

5、乘法运算符:*

6、除法运算符:/


C用运算符(operator)表示算术运算。例如,+运算符使在它两侧的值加在一起。如果你觉得术语“运算符”很奇怪,那么请记住东西总得有个名称。与其叫“那些东西”或“运算处理符”,还不如叫“运算符”。现在,我们介绍一下用于基本算术运算的运算符:=、+、-、*和/(C  没有指数运算符。不过,C 的标准数学库提供了一个pow()函数用于指数运算。例如,pow(3.5,2.2)返回3.5的2.2次幂)。

1、赋值运算符:=

在C语言中,=并不意味着“相等”,而是一个赋值运算符。下面的赋值表达式语句:

Year = 2020;

把值2002赋给变量Year。也就是说,=号左侧是一个变量名,右侧是赋给该变量的值。符号=被称为赋值运算符。另外,上面的语句不读作“Year等于2020”,而读作“把值2020赋给变量Year”。赋值行为从右往左进行。也许变量名和变量值的区别看上去微乎其微,但是,考虑下面这条常用的语句:

i = i + 1;

对数学而言,这完全行不通。如果给一个有限的数加上  1,它不可能“等于”原来的数。但是,在计算机赋值表达式语句中,这很合理。该语句的意思是:找出变量 i 的值,把该值加 1,然后把新值赋值变量i(见下图)。

在C语言中,类似这样的语句没有意义(实际上是无效的):

2020 = Year;

因为在这种情况下,2002 被称为右值(rvale),只能是字面常量。不能给常量赋值,常量本身就是它的值。因此,在编写代码时要记住,=号左侧的项必须是一个变量名。实际上,赋值运算符左侧必须引用一个存储位置。最简单的方法就是使用变量名。不过,后面章节还会介绍“指针”,可用于指向一个存储位置。概括地说,C 使用可修改的左值(modifiable lvalue)标记那些可赋值的实体。也许“可修改的左值”不太好懂,我们再来看一些定义。

几个术语:数据对象、左值、右值和运算符

赋值表达式语句的目的是把值储存到内存位置上。用于储存值的数据存储区域统称为数据对象(data object)。C 标准只有在提到这个概念时才会用到对象这个术语。使用变量名是标识对象的一种方法。除此之外,还有其他方法,但是要在后面的章节中才学到。例如,可以指定数组的元素、结构的成员,或者使用指针表达式(指针中储存的是它所指向对象的地址)。左值(lvalue)是 C 语言的术语,用于标识特定数据对象的名称或表达式。因此,对象指的是实际的数据存储,而左值是用于标识或定位存储位置的标签。右值(rvalue)指的是能赋值给可修改左值的量,且本身不是左值。例如,考虑下面的语句:

Year = 2020;

这里,bmw是可修改的左值,2002是右值。

右值可以是常量、变量或其他可求值的表达式(如,函数调用)。实际上,当前标准在描述这一概念时使用的是表达式的值(value  of an expression),而不是右值。我们看几个简单的示例:

int ex;
int why;
int zee;
const int TWO = 2;
why = 42;
zee = why;
ex = TWO * (why + zee);

这里,ex、why和zee都是可修改的左值(或对象定位值),它们可用于赋值运算符的左侧和右侧。TWO是不可改变的左值,它只能用于赋值运算符的右侧(在该例中,TWO被初始化为2,这里的=运算符表示初始化而不是赋值,因此并未违反规则)。同时,42 是右值,它不能引用某指定内存位置。另外,why和 zee 是可修改的左值,表达式(why + zee)是右值,该表达式不能表示特定内存位置,而且也不能给它赋值。它只是程序计算的一个临时值,在计算完毕后便会被丢弃。

在学习名称时,被称为“项”(如,赋值运算符左侧的项)的就是运算对象(operand)。运算对象是运算符操作的对象。例如,可以把吃汉堡描述为:“吃”运算符操作“汉堡”运算对象。类似地可以说,=运算符的左侧运算对象应该是可修改的左值。

 

2、加法运算符:+

加法运算符(addition operator)用于加法运算,使其两侧的值相加。例如,语句:

printf("%d", 4 + 20);

打印的是24,而不是表达式

4 + 20

相加的值(运算对象)可以是变量,也可以是常量。因此,执行下面的语句:

c = a+b;

计算机会查看加法运算符右侧的两个变量,把它们相加,然后把和赋给变量c。在此提大家注意,a、b和c都是可修改的左值。因为每个变量都标识了一个可被赋值的数据对象。但是,表达式a+ b是一个右值。

 

3、减法运算符:-

减法运算符(subtraction operator)用于减法运算,使其左侧的数减去右侧的数。例如,下面的语句把200.0赋给Number:

Number= 224.00 – 24.00;

+和-运算符都被称为二元运算符(binary operator),即这些运算符需要两个运算对象才能完成操作。

 

4、符号运算符:-和+

减号还可用于标明或改变一个值的代数符号。例如,执行下面的语句后,a的值为12:

b = –12;

a=  –b;

以这种方式使用的负号被称为一元运算符(unaryoperator)。一元运算符只需要一个运算对象(见下图)。

 

5、乘法运算符:*

符号*表示乘法。下面的语句用2.54乘以inch,并将结果赋给cm:

cm = 2.54 * inch;

C没有平方函数,如果要打印一个平方表,怎么办?如程序清单所示,可以使用乘法来计算平方。

/************************************************************************
功能:演示乘法运算,计算1~20的平方                                                                   
************************************************************************/
#include<stdio.h>
int main(void)
{
	int num = 1;
	while(num<21)
	{
		printf("%4d %6d\n", num, num * num);
		num = num + 1;
	}
	system("pause");
	return 0;
}

该程序打印数字1~20及其平方。接下来,我们再看一个更有趣的例子。

指数增长

大家可能听过这样一个故事,一位强大的统治者想奖励做出突出贡献的学者。他问这位学者想要什么,学者指着棋盘说,在第1个方格里放1粒小麦、第2个方格里放2粒小麦、第3个方格里放4粒小麦,第4个方格里放 8 粒小麦,以此类推。这位统治者不熟悉数学,很惊讶学者竟然提出如此谦虚的要求。因为他原本准备奖励给学者一大笔财产。如果下程序清单运行的结果正确,这显然是跟统治者开了一个玩笑。程序计算出每个方格应放多少小麦,并计算了总数。可能大多数人对小麦的产量不熟悉,该程序以谷粒数为单位,把计算的小麦总数与粗略估计的世界小麦年产量进行了比较。

/************************************************************************
功能:演示乘法运算,指数增长
************************************************************************/
#include<stdio.h>
int main(void)
{
	int SQUARES = 64;				// 棋盘中的方格数
	const double CROP = 2E16;	// 世界小麦年产谷粒数
	double current,total;
	int count = 1;
	printf("square   grains    total   ");
	printf("fraction of \n");
	printf("       added     grains  ");
	printf("world total\n");
	total = current = 1.0;			//从1颗谷粒开始
	printf("%4d %13.2e %12.2e %12.2e\n", count, current,total, total/CROP);

	while(count<SQUARES)
	{
		count = count + 1;
		current = 2.0 * current;	//下一个方格谷粒翻倍 
		total = total + current;	//更新总数 
		printf("%4d %13.2e %12.2e %12.2e\n", count, current, total, total/CROP);
	}
	printf("That's all.\n");
	system("pause");
	return 0;
}

程序的输出结果如下:

square   grains    total   fraction of 
       added     grains  world total
   1      1.00e+00     1.00e+00     5.00e-17
   2      2.00e+00     3.00e+00     1.50e-16
   3      4.00e+00     7.00e+00     3.50e-16
   4      8.00e+00     1.50e+01     7.50e-16
   5      1.60e+01     3.10e+01     1.55e-15
   6      3.20e+01     6.30e+01     3.15e-15
   7      6.40e+01     1.27e+02     6.35e-15
   8      1.28e+02     2.55e+02     1.27e-14
   9      2.56e+02     5.11e+02     2.55e-14
  10      5.12e+02     1.02e+03     5.12e-14
  //省略
  55      1.80e+16     3.60e+16     1.80e+00
  //省略
  64      9.22e+18     1.84e+19     9.22e+02
That's all.
请按任意键继续. . .

10个方格以后,该学者得到的小麦仅超过了1000粒。但是,看看55个方格的小麦数是多少,总量已超过了世界年产量!不妨自己动手运行该程序,看看第64个方格有多少小麦。

这个程序示例演示了指数增长的现象。世界人口增长和我们使用的能源都遵循相同的模式。

 

6、除法运算符:/

C使用符号/来表示除法。/左侧的值是被除数,右侧的值是除数。例如,下面four的值是4.0:

four = 12.0/3.0;

整数除法和浮点数除法不同。浮点数除法的结果是浮点数,而整数除法的结果是整数。整数是没有小数部分的数。这使得5除以3很让人头痛,因为实际结果有小数部分。在C语言中,整数除法结果的小数部分被丢弃,这一过程被称为截断(truncation)。运行下程序清单中的程序,看看截断的情况,体会整数除法和浮点数除法的区别。

/************************************************************************
功能:演示除法                                                                      
************************************************************************/
#include<stdio.h>
int main(void)
{
	printf("integer division: 5/4  is %d \n", 5 / 4);
	printf("integer division: 6/3  is %d \n", 6 / 3);
	printf("integer division: 7/4  is %d \n", 7 / 4);
	printf("floating division: 7./4. is %1.2f \n", 7. / 4.);
	printf("mixed division:  7./4 is %1.2f \n", 7. / 4);
	system("pause");
	return 0;
}

程序清单中包含一个“混合类型”的示例,即浮点值除以整型值。C相对其他一些语言而言,在类型管理上比较宽容。尽管如此,一般情况下还是要避免使用混合类型。该程序的输出如下:

integer division: 5/4  is 1 
integer division: 6/3  is 2 
integer division: 7/4  is 1 
floating division: 7./4. is 1.75 
mixed division:  7./4 is 1.75 
请按任意键继续. . .

注意,整数除法会截断计算结果的小数部分(丢弃整个小数部分),不会四舍五入结果。混合整数和浮点数计算的结果是浮点数。实际上,计算机不能真正用浮点数除以整数,编译器会把两个运算对象转换成相同的类型。本例中,在进行除法运算前,整数会被转换成浮点数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值