日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android NDK 開發(fā)之旅 2--C 語言基礎(chǔ)--指針

 codingSmart 2021-10-22

1

 指針

指針是一個變量,也叫指針變量,存放的是變量的地址(內(nèi)存地址,系統(tǒng)給數(shù)據(jù)分配的編號(門牌號)),有類型之分。

指針的意義

沒有指針就沒有Java的面向?qū)ο螅∣OP)。

指針的定義與基本使用示例

void change(int* p){ *p = 300;}void main(){ int i = 90; int* p = &i; //輸出指針指向的地址 printf("%#x\n" , p);//p的值就是i這個變量的內(nèi)存地址 //通過指針間接給i賦值 *p = 200; printf("%d\n" , i); change(p); printf("%d\n" , i); system("pause");
}

注意

  1. 指針通過 類型* 指針名字來定義,可以賦值為變量的地址。

  2. 可以通過指針間接給變量賦值。

  3. 在函數(shù)傳參的時候,通過指針的方式,函數(shù)對值的修改會影響到調(diào)用的地方。

2

 趣味例子--游戲外掛原理

先寫一個游戲,運行,初始化一個游戲時間。

#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
void
main(){ //游戲時間 int time = 600; //打印出time的地址 printf("%#x\n",&time); while(time>0){ time--; printf("游戲時間剩余%d秒\n",time); Sleep(1000);//#include <Windows.h> } system("pause");
}

再創(chuàng)建一個工程,作為外掛,去修改游戲的時間:

#include <stdlib.h>
#include <stdio.h>

__declspec(dllexport) void go(){ //修改游戲時間 int* p =(int*)0x55feb4;//注意:這個地址是游戲打印出來的 *p = 99999;
}

注意:

  1. 添加動態(tài)庫 DLL 的輸出聲明:__declspec(dllexport)。

  2. 把項目的輸出改為 DLL,而不是 EXE。(VS 里面:解決方案--屬性--常規(guī))。

  3. 通過 DllInject.exe 軟件把 DLL 注入到游戲中,就可以發(fā)現(xiàn)游戲時間修改為 99999 了。

3

指針類別

空指針NULL

void main(){ int i = 0; int* p = NULL; printf("%#x\n" , p);//輸出NULL的地址,就是0x0 //某些比較小的地址操作系統(tǒng)不允許訪問(訪問沖突) //*p =100; system("pause");
}

多級指針(主要討論二級)

指針變量保存的是變量的地址,可以是一個指針變量的地址,這時候就是多級指針了。

多級指針的意義:

  1. 動態(tài)內(nèi)存分配二維數(shù)組,操作數(shù)組的時候。

  2. 在 jni.h 中的 struct JNIEnv 結(jié)構(gòu)體等有用到。

例子:

void main(){ int a = 50; int* p1 = &a; int** p2 = &p1;//p2是一個二級指針,存放的是p1的值(即a的地址) printf("%d",**p2); system("pause");
}

指針運算(加減法)(與數(shù)組的操作相結(jié)合)

void main(){ //數(shù)組在內(nèi)存中是連續(xù)存儲的 //指針的運算在數(shù)組遍歷的時候才有意義 //ids+i等價于&ids[i] //二維數(shù)組的行指針、列指針 //*(ids+i)等價于ids[i] int ids[] = {0,1,2,3,4,5}; //數(shù)組的首地址,下面都是一個意思 int* p = ids; printf("%#x\n",ids); printf("%#x\n",&ids[0]); printf("%#x\n",&ids); printf("%d\n",*p); p++;//指針的加減法,移動sizeof(數(shù)據(jù)類型)個字節(jié) printf("%d\n",*p);//輸出的是數(shù)組中的數(shù)據(jù)1 //通過指針給數(shù)組賦值 //高級寫法([]運算符的重載) int i =0; for (;i<5;i++) { ids[i] =10; } //普通寫法(利用指針) p=ids; for (;p<ids+5;p++) { *p=10; } system("pause");
}

函數(shù)指針(與 Java 中的回調(diào)類似)

函數(shù)指針的定義與基本使用

void msg(char* msg , char* title){ //C語言里面字符串用char指針代替 MessageBox(0,msg,title,0);}void main(){ //直接調(diào)用 //msg("內(nèi)容","標(biāo)題"); //函數(shù)指針的定義:返回類型,指針名字,參數(shù)列表(后面也可以通過typedef關(guān)鍵字來定義一個新的類型) //參數(shù)名可以省略 //定義一個函數(shù)指針,指向msg函數(shù) void(*fun)(char* msg, char* title) = msg; //使用函數(shù)指針去間接調(diào)用msg函數(shù) fun("我愛你","李璐"); system("pause");
}

函數(shù)指針的例子

int add(int a , int b){ return a+b;}int minus(int a , int b){ return a-b;}void msg(int(*function_p)(int a , int b) ,int a,int b){ //調(diào)用函數(shù)指針的函數(shù) int res = function_p(a,b); printf("%d\n",res);}void main(){ msg(add , 1,2); msg(minus ,2,1); system("pause");
}

注意

  1. 可以看到,msg 函數(shù)調(diào)用的時候需要傳一個函數(shù)指針,參數(shù)是兩個整型,返回值是整型。msg 函數(shù)的執(zhí)行需要執(zhí)行我們手動傳入的代碼(函數(shù)),從而實現(xiàn)了回調(diào)(注入代碼)。

  2. 函數(shù)指針的使用,Java 中 new 內(nèi)部類,類似 Java 的回調(diào)(比回調(diào)更加強大)。

  3. 函數(shù)指針,提高復(fù)用性,在 C 語音的回調(diào)機制里面非常重要。

4

本系列

Android NDK 開發(fā)之旅 1--C 語言基礎(chǔ)--基本數(shù)據(jù)類型

讀者須知

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多