1、6.2.3 指针与字符串(字符数组), C语言用字符数组存放字符串。 字符数组:元素个数确定,一般用下标控制循环。 字符串:有效字符个数由0确定,用结束符0控制循环。, 字符数组名和字符串的值都是地址(字符串的首地址 ),1、字符串的访问方法: 直接引用字符串:,char *chp,ch =”abcde”; /*定义字符指针和字符数组*/ chp=ch; /*指针指向字符数组*/ putchar( *(chp+2); /*通过指针引用数组元素*/ printf(“%s,%s”,ch+1,chp+2);, 引用字符数组:,char *chp; /*说明字符指针*/ chp=“Hello!”; /
2、*指针指向字符串*/ puts(chp); /*通过指针引用字符串*/,字符指针可直接指向字符串:char *chp=“Hello!”;,输出?,无名一维字符数组 0,例1: 输出字符串,#includevoid main() char s =“computer”, *ps=s ; while(*ps!=0) putchar(*ps);ps+; ,main( ) char str80, *p, ch;int i=0;p=str;gets(p);ch=getchar();for( ; *p!=0;p+) if(*p!=ch) stri+=*p;stri=0;printf(“The new str
3、ing is:%sn”,str); ,例2:在输入的字符串中删除指定的字符,2000H,p,0,ch,0,i,运行程序: abcdefc, ,2000H,str,c,str,printf(“%s”,ps); 或: puts(ps),The new string is: abdef,字符指针(变量)与字符数组的区别,字符指针与字符数组:两者均可存储和运算字符串。 主要区别: 存储格式不同: 字符指针变量中存放的是字符串的首地址(2字节);而字符数组中存放的是整个字符串(一个数组元素存放一个字符)。 性质不同:字符数组名是地址常量,不能改变(指向首字符); 字符指针是地址变量,可以改变(指向不同的
4、字符)。 赋值方式不同:,字符指针,char *ps=“Hello”;,char *ps;ps=“Hello”;,字符数组,char st =“Hello”;,char st80;st=“Hello” 或:st =“Hello”,用循环逐个赋值或用strcpy()函数赋值,例: 统计字符串中的各元音字母的个数(P182 例6.15),#include void main(void) char str80,*p;int a=0,e=0,i=0,o=0,u=0;gets(str);for(p=str;*p!=0;p+)switch(*p)case a: case A: a+; break;case
5、 e: case E: e+; break;case i: case I: i+; break;case o: case O: o+; break;case u: case U: u+; printf(“a:%3dne:%3dni:%3dno:%3dnu:%3dn“,a,e,i,o,u); ,循环遍历数组元素,判断字母。,判断字符串是否结束,2. 字符串指针做函数参数(见P183 表6-2),#include void cpystr(char *s1, char *s2) while(*s2!=0 )*s1+=*s2+;*s1=0; void main (void ) char str120,
6、str2 =“123456abcdef“;printf(“str2: %sn“,str2);printf(“str1: %sn“,str1);cpystr(str1,str2);printf(“str2: %sn“,str2);printf(“str1: %sn“,str1); ,去掉该句,对程序结果是否有影响?,例: 编写函数,用指针进行字符串的复制,6.2.4 指针数组,指针是存放其它数据对象地址的变量。也可以构成数组。每个数组元素均为一个指针变量,且在内存中连续存放。,1. 指针数组定义,格式: type *数组名元素个数;,int *p 4 ;,定义(说明)p是含有4个元素的指针数组,
7、每个元素都是 一个指向整型变量的指针(二级指针) 。,数组名p为数组的首地址。,使用前必须让各元素指向对象。,int i, a34, *p3; for(i=0;i3;i+)p i =a i ; *(pi+j)=2; /*通过指针数组引用数组元素aij*/,2、用指针数组处理多字符串,例:用指针数组对字符串进行排序。,#include void main(void ) int i, j ; char *ps = “Get“, “Put“, “Time“, “Date“, *p ; printf(“排序前字符串 :n“); for(i=0;i0)p=psi;psi=psj;psj=p; print
8、f(“排序后字符串 :n“); for(i=0;i4;i+) puts(psi); ,循环实现排序,ps,2、指针数组访问二维数组,通过指针数组输出数组元素的值, 分析运行结果。,#include void main( ) int i , j;int a33= 1,2,3, 4,5,6, 7,8,9 ;int *pa3= a0, a1, a2 ;int *p=a0;for (i=0 ; i3 ; i+) for (j=0; j3; j+)printf (“ %5d“, paij );printf ( “n“ ) ; for(i=0;i3;i+)printf(“%d,%d,%dn“,ai2-i,
9、*ai,*(*(a+i)+i);for(i=0;i3;i+)printf(“%d,%d,%dn“,*pai,pi,*(p+i); ,pa0,数组a的二维结构,pa1,pa2,a0,a1,a2,6.3 指针与函数,6.3.1 指向函数的指针 概念:函数为程序实体,其代码占据连续的内存地址,其首地址 称为函数的入口地址,用函数名表示。C语言通过指针指向函数 的入口地址(函数名),也可以实现函数的调用。,c=max(a,b);,int max(int x, int y) return (x=y?x:y); ,2400H,函数指针变量的定义:,type ( *p )( );,函数的类型。,指针变量名,
10、函数,使用步骤:, 定义函数fname和指向函数的指针p; 指针指向函数; p=fname; 通过指针引用函数。 格式:(* p)(实参表);, , ,main( ),举例:求a、b的最大值。,#include int lmax(int,int); void main(void) int a,b,c;int (* funp)( );funp=lmax;scanf(“%d,%d”, ,说明指向函数的指针。,指针指向函数。,funp,lmax,通过指针引用函数。,lmax,2100H,2100H,6.3.2 返回指针的函数,概念:函数可以返回一个值,也可以返回一个地址(指针),如果函数返回指针,称
11、为返回指针的函数。,定义:type *函数名(形参表) /* 函数体 */,int *max(int a, int b),注意: int (*p)( ) 和 int *p( ) 的区别:int (*p)( ) 是定义一个 变量(p是一个指向函数入口的指针变量);int *p( ) 则是定义一个函数(p是一个返回值为指针的函数),它还有函数体部分。,例: 输入一个17之间的整数,输出对应的星期名。,char *day_name(int n)char *name =“Illegal day”,”Monday”,”Tuesday”,”Wednesday”, “Thursday”,”Friday”,”
12、Saturday”,”Sunday”;return (n7) ? name0: namen) ; #includemain ( )int i;printf ( “Input Day No: n”);scanf ( “%d”, ,定义一个指针型函数, 其返回值指向一个字符串,形参 n 为星期名对应的整数,exit为一库函数,exit(1)有错退出程序,exit(0)正常退出,name为一指针数组,每个元素均为指针变量。,运行结果:,Input Day No: 2 Day No: 2 Tuesday,6.3.3 main函数的参数,如DOS命令:C:test aa bb cc,可执行文件名,命令参
13、数,主函数main()也可以带参数,由于main()不能被其他函数调用,故无法在程序内部取得实参值。它的参数来自dos提示符命令行(如用命令行运行编译连接好的.exe文件),实参就是命令行输入的字符串。主函数一般有两个参数。,void main(int argc, char *argv ) (函数体) ,整型变量。存放命令行字符串的个数(以空格分隔) 。,指向字符的指针数组。分别存放各字符串参数的地址。,举例:编程显示命令行输入的参数。,#include void main(int argc, char *argv ) int i;printf(“argc=%dn“, argc);for(i=
14、0; iargc; i+)printf(“argv%d=%sn “,i, argv i ); ,test How are you? (该程序名应为test.c,编译、连接后生成test.exe),C:,argc 4,*举例:在字符串中查找特定的字符。,#include #include char *lstrchar ( char * , char ) ; void main ( void) char c , *p , str80 ;gets (str ) ;scanf ( “ %c ” , ,返回指针的函数。,指向空!, 课堂作业:, #include main() int i;char s5
15、,*p;for(i=0; is;p-)printf(“%s,%cn“,p,*p); ,写出下列程序运行结果。, #include int f(int *a,int n) if(n1)return *a+f(a+1,n-1);elsereturn *a; void main() int aa10=1,2,3,4,5,6,7,8,9,10,s;s=f(aa+1,4);printf(“%dn“,s); , 思考题:, 作业题:,p188习题一、选择题 720。二、填空题 47。三、程序运行题13。四、程序填空题2、4。五、程序设计题 2、3、6。,上机验证 p178 例 6.19 ,分析行指针定义(*p)n和指针数组定义*pn的异同点,进一步理解和记忆二维数组中数组元素和其地址的表示方法。,编程题:,#include #define N 3 void ss(int c3,int *s1,int *s2); void main(void) int aNN,bN;int i,j,k,sum1,sum2;for(i=0;iN;i+)for(j=0;jN;j+)scanf(“%d“, ,用指针编写函数分别求二维方阵主、辅对角线上元素的和 sum1 和 sum2。 要求:在主函数中输入a44,通过函数用指针求a44主、辅对角线元素的和。 见 ktzyss.c,