指針_C語言

基礎(chǔ)

  • 內(nèi)存:是通過連續(xù)的內(nèi)存編號來管理的(內(nèi)存的地址)
  • 指針:指針變量里邊存儲的就是內(nèi)存地址

值和類型

不能簡單通過檢查一個值的位來判斷它的類型,值得類型取決于其使用方式

未初始化和非法指針

int *a;
*a = 12;

訪問未初始化的指針是非法的

指向指針的指針

int a = 12;
int *b = &a;
int **c = &b;
*操作符具有從右向左的結(jié)核性,所以這個表達(dá)式相當(dāng)于*(*c)

定義

*a 間接訪問

通過一個指針訪問它所指向的地址的過程稱為間接訪問(indirection)或解引用指針(dereferencing the pointer),這個用于執(zhí)行間接訪問的操作符是單目操作符*

int a = 10;
int *p = &a;
  • int *p表示:表達(dá)式*p產(chǎn)生的結(jié)果類型是int類型
  • int *并不是一個類型,原因如下
int* b,c,d;

這并不是將三個變量聲明為指向整型的指針,b是一個指針,其余兩個變量為普通整型

&b 取地址符

int *pb = &b;// & scanf函數(shù)中有一個取地址符指針變量可以通過地址賦值

%p 指針占位符

printf("%p\n",p);

NULL指針

對一個NULL指針進(jìn)行解引用操作是非法的

NULL類似于給普通變量賦初始值的0,其實(shí)就是地址為0

int *p =NULL;//定義了一個指針變量,初始值為NULL
float*p1 = NULL;//浮點(diǎn)型指針
double *p2 =NULL;
char *p3 =NULL;

指針的算術(shù)運(yùn)算

int *pp =NULL;
int num1 = 10;

pp = &num1;

printf("%p\n",pp);
printf("%p\n",(pp+1));

指針的算術(shù)運(yùn)算需要根據(jù)指針類型去計算,指針+ 1是向高位移動一個類型所占的字節(jié)數(shù),指針- 1是向低位移動一個類型所占的字節(jié)數(shù)

printf("%p\n",pp++);
printf("%p\n",++pp);
printf("%p\n",pp);

++ --還是遵循之前++ --運(yùn)算符法則

指針的重指向

咱們可以讓指針重新指向另一個變量(內(nèi)存的另一塊區(qū)域),這就叫指針的重指向
我們可以通過指針修改內(nèi)存地址上的值

int number1 = 10;
int *pNum1 = &number1;

int number2 = 8;
pNum1 = &number2;

*pNum1 = 9;
printf("%d\n",*pNum1);
printf("%d\n",number2);

用指針交換兩個數(shù)的值

  • 函數(shù)在傳參數(shù)的時候,形式參數(shù)只是拷貝了實(shí)際參數(shù)的內(nèi)容或者值,實(shí)際參數(shù)并未發(fā)生改變
  • 有了指針我們可以直接操作指針指向的內(nèi)存區(qū)域,然后修改內(nèi)存中的值
int num1 = 12;
int num2 = 16;
swapTwoNumbers(&num1, &num2);
printf("%d %d\n",num1,num2);

指針與數(shù)組的關(guān)系

數(shù)組名就是數(shù)組的地址,它恒等于數(shù)組元素的首地址

實(shí)際上*(arr1 + i) = arr[i];

int arr1[4] = {1,2,3,4};
for(inti = 0; i < 4; i++) {
    printf("%p\n",arr1+0);
}

printf("%lu\n",sizeof(arr1));//數(shù)組名雖然是地址,但是我們利用它計算內(nèi)存空間的話,還是根據(jù)里邊存儲的數(shù)據(jù)類型而定

int *pp = &num1;

printf("%lu\n",sizeof(pp));//打印一個單純的變量地址的話,并不是根據(jù)類型而定

printf("%lu\n",sizeof(&num1));

char aa = 'w';
char *pp1 = &aa;

printf("%lu\n",sizeof(pp1));//指針類型所占的字節(jié)數(shù)與計算機(jī)本身的計算位數(shù)有關(guān),如果是32位的計算機(jī),指針類型占4個字節(jié),如果是64位的計算機(jī),指針類型占8個字節(jié)
   
short array[4] = {1,2,3,4};

int *p = array;//不匹配的指針類型

數(shù)組名確實(shí)能夠打印出數(shù)組元素的首地址,但是如果把數(shù)組名認(rèn)為就是地址是不準(zhǔn)確的,實(shí)際上數(shù)組名是一個常量

指針與字符串的關(guān)系

char name[] ="guozhenyan";
char *p1 = name;

printf("%p\n",p1);

for(int i = 0; i <strlen(name); i++) {
    printf("%c\n",*(p1+i));
}

指針數(shù)組

char *a[10] = {"ddd","sdq","das","qwe","cva","btg","aaa","ccc","eee","fff"};

printf("%p\n",a);//數(shù)組指針的地址
printf("%p\n",a+1);//對數(shù)組指針地址進(jìn)行操作
printf("%p\n",a[0]);//對存的數(shù)據(jù)地址進(jìn)行操作
printf("%p\n",a[1]);

printf("%p\n",*a);//存的是地址
printf("%p\n",*(a+1));

printf("%c\n",**a);
printf("%c\n",**(a+1));

printf("%c\n",*a[0]);
printf("%c\n",*a[1]);

結(jié)構(gòu)體指針

typedef struct person {
   char name[20];
   int age;
   int score;
}Person;

Person p1 = {"guangguang",16,90};
Person p2 = {"jintao",18,99};
Person p3 = {"wangce",17,88};
      
void printArr(Person*p,intcount){
for(int i = 0; i < count; i++) {
printf("%s,%d,%d\n",(*(p+i)).name,(p+i)->age,(*(p+i)).score);
}
    //使用指針去訪問結(jié)構(gòu)體數(shù)組的成員變量的時候,可以使用-> 
Person arr[3] = {p1,p2,p3};

函數(shù)指針

函數(shù)名跟數(shù)組名類似,實(shí)際上它也是一個地址

printf("%p\n",helloWorld);

我們也可以找一個指針,指向函數(shù)名所在的地址.這個指針就是所謂的函數(shù)指針

函數(shù)的指針類型根據(jù)函數(shù)的返回值和參數(shù)而定
返回值類型+ (*指針名) +參數(shù)的類型=函數(shù)指針

void (*p1)() =NULL;
p1 =helloWorld;//聲明
p1();//調(diào)用方式
void (*p2)(int) =NULL;

p2 =printNumber;
p2(31415);

BOOL (*p3)() =backYes;

printf("%d\n",p3());

int (*p4)(int,int) =sum;
printf("%d\n",p4(8,4));

函數(shù)指針可以重新指向別的函數(shù),只要函數(shù)類型一樣就可以重指向

char a[10];

printf("請輸入函數(shù)名:\n");

scanf("%s",a);

int(*p5)(int,int) =NULL;

printf("請輸入a,b的值:\n");

int b,c;
scanf("%d%d",&b,&c);

if(strcmp(a,"maxValue") == 0){
p5 =max;
}else if(strcmp(a,"sum") == 0){
p5 =sum;
}else{
printf("輸入有誤\n");
return 0;
}
//現(xiàn)在p5這個指針并沒有指向認(rèn)可地址,也可以導(dǎo)致程序崩潰,這種情況叫作野指針

printf("%d\n",p5(b,c));

替換指針類型

typedef int (*pGet)(int,int);//重新定義函數(shù)指針的類型:pGet
//我們利用typedef這個關(guān)鍵字還可以重新定義函數(shù)指針的類型變成一個新的類型*后邊跟上我們新類型的名字

函數(shù)指針的作用

  1. ?函數(shù)指針是OC中block的底層實(shí)現(xiàn),OC中block得形式跟函數(shù)指針一模一樣.
  2. ?函數(shù)指針因?yàn)榭梢灾刂赶虿煌瘮?shù),可以起到簡化代碼和解耦合的作用

函數(shù)回調(diào)(用函數(shù)指針作為函數(shù)參數(shù))

int(*p)(int,int) =NULL;
p = max;//函數(shù)指針指向的函數(shù)可能實(shí)現(xiàn)的功能比較復(fù)雜,或者是公司核心代碼,我們一般程序員不需要知道里面的詳細(xì)內(nèi)容,只需要會調(diào)用即可.(面向?qū)ο笳Z言,封裝特性的底層(雛形))

函數(shù)轉(zhuǎn)移表

//常規(guī)寫法
switch ( oper ){
    case ADD:
        result = add( oper1, oper2 );
        break;
    case SUB:
        result = sub( oper1, oper2 );
        break;
    case MUL:
        result = mul( oper1, oper2 );
        break;
    case DIV:
        result = div( oper1, oper2 );
        break;
    ...
}
//使用轉(zhuǎn)移表之后的寫法
double add( double, double );
double sub( double, double );
double mul( double, double );
double div( double, double );
...
double (*oper_func[])( double, double ) = {
    add, sub, mul, div, ...
};
//下面的語句替換前面整條switch語句
result = oper_func[ oper ]( op1, op2 );

范指針

void *p;
memcpy;

類型轉(zhuǎn)換

fptr = (float *) iptr;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腰耙,一起剝皮案震驚了整個濱河市齿税,隨后出現(xiàn)的幾起案子伊约,更是在濱河造成了極大的恐慌,老刑警劉巖蔓挖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡饱亿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門闰靴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪笼,“玉大人,你說我怎么就攤上這事蚂且∨涿ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵杏死,是天一觀的道長章姓。 經(jīng)常有香客問我,道長识埋,這世上最難降的妖魔是什么凡伊? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮窒舟,結(jié)果婚禮上系忙,老公的妹妹穿的比我還像新娘。我一直安慰自己惠豺,他們只是感情好银还,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布风宁。 她就那樣靜靜地躺著,像睡著了一般蛹疯。 火紅的嫁衣襯著肌膚如雪戒财。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天捺弦,我揣著相機(jī)與錄音饮寞,去河邊找鬼。 笑死列吼,一個胖子當(dāng)著我的面吹牛幽崩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寞钥,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼慌申,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了理郑?” 一聲冷哼從身側(cè)響起蹄溉,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎您炉,沒想到半個月后柒爵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邻吭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年餐弱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囱晴。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡膏蚓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畸写,到底是詐尸還是另有隱情驮瞧,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布枯芬,位于F島的核電站论笔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏千所。R本人自食惡果不足惜狂魔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淫痰。 院中可真熱鬧最楷,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犯建,卻和暖如春讲冠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背适瓦。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工竿开, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人犹菇。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓德迹,卻偏偏與公主長得像芽卿,于是被迫代替她去往敵國和親揭芍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容