指針篇數組
1.基本指針變量函數
(1)定義學習
int i,j;ui
int *pointer_1,*pointer_2;spa
pointer_1 = &i;指針
pointer_2 = &j;orm
等價於blog
int *pointer_1 = &i,*pointer_2 = &j;內存
(指針誤區: 你們首先應該知道,地址可稱爲指針,是不可變的;指針變量(上述定義的pointer_1爲指針變量)是變量,變量是可變的,和一般的變量相比,它存放的量CPU會當地址來處理)ci
-------------------------------------------------------
(2)簡記
*:取該地址空間存放量,*後面的內容CPU當地址處理;
&:取該變量的地址,&後面的內容CPU當變量來處理;
2.一維數組的指針變量
(1)定義
int a[10];
int *p;
p = &a[0];
等價於 p = a;
a[0]和a都表示該數組的首地址;
(2)指向數組的指針變量也能夠帶下標,如:p[i]、*(p+i);
(3)數組名a表明數組首元素的地址,它是一個指針常量,它的值在程序運行期間是固定不變的,請不要出現相似a++這樣的錯誤。
3.當用數組名作函數參數時傳遞給函數的是數組的首元素地址,所以要求形參是指針變量;
概括:
①:形參、實參都用數組名
int a[10];
f(a,10);
.
.
.
viod (int x[ ] , n)
{...}
簡解:編譯器遇到形參爲數組名會當指針變量來處理,故此程序運行期間形參指向數組a[ ]各個元素,或者理解爲形參實參在程序運行區間佔用同一段內存空間;
②實參數組名,形參指針變量
int a[10];
f(a,10);
.
.
.
viod (int *x, n)
{...}
簡解:函數開始執行x指向數組各個元素
③實參形參都是指針變量
int a[10], *p = a;
f(p , 10);
.
.
.
void f(int *x,int n)
{...}
簡介:1. p先指向數組a首元素; 2. p值給x; 3. x指向數組a各個元素;
④實參爲指針變量,形參爲數組名
int a[10],*p = a;
f(p , 10)
void f(int x[],int n)
{...}
簡解:1.形參當指針變量處理,後面同③
4.數組a 的性質
int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}
int 型數據在KEIL編譯環境下,佔2字節內存
表示形式 |
含義 |
地址 |
a |
二維數組名,指向一位數組a[0],即0行首地址 |
設2000 |
a[0]、*(a+0)、*a |
0行0列元素地址 |
2000 |
a+1,&a[1] |
1行0列元素地址 |
2008 |
a[1]、*(a+1) |
1行0列元素a[1][0]的地址 |
2008 |
a[1]+二、*(a+1)+二、&[1][2] |
1行2列(即a[1][2])元素地址 |
2012 |
*(a[1]+2)、*(*(a+1)+2),a[1][2] |
1行2列(即a[1][2])元素值 |
元素13 |
(1)爲何*(a+1)表示第一行的首地址呢?
答:*(a+x)==a[X]; 二者等價。
(2)那麼C語言中是怎麼形成*(a+x)與a[X]徹底等價呢?
答:在一位數組中,*a就是a[0],a+1指向a[1],a+2指向a[2],a+3指向a[3],也就是說
*(a+1)、*(a+2)、*(a+3)分別是a[1]、a[2]、a[3]。在實際代碼生成機械碼的關係中,兩個效應徹底等價。
5.對於 int(*p)[4]的解釋
答:int(*p)[4]表示p是一個指針變量,它指向包含4個整形元素的一維數組,此時p只能指向一個包含4個元素的一維數組,p不能指向一維數組中的某一個元素,p的值就是該一維數組的起始地址。
P
(*p)[0] |
(*p)[1] |
(*p)[2] |
(*p)[3] |
→
由此也可得出
指針做爲函數參數 |
① 指向變量的指針變量(通常) |
② 指向一維數組的指針變量 |
6.while(*from != '\0') == while(*from != 0),CPU在處理時,字符與ASCLL碼按相同處理。
7.字符數組與字符指針變量
char str[14];
str = "I Love China"; ×(對字符數組只能對各個元素賦值)
數組只能夠在定義時總體賦初值,但不能再賦值語句中總體賦值;
BUT(aber)
char *a;
a = "I Love China"; √(注意賦值給a的不是字符,而是字符串第一個元素的地址)
等價於
char *a = "I Love China";
/******典printf******/
char *format;
format = "a=%d,b=%f\n"; 當字符串處理
printf(format,a,b);
等價於
printf("a=%d,b=%f\n",a,b);
8.指向函數的指針
#include<stdio.h>
void main()
{
int max(int,int);
int(*p)(int,int);
int a,b,c;
p = max;
scanf("%d,%d",&a,&b);
c = (*p)(a,b);
printf("a = %d,b = %d,max = %d\n",a,b,c);
}
(1),「int(*p)(int,int);」用來定義p是一個指向函數的指針變量,*p兩端的括號絕對不能省略。
(2),"p = max"的做用是將函數max的入口地址賦給指針變量p。和數組名錶明數組首元素地址相似,函數名錶明該函數的入口地址。(同理:max++是錯誤的)
(3),指向函數的指針變量的通常定義形式:
數據類型(*指針變量名)(函數參數表列);
9.用指向函數的指針做函數參數
如:
int a = 1;
int b = 2;
int max(int x,int y)
{______________}
void process(int,int,int(*fun)(int,int)); //聲明
process(a,b,max); //引用
10.返回指針值的函數
類型名 *函數名(參數列表);
如:
int *a(int x ,int y);
解釋:括號的運算優先級大於*號,及是函數a(int x ,int y )的返回值取地址值;
請區別上題8中的int(*p)(int,int);此爲指向函數的指針;
int(*p)(int,int); //指向函數的指針
int *a(int,int); //返回指針值的函數
此二者用法順序相反
用法:
float *p;
float score[][4] = {{1,2,3,4},{5,6,7,8},{11,12,13,14}};
float *search(float (*pointer)[4],int n);
p = search(score, m);
11.指針數組
(1)定義形式
類型名 * 數組名[數組長度];
如:int *p[4];
請不要寫成 int (*p)[4]; 這是指向一維數組的指針變量;
指針數組中每個量都用做指針變量;
爲何用指針數組?
答:它能夠比較適合於用來指向若干個字符串,使字符串處理更加方便靈活。
12.指向指針的指針
(1)定義
char **p;
謹記:*p是**p的地址,p是**p的地址,**p是變量。p和*p都是地址;
p前面有兩個*號,*運算符的結合性是從右到左,所以**p至關於*(*p),顯然*p是指針變量的定義形式。
13.NULL
#define NULL 0 (這句在stdio.h裏面已經有了)
p = NULL;
表示p不指向任一有用單元,應該注意p的值爲NULL與未對p賦值是兩個不一樣的概念。前者是有值的(0),不指向任何程序變量,後者雖未對p賦值但並不等於P無值,只是它的值是一個沒法預料的值,也就是p可能指向一個事先未指定的單元。這種狀況很危險的。所以,在引用指針變量以前應對它賦值。
任何指針變量或地址均可以與NULL做相等或不相等的比較,例如:
if(p == NULL)...
14.指向同一個數組中的指針運算
(1)相減、比較
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
p1指向a[1],p2指向a[3]
那麼:
減法:p2 - p1 = 2,但 p1 + p2是無心義的;
比較:指向前面的元素的指針變量「小於」指向後面元素的指針變量。
即:p1 < p2,或者說「p1 < p2」爲1(真);
15.void 指針類型
char *p1;
void *p2;
.
.
.
p1 = (char *)p2;
也可:
p2 = (void *)p1;
void用來指向一個抽象的類型數據,將它的值賦給另外一個指針變量時要進行強制類型轉換使之適合於被賦值的變量的類型。
15.指針類型小結
定義 | 含義 |
int i; | 定義整型變量i |
int*p; | p爲指向整型數據的指針變量 |
int a[n]; | 定義整型數組a,它有n個元素 |
int *p[n]; | 定義指針數組p,它有n個指向整型數據的指針元素組成(多) |
int (*p)[n]; | p爲指向含n個元素的一維數組的指針變量(一) 數組指針 |
int f(); | f爲返爲整型函數值的函數 |
int*p(); | p爲返回一個指針的函數,該指針指向整型數據,(指針函數)返回int型的指針的函數 |
int(*p)(); | (函數指針)p爲指向函數的指針,該函數返回一個整型值 |
int **p; | p是一個指針變量,它指向一個指向整型數據的指針變量 |
例:
nt(*p)();是一個函數指針
int (*s[10])(int) 函數指針數組,每一個指針指向一個int func(int param)的函數。
一個數組全是函數指針;
(uint32_t *)(x) 等價於 uint32_t (*p)(x) p表明函數指針,對該地址的存儲量操做,以下:
(*((volatile uint32_t *)(x)))
取該地址的量;
也就是括進去的是指針,沒有括進去的是數組或函數;
下次更新時間2014.10.10
新的理解和看法可留言相互交流,共同窗習