瘋子C語言筆記(指針篇)


 

指針篇

1.基本指針變量

(1)定義

int i,j;

int *pointer_1,*pointer_2;

pointer_1 = &i;

pointer_2 = &j;

等價於

int *pointer_1 = &i,*pointer_2 = &j;

(指針誤區:  大家首先應該知道,地址可稱為指針,是不可變的;指針變量(上述定義的pointer_1為指針變量)是變量,變量是可變的,和通常的變量相比,它存放的量CPU會當地址來處理)

-------------------------------------------------------

(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]+2、*(a+1)+2、&[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

                                                              新的理解和見解可留言相互交流,共同學習  

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM