关于自增自减:C、C++自增自减运算符的研究

版权声明:转载时请以超连接形式标明文章原始出处和做者信息及本声明http://imlsb.blogbus.com/logs/97126472.html
html

摘要: 从自增自减运算符的概念出发, 分析了C++与 C 语言中自增自减运算符在循环结构和指针运算中的应用方法,详细概括了 + + / - - 运算符在解题过程当中应注意的多个方面的事项 , 并分析C++与C在处理自增自减运算构成的复杂算术表达式的区别。是对教材的一个很是有益的补充 ,可用于语言教学的参考 ,也有助于初学者的自学。数组

关键词:C,C++,自增运算符,自减运算符函数

1、自增自减运算符的概念学习

C 语言程序设计 过 程中 , 我 们 经 常 用 到 x=x+1 ,x=x-1这 样 的赋值表达式, 用更简洁的方式表示x=x+1 可表示为: x + + 或 + + x,x=x- 1 可表示为: x - - 或 - - x,“++” - - ”称为自增、自减运算符。它们是单目运算符, 只能应用于变量, 而不能用于常量或表达式。结合性与简单赋值运算符相同,但优先级高于任何双目运算符。spa

    自增自减运算符有两种使用形式: 前缀形式, 即它们在操做数前,如 ++x、 - x; 后缀形式, 即它们在操做数后, 如 x++、- 。++-x-表达式与 - - 表达式独立使用时,前缀形式与后缀形式无区别, 但它们在表达式中被引用时, 结果是不一样的。前缀形式是先增 减)(1, 后被引用; 后缀形式是先被引用, 后增 减) 1。例如, 若是变量 x的原值等于 3, 则执行下面的赋值语句:设计

  ①y=++x; ( x 的值先变成 4, 再将 x 的值赋给 y, y 的值为 4)指针

  ②y=x++; ( 先 将 x 的 值 3 赋 给 y, y 的 值 为 3, 然 后 x 的 值 变为 4)htm

2、学习和应用这两个运算符应注意如下几点 :对象

1 注意表达式的值和变量值的区别blog

    以自增运算符为例 ,当自增运算符 + + 做用于一个变量时 ,例如 :当 i = 3 时 + + i 这个算术表达式的值为 4 ,同时变量 i 的值也由原来的 3 改变为 4 。通常状况下 ,计算表达式后不改变之量的值 ,而 + + 运算符和运算符组成的表达式计算后 ,则改变之量的值 ,这称为运算符的反作用 ,这种运算符在计算表达式时 ,必定要注意区分表达式的值和变量的值。

2 注意前缀运算和后缀运算的区别

    仍以自增运算符为例 ,该运算符可做用在变量以前 ,例如 ,前面所讲的 + + i ,称为前缀运算 ;也可做用在变量以后 ,例如 ,i + + 称为后缀运算 ,在这两种运算中 ,表达式的值不一样 ;前缀运算后 ,表达式的值为原变量的值加 I ;后缀运算后 ,表达式的值仍为原变量值 ;而变量不论前缀运算仍是后缀运算都加 1 。自减运算符与自增运算符相似 ,即前缀运算是“先变后用”,然后缀运算是“先用后变”。

3 注意运算符的运算对象

     自增、自减运算符能做用于变量 , 而不能做用于常量或表达式。由于自增、自减运算符具备对运算量从新赋值的功能 , 而常量、表达式无存储单元可言。固然不能作自增、自减运算 , 只要是标准类型的变动 , 无论是整型、实型 , 仍是字符型、枚举型均可以做为这两个运算符的运算对象。如 i + + +j + + 、+ + i + ( + + j ) 、 + + a + b ++ 、+ + array [ - j ] 合法 ; 而 + + 五、 ( i + j ) + + 、’A’+ + 、+ + i + + +j 都是不合法的。为何 i + + +j + +合法 , 而 + + i + + +j 却不合法呢 ? 这是由于 C 语言的编译器对程序编译时 , 从左到右尽量多地将字符组成一个运算符或标识符 , 所以 i + + +j + + 等效于 (i + + ) + (j+ + ) , 两个 “+ + ”做用的对象都是变量 , 这是合法的 ;而 + + i + + +j 等效于 + + ( i + + ) + j , 第 1 个 “ + + ”做用的对象是表达式 “i + + ” 这是不容许的。,

四、 注意运算符的结合方向

表达式 k = - i + +等效于 k = ( - i) + + 不是 K = - ( i+ + ) ? 由于负号运算符和自增运算符的优先级相同 ,哪个正确就得看结合方向。自增、自减运算符的结合方向都是从右向左 ,所以 ,上式等效于 k = - ( i + + ) 若 i = 4 则表达式 k = - i + +运算后 k 的值为 - 4 ,i 为 5 。

5 注意运算符的反作用

     C 语言容许在一个表达式中使用一个以上的赋值类运算 ,包括赋值运算符 、自增运算符、自减运算符等 ,这种灵活性使程序简洁 ,但同时也会引发反作用 。这种反作用主要表如今 :使程序费解 ,并易于发生误解或错误 。例如 ,当 i =3 时 ,表达式 (i + + ) + ( i + + ) + ( i + + ) 的值为多少 ,各类教材说法不统一 :有的认为是 9 ;也有人认为是 12 。到底哪种说法正确呢 ? 请看下面这个程序的运行状况 :

       main ()

       {

       int i , j ;

       i = 3 ,j = (i + + ) + (i + + ) ;

       printf ( \ nj = %d” ) ;“,j

       i=3

       printf ( j = %d” (i + + ) + i ( + + ) + (i + + ) ) ;“,

       }

以上运行 ,其结果则是 :j = 9 ,j = 12 ,究其缘由“先用后变 ,先变后用” “先” “后”中的和是一个模糊的概念 ,很难给出顺序或时间上的准肯定论 “先”,到何时 “后”,到什么程度 ,没有此方面的详细资料可查询 。克服这类反作用的方法是 ,尽可能把程序写得易懂一些 ,将费解处分解成若干个语句 ,如 : k = i + + +j ,可写成 k = i+ j ,i + +而相似 (i + + ) + i ( + + ) + (i + + ) 这类连续自增、自减的运算最好不要使用 ,以减小程序出错的可能性 。在程序设计中 ,效率和易读性是一对主要矛盾 。

3、在实例应用中的分析

在赋值语句中的应用

在使用自增自减运算时常会出现一些人们想不到的反作用,在不一样的例子中应用有所不一样,下面咱们就结合不一样的例子对其加以分析。

例:main()

{  int a=-1,b=1,k;

   If((++a)<0)&&(--b<=0))

   printf(“%d,%d\n”,b,a);

    else printf(“%d,%d\n”,b,a);

}

运行结果为:1,0

++,--运算符出如今条件表达式中,对于条件表达式(++a<0)&&!(b--<=0)进行运算,由于a=a+1=-1+1=0,因此(++a<0)为假,并且C语言规定:在一个“&&”表达式中,若“&&”的一端为0,则没必要再计算另外一端,该表达式的值为0,因此此时再也不执行语句—b,即b的值为1.

例:有如下程序段

J=-i++;printf(“%d,%d\n”,I,j);

运行结果为:3,-2

在C语言中,“++,--”运算符与“-”的优先级相同,结合方向从右至左,因此表达式-i++ 至关于-(i++),计算顺序是先计算表达式i++,表达式取i的为2,而后变量i增1;2再作取负值运算,表达式-i++的值为-2;再将-2赋给变量j。

自增自减运算符在循环结构中的应用

为了充分发挥计算机在程序控制下进行自动计算的功能和运算速度快的特色, 在程序设计过程当中力求把复杂问题的求解转化为简单过程的重复。为此,在多数计算机程序设计语言中, 都提供有循环结构。C++与C 语 言 提 供 有 3 种循环结构 : for 结 构 、while 结 构 和 do…while 结构。

    在 while 结构和 do… while 结构中, 其循环 体 中 应 有 使 循 环趋向于结束的语句。而这样的语句通常用赋值语句。

例如:用表达式“i++” “i- - ”或。其中 i 称 为 循环 变 量 , 在 循 环 结 构 中 只 有 改 变循环变量的值, 这样在循环体执行若干次以后, 才能使循环条件不知足, 结束循环。若是无此语句, 则 i 的值始终不 变 , 程 序 陷入死循环。

    在 for 结构中, for 语句最简单的应用形式也可 理 解 为 如 下 形式:(for 循环变量赋初值; 循环条件; 循环变量增值)语句其中循环变量增值语句通常应用包含自增自减)运算符的表达式来实现。使用原理同 while 结构和 do… while 结构。

    例如: for (i=1; i<=100; i++) sum+=i;该语句能完成 1+2+3+……+100 的功能。(固然在循环结构中使用自增 自减) 运算符 ,只有在长增或1的状况下使用,在其它状况下,还应使用赋值表达式来完成改变循环变量值的功能。

自增自减运算符在指针中的应用

在 C 程序 中 , 定 义 一个 变 量 , 就 意 味 着 在 计 算 机 内 存中 给 这个变量分配必定的存储空间。使用 Turbo C 系统时计算机内存为整型变量分配 1 个字节, 对单精度型变量分配 4 个字节, 为双精度变量分配 8 上字节, 为字符型变量分配 1 个字节。内存区的每个存储单元 1 字节) 都有一个固定的编号, 这 个 编 号 就 称 为 地(址。如图 1 所示, 假设定义变量 p 和 a, 则在内存中分别为两个变量分配存储单元,其存储单元的首地址分别是 3420 和 2000。为了方便对存储单元进行控制, 咱们能够设置某些变量专门存放指针, 这样的变量称 为 指 针 变 量 。 图 1 中 的 变 量 p 存 放 了变 量 a 的 地 址 2000, 所以, p 就是指向 a 的指针变量。

    在 C 语言 中 , 指针使用很是灵活 , 指 针 既 可 指 向 各 种 类 型 的函数和文件。指针指向必定的数据对象时 ,变量, 也可指向数组、便可下移指向下一对象, 又可上移指向上一对象, 这就用到自增自减运算符来实 现 。 在 C语言中 , 指针变量引用时 ,一样要先定义, 后使用。若是定义指针变量 p 指向必定的数据类型, 则 p++ 指向内存中下一个元素 ( 而不是将值简单加 1) ,p- - 指向内 存 中 上一个元素 而不是将值简单减 1) 。 ( p-- ) 所表明的地址实际上(p++是 p+ 1×d (p- 1×d), d 是一个数据对象所占的 字 节 数 , 在C++与C 中, 对整数 d=2, 对单精度实数 d=4, 对字符型数 d=1。

    下面来看一个程序段:int a[6]={1,2,3,4,5,6},*p;p=a;

 “%d”printf(,*p++);

 “%d”printf(,(*p)++);

此程序段中 , 定义了一 个整型数组a, 包含有6个数组元素,而且该数组已初始化。同时定义指针变量 p, 将 a 数组的起始地址赋予指针变量 p, 也可认为指 针 p 指 向 a 数 组 。第一次调用 printf 函 数 输 出 *p++ 表 达 式 的 值 , 在 此 表 达 式 中 , *和 ++ 运算符的优先级相同,结合性为自右向左, 便可表示为 *(p++), 括号内为自增运算符的后缀形式, 即先引用 p, 而后 p 自身即先求 *p 的值, 而后求 p+1。第一次输出结果为 p 所指向的加 1。存储单元 a[0]的值 1, 然 后 指 针 变 量 p 指 向 下 一 个 数 组 元 素 a[1]。第二次调用 printf 函数输出表达式(*p)++ 的值, 在此表达式中, 括号的优先级高, 首先计算 *p 的值, 而后将 *p 表达式的值加 1。第二 次 输 出 结 果 为 p 所 指 向 的 存 储 单 元 a[1]的 值 再 加 1, 即 结 果为

在程序设计中 ,常常遇到 = i + 1” “i = i - 1”“i和这两种极为经常使用的操做 ,变量 i 被称为“计数器”,用来记录完成某一操做的次数。C 语言为这种计数器操做提供了两个更为简洁的运算符 ,即 + + 和 - - ,分别叫作自增运算符和自减运算符 ,它们是从右向左结合的一元算术运算符 ,优先级为2 。

4、在C和C++语言中,操做符存在着优先级与结合性,经过操做符的链接,能够构造出据用不一样复杂程度的表达式。一当表达式中有多个操做符时,优先级高的操做符先执行。二 操做符的结合性分为由左向右或由右向左两种,一元操做符,赋值及复合赋值操做符具备从右向左的结合性,其他操做符具备从左向右的结合性。若表达式中相邻的两个操做符优先级相同,先执行哪一个操做符,即与前一个操做符的结合性有关。三在处理含有前增1,前减1操做符的算术表达式时,前增1的过程在C++与C例处理方法略有不一样,C是一开始进行的,而C++是分布进行的。

综上所述,当“++”,“--”运算符所在的表达式或语句中只含右一种操做时(如++n;或n++;仅含有加1一种操做),则其前缀和后缀功能对程序的做用时同样的;而当含有两个或两个以上操做时,在考虑各个运算符的优先级别和结合性的基础上,则其前缀和后缀的功能对程序的做用时不同的。为了提升程序的效率 ,须要用技巧把程序写得尽量简洁一些 ,但这样有可能下降和谐的可能性和可理解性。可读性差的程序容易隐藏错误且难于纠正 ,不易维护 ,下降了程序的可靠性。人们在程序设计时遵照的基本规范是 :可靠性第一 ,效率第二。为了保证可靠性 ,程序必须清晰易读 ,而表达式的清晰易读是十分重要的 ,所以 ,在 C++与C 程序设计中 ,要慎重。