天天看點

iOS語言基礎篇-C語言指針

c語言指針

前導程式

iOS語言基礎篇-C語言指針

#include<stdio.h>

void change(int *);

int main()

{

int a=90;

change(&a);

printf("a=%d\n",a);

return 0;

}

void change(int *n)

*n=10;

一、基本知識點

int a=10;

int *p;//定義一個int類型的指針

p=&a;//指針變量p指向了變量a

*p=20;//使用指針不通過變量直接修改變量a的值為20

*p表示通路指針變量p指向的存儲空間

指針一個作用:能夠根據一個位址值,通路(取值 | 指派)對應的存儲空間

指針變量p前面的int,表示指針的類型

①. int *p;

②. *p=10;

兩個*的差別:前一個起辨別作用,表明定義的p是一個指針,後者的*表示通過通路p指向的位址空間

二、指針使用注意

double d=10.0;

p=&d;//不建議此種做法

②. int *p;

p=200;//指針變量隻能存儲位址

③. int *p;

printf(“%d\n”,*p);//指針變量未經初始化,不要拿來間接通路其他的存儲空間

④. int *p=&a;但是不能寫成 int *p;*p=&a;這種寫法沒有任何的意義,可以認為*是和類型符一起使用的。

⑤. *是指針運算符,通路指針指向的空間

三、指向指針的指針

int *p=&a;//指向int型的指針

int **p1=&p;//指向指針的指針

int ***p2=&p1;//三級指針

iOS語言基礎篇-C語言指針

*p2相當于通路p1;

**p2相當于通路p;

***p2相當于通路a;

*p1相當于通路p;

一顆星一條線。

四、指針練習

編寫一個函數,計算a和b的和與差(一個函數傳回兩個值)

提示:指針的作用之一:實作讓函數擁有多個傳回值

iOS語言基礎篇-C語言指針

五、有關指針的疑問

注意:任何類型的指針都占據8個位元組的存儲空間,那麼為什麼還要為指針加上類型呢?

對下面一段代碼進行記憶體分析,可以證明指針類型不正确帶來的嚴重後果。

int i=2;

char c=1;

int *p=&c;//本應該是char類型的,寫成了int類型

printf(“c的值是%d\n”,*p);//列印結果為513,而非1

printf(“c的值是%d\n”,c);//值為1

下面是上述代碼的結果的記憶體分析:

iOS語言基礎篇-C語言指針

指針p通路的本應該是1個位元組空間的資料,此時因為指針的類型是int型的,是以程式自然的從指向的位址0x0a開始讀取了4個位元組的資料,通路的資料從1變成了513。

提示:明确了指針的資料類型,指針才能夠正确的通路應該通路的空間資料。

六、指針和數組

int ages[5]={10,9,8,7,6};

周遊數組

for(int i=0;i<5;i++)

printf(“%d\n”,ages[i]);

使用指針周遊數組

int *p;

p=ages;//也可以寫成p=&ages[0];,指針變量p指向了數組的首元素

元素的位址:

第一個元素的位址p    &ages[0]

第二個元素的位址p+1    &ages[1]

第三個元素的位址p+2    &ages[2]

元素的值

*p        ages[0]

*(p+1) ages[1]

*(p+2) ages[2]

把指針當做數組來用:

printf(“%d\n”,*(p+i));

  (1)數組元素的三種通路形式:

①. 數組名[下标]

②. 指針變量名[下标]

③. *(p+1)

(2)指針變量的+1究竟是加多少?這取決于指針的類型,如果是char類型則加1個位元組,如果是int類型的,則加4個位元組。

  (3)利用指針來接收一個數組,指針變量指向了數組的首元素。

void change(int array[])等價于void change(int *array)。

前者存儲的雖然是數組元素的首位址,但是在傳遞時就已經變成指針了。

示例:

void change(int *array)

//printf(“%d\n”,array[2]);

printf(“%d\n”,*(array+2));

int main()

int ages[5]={1,2,3,4,5};

change(ages);

調用的結果為:數組的第三個元素3

若改給change(&ages[2]);則調用的結果為5,因為此時array指向的是ages[2],把ages[2]當做了array的首元素

七、指針和字元串

(一)基礎知識

下面兩行代碼有着本質的差別:

①. char name[]=“it”;

②. char *name2=“it”;//指針變量name2指向了字元串的首字元i

char name[0]=‘y’;//改變第一個元素的值

printf(“%s\n”,name);//列印結果為yt

 *name2=‘y’;

printf(“%s\n”,name2);//此時程式崩潰

這是因為,兩者一個是字元串變量,一個是字元串常量。c語言的數組元素存放于棧,裡面的元素可以随便修改,稱為字元串變量。而字元串常量存放于常量區,會緩存起來是不可更改的。

char *name1=“it”;

char *name2=“it”;

printf(“%p %p”,name1,name2);//位址是一樣的,說明name1和name2指向的是同一個字元串。

掌握字元串定義的兩種方式:

①. 利用數組

特點:字元串裡邊的字元是可以修改的,适用于内容需要經常修改時。

②. 利用指針

特點:其實是一個常量字元串,裡面的字元不能修改,适用于字元串的内容不需要修改,且這個字元串經常被使用時。

(二)指針數組

整型數組:這個數組中存放的都是整型數組

指針數組:這個數組中存放的都是指針

int ages[5];

char *name[5]={“jack”,“rose”,“yang”};//字元串數組的常見寫法

對應于:

char name2[3][10]={“jack”,“rose”,“yang”};

儲存字元串數組的兩種方式:

①. 指針數組(字元串數組)

②. 二維字元數組(字元串數組)

如何輸入字元串?(使用數組——因其可變)

char name[20];

printf(“請輸入姓名:\n”);

scanf(“%s”,name);

printf(“%s”,name);

八、傳回指針的函數

程式示例:

char *test();

char *name=test();

printf(“name=%s\n”,name);

return 0;

char *test() //傳回指針的函數

return “rose”;

九、指向函數的指針

數組名即數組的位址,函數名即函數的位址。

假設有函數:

void test ()

printf(“調用了test函數\n”);

void (*p)();  //void指針變量指向的函數沒有傳回值,()表示p指向的函數沒有形參

p=test; //有指針p,把指針p指向函數

有三種方式可以操縱函數:

①. 直接調用test();

②. 利用指針變量簡介調用  (*p)();

③. 簡化使用p()

練習:

假設有函數聲明為 int sum(int a,int b)

則相對應的指向該函數的指針應該定義為:int (*p)(int ,int);

把指針變量p指向函數:p=sum;

調用該函數的三種方式:

(1)int c=p(10,12);

(2)int c=sum(10,12);

(3)int c=(*p)(10,12);

假設函數聲明為:double haha(double a,char *b,int c);

則定義一個指向haha函數的指針應該為:double (*p)(double,char *,int)=haha;

write the code ,change the world!

繼續閱讀