1、第10章 指针 指针类型:与机器内部的硬件结构(如内存地址)及其对数据的处理形式(如变量、数组等及其类型)等内容有关。,指针变量:存放变量地址的变量 由此对变量的操作可转换为对指针变量的操作,10.1 地址和指针的概念地址就是指针(!=指针变量) 例如:int i, j, k; i=3; j=6; k=i+j;,编译时,系统将内存单元分配给变量后,变量名就不存在了, 程序执行时对变量的操作实际上就是根据变量名查找与之对应的变量的地址,然后对地址中的数据进行操作。 对变量的操作实际上是对变量所对应的地址中的数据进行操作。 1.直接访问k = i + j2004 2000 20022005 =9
2、2001=3 2003=6 2.间接访问 * kp = * ip + *jp 3014 3010 3012 3015 2004 3011 2000 3013 20022005=9 2001=3 2003=6 这里:i p, j p, k p:就称为指针变量,其值是另一个变量所对应的内存地址。,变量的指针:就是变量的地址。如 i 所对应的内存地址是2000,则 i 的指针就是2000 指针变量:用来存放变量地址的变量,用来找到另一个变量 如:ip所对应的地址是3010,其内容是2000, 2000就是 i 所对应的地址(指针),因此,ip是存放变量 i 的地址的变量。 若ip 是存放变量i 的地
3、址的指针变量,执行操作:ip= 则 *ip是指针变量 ip所指的对象(即变量 i ) (思考: ip,*ip,&ip),10.2 变量的指针和指向变量的指针变量,指针变量在使用前必须定义,以便使其指向特定类型的变量 指针变量的定义形式: 类型标识符 * 标识符 其中:类型标识符:指针变量指向何种数据类型的变量(基类型)标识符:表示指针变量名。 例: float * p3; /* p3是指向实型变量的指针变量 * /char * p4; / * p4是指向字符型变量的指针变量 * /,int i, j; int *p1, *p2; p1=,10.2.1 定义一个指针变量,1、定义指针变量时,变量
4、名前以 * 开头。2、一定要指明基类型且指针变量一经定义就只可指向同类型的变量。如:float *p3; 指针变量名是p3,它只能指向实型数据。 3、在引用中,指针变量前加 * 表示指针变量所指 向的 对象(即变量)。,说明:,通常,只能将变量的地址赋给指针变量,但在Turbo c中,整型数据(十进制、十六进制、八进制)也可赋给指针变量, 如:int *p1; p1=100; printf(“%d n”,* p1);指针变量有两种运算符:*:指向对象运算符, 如:* p1, 表示p1指向的对象是变量i,10.2.2 指针变量的引用,例10_1.c:指针变量操作举例 main( ) int a,
5、 b, *p1, *p2 ; a=100; b=10; p1= ,运算结果: 一起做一下,关于 则 &* p1 &a p1 &* p2 &b p2p2=&* p1 p2=&a即:&*p=p 指针等式一,2. * & a:先进行&a得a的地址,再对a的地址进行* 运算(因为&a=p)即指向a地址所指向的变量,就是a ,其值是100即:*&a=a 指针等式二 3.运算符 * , + :优先级为2, 结合性:从右到左(* p1)+ a+* p1+ * (p1+) 意即:将p1所指向的对象 a 的值取出, 然后使 p1 自增, p1原指向a , 现在可能指向下一个变量了。,例10_2:输入值给a,b,
6、用指针方法按先大后小的顺序输出。 main( ) int *p1, *p2, *p, a, b; scanf(“%d%d”, ,输入:5 9,例10_3:指针变量作函数参数,将两个整数按大小顺序输出。 swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p; printf(“ ,10.2.3 指针变量作为函数参数 指针变量作为函数参数时,传递的是变量的地址。,main( ) int a, b, *p11, *p12; scanf(“%d%d”, ,运行:输入:5,9 输出:&a=ffd4,&b=ffd6,&p11=ffd8,&p12=ffdap1
7、1=ffd4,p12=ffd6a=5, b=9&p=ffca, &p1=ffd0,&p2=ffd2p1=ffd4,p2=ffd6p=5,*p1=9,*p2=5max=9,min=5,问题:函数调用结束后, 分配给p1,p2单元释放否?,例10_3_2:对10_3中的函数稍作改动 swap(int *p1, int *p2) int * p; * p=* p1; * p1= * p2; * p2= * p; printf(“p=%x, p1=%x, p2=%x n”, p, p1, p2); main ( ) int a, b; int * p11, * p12; scanf(“%d%d”, ,
8、如何解决此问题?,运行:5, 9 输出:p=ffd2, p1=ffd2, p2=ffd4 a=9, b=9,例10_3_3:在数据交换过程中,形实参采用普通变量 swap(int x, int y) int t; t=x; x=y; y=t; printf(“ ,在被调用函数中变量的值被交换了,返回主函数后,变量的值为什么依旧? 原因:单向的值传递,当函数调用返回后,分配的单元被释放了.,输出: &t=ffc8, &x=ffce, &y=ffd0t=5, x=9, y=5&a=ffd2, &b=ffd4 a=5,b=9,输入: 5, 9,数组的指针:指数组的起始地址。 数组元素的指针:指数组元
9、素的地址。 数组的地址指针变量,指针变量就指向该数组了。 数组元素的引用: (1) 下标法:a3 (2) 指针法:用指针变量指向所找的数组元素。 10.3.1 指向数组元素的指针 例:int a5;int *p;p=a;p=,等价,10.3 数组的指针和指向数组的指针变量,例10_4: main( ) int a5; int *p= ,输出:&p=ffd8, p=ffce&a=ffce, &a0=ffce, a0=2*p=2,例10_5:指针变量指向不同类型数组时,指针变量值加1其意义不同 main( ) int i, a3=1, 3, 5; float b3=2,4,6; int *p1=a
10、; float *p2=b; printf(“,10.3.2 通过指针引用数组元素 指针变量所指数组元素的地址的计算,与数组数据类型有关。,注:若a=&a0=ffc4则a+0=ffc4 , a+1=ffc6 即: a+0&a0 a+1 &a1若b=&b0=ffca 则b+1=ffce , a+2=ffd2,输出:&a0=ffc4,&b0=ffca,&p1=ffd6,&p2=ffd8 p1=ffc4, *p1=1 p1=ffc6, *p1=3 p1=ffc8, *p1=5 p2=ffca, *p2=2.00 p2=ffce, *p2=4.00 p2=ffd2, *p2=6.00 *(a+2)=5
11、 *(p2+1)=4.00,设 a:数组,p:指针变量,当数据类型不同时其地址的计算方法也不同。 (1) p=ap+i = = a+i &ai而a的第 i 个元素的实际地址为: a + i * d(数组元素所占字节数),如:数组a第2个元素的地址: a+2*2=ffc4+4=ffc8数组b第2个元素的地址: b+2*4=ffca+8=ffd2,几点说明:,(2) * (p+i)=*(a+i)=ai编译时,按数组首地址加上相对位移量得到要找数组元素的地址,然后取出该单元中的内容,即:*(p+i)=*(a + i)=ai 指针等式三例:a的首地址:ffc4,则对a2的存取方法为:* (&a2) =
12、 * (a+2* 2)= * (ffc4+4) = * (ffc8) = a2 = 5p+i=a + i=&ai 指针等式四 (3) 指向数组的指针变量可带下标如:pi, ai, * (a+i), * (p+i) 都是指向a数组的第i个元素。其中: a:数组名 p: 指向a 的指针变量 初值p = a (4)pi与*(p+i)等价,举例:用三种方法输出数组元素 例10_6:用下标法 main( ) int i, a5=55, 66, 77, 88, 99; for(i=0; i5; i+) printf(“ ,输出:&a0=ffd2, a0=55&a1=ffd4, a1=66&a2=ffd6,
13、 a2=77&a3=ffd8, a3=88&a4=ffda, a4=99,例10_6_2:计算数组元素地址法 main( ) int i, a5=55, 66, 77, 88, 99; for(i=0;i5;i+) printf(“(a+%d)=%x,*(a+%d)=%d n”,i,(a+i), i,*(a+i); ,输出:(a+0)=ffd0, *(a+0)=55(a+1)=ffd2, *(a+1)=66(a+2)=ffd4, *(a+2)=77(a+3)=ffd6, *(a+3)=88(a+4)=ffd8, *(a+4)=99,例10_6_3:用指针变量指向数组元素法(指针法) main(
14、 ) int *p, a5=55, 66, 77, 88, 99; for(p=a; p (a+5); p+) printf(“p=%x, *p=%d n”, p,* p); ,输出: p=ffd0, *p=55 p=ffd2, *p=66 p=ffd4, *p=77 p=ffd6, *p=88 p=ffd6, *p=99,例10_6_4:指针下标法及指针变量指向数组元素 main( ) int i, * p, a5=55, 66, 77, 88, 99; p=a; for(i=0;i5;i+) printf(“p%d=%d,*(p+%d)=%d n” i,pi,i,*(p+i); ,输出:p
15、0=55, *(p+0)=55p1=66, *(p+1)=66p2=77, *(p+2)=77p3=88, *(p+3)=88p4=99, *(p+4)=99,(1) p+: 合法, 因p是指针变量,+只能用于变量。a+: 不合法, 因为a是数组名,其值是数组元素的首地址,是常量。但主要原因:a是数组名,是地址常量.它不占任何具体的存储单元,但对于具体数组元素名,则可使用+如:a1+, a3+等。 (2) 指针变量使用时要注意当前值.,使用指针变量时要注意的问题:,例10_7:利用指针变量连续两次输出数组元素 main( ) int i, * p, a5=55, 66, 77, 88, 99;
16、 p=a; for(i=0; i5; i+,p+) printf(“p=%x, *p=%d n”, p, *p); for(i=0; i5; i+, p+) printf(“p=%x, *p=%d n”, p, *p); ,输出: p=ffd2, *p=55 p=ffd4, *p=66 p=ffd6, *p=77 p=ffd8, *p=88 p=ffda, *p=99 p=ffdc, *p=-24 p=ffde, *p=285 p=ffe0, *p=1 p=ffe2, *p=-26 p=ffe4, *p=1444,此结果,是何原因?,数组下标越界时,编译不作检查,如上例。 (3) 指针变量使用
17、时的几个问题;+和* 优先级为2,结合性从右向左 若 p=a+3 则: *p+:将p所指对象(a3)的值88取出,然后p增1 指向a4 *+p:先将p增1指向a4,然后将其指向的对象a4的值99取出。 *p- - :将p所指对象(a3)的值88取出,然后p减1 指向a2 *- -p :先将p减1指向a2,然后将其指向的对象a2的值77取出。,若:p=a+i, 则 *p+ ai+ *p - - ai- - *+p a+i - -p a- -i 思考(*p)+=?,10.3.3 数组名作函数参数 main( ) int array10;f(array, 10); f(int arr , int n
18、) ,调用函数时,以数组名作实参时实际上是把数组的首地址传递给形参,此时,形参数组和实参数组占用的是同一段内存,在函数调用过程中,改变形参数组元素实际上也是改变实参数组元素,调用结束后,虽然形参数组名不存在了,但对实参数组元素的操作已产生作用。,T10-7.c 将数组a中n个整数按相反顺序存放 算法:,void inv (int x ,int n) int t, i, j, m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i;t=xi; xi=xj; xj=t; return; main( ) int i,a10=3,7,9,11,0,6,7,5,4,2; printf(“t
19、he original array: n”); for(i=0;i10;i+) printf(“%d,”,ai);printf(“ n”); inv(a, 10); printf(“the array has been inverted:n”); for(i=0;i10;i+) printf(“%d,”,ai); printf(“ n”); ,例T10-7-1.c 将上例中的形参x改为指针变量,以接收实参数组a传递来的地址,再设指针i, j, p 指向有关元素,以实现数组元素的转换。 void inv(int *x,int n) int *p, t, *i, *j, m=(n-1)/2; i=
20、x; j=x+n-1; p=x+m; for( ; i=p; i+, j-) t=*i; *i=*j; *j=t; return; ,t 3, * i 2, * j 3 t 7, * i 4, * j 7 t 9, * i 5, * j 9 t 11, * i 7, * j 11 t 0, * i 6, * j 0,main( ) int i, a10=3, 7, 9, 11, 0, 6, 7, 5, 4, 2; printf(“the original array: n”); for(i=0; i10; i+) printf(“%d,”, ai); printf(“n”); inv(a, 1
21、0); printf(“the array has been inverted:n”); for(i=0; i10; i+) printf(“%d,” , ai); printf(“ n”); ,t 3, * i 2, * j 3 t 7, * i 4, * j 7 t 9, * i 5, * j 9 t 11, * i 7, * j 11 t 0, * i 6, * j 0,例10_8:从10个数中找出最大值和最小值, 并分别存入全局 量max, min中,在查找过程中 指针p:依次指向数组各元素, array_end:指向最未元素后, array:指向array0所对应值。 int max
22、, min; void max_min_value(int array,int n) int *p, *array_end; array_end=array+n;max=min=*array; for(p=array+1; p max) max=*p; else if(*pmin) min=*p;return; ,main( ) int i, number10; printf(“enter 10 data n”); for(i=0;i10;i+) scanf(“%d”, ,运行: enter 10 data -2 4 6 8 0 -3 45 67 89 10 输出: max=100, min=
23、-3,例T10-8-1.c 对数组元素的操作,形、实参数均使用指针变量。int max, min; void max_min_value(int *array,int n) int *p, *array_end;array_end=array+n;max=min=*array; for(p=array+1; p max) max=*p; else if(*pmin) min=*p;return; ,main( ) int i, number10, *p ; p=number;printf(“enter 10 data n”); for(i=0;i10;i+,p+) scanf(“%d”, p)
24、; printf(“the 10 data : n”); for(p=number, i=0; i10; i+, p+) printf(“%d ”,*p); p=number ; max_min_value(p,10); printf(“ nmax=%d, min=%d n”, max, min); ,运行: enter 10 data -2 4 6 8 0 -3 45 67 89 100 the 10 data: -2 4 6 8 0 -3 45 67 89 100 输出: max=100, min=-3,归纳: 在被调用函数中改变数组的值,实参、形参的取值,有四种情况: (1)实、形参都是
25、数组名main( ) int a10 f(a, 10); ,f(int x , int n) ,(2)实参为数组名,形参为指针变量main( )int a10 f(a, 10); ,f(int *x, int n) ,(3)形、实参都是指针变量main( )int a10 ,*p; p=a;f(p, 10); ,f(int *x, int n) ,(4)实参为指针变量,形参为数组main( )int a10 ,*p; p=a; f(p , 10); ,f(int x , int n) ,例T10-9.c 形实参都是指针变量,将数组10个元素反序存放。 void inv (int *x, int
26、 n) int *p, m, t, *i, *j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for( ; i=p; i+, j-) t=*i; *i=*j; *j=t; return; ,main( ) int i, arr10, *p=arr; printf(“input original array : n”); for(i=0; i10; i+, p+) scanf(“%d”,p); printf(“n”); p=arr ; inv(p, 10); printf(“the array has been inverted: n”); for(p=arr; parr+
27、10; p+) printf(“%d “, *p); printf(“ n”); ,显示:the original array: 输入: 3 7 9 11 0 6 7 5 4 2 the array has been inverted: 2 4 5 7 6 0 11 9 7 3,例T10-9-1.c 在主函数中不设数组,只 设针变量程序也可运行(TC中)。 void inv (int *x, int n) int *p, m, t, *i, *j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for( ; i=p; i+, j-) t=*i; *i=*j; *j=t; fo
28、r(m=0 ; m10; m+) printf(“x+%d)=%x,*(x+%d)=%d n”, m,(x+m),m,*(x+m); return; ,(x+0)=fc, *(x+0)=2 (x+1)=fe, *(x+1)=4 (x+2)=100 *(x+2)=5 (x+3)=102, *(x+3)=7 (x+4)=104, *(x+4)=6 (x+5)=106, *(x+5)=0 (x+6)=108, *(x+6)=11 (x+7)=10a, *(x+7)=9 (x+8)=10c, *(x+8)=7 (x+9)=10e, *(x+9)=3 the array has been inverte
29、d: (arr+0)=fc, *(arr+0)=2 (arr+1)=fe, *(arr+1)=4 (arr+2)=100, *(arr+2)=5 (arr+3)=102, *(arr+3)=7 (arr+4)=104, *(arr+4)=6 (arr+5)=106, *(arr+5)=0 (arr+6)=108, *(arr+6)=11 (arr+7)=10a, *(arr+7)=9 (arr+8)=10c, *(arr+8)=7 (arr+9)=10e, *(arr+9)=3,见P222,main( ) int i, *arr; printf(“ ,(x+0)=fc, *(x+0)=2 (x
30、+1)=fe, *(x+1)=4 (x+2)=100 *(x+2)=5 (x+3)=102, *(x+3)=7 (x+4)=104, *(x+4)=6 (x+5)=106, *(x+5)=0 (x+6)=108, *(x+6)=11 (x+7)=10a, *(x+7)=9 (x+8)=10c, *(x+8)=7 (x+9)=10e, *(x+9)=3 the array has been inverted: (arr+0)=fc, *(arr+0)=2 (arr+1)=fe, *(arr+1)=4 (arr+2)=100, *(arr+2)=5 (arr+3)=102, *(arr+3)=7
31、(arr+4)=104, *(arr+4)=6 (arr+5)=106, *(arr+5)=0 (arr+6)=108, *(arr+6)=11 (arr+7)=10a, *(arr+7)=9 (arr+8)=10c, *(arr+8)=7 (arr+9)=10e, *(arr+9)=3,运行: &arr=ffd8, arr=fc 输入: 3 7 9 11 0 6 7 5 4 2,例T10-10.c 用选择法对 10个整数按从大到小顺 序排列 main( ) int *p, i, a10; p=a; for(i=0; i10; i+)scanf(“%d”, p+); p=a; sort(p,
32、10); for(p=a, i=0; i10; i+) printf(“%d”, *p); p+; ,sort(int x, int n) int i, j, k, t; for(i=0; i xk) k=j;if(k != i) t=xi;xi=xk;xk=t; ,输入:1 3 -2 6 8 -1 9 2 4 5,i j 0 1 k=0 x1x0 k=12 x2x13 x3x1 k=34 x4x3 k=45 x5x4 6 x6x4 k=67 x7x6 8 x8x6 9 x9x6 tx0=1, x0x6=9x6 t=1 1 2 k=1 x2x13 x3x1 k=34 x4x3 k=45 x5x
33、4 6 x6x4 7 x7x4 8 x8x49 x9x4 tx1=3, x1x4=8x4 t=3,2 3 k=2 x3x2 k=34 x4x35 x5x36 x6x3 7 x7x3 8 x8x3 9 x9x3 tx2=-2, x2x3=6x3 t=-2 3 4 k=3 x4x3 k=45 x5x46 x6x47 x7x4 8 x8x4 k=8 9 x9x8 k=9 t x3=-2, x3x9=5x9 t=-2 4 5 k=4 x5x4 6 x6x47 x7x48 x8x4 k=8 9 x9x8,t x4=3, x4x8=4x8 t=3 5 6 k=5 x6x5 k=6 7 x7x6 k=78
34、x8x7 k=89 x9x8 t x5=-1, x5x8=3x8 t=-1 6 7 k=6 x7x6 k=7 8 x8x7 9 x9x7 t x6=1, x6x7=2x7 t=17 8 k=7 x8x7 x9x7,10.3.4 指向多维数组的指针和指针变量 1、多维数组的地址 如定义:int a34=1,3,5,7,9,11,13,15,17,19,21,23;说明:a, a0, a1 ,a2:数组名,本身不占内存,不存放数据,仅表示一个地址,a:代表整个数组首地址,设为2000 a+1:第1行首地址为:a+14 2=2008 a+2:第2行首地址为:a+2 4 2=2016,a0、a1、a2
35、是一维数组名,而数组名代表数组首地址 因此:a0 与 &a00 :表示相同的地址a1 与 &a10 :表示相同的地址a2 与 &a20 :表示相同的地址,a2+0,a1+3,关于二维数组的地址的其值的表示:,2000:,2002:,2004:,2006:,2008:,2010:,2012:,2014:,2016:,2018:,2020:,2022:,例T10-10-2.c 二维数组元素及地址的输出 main( ) int i, j, a34=1, 3, 5, 7,9,11,13,15,17,19,21,23; printf(“a=%x, a0=%x, a1=%x,a2=%x n”,a,a0,a
36、1,a2); printf(“a+0=%x, a+1=%x,a+2=%x n”, a+0, a+1,a+2); for(i=0; i3; i+) for(j=0; j4; j+) printf(“%x,%x,%x n”,*(a+i)+j, ai+j, ,运行结果: 地址 a=ffc0,a0=ffc0,a1=ffc8,a2=ffd0 a+0=ffc0,a+1=ffc8,a+2=ffd0 *(a+0)+0=ffc0,a0+0=ffc0,&a00=ffc0 *(a+0)+1=ffc2,a0+1=ffc2,&a01=ffc2 *(a+0)+2=ffc4,a0+2=ffc4,&a02=ffc4 *(a+
37、0)+3=ffc6,a0+3=ffc6,&a03=ffc6 *(a+1)+0=ffc8,a1+0=ffc8,&a10=ffc8 *(a+1)+1=ffca,a1+1=ffca,&a11=ffca *(a+1)+2=ffcc,a1+2=ffcc,&a12=ffcc *(a+1)+3=ffce,a1+3=ffce,&a13=ffce *(a+2)+0=ffd0,a2+0=ffd0,&a20=ffd0 *(a+2)+1=ffd2,a2+1=ffd2,&a21=ffd2 *(a+2)+2=ffd4,a2+2=ffd4,&a22=ffd4 *(a+2)+3=ffd6,a2+3=ffd6,&a23=ffd
38、6,数值 a00=1,*(a0+0)=1,*(*(a+0)+0)=1 a01=3,*(a0+1)=3,*(*(a+0)+1)=3 a02=5,*(a0+2)=5,*(*(a+0)+2)=5 a03=7,*(a0+3)=7,*(*(a+0)+3)=7 a10=9,*(a1+0)=9,*(*(a+1)+0)=9 a11=11,*(a1+1)=11,*(*(a+1)+1)=11 a12=13,*(a1+2)=13,*(*(a+1)+2)=13 a13=15,*(a1+3)=15,*(*(a+1)+3)=15 a20=17,*(a2+0)=17,*(*(a+2)+0)=17 a21=19,*(a2+1
39、)=19,*(*(a+2)+1)=19 a22=21,*(a2+2)=21,*(*(a+2)+2)=21 a23=23,*(a2+3)=23,*(*(a+2)+3)=23,2、指向多维数组的指针变量 (1).指向数组元素的指针变量 例T10-12.c 用指针变量顺序输出数组元素的值。 main( ) int a34=1, 3, 5, 7,9,11,13,15,17,19,21,23; int *p; for(p=a0; p a0+12; p+) if(p-a0)%4=0)printf(“n”);printf(“%4d ”,*p); for(p=a0;pa0+12;p+) printf(“add
40、r=%x, value=%dn”,p,*p); ,运行结果:1 3 5 79 11 13 15 19 21 23 addr=ffc2, value=1 addr=ffc4, value=3 addr=ffc6, value=5 addr=ffc8, value=7 addr=ffca, value=9 addr=ffcc, value=11 addr=ffce, value=13 addr=ffd0, value=15 addr=ffd2, value=17 addr=ffd4, value=19 addr=ffd6, value=21 addr=ffd8, value=23,由此可见:顺序输
41、出数组元素方法简单而输出指定的数组元素则要进行地址的计算 如二维数组为 n m (n为行, m 为列) 首元素地址为 a0 aij在数组中相对位置的计算公式: i * m + j ( m为每行元素个数) 位移量的计算: a11=1*4+1=5a23=2*4+3=11 若初值: p=a0 则: *(p+1*4+1)=*(p+5) a11*(p+2*4+3)=*(p+11) a23,a11,(2).指向包含m个元素的一维数组的指针变量若p是指向某数组(一或二维)的指针变量,则每当p+时,就指向下一元素。若p是指向包含m个元素的一维数组时, 如定义: (* p)4此时,p只能指向包含4个元素的一维数
42、组.:p的值是该一维数组的首地址.(每行看成是一维数组): p不能指向一维数组中的任一元素,某行第j个元素只能通过(*p)j访问。,例T10-13.c 输出二维数组任一行任一列元素的值。 main( ) int a34=1, 3, 5, 7,9,11,13,15,17,19,21,23; int (*p)4, i, j; p=a; scanf(“i=%d, j=%d”, ,输入: i=1, j=1 输出:a11=11a13=15a22=21,a,a+0,p+0,a+1,p+1,a+2,p+2,10.4 字符串的指针和指向字符串的指针变量 9.4.1 字符串的表示形式 字符串:用双引号括起的一串
43、字符。 可赋给字符型的数组或指针变量, 可通过字符型数组名或字符型指针变量输出。,例T10-16.c 用字符数组和字符型指针变量输出字符串。 main( ) char s1 =“ I love china !” ;char *s2=“ I love wuhan!” ; printf(“s1=%s n”,s1); printf(“s2=%s n”,s2);s2=s2+7; printf(“s2=%s n”,s2); ,运行结果: s1=I love china! S2=I love wuhan! S2=wuhan!,能否使用s1=s1+7 ? S1是数组名 是常量,例T10-18.c 用下标法存
44、取字符串中的字符 main( ) char a =“ I am a boy. ” ,b20; 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; bi != 0 ; i+) printf(“%c”, bi); printf(“n”); ,运行结果: string a is : I am a boy. string b is : I am a boy.,例T10-19.c 用指针法存取字符串中的字符 main( ) char a =“ I am a boy. ” ; char b20,*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; bi != 0 ; i+) printf(“%c”, bi); printf(“n”); ,