6.指 针
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
XUAN SHANLI
合 肥 工 业 大 学
将无符号的八进制字符串转换为十进制整数。
#include <stdio.h> void main(void) „5‟ { „5‟ char *p,s[6]; „6‟ int i,n=0; „\0‟ p指向s数组。 p=s; gets(p); for(;*p!=\0;p++) 输入字符串。 n=n*8+*p-‟0‟; s printf(“%d\n”,n); } n=0*8+‟5‟-‟0‟5 chp5ex5 n=5*8+‟5‟-‟0‟45 n=45*8+‟6‟-‟0‟366 思考题:将4位十六进值字符串转化为十进制字符串。
XUAN SHANLI
合 肥 工 业 大 学
⑵指针数组与多字符串 通过指针数组构成的菜单,执行DOS命令。
XUAN SHANLI
合 肥 工 p+i 或a+i 业 引用数组元素可以有三种方法: 下标法: a[ i ] 大 注意:数组名是常量地址,不能改变! 指针法: *(p+i) a=p; /*Error!*/ 学 数组名法:*(a+i)
举例:打印数组中的奇数。 #include <stdio.h> void main(void ) { int i ,a [10] ;,*p ; p = a; 循环输入。 for (i=0 ; i<10 ; i++ ) scanf ( “ %d” , &a[i] ) ; p++ a+i p= a; \*p=&a[0];*\ 循环判断,满足条件输出。 for (i=0 ; i<10 ; i++) *(a+i) if ( *(p+i)] % 2 ) printf ( “ %d”, a[ i ]); a[ i } 数组元素法。 数组名法。 指针法。
指针指向对象的类型。
⒊指针的引用 定义指针的目的是通过指针引用内存对象,指针的引用应按如 下步骤进行: ⑴说明指针 int a=0, *p; ⑵指针指向对象 p=&a; ⑶通过指针引用对象 *p=*p+2; 指针操作的两种运算:
取地址运算 & 间接运算 * &a表示取变量a地址的运算。 *p表示取指针p指向变量内容的运算。
a[0][2] a[1][0] a[1][1] a[1][2] a[2][0] a[2][1] a[2][2]
XUAN SHANLI
合 肥 工 业 大 学
举例: 在数组a中查找输入的数,输出行列位置。 #include <stdio.h> void main (void ) { static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int i, j,iS; int *p; p=a; scanf (“ %d” , &iS) ; for(i=0;i<3;i++) for(j=0;j<4;j++) if(iS== *(a[ ][ ]+j) ) 下标法。 a[ i i j ] *(p+4*i+j) *(*(a+i)+j) printf(“iS equal to a[%d ][%d ]\n”,i , j);
s
XUAN SHANLI
合 肥 p 工 业 大 学
⒊二维数组的地址 如下说明数组 static int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 其二维结构如下:
a[0] a[1] 行 a[2] 1 5 2 6 3 7 4 8
XUAN SHANLI
合 9 10 11 12 肥 列 为了便于索引,C语言将数组分为两级管理。 ⑴将a理解为一维数组, 数组有三个元素,它们分别为a[0]、 工 a[1],a[2] 。各个元素又是一个有四个元素的一维数组。 业 ⑵从地址的角度看: a 为a[0] 第一行的首地址 大 a+1 为a[1] 第二行的首地址 a+1 地址一次加一行。 a+2 为a[2] 第三行的首地址 学
}
XUAN SHANLI
合 肥 工 业 大 学
思考题:下列程序输出的结果是? #include <stdio.h> #include <string.h> void main(void) { char arr[2][4]; strcpy(arr,”you”); strcpy(arr[1],”me”); arr[0][3]=„&‟; printf(“%s\n”,arr); }
XUAN SHANLI
第五章 指 针
合 肥 工 业 大 学
5.1 指针的概念
指针是C语言的重要特征,是C语言访问内存数据和程序的灵活 和有效的手段。 C语言的指针支持: ⑴函数的地址调用; ⑵动态分配内存; ⑶数组的地址引用。
XUAN SHANLI
合 肥 工 业 大 学
⒈内存、地址、指针 内存存放了计算机正在运行的程序和程序正在使用的数据。内 存的基本单元是字节(Byte)。 为了访问内存单元,CPU给每个内存单元一个编号,该编号称 为该内存单元的地址。 a的地址&a 变量是程序中可以改变的量,当说 a 明变量时,系统将为其在内存中开辟相 的 2000H 0 应得内存单元。由此确定变量的地址及 内 存 内存中的表示方式。 2001H 0 单 int a=0; 元 2002H 如果有一变量p,其内容存放了a的 2003H 地址&a,通过p也可实现对a的访问,p 称为指针,并指向a。 00H 20H
XUAN SHANLI
合 肥 工 业 大 学
⒋指针的运算 指针是特殊类型的变量,其内容是变量的地址,因此,指针的 运算及结果一定要符合地址逻辑。 int a, b, *p1, *p2; ⑴五种算术运算 p1=&a; p1++; /*含义指向a后的整型单元*/ p2=&b; p1- -; /*指向a前的整型单元*/ p1+n; /*指向a后的n个整型单元*/ p1- n; /*指向a前的n个整型单元*/ 2000H a p2- p1; /*a和b之间差的单元数*/ 2002H p ± n 相当于: p的实际内容 ± nsizeof(*p); 2400H b ⑵六种关系运算 比较两个同类型变量之间的地址关系。 结果 p1 2000H 2002H 200H
XUAN SHANLI
y m
o e
u \0
\0
合 肥 工 业 大 学
5.3 指 针 数 组
指针是存放其它数据对象地址的变量。因此,指针可以构成数 组。每个数组元素为一个指针变量,且在内存中连续存放。 ⒈指针数组的说明 说明格式: type *数组名[const exp]; int *p[ 4 ];
结果是否 正确? 注意指针在运算时的变化。
XUAN SHANLI
合 肥 工 业 大 学
⒉指针与字符串(字符数组) 字符串在内存中可以存储为两种形式: ⑴字符数组 ⑵字符串常量
可以使指针指向字符数组或字符串常量,通过指针引用字符数 组或字符串的各个字符。 指针与字符数组: char *chp,ch[ ]=”Hello!”; /*说明字符指针和字符数组*/ chp=ch; /*指针指向字符数组*/ putchar( *(chp+2)); /*通过指针引用数组元素*/ 指针与字符串: char *chp; /*说明字符指针*/ chp=“Hello!”; /*指针指向字符串*/ puts(chp); /*通过指针引用字符串*/ 说明指针时,可以同时赋初值,如: char *chp=“Hello!”; 赋值表示将字符串的地址赋给指针!
(a+1)+1 *(a+1)+1
XUAN SHANLI
合 肥 工 业 大 学
⑹数组名表示数组元素
*(a+i)[ j ] a a[0]
a[ i ][ j ]
*(*(a+i)+j) a+1 a[1] a[1]+2 a[2]
a[0][0] a[0][1]
*(a[ i ]+j) ⑺指针与二维数组 int *p, a[3][4]; p=a; a[i][j] *(p+4*i+j)等价!
XUAN SHANLI
b
3
&b 2400H
p1
p2
2000H
2400H
合 肥 工 业 大 学
5.2 指针与数组
数组是同类型的变量的集合,各元素按下标的特定顺序占据一 段连续的内存,各元素的地址也连续,指针对数组元素非常方便。 ⒈指针与一维数组 通过指针引用数组元素可以分以下三个步骤: ⑴说明指针和数组 int *p,a[10]; ⑵指针指向数组 p=a; /*指向数组的首地址*/ p=&a[0]; /*指向数组的首地址*/ ⑶通过指针引用数组元素 当指针指向数组的首地址时,则下标为i的元素地址为:
XUAN SHANLI
合 肥 工 业 大 p 学
⒉指针的说明 指针是特殊类型的变量,其内容是变量的地址。在使用前必须 说明,说明某标识符是指针类型,并可指向某种类型的对象。 指针的说明格式: 标识符命名的指针变量名。 type *pname1,…*pnamen; 指针标志。
XUAN SHANLI
合 int *p, *q; /* p、q是指向整型变量的指针。*/ 肥 float *pfValue ,*pf; /* pfValue和pf是指向浮点型的指针。*/ 工 业 大 学
XUAN SHANLI
int a,*p; p=&a; /* p指向a。 */ *p=2;
a p
2
2000H
合 肥 工 2000H 业 大 学
举例: #include <stdio.h> void main (void ) { int x ,*p; x=55; p=&x; 65 x 55 2000H printf ( “ %d, %u ”, x, *p) ; *p=65; printf ( “ %d, %u”, x, *p) ; p 2000H } int *p; *p=2; /* Error! */ 关于指针的说明: ⑴指针必须指向对象后,才能引用。 int a,*p; ⑵ &和 * 为互补运算。 p=&a; 则:&*p p *&a a
⒉指针数组的应用举例 ⑴指针数组与多维数组 通过指针数组按数学方式输出数组的值。 #include <stdio.h> void main ( ) { int i , j; static int a[3][4]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; int *p[3]={ a[0], a[1], a[2] }; 数组a的二维结构 for (i=0 ; i<3 ; i++) { 1 2 3 4 for (j=0; j<4; j++) 5 6 7 8 printf (“ %5d” , *(p[i]+j)); 9 10 11 12 printf ( “\n” ) ; } p[0] a[0] } p[1] a[1] 每输出一行,打印回车。 p[2] a[2]
XUAN SHANLI
p1>p2;
p2 2400H
合 肥 工 业 大 学
指针运算说明
#include <stdio.h> void main(void) { int a,b,*p1,*p2; a=2; b=3; p1=&a; p2=&b; *p1=*p2; printf(“%d,%d\n”,a,b); 差 a=3; 别 b=5; p1=p2; printf(“%d,%d”,*p1,*p2); } a 2 &a 2000H
XUAN SHANLI
合 含义是在内存中开辟空间,并指明元素所指向的对象的类型。 肥 使用前必须让各元素指向对象。 p[ 0 ] 工 数组名p为数组的地址。 p[ 1 ] 业 int i, a[3][4], *p[3]; p[ 2 ] for(i=0;i<3;i++) 大 p[ 3 ] p[ i ]=a[ i ]; *(p[i]+j)=2; /*通过指针数组引用数组元素a[i][j]*/ 学
⑶i行j列数组元素的地址可以由a[ i ]+j得到。
⑷数组名地址的两级管理
a[0]
a[0][0]
a[0][1]
a[0][2]
按 a[1] a[1][0] a[1][1] a[1][2] 行 a 递 增 a[2] a[2][0] a[2][1] a[2][2] ⑸等价地址及其管理方式 数组名是数组的地址,而且是常量,* 运算不改变其值! 以下三种地址等价: a+i *(a+i) a[ i ] 按列递增 差别?