C語言指針
1、指針定義
??指針是一個變量, 它保存的是另一個變量的地址, 即內存位置的直接地址。
int ptr; //整型變量,ptr+1 表示變量值+1;
const int ptr;//只讀變量,和int const ptr效果一致;
int *ptr1; //定義一個整型指針, ptr+1 表示地址偏移 int 類型字節(jié);
int ptr[3];//3 個成員的整型數(shù)組, ptr+1 表示指向 ptr[1]的地址;
int *ptr[3];//指針數(shù)組,ptr[3]是數(shù)組,int*再與 ptr[3]結合成指針數(shù)組, 表明數(shù)組中保存著 int 類型的指針, ptr+1 表示指向 ptr[1][]的地址, 即二維數(shù)組 ptr[1][0]的地址;
int (*ptr)[3];//數(shù)組指針,()優(yōu)先級高,(*ptr)是指針, 再與[3]結合, 說明指針所指向的內容是數(shù)組, 最后和 int 結合, 表示數(shù)組元素類型是 int 類型。ptr+1 表示指向 ptr[1][]的地址, 即 ptr[1][]的地址;
int **ptr;//二維指針變量, 保存一維指針變量的地址;
int const *ptr;//常量指針,ptr指向的內容不可以修改,但可以改變指向;
int *const ptr;//指針常量,ptr的指向不可以修改,但可以修改指向的內容;
2、*p++、 *(p++)、 *++p、 ++*p、 *p+1、 *(p+1)
#include
int main()
{
int buff[]={10,20,30};
int *p=buff;
/*1 buff[0]的地址:&buff[0]*/
printf("print1 buff addr:%#x\n",buff);
/*2 buff[0]的地址:&buff[0]*/
printf("print2 p addr:%#x\n",p);
/*3 偏移 sizeof(int)字節(jié)*/
printf("print3 p+1 addr:%#x\n",p+1);
/*4 取 buff[0]的值*/
printf("print4 *p=%d\n",*p);
/*5 取 buff[0]的值+1*/
printf("print5 *p+1=%d\n",*p+1);
/*6 地址偏移 sizeof(int)再取值, 即 buff[1]*/
printf("print6 *(p+1)=%d\n",*(p+1));
/*7 先取*p 的值,再 p+1*/
printf("print7 *p++=%d\n",*p++);
/*8 先取*p 的值, 再(*p)+1*/
printf("print8 ++*p=%d\n",++*p);
/*9 先 p+1,再取*(p+1)*/
printf("print9 *++p=%d\n",*++p);
}
- 運行結果:
[xsw@xsw cc]$ ./a.out
print1 buff addr:0xbf98f2a0
print2 p addr:0xbf98f2a0
print3 p+1 addr:0xbf98f2a4
print4 *p=10
print5 *p+1=11
print6 *(p+1)=20
print7 *p++=10
print8 ++*p=21
print9 *++p=30
3.NULL指針和void*指針
??NULL 是標準宏定義, 用來表示空指針常量, 在聲明指針變量時若沒有確切地址賦值, 可以給指針變量賦NULL。
#include
int main()
{
char *ptr=NULL;
printf("ptr addr:%d\n",ptr);
return 0;
}
- 執(zhí)行結果
[xsw@xsw cc]$ ./a.out
ptr addr:0
?在大多數(shù)操作系統(tǒng)中程序不允許訪問地址為 0 的內存, 因為該內存是操作系統(tǒng)保留的。 指針指向地址為 0 的內存表示該指針指向的地址不可訪問。 按照慣例 NULL 指針假定為不指向任何東西。
??void 表示”無類型”, void*指針表示”無類型指針”, 即可指向任何數(shù)據類型。
#include
int main()
{
void *p;
int a=100;
char buff[]={0,10,20,30};
p=&a;//保存 int 型變量地址
//void*指針訪取值時要保證和所指向的變量類型一致
printf("*p=%d\n",*((int *)p));//強制轉換成 int*
p=buff;//指向字符數(shù)組首地址
//強制轉換成 char*
printf("*p=%d\n",*(char *)p);//buff[0]
printf("*(p+1)=%d\n",*(char *)(p+1));//地址往后偏移 char 字節(jié): buff[1]
printf("*p+1=%d\n",*(char *)p+1);//取出的值+1: buff[0]+1
return 0;
}
- 執(zhí)行結果
*p=100
*p=0
*(p+1)=10
*p+1=1
??注:void 幾乎只能用于指針的聲明和函數(shù)返回值以及函數(shù)形參, 不能用于變量的定義。
4、二維指針
??二維指針:指向指針的指針。 保存一維指針的地址。
??指針聲明:int **ptr;
#include
int main()
{
int a=0x12;
int *ptr=&a;//一維指針保存變量地址
int **pptr=&ptr;//二維指針保存一維指針本身地址
//1 ptr==&a
printf("line1:a addr:%#x\n",ptr);
//2 *(&ptr)==&a
printf("line2:*(&ptr)=%#x\n",*(&ptr));
//3 pptr==&ptr
printf("line3:pptr :%#x\n",pptr);
//4 *ptr==*(&a)==a
printf("line4:*ptr=%#x\n",*ptr);
//5 *(&ptr)==ptr==&a
printf("line5:*pptr=%#x\n",*pptr);
//6 **pptr==**(&ptr)==*ptr=*(&a)
printf("line6:**pptr=%#x\n",**pptr);
//7 ***(&pptr)==**(&ptr)==*ptr==*(&num)=0x12
printf("line7:**pptr=%#x\n",***(&pptr));
}
- 執(zhí)行結果:
[xsw@xsw cc]$ ./a.out
line1:a addr:0xbf90384c
line2:*(&ptr)=0xbf90384c
line3:pptr :0xbf903848
line4:*ptr=0x12
line5:*pptr=0xbf90384c
line6:**pptr=0x12
line7:**pptr=0x12
5、數(shù)組指針
指針定義:int (p)[n];指向數(shù)組整體的指針。 數(shù)組指針類型:int ()[n];
()優(yōu)先級高, 所以 p 是一個指針, 指向一個整型的一維數(shù)組, 一維數(shù)組的成員個數(shù)位 n, 也就是說 p 的步長為 n。 即 p+1 偏移的地址為 n 個 int 型長度。 因此數(shù)組指針也稱為行指針。
優(yōu)先級: () > [] > *
示例一:數(shù)組指針指向一維數(shù)組示例
#include
int main()
{
int buff[]={11,22,33,44,55,66};
int (*ptr)[6];//數(shù)組指針,指向數(shù)組整體
ptr=&buff;
int i;
//數(shù)組指針 ptr+1 偏移指向的數(shù)組整體大小,即偏移 6*sizeof(int)=24 字節(jié)
printf("ptr addr:%#x\n",ptr);
printf("(ptr+1) addr:%#x\n",ptr+1);
/*數(shù)組指針遍歷 buff*/
for(i=0;i<6;i++)
{
printf("%d ",*(*ptr+i));//或*(ptr[0]+i)或 ptr[0][i]
}
printf("\n");
return 0;
}
- 執(zhí)行結果:
[root@xsw cc]# ./a.out
ptr addr:0xbfbc8ce0
(ptr+1) addr:0xbfbc8cf8
11 22 33 44 55 66
示例二:數(shù)組指針指向二維數(shù)組示例:
#include
int main()
{
int buff[][3]={1,10,3,4,5,6};//每行有 3 個元素
int (*p)[3]=buff;
printf("*p[0]=%d\n",*p[0]);//等價于 buff[0][0]
printf("*(p[0]+1)=%d\n",*(p[0]+1));//等價于 buff[0][1]
printf("*p[1]=%d\n",*p[1]);//等價于 buff[1][0]
}
6、指針數(shù)組
??定義:int p[n];數(shù)組中保存 int指針。指針數(shù)組類型:int *[n], p的類型是 int **,p+1 偏移的地址為:sizeof(int *)。
??示例一:將一維數(shù)組賦值給指針數(shù)組:
#include
int main()
{
int buff[]={11,22,33,44,55,66};
/*
//初始化直接賦值
int *ptr[10]={&buff[0],&buff[1],&buff[2],&buff[3],&buff[4],&buff[4]}
*/
int *ptr[10];//指針數(shù)組,數(shù)組中保存 int 型指針
/*數(shù)組指針賦值*/
int i;
for(i=0;i<6;i++)
{
*(ptr+i)=&buff[i];//或:buff+i
}
for(i=0;i<6;i++)
{
printf("%d ",*(*ptr+i));
}
printf("\n");
return 0;
}
- 運行結果:
[root@xsw cc]# ./a.out
11 22 33 44 55 66
??示例二:將二維數(shù)組賦值給指針數(shù)組示例
#include
void tow_array(int (*buff)[3],int line);
int main()
{
int buff[][3]={1,10,3,4,5,6};//每行有 3 個元素
int *p[3];
*p=buff[0];
p[0]=buff[0];
*(p+1)=buff[1];
printf("%d\n",(*p)[0]);//等價于:p[0][0]
printf("%d\n",(*p)[1]);//等價于 p[0][1]
printf("%d\n",*(p[0]+1));//等價于 p[0][1]printf("%d\n",*(p+1)[0]);//等價于 p[1][0], *(p+1)指向 buff[1][0]地址
printf("%d\n",*(*(p+1)+1));//等價于 p[1][1]
}
printf("%d\n",*(p+1)[0]);//等價于 p[1][0], *(p+1)指向 buff[1][0]地址
printf("%d\n",*(*(p+1)+1));//等價于 p[1][1]
??注:二維數(shù)組賦值給指針數(shù)組時 p=buff 是錯誤的。
7、函數(shù)指針
??函數(shù)指針:指向函數(shù)的指針變量。 本質是指針變量。
#include
int func(int a,int b);
int main()
{
//pfunc 表示函數(shù)指針變量
int (*pfunc)(int ,int );//定義函數(shù)指針,可以在定義時初始化
pfunc=func;//初始化函數(shù)指針,也可寫成 pfunc=&func
int data=pfunc(10,20);
printf("%d\n",data);
}
int func(int a,int b)
{
return a+b;
}
8、回調函數(shù)
#include
int func_1(int a,int b);
int func_2(int a,int b);
int func_3(int a,int b);
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num);
int main()
{
int data;
int i=0;
//定義函數(shù)指針數(shù)組
int (*pfunc[3])(int ,int)={func_1,func_2,func_3};
func_Callback(30,20,pfunc,sizeof(pfunc)/sizeof(int *));
}
int func_1(int a,int b)
{
printf("\t[%s] %s line:%d %d+%d=%d\n",__FILE__,
__FUNCTION__,
__LINE__,
a,b,a+b
);
return a+b;
}
int func_2(int a,int b)
{
printf("\t[%s] %s line:%d %d*%d=%d\n",__FILE__,
__FUNCTION__,
__LINE__,
a,b,a*b
);
return a*b;
}
int func_3(int a,int b)
{
printf("\t[%s] %s line:%d %d%%%d=%d\n",__FILE__,
__FUNCTION__,
__LINE__,
a,b,a%b
);
return a%b;
}
/***************************回調函數(shù)******************
**
**
**形參:int a,int b ---函數(shù)指針所需要動形參
** int (*pfunc[])(int,int) --- 函數(shù)指針數(shù)組
** int num ---函數(shù)指針數(shù)組成員個數(shù)
**
*********************************************************/
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num)
{
int i;
int data;
for(i=0;i
-
運行結果:
[xsw@xsw cc]$ ./a.out
[func.c] func_1 line:17 30+20=50
data=50
[func.c] func_2 line:22 30*20=600
data=600
[func.c] func_3 line:27 30%20=10
data=10
審核編輯:湯梓紅
-
C語言
+關注
關注
180文章
7594瀏覽量
135864 -
指針
+關注
關注
1文章
478瀏覽量
70491
發(fā)布評論請先 登錄
相關推薦
評論