当前位置:首页 >> 理学 >>

第19讲 二维数组 字符串与指针 函数与指针lf


1

第19讲
二维数组 字符串与指针 函数与指针

一.指针与二维数组
1. a 二维数组和数组元素的地址
2000 a[0] 2002 a[0][0] a[0][1]

2

2000

a+12008

a[1]

? 对二维数组 int a[3][4],有 ?a-----二维数组的首地址,即第0行的首地址 a[0][2] ?a+i-----第i行的首地址 a[0][3] ?a[i] ? *(a+i)------第i行第0列的元素地址 2008 a[1][0] ?a[i]+j ? *(a+i)+j -----第i行第j列的元素地址 2010 ?*(a[i]+j) ? *(*(a+i)+j) ? a[i][j] a[1][1] a[1][2] ? a+i=a[i]=*(a+i) =&a[i][0], 值相等,含义不同 a[1][3] ?a+i 表示第i行首地址,指向行 2016 ?a[i] ? *(a+i) ? &a[i][0],表示第i行第0 a[2][0] 2018 列元素地址,指向列 a[2][1]

a+22016
a[2]

a[2][2]
a[2][3]

int a[3][4];
a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2]

地址表示: (1) a+1 (2) &a[1][0] (3) a[1] (4) *(a+1) (5)(int *) (a+1) 地址表示: (1) &a[1][2] (2) a[1]+2 (3) *(a+1)+2 (4)&a[0][0]+1*4+2

行指针

3

列指针

a[1][3]
a[2][0] a[2][1]

二维数组元素表示形式: (1)a[1][2] (2)*(a[1]+2) (3)*(*(a+1)+2) (4)*(&a[0][0]+1*4+2)

a[2][2]
a[2][3]

表示形式 a a[0],*(a+0),*a

含义 二维数组名,数组首地址

地址 2000 2000 2008 2008 2012 13

4

第0行第0列元素地址
第1行首地址 第1行第0列元素地址 第1行第2列元素地址 第1行第2列元素值

a+1 a[1],*(a+1) a[1]+2,*(a+1)+2,&a[1][2]
*(a[1]+2),*(*(a+1)+2),a[1][2]

例 用指针变量指向二维数组的数组元素
p
main() { static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int *p; for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0) printf("\n"); printf("%4d ",*p); } }
p=*a; p=&a[0][0]; p=(int *)a; p=a;
int a[3][4];

5

a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2]

a[1][3]
a[2][0] a[2][1]

a[2][2]
a[2][3]

2. 通过建立指针数组和行指针引用二维数组
? 定义形式: 数据类型 (*指针名)[一维数组的元素个数]; int a[3][4]; 例 int (*p)[4]; a p a[0][0]

6

( )不能少 (*p)说明p是一个指针变量!
(*p)[4]说明p的值是某个 包含4个元素的一维数组 的首地址,p是行指针

a[0][1]

p[0]+1或 *p+1 *(*p+1)或 (*p)[1] p+1 p[1]+2或 *(p+1)+2 *(*(p+1)+2) p+2

a[0][2]
a[0][3]

a+1

a[1][0]

a[1][1]
a[1][2] a[1][3]

可让p指向二维数组某一行
如 int a[3][4], (*p)[4]; p=a; p指向的一维数组的元素个数和 二维数组列数必须相同

a+2

a[2][0] a[2][1] a[2][2]

?指针数组: 如 int a[3][4], *q[4]; q[0]=&a[0][0]; q[1]=&a[2][0];

a[2][3]

例 指向一维数组的指针变量(行指针)应用 main() { static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int i,j,(*p)[4]; for(p=a,i=0;i<3;i++,p++) ?for(p=a,p<a+3;p++) for(j=0;j<4;j++) printf("%d ",*(*p+j)); ? p[0][j] printf("\n"); } p=a[0]; p=*a; p=&a[0][0]; p=a; ? p=&a[0];

p

int a[3][4];

7

a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2]

p

p

a[1][3]
a[2][0] a[2][1]

a[2][2]
a[2][3]

a+3

3. 二维数组名或行指针作函数的形参
8

通过指针引用二维数组的几种形式:
若int a[3][4]; int (*p1)[4]=a; int *p2=a[0]; 实参 形参

数组名a
数组名a 指针变量p1

数组名int x[][4]
指针变量int (*q)[4] 数组名int x[][4]

指针变量p1
指针变量p2

指针变量int (*q)[4]
指针变量int *q

例 3个学生各学4门课,计算总平均分,并输出第n个学生成绩 函数说明 void average(float *p,int n) 9 main() { float *p_end, sum=0,aver; { void average(float *p,int n); p_end=p+n-1; void search(float (*p)[4],int n); for(;p<=p_end;p++) float score[3][4]= sum=sum+(*p); {{65,67,79,60},{80,87,90,81}, aver=sum/n; {90,99,100,98}}; printf("average=%5.2f\n",aver); average(*score,12); } search(score,2); 列指针 void search(float (*p)[4], int n) } { int i; p printf(" No.%d :\n",n); 行指针float p[][4] p for(i=0;i<4;i++) 65 52 79 60 printf("%5.2f ",*(*(p+n)+i)); } 80 87 90 81 *(*(p+n)+i) ? p[n][i]
90 99 100 98

例 3个学生各学4门课,计算总平均分,并查找一门以上课 不及格学生, 输出其各门课成绩 void search(float (*p)[4], int n) p { int i,j,flag; 65 52 79 60 for(j=0;j<n;j++) 80 87 90 81 { flag=0; for(i=0;i<4;i++) *(*(p+j)+i) ? p[j][i] 90 99 100 98 if(*(*(p+j)+i)<60) flag=1; if(flag==1) { printf("No.%d is fail,his scores are:\n",j+1); for(i=0;i<4;i++) printf("%5.1f ",*(*(p+j)+i)); printf("\n"); main() } { void search(float (*p)[4], int n); } float score[3][4]={{...},{...},{...}}; } search(score,3); }

10

二维数组与指向一维数组的指针变量的关系
11

如有: int a[5][10],(*p)[10]; p = a ;
? ? ? ? ? ? 系统给数组a分配2*5*10个字节的内存区。 系统只给变量p分配能保存一个指针值的内存区(2字节); 数组名a的值是一个指向有10个元素的一维数组的指针常量; p=a+i 使 p指向二维数组的第i行; *(*(p+i)+j) ? a[i][j] ; 二维数组形参实际上是一个指向一维数组的指针变量, 即: fun(int x[ ][10]) ? fun(int (*x)[10]) 在函数fun中两者都可以有x++;x=x+2;等操作! 但在变量定义(不是形参)时,两者不等价;

指针数组与二级指针的关系
int **p 与 int *q[10] ?系统只给p分配能保存一个指针值的内存区;而给q分 配10个内存区,每个内存区均可保存一个指针值 ; ?指针数组名是二级指针常量; ?p=q; p+i 是q[i]的地址; ?指针数组作形参,int *q[ ]与int **q完全等价;但作 为变量定义两者不同。

12

二. 指针与字符串
1. 字符串表示形式
(1) 用字符数组实现 例 main( ) { char string[]=“I love China!”; printf(“%s\n”,string); printf(“%s\n”,string+7); }
string
I l o v e C h i n a ! \0

13
string[0] string[1] string[2] string[3] string[4] string[5] string[6] string[7] string[8] string[9] string[10] string[11] string[12] string[13]

(2) 用字符指针实现 14 字符指针初始化:把字符串首地址赋给string string 相当于以下两个语句: char *string; string="I love China!"; 例 main( ) { char *string="I love China!"; printf("%s\n",string); string+=7; *string!=0 while(*string) { putchar(string[0]); string++; } *string }
I l o v e C h i n a ! \0

string

2. 用指向字符串的指针作函数参数
例 字符串复制
void copy_string(char from[],char to[]) 15 { int i=0; while(from[i]!='\0') { to[i]=from[i]; i++; } to[i]='\0'; } main() { char a[]="I am a teacher."; char b[]="You are a student."; printf("string_a=%s\n string_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); }

(1)用字符数组 作参数

(2) 用字符指针变量作参数
例 实现字符串复制 16

void copy_string(char *from,char *to) { for(;*from!='\0';from++,to++) *to=*from; *to='\0'; } void main() { char *a="I am a teacher.123456789"; char b[80]="You are a student."; printf("string_a=%s\nstring_b=%s\n",a,b); 注意:数组b要有 足够的存储空间! copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); }

3. 字符指针变量与字符数组的分别
char *cp; 与 char str[20]; 17 ? 字符数组str由若干元素组成,每个元素放一个字符;而指针 变量cp中只能存放一个地址值。 char str[20]= "……"; (?) ? char str[20]; str= "I love China!"; (?) cp++; (?) char *cp; cp= "I love China!"; (?) str++; (?) ? str是地址常量;cp是地址变量。 str+1; (?) ? cp接受键入字符串时,必须先开辟存储空间。 例 char str[10]; scanf("%s",str); (?) 而 char *cp; scanf("%s", cp); (?) 改为: char *cp,str[10]; cp=str; scanf("%s",cp); (?)

4. 字符串与数组的关系
? 字符串用一维字符数组存放; ? 一维字符数组中若有一个元素的值为0,则该数组可当字符串用; ? 字符数组具有一维数组的所有特点; ? 数组名是指向数组首地址的地址常量; ? 数组元素的引用方法可用指针法和下标法; ? 数组名作函数参数是地址传递等; char str[80]; ? 区别 scanf(“%s”,str); ? 存储格式:字符串结束标志; printf(“%s”,str); gets(str); ? 赋值方式与初始化; puts(str); ? 输入输出方式:%s %c char str[]={“Hello!”}; char str[]=“Hello!”; char str[]={?H?,?e?,?l?,?l?,?o?,?!?}; char *cp=“Hello”; int a[]={1,2,3,4,5}; int *p={1,2,3,4,5}; (?) (?) (?) (?) (?) (?)

18

char str[10],*cp; int a[10],*p; str=“Hello”; (?) cp=“Hello!”; (?) a={1,2,3,4,5}; (?) p={1,2,3,4,5}; (?)

对字符串排序 例 对字符串排序(简单选择排序)
main() { void sort(char *name[],int n), print(char *name[],int n); char *name[]={"Follow me","BASIC", "Great Wall","FORTRAN","Computer "}; int n=5; void print(char *name[],int n) sort(name,n); { int i=0; print(name,n); char *p; } /*p=name[0];*/ void sort(char *name[],int n) while(i<n) { char *temp; { p=*(name+i++); int i,j,k; printf("%s\n",p); for(i=0;i<n-1;i++) } { k=i; } for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0) k=j; if(k!=i) { temp=name[i]; name[i]=name[k]; name[k]=temp;} } }

19

例 用二级指针处理字符串 20 用*p可输出地址(%o或%x), #define NULL 0 也可用它输出字符串(%s) void main() { char **p; char *name[]={"hello","good","world","bye",""}; p=name+1; printf("%o : %s ", *p,*p); p+=2; while(**p!=NULL) printf("%s\n",*p++); ?*(p++)右结合 }
运行结果: 644 : good bye

三. 指针与函数
?函数指针:函数被存放在内存中一片连续的存储单元内, 21
其中排在最前面的那个存储单元的地址就是这个函数的地 址,也叫函数指针,用函数名表示,它是一个地址常量。
max
指令1 指令2

?指向函数的指针变量

作用:专门存放函数的入口地址 可指向返回值类型相同的不同函数 ?定义形式: 数据类型 (*指针变量名)();

…...

函数返回值的数据类型 ( )不能省 int (*p)() 与 int *p()不同 如 int (*p)( );

函数指针变量的赋值
如 int (*p)( ); p = max;

max 指令1 指令2

22

…...

函数指针变量指向的函数必须有函数说明

函数调用形式: c= max(a,b); ? c= (*p)(a,b); ? c= p (a,b); 注意:对函数指针变量 p ? n , p++ 等操作没有意义!

1. 用指向函数的指针变量调用函数 23 main() main() { int max(int ,int); { int max(int ,int), (*p)(); int a,b,c; int a,b,c; scanf("%d,%d",&a,&b); p=max; c=max(a,b); scanf("%d,%d",&a,&b); printf("a=%d,b=%d,max=%d\n",a,b,c); c=(*p)(a,b); } printf("a=%d,b=%d,max=%d\n",a,b,c); int max(int x,int y) } { int z; int max(int x,int y) if(x>y) z=x; { int z; else z=y; if(x>y) z=x; return(z); else z=y; } return(z); }

2. 用指向函数的指针变量作函数参数
例 用函数指针变量作参数,求最大值、最小值和两数之和 24

void main() { int a,b,max(int,int), min(int,int),add(int,int); void process(int,int,int (*fun)()); scanf("%d,%d",&a,&b); process(a,b,max); process(a,b,min); process(a,b,add); } void process(int x,int y,int (*fun)()) { int result; result=(*fun)(x,y); printf("%d\n",result); }

max(int x,int y) { printf(“max=”); return(x>y?x:y); } min(int x,int y) { printf(“min=”); return(x<y?x:y); } add(int x,int y) { printf(“sum=”); return(x+y); }

3. 返回指针值的函数
函数定义形式:
类型标识符 *函数名(参数表); 例 int *f(int x, int y)

main() { float score[][4]={{60,70,80,90}, {56,89,67,88},{34,78,90,66}}; float *search(float (*pointer)[4],int n), *p; int i,m; printf("Enter the number of student:"); scanf("%d",&m); printf("The scores of No.%d are:\n",m); p=search(score,m); pointer for(i=0;i<4;i++) printf("%5.2f\t",*(p+i)); pointer+1 } float *search(float (*pointer)[4], int n) { float *pt; pt=*(pointer+n); return(pt); }

例 用指针函数 实现:有若干 学生成绩,要 求输入学生序 号后,能输出 其全部成绩。

25

p score数组
60 56 70 89 80 67 90 88

34

78

90

66

4. main函数的参数
? 命令行:在DOS操作系统状态下,为执行某个程序而键入的 26 一行字符 ? 命令行一般形式:命令名 参数1 参数2………参数n C:\TC> copy source.c temp.c <CR> 有3个字符串参数的命令行

?带参数的main函数形式:
形参名argc, argv任意 main(int argc, char *argv[]) { ……… } 指针数组:各元素指向命令 行参数中各字符串首地址 命令行中参数个数

命令行参数的传递
?命令行参数传递
系统自动调用 main函数时传递 命令行实参 main(int argc, char *argv[]) 27 { ……… }

main(形参)

C:\TC> copy source.c temp.c <CR>
argv char *argv[] argv[0]

"copy "
"source.c " "temp.c "

argc=3

argv[1] argv[2]

例 输出命令行参数 /*test.c*/ main(int argc, char *argv[]) { while(argc>1) { ++argv; printf("%s\n",*argv); --argc; } } 28

argv

char *argv[]

argv[0]

test hello world

argc=3

argv[1] argv[2]

1. 编译、链接test.c,生成可执行文件test.exe 2. 在DOS状态下运行(test.exe所在路径下) argc, char *argv[]) main(int { while(argc-->0) 例如: C:\TC> test hello world! printf("%s\n",*argv++); } 运行结果:test 运行结果:hello
world!

hello world!

有关指针操作的小结
1.指针变量是把其它变量的地址作为内容的变量。指针变量 的内容可以是0、NULL和一个确定的地址。 2. 地址运算符(&) 返回其操作数的地址。 地址运算符的操作数必须是一个变量(或数组元素)。 3. 指针运算符(*) 又称为“间接引用运算符” ,它表示从相 应的存储单元中获取某种类型的数据值。 4. 指针±整数 5. 指针1-指针2 6. 指针的关系运算,如:指针1<指针2 7. 在调用带有参数的函数时,如果调用函数要求被调用函数 修改参数的值,应该把参数的地址传递给被调用函数, 被调用函数用间接引用运算符(*)修改调用函数中的参数 的值。

29

指针的数据类型
定义 int i; int *p; int a[n]; int *p[n]; 定义整型变量i p为指向整型数据的指针变量 定义含n个元素的整型数组a n个指向整型数据的指针变量组成的指针数组p p为指向含n个元素的一维整型数组的指针变量 f为返回整型数的函数 p为返回指针的函数,该指针指向一个整型数据 p为指向函数的指针变量,该函数返回整型数 p为指针变量,它指向一个指向整型数据的指针变量

含义

30

int (*p)[n]; int f(); int *p();
int (*p)(); int **p;

例 下列定义的含义 (1)int *p[3]; (2)int (*p)[3]; (3)int *p(int); (4)int (*p)(int); (5)int *(*p)(int); (6)int (*p[3])(int); (7)int *(*p[3])(int);

指针数组 31 指向一维数组的指针 返回指针的函数 指向函数的指针,函数返回int型变量 指向函数的指针,函数返回int 型指针 函数指针数组,函数返回int型变量 函数指针数组,函数返回int型指针


赞助商链接
相关文章:
用指针处理二维数组
定义一个二维数组 int *p; p=a[0];//语句 p=a[i]等价于 p=&a[i][0],即将 p 指向数组 a 的第 i 行的第一个元 素 //下面来检验指针 p 是否...
《C语言程序设计II》期末复习
第 1~4 讲 指针 ? 指针的概念:内存单元的排列...字符指针函数参数,使用字符 指针变量和字符数组的...("\n"); } 19、实验_3 4、 (基础题)指针...
C++指针函数习题
C++指针函数习题 一、选择题 1.以下程序的运行结果...“%lf”,p); C) p=&a; scanf(“%lf”,*p)...个字符的一维字符数组的首地址 C)cc 是指针变量,...
C语言编程实验8
能否使用二维数组或者而为数组的行指针作为函数参数进行...编写返回字符指针函数搜寻一个字符串中第一个字符’...("sum=%.2lf\n",sum(4,ptr)); } double ...
指针知识点总结
变量、数组字符串、函数、结构体的指针,以及指向...8.函数与指针 函数与指针 (1)指针作为函数参数(...数组指针 知识点总结 19页 1下载券 c指针练习题...
实验8 指针的应用
指针对变量进行操作; 4、 掌握指针与数组的关系; 5、 了解通过指针操作字符串...程序 3 用指向二维数组第 0 行第 0 列元素的指针作为函数参数,编写一个能...
C语言程序设计第5章“使用指针参数交换两个变量值 ”案例
字符指针作为函数参 数 4. 用字符数组和字符指针处理字符串的区别 5.4 “学生成 绩查询”案例 【案例说明】 有一个班内有 5 个学生每个学生有 4 门功课的...
教材课后题答案-第6章_指针习题答案
求一个 3×3 二维数组主对角线元素之和。 #include <stdio.h> void main(...用指针参数编写一个字符串连接的函数 radd(char *s,char *t,int f),其中 ...
C++第5章习题解答
第五章 数组与指针习题 第五章 数组与指针习题一...”; 是否建立了一个字符串,并把”it’s a book...(num,19); cout<<atoi(num)<<'\n'; return ...
二维数组与指针
19】 } (11) 设在主函数中有以下定义和函数调用语句,且 fun 函数为 void...第2讲 二维数组与指针 23页 5下载券 第5讲 二维数组与指针 17页 1下载券...
更多相关标签: