C 語言指針

// - 在 C語言中, **函數之間傳值時候, 想改變誰, 就傳遞誰的地址; 傳遞了誰的地址, 就可以改變誰** 比如, **要改變的數據是 int 類型, 那麼傳遞的參數是 int *, 要改變的數據是 int *類型 , 則傳遞的參數是 int ** 類型**; 相反 ,**如果傳入的是 int **類型, 那麼能改的就是 int* 類型的數據, 如果我們傳入的是 int*類型, 那麼能改邊的就是 int 類型**;
// - 函數指針的調用
1.NSString *(*fn)(id, SEL, NSString *) = (NSString *(*)(id, SEL, NSString *))objc_msgSend;

      fn(self, @selector(method1:), @"呵呵");

    2.((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
      ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);

    // - 調用 IMP 方法
    IMP result7 = class_getMethodImplementation([ViewController class], @selector(method0:));

    int (*px)(id, SEL, NSString *) = (int (*)(id, SEL, NSString *))result7;

  // - 下邊的兩種寫法都可以
    1. px(nil, nil, @"ssss");      2. px(self, @selector(method0:), @"ssss");

// - C語言
#include<stdio.h>

int main(){
/**
指針變量的作用:能夠根據一個地址,訪問指針變量指向的存儲空間(包括取值和賦值)
*/
   int a =90;
   
   // - 定義了一個指針變量 變量名是 p;
   int *p;
   
   // - 指針變量p指向了變量 a (把 a的地址賦值給指針變量 p);
    p = &a;
    
   //    *p // - 訪問指針變量 p 指向的存儲空間;
    *p =10;

   /**
     *p = 10; 給指針變量 p 所指向的存儲空間賦值
     *p       訪問指針變量 p 指向的存儲空間的值
     */
   printf("%d\n",*p);

int * p  (p = 0xcc08); p + N
就是 p 裏邊存儲的地址 + N* 指針所指向的數據類型所佔的字節數 上邊的就是加4個字節 就是 0xcc0a

double * p; (p = 0xcc08);p - N
就是 p 裏邊存儲的地址 - N* 指針所指向的數據類型所佔的字節數 上邊的就是減8個字節 就是 0xcc00
p+N  就是 p + (N * 8)


數組名代表着這個數組的首元素的地址;
numbers[0][0] + 1 的跨度是4 (因爲相當於&numbers[0][0][0] + 1 就是 p 裏邊存儲的地址地址+1個指向的數據類型(這裏是整數 10)所佔的字節數)

numbers[1] + 1 的跨度是 8 (因爲相當於&numbers[1][0] + 1 就是 p 裏邊存儲的地址地址+1個指向的數據類型(這裏是整形數組{50,60})所佔的字節數)

numbers + 1 的跨度是 16 (因爲相當於&numbers[0] + 1 就是 p 裏邊存儲的地址地址+1個指向的數據類型(這裏是整形二維數組{{10,20}, {30, 40})所佔的字節數)

&numbers + 1 的跨度是32 (因爲相當於指向整個 numbers 的數組 就是整個三維數組 所佔的字節數)

X *p; p =  &X; 這裏就是指向 X 整個數據類型的 X 類型的指針;

& Y + N ; 就是 Y 原來存儲的地址 + ( N * Y這個數據類型所佔的字節數)
   return0;
}

#import "C.h"
@implementation C

- (void)test{
    int a = 10;
    /**普通指針 */
    int *p;
    p = &a;
    
    // 作用同上兩句
//    int *p1 = &a; ==  int *p; p = &a;
===========================================================================================================

   /**指向指針的指針 */
    int *po1 = &a;

    // 兩個*的作用
    /**
     *  1.第一個作用是指向 int *類型的數據

     *  2.第二個作用是定義一個指針類型的數據
     */

    int **po2 = &po1;
    
    // 分開寫 int *(*po2);   po2 = &po1;
    /**
     *  這裏 po2是 po1的地址 *po2是 po1的地址裏存儲的數據 **po2是po1的地址裏存儲的指針存儲的地址指向的數據

     即 **po2 = a;
     *  po1的地址裏存儲的數據是 a的地址
     */
===========================================================================================================

    /**指針和數組 */
    int ages[5] = {2,4,5,6,70};
    int * p2 = &ages[0];

    // 作用同上
   //    p2 = ages; == int * p2 = &ages[0]
 
   /**三種方式打印數組元素 */
    //    打印數組的第3個元素

    int c;
    c = ages[3];
    c = p2[3];
    c = *(p2 + 2);
===========================================================================================================

    /**指針和字符串 */
    //這個指針變量指向字符串的首字符如果打印 *po3打印的是 i如果打印 po3打印的是 itcase;
    char * po3 = "itcase";
===========================================================================================================
   /**指向函數的指針 */
   1.沒有參數和返回值的函數

    // - (*p)是固定寫法代表指針變量 p將來會指向一個函數

    // - void 指針變量 p 指向的函數沒有返回值

    // -右邊的()代表指針變量 p指向的函數沒有形參

    // -這句話只是定義一個指向函數的指針

    void (*p)();

    // - 指針變量 p 指向了 test函數(函數名就代表着函數地址)
    p = test;
    // - 調用函數
    (*p)();
//    (*p)(); 同上也是一種調用函數的方式

    2.有參數和返回值的函數

    // - (*p)是固定寫法代表指針變量 p將來會指向一個函數

    // - int 指針變量 p 指向的函數返回值是 int類型

    // - 右邊的(int, int)代表指針變量 p指向的函數有兩個 int類型的參數


    int (*p)(int,int);
     // - 指針變量 p 指向了 sum函數(函數名就代表着函數地址)
    p = sum;

     // - 調用函數
    int c =  p(4,6);
//   int c =  (*p)(4, 6); 同上
}

int sum (int a,int b){

    return a + b;

}

@end


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章