3.2 算术运算符和算术表达式
考点4 基本的算术运算符
真考链接
考点4是构成算法的基本元素,该知识点在选择题中为常考点。在选择题中将以判断表达式是否正确的形式考查。在操作题中就涉及应用这些基本的运算符去实现程序的特定算法和功能。
C语言的基本算术运算符有+(加法运算符或正值运算符)、-(减法运算符或负值运算符)、*(乘)、/(除)和%(求余)。其中作为正值运算符和负值运算符的“+”和“-”是单目运算符。算术运算符除了“%”以外,运算对象都可以是整型或者实型。“%”运算的两端必须都是整型,运算结果是两个整数相除后的余数,如“5%3”这个表达式的值就是2。
注意:(1)当运算对象是负数时,不同机器的运算结果也可能是不同的,在TURBOC中,规定符号与被除数相同。
(2)双目运算符两边的数值类型必须一致才能进行运算,所得结果也是相同类型的数值。
(3)双目运算符两边的数值类型如果不一致,必须由系统先进行一致性转换。例如,一边是整数,另一边是实数,C语言系统将首先把整数类型转换成实数类型,再进行运算,结果也是实数类型。
(4)C语言规定,所有实数的运算都是以双精度方式进行的,若是单精度数值,则需要在尾数后面补0,转换为双精度数才能进行运算。
真题精选
【例1】设变量已正确定义并赋值,以下正确的表达式是( )。
A.x=y*5=x+z B.int(15.8%5) C.x=y+z+5,++y D.x=25%5.0
【答案】 C
【解析】求余运算符“%”两边的运算对象必须是整型,而选项B、D中“%”两边的运算对象有浮点整型数据,所以选项B、D是错误的表达式。在选项A中赋值表达式的两边出现相同的变量“x”,也是错误的。选项C是一个逗号表达式,所以正确的答案为C。
【例2】下列给定程序中函数fun()的功能是:求两个非零正整数的最大公约数,并作为函数值返回。
例如,若num1和num2分别为49和21,则输出的最大公约数为7;若num1和num2分别为27和81,则输出的最大公约数为27。请改正程序中的错误,使它能得出正确结果。
注意:不要改动main()函数,不得增行或删行,也不得更改程序的结构。
试题程序
#include <stdio.h>
int fun(int a,int b)
{ int r,t;
if(a<b)
/*****found*****/
{t=a;b=a;a=t;}
r=a% b;
while(r!=0)
{a=b;b=r;r=a% b;}
/*****found*****/
return(a);
}
void main()
{ int num1,num2,a;
printf("Input num1 num2:");
scanf("% d% d",&num1,&num2);
printf("num1 =% d num2 =% d \n \n",
num1,num2);
a=fun(num1,num2);
printf("The maximun common divisor is
%d\n\n",a);
}
【答案】(1){t=a;a=b;b=t;}
(2)return(b);或return b;
【解析】本题考查:return语句,功能是计算表达式的值,并将其返回给主调函数。
求最大公约数算法一般采用辗转相除法。辗转相除法的算法为:首先将 m除以 n(m>n)得余数 r,再用余数r去除原来的除数,得到新的余数,重复此过程直到余数为0时停止,此时的除数就是m和 n的最大公约数。
程序首先判断参数a和b的大小,如果a<b则进行交换,这里是一个数学逻辑错误,应先将a的值赋给中间变量t,再将b的值赋给a,最后将t的值赋给b。当余数r为0时,除数b即为所求的最大公约数,所以函数应返回b。
考点5 算术表达式和运算符的优先级与结合性
真考链接
考点5难度适中,属需重点掌握重点理解的知识点。由于优先级的不同,在结合多个运算符的表达式时要尤其注意。此知识点在选择题和操作题中均为常考考点。
算术表达式是用算术运算符和括号将运算量(也称操作数)连接起来的、符合C语言语法规则的表达式。运算对象包括函数、常量和变量等。
在计算机语言中,算术表达式的求值规律与数学中四则运算的规律类似,其运算规则和要求如下。
(1)在算术表达式中,可使用多层圆括号,但括号必须配对。运算时从内层圆括号开始,由内向外依次计算各表达式的值。
(2)在算术表达式中,对于不同优先级的运算符,可按运算符的优先级由高到低进行运算,若表达式中运算符的优先级相同,则按运算符的结合方向进行运算。
(3)如果一个运算符两侧的操作数类型不同,则先利用自动转换或强制类型转换,使两者具有相同数据类型,然后再进行运算。
真题精选
【例1】现有定义inta;doubleb;floatc;chark;,则表达式a/b+c-k的值的类型为( )。
A.int B.double C.float D.char
【答案】 B
【解析】双目运算中两边运算量类型转换规则。
在a/b的时候,a、b的类型不一致,根据类型转换规则,要把整型转换成double类型,之后的加、减类似。转换规则为char,short→int→unsigned→long→double→float。
【例2】下列给定的程序中,函数fun()的功能是:计算并输出k以内最大的10个能被13或17整除的自然数之和。k的值由主函数传入,若k的值为500,则函数的值为4622。
请改正程序中的错误,使它能得出正确的结果。
注意:不要改动main()函数,不得增行或删行,也不得更改程序的结构。
试题程序
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int fun(int k)
{ int m=0,mc=0,j;
while((k> =2)&&(mc<10))
{ /*****found*****/
if((k% 13=0)||(k% 17=0))
{m=m+k;mc++;}
k--;
/*****found*****/
return m;
}
void main()
{ printf("% d\n ",fun(500));
}
【答案】(1)if((k%13==0)||(k%17==0))
(2)程序最后加花括号“}”
【解析】本题考查:if语句条件表达式,区分逻辑表达式和算术表达式;同时注意C语言书写程序应遵守的规则。
(1)C语言中“=”是赋值运算符,“==”才表示等于,x能被y整除的表示方法是x%y==0,而并非像题目中所表示的x%y=0。所以,if((k%13=0)||(k%17=0))修改后的结果应该是答案所示信息。
(2)程序中缺少“}”花括号,程序不完整。此类信息在做题时一定要注意,可以在做题前先运行一下程序,这样明显的错误一般都会有错误信息显示出来,比如丢失“}”的错误信息是“Compound statementmissing} in function fun”。
考点6 自加、自减运算符
真考链接
考点6难度适中,为重点掌握重点理解知识点。由于其在运算符表达式中的使用便利,经常会使用到自加、自减运算符。尤其是在for语句中。此知识点在选择题中为必考点。在操作题中,此知识点的考核概率为25%。
(1)自加运算符“++”和自减运算符“--”的作用是使运算变量的值增1或减1。
(2)自加、自减运算符是单目运算符。其运算对象可以是整型或实型变量,但不能是常量和表达式,因为不能给常量或者表达式赋值。
(3)自加、自减运算符可以作为前缀运算符,也可以作为后缀运算符构成一个表达式,如++i、--i、i++、i--等都是合法的表达式。
无论是前缀还是后缀运算符,一定会有i的值加1或者减1这一步。
前缀和后缀运算符,作为表达式来说有不同的作用。
++i,--i:在使用i之前,先使i的值加1或者减1,再使用此时的表达式的值参加运算。
i++,i--:在使用i之后,使i的值加1或者减1,再使用此时的表达式的值参加运算。
(4)自加、自减运算符的结合方向是“自右向左”。
针对“-i++”进行分析,i的左边是负号运算符,右边是自加运算符,负号运算和自加运算的优先级是相同的,而且都是“自右向左”结合的,所以此表达式相当于 -(i++)。
例如,当i的初值为2时,求“-i++”这个表达式和i的值分别是多少。
根据分析可以知道,此时相当于“-(i++)”,即先使用i的原值参与负值运算,得到整个表达式的值为-2,然后对i的值进行加1,得到i的值为3。
(5)不要在一个表达式中对同一变量进行多次自加或者自减运算。这种表达式不仅可读性很差,而且不同的编译系统对它的运算结果也不同,很容易出现错误。
小提示
“++、--”与i的相对位置不同其运行结果也不同。i在后面,则i应先进行自加或自减运算,否则先不进行自加或自减运算。
真题精选
【例1】设有定义:intk=0;,以下选项的4个表达式中与其他3个表达式的值不相同的是( )。
A.k++ B.k+=1 C.++k D.k+1
【答案】 D
【解析】选项A、B、C都使k的值增加1,D选项不改变k的值。本题答案为D。
【例2】以下关于单目运算符++、--的叙述中正确的是( )。
A.它们的运算对象可以是任何变量和常量
B.它们的运算对象可以是char型变量和int型变量,但不能是float型变量
C.它们的运算对象可以是int型变量,但不能是double型变量和float型变量
D.它们的运算对象可以是char型变量、int型变量和float型变量
【答案】 D
【解析】“++”和“--”运算符都是单目运算符,其运算对象可以是整型变量,也可以是实型变量,但不能是常量或表达式。当运算对象是字符型时,系统自动将其转换成该字符所对应的ASCII码值。
【例3】以下选项中,与k=n++完全等价的表达式是( )。
A.k=n,n=n+1 B.n=n+1,k=n C.k=++n D.k+=n+1
【答案】 A
【解析】题中的表达式是先让n参与赋值运算,然后再对本身进行自加,所以选A。
【例4】以下非法的赋值语句是( )。
A.n=(i=2,++i); B.j++; C.++(i+1); D.x=j>0;
【答案】 C
【解析】自加或自减运算的操作数不能是表达式。
【例5】以下程序的输出结果为( )。
#include <stdio.h>
main()
{ int i=4,a;
a=i++;
printf("a=% d,i=% d ",a,i);
}
A.a=4,i=4 B.a=5,i=4 C.a=4,i=5 D.a=5,i=5
【答案】 C
【解析】本题考查的是自增运算符及赋值运算符的综合使用问题。自增运算符是一元运算符,其优先级比赋值运算符高,要先计算。把表达式i++的值赋予a,由于i++的结果为当前i的值(当前i的值为4),所以i++的值为4,得到a的值为4。同时,计算了i++后,i由4变为5。
【例6】下列给定程序中函数fun()的功能是:将p所指字符串中的所有字符复制到b中,要求每复制3个字符之后插入一个空格。
例如,若给a输入字符串:ABCDEFGHIJK,调用函数后,字符数组b中的内容为:ABC DEF GHI JK。请改正程序中的错误,使它能得出正确结果。
注意:不要改动main()函数,不得增行或删行,也不得更改程序的结构。
试题程序
#include <stdio.h>
void fun(char *p,char *b)
{ int i,k=0; while(*p)
{ i=1;
while(i< =3 && *p){
/*****found*****/
b[k] =p;
k++;p++;i++;
}
if(*p)
{ /*****found*****/
b[k++] ="";
}
}
b[k] = '\0';
}
main()
{ char a[80],b[80];
printf(" Enter a string:");gets(a);
printf("The original string:");puts(a);
fun(a,b);
printf("\nThe string after insert space:");
puts(b);printf("\n\n");
}
【答案】(1)b[k] =*p;
(2)b[k++] =' ';
【解析】本题考查:指针类型变量作为函数的参数,函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。
(1)题目中p是指针型变量作函数参数,因此给b[k]赋值时出现错误。
(2)题目要求复制3个字符后加一个空格,所以应该是先给b[k]赋值空格,然后变量k再加1。
常见问题
++i和i++在运算中有何区别?
++i在程序运行过程中,i的值先自行加1,而i++在程序运行过程中,第一次使用i的初值,后面用到i时再根据需要进行自加运算。