《指向字符串的指针》由会员分享,可在线阅读,更多相关《指向字符串的指针(6页珍藏版)》请在金锄头文库上搜索。
1、10.4 符串的指针指向字符串的针指变量10.4.1 字符串的表示形式在 C 语言中,可以用两种方法访问一个字符串。1) 用字符数组存放一个字符串,然后输出该字符串。【例 10.24】main()char string=”I love China!”;printf(%sn,string);说明:和前面介绍的数组属性一样,string 是数组名,它代表字符数组的首地址。2)用字符串指针指向一个字符串。【例 10.25】main()char *string=”I love China!”;printf(%sn,string);字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。只能按对指
2、针变量的赋值不同来区别。对指向字符变量的指针变量应赋予该字符变量的地址。如: char c,*p=表示 p 是一个指向字符变量 c 的指针变量。而: char *s=C Language;则表示 s 是一个指向字符串的指针变量。把字符串的首地址赋予 s。上例中,首先定义 string 是一个字符指针变量,然后把字符串的首地址赋予string(应写出整个字符串,以便编译系统把该串装入连续的一块内存单元),并把首地址送入 string。程序中的:char *ps=C Language;等效于:char *ps;ps=C Language;【例 10.26】输出字符串中 n 个字符后的所有字符。ma
3、in()char *ps=this is a book;int n=10;ps=ps+n;printf(%sn,ps);运行结果为:book在程序中对 ps 初始化时,即把字符串首地址赋予 ps,当 ps= ps+10 之后,ps 指向字符“ b”,因此输出为book。【例 10.27】在输入的字符串中查找有无k 字符。main()char st20,*ps; int i;printf(input a string:n);ps=st;scanf(%s,ps);for(i=0;psi!=0;i+)if(psi=k)printf(there is a k in the stringn);break
4、;if(psi=0) printf(There is no k in the stringn);【例 10.28】本例是将指针变量指向一个格式字符串,用在 printf 函数中,用于输出二维数组的各种地址表示的值。但在 printf 语句中用指针变量 PF 代替了格式串。这也是程序中常用的方法。main()static int a34=0,1,2,3,4,5,6,7,8,9,10,11;char *PF;PF=%d,%d,%d,%d,%dn;printf(PF,a,*a,a0,printf(PF,a+1,*(a+1),a1,printf(PF,a+2,*(a+2),a2,printf(%d,%
5、dn,a1+1,*(a+1)+1);printf(%d,%dn,*(a1+1),*(*(a+1)+1);【例 10.29】本例是把字符串指针作为函数参数的使用。要求把一个字符串的内容复制到另一个字符串中,并且不能使用 strcpy 函数。函数 cprstr 的形参为两个字符指针变量。pss 指向源字符串,pds 指向目标字符串。注意表达式:(*pds=*pss)!=0的用法。cpystr(char *pss,char *pds)while(*pds=*pss)!=0)pds+;pss+; main()char *pa=CHINA,b10,*pb;pb=b;cpystr(pa,pb);print
6、f(string a=%snstring b=%sn,pa,pb);在本例中,程序完成了两项工作:一是把 pss 指向的源字符串复制到 pds 所指向的目标字符串中,二是判断所复制的字符是否为0,若是则表明源字符串结束,不再循环。否则,pds 和 pss 都加 1,指向下一字符。在主函数中,以指针变量 pa,pb 为实参,分别取得确定值后调用 cprstr 函数。由于采用的指针变量 pa 和 pss,pb 和 pds 均指向同一字符串,因此在主函数和 cprstr 函数中均可使用这些字符串。也可以把 cprstr 函数简化为以下形式:cprstr(char *pss,char*pds)whil
7、e (*pds+=*pss+)!=0);即把指针的移动和赋值合并在一个语句中。 进一步分析还可发现0的 ASC码为0,对于 while 语句只看表达式的值为非 0 就循环,为 0 则结束循环,因此也可省去“!=0”这一判断部分,而写为以下形式:cprstr (char *pss,char *pds)while (*pdss+=*pss+);表达式的意义可解释为,源字符向目标字符赋值,移动指针,若所赋值为非 0 则循环,否则结束循环。这样使程序更加简洁。【例 10.30】简化后的程序如下所示。cpystr(char *pss,char *pds)while(*pds+=*pss+);main()
8、char *pa=CHINA,b10,*pb;pb=b;cpystr(pa,pb);printf(string a=%snstring b=%sn,pa,pb);10.4.2 使用字符串指针变量与字符数组的区别用字符数组和字符指针变量都可实现字符串的存储和运算。但是两者是有区别的。在使用时应注意以下几个问题:1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以0作为串的结束。字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。2. 对字符串指针方式char *ps=C Language;可以写为:char *ps;ps
9、=C Language;而对数组方式:static char st=C Language;不能写为:char st20;st=C Language;而只能对字符数组的各元素逐个赋值。从以上几点可以看出字符串指针变量与字符数组在使用时的区别,同时也可看出使用指针变量更加方便。前面说过,当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。但是对指针变量直接赋值是可以的。因为 C 系统对指针变量赋值时要给以确定的地址。因此, char *ps=C Langage;或者 char *ps; ps=C Language;都是合法的。10.5 函数指针变量在语言中,一个函数总是占用一段连续的内存区
10、,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为“函数指针变量 ”。函数指针变量定义的一般形式为:类型说明符 (*指针变量名)();其中“类型说明符” 表示被指函数的返回值的类型。 “(* 指针变量名)”表示“*”后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数。例如:int (*pf)();表示 pf 是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。【例 10.31】本例用来说明用指针形式实现对函数调用的方法。
11、int max(int a,int b)if(ab)return a;else return b;main()int max(int a,int b);int(*pmax)();int x,y,z;pmax=max;printf(input two numbers:n);scanf(%d%d,z=(*pmax)(x,y);printf(maxmum=%d,z);从上述程序可以看出用,函数指针变量形式调用函数的步骤如下:1) 先定义函数指针变量,如后一程序中第 9 行 int (*pmax)();定义 pmax 为函数指针变量。2) 把被调函数的入口地址(函数名)赋予该函数指针变量,如程序中第
12、11 行 pmax=max;3) 用函数指针变量形式调用函数,如程序第 14 行 z=(*pmax)(x,y);4) 调用函数的一般形式为:(*指针变量名) (实参表)使用函数指针变量还应注意以下两点:a) 函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。b) 函数调用中(*指针变量名)的两边的括号不可少,其中的*不应该理解为求值运算,在此处它只是一种表示符号。10.6 返回指针值的函数前面我们介绍过,所谓函数类型是指函数返回值的类型。在语言中允许一个函数的返回值是一个指针(即地址),这种返回指
13、针值的函数称为指针型函数。定义指针型函数的一般形式为:类型说明符 *函数名(形参表) /*函数体 */ 其中函数名之前加了“*” 号表明这是一个指针型函数,即返回值是一个指针。类型说明符表示了返回的指针值所指向的数据类型。如:int *ap(int x,int y). /*函数体*/表示 ap 是一个返回指针值的指针型函数,它返回的指针指向一个整型变量。【例 10.32】本程序是通过指针函数,输入一个 17 之间的整数,输出对应的星期名。main()int i;char *day_name(int n); printf(input Day No:n);scanf(%d,if(i%sn,i,da
14、y_name(i);char *day_name(int n)static char *name= Illegal day,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday;return(n7) ? name0 : namen);本例中定义了一个指针型函数 day_name,它的返回值指向一个字符串。该函数中定义了一个静态指针数组 name。name 数组初始化赋值为八个字符串,分别表示各个星期名及出错提示。形参 n 表示与星期名所对应的整数。在主函数中,把输入的整数 i 作为实参,在printf 语句中调用 day_name 函
15、数并把 i 值传送给形参 n。day_name 函数中的 return 语句包含一个条件表达式,n 值若大于 7 或小于 1 则把 name0指针返回主函数输出出错提示字符串“Illegal day” 。否则返回主函数输出对应的星期名。主函数中的第 7 行是个条件语句,其语义是,如输入为负数(i0)则中止程序运行退出程序。exit 是一个库函数,exit(1)表示发生错误后退出程序,exit(0)表示正常退出。应该特别注意的是函数指针变量和指针型函数这两者在写法和意义上的区别。如int(*p)()和 int *p()是两个完全不同的量。int (*p)()是一个变量说明,说明 p 是一个指向函数入口的指针变量,该函数的返回值是整型量,(*p)的两边的括号不能少。int *p()则不是变量说明而是函数说明,说明 p 是一个指针型函数,其返回值是一个指向整型量的指针,*p 两边没有括号。作为函数说明,在括号内最好写入形式参数,这样便于与变量说明区别。对于指针型函数定义,int *p()只是函数头部分,一般还应该有函数体部分。