页数:32页文件大小:498.0 KB来源: 计算机语言与程序设计ppt课件
本课件系统讲解指针,先说明内存地址、指针变量的定义与取地址、间接访问运算,再讲指针与一维数组、二维数组的对应关系及指针运算,随后展开字符串指针、字符指针数组与多级指针的用法,并通过对程序运行结果的对照演示,帮助读者建立「逻辑指代与物理指代」的清晰认识。
本页为第九讲 指针章节封面。指针是 C 语言中的一个重要概念,掌握指针的用法可使程序简洁、高效、灵活。
为了了解什么是指针,先看一个小故事:地下工作者阿金接到上级指令,要去寻找打开密电码的密钥,这是一个整数。几经周折,才探知如下线索,密钥藏在一栋三年前就被贴上封条的小楼中。
一个风雨交加的夜晚,阿金潜入了小楼,房间很多,不知该进哪一间,正在一筹莫展之际,忽然走廊上的电话铃声响起。艺高人胆大,阿金毫不迟疑,抓起听筒,只听一个陌生人说:“去打开 211 房间,那里有线索”。阿金疾步上楼,打开 211 房间,用电筒一照,只见桌上赫然 6 个大字:地址 1000。阿金眼睛一亮,迅速找到 1000 房间,取出重要数据 66,完成了任务。
我们画出下图:
指针变量——用来存放另一变量地址的变量,变量的指针就是变量的地址。
1、指针的概念:指针是一种特殊的变量,特殊性表现在类型和值上。从变量讲,指针也具有变量的三个要素:
从上面的概念可知,指针本身类型是 int 型,因为任何内存地址都是整型的,但是指针变量的类型却定义成它所指向的变量的类型。
2、指针的定义(说明,先说明后引用),例如:
int *p, *q;float *point;double *pd;int (*pa)[10];int (*pu)();int **qq; 第6页:指针的赋值
3、指针赋值,例:
int akey;int *p,*q;akey=66;p = &akey;q = p; 第7页:指针赋值示意图
本页以图形方式展示 q = p 之后两个指针指向同一变量的情形(图2),源文件未给出更多文字说明。
第8页:指针1.c示例程序
//指针1.c #include <stdio.h>void main(){ int a[5]={0,1,2,3,4}; int *p1,*p2; p1=&a[1]; p2=&a[2]; printf("a[1]=%d;a[2]=%d\n",*p1,*p2);} 第9页:取地址与间接访问运算符
说明:见图 p1 和 p2 分别指向 a[1]、a[2],这里
&——取地址运算符*——指针运算符(间接访问运算符)*p1——间接访问 p1 所指向的内存单元,当然是输出 a[1] 的值*p2——间接访问 p2 所指向的内存单元,当然是输出 a[2] 的值
第10页:指针2.c示例程序
//指针2.c #include <stdio.h>void main(){ int akey,b; int *p,*q; akey=66; p=&akey; q=&b; *q=*p; printf("b=%d\n",b); printf("*q=%d\n",*q);} 第11页:向指针所指单元赋值
本页以图形方式展示向指针所指向的内存单元赋值(*q=*p)的效果,源文件未给出更多文字说明。
第12页:指针3.c示例程序
//指针3.c #include <stdio.h>void main(){ int a[5]={1,3,5,7,9}; int *p; int i; p=a; for(i=0;i<5;i=i+1) { printf("a[%d]=%d\n",i,*p); p=p+1; }} 第13页:指针与数组的等价关系
说明:
p=a; 这里数组名作为数组的起始地址,即 a[0] 的地址。因此 p=a 等效于 p=&a[0];p=p+1; 如 p 指向 a[0],则 p=p+1 之后,p 指向 a[1]- 如果
p=a 等效于 p=&a[0];,则 p=a+4 等效于 p=&a[4];
a[0]、a[1]、…、a[4] 可分别用 *p、*(p+1)、…、*(p+4) 表示,二者等效。
第14页:指针4.c示例程序
//指针4.c #include <stdio.h>void main(){ int a[5]={1,3,5,7,9}; int *p; int i=0; for(p=a;p<a+5;p=p+1) { printf("a[%d]=%d\n",i,*p); i=i+1; }} 第15页:指针5.c示例程序
//指针5.c #include <stdio.h> void main() { char *p; static char s[] = "abcdefgh"; p=s; while (*p != '\0') { p=p+1; } printf("字串长度为%d\n",p-s);}
数组名是一个常量指针,指向该数组的首地址,例:
第16页:常量指针与数组首地址
图中数组的首地址是 s[0] 的地址,即 &s[0]。s 可看作是指向 s[0] 的指针。s 是不会动的,是常量指针。
- 下标 0~7 依次存放字符 a~h,下标 8 存放串结束标志
\0 - 指针 p 可在数组内前后移动,而 s 固定指向首元素
第17页:指针6.c示例程序
//指针6.c #include <stdio.h>void main(){ static char shuzi[]="987654321"; char *p=&shuzi[8]; do { putchar(*p); p=p-1; } while (p>=shuzi); putchar('\n');}
数组名是一个常量指针,指向该数组的首地址,例:
第18页:指针6.c的说明
说明:
- 字符串:数字字符串
- p 指向 shuzi[8],即指向串中的字符 '1'
- 直到型循环,用 putchar 函数将 shuzi[8] 输出到屏幕;之后让 p=p-1
- 在 while 中,当
p>=shuzi 则继续执行循环体,一旦 p<shuzi 则退出循环。这种做法使输出结果为 123456789 - 在本例中数组名 shuzi 是一个常量指针,永远指向 shuzi[0] 的地址上
思考:如何通过 p 和 shuzi 求该数字字符串的长度?
第19页:指针7.c示例程序
//指针7.c #include <stdio.h>void main(){ int i; char *p; p="computer"; printf("%s\n",p); for (i=0;i<8;i=i+1) { putchar(p[i]); } putchar('\n'); while(*p) { putchar(*p); p=p+1; } putchar('\n');} 第20页:字符指针与字符数组的赋值
上例中有三种不同的输出方式,请你自己分析一下,各有什么特点。
说明:
- 对字符指针变量赋值的写法:
(1)char *p; (2)char *p="computer"; p = "computer";
以上两种都行,可以整体赋值。
- 对字符数组赋初值的写法:
(1)char as[12]="department"; char as[] ="department";(2)char as[12]; as = "department"; as[12]="department"; 第21页:例题分析的定义部分
#include <stdio.h>void main(){ int i; char s[ ] = "China"; char* t = s ; char* p[ ]={"China","Canada","Denmark","Greece"}; char** q[ ]={p,p+2,p+3,p+1};
例题分析。
第22页:第一组输出语句
//输出1.1:s的地址 cout<<"1.1:输出s的地址"<<&s<<endl;cout<<"1.2:输出s的内容"<<s<<endl;cout<<"1.3:输出t指向的内容"<< t <<endl;cout<<"1.4:输出*t表示的内容"<< *t<<endl;cout<<"1.5:输出*s表示的内容"<< *s <<endl;cout<<"1.6:输出t所在的地址"<< &t<<endl;
第23页:第一组输出结果
第一组输出的结果 输出项 说明 输出值 1.1 s 的地址 0x0012FF78 1.2 s 的内容 China 1.3 t 指向的内容 China 1.4 *t 表示的内容 C 1.5 *s 表示的内容 C 1.6 t 所在的地址 0x0012FF74
第24页:第二组输出语句
//输出2.1: P[0]指向的字符串 cout<<"2.1:输出P[0]指向的字符串"<<p[0]<<endl;cout<<"2.2:输出P[1]指向的字符串"<<p[1]<<endl;cout<<"2.3:输出P[2]指向的字符串"<<p[2]<<endl;cout<<"2.4:输出P[3]指向的字符串"<<p[3]<<endl;
第25页:第二组输出结果
第二组输出的结果 输出项 说明 输出值 2.1 P[0] 指向的字符串 China 2.2 P[1] 指向的字符串 Canada 2.3 P[2] 指向的字符串 Denmark 2.4 P[3] 指向的字符串 Greece
第26页:第三组输出语句
//输出3.1: p[0]本身的地址 cout <<"3.1:输出p[0]本身的地址"<<&p[0]<< endl;cout <<"3.2:输出p[1]本身的地址"<<&p[1]<< endl;cout <<"3.3:输出p[2]本身的地址"<<&p[2]<< endl;cout <<"3.4:输出p[3]本身的地址"<<&p[3]<< endl;
第27页:第三组输出结果
第三组输出的结果 输出项 说明 输出值 3.1 p[0] 本身的地址 0x0012FF64 3.2 p[1] 本身的地址 0x0012FF68 3.3 p[2] 本身的地址 0x0012FF6C 3.4 p[3] 本身的地址 0x0012FF70
第28页:第四组输出语句
//输出4.1: q[0]指向的内容 cout << "4.1:输出q[0]指向的内容" << q[0] << endl;cout << "4.2:输出q[1]指向的内容" << q[1] << endl;cout << "4.3:输出q[2]指向的内容" << q[2] << endl;cout << "4.4:输出q[3]指向的内容" << q[3] << endl;
第29页:第四组输出结果
第四组输出的结果(q 元素指向的指针地址) 输出项 说明 输出值 4.1 q[0] 指向的内容 0x0012FF64(即 &p[0]) 4.2 q[1] 指向的内容 0x0012FF6C(即 &p[2]) 4.3 q[2] 指向的内容 0x0012FF70(即 &p[3]) 4.4 q[3] 指向的内容 0x0012FF68(即 &p[1])
第30页:第五组输出语句
//输出5.1: q[0]指向的内容的内容 cout << "5.1:输出q[0]指向的内容的内容" << *q[0] << endl;cout << "5.2:输出q[1]指向的内容的内容" << *q[1] << endl;cout << "5.3:输出q[2]指向的内容的内容" << *q[2] << endl;cout << "5.4:输出q[3]指向的内容的内容" << *q[3] << endl;
第31页:第五组输出结果
第五组输出的结果(对 q 元素做两级间接访问) 输出项 说明 输出值 5.1 q[0] 指向的内容的内容 China 5.2 q[1] 指向的内容的内容 Denmark 5.3 q[2] 指向的内容的内容 Greece 5.4 q[3] 指向的内容的内容 Canada
第32页:第九讲结束页
本页为第九讲 指针的结束页,本讲内容至此结束。
下载地址:{{downurl}}
{{{a}}}
{{#b}}{{{b}}}
{{/b}} {{/title}} {{#nolog}}登陆注册
{{/nolog}} {{#djsx}}点我刷新
{{/djsx}} {{#gocz}} {{/gocz}} {{#ffqr}} {{/ffqr}}