C语言指针数组与指针指针2

上传人:桔**** 文档编号:570741960 上传时间:2024-08-06 格式:PPT 页数:72 大小:649.50KB
返回 下载 相关 举报
C语言指针数组与指针指针2_第1页
第1页 / 共72页
C语言指针数组与指针指针2_第2页
第2页 / 共72页
C语言指针数组与指针指针2_第3页
第3页 / 共72页
C语言指针数组与指针指针2_第4页
第4页 / 共72页
C语言指针数组与指针指针2_第5页
第5页 / 共72页
点击查看更多>>
资源描述

《C语言指针数组与指针指针2》由会员分享,可在线阅读,更多相关《C语言指针数组与指针指针2(72页珍藏版)》请在金锄头文库上搜索。

1、指针的复习 类型标识符类型标识符 *变量名;变量名;指针类型 指针指向的类型 指针指向的变量 指针变量的地址赋值: 变量名=目标变量的地址或同类型的指针变量、常量数组的复习类型标识符类型标识符 数组名数组名整型常量表达式整型常量表达式;例如:int a3;大小、类型(数组元素和数组)、变量集合定义后,其内存块和地址在生命期中保持不变数组名的两种含义:代表数组 指针常量验证: sizeof(a) sizeof(a+1)指针和数组的关系数组的类型标识符:数组类型 指针类型指针数组与指针的指针a001 a1a22a1指针数组与指针的指针1 指针数组的定义形式: 类型标识符类型标识符 *数组名数组名整

2、型常量表达式整型常量表达式例如:int *a3=NULL; char *s 6=NULL;a0=null01 a1=nulla2=null2as0=null0145s1=nulls2=nulls3=nulls4=nulls5=null23s2举例:int *p3, *pa, a=12, b=20; pa = &a; p0 = pa; p1 = &b;p0=pa01abp1=&bp2随机值随机值&a12202papp0随机值随机值01abp1随机值随机值p2随机值随机值随机值随机值12202pap*p0等价于a *p1等价于b 3【例14.5】 用指针数组输出n个字符串。#include std

3、io.h“main() char *ps4=Unix,Linux,Windows,Dos;int i;for(i=0;i=0;i-) printf(%sn, namei);56指针的指针指针的指针指针的指针定义形式如下: 类型符类型符 *变量名;变量名;例如: float *pp;例如,有如下程序段:float a=3.14;float *p;float *pp; /* pp是指向float *类型数据的指针 */p=&a; pp=&p; /* 将p的地址赋给pp */*pp a7指针的指针和指针数组关系指针的指针和指针数组关系char *name =Unix,Linux,Windows,C

4、language,Internet;char *p;p=name;这样,pi等价于namei *p等价于*name0等价于Up的目标变量类型是char * name数组的数组元素类型是char * p的类型是char * 数组名name的类型是char * *8【例例14.8】 用指向指针的指针变量将一批顺序给用指向指针的指针变量将一批顺序给定的字符串按反序输出。定的字符串按反序输出。main() int i;char *name =Unix,Linux,Windows,C language,Internet;char *p; for(i=4;i=0;i-) p=name+i; printf(

5、%sn,*p);p=name; for(i=4;i=0;i-) printf(%sn,pi);9例 用二级指针处理字符串#define NULL 0void main() char *p; char *name=hello,good,world,bye,; p=name+1; printf(%o : %s , *p,*p); p+=2; while(*p!=NULL) printf(%sn,*p+);name0name1name2name3name4char *name5worldbye0hellogoodnamep运行结果:644 : good bye用*p可输出地址(%o或%x), 也可用

6、它输出字符串(%s)p*(p+)10指针的指针类型作为函数的参数基本类型作为函数的参数 通过函数运算带回一个基本类型的值 实参: 该类型变量的地址 形参: 指向该类型的指针变量 构造类型作为函数的参数 非数组类型:结构体、共同体 通过函数运算带回一个构造类型的值 实参: 该类型变量的地址 形参: 指向该类型的指针变量11 数组类型: 通过函数运算带回一个数组 实参: 数组名 或某个数组元素变量的地址 形参: 指向数组元素类型的指针变量 指针类型作为函数的参数 通过函数运算带回一个指针变量 实参: 该指针变量的地址 形参: 指向该指针变量类型的指针变量 例如: char *name= CHINA

7、,AMERICA; sort(name, 2); void sort(char *name,int n);12【例14.9】 输入5个国名,并按字母顺序排列后输出#include string.h 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);char *name13void sort(char *name, int n) char *pt;

8、 int i, j, k; for (i=0; in-1; i+) k=i; for (j=i+1; j0) k=j; if(k!=i) pt=namei; namei=namek; namek=pt; 14void print(char *name, int n) int i; for (i=0; i15#include float f_xx(float x) return x*x;void main() float x = 3.0f; float y; y = f_xx(x); printf(n y=%f, y);计算y=x*x#include void f_xx(float x, flo

9、at *p) *p = x*x;void main() float x = 3.0f, y;/* float *p = &y; f_xx(x, p);*/ f_xx(x, &y); printf(n y=%f, y);16#include #include struct student char name20; int age; ;struct student f(struct student stu) printf(n name=); scanf(%s, stu.name); printf(n age=); scanf(%d, &stu.age); return stu; void main

10、() struct student stu = zhang_san, 19; printf(n name=%s, age=%d, stu.name, stu.age); stu = f(stu); printf(n name=%s, age=%d, stu.name, stu.age);17#include #include struct student char name20; int age; ;void f(struct student *stu) printf(n name=); scanf(%s, stu-name); printf(n age=); scanf(%d, &stu-a

11、ge);void main() struct student stu = zhang_san, 19; printf(n name=%s, age=%d, stu.name, stu.age); f(&stu); printf(n name=%s, age=%d, stu.name, stu.age);18void f(int a, int n) int i; for (i=0; in; i+) ai = ai + 3; void main() int i; int a = 1, 2; printf(n); for (i=0; i2; i+) printf(a%d=%d , i, ai); f

12、(a,2); printf(n); for (i=0; i2; i+) printf(a%d=%d , i, ai);int *a19#include int *f(int a, int n) int i; for (i=0; in; i+) ai = ai + 3; return a;void main() int i, *p = NULL; int a = 1, 2; printf(n); for (i=0; i2; i+) printf(a%d=%d , i, ai); p = f(a,2); printf(n); for (i=0; i2; i+) printf(p%d=%d , i,

13、 pi);int *a20#include void f(float *pp) static float a = 3.14f; *pp = &a;void main() float a = 0.0f; float *p = NULL; p = &a; f(&p); printf(n a=%f, *p=%fn, a, *p);21#include float *f(float *pp) static float a = 3.14f; pp = &a; return pp;void main() float a = 0.0f; float *p = NULL, *pp = NULL; p = &a

14、; pp = f(p); printf(n a=%f, *p=%f *pp=%fn, a, *p, *pp);2220002008200A20022004200612变量a 变量b(main) 指针变量p2000 指针变量q2002例 一级指针与二级指针#include void s *r,int *s) int *t; t=r; r=s; s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*q);20022000COPY 指针变量s 指针变量r(swap) 指针变量t2000200220002320002008200

15、A20022004200612变量a 变量b(main) 指针变量p2000 指针变量q2002例 一级指针与二级指针#include void s *r,int *s) int *t; t=r; r=s; s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*q);输出: 1,224例 一级指针与二级指针#include void s *r,int *s) int *t; t=r; r=s; s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*

16、q);abpqabpqrsabpqsrabpq输出: 1,225例 一级指针与二级指针#include void s *r,int *s) int *t; t=*r; *r=*s; *s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*q);20002008200A20022004200612变量a 变量b(main) 指针变量p2000 指针变量q200220062004COPY 二级指针s 二级指针r(swap) 指针变量t20002002200026例 一级指针与二级指针#include void s *r,in

17、t *s) int *t; t=*r; *r=*s; *s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*q);20002008200A20022004200612变量a 变量b(main) 指针变量p2000 指针变量q200220002002输出: 2,127例 一级指针与二级指针#include void s *r,int *s) int *t; t=*r; *r=*s; *s=t;main() int a=1,b=2,*p,*q; p=&a; q=&b; s); printf(%d,%dn,*p,*q);ab

18、pqbapqabrspqabrspq输出: 2,128 int *p 与 int *q10 指针数组名是二级指针常量p=q; p+i 是qi的地址指针数组作形参,int *q 与int *q完全等价;但作为变量定义两者不同系统只给p分配能保存一个指针值的内存区;而给q分配10块内存区,每块可保存一个指针值二级指针与指针数组的关系29函数指针函数指针指针变量变量的定义格式: 类型标识符类型标识符(*标识符标识符)(参数类型表参数类型表);变量的类型:类型标识符变量的类型:类型标识符(*)(参数类型表参数类型表)变量指向的类型:类型标识符变量指向的类型:类型标识符()(参数类型表参数类型表)函数名

19、是该函数所占内存区的函数名是该函数所占内存区的首地址首地址(入口地址入口地址)具有类型标识符具有类型标识符()(参数类型表参数类型表)的指针变量的指针变量=具有类型具有类型标识符标识符()(参数类型表参数类型表)格式的函数名格式的函数名int (*fun)(int,int);int max(int,int); int min(int,int);fun=max;fun=min;30函数指针变量的使用通过函数指针变量调用函数的语法格式为: (*函数指针变量名函数指针变量名)(参数列表参数列表);例如,上例中对fun变量所指函数的调用格式为:(*fun)( a, b );【例例14.7】 输入一个两

20、个数的四则运算式,通过函数指针求该输入一个两个数的四则运算式,通过函数指针求该运算式的值。运算式的值。float add(float a,float b)return a+b;float minus(float a,float b)return a-b;float mult(float a,float b)return a*b;float div(float a,float b)return a/b;31main() float m, n, r;char op;float (*p)(float,float);scanf(%f%c%f, &m, &op, &n);switch(op) case

21、+: p=add; break; case -: p=minus; break; case *: p=mult; break; case /: p=div; break; default: printf(Error Operation!); return; r=(*p)(m, n);printf(%f, r);32对指针的几点说明对指针的几点说明(1)有关指针的说明很多是由有关指针的说明很多是由指针、数组、函数说指针、数组、函数说明组合明组合而成的。但它们并不是可以任意组合的,如而成的。但它们并不是可以任意组合的,如数组就不能由函数组成,即数组元素不能是一个函数组就不能由函数组成,即数组元素不

22、能是一个函数;函数也不能返回一个数组或返回另一个函数。数;函数也不能返回一个数组或返回另一个函数。例如,例如,“int a5();”就是错误的。就是错误的。(2)与指针有关的常见说明和意义:与指针有关的常见说明和意义: int *ptr; char *ptr; int *ptrn int (*ptr)n; int (*ptr)(); int *ptr(); int *ptr; int *(*ptr)4;(3)标识符右边的标识符右边的方括号和圆括号方括号和圆括号优先优先于标识符左于标识符左边的边的“*”号,而方括号和圆括号以相同的优先级从号,而方括号和圆括号以相同的优先级从左到右结合。左到右结合

23、。 (4)阅读组合说明符的规则是阅读组合说明符的规则是“从里向外从里向外”。33指针与链表指针作为函数的返回值指针作为函数的返回值返回指针类型数据的函数函数定义形式为:类型标识符类型标识符 *函数名函数名(形式参数表形式参数表) 函数体函数体main() int *p, a10; p = max(a, 10);int *max(int a, int n) int *pmax return pmax;34链表的引入线性表的概念 每个数据元素(除第一个和最后一个元素)都有一个唯一的直接前驱和直接后继。第一个有唯一一个直接后继;最后一个有唯一一个直接前驱。数据的逻辑结构、 存储结构和运算 数据元素之

24、间的逻辑关系,与存储无关。 数据元素及其逻辑关系在存储器内的表示 在逻辑结构定义运算,在存储结构实现运算线性表的两种实现方式(存储结构) 数组和链表 数组的缺点:插入和删除移动大量数据 预先分配空间35 链表的基本构成单位是节点(Node),节点包括两个域:数据域和指针域数据。数据域(data)用于存储节点的值;指针域(next)用于存储数据元素的直接后继的地址(或位置)。数据域指针域数据域 指针域数据域 指针域数据域 空指针数据域 指针域头指针头指针head表节点表节点表节点表节点头节点头节点数据域 指针域数据域 指针域数据域 空指针指针域头指针头指针head指针指针p链表结构链表结构(节点

25、序列节点序列)36表节点的实现struct Node int data; struct Node *next;typedef struct Node ListNode;typedef ListNode *SingleLink;头结点头结点头指针 线性表为空表时,头结点的指针域为空 a1 a2 . an 空指针37链表的遍历 SingleLink p = NULL, head = NULL; p = head-next; while (p != NULL) printf(%d , p-data); p = p-next; 数据域 指针域数据域 指针域数据域 空指针指针域头指针头指针head指针指

26、针p38带头节点链表的遍历,应注意:固定的头指针head2可移动的指针p3 循环的初值p=head-next; 结束条件p=NULL进一步的问题:1求链表的长度2 在链表中查找指定的值39空间的分配与收回空间的分配与收回空间使用的基本规则是:空间使用的基本规则是:谁申请,谁释放。谁申请,谁释放。编译时,系统分配的有:基本类型的常量、变量,数组,编译时,系统分配的有:基本类型的常量、变量,数组,结构体类型的常量、变量结构体类型的常量、变量程序运行时,用户自己调用相关的函数进行了空间的分程序运行时,用户自己调用相关的函数进行了空间的分配,则最后用户必须调用相关的函数释放空间。配,则最后用户必须调用

27、相关的函数释放空间。1空间的申请空间的申请malloc()函数格式如下:函数格式如下: void *malloc(unsigned size);成功:返回值是所申请空间的首地址。成功:返回值是所申请空间的首地址。 失败:返回值是失败:返回值是NULL指针。指针。40例如:例如: int *p; p = (int*)malloc( sizeof(int); char *p; p = (char *)malloc( sizeof(char); double *p; p = (double *)malloc( sizeof(double); int *p; p = (int*)malloc(10*

28、sizeof(int); char *p; p = (char *)malloc(10* sizeof(char); double *p; p = (double *)malloc(10* sizeof(double); struct Node int data; struct Node *next; *p; p = (struct Node *)malloc( sizeof(struct Node); p = (struct Node *)malloc(10* sizeof(struct Node); 412空间的释放空间的释放格式如下:格式如下: void free(char *p );注

29、意:注意: free()函数与函数与malloc()函数配对使用。函数配对使用。 使用使用malloc()函数和函数和free()函数时,必须包含头文件函数时,必须包含头文件“stdlib.h”或或“alloc.h” 。例如,例如,“free(p);”语句就可以释放用户自己申请的空间,语句就可以释放用户自己申请的空间,其中参数其中参数p指向指向将要被释放的空间将要被释放的空间。3使用函数完成申请空间的方法使用函数完成申请空间的方法(关键是关键是指针类型的传递指针类型的传递): 指针作为函数的返回值指针作为函数的返回值 类型标识符类型标识符 *函数名函数名(形式参数表形式参数表) 指向指针的指针

30、变量作为函数的形参指向指针的指针变量作为函数的形参 类型标识符类型标识符 函数名函数名(类型标识符类型标识符 *pp,)42 指针作为函数的返回值指针作为函数的返回值 int *Get_Int_Arr(int num) int *p = (int*)malloc(sizeof(int)*num), *pp = p, i; for (i=0; inum; i+) *pp = i+1; pp+; return p;main() int *p = NULL, *p0 = NULL; p0 = p = Get_Int_Arr(10); while (p p0+10) printf(“%d ”, *p)

31、; p+; free(p0);43 指向指针的指针变量作为函数的形参指向指针的指针变量作为函数的形参void Get_Int_Arr(int *p, int num) int i; int *pp = NULL; *p = (int*)malloc(sizeof(int)*num); pp = *p; for (i=0; inum; i+) *pp = i+1; pp+; main() int *pp = NULL , *p0 = NULL; Get_Int_Arr(&pp, 10); p0 = pp; while (pp p0+10) printf(%d , *pp); pp+; free(

32、p0);44 不用不用指向指针的指针变量作为函数的形参指向指针的指针变量作为函数的形参void Get_Int_Arr(int *p, int num) int i; int *pp = NULL; p = (int*)malloc(sizeof(int)*num); pp = p; for (i=0; inum; i+) *pp = i+1; pp+; main() int *pp = NULL , *p0 = NULL; Get_Int_Arr(pp, 10); p0 = pp; while (pp next = NULL;2 建立空表建立空表51 p = (SingleLink)mall

33、oc(sizeof(ListNode); if (p = NULL) printf( p=NULL error! n); exit (1); p-data = data;3 产生新结点产生新结点 printf(data=); scanf(%d, &data);4 将新结点插入链表中将新结点插入链表中 p-next = head-next; head-next = p;52链表的建立SingleLink CreateFromHead() SingleLink head = NULL; ListNode *p; int data; int flag = 1; head = (SingleLink)

34、malloc(sizeof(ListNode); if (head = NULL) printf( head=NULL error! n); exit (1); head-next = NULL; printf(n input data?(1:yes,0:no):); scanf(%d, &flag);53while (flag) printf(data=); scanf(%d, &data); p = (SingleLink)malloc(sizeof(ListNode); if (p = NULL) printf( p=NULL error! n); exit (1); p-data =

35、data; p-next = head-next; head-next = p; printf(n input data?(1:yes,0:no):); scanf(%d, &flag); return head;54链表的建立链表的建立尾插法尾插法SingleLink CreateFromHead() SingleLink head = NULL, *tail = NULL; ListNode *p; int data; int flag = 1; return head;1 设计函数的首部及说明部分设计函数的首部及说明部分2 建立空表建立空表前一部分与头插法相同前一部分与头插法相同tail

36、 = head;553 产生新结点产生新结点 p = (SingleLink)malloc(sizeof(ListNode); if (p = NULL) printf( p=NULL error! n); exit (1); p-data = data; p-next = NULL;4 将新结点插入链表中将新结点插入链表中 tail-next = p; / p-next = head-next; tail = p; / head-next = p;56元素的插入元素的插入1设计函数的首部及说明部分设计函数的首部及说明部分2产生被插入的新结点产生被插入的新结点3确定插入位置确定插入位置4 将新

37、结点插入链表中将新结点插入链表中heada1头结点an .0a2dataai-1heada1头结点头结点an .0ai.prep571 设计函数的首部及说明部分设计函数的首部及说明部分SingleLink InsertSingleLink(SingleLink head, int i, int data) SingleLink pre = NULL, p = NULL; int k; return head;struct Node int data; struct Node *next;typedef struct Node ListNode;typedef ListNode *SingleL

38、ink;582 产生被插入的新结点产生被插入的新结点 p = (SingleLink)malloc(sizeof(ListNode); if (p = NULL) printf( p=NULL error! n); exit (1); p-data = data;dataai-1heada1头结点头结点an .0ai.prepk=0k=1k=i-1k=ik=npre593 确定插入位置确定插入位置 pre = head; k = 0; while (pre!=NULL & knext; k = k + 1; 1 k = 0和和ki-1) /*if (k != i-1) */ printf(in

39、put location error! n); exit (1); p-next = pre-next; pre-next = p;4 将新结点插入链表中将新结点插入链表中dataai-1heada1头结点头结点an .0ai.prep p-next = pre-next; pre-next = p;61元素的删除元素的删除1设计函数的首部及说明部分设计函数的首部及说明部分2确定删除位置确定删除位置3修改指针,将结点从链表中清除出去修改指针,将结点从链表中清除出去4 释放结点释放结点heada1头结点an .0a2pai-1heada1头结点头结点an .0ai.preai+1621 设计函数

40、的首部及说明部分设计函数的首部及说明部分SingleLink DeleteSingleLink(SingleLink head, int i) SingleLink pre = NULL, p = NULL; int k; return head;struct Node int data; struct Node *next;typedef struct Node ListNode;typedef ListNode *SingleLink;632 确定删除位置确定删除位置 pre = head; k = 0; while (pre-next != NULL & k next; k = k +

41、1; 1 k = 0和和knext; pre-next = p-next;ai-1heada1头结点头结点an .0ai.preai+1p4 释放结点释放结点 free(p); p = pre-next; pre-next = p-next;65链表的排序主程序主程序:定义有关数据结构定义有关数据结构2建立一个链表并输出建立一个链表并输出3排序(用函数)排序(用函数)4 输出验证输出验证排序函数排序函数:定义有关数据结构定义有关数据结构2建立有序新链表和旧链表建立有序新链表和旧链表3从链表第二个元素起(旧链表第一个元素起)插入新从链表第二个元素起(旧链表第一个元素起)插入新链表中链表中661

42、设计函数的首部及说明部分设计函数的首部及说明部分SingleLink link_sort(SingleLink head) SingleLink p = NULL, headOld = NULL, pTemp = NULL, pre = NULL; return head;struct Node int data; struct Node *next;typedef struct Node ListNode;typedef ListNode *SingleLink;67while (headOld !=NULL) pre = head; p = pre-next; while (p!=NULL

43、 & p-datadata) pre = pre-next; p = pre-next; pTemp = headOld; headOld = headOld-next; pre-next = pTemp; pTemp-next = p; p = head-next; headOld = p-next; p-next = NULL;建立有序新链表和旧链表建立有序新链表和旧链表68两个由小到大的有序链表连接成一个链表两个由小到大的有序链表连接成一个链表主程序主程序:定义有关数据结构定义有关数据结构2建立两个有序链表建立两个有序链表3连接链表并保持由小到大的次序连接链表并保持由小到大的次序4 输出

44、验证输出验证struct Node int data; struct Node *next;typedef struct Node ListNode;typedef ListNode *SingleLink;69SingleLink p = NULL, head = NULL, head1 = NULL, head2 = NULL; head1 = CreateFromHead(); head2 = CreateFromTail(); head = ConcateLink(head1, head2); p = head-next; while (p != NULL) printf(%d , p

45、-data); p = p-next; 70连接链表并保持由小到大的次序连接链表并保持由小到大的次序1设计函数的首部及说明部分设计函数的首部及说明部分2建立空表建立空表3两个链表都不空时两个链表都不空时,比较大小比较大小,插入新链表插入新链表4当当A链表空时,新链表尾部接上链表空时,新链表尾部接上B链表链表 当当B链表空时,新链表尾部接上链表空时,新链表尾部接上A链表链表SingleLink ConcateLink(SingleLink head1, SingleLink head2) SingleLink head = NULL, tail = NULL; return head;71 当当A链表空时,新链表尾部接上链表空时,新链表尾部接上B链表链表 当当B链表空时,新链表尾部接上链表空时,新链表尾部接上A链表链表 if (head1 = NULL) tail-next = head2; if (head2 = NULL) tail-next = head1;主程序中:主程序中: head = ConcateLink(head1, head2); free(head1); free(head2);问题:链表问题:链表head1和和链表链表head2的头结点在不在新链表的头结点在不在新链表head中?中?72

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号