C語言指針

C語言指針數組

前導程序緩存

#include<stdio.h>函數

 

void change(int *);3d

int main()指針

{code

int a=90;blog

change(&a);內存

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

return 0;it

}

 

void change(int *n)

{

*n=10;

}

 

1、基本知識點

Int a=10;

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

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

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

*p表示訪問指針變量p指向的存儲空間

指針一個做用:可以根據一個地址值,訪問(取值 | 賦值)對應的存儲空間

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

①. Int *p;

②. *p=10;

兩個*的區別:前一個起標識做用,代表定義的p是一個指針,後者的*表示經過訪問p指向的地址空間

 

2、指針使用注意

①. Int *p;

double d=10.0;

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

②. Int *p;

p=200;//指針變量只能存儲地址

③. Int *p;

printf(「%d\n」,*p);//指針變量未經初始化,不要拿來間接訪問其餘的存儲空間

④. Int *p=&a;可是不能寫成 int *p;*p=&a;這種寫法沒有任何的意義,能夠認爲*是和類型符一塊兒使用的。

⑤. *是指針運算符,訪問指針指向的空間

 

3、指向指針的指針

Int a=10;

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

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

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

 

*p2至關於訪問p1;

**p2至關於訪問p;

***p2至關於訪問a;

*p1至關於訪問p;

一顆星一條線。

 

4、指針練習

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

提示:指針的做用之一:實現讓函數擁有多個返回值

 1 #include<stdio.h>
 2 
 3  
 4 
 5 int SumAndMinus(int n1,int n2,int *n3)
 6 
 7 {
 8 
 9    *n3=n1-n2;
10 
11    return n1+n2;
12 
13 }
14 
15  
16 
17 int main()
18 
19 {
20 
21    int a=10;
22 
23    int b=11;
24 
25    int sum;
26 
27    int minus;
28 
29    sum=SumAndMinus(a,b,&minus);
30 
31    printf("和=%d,差=%d\n",sum,minus);
32 
33 }

 

5、有關指針的疑問

注意:任何類型的指針都佔據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

下面是上述代碼的結果的內存分析:

 

指針p訪問的本應該是1個字節空間的數據,此時由於指針的類型是int型的,所以程序天然的從指向的地址0x0a開始讀取了4個字節的數據,訪問的數據從1變成了513。

提示:明確了指針的數據類型,指針纔可以正確的訪問應該訪問的空間數據。

 

6、指針和數組

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]

把指針當作數組來用:

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

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的首元素

 

7、指針和字符串

(一)基礎知識

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

①. 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」};

保存字符串數組的兩種方式:

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

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

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

Int main()

{

Char name[20];

Printf(「請輸入姓名:\n」);

Scanf(「%s」,name);

Printf(「%s」,name);

}

 

8、返回指針的函數

程序示例:

#include<stdio.h>

Char *test();

Int main()

{

Char *name=test();

Printf(「name=%s\n」,name);

Return 0;

}

 

Char *test() //返回指針的函數

{

Return 「rose」;

}

 

9、指向函數的指針

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

假設有函數:

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;

相關文章
相關標籤/搜索