slide1
Download
Skip this Video
Download Presentation
第 10 章 指 针

Loading in 2 Seconds...

play fullscreen
1 / 43

第 10 章 指 针 - PowerPoint PPT Presentation


  • 167 Views
  • Uploaded on

第 10 章 指 针. 指针是C语言中的重要概念,也是C语言的重要特色。使用指针,可以使程序更加简洁、紧凑、高效。. §10.1 指针的概念. 一 . 内存单元的内容、内存单元地址 : 内存区域划分为一个一个的内存单元,一个内存单元 可以存放一字节数据,每一个内存单元都有一个地址。 例: int i=3 ; char j=‘s’;. 地址. 内存单元. 3. 2002 2004 3000. 2000 2001. 变量 i 变量 j. 编译时为变量 i 分配 2000 和 2001 两

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' 第 10 章 指 针' - julio


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
slide1
第10章 指 针

指针是C语言中的重要概念,也是C语言的重要特色。使用指针,可以使程序更加简洁、紧凑、高效。

slide2
§10.1 指针的概念
  • 一.内存单元的内容、内存单元地址:

内存区域划分为一个一个的内存单元,一个内存单元

可以存放一字节数据,每一个内存单元都有一个地址。

例:int i=3;

char j=‘s’;

地址

内存单元

3

2002

2004

3000

2000

2001

变量i

变量j

编译时为变量i分配2000和2001两

个字节的内存单元,为j分配2003

一个字节的内存单元

75

2003

通常把内存单元的地址称为指针.

2003

指针变量j-pointer

slide3
二.内存单元的访问:

j

  • 直接访问:通过变量名访问。

char j=‘s’;

printf(“%c”, j );

  • 间接访问:通过该变量的指针来访问。

p=&j;

  • 称:指针变量p指向变量j,是变量j的指针。

75

2000

p

j

75

2000

slide4
指针(pointer):是一个变量的地址,

是常量。

  • 指针变量:是指取值为地址的变量,其

值是另一个变量的地址。

  • 要引用指针,必须定义指针。
  • 定义指针,是为了通过指针访问内存单元。
  • 一个数组或函数占有一段连续内存单元,假如将一个数组或函数的首地址赋给指针变量,通过指针就可以找到数组或函数。
slide5
§10.2 变量的指针

一、指针变量的定义

类型标识符* 标识符

例如:int *cm

  • “标识符”是指针变量名
  • “*”表示定义指针变量
  • “类型标识符”表示该指针变量所指向的变量类型。
  • 指针是一个变量的地址,为了表示指针与它指向变量的地址之间的关系,用*表示指向.
slide6

a

2000

5

b

2002

...

...

p

3000

&a

2000

二、指针变量的引用
  • 未经赋值的指针变量不能用。
  • 指针变量只能赋予地址。

C语言提供两种相关地址运算符:

&: 取地址运算符

*: 取内容运算符

* \ &优先级相同.

例:int a=5,b;

int *p;

p=&a;

b=*p;

类型说明中的*表示

定义指针变量

p

a

表达式中的*是运算符

&a

5

slide7
三、指针变量的赋值:

/*整型变量a的地址赋给指针变量pa*/

/*指针变量p取得整型变量a的地址.*/

/*指针pa的值赋给指针pb*/

/*将数组的首地址赋给相同类型的指针*/

/*将字符串的首地址赋给指针变量*/

(1)、int a,*pa;

pa=&a;

(2)、int a=5,*p=&a;

(3)、int a,*pa=&a,*pb;

pb=pa;

(4)、int a[5],*pa;

pa=a;

(5)、char *pc;

pc=“c language”;

slide8
[例10.1]
  • main ()
  • { int a,b;
  • int *pointer_1, *pointer_2; /* 定义指针变量 */
  • a = 100; b = 10;
  • pointer_1 = &a;
  • pointer_2 = &b;
  • printf("%d,%d\n", a,b );
  • printf("%d,%d\n", *pointer_1,*pointer_2 );
  • }
  • 程序运行结果:

pointer-1

a

100

&a

100,10

100,10

b

pointer-2

10

&b

slide9

p1

a

[例10.2]输入a和b两个整数,按先大后小的顺序输出a和b。

See:9_2.c

main ()

{ int *p1, *p2, *p , a, b;

scanf("%d,%d",&a,&b);

p1 = &a; p2 = &b;

if (a < b)

{ p = p1; p1 = p2; p2 = p; }

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

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

}

运行:5,9

5

&a

p

&b

b

p2

9

&b

&a

a=5,b=9;

max=9,min=5

该例不交换变量a、b的值,而是交换指针p1、p2的值。

slide10
四、指针变量作为函数的参数

[例10.3]题目要求同[例10.2],输入a和b两个整数,按先大后小的顺序输出a和b。

swap( int* p1,int *p2 ) /*交换指针p1、p2所指向的变量的值 */

{ int p;

p = *p1; *p1 = *p2; *p2 = p;

}

main ()

{ int a, b;

int *pointer_1, *pointer_2;

scanf("%d,%d",&a,&b);

pointer_1 = &a; pointer_2 = &b;

if (a<b) swap(pointer_1, pointer_2) ;

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

}

把变量a和b的地址传送给形参

slide11

1

a[0]

pa

&a[0]

2

3

4

5

6

a[6]

7

§10.3 数组的指针
  • 指针可以指向数组和数组元素,对数组元素的访问:

既可以使用数组下标,也可以使用指针.

一、指向数组元素的指针变量

指向数组元素的指针变量,其类型应与数组元素相同.

例1: int a[7];

int *pa;

pa=&a[0];

或 pa=a;

例2: float b[10],*pb=b ;

或 float b[10],pb=&b[0];

slide12
二、通过指针引用数组元素

设:int a[10],*p=&a[0];

(1).p+1和a+1指向下一个元素a[1];

如果数组元素是整型,p+1表示p的地址加2;

如果数组元素是实型,p+1表示p的地址加4;

p+i和a+i指向元素a[i]。

(2).*(p+i)和*(a+i)访问元素a[i];

例: *(p+5)和*(a+5)与a[5]等效;

(3).指向数组指针可以带下标:

例: p[i]与*(p+i)等效.

slide13
[例10.5]输出数组的全部元素。(设10个元素,整型)。[例10.5]输出数组的全部元素。(设10个元素,整型)。
  • 访问各元素有三种方法:

1、下标法(常用,很直观)

main ()

{

int a[10];

int i;

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

scanf("%d", &a[i]);

printf("\n");

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

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

}

slide14
2、用数组名计算数组元素的地址。

(效率与下标法相同,常用)

main ()

{

int a[10];

int i;

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

scanf("%d", &a[i]);

printf("\n");

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

printf("%d ", *(a+i) );

}

特点:不移动指针

slide15
3、用指针访问各元素。(常用,效率高)

main () (see:9_5.c)

{

int a[10];

int *p , i;

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

scanf("%d", &a[i]);

printf("\n");

for( p=a ; p<(a+10) ; p++ )

/* p++使p指向下一个元素 */

printf("%d ", *p );

}

特点:移动执针

slide16

例:通过以下程序输出a数组中的10个元素。

main()

{

int a[10],*p,i;

p=a;

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

scanf("%d",p++);

printf("\n");

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

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

}

??请问大家:以上程序可以输出a数组中的10个元素吗?

slide17
三、数组名作函数参数1、形参和实参都用数组名三、数组名作函数参数1、形参和实参都用数组名

f( int arr[ ],int n)

{

}

例:main()

{int array[10];

f(array,10);

}

slide18

2、实参用数组名,形参用指针变量。

例:main()

{int array[10];

f(array,10);

}

f( int *arr,int n)

{

}

slide19

3、实参、形参都用指针变量。

例:main()

{int array[10],*p;

p=array;

f(p,10);

}

f( int *arr,int n)

{

}

slide20

4、实参用指针变量,形参用数组名 。

例:main()

{int array[10],*p;

p=array;

f(p,10);

}

f( int arr[ ],int n)

{

}

slide21
实际上,c编译系统将形参数组名作为指针变量处理.实际上,c编译系统将形参数组名作为指针变量处理.

若有定义 :f(int arr[ ],int n)

编译后:f(int *arr,int n)

slide22
§10.4 字符串的指针

一、字符串的表现形式

C语言中,有两种方式可以实现字符串:

字符数组、字符指针。

[例10.16]:字符数组

main()

{ char string[ ] ={"I love China!”};

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

}

用字符串对字符数组赋值

string是数组名,代表字符数组的首地址。

数组可以用下标访问,也可以用指针访问

slide23

Mary

Hare

name1

name2

name1是一个指针变量

[例10.17]字符指针

main()

{ char *name1 =”Mary";

char *name2=“Hare”;

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

}

char *name1 =“Mary”;等价于:

char * name1;

name1 = ”Mary";

它把字符串常量的首地址赋给指针name1.

slide24

数组a

a

数组b

I

b

a

m

a

b

o

y

.

\0

用数组名计算数组元素的地址

[例10.18]将字符串a复制到字符串b。

main ()

{ char a[ ] = "I am a boy.";

char b[20];

int i;

for (i=0; *(a+i) !=\'\0\'; i++)

*(b+i) = *(a+i);

*(b+i) = \'\0\';

printf("string a is: %s\n",a);

printf("string b is:");

for (i=0; b[i] !=\'\0\'; i++)

printf("%c",b[i]);

printf("\n");

}

特点:不移动指针

slide25

p1

数组a

p2

数组b

I

a

m

a

b

o

y

.

\0

特点:移动执针

[例10.19]:用指针处理字串复制.

main ()

{ char a[ ] = "I am a boy.",b[20],*p1,*p2;

int i;

p1=a;p2=b;

for ( ; *p1 !=\'\0\'; p1++,p2++)

*p2 = *p1;

*p2 = \'\0\';

printf("string a is: %s\n",a);

printf("string b is:");

for (i=0; b[i] !=\'\0\'; i++)

printf("%c",b[i]);

printf("\n");

}

I

a

m

a

b

o

y

.

\0

slide26
例10.21:
  • main()
  • { char *a=“I love china!”;
  • a=a+7;
  • printf(“%s”,a);
  • }
  • 运行结果如下:
  • China!

(a+7)是用指针指向数组元素a[i]的第7个字符

slide27
§10.5 函数指针

一、用函数指针变量调用函数

  • 函数指针定义的一般形式:

函数返回值类型(*指针变量名)( )

例: int (*p) ( )

  • 说明:(*p)( )表示定义一个指向函数的指针变量,它不固定指向哪一个函数,它是专门用来存放函数的入口地址的,该函数返回一个整型值.。
  • C规定:函数的名称就是函数的入口地址
slide28
[例9.23]求a和b中的大者。

用函数名调用函数max()

  • int max(int x, int y); /*原型*/
  • {int z;
  • if (x>y) z = x;
  • else z = y;
  • return z;
  • }
  • main ()
  • {int a,b,c;
  • scanf("%d,%d", &a, &b);
  • c = max(a, b);
  • printf("a=%d,b=%d,max=%d",a,b,c);
  • }
slide29
用函数指针调用函数max()
  • int max(int x, int y) /*原型*/
  • {int z;
  • if (x>y) z = x;
  • else z = y;
  • return z;}
  • main ()
  • { int (*p) ( );/*定义函数指针p */
  • int a,b,c;
  • p = max; /*函数max的入口地址赋给函数指针p*/
  • scanf("%d,%d", &a, &b);
  • c = (*p)(a,b); /*用函数指针p调用函数 */
  • printf("a=%d,b=%d,max=%d",a,b,c);}

用函数指针变量调用函数时,只须将(*p)代替函数名max,并加上实参

slide30
§10.6 返回指针的函数(自学)

一般形式:

类型标识符 * 函数名(参数表)

例、int * a (int x, int y)

  • 声明一个函数,函数名为a,其返回值类型是“指向整型的指针”,
  • 函数形式参数为int x 和 int y。

注意:在a的两侧分别为*运算符和( )运算符,a先与( )结合,这是函数形式;函数前有个*号,表示该函数为指针型函数.

slide31
§10.7 指针数组和指向指针的指针(自学)

一、指针数组

概念:指针数组是一个数组,该数组中的

每一个元素是指针变量。

形式:类型标识符 *数组名[数组元素个数]

例: int * p[4];

定义一个指针数组,数组名p,有4个元素, 每一个元素是指向整型变量的指针。

slide32

p

name[0]

name[1]

name[2]

Ann

Hare

Jack

二、指向指针的指针

定义举例:

char * * p;

char *name[]={“Ann”,“Hare”,“Jack”};

p=name;

p是一个指向指针的指针.被p指向的指针指向字符变量。

name指针数组

二维字符数组

slide33

p

name[0]

name[1]

name[2]

Ann

Hare

Jack

  • main()
  • {int i;
  • char *name[]={"Ann","Hare","Jack","Mary"};
  • /* storage address of per string*/
  • char **p;
  • printf("\n Students\'s names are:\n");
  • for(i=0;i<4;i++)
  • { p=name+i;/*point into address of next char string */
  • printf("%6s\t",*p); }
  • }
  • 运行结果:
  • Ann Hare Jack Mary

name指针数组

二维字符数组

name[3]

mary

slide34
§10.8 指针使用小结

一、有关指针的数据类型

定义:

  • int i;定义整型变量i
  • int *p; p是指向整型数据的指针变量
  • int a[n];定义数组a,元素类型为int,元素个数是n
  • int *p[n];p是指针数组,包含n个指针,每一个指针可以指向整型数据
  • int f( ); f是函数,返回值是int
  • int (*p)( ); p是函数指针,所指向的函数返回整型数据
  • int *p( );p是函数,返回值是指针,该指针指向整型数据
  • int **p; p是指针,指向一个指向整型数据的指针
slide35
二、指针运算小结

1、指针变量加/减运算

  • p++、p--、p+i、p-i、p+=i、p-=i

加1表示指向下一个数据。

2、指针变量赋值

  • p = &a; 变量a的地址赋给p,即指针p指向a
  • p = array; 数组array首地址赋给p
  • p = &array[i]; 数组元素array[i]的地址赋给p
  • p = max; 函数max的入口地址赋给p
  • p1 = p2; 指针p2的值赋给指针p1,

即p1、p2所指的数据相同

  • p=NULL; 指针变量可以由空值,NULL的值为0
slide36
3、空指针 p = NULL
  • 空指针p=NULL表示p不指向任何数据。
  • 在stdio.h中,NULL被定义为0:
  • #define NULL 0

习惯上,不使用 p = 0而使用 p = NULL

  • 指针变量p可以与NULL作比较,

例:if (p = = NULL) ...

注意:空指针不指向任何数据,与p未赋值不同。

当p未赋值时,其值是不确定的,而空指针

的值是确定数0。

slide37
4、指针变量相减。
  • 当p1、p2指向同一个数组的元素,指针相减p2-p1等于p1、p2间的元素个数。
  • 注意:指针相加无意义。

5、两个指针的比较

  • 当p1、p2指向同一个数组的元素时,可以比较,如、p1 > p2。若p1、p2不是指向同一个数组的元素,比较无意义。
slide38
三、空类型指针 void *
  • void *p,表示p是空类型指针,它可以指向任何数据类型。
  • 空类型指针与其他类型指针之间赋值时,应进行强制类型转换.

例、 char *p1;

void *p2;

p1 = (char *)p2;

p2 = (void *)p1;

slide39
第10 章 习 题

10.1 指针变量a所指的字符串长度为,

这个长度是可以用strlen(a)测出来的。

char *a=“\nMY Name is\”zhang li\”.\n”;

(1)28 (2) 27 (3) 26 (4) 24 (5)23

10.2 下面程序的作用是,将两个变量中的值互换,

请检查程序是否正确,如不正确的,改正之。

main ( )

{int a=3,b=4;

int *p1,*p2,*p;

p1=&a,p2=&b;

p=p1;p1=p2;p2=p;

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

}

*p1,*p2

slide40
10.3 已设p1和p2为指针变量,且已指向同一个整

型数组中的元素,a是一个整型变量,问下面

哪一个语句不能正确执行?

(1) a=*p1 (2) a=*p1+*p2

(3) a=*p1-*p2 (4)p1=a-p2

10.4 有一个二维数组a[3,4],2行3列元素的正确表

示方法为。

(1) &a[2][3] (2)a[2]+3

(3) *(a+2)+3 (4)*(a[2]+3)

10.5 下列程序的输出结果是 A)44 B)22 C)24 D)结果错误

main()

{int a[5]={2,4,6,8,10},*p,**k;

p=a;k=&p;

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

printf("%d\n",**k);

}

slide41
10.6 若有语句:int a=4,*p=&a;

下面均代表地址的一组选项是:

1) a,p,&*a 2) *&a,&a,*p

3) &a,p,&*p 4) *&p,*p,&a

10.7 以下程序段的输出结果为:

char a[]=“Program”,*ptr;

ptr =a;

for ( ;ptr<a+7;ptr+=2)putchar(*ptr);

1) Program 2) Porm

3) 有语法错误; 4) Por

slide42
10.8下面说明不正确的是:

1) int *a[4]; 2) float (*p)();

2) int **p; 4) char *(*a)[];

slide43
作业

10.1 10.2 10.6 10.11

  • 上机实验

学生成绩管理(使用指针):

1.学生姓名与成绩录入;

2.求学生平均成绩并输出;

3.将不及格的学生姓名与成绩输出;

4.按从高到低成绩排序并输出.

ad