数组指针与字符串_第1页
数组指针与字符串_第2页
数组指针与字符串_第3页
数组指针与字符串_第4页
数组指针与字符串_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、(1)熟练掌握一维和二维数组的定义和初始化,数 组元素的引用。 (2)掌握一维字符数组和字符串,二维字符数组和字符串数组。 (3)熟练掌握指针和地址的概念 (4)熟练掌握指针变量的定义和初始化 (5)熟练掌握通过指针引用指向实体 (6)掌握通过指针变量引用数组元素及处理字符串 (7)掌握指针数组和指向指针的指针(二级指针),第三讲 数组、指针和字符串,数 组,C语言中,数组是一个构造数组类型。数组是一组相同类型(基本类型或结构类型)的变量的集合,数组中的每个数据称为数组的元素,元素在数组中按线性顺序排列。 用数组名代表逻辑上相关的一批数据,每个元素用下标变量来区分,下标变量代表元素在数组中的位

2、置。 C语言中的数组的分类: 按元素的数据类型可分为:整型数组、字符数组、实型数组、结构体数组、共用体数组、指针数组等。 按数组维数可分为:一维数组、二维数组、多维数组。 数组在内存中占用一片连续的存储单元,最低地址对应于数组的第一个元素,最高地址对应于最后一个元素。,数组定义: 一维数组: 类型说明符 数组名 常量表达式; 二组数组: 类型说明符 数组名 常量表达式1常量表达式2; 例如: int a10 , x34;,从C语言二维数组的定义可以看出,一个二维数组也可以分解为多个一维数组。 例如: int a34 即: a00, a01, a02, a03 a10, a11, a12, a1

3、3 a20, a21, a22, a23 二维数组是按行排列的,即按行顺次存放,先存放a0行,再存放a1行,最后存放a2行。 每行中的元素也是依次存放。,1. C语言中规定数组的下标从0开始,方括号中常量表达式表示数组元素的个数。 2. 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。 数组名的书写规则应符合标识符的书写规定。 数组名不能与其它变量名相同。 允许在同一个类型说明中,说明多个数组和多个变量。 不能在方括号中用变量来表示元素的个数, 但可以是符号常数或常量表达式。 不允许对数组的大小作动态定义 。,注 意:,初始化 定义同时赋初值 例如: i

4、nt a10=1,2,3,4,5,6 int x=3,5,7,9,11 使用赋值语句逐个赋值 注意: 1. 可以只给前面部分元素赋初值,其余元素自动赋0。 2. 只能给元素逐个赋值,不能给数组整体赋值。 3. 二维数组可按行分段赋值,也可按行连续赋值,未赋值的自动取零。 4. 当 中值的个数多于元素个数时,系统出错。,二维数组可按行分段赋值,也可按行连续赋值。 1. 按行分段赋值可写为 int 33=80,75,92,61,65,71,59,63,70; 2. 按行连续赋值可写为 int a53= 80,75,92,61,65,71,59,63, 70; 这两种赋初值的结果是完全相同的。,数组

5、引用: 数组名下标 数组名下标1下标2 指针法引用: 一维数组a, *(a+i) 等价于ai 二维数组a * (*(a+i)+j) 等价于aij 注 意: 1、只能通过下标变量逐个引用数组元素,而不能 一次引用整个数组的全部元素。 2、数组说明的方括号中给出的是某一维的长度;而数组引用中的下 标是该元素在数组中的位置标识。前者只能是常量,后者可以是常量,变量或表达式。,练 习,判断题(P18) 34C语言中的数组下标从0开始,当引数组元素超过所定义的范围,将出来编译错误。 38假定int类型变量占用两个字节,若有定义:int x10=0,2,4;,则数组x在内存中所占字节数是6。,填空题 (P

6、21) (18)引用二维数组a第i行、第j列的元素(i、j为0表示第1行、第1列),可以写作: 或 。 (20)数组声明为“float x75;”若x64是内存中从x00数起的第35个元素,则x44是第 个元素。,单项选择题 (P22) 6下列数组声明语句中,正确的是( )。 A、int a=1, 2, , 4, 5; B、char a5=A, B, C, D, E; C、int a5=1, 2; D、char a5= Hello;,7数组声明语句为“int a6;”,输入数组所有元素的语句应为( )。 A、scanf(%d%d%d%d%d,a6); B、for(int i=0; i6; i+

7、) scanf(%d, a+i); C、for(int i=0; i6; i+) scanf(%d, *a+i); D、for(int i=0; i6; i+) scanf(%d, ai);,程序填空(P26),7输入10个数,输出其中与平均值之差的绝对值最小的数。 # include (1) void main() float a10, s , d, x; int i; for(i=0; i10; i+) (2) ; (3) for(i=0; i10; i+) s+=ai; s/=10; d=fabs(a0-s); (4) ; for(i=1; i10; i+) if(fabs(ai-s)d

8、) d= (5) ; x=ai; printf(%f, x);,(1) #include (2) scanf(“%d”, (4) x= a0 (5) fabs(ai - s),8输出如下形式的二项式系数列标。要求表的行数运行时输入,若小于1或者大于10则重新输入。 # includevoid main() int a1010=0, i, j, n; while( (1) , n10); for(i=0; in; i+) ai0=1; (2) ; for(i=2; in; i+) for(j=1; ji; j+) aij=ai-1j+ (3) ; for(i=0; in; i+) for(j=0

9、; j=i; j+) printf(%4d, aij); (4) ; ,1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 51,(1) scanf(“%d”, int *pa; pa=,指针变量的定义其一般形式为: 类型说明符 *变量名; *表示这是一个指针变量,变量名即为定义的指针变量名; 类型说明符表示指针变量所指向的变量的数据类型(基类型)。 例如: int *p1; 表示p1是一个指针变量,它的值是某个整型变量的地址。 或者说p1指向一个整型变量。 至于p1究竟指向哪一个整型变量,应由向p1赋予的地址来决定。,指针变量的定义,static int *p2;

10、 /*p2是指向静态整型变量的指针变量*/ float *p3; /*p3是指向浮点变量的指针变量*/ char *p4; /*p4是指向字符变量的指针变量*/,再如:,注意: 一个指针变量只能指向同类型的变量,如p3 只能指向浮点变量,不能时而指向一个浮点变量,时而又指向一个字符变量。 这是由于指针的移动和运算都与基类型有关。,指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机。 指针变量的赋值只能赋予地址,不能赋予任何其它数据,否则将引起错误。 语言中提供了地址运算符 int *p=,设有指向整型变量的指针变量p,

11、如要把整型变量a 的地址赋予p可以有以下两种方式:,(2)赋值语句的方法: int a, *p; p=,指针变量可以进行某些运算,但其运算的种类是有限的,只能进行赋值运算和部分算术运算及关系运算。 1. 指针运算符 (1)取地址运算符 pa= /*把整型变量a的地址赋予整型指针变量pa*/ 把一个指针变量的值赋予指向相同数据类型变量的另一个指针变量。,2. 赋值运算,void main() int a=1,b=2,*pa= ,例如:,若改为*pa=*pb; 有何不同?,void main() int a=1,b=2,*pa= ,例如:,把数组的首地址赋予指向数组的指针变量。 例如: int a

12、5,*pa; pa=a; (C语言规定数组名表示数组的首地址) 也可写为: pa=,把字符串的首地址赋予指向字符类型的指针变量。 例如: char *pc; pc=C language; 或用初始化赋值的方法写为: char *pc=C Language; 这里应说明的是并不是把整个字符串装入指针变量, 而是把存放该字符串的字符数组的首地址装入指针变量。 输出字符串是可以使用s格式字符串,即语句 printf(“%s”,pc);,指针变量可以赋予0值,p=0表明p是空指针,它不指向任何变量 在头文件stdio.h中有: #define NULL 0 因此在C程序中常使用 int *p=NULL

13、; 让指针变量p为空指针。 对指针变量赋0值和不赋值是不同的。指针变量未赋值时,可以是任意值,是不能使用的。否则将造成意外错误。 而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。,说 明:,void main() int a,b,*p,*p1= ,例如:输入a、b两个整数,按先大后小的顺序输出,一个数组是由连续的一块内存单元组成的。C语言规定:数组名就是这块连续内存单元的首地址(数组的指针)。 一个数组也是由各个数组元素(下标变量) 组成的。每个数组元素按其类型不同占有几个连续的内存单元。 一个指针变量既可以指向一个数组,也可以指向一个数组元素,可把数组名或第一个元素的地址赋予它。

14、 要使指针变量指向第i号元素可以把第i号元素的首地址赋予它或把数组名加i 赋予它。,数组的指针,例:int a10,*p=a; p,a, for(i=0;i5;i+) scanf(%d , ,void main() int a5,i,*pa=a; for(i=0;i5;i+) scanf(%d , pa); pa+; for(i=0;i5;i+) printf(a%d=%dn,i,*pa); pa+; ,第二种方法为指针法,即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素。,分析程序中存在的问题,pa=a;,void main() int a5,i; for(i=0;i5;

15、i+) scanf(%d , a+i); for(i=0;i5;i+) printf(a%d=%dn,i,*(a+i); ,三种方式的比较: (1)下标法比较直观,但执行效率低。 (2)ai 编译时转换为*(a+i) ,计算出元素的地址。 (3)使用指针变量引用元素,用p+指向下一个元素,因执行效率较高。,第二种方法为指针法,即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素。,1、指针变量可实现本身值的改变 例如: int a10,*p=a p+ 指向a1元素 可以使用下面语句来输入数组元素。 for(p=a;pa+10;p+) scanf(%d,p); 使用指针变量引用数

16、组元素时要注意指针变量当前的指向,否则将出错。,使用指针变量要注意的几个问题:,2、数组名表示数组首地址,是地址常量,不能出现如下运算:,设有定义: int a10,*p=a; (1) p+ 指向下一个元素,p的实际值加sizeof(int) 2, (2) *p+ 等价于 *(p+) (3) *(p+) 与 *(+p)不同 (4) (*p)+ 表示p当前所指向元素的值加1 (5) 若p= int *p= p为指向数组元素的指针变量,引用二维数组元素的方法: p+1则表示指向当前元素的下一个元素 元素aij的地址表示为: p+4*i+j 元素aij的值表示为: *(p+4*i+j) 如果一个n*

17、m的二维数组的第 i 行第 j 列元素相对于首地址的增量为: i*m+j 以上可以体现出数组下标从0开始的优点。,void main() int a34=0,1,2,3,4,5,6,7,8,9,10,11; int i,*p; p= ,例: 用指针变量输出二维数组元素的值,改成p=可否? 为什么?,因为nm的二维数组a可分解为一维数组a0,a1,. .am-1,而它们分别又是具有m个元素的一维数组。 因此可定义一个指向由m个元素组成的一维数组的指针变量来处理二维数组。 这个指针变量称为:行指针变量 行指针变量说明的一般形式为: 类型说明符 (*指针变量名)长度 例:int (*p)4 它表示p

18、是一个指针变量,它指向由4个元素组成的一维数组,或说p可指向一个有4列的二维数组。,2、指向由m个元素组成的一维数组的指针变量,定义一个数组指针变量 p , 指向包含 4 个元素的一维数组。,定义方法: int (*p)4;,定义:int a34; p= /*p指向a0*/ 则p+1 不是指向a01,而是a1,p的增值以一维数组的长度为单位。故aij可表示为:*(*(p+i)+j)。,例: 使用指针输出二维数组任一行任一列元素的值。,main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23 ; int (*p)4 , i , j ; p=a ; scanf(

19、%d,%d , ,运行结果: 输入: 1, 2 输出: a12=13,说明: aij 的地址可以表示为: *(p+i) + j 注意*(p+i) + j 不能写成 p+ i+j 对于行指针变量p, p=a; 则p 指向二维数组 a 的第一行首地址 。 对于指针变量 p,p=a0;则 p 指向二维数组 a 的第一行第一列元素首地址,而 p=a ; 是不合法 的。,设有定义: int a34,i,j; (1)下标法: aij (2)指针法: *(*(a+i)+j) 或者 *(ai+j),引用二维数组元素的方法:,a 二维数组首地址,第0行首地址 a0,*(a+0),*a,”,数组元素a1是否又可以

20、写作“*(a+)”? 原因是 。 (19)数组声明为“int a66;”,表达式“*a+i”是指 、“*(a+i)”是指 、“*a”又是指 。,填空题 (P21) (27) 有定义int a35,(*P)5=a; 则通过指针变量P引用数组元素a24的表达式是_。 (28)有定义: int a3=1,2,3,4,5,6,8,9,10,则printf(%d,*(*(a+1)+2)语句的输出结果为 。 (30)设int x=1,2,3,4,y,*p= 后变量y的值为_。,单项选择题 (P22) 8数组声明语句为“float a34;”,引用第3行第1列的元素写作( )。A、*(a+2) B、*(*a

21、+2) C、a31 D、*(a3+1) 13下列语句定义px为指向int类型变量x的指针,其中哪一个是正确的( )。 A、int *px=x, x; B、int *px=,单项选择题 (P22) 16数组定义为“int a45;”,哪一个引用是错误的()。 A、*a B、*(*(a+2)+3) C、,程序12# includevoid main() int x44=1, 2, 3, 4, 3, 4, 5, 6, 5, 6, 7, 8,7, 8, 9, 10, int i, j; for(i=0; i4; i+) for(j=0; j4; j+) *(*(x+i)+j)/= *(*(x+i)+i

22、); for(i=0; i4; i+) for(j=0; j4; j+) printf(%3d, *(*(x+i)+j); putchar(n); ,P33 程序阅读,1234015600180001,字符数组,初始化 若只给前面部分元素赋初值,其余元素自动赋0。 例如 char 10=c, ,p,r,o,g,r,a,m; 其中c9未赋值,由系统自动赋予为空字符0 值。 当对全体元素赋初值时也可以省去长度说明。,用来存放字符量的数组称为字符数组。 字符数组的定义 字符数组类型说明的形式与前面介绍的数值数组相同。 例如: char c10; 定义有10个元素的数组 例如: char ch510;

23、 即为5*10 的二维字符数组。,在语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。字符串总是以0作为串的结束符。 因此当把一个字符串存入一个数组时,也把结束符0存入数组,并以此作为该字符串是否结束的标志。 有了0标志后,就不必再用字符数组的长度来判断字符串的长度了。 当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。,字符串和字符串结束标志,语言允许用字符串的方式对数组作初始化赋值。 例如: char c =C, ,p,r,o,g,r,a,m; 可写为: char c =“C program”; 或写为: char c =C program;,

24、由于采用了0标志,所以在用字符串赋初值时一般无须指定数组的长度,而由系统自行处理。 除了上述用字符串赋初值的办法外,还可用printf函数和scanf函数中使用“%S”格式控制符一次性输出/输入一个字符数组中的字符串,而不必使用循环语句逐个地输入输出每个字符。,字符数组的输入输出,输出表列中给出数组名即可, 不能写为:printf(%s,c ); 在语言中规定,数组名就代表了该数组的首地址。 当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。,示 例:,main() char c =BASICndBASE; printf(%sn,c); ,指向字符串的指针变量的

25、定义与指向字符变量的指针变量说明是相同的。只能按对指针变量的赋值不同来区别。 对指向字符变量的指针变量应赋予该字符变量的地址。 char c,*p= ,字符串的指针和指向字符串的指针变量,void main() char *ps=this is a book; int n=10; ps=ps+n; printf(%sn,ps); 程序运行的结果为?,例:输出字符串中n个字符后的所有字符。,book,void main() char a=this is a book,b16; int n; for(n=0;an!=0;n+) *(b+n)=*(a+n); *(b+n)=0; printf(%sn

26、,b); ,例:字符串的复制,void main() char a=this is a book; char b16,*p1,*p2; p1=a;p2=b; while(*p1!=0) *p2+=*p1+; *p2=0; p2=b; printf(%sn,p2); ,例:字符串的复制,void main() char *p1=this is a book ; char *p2; while (*p1!=0) . . . /* 以下与上面相同*/ ,问能否将程序写成如下形式?,危险的使用,1.字符串输出函数 puts,Str为数组名或指针变量,格式: puts (str) ;,它等价于: pri

27、ntf(%s,str);,格式: gets (str);,Str为数组名或指针变量,功能:从键盘上输入一个字符串直到回车键结束。将输入的字符串加上结束标志0,存放到数组或字符指针所指向的一片存储单元。,2.字符串输入函数gets,字符串常用函数,#includestdio.h main() char st15; printf(input string:n); gets(st); puts(st); ,示例:,说明:当输入的字符串中含有空格时,输出仍为全部字符串。因gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与scanf函数不同的。,格式: strcat (str

28、1,str2) 功能:把字符数组str2中的字符串连接到字符数组str1 中字符串的后面,并删去字符串1后的串标志“0”。 本函数返回值是符数组1的首地址。 注意: (1) 字符数组1必须足够大,以便容纳连接后的新字符串。 (2) 连接时将字符数组1后面的0取消,在新串后保留一个0。,3.字符串连接函数strcat,格式: strcpy (str1,str2) 功能:把字符数组str2中的字符串拷贝到字符数组str1中。串结束标志“0”也一同拷贝。,4.字符串拷贝函数strcpy,(1)复制时串结束标 志“0”也一同拷贝。 (2)不能用一个赋值语句将一个字符串常量或字符数组直接给一个字符数组。

29、不允许 str1=“hello”; 或 str1=str2; (3)可以用strcpy函数将字符串2中前面的若干字符复制到字符数组1中。 strcpy(str1,str2,4); (4)字符数组1必须写成数组名形式,字符数名2可以是一个字符串常量。相当于把一个字符串赋予一个字符数组。 strcpy(str1,”hello”);,格式: strcmp(str1,str2) 功能:对两个字符串自左向右逐个比较,直到出现不相同的字符或遇到n。如果全部字符相同,则认为相同,若出现不相同的字符,则以第一个不相同的字符比较结果为准,返回是不相同字符ASCII码之差(str1-str2)。 比较结果: st

30、r1str2, 返回值0; str1 str2, 返回值 0; str1 str2, 返回值 0。 本函数也可用于比较两个字符串常量,或比较数组和字符串常量。,5.字符串比较函数strcmp,格式: strlen(str) 功能:测字符串的实际长度(不含字符串结束标志0) 并作为函数返回值。,6.测字符串长度函数strlen,例如: char st=“C language”; 则strlen(st)的返回值为 10 char st=C lang65u0age 则strlen(st)的返回值为 8。 注意:strlen函数返回的是从第一个字符开始的碰到的第一个结束标志“0”字符串中的转义字符(如

31、n,65)都按一个字符计算。,格式: strlwr(str) 功能:将字符串str中的大写字母转换为小写字母。,7. 字符大写转小写函数strlwr,8. 字符小写转大写函数strupr 格式: strupr(str) 功能:将字符串str中的小写字母转换为大写字母。,指针数组的概念 一个数组的元素值为指针则这个数组称为是指针数组。 指针数组是一组有序的指针的集合。 指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。 指针数组说明的一般形式为: 类型说明符 *数组名数组长度 其中类型说明符为指针值所指向的变量的类型。 例如: int *pa3; 表示pa是一个指针数组,它

32、有三个数组元素, 每个元素值都是一个指针,指向整型变量。,指针数组和指向指针的指针,#include string.h void main() void sort(char *name,int n); void print(char *name,int n); char *name= CHINA,AMERICA, AUSTRALIA, FRANCE,GERMAN; int n=5; sort(name,n); print(name,n); ,例:由字符指针数组处理多个字符串的问题,void sort(char *name,int n) char *pt; int i,j,k; for(i=0;

33、i0) k=j; if(k!=i) pt=namei; namei=namek; namek=pt; void print(char *name,int n) int i; for (i=0;in;i+) printf(%sn,namei); ,P80程序调试题,2程序功能:调用函数f,求二维数组a中全体元素之和。 #include float f( _1_) float y=0; int i,j; for(i=0;im;i+) for(j=0;jn;j+) y=y+*(*(x+i)+j); return y; void main() float a34=1,2,3,4,5,6,7,8,9,1

34、0,11,12,*b3; int i; for(i=0;i3;i+) bi=_2_; printf(%.2fn,f(b,3,4); ,(1) float *x,mint m,int n,(2) ai,指针数组名同样表示指针数组的首地址,是一个指针变量的地址,即是指针的指针。 指针变量在内存中仍有一个存储单元,该单元的地址,即指针的指针。如图:,指向指针的指针变量的定义:int a, *p=a;*pp=,类型说明符 *指针名,指向指针的指针,例声明语句为“char a=%, *b=”,下列表达式中错误的是( )。 A、a=*c B、b=*c C、*c=% D、 int i=0; strcat(a

35、,b); while(ai+!=0) bi=ai; puts(b); (a) LB (b ) ABLMNP ( c) AB (d) LBLMNP,练 习 题,写出下面程序的运算结果 #include #include void main() char c,*a=Office; int i; for (i=0;istrlen(a)/2;i+) c=*a; strcpy(a,a+1); astrlen(a)=c; puts(a); getch(); ,fficeO ficeOf iceOff,练 习(复习指导书),填空题 (P21) (21)声明“char str120= Borland c+ 5.0”后,使字符串str1为Borland的赋值表达式,应为 。 (22)将包括空格在内的6个字符串输入到字符数组a620 中,输入语句可以写作: 。 (26)定义语为char a10 =john0ni;,语句printf(%d,strlen(a);输出结果是_。 (29)若有如下定义和语句,请写出通过指针p取字符g的表达式 。 char s8=”abcdefghijk”, *p=s;,单项选择题 (P23),11数组声明为“char str120= Borland, str2=C+5.0;”,调用函数“strcat(str1, str2);”后,字符串str1的串长是(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论