1 / 24

第 8 章 指针

第 8 章 指针. 8.1 指针的概念 8.2 指向简单变量的指针 8.3 指向数组的指针变量 8.4 指向字符串的指针变量 8.5 指针作为函数参数 8.6 指向结构体的指针变量 8.7 应用实例 本章小结. 8.1 指针的概念. 指针,也就是内存地址。 指针变量是用来存放这些内存地址的变量。 不同类型指针变量所占用的存储单元长度是相同的 . 直接访问方式 : 根据变量名实现对存储空间的访问。 间接访问方式 : 通过存放地址的 指针 变量实现对存储空间的访问。.

Télécharger la présentation

第 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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第8章 指针

  2. 8.1 指针的概念 8.2 指向简单变量的指针 8.3 指向数组的指针变量 8.4 指向字符串的指针变量 8.5 指针作为函数参数 8.6 指向结构体的指针变量 8.7 应用实例 本章小结

  3. 8.1 指针的概念 • 指针,也就是内存地址。 • 指针变量是用来存放这些内存地址的变量。 • 不同类型指针变量所占用的存储单元长度是相同的. • 直接访问方式:根据变量名实现对存储空间的访问。 • 间接访问方式:通过存放地址的指针变量实现对存储空间的访问。

  4. 如果将变量x的地址2060存放到另一个变量p中,即p的值为2060,这样通过变量p可以找到变量x的地址,从而找到 x 的值。存放地址的变量p就是指针变量。可以形象地说,p指向x。

  5. "*" 是指针运算符,或称为“间接访问”运算符。*p表示指针变量p所指向的变量。若要改变x变量的值,也可通过改变 *p的值来实现。如执行 *p = 47;则此时x=47。 • "&" 也是一个指针运算符,称为取地址运算符。如为了让指针p指向变量x,可执行p = &x,此时变量x的地址即存入了指针p中。 • 注意,指针变量只能存放地址值,不要将一个整型数据赋给一个指针变量。

  6. 8.2 指向简单变量的指针 • 指针变量也必须先定义后使用。 • 格式如下: 类型标识符 * 指针变量名; 例如: int *p1, p2; 则p1是指针变量,而p2是整型变量。

  7. 例8-1:通过指针变量访问变量。 main( ) {int a, b, *p1, *p2; float x, y, *q1, *q2; a=123; b=45; x=1.25; y=-0.98; p1=&a; p2=&b; q1=&x; q2=q1; printf("\na=%d, b=%d\n", a, b ); printf("*p1=%d, *p2=%d\n", *p1, *p2 ); printf("x=%f, y=%f\n", x, y ); printf("*q1=%f, *q2=%f\n", *q1, *q2 ); }

  8. 8.3 指向数组的指针变量 • 任何可通过数组下标完成的操作也可通过指针完成。 • 然而它们之间也存在细微但很重要的区别。一般来讲,使用指针速度更快,程序更紧凑。

  9. 8。3。1 指向一维数组的指针变量 • 指针变量可以指向数组或数组元素,即把数组的起始地址或某一元素的地址存放到一个指针变量中。例如:定义指针p指向一维整型数组a[5]。可进行如下说明: int a [5]; int *p; • 注意,不能定义成 int *p[5]; • 如果这样定义,就表示定义了一个指针数组。它有5个元素,p[0]、p[1]、p[2]、p[3]、p[4],每个元素都指向整型变量。

  10. 如果数组为int型,则指针变量亦应指向int型。 执行语句: p = a ; 或 p = &a[0]; 均可以使指针p 指向数组a的第1个元素a[0]。 C语言规定,数组名代表数组的首地址,也就是第一个元素的地址。此外,p+1指向下一个元素,p+i 指向p后的第i个元素 a[i]。 无论某个数组的元素占据多少内存字节( 即元素长度,设为len ),当指针p指向其中一个元素时,p+1均是指向它的下一个元素,而不是p+len。 可见,a[i], *(a+i), *(p+i) 都是等价的。

  11. 例8-2:用三种方法输出数组元素。 main ( ) { static int a[5]={5, 4, 3, 2, 1 }; int i, *p = a; for ( i = 0; i < 5; i++ ) printf (" %d, %d, %d \n ", a[i], *(a+i), *(p+i ) ); } 运行结果: 5, 5, 5 4, 4, 4 3, 3, 3 2, 2, 2 1, 1, 1

  12. 例8-3:输出数组的所有元素。 main ( ) { int a[5], *p, i ; for ( i = 0; i < 5; i++ ) scanf ("%d", a + i ); for ( p = a; p < a+5; p++ ) printf ("%4d ", *p ); } 运行结果: 1 3 5 7 9↙ 1 3 5 7 9 说明:指针变量和数组名有区别,指针变量是一个变量,可以改变其值,而数组名是数组首地址,是一个地址常量,不能对它赋值。

  13. 8。3。2 指向多维数组的指针变量 • C 语言将二维数组定义时的行数和列数分别用两个方括号分开,如 int a[4][3];,目的是把二维数组看作是一种特殊的一维数组,它的元素又是一个一维数组。 • 如,把a看作是由四个元素a[0]、a[1]、a[2]、a[3] 组成的一维数组,而每个元素a[i]( i=0,1,2,3 ),又都是具有3个元素的一维数组。

  14. 例8-5:输出数组int a[4][3] 中的第3行的所有元素。 main ( ) { static int a[4 ][3]= {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}; int *p; for ( p = a[2 ]; p < a[2]+3; p++) printf ("%4d", *p ); } 运行结果: 7 8 9

  15. 例8-8:用指针输出二维数组的各元素。 #include <stdio.h> #define M 4 #define N 3 #define L M*N main ( ) { int a[M][N], *p=a[0], i; for ( ; p < a[0]+L; p++ ) /* 从键盘上输入L个数据 */ scanf ( "%d", p ); for ( i = 0; i < M; i++ ) { p = a[i]; /* 取第i行的首地址 */ for( ; p < a[i] + N; p++ ) /* 输出第i行的n个元素 */ printf ("%5d", *p ) ; printf ( "\n" ); /* 换行 */ } }

  16. 8.4 指向字符串的指针变量 • 在C语言中,字符串可以用字符数组实现。其实,字符串还可以用字符指针实现,而且字符指针更方便、简洁。 • 例如: char string[ ] = "this is a string!"; char *pstr = "that is a book!";

  17. 例8-10:编写字符串复制函数strcpy (s1, s2 )。 • 用数组方法 void strcpy ( char s1[ ],char s2[ ] ) { int i = 0; while ( s2[i] != '\0' ) { s1[i] = s2[i]; i++; } s1[i]=0; /* 补上串结尾符 */ }

  18. 用指针方法 void strcpy ( char *p,char *q ) { while ( *q != '\0' ) { *p = *q; p++; q++; } *p=0; /* 补上串结尾符 */ }

  19. 例8-12:分别用字符指针和字符数组表示字符串。例8-12:分别用字符指针和字符数组表示字符串。 #include <stdio.h> main( ) { char s1[5], s2[8], *p; p=s2; scanf("%s %s", s1, p ); puts(s1); puts(p); } 运行上述程序: qwe iop↙ qwe iop

  20. 例8-13:改变数组指针的程序。 #include <stdio.h> main( ) { char *p = "money order"; p = p+6; printf("%s \n", p); } 运行结果: order

  21. 8.5 指针作为函数参数 例8-15:输入两个整数a, b,从大到小输出。 main( ) { int a, b; scanf("%d %d", &a, &b ); if ( a < b ) swap (&a, &b ); printf("%d %d \n", a, b ); } swap( int *q1, int *q2 ) { int tmp = *q1; *q1 = *q2; *q2 = tmp; }

  22. 8.6 指向结构体的指针变量 以下3 种形式等价: ① s.xh ② (*p).xh ③ p -> xh #include <stdio.h> struct student { char xh[3], xm[7]; int cj; }; main( ) { struct student *p, s; p = &s; /* 将结构体变量s 的起始地址存入指针p中 */ scanf("%s%s%d", (*p).xh, (*p).xm, &s.cj ); /* 可通过指针p对s的域赋值 */ printf("%s,%s,%d", p->xh, p->xm, p->cj ); /* 通过指针p输出s的内容 */ } 运行: 30 wang 79↙ 30, wang,79

  23. 8.7 应用实例 • 例8-20:将数组b 中n个整数按相反顺序存放。 invert1 ( int b[ ], int n ) /*用数组实现*/ { int tmp, i, j, m = n / 2; i = 0; j = n -1; for ( ; i < m; i++, j-- ) { tmp = b[i]; b[i] = b[j]; b[j] = tmp; } } invert2 ( int *p, int n ) {int tmp, *i, *j; i = p; j = p + n - 1; for ( ; i < j; i++, j-- ) { tmp =*i; *i =*j; *j =tmp; } } /*用指针实现*/

  24. 本章小结 1.指针( pointer )是用于存放内存地址的特殊变量( 这里地址一般是指内存中另一个变量的位置 )。称指针指向某个变量,也就是说,指针存放的是该变量的地址值。指针变量的命名规则同普通变量。 2.通常所说的指针类型是指它所指向的变量的数据类型。 3.求地址运算符&,返回操作数变量在内存中的地址,而与变量的内容无关。 4.运算符*,返回操作数所指变量的值。 5.下面三个表达式等价: dd.year (*p).year p->year

More Related