第
This presentation is the property of its rightful owner.
Sponsored Links
1 / 39

第 8 章 指 针 PowerPoint PPT Presentation


  • 93 Views
  • Uploaded on
  • Presentation posted in: General

第 8 章 指 针. 8.1 指针的基本概念 8.2 指针和指针变量 8.3 一维数组和指针 8.4 指针数组 8.5 指针与函数 8.6 指针的指针 8.7 指针 与二维数组 8.8 main() 函数的参数. 第 8 章 指针. 8.1 指针的基本概念. 指针就是地址,是一种数据类型。 它是用来表示另外变量的地址。 “直接访问”方式:按变量地址直接对变量的值进行存取。

Download Presentation

第 8 章 指 针

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


8

第8章 指 针

  • 8.1 指针的基本概念

  • 8.2 指针和指针变量

  • 8.3 一维数组和指针

  • 8.4指针数组

  • 8.5 指针与函数

  • 8.6 指针的指针

  • 8.7 指针与二维数组

  • 8.8 main()函数的参数


8

第8章 指针

8.1 指针的基本概念

指针就是地址,是一种数据类型。它是用来表示另外变量的地址。

“直接访问”方式:按变量地址直接对变量的值进行存取。

“间接访问”方式:在访问变量时,不直接按变量的地址取其值,而将变量的地址存放在另一个存储单元中,要访问某变量时,先访问存放该变量地址的存储单元,再间接地访问变量,对变量进行存取操作。

返回章目录


8

第8章 指针

8.2 指针和指针变量

可以用运算符“*”来定义指针变量,也可以用“*”表示“指向”关系来使用指针变量。

8.2.1 指针变量的定义

指针变量是专门用于存放地址的变量,C语言将它定义为“指针类型”。定义指针变量的一般格式为:类型标识符 * 指针变量名

例如: int * p ;

我们说:p 是指向整型数据的指针,p的值是整型变量的地址。


8

第8章 指针

8.2.2 指针变量的赋值

与指针有关的运算符有两个:

运算符“&”:求变量的地址;*求指针所指变量的值。

可以用赋值语句使一个指针变量指向一个变量,例如: int i,j,*p1;

p1=&i ; j = *p1;

也可以在定义指针变量的同时对其赋值,例如:

int i=3 , *p1=&i ;

int *p1=&i 相当于:int *p1;

p1 = &i;


8

第8章 指针

指针变量的赋值

(1)指针变量定义和赋值注意:

例如: int i,*p, *p1=&i;

*p=i ; 或 *p = *p1; 危险动作!,不知p指向那里,不能它赋值

应该:int *p, j;

p=0; 或p=‘\0’; 或 p=NULL 或 p=&j;

然后,*p=i; 先让它指到一个“安全”地带,再给它赋与内容

(除0以处,不能把非地址整型值赋给指针)

(2)指针变量互相赋值:

int i=3 , *p1,*p2 ;

p1=&i; p2 = p1;

使指针变量p2指向p1所指变量, p1,p2同时指向i变量。


8

第8章 指针

x

d

d

例:指针运算符

void main( )

{ int d,x,*p,*q;

d=5;p=&d;

x=*p;

printf("x=%d\n",x);

*p=7;

printf(“d=%d\n",d);

q=p;

printf(“*q=%d\n",*q);

}

q

q

p


8

第8章 指针

*和&是互逆运算。

已知:int a,*p;

p=&a;

请考虑:

*&a 与 a的关系

*&p 与 &*p 与p的关系

指针运算符:

“*”和“&”优先级相同,自右向左运算。 “&”只能用于变量和数组元素。

void main( )

{ int d,p;

d=4;

p=*&d;

printf("p=%d\n",p);

}


8

第8章 指针

8.2.3 指针变量的引用

可以通过指针运算符“*”引用指针变量,指针运算符可以理解“指向”的含义。

例:交换指针还是交换所指变量?

void main( )

{ int a=10,b=8,t,*p1,*p2,*pt;

p1=&a;p2=&b;

t=*p1;*p1=*p2;*p2=t;

printf ("a =%d,b=%d\n",a,b);

a=10; b=8; /*归位*/

pt=p1;p1=p2;p2=pt;

printf("a=%d,b=%d\n",a,b);

}


8

第8章 指针

8.2.4 指针变量作为函数参数

函数的参数是一般变量或常数时,函数实参向形参是单向值传递。

函数的参数是数组名时,则将实参数组名传递给形参数组名,数组名表示数组中第1个元素的地址,故这种传递是地址的传递。

函数参数也可以是指针变量,其作用是将变量的地址传到另一函数中去。

返回章目录


8

第8章 指针

指针变量作函数参数示例1:使函数返回多个值

void main( )

{int a=10,b=8;

f(&a, &b); printf("a=%d,b=%d\n",a,b);

}

void f(int *x, int *y) /*函数f的功能是什么?*/

{ *x=*x*2;*y=*y*2;

}“遥控”作用。

x和y说:你只要让我指向你,我通过改变我指的内容,就能改变你!(类似文件副本与快捷方式)


8

第8章 指针

指针变量作函数参数示例2:

完善求一元二次方程根的函数getroot

void main( )

{int a=3,b=8,c=2;

float x1,x2;

getroot(a, b,c,&x1,&x2);

printf(“x1=%f,x2=%f\n",x1,x2);

}

void getroot(int a,int b,int c,float *root1, float *root2)

{ 补充内容;

}


8

第8章 指针

指针变量作函数参数示例3:交换两个整数

void main( )

{int a=10,b=8;

swap(&a,&b);

printf(“%d,%d”,a,b)

}

void main( )

{int a=10,b=8;

swap(a,b);

printf(“%d,%d”,a,b)

}

void swap(int *x,int *y)

{int t; /*用int *t行吗 */

t=*x;*x=*y;*y=t;

}能交换

void swap(int x,int y)

{int t;

t=x;x=y;y=t;

}

不能交换

void swap(int *x,int *y)

{int *t;

t=x; x=y; y=t;

}不能交换

void swap(int *x,int *y)

{int *t,q;t=&q;

*t=*x;*x=*y;*y=*t;

}能交换


8

第8章 指针

8.3 一维数组和指针

8.3.1 一维数组与指针

指针可以指向数组或数组元素.

一维数组中,第1个元素如a[0]的地址,即该数组的起始地址。可以用数组名方式,通过指向运算符“*”引用数组元素,也可以将指针变量指向一维数组,通过指针变量引用数组元素。例如:

int a[10] , *p ; /* 定义a数组和指针变量p */

p=a ; /* a数组首地址→p */

或p=&a[0] 使p指向了数组 a


8

第8章 指针

一维数组和指针示例

p+i是 a[i]的地址 ;

*(p+i)是a[i]的值 .

void main( )

{int *p1,*p2,*p3;

static int a[ ]={1,2,3,4,5};

p1=a;p2=&a[2];

p3=p2+2;

printf("a[ ]=%d\n",p1);

printf("%d:%d\n",p2,*p2);

printf("%d:%d\n",p3,*p3);

}

结果:

a[ ]=2003

2007:3

2011:5


8

第8章 指针

数组名常指针法:

void main()

{int a[]={1,2,3,4,5};

int i;

for(i=0;i<5;i++)

printf("%d\t",

*(a+i));

} 不能使用a++

指向数组的指针作为函数参数示例:下标法

void main()

{int a[]={1,2,3,4,5};

int i;

for(i=0;i<5;i++)

printf("%d\t",a[i]);

}


8

第8章 指针

两指针:

void main()

{int a[]={1,2,3,4,5};

int i,*p=a,*q=a+4;

for(;p<=q;p++)

printf("%d\t",*p);

}

指针变量指向数组访问法:

void main()

{int a[]={1,2,3,4,5};

int i,*p=a;

for(i=0;i<5;i++,p++)

printf("%d\t",*p);

}


8

第8章 指针

8.3.2 指向数组的指针作为函数参数

数组名作为函数参数,实现函数间地址的传递。指向数组的指针也可以作为函数参数,数组名和指针都是地址。在作为函数参数时有以下几种情况:

实参 形参

数组名 数组名

指针变量 指针变量

在实参向形参传递中,应保证其类型的一致性。

返回章目录


8

第8章 指针

形参,实参均为数组名:

void inv(int x[],int n)

{int t;

int i,j;

for(i=0;i<(n-1)/2;i++)

{j=n-1-i;/*后边的下标*/

t=x[i];x[i]=x[j];x[j]=t;

}

}P237

数组名或指针作为函数形参与实参示例:逆置元素

void main()

{int a[]={1,2,3,4,5};

int inv(int x[],int 5);

inv(a,5);

for(i=0;i<5;i++)

printf("%d\t",a[i]);

}


8

第8章 指针

形参指针,实参数组名:

void inv(int *x,int n)

{int *i,*p,*j;

int t,m=(n-1)/2;

i=x;j=x+n-1;p=x+m

for(;i<=p;i++,j--)

{t=*i;*i=*j;*j=t;

} /*i左p终j右*/

}P238

数组名或指针作为函数形参与实参示例:逆置元素

void main()

{int a[]={1,2,3,4,5};

int inv(int x[],int n);

inv(a,5);

for(i=0;i<5;i++)

printf("%d\t",a[i]);

}与前同


8

第8章 指针

8.3.3 指针与字符串

C语言中,一个字符串可以存放在一个字符数组中,数组名表示该字符串第一个字符存放的 地址,也可以将字符串的首地址赋给一个字符型指针变量中,该指针变量便指向这个字符串,或者说,指针变量可以指向任一字符串的首地址。

例如:

char *str="I love China" ;

或 char *str ; str="I love China" ;

char str[]= ="I love China" ; 可以

char str[20]; str[20]="I love China" ; 不可以


8

第8章 指针

main( )

{static char *p,s[ ]=" abcdef\n ";

p=s;

printf("%s\n",p);

while(*p!=‘\0’)

{printf("%c",*p++);}

}

指向字符数组示例:

打印字符串

main( )

{static char s[ ]=" abcdef\n ";

printf("%s\n",s);

}

main( )

{char *s=" abcdef\n ";

printf("%s\n",s);

}

注意:

char s[ ]

char *s


8

第8章 指针

指针与字符串例:字符串复制

void str_cpy(char *s,char *t) /*char s[],char t[]*/

{while(*t!=0) /*while(*t)*/

{*s=*t;s++;t++;} /* *(s++)=*(t++) */

*s='\0';

}

void main()

{char *str2;char str1[80];

str2=“welcome“;

str_cpy(str1,str2);

puts(str1);

}


8

第8章 指针

8. 4 指针数组

由指针构成的数组。定义形式为:

类型标识符 *指针变量名[ ] ;

例如: char *p[ 13] ;

p是一个有13个元素的数组,每个元素都是指向char类型的指针。

*p[i]可存取一个字符;

p[i]可存取一个字符串。

当处理长度不等的字符串时,数组指针很方便。

返回章目录


8

第8章 指针

指针数组例1

#include <stdio.h>

void main( )

{int i;

int a=10, b=8;

int *p1=&a,*p2=&b;

int *x[2];

x[0]=p1,x[1]=p2;

printf("*x[0]=%d\n",*x[0]);

printf("*x[1]=%d\n",*x[1]);

}把一群指针纳入数组进行管理

返回章目录


8

第8章 指针

指针数组例2

void main( )

{int i;

int a[]={1,2,3}; int b[]={3,4,5}};

int *p[2]; /*p 是数组,元素是指针*/

p[0]=a;p[1]=b;

printf("%d,%d,%d\n",*p[0],*(p[0]+1),*(p[0]+2));

printf("%d,%d,%d\n",*p[1],*(p[1]+1),*(p[1]+2));

}

返回章目录


8

第8章 指针

指针数组例3

void main( )

{int n; char *day-name( );

scanf(“%d”,&n);

printf(“%d day:%s\n”,n,day-name(n));

}

char *day-name(int n)

{char *name[ ]={“illegal day”,”Mon”,”Tues”,”Wen”,”Thurs”,

”Friday”,”Sat”,”Sun”};

return((n<1|n>7)?name[0]:name[n]);|

}函数返回一个指向包含第N天名字的字符串的指针。

name指针数组存储字符串列表。各串不等,由系统计数。


8

第8章 指针

指针数组例4

while(n--)

{

printf("%s",digt[x[n]]);

printf("%s",dw[n]);

}

}

#include <stdio.h>

void main() /*整数人民币转换,不完善*/

{

char *digt[]={" ","一","二","三","四","五","六","七","八","九"};

char *dw[]={"元","十","百","千","万"};

int m;

int n=0,x[5];

scanf("%d",&m);

while(m!=0)

{

x[n]=m%10; /*printf("%d\t",x[n]); */

m=m/10;

n++;

}


8

第8章 指针

8.5 指针与函数

8.5.1 指向函数的指针

指向函数的指针叫做函数指针。一个函数在编译时被分配给一个入口地址,这个入口地址称为函数的指针。可以定义一个指向函数的指针变量,将函数入口地址赋予指针变量,然后通过指针变量调用此函数。

指向函数的指针变量定义形式为:

类型标识符 (*指针变量名)( ) ;

函数返回值的类型

例如: int (*p)( ) ;

P表示一个指向函数的指针,P指向的函数返回整型数据。

返回章目录


8

第8章 指针

而 int *p( ) ;

表示p是一个函数,返回整型指针的函数。前者是指针,后者是函数。函数指针可用来传递函数。

void main( )

{int (*pi)( int x);

int prnx(int x);

pi=prnx; /*不加 ( )*/;

(*pi)(123);

}

prnx(int x )

{

printf("%d\n",x);

}

返回章目录


8

第8章 指针

例2: 由用户指定分别求x2-2和 x3-2x+5的值

double f1(double x )

{return (x*x-2);}

double f2(double x )

{ return (x*x*x-2*x+5);

}

void main( )

{int i;double x;

double (*fp)(double);

scanf("%d%lf",&i,&x);

if(i==1) fp=f1;

else fp=f2;

printf("f(x)=%lf ",(*fp)(x));

}


8 5 2

第8章 指针

8.5.2 返回指针的函数

例:

#include <stdio.h>

void main( )

{int i;

int *p;

int *f(int x,int y);

p=f(10,8);

printf("max=%d\n",*p);

}

int *f(int x,int y)

{

int *q;

if(x>y)

q=&x;

else

q=&y;

return(q);

}


8

第8章 指针

8.6 指针的指针称二级指针。即一个指针存放另一指针的地址。

例:

#include <stdio.h>

void main()

{

int a=3;

int *p1=&a;

int **pp;

pp=&p1;

printf("**p=%d\n",**pp);

printf("*p1=%d\n",*p1);

}


8

第8章 指针

8.7 指针与二维数组

二维数组中:

a+i,a[i],*(a+i),&a[i],&a[i][0]

它们都表示地址,且地址值是相等的,但指针类型不同。

a+i和&a[i]指向行,表示第i行首地址;

a[i]和*(a+i)用于指向列,表示第i行第0列元素地址。

a[i]+j和*(a+i)+j表示第i行第j列元素地址,见表8-1。


8

第i行j列元素地址

第i行j列元素值

a[i]+j

*(a[i]+j)

*(a+i)+j

*(*(a+i)+j)

&a[i][j]

a[i][j]

第8章 指针

表8-1 第i行第j列元素地址及其元素值


8

第8章 指针

指针与二维 数组例:

#include <stdio.h>

void main()

{int a[2][3]={{1,2,3},{4,5,6}};

int *p=a;

printf("a=%d,a[0]=%d,&a[0]=%d,p=%d\n",a,a[0],&a[0],p);

printf("*a=%d,**a=%d,*a[0]=%d,*p=%d\n",*a,**a,*a[0],*p);

printf("a[1]=%d,a+1=%d\n",a[1],a+1);

printf("*a[1]=%d,*(a+1)=%d\n",*a[1],*(a+1));

printf("a[0]+1=%d,p+1=%d\n",a[0]+1,p+1);

printf("*(a[0]+1)=%d,*(p+1))=%d\n",*(a[0]+1),*(p+1));

printf("*(p+5)=%d,*(*(a+1)+1))=%d\n",*(p+5),*(*(a+1)+1));

}


8

第8章 指针

说明:

a指向第0行首址,即&a[0]

a+1指向第1行首址,即&a[1]

a+i指向第i行首址,即&a[i]

*a指向0行0列首址a[0][0]

*(a+1)指向1行0列a[1][0]

*(a+i)指向i行0列a[i][0]

*(a+i)+j,a[i]+j指向a[i][j]

*(*(a+i)+j),*(a[i]+j)即a[i][j]

从值上看:a 和*a, a+1和*(a+1)相等。

但a+1 与 *a+1不同。前者走1行,后者走1列。

上例中,a指针加1跨度大,p和a[i]跨度小


8 8 main

第8章 指针

8. 8 main()函数的参数

main(int agrc,char *argv[ ])

argc是整型数,表示命令行参数个数,命令名为第一个参数,故 argc至少为1。

argv是指向命令行参数(含命令名)字符串的指针数组。argv[0], argv[1], argv[2]分别指命令名,第2参数,第3参数.

例:

void main(int agrc,char *argv[ ] )

{int i;

for(i=1;i<argc;i++)

printf(“%s%c”,argv[i], (i<agrc-1)? ’ ‘ : ’\n’ );

}


8

第8章 指针

main()函数的参数

例:

void main(int agrc,char *argv[ ])

{int i,n;

n=agrc;

for(i=0;i<n;i++)

printf(“%s”,argv[i] );

}

返回章目录


8

第8章 指针

指针小结

定义 意义

int i; 整型变量

int *p; 指向整型数据的指针

int *p[n]; 由n个指向整型数据的指针组成的指针数组

int (*p)[n]; 指向n个整型数据的数组的指针

int p( ); 返回整型数据的函数

int *p( ); 返回整型指针的函数

int (*p)( ); 指向整型函数的指针(函数指针)


  • Login