函数调用符、聚合访问符、单目操作符综合学习

函数调用符、聚合访问符、单目操作符综合学习

1.简介:
     操作符的学习是我们日常学习C语言时遇见的第一个重点内容,在很多书中,操作符的学习章节在书的前半部分就完成了,讲的比较抽象,一般我们能学到聚组符,算术运算符,比较运算符,赋值运算符,如果认真的学习,还可能会学习到 &&, ||, ?: , 这四个控制操作符,不然的话,只有在 % 符号上找成就感了,因为剩下的符号的运用都将集中在本章后。所以这些知识必须在学完指针、数组、函数、结构后,再次学习。
     那么抛开前面说的聚组,算术运算符,比较运算符,赋值运算符,控制操作符,还剩下函数调用符,聚合访问符,单目操作符,位运算(也是算术运算符)。而这几天我就参考《C与指针》这本书综合学习了它们。

2.操作符:
    1. 聚组                    ( expression  )
    2. 函数调用            ( option_list )
    3. 聚合数据访问    []    .      ->
    4. 单目操作符        (右)++      (右)--  
                                      !   ~   +   -   *   ++(左)  --(左)   &   sizeof  (类型)
          上表从上到下, 优先级由高至低。
          第  1,2,3,4  行, 结合性由左向右。
          第      5       行,  结合性由右向左。

3. 预备知识:
    1> 源代码的组成:    由标识符、32个关键字、28个符号、字面值常量和若干个空白符组成的文本文件。
    2> 什么是标识符:    变量,函数,类型的名称。
    3> 什么是声明标识符:声明就是告诉编译器,此标识符是什么类型,占多大内存空间。
    4> 什么是定义标识符:定义就是让系统为该标识符分配合理的内存空间。
    总结: 1>定义标识符的同时也会产生一份该标识符的声明。
                 2>对于已定义的静态标识符,可以在多处进行重声明。    
                 3>对于已定义的动态标识符,其声明仅在定义时完成,不能重声明。
                 4>在代码中,调用标识符的位置前,必需得有它的声明。

4. 标识符的声明:
   理解: 声明一个标识符并不是我们所想的那样直观----告诉编译器将一个标识符声明成某种类型。
              而是用该标识符与多个符号和类型关键字组合成一条语句,编译器阅读该语句后推测出标识符的类型。

   说明: 标识符的声明其实就是聚组符,函数调用符,聚合数据访问符,单目运算符的综合运用。
 
   例:  1> int a;
           标识符 a 是int类型数据。

         1> int *a,
           对标识符 a 间接访问后是一个int类型数据。
           a是指向int的指针。
          
        2> int a[20],
           对标识符 a 的第20个元素下标访问,得到是int型数据。
           a是指向整型的指针常量。
           定义时分配20个int型内存空间,a初始化为该空间首数据地址

        3> char *str[15] ,
           对标识符 str 的第15个元素下标访问后再间接访问,得到一个char型数据。
           str是指向字符指针的指针常量。
           定义时连续分配了15个字符指针类型内存空间,str初始化为该空间首数据地址。

        4> char (*str)[15],
           对str间接访问后,再对第15个元素下标访问,得到一个char型数据。
           str是一个指针,指向的是一个长度为15的字符数组。
           定义时分配了1个指向长度为15个字符数组的指针空间。

        5> char **str,
           对str间接访问两次后,得到一个char型数据。
           str是指向字符指针的指针变量。
           定义时分配1个指向字符指针的指针类型空间。

        6> double (*oper_func[5])( double, double );
           对oper_func的第5个元素下标访问后再间接访问是一个必须接收两个double形参数且返回double型数据的函数
           oper_func是指向函数指针的指针常量。
           定义时分配了5个指向函数的指针空间,oper_func初始化为该空间的首数据地址。

        7> int *func( void *value );
           调用func函数接收一个指针形参,对返回值间接访问得到一个int型数据
           func是一个函数名,返回值是整型的指针
                 
        8> int *(*cmp)( void *a1, void *a2 );
           对cmp间接访问,函数接收两个指针形参,对返回值间接访问得到一个int型数据
           cmp就是一个指向函数的指针,返回值是整型指针。

5. 指针的移动:

   说明: 遍历数组型数据结构时,会综合运用了三个单目操作符( * ++ --)。
              当遇见 ++ -- 时,表答式中运用的都是其所操作数据的一份拷贝。
        
   例:  1> *spt++
                获得一份spt的拷贝,spt指向下一个数据, 间接访问拷贝的spt指针。

           2> *++spt
                spt指向下一个数据,获得一份spt的拷贝,间接访问spt指针。

           3> ++*spt
                间接访问spt指针,将访问到的数据加1并获得一份该数据的拷贝。

           4> (*spt)++
               间接访问spt指针并获得一分该数据的拷贝,将访问到的数据加1。

           5> --*spt++
               获得一份spt的拷贝,spt指向下一个数据,间接访问拷贝的spt指针,将访问至的数据减1并获得一份该数据的拷贝。

6.其它综合运用:
   说明: 这个版块主要是为了证明单目运算符的结合性是从右到左的。

   例:  1>  int a, b, *&c;
                 a = *&b;
                 先对 c 取地址,再对该地址间接访问,得到一个整型数据。
                 那么 c 就是一个整型数据。

          2>  int a = 10, b, c ;
                 b = ~a--;
                 c = ~--a;
                首先得说明书上的一点问题:
                书中将 ~ 符号称之求补符号,但是它的过程是求反码,因为补码等于反码加 1 。a = 0XA, ~a = 0XFFFFFFF5, 当我们以十进制打印出~a时,因为a 是有符整型值,故要经过取返、加1、添负号这个过程,所以值为-11。

                  b = ~a--;  取到一份 a 的数据拷贝; 将 a 的值减1; 对拷贝取反并赋与 b。
                  c = ~--a;  把a的值减1;取到一份a的数据拷贝;对拷贝取反并赋与c。
                  注: b = 0XFFFFFFF5 = -11,  c = 0XFFFFFFF7 = -9 ( 这里考虑了--的负作用 )

            3> int a, b, c = 5;
                  a = - --c; 把c的值减 1,取到一份 c 的拷贝,对该拷贝求负并赋与a。
                  b = -c--;  取到一份 c 的拷贝,把 c 的值减1,对拷贝求负并赋值与b。
                  -- -c 与 (-c)--是非法的,因为 ++ 与-- 的操作数必须是一个左值。

你可能感兴趣的:(C语言)