C語言的指針確實比較難搞懂,今天再溫習,學習一遍,加深理解,進一步提高C語言編程水平。
一、指針說明
指針是包含另一變量的地址變量。
1、int *p
p是一個指針,指向整型數。
2、int *P()
p是一個函數,該函數返回一個指向整型的指針。
3、int (*p)()
p是一個指針,該指針指向一個函數,這個函數返回一個整數。
4、int *p[]
p是一個數組,該數組的每一個元素是指向整數的指針。
5、int (*p)[]
p是一個指針,該指針指向一個數組,這個數組的每一個元素是一個整數。
6、int *(*p)()
p是一個指針,該指針指向一個函數,這個函數返回一個指向整數的指針。
二、指針的初始化(賦地址)
1、通過符號&取變量(包括結構變量、數組第一個元素)的地址賦給指針;
2、把數組名賦給指針;
3、把函數名賦給指向函數的指針;
4、動態分配內存;
示例:
struct c {double r,i;};
struct c *p;
p=(struct c*)malloc(sizeof(struct c));
三、指針與數組、函數的關係
1、對於一維數組int a[]或指針int *a
a+i指向a[i]
2、對於字符串char s[i]或指針char *s
s+i指向第i個字符s[i]
3、對於二維數組int a[i][j]
*a+j指向a[0][j]
*(a+i)指向a[i][0]
*(a+i)+j指向a[i][j]
示例:
對於a[2][3]={1,2,3,4,5,6};
有*(*(a+1)+1)=5;
4、對於字符串數組char p[i][j]或字符型指針數組char *p[i]
*p+j指向第0個字符串的第j個字符
*(p+i)指向第i個字符串的第J個字符
示例:
對於*p[]={"ABC","DEF"};有*(*(p+1)+1)="E";
對於char P[3]={"ABC","DEF"};有*(*(p+1)+1)="E";
5、對於指針數組int *a[i]
a[i]指向變量i,即*a[i]=變量i或a[i]=&變量i
6、對於結構struct XY
{int x;int *p}*p;
p是指向結構XY的指針
(*p).x或p→x是表示x的內容
(*p).y或p→y是表示指針y的值(地址)
*(*p).y或p→y是表示y所指的內容
&(*p).x或&p→x是表示x的地址
四、指針的分類
1、近指針(near)
近指針爲16位指針,它只含有地址的偏移量部分,近指針用於不超過64K字節的單個數據段或代碼段。在微、小和中編譯模式下產生的數據指針是近指針(缺省狀態),在微、小和中編譯模式下產生的碼指針(指向函數的指針)是近指針(缺省狀態)。
2、遠指針(far)
遠指針爲32位指針,指針的段地址和偏移量都在指針內,可用於任意編譯模式,每次使用遠指針時都要重裝段寄存器,遠指針可尋址的目標不能超過64K,因爲遠指針增減運算時,段地址不參與運算,在緊湊、大和巨模式下編譯產生的數據指針是遠指針(缺省狀態)。
3、巨指針(huge)
巨指針爲32位指針,指針的段地址和偏移量都在指針內,可用於任意編譯模式,遠指針可尋址的目標可以超過64K,巨指針是規則化的指針。
五、指針的轉換
1、遠指針轉換成巨指針
使用以下函數
void normalize(void far **p)
{
*p=(void far *)(((long)*p&0xffff000f)+(((long)*p&0x0000fff00<<12));
}
六、指針的使用
1、將浮點數轉換爲二進制數
float ff = 16.5;
unsigned char *cc;
(float*)cc=&ff;
此時cc的內容爲“00008441”,即cc第一個字節=0,第二個字節=0,第三個字節=0x84,第四個字節=0x41。
2、將二進制數轉換成浮點數
float ff;
unsigned char *cc;
cc=(unsigned char *)malloc(4);
cc=(unsigned char *)&ff;
*(cc+0)=0;
*(cc+1)=0;
*(cc+2)=0x84;
*(cc+3)=0x41;