null第十章 指针第十章 指针C程序设计中使用指针可以:
使程序简洁、紧凑、高效
有效地表示复杂的数据结构
动态分配内存
得到多于一个的函数返回值
null10.1 指针的概念
变量与地址程序中: int i;
float k; 内存中每个字节有一个编号-----地址ik 编译或函数调用时为其分配内存单元变量是对程序中数据
存储空间的抽象null指针与指针变量
指针:一个变量的地址
指针变量:专门存放变量地址的变量叫~2000指针指针变量 变量的
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
变量的地址null&与*运算符
含义含义: 取变量的地址
单目运算符
优先级: 2
结合性:自右向左含义: 取指针所指向变量的内容
单目运算符
优先级: 2
结合性:自右向左两者关系:互为逆运算
理解i_pointer-----指针变量,它的内容是地址量
*i_pointer----指针的目标变量,它的内容是数据
&i_pointer---指针变量占用内存的地址i_pointer &i &(*i_pointer)
i *i_pointer *(&i)i_pointer = &i = &(*i_pointer)
i = *i_pointer = *(&i)null直接访问与间接访问
直接访问:按变量地址存取变量值
间接访问:通过存放变量地址的变量去访问变量例 i=3; -----直接访问3例 *i_pointer=20; -----间接访问20null例 k=i; --直接访问
k=*i_pointer; --间接访问10例 k=i;
k=*i_pointer; null10.2 指针变量
指针变量与其所指向的变量之间的关系指针变量的定义
一般形式: [存储类型] 数据类型 *指针名;合法标识符指针变量本身的存储类型指针的目标变量的数据类型表示定义指针变量
不是‘*’运算符例 int *p1,*p2;
float *q ;
static char *name;注意:
1、int *p1, *p2; 与 int *p1, p2;
2、指针变量名是p1,p2 ,不是*p1,*p2
3、指针变量只能指向定义时所规定类型的变量
4、指针变量定义后,变量值不确定,应用前必须先赋值null指针变量的初始化
一般形式:[存储类型] 数据类型 *指针名=初始地址值;赋给指针变量,
不是赋给目标变量例 int i;
int *p=&i;变量必须与已说明过的
类型应一致例 int i;
int *p=&i;
int *q=p;用已初始化指针变量作初值例 main( )
{ int i;
static int *p=&i;
..............
} ()不能用auto变量的地址
去初始化static型指针null例 main( )
{ int i=10;
int *p;
*p=i;
printf(“%d”,*p);
}危险!例 main( )
{ int i=10,k;
int *p;
p=&k;
*p=i;
printf(“%d”,*p);
}指针变量必须先赋值,再使用null零指针与空类型指针
零指针:(空指针)
定义:指针变量值为零
表示: int * p=0; p指向地址为0的单元,
系统保证该单元不作它用
表示指针变量值没有意义#define NULL 0
int *p=NULL:p=NULL与未对p赋值不同
用途:
避免指针变量的非法引用
在程序中常作为状态比较 例 int *p;
......
while(p!=NULL)
{ ...…
}void *类型指针
表示: void *p;
使用时要进行强制类型转换例 char *p1;
void *p2;
p1=(char *)p2;
p2=(void *)p1;表示不指定p是指向哪一种
类型数据的指针变量null例 指针的概念main()
{ int a;
int *pa=&a;
a=10;
printf("a:%d\n",a);
printf("*pa:%d\n",*pa);
printf("&a:%x(hex)\n",&a);
printf("pa:%x(hex)\n",pa);
printf("&pa:%x(hex)\n",&pa);
}运行结果:
a:10
*pa:10
&a:f86(hex)
pa:f86(hex)
&pa:f88(hex)null例 输入两个数,并使其从大到小输出main()
{ int *p1,*p2,*p,a,b;
scanf("%d,%d",&a,&b);
p1=&a; p2=&b;
if(a
p2 表示p1指的元素在后
p1==p2 表示p1与p2指向同一元素
若p1与p2不指向同一数组,比较无意义
p==NULL或p!=NULLnull数组元素表示方法[] 变址运算符
a[i] *(a+i)a[i] p[i] *(p+i) *(a+i)null例 数组元素的引用方法main()
{ int a[5],*pa,i;
for(i=0;i<5;i++)
a[i]=i+1;
pa=a;
for(i=0;i<5;i++)
printf("*(pa+%d):%d\n",i,*(pa+i));
for(i=0;i<5;i++)
printf("*(a+%d):%d\n",i,*(a+i));
for(i=0;i<5;i++)
printf("pa[%d]:%d\n",i,pa[i]);
for(i=0;i<5;i++)
printf("a[%d]:%d\n",i,a[i]);
}null例 int a[]={1,2,3,4,5,6,7,8,9,10},*p=a,i;
数组元素地址的正确表示: (A)&(a+1) (B)a++ (C)&p (D)&p[i]数组名是地址常量
p++,p-- ()
a++,a-- ()
a+1, *(a+2) ()null例 void main()
{ int a []={5,8,7,6,2,7,3};
int y,*p=&a[1];
y=(*--p)++;
printf(“%d ”,y);
printf(“%d”,a[0]);
} 输出:5 6例 注意指针变量的运算6nullmain()
{ int i,*p,a[7];
p=a;
for(i=0;i<7;i++)
scanf("%d",p++);
printf("\n");
for(i=0;i<7;i++,p++)
printf("%d",*p);
}例 注意指针的当前值p=a;指针变量可以指到数组后的内存单元null数组名作函数参数
数组名作函数参数,是地址传递
数组名作函数参数,实参与形参的对应关系null例 将数组a中的n个整数按相反顺序存放 实参与形参均用数组void inv(int x[], int n)
{ int t,i,j,m=(n-1)/2;
for(i=0;i<=m;i++)
{ j=n-1-i;
t=x[i]; x[i]=x[j]; x[j]=t;
}
}
main()
{ int i,a[10]={3,7,9,11,0,6,7,5,4,2};
inv(a,10);
printf("The array has been reverted:\n");
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("\n");
}m=4null例 将数组a中的n个整数按相反顺序存放 void inv(int *x, int n)
{ int t,*p,*i,*j,m=(n-1)/2;
i=x; j=x+n-1; p=x+m;
for(;i<=p;i++,j--)
{ t=*i; *i=*j; *j=t; }
}
main()
{ int i,a[10]={3,7,9,11,0,6,7,5,4,2};
inv(a,10);
printf("The array has been reverted:\n");
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("\n");
}实参用数组,形参用指针变量null例 将数组a中的n个整数按相反顺序存放 void inv(int *x, int n)
{ int t,*i,*j,*p,m=(n-1)/2;
i=x; j=x+n-1; p=x+m;
for(;i<=p;i++,j--)
{ t=*i; *i=*j; *j=t; }
}
main()
{ int i,a[10],*p=a;
for(i=0;i<10;i++,p++)
scanf("%d",p);
p=a; inv(p,10);
printf("The array has been reverted:\n");
for(p=a;py) z=x;
else z=y;
return(z);
}main()
{ int max(int ,int), (*p)();
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);
}
int max(int x,int y)
{ int z;
if(x>y) z=x;
else z=y;
return(z);
}null用函数指针变量作函数参数例 用函数指针变量作参数,求最大值、最小值和两数之和null10.6 返回指针值的函数
函数定义形式:
类型标识符 *函数名(参数表);
例 int *f(int x, int y)例 指针函数实现:有若干学生成绩,
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
输入学生序号后,
能输出其全部成绩main()
{ float score[][4]={{60,70,80,90},
{56,89,67,88},{34,78,90,66}};
float *search(float (*pointer)[4],int n), *p;
int i,m;
printf("Enter the number of student:");
scanf("%d",&m);
printf("The scores of No.%d are:\n",m);
p=search(score,m);
for(i=0;i<4;i++)
printf("%5.2f\t",*(p+i));
}
float *search(float (*pointer)[4], int n)
{ float *pt;
pt=*(pointer+n);
return(pt);
}null例 写一个函数,求两个int型变量中居于较大值的变量的地址2320022000**null例 写一个函数,求两个int型变量中居于较大值的变量的地址2002null例 写一个函数,求两个int型变量中居于较大值的变量的地址2332**null例 写一个函数,求两个int型变量中居于较大值的变量的地址不能返回形参或局部变量
的地址作函数返回值200Anull10.7 指针数组和多级指针
用于处理二维数组或多个字符串
指针数组
定义:数组中的元素为指针变量
定义形式:[存储类型] 数据类型 *数组名[数组长度说明];
例 int *p[4];指针所指向变量的数据类型指针本身的存储类型区分int *p[4]与int (*p)[4]指针数组赋值与初始化null指针数组赋值与初始化null char name[5][9]={“gain”,“much”,“stronger”, “point”,“bye”}; char *name[5]={“gain”,“much”,“stronger”, “point”,“bye”};二维数组与指针数组区别:二维数组存储空间固定
字符指针数组相当于可变列长的二维数组
分配内存单元=数组维数*2+各字符串长度指针数组元素的作用相当于二维数组的行名
但指针数组中元素是指针变量
二维数组的行名是地址常量nullmain()
{ int b[2][3],*pb[2];
int i,j;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
b[i][j]=(i+1)*(j+1);
pb[0]=b[0];
pb[1]=b[1];
for(i=0;i<2;i++)
for(j=0;j<3;j++,pb[i]++)
printf("b[%d][%d]:%2d\n",i,j,*pb[i]);
}例 用指针数组处理二维数组null例 对字符串排序(简单选择排序)main()
{ void sort(char *name[],int n), print(char *name[],int n);
char *name[]={"Follow me","BASIC",
"Great Wall","FORTRAN","Computer "};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n)
{ char *temp;
int i,j,k;
for(i=0;i0) k=j;
if(k!=i)
{ temp=name[i]; name[i]=name[k]; name[k]=temp;}
}
}i=0null例 对字符串排序(简单选择排序)main()
{ void sort(char *name[],int n), print(char *name[],int n);
char *name[]={"Follow me","BASIC",
"Great Wall","FORTRAN","Computer "};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n)
{ char *temp;
int i,j,k;
for(i=0;i0) k=j;
if(k!=i)
{ temp=name[i]; name[i]=name[k]; name[k]=temp;}
}
}name[0]name[1]name[2]name[3]name[4]nameGreat WallFORTRANComputerFollow meBASICi=1null例 对字符串排序(简单选择排序)main()
{ void sort(char *name[],int n), print(char *name[],int n);
char *name[]={"Follow me","BASIC",
"Great Wall","FORTRAN","Computer "};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n)
{ char *temp;
int i,j,k;
for(i=0;i0) k=j;
if(k!=i)
{ temp=name[i]; name[i]=name[k]; name[k]=temp;}
}
}name[0]name[1]name[2]name[3]name[4]nameGreat WallFORTRANComputerFollow meBASICi=2null例 对字符串排序(简单选择排序)main()
{ void sort(char *name[],int n), print(char *name[],int n);
char *name[]={"Follow me","BASIC",
"Great Wall","FORTRAN","Computer "};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n)
{ char *temp;
int i,j,k;
for(i=0;i0) k=j;
if(k!=i)
{ temp=name[i]; name[i]=name[k]; name[k]=temp;}
}
}name[0]name[1]name[2]name[3]name[4]nameGreat WallFORTRANComputerFollow meBASICi=3null例 对字符串排序(简单选择排序)main()
{ void sort(char *name[],int n), print(char *name[],int n);
char *name[]={"Follow me","BASIC",
"Great Wall","FORTRAN","Computer "};
int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[],int n)
{ char *temp;
int i,j,k;
for(i=0;i0) k=j;
if(k!=i)
{ temp=name[i]; name[i]=name[k]; name[k]=temp;}
}
}name[0]name[1]name[2]name[3]name[4]nameGreat WallFORTRANComputerFollow meBASICnull多级指针
定义: 指向指针的指针
一级指针:指针变量中存放目标变量的地址例 int **p1;
int *p2;
int i=3;
p2=&i;
p1=&p2;
**p1=5;二级指针:指针变量中存放一级指针变量的地址例 int *p;
int i=3;
p=&i;
*p=5;一级指针单级间接寻址二级指针一级指针目标变量二级间接寻址null定义形式:[存储类型] 数据类型 **指针名;
如 char **p;例 int i, **p;
p=&i; ()//p是二级指针,不能用变量地址为其赋值指针本身的存储类型最终目标变量的数据类型*p是p间接指向对象的地址
**p是p间接指向对象的值例 int i=3;
int *p1;
int **p2;
p1=&i;
p2=&p1;
**p=5;多级指针例 三级指针 int ***p;
四级指针 char ****p;null例 一级指针与二级指针#include
void swap(int *r,int *s)
{ int *t;
t=r;
r=s;
s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(p,q);
printf("%d,%d\n",*p,*q);
}200020022000null例 一级指针与二级指针#include
void swap(int *r,int *s)
{ int *t;
t=r;
r=s;
s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(p,q);
printf("%d,%d\n",*p,*q);
}输出: 1,2null例 一级指针与二级指针#include
void swap(int *r,int *s)
{ int *t;
t=r;
r=s;
s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(p,q);
printf("%d,%d\n",*p,*q);
}输出: 1,2null例 一级指针与二级指针#include
void swap(int **r,int **s)
{ int *t;
t=*r;
*r=*s;
*s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(&p,&q);
printf("%d,%d\n",*p,*q);
}200020022000null例 一级指针与二级指针#include
void swap(int **r,int **s)
{ int *t;
t=*r;
*r=*s;
*s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(&p,&q);
printf("%d,%d\n",*p,*q);
}20002002输出: 2,1null例 一级指针与二级指针#include
void swap(int **r,int **s)
{ int *t;
t=*r;
*r=*s;
*s=t;
}
main()
{ int a=1,b=2,*p,*q;
p=&a;
q=&b;
swap(&p,&q);
printf("%d,%d\n",*p,*q);
}输出: 2,1null例 用二级指针处理字符串#define NULL 0
void main()
{
char **p;
char *name[]={"hello","good","world","bye",""};
p=name+1;
printf("%o :