Object-C基础(5)——指针

来源:互联网 发布:软件架构 pdf 编辑:程序博客网 时间:2024/05/21 10:44

要接受的观点

    1.操作系统管理内存分配(有人来了,要分房间给它住)、内存回收(人走了,房间要收回来)的方式就是给内存编号。这个编号是二进制的编号,而且与操作系统位数相关。

    2.  所有变量运行时都要保存在内存中,程序有两种方式来访问变量:

       - 直接访问方式:根据变量对变量赋值或读取变量。

       - 间接访问方式:每个变量都需要保存在内存中,因此它所在的首内存就有一个内存编号,此时也可通过该内存编号来访问变量。

    3.内存编号 = 内存地址 = 指针(pointer)

    指针变量及其基本用法:

           定义指针变量:

                   类型 * 变量名;

    定义了一个变量,该变量用于装内存编号(地址、指针),而且该变量只能装指定类型的变量所在内存的内存地址。

    两个运算符:

       &变量:取地址运算符,获取给定变量所在内存的首地址。

       *指针变量:取变量运算符。获取指定的内存编号(地址、指针)中所装的变量。

 

指针作为函数的参数

    当使用指针作为函数参数,程序传入函数的不再是普通的变量、而是地址的副本。

    使用指针作为函数参数时,有两点注意:

       1. 程序传入函数的,依然是指针(地址)的副本。

       2. 函数可以改变指针所指变量的值。但函数对传入参数(指针变量本身)依然不会有任何影响。

 

指针与数组

    数组变量,本身就是指针。数组变量指向数组的首地址。

    数组变量,里面装的是第一个元素所在内存的编号(首地址)。

    数组变量与普通指针变量的区别为:普通指针变量可以被赋值(改变),但数组变量不允许被赋值。

    指针变量的赋值方式:

       int * p = 0x14344 ;                                  ×

       int * p = &int型变量;                             √

       int * p = q;   其中q是另一个int*型的变量           √

       int * p = arr;   其中arr是int数组                   √

       int * p = arr[i];   其中arr是int数组                  ×

       int * p = &arr[i];   其中arr是int数组                 √

    指针的运算:

           指针的加法、减法并非以字节为单位,而是size(类型)为单位。

           指针 + n: 将内存编号 + n*sizeof(类型)

           通常而言,只有对指向数组元素的指针进行加N才有意义,相当得到该元素后面第N个元素的地址

           指针 - n: 将内存编号 - n*sizeof(类型)

           通常而言,只有对指向数组元素的指针进行减N才有意义,相当得到该元素钱面第N个元素的地址

          指针 - 指针 => 编号差/sizeof(类型)

          通常而言,只有两个指向数组元素的指针相减才有意义,得到结果就是两个元素之间相差几个元素。

          指针与指针可以比较大小。通常而言,只有对指向同一个数组元素的两个指针比较大小,指针越大,位于数组的越后面。

    数组本身作为函数的参数

          当程序把数组本身作为函数的参数时,实际上就是把指针作为函数的参数。

          1.  程序只是将数组变量的副本传入函数。

          2.  函数不能改变数组变量本身(肯定不能改变),但是可以改变数组元素的值

         记住:如果函数需要改变数组元素的值,那么应该向函数传入数组元素的地址,或者数组变量本身(第一个数组元素的地址)。

         arr[i]在底层的访问方式,本身就是2步:①、先计算arr+i的地址;②、根据地址去取得对应元素。

         如果你写成&arr[i]——这就会导致系统先计算地址,再根据地址得到数组元素,最后又根据元素获取地址。

 

    指向多维数组的指针:

    对于intarr[3][4]这样一个数组。

     arr+n与 arr[n]、*(arr+n)都是指针,它们装的编号是相同的,都是指向整个数组的首地址。

     *(arr+n)与*arr+n是否相同?不同,其实计算公式如下:

           arr+n   =>  arr编号 + n* 第二维长度  * sizeof(类型)

          *arr+n =>  arr编号 + n*sizeof(类型)

          arr[m] + n  、*(arr+m)+n  、&arr[m][n]是一样的。

          *(arr[m] + n) 、*(*(arr+m)+n)、 arr[m][n]是一样的。

 

字符串与字符指针

       C本身并没有字符串,C采用了字符数组来保存字符串。

       程序可以直接用字符串对字符数组进行赋值,程序会自动在所有字符之后添加结束符(\0)。

        【虽然程序可以用字符数组来装多个字符,从而代码字符串,但由于数组不能被重复赋值,因此用起来不方便】。

       由于数组的本质,就是指针,因此实际上往往会使用字符指针来代表字符串。

       使用字符指针声明字符串之后,有如下2个特征:

       -- 由于指针是可以被多次赋值的,因此char*可以被多次存入不同的字符串。

          每次传入字符串时,实际上是先将字符串转换为字符数组,再将数组的首地址赋值给字符指针变量。

       -- 使用char*声明的字符串,是不可变的字符串,它的字符序列是不允许改变的。

              

函数和指针

    C语言允许定义函数指针来指向函数, 函数指针可以在不同时间指向不同的函数。

    函数指针

           定义函数指针的语法:

           函数返回值类型 (* 函数指针变量)();

         【注意】:对函数指针类型的变量赋值时,要用函数本身进行赋值,而不是调用函数!!       

           int (* fnPt)();

          fnPt = jiechen; //jiecheng为自定义的一个函数

          (*fnPt)(5);   //利用函数指针类型调用函数的方法

    返回指针的函数

            对于返回指针的函数,该指针指向的东西,不能是函数中的局部变量。函数返回的指针,通常有如下做法:

           1.  如果指针指向的该函数中的局部变量,应该将局部变量用static修饰。

           2.  让函数返回的指针指向全局变量

           3.  让函数返回的指针指向main函数中的变量——这是因为main结束时,你的程序大致上也就结束了。

     

        

1 0
原创粉丝点击